From f9feb568e6c03e9f6fd1655aea79a00dfb127d7c Mon Sep 17 00:00:00 2001 From: iiPython Date: Mon, 6 Mar 2023 15:59:39 -0600 Subject: [PATCH 01/15] [struct] Attempt to remove main.x2 --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0cb035e..72704d9 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,4 @@ package.zip .installer_cache # Hide x2 testing files -*.x2 +*.xpp From 101a550de3fa1c49d8b646c00570b4e8085740c9 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Mon, 6 Mar 2023 16:00:19 -0600 Subject: [PATCH 02/15] [github] Remove main.x2 manually --- main.x2 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 main.x2 diff --git a/main.x2 b/main.x2 deleted file mode 100644 index 3632bed..0000000 --- a/main.x2 +++ /dev/null @@ -1 +0,0 @@ -prt "Hello, world!" From 808de26c14c8b3c84235cc87020acb29e825335b Mon Sep 17 00:00:00 2001 From: iiPython Date: Mon, 6 Mar 2023 16:03:17 -0600 Subject: [PATCH 03/15] [branding] Ensure config uses .xconfig --- xpp/extra/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xpp/extra/config.py b/xpp/extra/config.py index 672ee3d..9c7e83b 100644 --- a/xpp/extra/config.py +++ b/xpp/extra/config.py @@ -6,9 +6,9 @@ # Initialization config = {} -if os.path.isfile(".x2config"): +if os.path.isfile(".xconfig"): try: - with open(".x2config", "r") as f: + with open(".xconfig", "r") as f: config = json.loads(f.read()) except Exception: From 2e99b36af31fc76f0863fa1c24ca24b5666d00fd Mon Sep 17 00:00:00 2001 From: iiPython Date: Mon, 6 Mar 2023 16:09:14 -0600 Subject: [PATCH 04/15] [docs] Patch documentation for now --- md/documents.md | 8 +- md/documents/comments.md | 4 +- md/documents/comparators.md | 8 +- md/documents/configurations.md | 8 +- md/documents/dataTypes.md | 18 +-- md/documents/operators.md | 202 ++++++++++++++++----------------- md/documents/packages.md | 12 +- md/documents/sections.md | 18 +-- md/documents/variables.md | 18 +-- md/tutorials.md | 8 +- md/tutorials/1helloWorld.md | 14 +-- md/tutorials/2userInput.md | 8 +- md/tutorials/3branches.md | 6 +- md/tutorials/4calculator.md | 16 +-- 14 files changed, 174 insertions(+), 174 deletions(-) diff --git a/md/documents.md b/md/documents.md index 0ab3043..f5216da 100644 --- a/md/documents.md +++ b/md/documents.md @@ -1,4 +1,4 @@ -# [x2](../README.md) / Documents +# [x++](../README.md) / Documents ## Table of Contents @@ -21,9 +21,9 @@ ## About -Welcome to the documents page of the official x2 documentation. In this section, you will be learning about the individual components that make up x2. +Welcome to the documents page of the official x++ documentation. In this section, you will be learning about the individual components that make up x++. -If you are looking for a beginner's guide for x2, check out the [tutorials](./tutorials.md) instead. +If you are looking for a beginner's guide for x++, check out the [tutorials](./tutorials.md) instead. ## Documents @@ -40,4 +40,4 @@ If you are looking for a beginner's guide for x2, check out the [tutorials](./tu Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--documents) \ No newline at end of file +[↑ Go To Top](#x--documents) \ No newline at end of file diff --git a/md/documents/comments.md b/md/documents/comments.md index 3ebdaa5..de157e8 100644 --- a/md/documents/comments.md +++ b/md/documents/comments.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Documents](../documents.md) / Comments +# [x++](../../README.md) / [Documents](../documents.md) / Comments ## Table of Contents @@ -37,4 +37,4 @@ out 5 :: This is a comment Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--documents--comments) \ No newline at end of file +[↑ Go To Top](#x--documents--comments) \ No newline at end of file diff --git a/md/documents/comparators.md b/md/documents/comparators.md index 9d7767d..2e55e5b 100644 --- a/md/documents/comparators.md +++ b/md/documents/comparators.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Documents](../documents.md) / Comparators +# [x++](../../README.md) / [Documents](../documents.md) / Comparators ## Table of Contents @@ -55,9 +55,9 @@ ## About -Comparators are symbols or keywords that compare two different variables or values and trigger a branch in the x2 thread. Each comparator has its functionality. +Comparators are symbols or keywords that compare two different variables or values and trigger a branch in the x++ thread. Each comparator has its functionality. -Expressions are segments in the code that creates a branch in the x2 thread. They are always made up of three components: the `source`, the `comparator`, and the `target`, and they are arranged like so: +Expressions are segments in the code that creates a branch in the x++ thread. They are always made up of three components: the `source`, the `comparator`, and the `target`, and they are arranged like so: ```xt @@ -302,4 +302,4 @@ cmp 5 from int "out \"true\"" Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--documents--comparators) \ No newline at end of file +[↑ Go To Top](#x--documents--comparators) \ No newline at end of file diff --git a/md/documents/configurations.md b/md/documents/configurations.md index 5d97031..b22da5a 100644 --- a/md/documents/configurations.md +++ b/md/documents/configurations.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Documents](../documents.md) / Configurations +# [x++](../../README.md) / [Documents](../documents.md) / Configurations ## Table of Contents @@ -62,9 +62,9 @@ The configuration file can also contain non-essential information, such as the a "contributors": [ "contributor A", "contributor B" ], - "description": "This is my x2 project", + "description": "This is my x++ project", "main": "main.xt", - "name": "my-x2-project", + "name": "my-x++-project", "version": "1.0.0" } ``` @@ -105,4 +105,4 @@ Throws errors silently. Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--documents--configurations) \ No newline at end of file +[↑ Go To Top](#x--documents--configurations) \ No newline at end of file diff --git a/md/documents/dataTypes.md b/md/documents/dataTypes.md index 4490f34..b00bbd1 100644 --- a/md/documents/dataTypes.md +++ b/md/documents/dataTypes.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Documents](../documents.md) / Data Types +# [x++](../../README.md) / [Documents](../documents.md) / Data Types ## Table of Contents @@ -50,9 +50,9 @@ Data types are classifications of variables or values. Each data type can only store a specific type of value. For example, a string cannot contain an integer value, or a boolean cannot contain a string value. -Because x2 is a dynamic programming language, you can change the data type of a variable or a value during run-time. +Because x++ is a dynamic programming language, you can change the data type of a variable or a value during run-time. -x2 is also a weakly-typed programming language. You do not (and cannot) directly specify what the data type of a variable or value is. The interpreter will read the value and determine the data type during run-time. +x++ is also a weakly-typed programming language. You do not (and cannot) directly specify what the data type of a variable or value is. The interpreter will read the value and determine the data type during run-time. Strongly-typed language, such as [Java](https://en.wikipedia.org/wiki/Java_(programming_language)): @@ -66,7 +66,7 @@ Weakly-typed language, such as [JavaScript](https://en.wikipedia.org/wiki/JavaSc let myInteger = 5; ``` -Similarly, in x2, you define a variable with a data type of an integer like so: +Similarly, in x++, you define a variable with a data type of an integer like so: ```xt psh 5 myInteger @@ -78,7 +78,7 @@ psh 5 myInteger A boolean value represents either `true` or `false`. -Currently, it is impossible to get a boolean value within vanilla x2. Because of that, integers are used instead to represent a true or false value, where `1` represents `true` and `0` represents `false`. +Currently, it is impossible to get a boolean value within vanilla x++. Because of that, integers are used instead to represent a true or false value, where `1` represents `true` and `0` represents `false`. --- @@ -130,7 +130,7 @@ psh 05 myInteger out myInteger ``` -In vanilla x2, it can also be used as a boolean value, where `1` represents `true` and `0` represents `false`: +In vanilla x++, it can also be used as a boolean value, where `1` represents `true` and `0` represents `false`: ```xt psh 0 hamburgerIsEaten @@ -143,7 +143,7 @@ evl hamburgerIsEaten == 1 "out \"Someone ate my hamburger\"" Null is a data type that represents nothing. -It cannot be defined normally in x2 and acts as the default value to undefined variables: +It cannot be defined normally in x++ and acts as the default value to undefined variables: ```xt out nonexistingVariable @@ -207,7 +207,7 @@ Below is a list of all the escape codes for reference: > Source: [Python DS - Python 3 Escape Sequences](https://www.python-ds.com/python-3-escape-sequences) -You can also string interpolation within an x2 string. All string interpolations must be a valid x2 statement and be surrounded by `$()`: +You can also string interpolation within an x++ string. All string interpolations must be a valid x++ statement and be surrounded by `$()`: ```xt psh 5 myInteger @@ -226,4 +226,4 @@ cmp "abc" < "cba" "out \"true\"" Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--documents--data-types) \ No newline at end of file +[↑ Go To Top](#x--documents--data-types) \ No newline at end of file diff --git a/md/documents/operators.md b/md/documents/operators.md index 8511d5b..208be41 100644 --- a/md/documents/operators.md +++ b/md/documents/operators.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Documents](../documents.md) / Operators +# [x++](../../README.md) / [Documents](../documents.md) / Operators ## Table of Contents @@ -125,19 +125,19 @@ Operators are keywords that process arguments. A statement is a line of code that tells the interpreter what to do. They are always made up of two components: the `operator` and the `arguments`, and they are arranged like so: -```xt +```xpp [...arguments] ``` For example: -```xt +```xpp out "Hello, world!" ``` Or: -```xt +```xpp add 1 2 sum ``` @@ -145,7 +145,7 @@ A statement can also be wrapped around parentheses (`()`) to group them. Some statements return values, which can be stored in a variable: -```xt +```xpp psh (add 1 2) sum ``` @@ -153,7 +153,7 @@ psh (add 1 2) sum ### Add -```xt +```xpp add [sum] ``` @@ -169,7 +169,7 @@ Returns: [Float](./dataTypes.md#float) or [Integer](./dataTypes.md#integer) or [ Example: -```xt +```xpp add 5 10 sum out sum ``` @@ -178,7 +178,7 @@ out sum ### Call -```xt +```xpp call
[...arguments] ``` @@ -194,7 +194,7 @@ Returns: Any Example: -```xt +```xpp call mySection 5 10 output out output @@ -207,7 +207,7 @@ out output ### Character -```xt +```xpp char [output] ``` @@ -223,7 +223,7 @@ Returns: [String](./dataTypes.md#string) Example: -```xt +```xpp char 3 "Hello, world!" output out output ``` @@ -232,7 +232,7 @@ out output ### Clear -```xt +```xpp cls ``` @@ -242,7 +242,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp out "Hello, world!" cls out "Hello, world!" @@ -252,7 +252,7 @@ out "Hello, world!" ### Compare -```xt +```xpp cmp [false branch] ``` @@ -268,7 +268,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp cmp 5 == 5 "jmp true" "jmp false" :true @@ -282,7 +282,7 @@ cmp 5 == 5 "jmp true" "jmp false" ### Constant -```xt +```xpp cnst ``` @@ -297,7 +297,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp cnst 5 myInteger out myInteger ``` @@ -306,7 +306,7 @@ out myInteger ### Decrement -```xt +```xpp dec [output] ``` @@ -323,7 +323,7 @@ Returns: [Float](./dataTypes.md#float) or [Integer](./dataTypes.md#integer) Example: -```xt +```xpp psh 5 myInteger dec myInteger out myInteger @@ -333,7 +333,7 @@ out myInteger ### Divide -```xt +```xpp div [quotient] ``` @@ -349,7 +349,7 @@ Returns: [Float](./dataTypes.md#float) or [Integer](./dataTypes.md#integer) Example: -```xt +```xpp div 10 5 quotient out quotient ``` @@ -358,7 +358,7 @@ out quotient ### End -```xt +```xpp end ``` @@ -368,7 +368,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp :main out "Hello, world!" end @@ -379,7 +379,7 @@ Example: ### Evaluate -```xt +```xpp evl ``` @@ -393,7 +393,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp evl "print('Hello, world!')" ``` @@ -401,8 +401,8 @@ evl "print('Hello, world!')" ### Exit -```xt -ext +```xpp +expp ``` Exits the process. @@ -411,9 +411,9 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp out "Hello, world!" -ext +expp out "Hello, world!" ``` @@ -421,7 +421,7 @@ out "Hello, world!" ### Float -```xt +```xpp flt [output] ``` @@ -438,7 +438,7 @@ Returns: [Float](./dataTypes.md#float) Example: -```xt +```xpp flt "5" myFloat out myFloat ``` @@ -447,7 +447,7 @@ out myFloat ### Import -```xt +```xpp imp [as ] ``` @@ -464,15 +464,15 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt -imp "myFile.xt" as "myPackage" +```xpp +imp "myFile.xpp" as "myPackage" ``` --- ### Index -```xt +```xpp idx [output] ``` @@ -488,7 +488,7 @@ Returns: [Integer](./dataTypes.md#integer) Example: -```xt +```xpp idx "ello" "Hello, world!" output out output ``` @@ -497,7 +497,7 @@ out output ### Increment -```xt +```xpp inc [output] ``` @@ -514,7 +514,7 @@ Returns: [Float](./dataTypes.md#float) or [Integer](./dataTypes.md#integer) Example: -```xt +```xpp psh 5 myInteger inc myInteger out myInteger @@ -524,7 +524,7 @@ out myInteger ### Is A Number -```xt +```xpp inm [output] ``` @@ -539,7 +539,7 @@ Returns: [Integer](./dataTypes.md#integer) Example: -```xt +```xpp inm 5 output out output ``` @@ -548,7 +548,7 @@ out output ### Is Any Number -```xt +```xpp inms [output] ``` @@ -563,7 +563,7 @@ Returns: [Integer](./dataTypes.md#integer) Example: -```xt +```xpp inms "5" output out output ``` @@ -572,7 +572,7 @@ out output ### Jump -```xt +```xpp jmp
``` @@ -586,7 +586,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp jmp mySection :mySection @@ -597,7 +597,7 @@ jmp mySection ### Length -```xt +```xpp len [output] ``` @@ -612,7 +612,7 @@ Returns: [Integer](./dataTypes.md#integer) Example: -```xt +```xpp len "Hello, world!" output out output ``` @@ -621,7 +621,7 @@ out output ### Load -```xt +```xpp load [output] ``` @@ -636,17 +636,17 @@ Returns: [String](./dataTypes.md#string) Example: -In `file.xt`: +In `file.xpp`: -```xt +```xpp :mySection out "Hello, world!" ``` -In `main.xt`: +In `main.xpp`: -```xt -load "file.xt" output +```xpp +load "file.xpp" output out output ``` @@ -654,7 +654,7 @@ out output ### Lowercase -```xt +```xpp lwr [output] ``` @@ -671,7 +671,7 @@ Returns: [String](./dataTypes.md#string) Example: -```xt +```xpp lwr "Hello, world!" output out output ``` @@ -680,7 +680,7 @@ out output ### Multiply -```xt +```xpp mul [product] ``` @@ -696,7 +696,7 @@ Returns: [Float](./dataTypes.md#float) or [Integer](./dataTypes.md#integer) or [ Example: -```xt +```xpp mul 5 10 product out product ``` @@ -705,7 +705,7 @@ out product ### Number -```xt +```xpp num [output] ``` @@ -722,7 +722,7 @@ Returns: [Float](./dataTypes.md#float) or [Integer](./dataTypes.md#integer) Example: -```xt +```xpp num "5" myInteger out myInteger ``` @@ -731,7 +731,7 @@ out myInteger ### Output -```xt +```xpp out [...value] ``` @@ -745,7 +745,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp out "Hello, world!" ``` @@ -753,7 +753,7 @@ out "Hello, world!" ### Pop -```xt +```xpp pop [output] ``` @@ -768,7 +768,7 @@ Returns: Any Example: -```xt +```xpp psh 5 myInteger pop "myInterger" output out output @@ -778,7 +778,7 @@ out output ### Provoke -```xt +```xpp pvk
[...arguments] ``` @@ -793,7 +793,7 @@ Returns: Any Example: -```xt +```xpp pvk mySection 5 10 :mySection a b @@ -805,7 +805,7 @@ pvk mySection 5 10 ### Push -```xt +```xpp psh ``` @@ -820,7 +820,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp psh 5 myInteger out myInteger ``` @@ -829,7 +829,7 @@ out myInteger ### Random Number Generator -```xt +```xpp rng [output] ``` @@ -845,7 +845,7 @@ Returns: [Integer](./dataTypes.md#integer) Example: -```xt +```xpp rng 0 5 myInteger out myInteger ``` @@ -854,7 +854,7 @@ out myInteger ### Read -```xt +```xpp read [prompt] [output] ``` @@ -869,7 +869,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp read "What is your name: " name out name ``` @@ -878,7 +878,7 @@ out name ### Remove -```xt +```xpp rem ``` @@ -892,7 +892,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp psh 5 myInteger out myInteger rem myInteger @@ -903,7 +903,7 @@ out myInteger ### Repeat -```xt +```xpp rep ``` @@ -918,7 +918,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp rep 5 "out \"Hello, world!\"" ``` @@ -926,7 +926,7 @@ rep 5 "out \"Hello, world!\"" ### Return -```xt +```xpp ret ``` @@ -940,7 +940,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp :mySection ret 5 ``` @@ -949,7 +949,7 @@ Example: ### Round -```xt +```xpp rnd [precision] ``` @@ -966,7 +966,7 @@ Returns: [Float](./dataTypes.md#float) or [Integer](./dataTypes.md#integer) Example: -```xt +```xpp psh 5.5 myInteger rnd myInteger out myInteger @@ -976,7 +976,7 @@ out myInteger ### Save -```xt +```xpp save [output] ``` @@ -991,15 +991,15 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt -save "file.xt" "Hello, world!" +```xpp +save "file.xpp" "Hello, world!" ``` --- ### Skip -```xt +```xpp skp ``` @@ -1009,7 +1009,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp skp ``` @@ -1017,7 +1017,7 @@ skp ### Slice -```xt +```xpp slc [output] ``` @@ -1034,7 +1034,7 @@ Returns: [String](./dataTypes.md#string) Example: -```xt +```xpp slc 0 5 "Hello, world!" output out output ``` @@ -1043,7 +1043,7 @@ out output ### String -```xt +```xpp str [output] ``` @@ -1060,7 +1060,7 @@ Returns: [String](./dataTypes.md#string) Example: -```xt +```xpp str 5 myString out myString ``` @@ -1069,7 +1069,7 @@ out myString ### Subtract -```xt +```xpp sub [difference] ``` @@ -1085,7 +1085,7 @@ Returns: [Float](./dataTypes.md#float) or [Integer](./dataTypes.md#integer) Example: -```xt +```xpp sub 10 5 difference out difference ``` @@ -1094,7 +1094,7 @@ out difference ### Throw -```xt +```xpp thrw ``` @@ -1110,7 +1110,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp out "Hello, world!" thrw "Error message!" out "Hello, world!" @@ -1120,7 +1120,7 @@ out "Hello, world!" ### Try -```xt +```xpp try [error statement] ``` @@ -1135,7 +1135,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp try "thrw \"Error message!\"" "out \"An error has occurred\"" ``` @@ -1143,7 +1143,7 @@ try "thrw \"Error message!\"" "out \"An error has occurred\"" ### Uppercase -```xt +```xpp upr [output] ``` @@ -1160,7 +1160,7 @@ Returns: [String](./dataTypes.md#string) Example: -```xt +```xpp upr "Hello, world!" output out output ``` @@ -1169,11 +1169,11 @@ out output ### Wait -```xt +```xpp wait ``` -Waits a certain number of seconds before executing the next statement. +Waits a certain number of seconds before executing the nexpp statement. | Parameter | Type | Optional | Description | | :-: | :-: | :-: | :-: | @@ -1183,7 +1183,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp out "Hello, world!" wait 5 out "Hello, world!" @@ -1193,7 +1193,7 @@ out "Hello, world!" ### While -```xt +```xpp whl ``` @@ -1208,7 +1208,7 @@ Returns: [Null](./dataTypes.md#null) Example: -```xt +```xpp psh 0 @myInteger whl @myInteger < 5 "jmp mySection" @@ -1221,4 +1221,4 @@ whl @myInteger < 5 "jmp mySection" Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--documents--operators) \ No newline at end of file +[↑ Go To Top](#x--documents--operators) \ No newline at end of file diff --git a/md/documents/packages.md b/md/documents/packages.md index 0e1eafd..634254c 100644 --- a/md/documents/packages.md +++ b/md/documents/packages.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Documents](../documents.md) / Packages +# [x++](../../README.md) / [Documents](../documents.md) / Packages ## Table of Contents @@ -23,13 +23,13 @@ ## About -Packages are x2 files written by other people that can be imported to your x2 project using the `imp` operator: +Packages are x++ files written by other people that can be imported to your x++ project using the `imp` operator: ```xt imp "examplePackage" ``` -All packages are located in the `pkg/` folder. If one is not found, the interpreter will automatically create one. When attempting to import a package, the interpreter will look for the `pkg//main.xt` file. If one is not found, an error is thrown. +All packages are located in the `pkg/` folder. If one is not found, the interpreter will automatically create one. When attempting to import a package, the interpreter will look for the `pkg//main.xpp` file. If one is not found, an error is thrown. Imported packages are only available in that one specific file. When attempting to use the package elsewhere, an error is thrown. @@ -43,12 +43,12 @@ examplePackage.mySection The same applies to importing files. -To import a file from the x2 project, the path must contain the `.xt` extension. The interpreter will then attempt to find the file from the current working directory. If one is not found, an error is thrown. +To import a file from the x++ project, the path must contain the `.xpp` extension. The interpreter will then attempt to find the file from the current working directory. If one is not found, an error is thrown. -Currently, the [standard library](../standardLibrary.md) is built into the x2 interpreter. You can install more packages at the [official website](https://x2.iipython.cf/). +Currently, the [standard library](../standardLibrary.md) is built into the x++ interpreter. You can install more packages from GitHub. --- Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--documents--packages) \ No newline at end of file +[↑ Go To Top](#x--documents--packages) \ No newline at end of file diff --git a/md/documents/sections.md b/md/documents/sections.md index 90ae0ff..468c040 100644 --- a/md/documents/sections.md +++ b/md/documents/sections.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Documents](../documents.md) / Sections +# [x++](../../README.md) / [Documents](../documents.md) / Sections ## Table of Contents @@ -27,13 +27,13 @@ A section is a set of statements that get executed when using the operators `cal Sections always start with a colon `:`, and their name can only contain alphabetical letters: -```xt +```xpp :mySection ``` By default, a section is public, which means other files can import and use the section. To define a private section, append an at symbol (`@`) at the beginning of the section name. A private section can only be used by other sections within the file: -```xt +```xpp :@mySection ``` @@ -41,17 +41,17 @@ Statements that are not within a section are located in the global section prede A section can also take arguments. Any variables separated by space and placed directly after the section name are considered arguments: -```xt +```xpp :myMethod argument0 argument1 ``` > All arguments of a method or a function must be passed. An error is thrown if an argument is missing. -Three types of sections exist in x2. +Three types of sections exist in x++. A section that does not take any additional arguments nor return a value is considered a `section` and generally invoked using the `jmp` operator: -```xt +```xpp jmp mySection :mySection @@ -60,7 +60,7 @@ jmp mySection A section that does take additional arguments but does not return a value is considered a `method` and generally invoked using the `pvk` operator. -```xt +```xpp pvk myMethod :myMethod a b @@ -70,7 +70,7 @@ pvk myMethod A section that does take additional arguments and returns a value is considered a `function` and can be invoked using either the `pvk` or `call` operator. The `pvk` operator is used when the returned value is not wanted and the opposite is true for `call`: -```xt +```xpp call myFunction a b output out output @@ -83,4 +83,4 @@ out output Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--documents--sections) \ No newline at end of file +[↑ Go To Top](#x--documents--sections) \ No newline at end of file diff --git a/md/documents/variables.md b/md/documents/variables.md index 85fa299..0621e22 100644 --- a/md/documents/variables.md +++ b/md/documents/variables.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Documents](../documents.md) / Variables +# [x++](../../README.md) / [Documents](../documents.md) / Variables ## Table of Contents @@ -27,13 +27,13 @@ A variable is a label that stores a value that can be referenced and modified at Even though a variable can contain any character besides spaces, it is recommended to use only alphabetical letters. A variable is defined using the `psh` operator: -```xt +```xpp psh 5 myInteger ``` A variable can then be referenced using the variable name: -```xt +```xpp out myInteger ``` @@ -43,31 +43,31 @@ There are two other types of variables, `file variable` and `global variable`. A A file variable is defined by appending an at symbol (`@`) in front of the variable name: -```xt +```xpp psh 5 @myInteger ``` A global variable is defined by appending a hashtag (`#`) in front of the variable name: -```xt +```xpp psh 5 #myInteger ``` Both file and global are not garbage collected and must be manually deleted from the memory using the `rem` operator: -```xt +```xpp rem 5 @myInteger ``` Or: -```xt +```xpp rem 5 #myInteger ``` A variable can also be constant, which means it cannot be deleted using the `rem` operator. A constant variable can be defined using the `cnst` operator: -```xt +```xpp cnst 5 myInteger ``` @@ -77,4 +77,4 @@ Attempting to delete the variable will cause an error to be thrown. Note that ev Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--documents--variables) \ No newline at end of file +[↑ Go To Top](#x--documents--variables) \ No newline at end of file diff --git a/md/tutorials.md b/md/tutorials.md index 7b3c929..4a39885 100644 --- a/md/tutorials.md +++ b/md/tutorials.md @@ -1,4 +1,4 @@ -# [x2](../README.md) / Tutorials +# [x++](../README.md) / Tutorials ## Table of Contents @@ -17,9 +17,9 @@ ## About -Welcome to the tutorials of the official x2 documentation. In this section, you will be learning all the basics within x2, including familiaring the syntax of x2 as well as creating your first x2 project! +Welcome to the tutorials of the official x++ documentation. In this section, you will be learning all the basics within x++, including familiaring the syntax of x++ as well as creating your first x++ project! -If you are looking for information for a specific component of x2, check out the [documents](./documents.md) instead. +If you are looking for information for a specific component of x++, check out the [documents](./documents.md) instead. ## Tutorials @@ -32,4 +32,4 @@ If you are looking for information for a specific component of x2, check out the Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--tutorials) \ No newline at end of file +[↑ Go To Top](#x--tutorials) \ No newline at end of file diff --git a/md/tutorials/1helloWorld.md b/md/tutorials/1helloWorld.md index 5502a3d..d87fb3f 100644 --- a/md/tutorials/1helloWorld.md +++ b/md/tutorials/1helloWorld.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Tutorials](../tutorials.md) / 1. Hello, world! +# [x++](../../README.md) / [Tutorials](../tutorials.md) / 1. Hello, world! ## Table of Contents @@ -19,9 +19,9 @@ ## Lesson -Welcome to the first lesson of the tutorials! In this lesson, you will be learning how to write your first x2 project, how to define and use a variable, and how to print a value into the terminal. +Welcome to the first lesson of the tutorials! In this lesson, you will be learning how to write your first x++ project, how to define and use a variable, and how to print a value into the terminal. -First, make sure you properly installed x2 to your device if you haven't done so already. You can follow the guide in the [getting started](../../README.md#getting-started) section for additional help. +First, make sure you properly installed x++ to your device if you haven't done so already. You can follow the guide in the [getting started](../../README.md#getting-started) section for additional help. Once you are done, open up the `main.xt` file. Inside, you should find something like this: @@ -31,7 +31,7 @@ Once you are done, open up the `main.xt` file. Inside, you should find something out "Hello, world!" ``` -This is the default template when you first installed x2. It is important for you to know what the code is doing. Let's break it down. +This is the default template when you first installed x++. It is important for you to know what the code is doing. Let's break it down. The first line in the file is a comment. A comment is a text that provides information to the developer, such as you. It is ignored by the interpreter as it is intended for only developers to read. @@ -39,7 +39,7 @@ The second line defines a section. A section is a region of code that will be ex The third line prints out a string with the value `"Hello, world!"`. A string is a series of characters wrapped around by double-quotes (`"`). You can think of it like a character, word, phrase, or a sentence. The `out` is an operator, which means it takes arguments, processes them, and does a specific action based on what the arguments are. In the case, the `out` operator simply takes the arguments and prints them in the terminal. -Although indentations in x2 aren't necessary, it is a good practice to use indentation to group the statements, so you or other developers won't get confused. +Although indentations in x++ aren't necessary, it is a good practice to use indentation to group the statements, so you or other developers won't get confused. Now that you understand what your code is doing, let's try it out. Using what you've learned, try printing out your name and age in the format `My name is and I am years old` in the terminal. @@ -87,7 +87,7 @@ Let's try it! out "My name is $(pop name) and I am $(pop age) years old" ``` -You did it! You made your first ever x2 project. +You did it! You made your first ever x++ project. In the next lesson, you will learn how to get user inputs and how to manupulate strings and numbers. @@ -95,4 +95,4 @@ In the next lesson, you will learn how to get user inputs and how to manupulate Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--tutorials--1-hello-world) \ No newline at end of file +[↑ Go To Top](#x--tutorials--1-hello-world) \ No newline at end of file diff --git a/md/tutorials/2userInput.md b/md/tutorials/2userInput.md index d23d1c8..bed2e54 100644 --- a/md/tutorials/2userInput.md +++ b/md/tutorials/2userInput.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Tutorials](../tutorials.md) / 2. User Input +# [x++](../../README.md) / [Tutorials](../tutorials.md) / 2. User Input ## Table of Contents @@ -19,9 +19,9 @@ ## Lesson -In the previous lesson, you learned how to write your first x2 project, define and use a variable, and output a value into the terminal. In this lesson, you will learn how to get a user input and how to manipulate strings and numbers. +In the previous lesson, you learned how to write your first x++ project, define and use a variable, and output a value into the terminal. In this lesson, you will learn how to get a user input and how to manipulate strings and numbers. -So far, you should've gotten this in your `main.xt` file: +So far, you should've gotten this in your `main.xpp` file: ```xt :: Main @@ -104,4 +104,4 @@ In the next lesson, you will learn how to make branches using the `cmp` operator Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--tutorials--2-user-input) \ No newline at end of file +[↑ Go To Top](#x--tutorials--2-user-input) \ No newline at end of file diff --git a/md/tutorials/3branches.md b/md/tutorials/3branches.md index ad70cc4..559e439 100644 --- a/md/tutorials/3branches.md +++ b/md/tutorials/3branches.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Tutorials](../tutorials.md) / 3. Branches +# [x++](../../README.md) / [Tutorials](../tutorials.md) / 3. Branches ## Table of Contents @@ -87,10 +87,10 @@ Did you get something like this: cmp age > 16 "out \"You can also drive a car\"" ``` -In the next lesson, you will be learning how to make a calculator using x2. +In the next lesson, you will be learning how to make a calculator using x++. --- Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--tutorials--3-branches) \ No newline at end of file +[↑ Go To Top](#x--tutorials--3-branches) \ No newline at end of file diff --git a/md/tutorials/4calculator.md b/md/tutorials/4calculator.md index c3600bf..caed468 100644 --- a/md/tutorials/4calculator.md +++ b/md/tutorials/4calculator.md @@ -1,4 +1,4 @@ -# [x2](../../README.md) / [Tutorials](../tutorials.md) / 4. Calculator +# [x++](../../README.md) / [Tutorials](../tutorials.md) / 4. Calculator ## Table of Contents @@ -19,14 +19,14 @@ ## Lesson -From the last three lessons, you learned how to print values into the terminal, get user inputs, modify strings and numbers, and create branches. In this lesson, you will be using all of this knowledge to construct a calculator using x2. Even though it may seem difficult at first, it is just made up of simple components. Let's break it down. +From the last three lessons, you learned how to print values into the terminal, get user inputs, modify strings and numbers, and create branches. In this lesson, you will be using all of this knowledge to construct a calculator using x++. Even though it may seem difficult at first, it is just made up of simple components. Let's break it down. Let's introduce the program and get some inputs from the user using the `out` and `read` operators: ```xt :: Main :main - out "Welcome to the x2 calculator!" + out "Welcome to the x++ calculator!" out "-----" read "Please enter your first number: " a read "Please enter your second number: " b @@ -38,7 +38,7 @@ You can also use escape codes to format your texts, such as `\t` to indent your ```xt :: Main :main - out "Welcome to the x2 calculator!" + out "Welcome to the x++ calculator!" out "-----" read "Please enter your first number: " a read "Please enter your second number: " b @@ -57,7 +57,7 @@ Currently, the numbers you got from the user are a string. You need to parse it ```xt :: Main :main - out "Welcome to the x2 calculator!" + out "Welcome to the x++ calculator!" out "-----" read "Please enter your first number: " a read "Please enter your second number: " b @@ -79,7 +79,7 @@ Now we can use the `cmp` operator to check what operator the user selected and a ```xt :: Main :main - out "Welcome to the x2 calculator!" + out "Welcome to the x++ calculator!" out "-----" read "Please enter your first number: " a read "Please enter your second number: " b @@ -105,7 +105,7 @@ Since you defined `c` as the answer to the equation, you can simply output it to ```xt :: Main :main - out "Welcome to the x2 calculator!" + out "Welcome to the x++ calculator!" out "-----" read "Please enter your first number: " a read "Please enter your second number: " b @@ -135,4 +135,4 @@ In the next lesson, you will be learning how to define and jump into another sec Last Updated: February 6th, 2022 by Dm123321_31mD -[↑ Go To Top](#x2--tutorials--4-calculator) \ No newline at end of file +[↑ Go To Top](#x--tutorials--4-calculator) \ No newline at end of file From 820035220f7cc4d6ec8645dbe19558c5a1d9da59 Mon Sep 17 00:00:00 2001 From: iiPython Date: Mon, 27 Mar 2023 15:30:00 -0500 Subject: [PATCH 05/15] Clean up source tree --- .gitignore | 10 +- python/DLLs/_asyncio.pyd | Bin 63864 -> 0 bytes python/DLLs/_bz2.pyd | Bin 83320 -> 0 bytes python/DLLs/_ctypes.pyd | Bin 123256 -> 0 bytes python/DLLs/_ctypes_test.pyd | Bin 34168 -> 0 bytes python/DLLs/_decimal.pyd | Bin 251768 -> 0 bytes python/DLLs/_elementtree.pyd | Bin 126848 -> 0 bytes python/DLLs/_hashlib.pyd | Bin 63864 -> 0 bytes python/DLLs/_lzma.pyd | Bin 157560 -> 0 bytes python/DLLs/_multiprocessing.pyd | Bin 33152 -> 0 bytes python/DLLs/_overlapped.pyd | Bin 49528 -> 0 bytes python/DLLs/_queue.pyd | Bin 31096 -> 0 bytes python/DLLs/_socket.pyd | Bin 78208 -> 0 bytes python/DLLs/_ssl.pyd | Bin 159616 -> 0 bytes python/DLLs/_uuid.pyd | Bin 23936 -> 0 bytes python/DLLs/_zoneinfo.pyd | Bin 43384 -> 0 bytes python/DLLs/libcrypto-1_1.dll | Bin 3441504 -> 0 bytes python/DLLs/libffi-8.dll | Bin 38232 -> 0 bytes python/DLLs/libssl-1_1.dll | Bin 702816 -> 0 bytes python/DLLs/pyexpat.pyd | Bin 198016 -> 0 bytes python/DLLs/python_lib.cat | Bin 162284 -> 0 bytes python/DLLs/python_tools.cat | Bin 27481 -> 0 bytes python/DLLs/select.pyd | Bin 29056 -> 0 bytes python/DLLs/unicodedata.pyd | Bin 1139576 -> 0 bytes python/LICENSE.txt | 650 -- python/Lib/__future__.py | 147 - python/Lib/__hello__.py | 16 - python/Lib/_aix_support.py | 91 - python/Lib/_bootsubprocess.py | 97 - python/Lib/_collections_abc.py | 1121 --- python/Lib/_compat_pickle.py | 252 - python/Lib/_compression.py | 162 - python/Lib/_markupbase.py | 396 - python/Lib/_osx_support.py | 574 -- python/Lib/_py_abc.py | 147 - python/Lib/_pydecimal.py | 6425 ----------------- python/Lib/_pyio.py | 2709 ------- python/Lib/_sitebuiltins.py | 103 - python/Lib/_strptime.py | 579 -- python/Lib/_threading_local.py | 242 - python/Lib/_weakrefset.py | 205 - python/Lib/abc.py | 188 - python/Lib/antigravity.py | 17 - python/Lib/argparse.py | 2621 ------- python/Lib/ast.py | 1736 ----- python/Lib/asyncio/__init__.py | 46 - python/Lib/asyncio/__main__.py | 125 - python/Lib/asyncio/base_events.py | 1944 ----- python/Lib/asyncio/base_futures.py | 68 - python/Lib/asyncio/base_subprocess.py | 288 - python/Lib/asyncio/base_tasks.py | 92 - python/Lib/asyncio/constants.py | 34 - python/Lib/asyncio/coroutines.py | 111 - python/Lib/asyncio/events.py | 857 --- python/Lib/asyncio/exceptions.py | 62 - python/Lib/asyncio/format_helpers.py | 76 - python/Lib/asyncio/futures.py | 428 -- python/Lib/asyncio/locks.py | 587 -- python/Lib/asyncio/log.py | 7 - python/Lib/asyncio/mixins.py | 21 - python/Lib/asyncio/proactor_events.py | 894 --- python/Lib/asyncio/protocols.py | 216 - python/Lib/asyncio/queues.py | 244 - python/Lib/asyncio/runners.py | 211 - python/Lib/asyncio/selector_events.py | 1242 ---- python/Lib/asyncio/sslproto.py | 921 --- python/Lib/asyncio/staggered.py | 149 - python/Lib/asyncio/streams.py | 746 -- python/Lib/asyncio/subprocess.py | 223 - python/Lib/asyncio/taskgroups.py | 218 - python/Lib/asyncio/tasks.py | 980 --- python/Lib/asyncio/threads.py | 25 - python/Lib/asyncio/timeouts.py | 151 - python/Lib/asyncio/transports.py | 335 - python/Lib/asyncio/trsock.py | 98 - python/Lib/asyncio/unix_events.py | 1477 ---- python/Lib/asyncio/windows_events.py | 939 --- python/Lib/asyncio/windows_utils.py | 173 - python/Lib/base64.py | 607 -- python/Lib/bdb.py | 890 --- python/Lib/bisect.py | 110 - python/Lib/bz2.py | 344 - python/Lib/cProfile.py | 190 - python/Lib/calendar.py | 768 -- python/Lib/cmd.py | 401 - python/Lib/code.py | 315 - python/Lib/codecs.py | 1127 --- python/Lib/codeop.py | 153 - python/Lib/collections/__init__.py | 1574 ---- python/Lib/collections/abc.py | 3 - python/Lib/colorsys.py | 166 - python/Lib/compileall.py | 463 -- python/Lib/concurrent/__init__.py | 1 - python/Lib/concurrent/futures/__init__.py | 53 - python/Lib/concurrent/futures/_base.py | 654 -- python/Lib/concurrent/futures/process.py | 836 --- python/Lib/concurrent/futures/thread.py | 236 - python/Lib/configparser.py | 1381 ---- python/Lib/contextlib.py | 776 -- python/Lib/contextvars.py | 4 - python/Lib/copy.py | 304 - python/Lib/copyreg.py | 223 - python/Lib/csv.py | 444 -- python/Lib/ctypes/__init__.py | 566 -- python/Lib/ctypes/_aix.py | 331 - python/Lib/ctypes/_endian.py | 78 - python/Lib/ctypes/macholib/README.ctypes | 7 - python/Lib/ctypes/macholib/__init__.py | 9 - python/Lib/ctypes/macholib/dyld.py | 165 - python/Lib/ctypes/macholib/dylib.py | 42 - python/Lib/ctypes/macholib/fetch_macholib | 2 - python/Lib/ctypes/macholib/fetch_macholib.bat | 1 - python/Lib/ctypes/macholib/framework.py | 42 - python/Lib/ctypes/test/__init__.py | 16 - python/Lib/ctypes/test/__main__.py | 4 - python/Lib/ctypes/test/test_anon.py | 73 - .../Lib/ctypes/test/test_array_in_pointer.py | 64 - python/Lib/ctypes/test/test_arrays.py | 238 - python/Lib/ctypes/test/test_as_parameter.py | 231 - python/Lib/ctypes/test/test_bitfields.py | 297 - python/Lib/ctypes/test/test_buffers.py | 73 - python/Lib/ctypes/test/test_bytes.py | 66 - python/Lib/ctypes/test/test_byteswap.py | 364 - python/Lib/ctypes/test/test_callbacks.py | 333 - python/Lib/ctypes/test/test_cast.py | 99 - python/Lib/ctypes/test/test_cfuncs.py | 218 - python/Lib/ctypes/test/test_checkretval.py | 36 - python/Lib/ctypes/test/test_delattr.py | 21 - python/Lib/ctypes/test/test_errno.py | 76 - python/Lib/ctypes/test/test_find.py | 127 - python/Lib/ctypes/test/test_frombuffer.py | 141 - python/Lib/ctypes/test/test_funcptr.py | 132 - python/Lib/ctypes/test/test_functions.py | 384 - python/Lib/ctypes/test/test_incomplete.py | 42 - python/Lib/ctypes/test/test_init.py | 40 - python/Lib/ctypes/test/test_internals.py | 100 - python/Lib/ctypes/test/test_keeprefs.py | 153 - python/Lib/ctypes/test/test_libc.py | 33 - python/Lib/ctypes/test/test_loading.py | 182 - python/Lib/ctypes/test/test_macholib.py | 110 - python/Lib/ctypes/test/test_memfunctions.py | 79 - python/Lib/ctypes/test/test_numbers.py | 295 - python/Lib/ctypes/test/test_objects.py | 67 - python/Lib/ctypes/test/test_parameters.py | 250 - python/Lib/ctypes/test/test_pep3118.py | 233 - python/Lib/ctypes/test/test_pickling.py | 81 - python/Lib/ctypes/test/test_pointers.py | 223 - python/Lib/ctypes/test/test_prototypes.py | 222 - python/Lib/ctypes/test/test_python_api.py | 85 - python/Lib/ctypes/test/test_random_things.py | 77 - python/Lib/ctypes/test/test_refcounts.py | 101 - python/Lib/ctypes/test/test_repr.py | 29 - python/Lib/ctypes/test/test_returnfuncptrs.py | 66 - .../Lib/ctypes/test/test_simplesubclasses.py | 55 - python/Lib/ctypes/test/test_sizes.py | 33 - python/Lib/ctypes/test/test_slicing.py | 167 - python/Lib/ctypes/test/test_stringptr.py | 77 - python/Lib/ctypes/test/test_strings.py | 145 - python/Lib/ctypes/test/test_struct_fields.py | 91 - python/Lib/ctypes/test/test_structures.py | 812 --- .../ctypes/test/test_unaligned_structures.py | 43 - python/Lib/ctypes/test/test_unicode.py | 64 - python/Lib/ctypes/test/test_values.py | 103 - python/Lib/ctypes/test/test_varsize_struct.py | 50 - python/Lib/ctypes/test/test_win32.py | 136 - python/Lib/ctypes/test/test_wintypes.py | 43 - python/Lib/ctypes/util.py | 376 - python/Lib/ctypes/wintypes.py | 202 - python/Lib/dataclasses.py | 1491 ---- python/Lib/datetime.py | 2639 ------- python/Lib/decimal.py | 11 - python/Lib/difflib.py | 2056 ------ python/Lib/dis.py | 775 -- python/Lib/distutils/README | 11 - python/Lib/distutils/__init__.py | 20 - python/Lib/distutils/_msvccompiler.py | 539 -- python/Lib/distutils/archive_util.py | 256 - python/Lib/distutils/bcppcompiler.py | 393 - python/Lib/distutils/ccompiler.py | 1116 --- python/Lib/distutils/cmd.py | 403 -- python/Lib/distutils/command/__init__.py | 30 - python/Lib/distutils/command/bdist.py | 138 - python/Lib/distutils/command/bdist_dumb.py | 123 - python/Lib/distutils/command/bdist_rpm.py | 579 -- python/Lib/distutils/command/build.py | 157 - python/Lib/distutils/command/build_clib.py | 209 - python/Lib/distutils/command/build_ext.py | 754 -- python/Lib/distutils/command/build_py.py | 416 -- python/Lib/distutils/command/build_scripts.py | 160 - python/Lib/distutils/command/check.py | 148 - python/Lib/distutils/command/clean.py | 76 - python/Lib/distutils/command/command_template | 33 - python/Lib/distutils/command/config.py | 344 - python/Lib/distutils/command/install.py | 679 -- python/Lib/distutils/command/install_data.py | 79 - .../Lib/distutils/command/install_egg_info.py | 77 - .../Lib/distutils/command/install_headers.py | 47 - python/Lib/distutils/command/install_lib.py | 217 - .../Lib/distutils/command/install_scripts.py | 60 - python/Lib/distutils/command/register.py | 304 - python/Lib/distutils/command/sdist.py | 494 -- python/Lib/distutils/command/upload.py | 215 - python/Lib/distutils/config.py | 133 - python/Lib/distutils/core.py | 234 - python/Lib/distutils/cygwinccompiler.py | 403 -- python/Lib/distutils/debug.py | 5 - python/Lib/distutils/dep_util.py | 92 - python/Lib/distutils/dir_util.py | 210 - python/Lib/distutils/dist.py | 1256 ---- python/Lib/distutils/errors.py | 97 - python/Lib/distutils/extension.py | 241 - python/Lib/distutils/fancy_getopt.py | 457 -- python/Lib/distutils/file_util.py | 238 - python/Lib/distutils/filelist.py | 327 - python/Lib/distutils/log.py | 77 - python/Lib/distutils/msvc9compiler.py | 788 -- python/Lib/distutils/msvccompiler.py | 642 -- python/Lib/distutils/spawn.py | 129 - python/Lib/distutils/sysconfig.py | 346 - python/Lib/distutils/tests/Setup.sample | 67 - python/Lib/distutils/tests/__init__.py | 41 - python/Lib/distutils/tests/includetest.rst | 1 - python/Lib/distutils/tests/support.py | 209 - .../Lib/distutils/tests/test_archive_util.py | 396 - python/Lib/distutils/tests/test_bdist.py | 52 - python/Lib/distutils/tests/test_bdist_dumb.py | 97 - python/Lib/distutils/tests/test_bdist_rpm.py | 141 - python/Lib/distutils/tests/test_build.py | 57 - python/Lib/distutils/tests/test_build_clib.py | 147 - python/Lib/distutils/tests/test_build_ext.py | 555 -- python/Lib/distutils/tests/test_build_py.py | 181 - .../Lib/distutils/tests/test_build_scripts.py | 112 - python/Lib/distutils/tests/test_check.py | 163 - python/Lib/distutils/tests/test_clean.py | 49 - python/Lib/distutils/tests/test_cmd.py | 126 - python/Lib/distutils/tests/test_config.py | 141 - python/Lib/distutils/tests/test_config_cmd.py | 103 - python/Lib/distutils/tests/test_core.py | 140 - .../distutils/tests/test_cygwinccompiler.py | 154 - python/Lib/distutils/tests/test_dep_util.py | 80 - python/Lib/distutils/tests/test_dir_util.py | 143 - python/Lib/distutils/tests/test_dist.py | 529 -- python/Lib/distutils/tests/test_extension.py | 70 - python/Lib/distutils/tests/test_file_util.py | 126 - python/Lib/distutils/tests/test_filelist.py | 340 - python/Lib/distutils/tests/test_install.py | 261 - .../Lib/distutils/tests/test_install_data.py | 75 - .../distutils/tests/test_install_headers.py | 39 - .../Lib/distutils/tests/test_install_lib.py | 117 - .../distutils/tests/test_install_scripts.py | 82 - python/Lib/distutils/tests/test_log.py | 46 - .../Lib/distutils/tests/test_msvc9compiler.py | 184 - .../Lib/distutils/tests/test_msvccompiler.py | 81 - python/Lib/distutils/tests/test_register.py | 324 - python/Lib/distutils/tests/test_sdist.py | 493 -- python/Lib/distutils/tests/test_spawn.py | 139 - python/Lib/distutils/tests/test_sysconfig.py | 264 - python/Lib/distutils/tests/test_text_file.py | 107 - .../Lib/distutils/tests/test_unixccompiler.py | 145 - python/Lib/distutils/tests/test_upload.py | 223 - python/Lib/distutils/tests/test_util.py | 313 - python/Lib/distutils/tests/test_version.py | 87 - .../distutils/tests/test_versionpredicate.py | 13 - python/Lib/distutils/text_file.py | 286 - python/Lib/distutils/unixccompiler.py | 329 - python/Lib/distutils/util.py | 562 -- python/Lib/distutils/version.py | 347 - python/Lib/distutils/versionpredicate.py | 166 - python/Lib/doctest.py | 2810 ------- python/Lib/encodings/__init__.py | 174 - python/Lib/encodings/aliases.py | 551 -- python/Lib/encodings/ascii.py | 50 - python/Lib/encodings/base64_codec.py | 55 - python/Lib/encodings/big5.py | 39 - python/Lib/encodings/big5hkscs.py | 39 - python/Lib/encodings/bz2_codec.py | 78 - python/Lib/encodings/charmap.py | 69 - python/Lib/encodings/cp037.py | 307 - python/Lib/encodings/cp1006.py | 307 - python/Lib/encodings/cp1026.py | 307 - python/Lib/encodings/cp1125.py | 698 -- python/Lib/encodings/cp1140.py | 307 - python/Lib/encodings/cp1250.py | 307 - python/Lib/encodings/cp1251.py | 307 - python/Lib/encodings/cp1252.py | 307 - python/Lib/encodings/cp1253.py | 307 - python/Lib/encodings/cp1254.py | 307 - python/Lib/encodings/cp1255.py | 307 - python/Lib/encodings/cp1256.py | 307 - python/Lib/encodings/cp1257.py | 307 - python/Lib/encodings/cp1258.py | 307 - python/Lib/encodings/cp273.py | 307 - python/Lib/encodings/cp424.py | 307 - python/Lib/encodings/cp437.py | 698 -- python/Lib/encodings/cp500.py | 307 - python/Lib/encodings/cp720.py | 309 - python/Lib/encodings/cp737.py | 698 -- python/Lib/encodings/cp775.py | 697 -- python/Lib/encodings/cp850.py | 698 -- python/Lib/encodings/cp852.py | 698 -- python/Lib/encodings/cp855.py | 698 -- python/Lib/encodings/cp856.py | 307 - python/Lib/encodings/cp857.py | 694 -- python/Lib/encodings/cp858.py | 698 -- python/Lib/encodings/cp860.py | 698 -- python/Lib/encodings/cp861.py | 698 -- python/Lib/encodings/cp862.py | 698 -- python/Lib/encodings/cp863.py | 698 -- python/Lib/encodings/cp864.py | 690 -- python/Lib/encodings/cp865.py | 698 -- python/Lib/encodings/cp866.py | 698 -- python/Lib/encodings/cp869.py | 689 -- python/Lib/encodings/cp874.py | 307 - python/Lib/encodings/cp875.py | 307 - python/Lib/encodings/cp932.py | 39 - python/Lib/encodings/cp949.py | 39 - python/Lib/encodings/cp950.py | 39 - python/Lib/encodings/euc_jis_2004.py | 39 - python/Lib/encodings/euc_jisx0213.py | 39 - python/Lib/encodings/euc_jp.py | 39 - python/Lib/encodings/euc_kr.py | 39 - python/Lib/encodings/gb18030.py | 39 - python/Lib/encodings/gb2312.py | 39 - python/Lib/encodings/gbk.py | 39 - python/Lib/encodings/hex_codec.py | 55 - python/Lib/encodings/hp_roman8.py | 314 - python/Lib/encodings/hz.py | 39 - python/Lib/encodings/idna.py | 307 - python/Lib/encodings/iso2022_jp.py | 39 - python/Lib/encodings/iso2022_jp_1.py | 39 - python/Lib/encodings/iso2022_jp_2.py | 39 - python/Lib/encodings/iso2022_jp_2004.py | 39 - python/Lib/encodings/iso2022_jp_3.py | 39 - python/Lib/encodings/iso2022_jp_ext.py | 39 - python/Lib/encodings/iso2022_kr.py | 39 - python/Lib/encodings/iso8859_1.py | 307 - python/Lib/encodings/iso8859_10.py | 307 - python/Lib/encodings/iso8859_11.py | 307 - python/Lib/encodings/iso8859_13.py | 307 - python/Lib/encodings/iso8859_14.py | 307 - python/Lib/encodings/iso8859_15.py | 307 - python/Lib/encodings/iso8859_16.py | 307 - python/Lib/encodings/iso8859_2.py | 307 - python/Lib/encodings/iso8859_3.py | 307 - python/Lib/encodings/iso8859_4.py | 307 - python/Lib/encodings/iso8859_5.py | 307 - python/Lib/encodings/iso8859_6.py | 307 - python/Lib/encodings/iso8859_7.py | 307 - python/Lib/encodings/iso8859_8.py | 307 - python/Lib/encodings/iso8859_9.py | 307 - python/Lib/encodings/johab.py | 39 - python/Lib/encodings/koi8_r.py | 307 - python/Lib/encodings/koi8_t.py | 308 - python/Lib/encodings/koi8_u.py | 307 - python/Lib/encodings/kz1048.py | 307 - python/Lib/encodings/latin_1.py | 50 - python/Lib/encodings/mac_arabic.py | 698 -- python/Lib/encodings/mac_croatian.py | 307 - python/Lib/encodings/mac_cyrillic.py | 307 - python/Lib/encodings/mac_farsi.py | 307 - python/Lib/encodings/mac_greek.py | 307 - python/Lib/encodings/mac_iceland.py | 307 - python/Lib/encodings/mac_latin2.py | 312 - python/Lib/encodings/mac_roman.py | 307 - python/Lib/encodings/mac_romanian.py | 307 - python/Lib/encodings/mac_turkish.py | 307 - python/Lib/encodings/mbcs.py | 47 - python/Lib/encodings/oem.py | 41 - python/Lib/encodings/palmos.py | 308 - python/Lib/encodings/ptcp154.py | 312 - python/Lib/encodings/punycode.py | 237 - python/Lib/encodings/quopri_codec.py | 56 - python/Lib/encodings/raw_unicode_escape.py | 46 - python/Lib/encodings/rot_13.py | 113 - python/Lib/encodings/shift_jis.py | 39 - python/Lib/encodings/shift_jis_2004.py | 39 - python/Lib/encodings/shift_jisx0213.py | 39 - python/Lib/encodings/tis_620.py | 307 - python/Lib/encodings/undefined.py | 49 - python/Lib/encodings/unicode_escape.py | 46 - python/Lib/encodings/utf_16.py | 155 - python/Lib/encodings/utf_16_be.py | 42 - python/Lib/encodings/utf_16_le.py | 42 - python/Lib/encodings/utf_32.py | 150 - python/Lib/encodings/utf_32_be.py | 37 - python/Lib/encodings/utf_32_le.py | 37 - python/Lib/encodings/utf_7.py | 38 - python/Lib/encodings/utf_8.py | 42 - python/Lib/encodings/utf_8_sig.py | 130 - python/Lib/encodings/uu_codec.py | 103 - python/Lib/encodings/zlib_codec.py | 77 - python/Lib/enum.py | 2039 ------ python/Lib/filecmp.py | 313 - python/Lib/fileinput.py | 442 -- python/Lib/fnmatch.py | 185 - python/Lib/fractions.py | 756 -- python/Lib/functools.py | 1012 --- python/Lib/genericpath.py | 155 - python/Lib/getopt.py | 215 - python/Lib/getpass.py | 185 - python/Lib/gettext.py | 634 -- python/Lib/glob.py | 251 - python/Lib/graphlib.py | 250 - python/Lib/gzip.py | 668 -- python/Lib/hashlib.py | 315 - python/Lib/heapq.py | 603 -- python/Lib/hmac.py | 219 - python/Lib/imaplib.py | 1649 ----- python/Lib/importlib/__init__.py | 176 - python/Lib/importlib/_abc.py | 54 - python/Lib/importlib/_bootstrap.py | 1367 ---- python/Lib/importlib/_bootstrap_external.py | 1754 ----- python/Lib/importlib/abc.py | 320 - python/Lib/importlib/machinery.py | 20 - python/Lib/importlib/metadata/__init__.py | 1088 --- python/Lib/importlib/metadata/_adapters.py | 68 - python/Lib/importlib/metadata/_collections.py | 30 - python/Lib/importlib/metadata/_functools.py | 104 - python/Lib/importlib/metadata/_itertools.py | 73 - python/Lib/importlib/metadata/_meta.py | 47 - python/Lib/importlib/metadata/_text.py | 99 - python/Lib/importlib/readers.py | 12 - python/Lib/importlib/resources/__init__.py | 36 - python/Lib/importlib/resources/_adapters.py | 170 - python/Lib/importlib/resources/_common.py | 107 - python/Lib/importlib/resources/_itertools.py | 35 - python/Lib/importlib/resources/_legacy.py | 121 - python/Lib/importlib/resources/abc.py | 151 - python/Lib/importlib/resources/readers.py | 122 - python/Lib/importlib/resources/simple.py | 125 - python/Lib/importlib/simple.py | 14 - python/Lib/importlib/util.py | 302 - python/Lib/inspect.py | 3341 --------- python/Lib/io.py | 114 - python/Lib/ipaddress.py | 2299 ------ python/Lib/json/__init__.py | 359 - python/Lib/json/decoder.py | 356 - python/Lib/json/encoder.py | 443 -- python/Lib/json/scanner.py | 73 - python/Lib/json/tool.py | 85 - python/Lib/keyword.py | 63 - python/Lib/linecache.py | 182 - python/Lib/locale.py | 1789 ----- python/Lib/logging/__init__.py | 2273 ------ python/Lib/logging/config.py | 948 --- python/Lib/logging/handlers.py | 1610 ----- python/Lib/lzma.py | 356 - python/Lib/mimetypes.py | 648 -- python/Lib/modulefinder.py | 666 -- python/Lib/multiprocessing/__init__.py | 37 - python/Lib/multiprocessing/connection.py | 972 --- python/Lib/multiprocessing/context.py | 376 - python/Lib/multiprocessing/dummy/__init__.py | 126 - .../Lib/multiprocessing/dummy/connection.py | 75 - python/Lib/multiprocessing/forkserver.py | 348 - python/Lib/multiprocessing/heap.py | 337 - python/Lib/multiprocessing/managers.py | 1381 ---- python/Lib/multiprocessing/pool.py | 957 --- python/Lib/multiprocessing/popen_fork.py | 83 - .../Lib/multiprocessing/popen_forkserver.py | 74 - .../Lib/multiprocessing/popen_spawn_posix.py | 72 - .../Lib/multiprocessing/popen_spawn_win32.py | 132 - python/Lib/multiprocessing/process.py | 439 -- python/Lib/multiprocessing/queues.py | 379 - python/Lib/multiprocessing/reduction.py | 281 - python/Lib/multiprocessing/resource_sharer.py | 154 - .../Lib/multiprocessing/resource_tracker.py | 239 - python/Lib/multiprocessing/shared_memory.py | 534 -- python/Lib/multiprocessing/sharedctypes.py | 240 - python/Lib/multiprocessing/spawn.py | 301 - python/Lib/multiprocessing/synchronize.py | 397 - python/Lib/multiprocessing/util.py | 491 -- python/Lib/netrc.py | 192 - python/Lib/ntpath.py | 849 --- python/Lib/nturl2path.py | 81 - python/Lib/numbers.py | 393 - python/Lib/opcode.py | 407 -- python/Lib/operator.py | 467 -- python/Lib/os.py | 1124 --- python/Lib/pathlib.py | 1406 ---- python/Lib/pdb.py | 1801 ----- python/Lib/pkgutil.py | 716 -- python/Lib/platform.py | 1323 ---- python/Lib/plistlib.py | 902 --- python/Lib/poplib.py | 483 -- python/Lib/posixpath.py | 562 -- python/Lib/profile.py | 610 -- python/Lib/pstats.py | 780 -- python/Lib/pty.py | 187 - python/Lib/py_compile.py | 212 - python/Lib/pyclbr.py | 314 - python/Lib/pydoc.py | 2840 -------- python/Lib/queue.py | 326 - python/Lib/quopri.py | 242 - python/Lib/random.py | 901 --- python/Lib/re/__init__.py | 374 - python/Lib/re/_casefix.py | 106 - python/Lib/re/_compiler.py | 763 -- python/Lib/re/_constants.py | 220 - python/Lib/re/_parser.py | 1100 --- python/Lib/reprlib.py | 167 - python/Lib/rlcompleter.py | 219 - python/Lib/runpy.py | 323 - python/Lib/sched.py | 167 - python/Lib/secrets.py | 72 - python/Lib/selectors.py | 618 -- python/Lib/shelve.py | 243 - python/Lib/shlex.py | 350 - python/Lib/shutil.py | 1519 ---- python/Lib/signal.py | 92 - python/Lib/site.py | 673 -- python/Lib/socket.py | 967 --- python/Lib/socketserver.py | 852 --- python/Lib/sre_compile.py | 7 - python/Lib/sre_constants.py | 7 - python/Lib/sre_parse.py | 7 - python/Lib/ssl.py | 1533 ---- python/Lib/stat.py | 195 - python/Lib/statistics.py | 1390 ---- python/Lib/string.py | 309 - python/Lib/stringprep.py | 272 - python/Lib/struct.py | 15 - python/Lib/subprocess.py | 2160 ------ python/Lib/symtable.py | 326 - python/Lib/sysconfig.py | 851 --- python/Lib/tabnanny.py | 331 - python/Lib/tarfile.py | 2618 ------- python/Lib/tempfile.py | 910 --- python/Lib/textwrap.py | 491 -- python/Lib/this.py | 28 - python/Lib/threading.py | 1661 ----- python/Lib/token.py | 137 - python/Lib/tokenize.py | 694 -- python/Lib/trace.py | 740 -- python/Lib/traceback.py | 980 --- python/Lib/tracemalloc.py | 560 -- python/Lib/types.py | 305 - python/Lib/typing.py | 3416 --------- python/Lib/uuid.py | 736 -- python/Lib/warnings.py | 580 -- python/Lib/weakref.py | 674 -- python/Lib/zipapp.py | 206 - python/Lib/zipfile.py | 2546 ------- python/Lib/zipimport.py | 778 -- python/Lib/zoneinfo/__init__.py | 31 - python/Lib/zoneinfo/_common.py | 164 - python/Lib/zoneinfo/_tzpath.py | 175 - python/Lib/zoneinfo/_zoneinfo.py | 752 -- python/include/Python.h | 109 - python/include/abstract.h | 873 --- python/include/bltinmodule.h | 14 - python/include/boolobject.h | 43 - python/include/bytearrayobject.h | 44 - python/include/bytesobject.h | 69 - python/include/ceval.h | 168 - python/include/codecs.h | 248 - python/include/compile.h | 25 - python/include/complexobject.h | 30 - python/include/cpython/abstract.h | 219 - python/include/cpython/bytearrayobject.h | 38 - python/include/cpython/bytesobject.h | 133 - python/include/cpython/cellobject.h | 31 - python/include/cpython/ceval.h | 26 - python/include/cpython/classobject.h | 57 - python/include/cpython/code.h | 236 - python/include/cpython/compile.h | 54 - python/include/cpython/complexobject.h | 44 - python/include/cpython/context.h | 78 - python/include/cpython/descrobject.h | 64 - python/include/cpython/dictobject.h | 78 - python/include/cpython/fileobject.h | 18 - python/include/cpython/fileutils.h | 8 - python/include/cpython/floatobject.h | 21 - python/include/cpython/frameobject.h | 29 - python/include/cpython/funcobject.h | 113 - python/include/cpython/genobject.h | 88 - python/include/cpython/import.h | 45 - python/include/cpython/initconfig.h | 257 - python/include/cpython/listobject.h | 51 - python/include/cpython/longintrepr.h | 93 - python/include/cpython/longobject.h | 95 - python/include/cpython/methodobject.h | 74 - python/include/cpython/modsupport.h | 107 - python/include/cpython/object.h | 511 -- python/include/cpython/objimpl.h | 89 - python/include/cpython/odictobject.h | 43 - python/include/cpython/picklebufobject.h | 31 - python/include/cpython/pthread_stubs.h | 88 - python/include/cpython/pyctype.h | 39 - python/include/cpython/pydebug.h | 38 - python/include/cpython/pyerrors.h | 179 - python/include/cpython/pyfpe.h | 15 - python/include/cpython/pyframe.h | 17 - python/include/cpython/pylifecycle.h | 65 - python/include/cpython/pymem.h | 98 - python/include/cpython/pystate.h | 366 - python/include/cpython/pythonrun.h | 121 - python/include/cpython/pythread.h | 42 - python/include/cpython/pytime.h | 323 - python/include/cpython/setobject.h | 67 - python/include/cpython/sysmodule.h | 16 - python/include/cpython/traceback.h | 16 - python/include/cpython/tupleobject.h | 43 - python/include/cpython/unicodeobject.h | 1153 --- python/include/cpython/warnings.h | 20 - python/include/cpython/weakrefobject.h | 58 - python/include/datetime.h | 267 - python/include/descrobject.h | 44 - python/include/dictobject.h | 97 - python/include/dynamic_annotations.h | 499 -- python/include/enumobject.h | 17 - python/include/errcode.h | 38 - python/include/exports.h | 30 - python/include/fileobject.h | 49 - python/include/fileutils.h | 26 - python/include/floatobject.h | 54 - python/include/frameobject.h | 20 - python/include/genericaliasobject.h | 14 - python/include/import.h | 98 - python/include/internal/pycore_abstract.h | 25 - python/include/internal/pycore_accu.h | 39 - python/include/internal/pycore_asdl.h | 112 - python/include/internal/pycore_ast.h | 866 --- python/include/internal/pycore_ast_state.h | 258 - python/include/internal/pycore_atomic.h | 557 -- python/include/internal/pycore_atomic_funcs.h | 94 - python/include/internal/pycore_bitutils.h | 186 - .../internal/pycore_blocks_output_buffer.h | 317 - .../include/internal/pycore_bytes_methods.h | 73 - python/include/internal/pycore_bytesobject.h | 52 - python/include/internal/pycore_call.h | 121 - python/include/internal/pycore_ceval.h | 138 - python/include/internal/pycore_code.h | 564 -- python/include/internal/pycore_compile.h | 44 - python/include/internal/pycore_condvar.h | 97 - python/include/internal/pycore_context.h | 67 - python/include/internal/pycore_dict.h | 178 - python/include/internal/pycore_dtoa.h | 28 - .../internal/pycore_emscripten_signal.h | 25 - python/include/internal/pycore_exceptions.h | 37 - python/include/internal/pycore_fileutils.h | 275 - python/include/internal/pycore_floatobject.h | 59 - python/include/internal/pycore_format.h | 29 - python/include/internal/pycore_frame.h | 237 - python/include/internal/pycore_function.h | 18 - python/include/internal/pycore_gc.h | 183 - python/include/internal/pycore_genobject.h | 49 - python/include/internal/pycore_getopt.h | 22 - python/include/internal/pycore_gil.h | 50 - .../include/internal/pycore_global_objects.h | 54 - .../include/internal/pycore_global_strings.h | 395 - python/include/internal/pycore_hamt.h | 131 - python/include/internal/pycore_hashtable.h | 148 - python/include/internal/pycore_import.h | 27 - python/include/internal/pycore_initconfig.h | 183 - python/include/internal/pycore_interp.h | 227 - .../internal/pycore_interpreteridobject.h | 22 - python/include/internal/pycore_list.h | 62 - python/include/internal/pycore_long.h | 114 - python/include/internal/pycore_moduleobject.h | 42 - python/include/internal/pycore_namespace.h | 20 - python/include/internal/pycore_object.h | 310 - python/include/internal/pycore_opcode.h | 581 -- python/include/internal/pycore_parser.h | 31 - python/include/internal/pycore_pathconfig.h | 24 - python/include/internal/pycore_pyarena.h | 64 - python/include/internal/pycore_pyerrors.h | 106 - python/include/internal/pycore_pyhash.h | 10 - python/include/internal/pycore_pylifecycle.h | 103 - python/include/internal/pycore_pymath.h | 224 - python/include/internal/pycore_pymem.h | 114 - python/include/internal/pycore_pystate.h | 167 - python/include/internal/pycore_runtime.h | 181 - python/include/internal/pycore_runtime_init.h | 1256 ---- python/include/internal/pycore_signal.h | 35 - python/include/internal/pycore_sliceobject.h | 20 - python/include/internal/pycore_strhex.h | 36 - python/include/internal/pycore_structseq.h | 28 - python/include/internal/pycore_symtable.h | 134 - python/include/internal/pycore_sysmodule.h | 26 - python/include/internal/pycore_traceback.h | 101 - python/include/internal/pycore_tuple.h | 73 - python/include/internal/pycore_typeobject.h | 50 - python/include/internal/pycore_ucnhash.h | 34 - .../include/internal/pycore_unicodeobject.h | 62 - python/include/internal/pycore_unionobject.h | 23 - python/include/internal/pycore_warnings.h | 29 - python/include/intrcheck.h | 30 - python/include/iterobject.h | 27 - python/include/listobject.h | 52 - python/include/longobject.h | 91 - python/include/marshal.h | 31 - python/include/memoryobject.h | 72 - python/include/methodobject.h | 132 - python/include/modsupport.h | 168 - python/include/moduleobject.h | 95 - python/include/object.h | 797 -- python/include/objimpl.h | 215 - python/include/opcode.h | 236 - python/include/osdefs.h | 51 - python/include/osmodule.h | 17 - python/include/patchlevel.h | 35 - python/include/py_curses.h | 99 - python/include/pybuffer.h | 142 - python/include/pycapsule.h | 59 - python/include/pyconfig.h | 710 -- python/include/pydtrace.h | 59 - python/include/pyerrors.h | 331 - python/include/pyexpat.h | 55 - python/include/pyframe.h | 26 - python/include/pyhash.h | 144 - python/include/pylifecycle.h | 78 - python/include/pymacconfig.h | 102 - python/include/pymacro.h | 155 - python/include/pymath.h | 65 - python/include/pymem.h | 104 - python/include/pyport.h | 742 -- python/include/pystate.h | 132 - python/include/pystrcmp.h | 23 - python/include/pystrtod.h | 46 - python/include/pythonrun.h | 45 - python/include/pythread.h | 133 - python/include/pytypedefs.h | 30 - python/include/rangeobject.h | 27 - python/include/setobject.h | 49 - python/include/sliceobject.h | 65 - python/include/structmember.h | 75 - python/include/structseq.h | 49 - python/include/sysmodule.h | 41 - python/include/token.h | 97 - python/include/traceback.h | 26 - python/include/tracemalloc.h | 38 - python/include/tupleobject.h | 46 - python/include/typeslots.h | 88 - python/include/unicodeobject.h | 1049 --- python/include/warnings.h | 45 - python/include/weakrefobject.h | 42 - python/libs/python3.lib | Bin 183544 -> 0 bytes python/libs/python311.lib | Bin 360148 -> 0 bytes python/python.exe | Bin 101752 -> 0 bytes python/python3.dll | Bin 65912 -> 0 bytes python/python311.dll | Bin 5761912 -> 0 bytes python/vcruntime140.dll | Bin 109392 -> 0 bytes python/vcruntime140_1.dll | Bin 49488 -> 0 bytes scripts/assets/x2.ico | Bin 4286 -> 0 bytes scripts/build.py | 59 - scripts/installer.py | 291 - 747 files changed, 1 insertion(+), 237054 deletions(-) delete mode 100644 python/DLLs/_asyncio.pyd delete mode 100644 python/DLLs/_bz2.pyd delete mode 100644 python/DLLs/_ctypes.pyd delete mode 100644 python/DLLs/_ctypes_test.pyd delete mode 100644 python/DLLs/_decimal.pyd delete mode 100644 python/DLLs/_elementtree.pyd delete mode 100644 python/DLLs/_hashlib.pyd delete mode 100644 python/DLLs/_lzma.pyd delete mode 100644 python/DLLs/_multiprocessing.pyd delete mode 100644 python/DLLs/_overlapped.pyd delete mode 100644 python/DLLs/_queue.pyd delete mode 100644 python/DLLs/_socket.pyd delete mode 100644 python/DLLs/_ssl.pyd delete mode 100644 python/DLLs/_uuid.pyd delete mode 100644 python/DLLs/_zoneinfo.pyd delete mode 100644 python/DLLs/libcrypto-1_1.dll delete mode 100644 python/DLLs/libffi-8.dll delete mode 100644 python/DLLs/libssl-1_1.dll delete mode 100644 python/DLLs/pyexpat.pyd delete mode 100644 python/DLLs/python_lib.cat delete mode 100644 python/DLLs/python_tools.cat delete mode 100644 python/DLLs/select.pyd delete mode 100644 python/DLLs/unicodedata.pyd delete mode 100644 python/LICENSE.txt delete mode 100644 python/Lib/__future__.py delete mode 100644 python/Lib/__hello__.py delete mode 100644 python/Lib/_aix_support.py delete mode 100644 python/Lib/_bootsubprocess.py delete mode 100644 python/Lib/_collections_abc.py delete mode 100644 python/Lib/_compat_pickle.py delete mode 100644 python/Lib/_compression.py delete mode 100644 python/Lib/_markupbase.py delete mode 100644 python/Lib/_osx_support.py delete mode 100644 python/Lib/_py_abc.py delete mode 100644 python/Lib/_pydecimal.py delete mode 100644 python/Lib/_pyio.py delete mode 100644 python/Lib/_sitebuiltins.py delete mode 100644 python/Lib/_strptime.py delete mode 100644 python/Lib/_threading_local.py delete mode 100644 python/Lib/_weakrefset.py delete mode 100644 python/Lib/abc.py delete mode 100644 python/Lib/antigravity.py delete mode 100644 python/Lib/argparse.py delete mode 100644 python/Lib/ast.py delete mode 100644 python/Lib/asyncio/__init__.py delete mode 100644 python/Lib/asyncio/__main__.py delete mode 100644 python/Lib/asyncio/base_events.py delete mode 100644 python/Lib/asyncio/base_futures.py delete mode 100644 python/Lib/asyncio/base_subprocess.py delete mode 100644 python/Lib/asyncio/base_tasks.py delete mode 100644 python/Lib/asyncio/constants.py delete mode 100644 python/Lib/asyncio/coroutines.py delete mode 100644 python/Lib/asyncio/events.py delete mode 100644 python/Lib/asyncio/exceptions.py delete mode 100644 python/Lib/asyncio/format_helpers.py delete mode 100644 python/Lib/asyncio/futures.py delete mode 100644 python/Lib/asyncio/locks.py delete mode 100644 python/Lib/asyncio/log.py delete mode 100644 python/Lib/asyncio/mixins.py delete mode 100644 python/Lib/asyncio/proactor_events.py delete mode 100644 python/Lib/asyncio/protocols.py delete mode 100644 python/Lib/asyncio/queues.py delete mode 100644 python/Lib/asyncio/runners.py delete mode 100644 python/Lib/asyncio/selector_events.py delete mode 100644 python/Lib/asyncio/sslproto.py delete mode 100644 python/Lib/asyncio/staggered.py delete mode 100644 python/Lib/asyncio/streams.py delete mode 100644 python/Lib/asyncio/subprocess.py delete mode 100644 python/Lib/asyncio/taskgroups.py delete mode 100644 python/Lib/asyncio/tasks.py delete mode 100644 python/Lib/asyncio/threads.py delete mode 100644 python/Lib/asyncio/timeouts.py delete mode 100644 python/Lib/asyncio/transports.py delete mode 100644 python/Lib/asyncio/trsock.py delete mode 100644 python/Lib/asyncio/unix_events.py delete mode 100644 python/Lib/asyncio/windows_events.py delete mode 100644 python/Lib/asyncio/windows_utils.py delete mode 100644 python/Lib/base64.py delete mode 100644 python/Lib/bdb.py delete mode 100644 python/Lib/bisect.py delete mode 100644 python/Lib/bz2.py delete mode 100644 python/Lib/cProfile.py delete mode 100644 python/Lib/calendar.py delete mode 100644 python/Lib/cmd.py delete mode 100644 python/Lib/code.py delete mode 100644 python/Lib/codecs.py delete mode 100644 python/Lib/codeop.py delete mode 100644 python/Lib/collections/__init__.py delete mode 100644 python/Lib/collections/abc.py delete mode 100644 python/Lib/colorsys.py delete mode 100644 python/Lib/compileall.py delete mode 100644 python/Lib/concurrent/__init__.py delete mode 100644 python/Lib/concurrent/futures/__init__.py delete mode 100644 python/Lib/concurrent/futures/_base.py delete mode 100644 python/Lib/concurrent/futures/process.py delete mode 100644 python/Lib/concurrent/futures/thread.py delete mode 100644 python/Lib/configparser.py delete mode 100644 python/Lib/contextlib.py delete mode 100644 python/Lib/contextvars.py delete mode 100644 python/Lib/copy.py delete mode 100644 python/Lib/copyreg.py delete mode 100644 python/Lib/csv.py delete mode 100644 python/Lib/ctypes/__init__.py delete mode 100644 python/Lib/ctypes/_aix.py delete mode 100644 python/Lib/ctypes/_endian.py delete mode 100644 python/Lib/ctypes/macholib/README.ctypes delete mode 100644 python/Lib/ctypes/macholib/__init__.py delete mode 100644 python/Lib/ctypes/macholib/dyld.py delete mode 100644 python/Lib/ctypes/macholib/dylib.py delete mode 100644 python/Lib/ctypes/macholib/fetch_macholib delete mode 100644 python/Lib/ctypes/macholib/fetch_macholib.bat delete mode 100644 python/Lib/ctypes/macholib/framework.py delete mode 100644 python/Lib/ctypes/test/__init__.py delete mode 100644 python/Lib/ctypes/test/__main__.py delete mode 100644 python/Lib/ctypes/test/test_anon.py delete mode 100644 python/Lib/ctypes/test/test_array_in_pointer.py delete mode 100644 python/Lib/ctypes/test/test_arrays.py delete mode 100644 python/Lib/ctypes/test/test_as_parameter.py delete mode 100644 python/Lib/ctypes/test/test_bitfields.py delete mode 100644 python/Lib/ctypes/test/test_buffers.py delete mode 100644 python/Lib/ctypes/test/test_bytes.py delete mode 100644 python/Lib/ctypes/test/test_byteswap.py delete mode 100644 python/Lib/ctypes/test/test_callbacks.py delete mode 100644 python/Lib/ctypes/test/test_cast.py delete mode 100644 python/Lib/ctypes/test/test_cfuncs.py delete mode 100644 python/Lib/ctypes/test/test_checkretval.py delete mode 100644 python/Lib/ctypes/test/test_delattr.py delete mode 100644 python/Lib/ctypes/test/test_errno.py delete mode 100644 python/Lib/ctypes/test/test_find.py delete mode 100644 python/Lib/ctypes/test/test_frombuffer.py delete mode 100644 python/Lib/ctypes/test/test_funcptr.py delete mode 100644 python/Lib/ctypes/test/test_functions.py delete mode 100644 python/Lib/ctypes/test/test_incomplete.py delete mode 100644 python/Lib/ctypes/test/test_init.py delete mode 100644 python/Lib/ctypes/test/test_internals.py delete mode 100644 python/Lib/ctypes/test/test_keeprefs.py delete mode 100644 python/Lib/ctypes/test/test_libc.py delete mode 100644 python/Lib/ctypes/test/test_loading.py delete mode 100644 python/Lib/ctypes/test/test_macholib.py delete mode 100644 python/Lib/ctypes/test/test_memfunctions.py delete mode 100644 python/Lib/ctypes/test/test_numbers.py delete mode 100644 python/Lib/ctypes/test/test_objects.py delete mode 100644 python/Lib/ctypes/test/test_parameters.py delete mode 100644 python/Lib/ctypes/test/test_pep3118.py delete mode 100644 python/Lib/ctypes/test/test_pickling.py delete mode 100644 python/Lib/ctypes/test/test_pointers.py delete mode 100644 python/Lib/ctypes/test/test_prototypes.py delete mode 100644 python/Lib/ctypes/test/test_python_api.py delete mode 100644 python/Lib/ctypes/test/test_random_things.py delete mode 100644 python/Lib/ctypes/test/test_refcounts.py delete mode 100644 python/Lib/ctypes/test/test_repr.py delete mode 100644 python/Lib/ctypes/test/test_returnfuncptrs.py delete mode 100644 python/Lib/ctypes/test/test_simplesubclasses.py delete mode 100644 python/Lib/ctypes/test/test_sizes.py delete mode 100644 python/Lib/ctypes/test/test_slicing.py delete mode 100644 python/Lib/ctypes/test/test_stringptr.py delete mode 100644 python/Lib/ctypes/test/test_strings.py delete mode 100644 python/Lib/ctypes/test/test_struct_fields.py delete mode 100644 python/Lib/ctypes/test/test_structures.py delete mode 100644 python/Lib/ctypes/test/test_unaligned_structures.py delete mode 100644 python/Lib/ctypes/test/test_unicode.py delete mode 100644 python/Lib/ctypes/test/test_values.py delete mode 100644 python/Lib/ctypes/test/test_varsize_struct.py delete mode 100644 python/Lib/ctypes/test/test_win32.py delete mode 100644 python/Lib/ctypes/test/test_wintypes.py delete mode 100644 python/Lib/ctypes/util.py delete mode 100644 python/Lib/ctypes/wintypes.py delete mode 100644 python/Lib/dataclasses.py delete mode 100644 python/Lib/datetime.py delete mode 100644 python/Lib/decimal.py delete mode 100644 python/Lib/difflib.py delete mode 100644 python/Lib/dis.py delete mode 100644 python/Lib/distutils/README delete mode 100644 python/Lib/distutils/__init__.py delete mode 100644 python/Lib/distutils/_msvccompiler.py delete mode 100644 python/Lib/distutils/archive_util.py delete mode 100644 python/Lib/distutils/bcppcompiler.py delete mode 100644 python/Lib/distutils/ccompiler.py delete mode 100644 python/Lib/distutils/cmd.py delete mode 100644 python/Lib/distutils/command/__init__.py delete mode 100644 python/Lib/distutils/command/bdist.py delete mode 100644 python/Lib/distutils/command/bdist_dumb.py delete mode 100644 python/Lib/distutils/command/bdist_rpm.py delete mode 100644 python/Lib/distutils/command/build.py delete mode 100644 python/Lib/distutils/command/build_clib.py delete mode 100644 python/Lib/distutils/command/build_ext.py delete mode 100644 python/Lib/distutils/command/build_py.py delete mode 100644 python/Lib/distutils/command/build_scripts.py delete mode 100644 python/Lib/distutils/command/check.py delete mode 100644 python/Lib/distutils/command/clean.py delete mode 100644 python/Lib/distutils/command/command_template delete mode 100644 python/Lib/distutils/command/config.py delete mode 100644 python/Lib/distutils/command/install.py delete mode 100644 python/Lib/distutils/command/install_data.py delete mode 100644 python/Lib/distutils/command/install_egg_info.py delete mode 100644 python/Lib/distutils/command/install_headers.py delete mode 100644 python/Lib/distutils/command/install_lib.py delete mode 100644 python/Lib/distutils/command/install_scripts.py delete mode 100644 python/Lib/distutils/command/register.py delete mode 100644 python/Lib/distutils/command/sdist.py delete mode 100644 python/Lib/distutils/command/upload.py delete mode 100644 python/Lib/distutils/config.py delete mode 100644 python/Lib/distutils/core.py delete mode 100644 python/Lib/distutils/cygwinccompiler.py delete mode 100644 python/Lib/distutils/debug.py delete mode 100644 python/Lib/distutils/dep_util.py delete mode 100644 python/Lib/distutils/dir_util.py delete mode 100644 python/Lib/distutils/dist.py delete mode 100644 python/Lib/distutils/errors.py delete mode 100644 python/Lib/distutils/extension.py delete mode 100644 python/Lib/distutils/fancy_getopt.py delete mode 100644 python/Lib/distutils/file_util.py delete mode 100644 python/Lib/distutils/filelist.py delete mode 100644 python/Lib/distutils/log.py delete mode 100644 python/Lib/distutils/msvc9compiler.py delete mode 100644 python/Lib/distutils/msvccompiler.py delete mode 100644 python/Lib/distutils/spawn.py delete mode 100644 python/Lib/distutils/sysconfig.py delete mode 100644 python/Lib/distutils/tests/Setup.sample delete mode 100644 python/Lib/distutils/tests/__init__.py delete mode 100644 python/Lib/distutils/tests/includetest.rst delete mode 100644 python/Lib/distutils/tests/support.py delete mode 100644 python/Lib/distutils/tests/test_archive_util.py delete mode 100644 python/Lib/distutils/tests/test_bdist.py delete mode 100644 python/Lib/distutils/tests/test_bdist_dumb.py delete mode 100644 python/Lib/distutils/tests/test_bdist_rpm.py delete mode 100644 python/Lib/distutils/tests/test_build.py delete mode 100644 python/Lib/distutils/tests/test_build_clib.py delete mode 100644 python/Lib/distutils/tests/test_build_ext.py delete mode 100644 python/Lib/distutils/tests/test_build_py.py delete mode 100644 python/Lib/distutils/tests/test_build_scripts.py delete mode 100644 python/Lib/distutils/tests/test_check.py delete mode 100644 python/Lib/distutils/tests/test_clean.py delete mode 100644 python/Lib/distutils/tests/test_cmd.py delete mode 100644 python/Lib/distutils/tests/test_config.py delete mode 100644 python/Lib/distutils/tests/test_config_cmd.py delete mode 100644 python/Lib/distutils/tests/test_core.py delete mode 100644 python/Lib/distutils/tests/test_cygwinccompiler.py delete mode 100644 python/Lib/distutils/tests/test_dep_util.py delete mode 100644 python/Lib/distutils/tests/test_dir_util.py delete mode 100644 python/Lib/distutils/tests/test_dist.py delete mode 100644 python/Lib/distutils/tests/test_extension.py delete mode 100644 python/Lib/distutils/tests/test_file_util.py delete mode 100644 python/Lib/distutils/tests/test_filelist.py delete mode 100644 python/Lib/distutils/tests/test_install.py delete mode 100644 python/Lib/distutils/tests/test_install_data.py delete mode 100644 python/Lib/distutils/tests/test_install_headers.py delete mode 100644 python/Lib/distutils/tests/test_install_lib.py delete mode 100644 python/Lib/distutils/tests/test_install_scripts.py delete mode 100644 python/Lib/distutils/tests/test_log.py delete mode 100644 python/Lib/distutils/tests/test_msvc9compiler.py delete mode 100644 python/Lib/distutils/tests/test_msvccompiler.py delete mode 100644 python/Lib/distutils/tests/test_register.py delete mode 100644 python/Lib/distutils/tests/test_sdist.py delete mode 100644 python/Lib/distutils/tests/test_spawn.py delete mode 100644 python/Lib/distutils/tests/test_sysconfig.py delete mode 100644 python/Lib/distutils/tests/test_text_file.py delete mode 100644 python/Lib/distutils/tests/test_unixccompiler.py delete mode 100644 python/Lib/distutils/tests/test_upload.py delete mode 100644 python/Lib/distutils/tests/test_util.py delete mode 100644 python/Lib/distutils/tests/test_version.py delete mode 100644 python/Lib/distutils/tests/test_versionpredicate.py delete mode 100644 python/Lib/distutils/text_file.py delete mode 100644 python/Lib/distutils/unixccompiler.py delete mode 100644 python/Lib/distutils/util.py delete mode 100644 python/Lib/distutils/version.py delete mode 100644 python/Lib/distutils/versionpredicate.py delete mode 100644 python/Lib/doctest.py delete mode 100644 python/Lib/encodings/__init__.py delete mode 100644 python/Lib/encodings/aliases.py delete mode 100644 python/Lib/encodings/ascii.py delete mode 100644 python/Lib/encodings/base64_codec.py delete mode 100644 python/Lib/encodings/big5.py delete mode 100644 python/Lib/encodings/big5hkscs.py delete mode 100644 python/Lib/encodings/bz2_codec.py delete mode 100644 python/Lib/encodings/charmap.py delete mode 100644 python/Lib/encodings/cp037.py delete mode 100644 python/Lib/encodings/cp1006.py delete mode 100644 python/Lib/encodings/cp1026.py delete mode 100644 python/Lib/encodings/cp1125.py delete mode 100644 python/Lib/encodings/cp1140.py delete mode 100644 python/Lib/encodings/cp1250.py delete mode 100644 python/Lib/encodings/cp1251.py delete mode 100644 python/Lib/encodings/cp1252.py delete mode 100644 python/Lib/encodings/cp1253.py delete mode 100644 python/Lib/encodings/cp1254.py delete mode 100644 python/Lib/encodings/cp1255.py delete mode 100644 python/Lib/encodings/cp1256.py delete mode 100644 python/Lib/encodings/cp1257.py delete mode 100644 python/Lib/encodings/cp1258.py delete mode 100644 python/Lib/encodings/cp273.py delete mode 100644 python/Lib/encodings/cp424.py delete mode 100644 python/Lib/encodings/cp437.py delete mode 100644 python/Lib/encodings/cp500.py delete mode 100644 python/Lib/encodings/cp720.py delete mode 100644 python/Lib/encodings/cp737.py delete mode 100644 python/Lib/encodings/cp775.py delete mode 100644 python/Lib/encodings/cp850.py delete mode 100644 python/Lib/encodings/cp852.py delete mode 100644 python/Lib/encodings/cp855.py delete mode 100644 python/Lib/encodings/cp856.py delete mode 100644 python/Lib/encodings/cp857.py delete mode 100644 python/Lib/encodings/cp858.py delete mode 100644 python/Lib/encodings/cp860.py delete mode 100644 python/Lib/encodings/cp861.py delete mode 100644 python/Lib/encodings/cp862.py delete mode 100644 python/Lib/encodings/cp863.py delete mode 100644 python/Lib/encodings/cp864.py delete mode 100644 python/Lib/encodings/cp865.py delete mode 100644 python/Lib/encodings/cp866.py delete mode 100644 python/Lib/encodings/cp869.py delete mode 100644 python/Lib/encodings/cp874.py delete mode 100644 python/Lib/encodings/cp875.py delete mode 100644 python/Lib/encodings/cp932.py delete mode 100644 python/Lib/encodings/cp949.py delete mode 100644 python/Lib/encodings/cp950.py delete mode 100644 python/Lib/encodings/euc_jis_2004.py delete mode 100644 python/Lib/encodings/euc_jisx0213.py delete mode 100644 python/Lib/encodings/euc_jp.py delete mode 100644 python/Lib/encodings/euc_kr.py delete mode 100644 python/Lib/encodings/gb18030.py delete mode 100644 python/Lib/encodings/gb2312.py delete mode 100644 python/Lib/encodings/gbk.py delete mode 100644 python/Lib/encodings/hex_codec.py delete mode 100644 python/Lib/encodings/hp_roman8.py delete mode 100644 python/Lib/encodings/hz.py delete mode 100644 python/Lib/encodings/idna.py delete mode 100644 python/Lib/encodings/iso2022_jp.py delete mode 100644 python/Lib/encodings/iso2022_jp_1.py delete mode 100644 python/Lib/encodings/iso2022_jp_2.py delete mode 100644 python/Lib/encodings/iso2022_jp_2004.py delete mode 100644 python/Lib/encodings/iso2022_jp_3.py delete mode 100644 python/Lib/encodings/iso2022_jp_ext.py delete mode 100644 python/Lib/encodings/iso2022_kr.py delete mode 100644 python/Lib/encodings/iso8859_1.py delete mode 100644 python/Lib/encodings/iso8859_10.py delete mode 100644 python/Lib/encodings/iso8859_11.py delete mode 100644 python/Lib/encodings/iso8859_13.py delete mode 100644 python/Lib/encodings/iso8859_14.py delete mode 100644 python/Lib/encodings/iso8859_15.py delete mode 100644 python/Lib/encodings/iso8859_16.py delete mode 100644 python/Lib/encodings/iso8859_2.py delete mode 100644 python/Lib/encodings/iso8859_3.py delete mode 100644 python/Lib/encodings/iso8859_4.py delete mode 100644 python/Lib/encodings/iso8859_5.py delete mode 100644 python/Lib/encodings/iso8859_6.py delete mode 100644 python/Lib/encodings/iso8859_7.py delete mode 100644 python/Lib/encodings/iso8859_8.py delete mode 100644 python/Lib/encodings/iso8859_9.py delete mode 100644 python/Lib/encodings/johab.py delete mode 100644 python/Lib/encodings/koi8_r.py delete mode 100644 python/Lib/encodings/koi8_t.py delete mode 100644 python/Lib/encodings/koi8_u.py delete mode 100644 python/Lib/encodings/kz1048.py delete mode 100644 python/Lib/encodings/latin_1.py delete mode 100644 python/Lib/encodings/mac_arabic.py delete mode 100644 python/Lib/encodings/mac_croatian.py delete mode 100644 python/Lib/encodings/mac_cyrillic.py delete mode 100644 python/Lib/encodings/mac_farsi.py delete mode 100644 python/Lib/encodings/mac_greek.py delete mode 100644 python/Lib/encodings/mac_iceland.py delete mode 100644 python/Lib/encodings/mac_latin2.py delete mode 100644 python/Lib/encodings/mac_roman.py delete mode 100644 python/Lib/encodings/mac_romanian.py delete mode 100644 python/Lib/encodings/mac_turkish.py delete mode 100644 python/Lib/encodings/mbcs.py delete mode 100644 python/Lib/encodings/oem.py delete mode 100644 python/Lib/encodings/palmos.py delete mode 100644 python/Lib/encodings/ptcp154.py delete mode 100644 python/Lib/encodings/punycode.py delete mode 100644 python/Lib/encodings/quopri_codec.py delete mode 100644 python/Lib/encodings/raw_unicode_escape.py delete mode 100644 python/Lib/encodings/rot_13.py delete mode 100644 python/Lib/encodings/shift_jis.py delete mode 100644 python/Lib/encodings/shift_jis_2004.py delete mode 100644 python/Lib/encodings/shift_jisx0213.py delete mode 100644 python/Lib/encodings/tis_620.py delete mode 100644 python/Lib/encodings/undefined.py delete mode 100644 python/Lib/encodings/unicode_escape.py delete mode 100644 python/Lib/encodings/utf_16.py delete mode 100644 python/Lib/encodings/utf_16_be.py delete mode 100644 python/Lib/encodings/utf_16_le.py delete mode 100644 python/Lib/encodings/utf_32.py delete mode 100644 python/Lib/encodings/utf_32_be.py delete mode 100644 python/Lib/encodings/utf_32_le.py delete mode 100644 python/Lib/encodings/utf_7.py delete mode 100644 python/Lib/encodings/utf_8.py delete mode 100644 python/Lib/encodings/utf_8_sig.py delete mode 100644 python/Lib/encodings/uu_codec.py delete mode 100644 python/Lib/encodings/zlib_codec.py delete mode 100644 python/Lib/enum.py delete mode 100644 python/Lib/filecmp.py delete mode 100644 python/Lib/fileinput.py delete mode 100644 python/Lib/fnmatch.py delete mode 100644 python/Lib/fractions.py delete mode 100644 python/Lib/functools.py delete mode 100644 python/Lib/genericpath.py delete mode 100644 python/Lib/getopt.py delete mode 100644 python/Lib/getpass.py delete mode 100644 python/Lib/gettext.py delete mode 100644 python/Lib/glob.py delete mode 100644 python/Lib/graphlib.py delete mode 100644 python/Lib/gzip.py delete mode 100644 python/Lib/hashlib.py delete mode 100644 python/Lib/heapq.py delete mode 100644 python/Lib/hmac.py delete mode 100644 python/Lib/imaplib.py delete mode 100644 python/Lib/importlib/__init__.py delete mode 100644 python/Lib/importlib/_abc.py delete mode 100644 python/Lib/importlib/_bootstrap.py delete mode 100644 python/Lib/importlib/_bootstrap_external.py delete mode 100644 python/Lib/importlib/abc.py delete mode 100644 python/Lib/importlib/machinery.py delete mode 100644 python/Lib/importlib/metadata/__init__.py delete mode 100644 python/Lib/importlib/metadata/_adapters.py delete mode 100644 python/Lib/importlib/metadata/_collections.py delete mode 100644 python/Lib/importlib/metadata/_functools.py delete mode 100644 python/Lib/importlib/metadata/_itertools.py delete mode 100644 python/Lib/importlib/metadata/_meta.py delete mode 100644 python/Lib/importlib/metadata/_text.py delete mode 100644 python/Lib/importlib/readers.py delete mode 100644 python/Lib/importlib/resources/__init__.py delete mode 100644 python/Lib/importlib/resources/_adapters.py delete mode 100644 python/Lib/importlib/resources/_common.py delete mode 100644 python/Lib/importlib/resources/_itertools.py delete mode 100644 python/Lib/importlib/resources/_legacy.py delete mode 100644 python/Lib/importlib/resources/abc.py delete mode 100644 python/Lib/importlib/resources/readers.py delete mode 100644 python/Lib/importlib/resources/simple.py delete mode 100644 python/Lib/importlib/simple.py delete mode 100644 python/Lib/importlib/util.py delete mode 100644 python/Lib/inspect.py delete mode 100644 python/Lib/io.py delete mode 100644 python/Lib/ipaddress.py delete mode 100644 python/Lib/json/__init__.py delete mode 100644 python/Lib/json/decoder.py delete mode 100644 python/Lib/json/encoder.py delete mode 100644 python/Lib/json/scanner.py delete mode 100644 python/Lib/json/tool.py delete mode 100644 python/Lib/keyword.py delete mode 100644 python/Lib/linecache.py delete mode 100644 python/Lib/locale.py delete mode 100644 python/Lib/logging/__init__.py delete mode 100644 python/Lib/logging/config.py delete mode 100644 python/Lib/logging/handlers.py delete mode 100644 python/Lib/lzma.py delete mode 100644 python/Lib/mimetypes.py delete mode 100644 python/Lib/modulefinder.py delete mode 100644 python/Lib/multiprocessing/__init__.py delete mode 100644 python/Lib/multiprocessing/connection.py delete mode 100644 python/Lib/multiprocessing/context.py delete mode 100644 python/Lib/multiprocessing/dummy/__init__.py delete mode 100644 python/Lib/multiprocessing/dummy/connection.py delete mode 100644 python/Lib/multiprocessing/forkserver.py delete mode 100644 python/Lib/multiprocessing/heap.py delete mode 100644 python/Lib/multiprocessing/managers.py delete mode 100644 python/Lib/multiprocessing/pool.py delete mode 100644 python/Lib/multiprocessing/popen_fork.py delete mode 100644 python/Lib/multiprocessing/popen_forkserver.py delete mode 100644 python/Lib/multiprocessing/popen_spawn_posix.py delete mode 100644 python/Lib/multiprocessing/popen_spawn_win32.py delete mode 100644 python/Lib/multiprocessing/process.py delete mode 100644 python/Lib/multiprocessing/queues.py delete mode 100644 python/Lib/multiprocessing/reduction.py delete mode 100644 python/Lib/multiprocessing/resource_sharer.py delete mode 100644 python/Lib/multiprocessing/resource_tracker.py delete mode 100644 python/Lib/multiprocessing/shared_memory.py delete mode 100644 python/Lib/multiprocessing/sharedctypes.py delete mode 100644 python/Lib/multiprocessing/spawn.py delete mode 100644 python/Lib/multiprocessing/synchronize.py delete mode 100644 python/Lib/multiprocessing/util.py delete mode 100644 python/Lib/netrc.py delete mode 100644 python/Lib/ntpath.py delete mode 100644 python/Lib/nturl2path.py delete mode 100644 python/Lib/numbers.py delete mode 100644 python/Lib/opcode.py delete mode 100644 python/Lib/operator.py delete mode 100644 python/Lib/os.py delete mode 100644 python/Lib/pathlib.py delete mode 100644 python/Lib/pdb.py delete mode 100644 python/Lib/pkgutil.py delete mode 100644 python/Lib/platform.py delete mode 100644 python/Lib/plistlib.py delete mode 100644 python/Lib/poplib.py delete mode 100644 python/Lib/posixpath.py delete mode 100644 python/Lib/profile.py delete mode 100644 python/Lib/pstats.py delete mode 100644 python/Lib/pty.py delete mode 100644 python/Lib/py_compile.py delete mode 100644 python/Lib/pyclbr.py delete mode 100644 python/Lib/pydoc.py delete mode 100644 python/Lib/queue.py delete mode 100644 python/Lib/quopri.py delete mode 100644 python/Lib/random.py delete mode 100644 python/Lib/re/__init__.py delete mode 100644 python/Lib/re/_casefix.py delete mode 100644 python/Lib/re/_compiler.py delete mode 100644 python/Lib/re/_constants.py delete mode 100644 python/Lib/re/_parser.py delete mode 100644 python/Lib/reprlib.py delete mode 100644 python/Lib/rlcompleter.py delete mode 100644 python/Lib/runpy.py delete mode 100644 python/Lib/sched.py delete mode 100644 python/Lib/secrets.py delete mode 100644 python/Lib/selectors.py delete mode 100644 python/Lib/shelve.py delete mode 100644 python/Lib/shlex.py delete mode 100644 python/Lib/shutil.py delete mode 100644 python/Lib/signal.py delete mode 100644 python/Lib/site.py delete mode 100644 python/Lib/socket.py delete mode 100644 python/Lib/socketserver.py delete mode 100644 python/Lib/sre_compile.py delete mode 100644 python/Lib/sre_constants.py delete mode 100644 python/Lib/sre_parse.py delete mode 100644 python/Lib/ssl.py delete mode 100644 python/Lib/stat.py delete mode 100644 python/Lib/statistics.py delete mode 100644 python/Lib/string.py delete mode 100644 python/Lib/stringprep.py delete mode 100644 python/Lib/struct.py delete mode 100644 python/Lib/subprocess.py delete mode 100644 python/Lib/symtable.py delete mode 100644 python/Lib/sysconfig.py delete mode 100644 python/Lib/tabnanny.py delete mode 100644 python/Lib/tarfile.py delete mode 100644 python/Lib/tempfile.py delete mode 100644 python/Lib/textwrap.py delete mode 100644 python/Lib/this.py delete mode 100644 python/Lib/threading.py delete mode 100644 python/Lib/token.py delete mode 100644 python/Lib/tokenize.py delete mode 100644 python/Lib/trace.py delete mode 100644 python/Lib/traceback.py delete mode 100644 python/Lib/tracemalloc.py delete mode 100644 python/Lib/types.py delete mode 100644 python/Lib/typing.py delete mode 100644 python/Lib/uuid.py delete mode 100644 python/Lib/warnings.py delete mode 100644 python/Lib/weakref.py delete mode 100644 python/Lib/zipapp.py delete mode 100644 python/Lib/zipfile.py delete mode 100644 python/Lib/zipimport.py delete mode 100644 python/Lib/zoneinfo/__init__.py delete mode 100644 python/Lib/zoneinfo/_common.py delete mode 100644 python/Lib/zoneinfo/_tzpath.py delete mode 100644 python/Lib/zoneinfo/_zoneinfo.py delete mode 100644 python/include/Python.h delete mode 100644 python/include/abstract.h delete mode 100644 python/include/bltinmodule.h delete mode 100644 python/include/boolobject.h delete mode 100644 python/include/bytearrayobject.h delete mode 100644 python/include/bytesobject.h delete mode 100644 python/include/ceval.h delete mode 100644 python/include/codecs.h delete mode 100644 python/include/compile.h delete mode 100644 python/include/complexobject.h delete mode 100644 python/include/cpython/abstract.h delete mode 100644 python/include/cpython/bytearrayobject.h delete mode 100644 python/include/cpython/bytesobject.h delete mode 100644 python/include/cpython/cellobject.h delete mode 100644 python/include/cpython/ceval.h delete mode 100644 python/include/cpython/classobject.h delete mode 100644 python/include/cpython/code.h delete mode 100644 python/include/cpython/compile.h delete mode 100644 python/include/cpython/complexobject.h delete mode 100644 python/include/cpython/context.h delete mode 100644 python/include/cpython/descrobject.h delete mode 100644 python/include/cpython/dictobject.h delete mode 100644 python/include/cpython/fileobject.h delete mode 100644 python/include/cpython/fileutils.h delete mode 100644 python/include/cpython/floatobject.h delete mode 100644 python/include/cpython/frameobject.h delete mode 100644 python/include/cpython/funcobject.h delete mode 100644 python/include/cpython/genobject.h delete mode 100644 python/include/cpython/import.h delete mode 100644 python/include/cpython/initconfig.h delete mode 100644 python/include/cpython/listobject.h delete mode 100644 python/include/cpython/longintrepr.h delete mode 100644 python/include/cpython/longobject.h delete mode 100644 python/include/cpython/methodobject.h delete mode 100644 python/include/cpython/modsupport.h delete mode 100644 python/include/cpython/object.h delete mode 100644 python/include/cpython/objimpl.h delete mode 100644 python/include/cpython/odictobject.h delete mode 100644 python/include/cpython/picklebufobject.h delete mode 100644 python/include/cpython/pthread_stubs.h delete mode 100644 python/include/cpython/pyctype.h delete mode 100644 python/include/cpython/pydebug.h delete mode 100644 python/include/cpython/pyerrors.h delete mode 100644 python/include/cpython/pyfpe.h delete mode 100644 python/include/cpython/pyframe.h delete mode 100644 python/include/cpython/pylifecycle.h delete mode 100644 python/include/cpython/pymem.h delete mode 100644 python/include/cpython/pystate.h delete mode 100644 python/include/cpython/pythonrun.h delete mode 100644 python/include/cpython/pythread.h delete mode 100644 python/include/cpython/pytime.h delete mode 100644 python/include/cpython/setobject.h delete mode 100644 python/include/cpython/sysmodule.h delete mode 100644 python/include/cpython/traceback.h delete mode 100644 python/include/cpython/tupleobject.h delete mode 100644 python/include/cpython/unicodeobject.h delete mode 100644 python/include/cpython/warnings.h delete mode 100644 python/include/cpython/weakrefobject.h delete mode 100644 python/include/datetime.h delete mode 100644 python/include/descrobject.h delete mode 100644 python/include/dictobject.h delete mode 100644 python/include/dynamic_annotations.h delete mode 100644 python/include/enumobject.h delete mode 100644 python/include/errcode.h delete mode 100644 python/include/exports.h delete mode 100644 python/include/fileobject.h delete mode 100644 python/include/fileutils.h delete mode 100644 python/include/floatobject.h delete mode 100644 python/include/frameobject.h delete mode 100644 python/include/genericaliasobject.h delete mode 100644 python/include/import.h delete mode 100644 python/include/internal/pycore_abstract.h delete mode 100644 python/include/internal/pycore_accu.h delete mode 100644 python/include/internal/pycore_asdl.h delete mode 100644 python/include/internal/pycore_ast.h delete mode 100644 python/include/internal/pycore_ast_state.h delete mode 100644 python/include/internal/pycore_atomic.h delete mode 100644 python/include/internal/pycore_atomic_funcs.h delete mode 100644 python/include/internal/pycore_bitutils.h delete mode 100644 python/include/internal/pycore_blocks_output_buffer.h delete mode 100644 python/include/internal/pycore_bytes_methods.h delete mode 100644 python/include/internal/pycore_bytesobject.h delete mode 100644 python/include/internal/pycore_call.h delete mode 100644 python/include/internal/pycore_ceval.h delete mode 100644 python/include/internal/pycore_code.h delete mode 100644 python/include/internal/pycore_compile.h delete mode 100644 python/include/internal/pycore_condvar.h delete mode 100644 python/include/internal/pycore_context.h delete mode 100644 python/include/internal/pycore_dict.h delete mode 100644 python/include/internal/pycore_dtoa.h delete mode 100644 python/include/internal/pycore_emscripten_signal.h delete mode 100644 python/include/internal/pycore_exceptions.h delete mode 100644 python/include/internal/pycore_fileutils.h delete mode 100644 python/include/internal/pycore_floatobject.h delete mode 100644 python/include/internal/pycore_format.h delete mode 100644 python/include/internal/pycore_frame.h delete mode 100644 python/include/internal/pycore_function.h delete mode 100644 python/include/internal/pycore_gc.h delete mode 100644 python/include/internal/pycore_genobject.h delete mode 100644 python/include/internal/pycore_getopt.h delete mode 100644 python/include/internal/pycore_gil.h delete mode 100644 python/include/internal/pycore_global_objects.h delete mode 100644 python/include/internal/pycore_global_strings.h delete mode 100644 python/include/internal/pycore_hamt.h delete mode 100644 python/include/internal/pycore_hashtable.h delete mode 100644 python/include/internal/pycore_import.h delete mode 100644 python/include/internal/pycore_initconfig.h delete mode 100644 python/include/internal/pycore_interp.h delete mode 100644 python/include/internal/pycore_interpreteridobject.h delete mode 100644 python/include/internal/pycore_list.h delete mode 100644 python/include/internal/pycore_long.h delete mode 100644 python/include/internal/pycore_moduleobject.h delete mode 100644 python/include/internal/pycore_namespace.h delete mode 100644 python/include/internal/pycore_object.h delete mode 100644 python/include/internal/pycore_opcode.h delete mode 100644 python/include/internal/pycore_parser.h delete mode 100644 python/include/internal/pycore_pathconfig.h delete mode 100644 python/include/internal/pycore_pyarena.h delete mode 100644 python/include/internal/pycore_pyerrors.h delete mode 100644 python/include/internal/pycore_pyhash.h delete mode 100644 python/include/internal/pycore_pylifecycle.h delete mode 100644 python/include/internal/pycore_pymath.h delete mode 100644 python/include/internal/pycore_pymem.h delete mode 100644 python/include/internal/pycore_pystate.h delete mode 100644 python/include/internal/pycore_runtime.h delete mode 100644 python/include/internal/pycore_runtime_init.h delete mode 100644 python/include/internal/pycore_signal.h delete mode 100644 python/include/internal/pycore_sliceobject.h delete mode 100644 python/include/internal/pycore_strhex.h delete mode 100644 python/include/internal/pycore_structseq.h delete mode 100644 python/include/internal/pycore_symtable.h delete mode 100644 python/include/internal/pycore_sysmodule.h delete mode 100644 python/include/internal/pycore_traceback.h delete mode 100644 python/include/internal/pycore_tuple.h delete mode 100644 python/include/internal/pycore_typeobject.h delete mode 100644 python/include/internal/pycore_ucnhash.h delete mode 100644 python/include/internal/pycore_unicodeobject.h delete mode 100644 python/include/internal/pycore_unionobject.h delete mode 100644 python/include/internal/pycore_warnings.h delete mode 100644 python/include/intrcheck.h delete mode 100644 python/include/iterobject.h delete mode 100644 python/include/listobject.h delete mode 100644 python/include/longobject.h delete mode 100644 python/include/marshal.h delete mode 100644 python/include/memoryobject.h delete mode 100644 python/include/methodobject.h delete mode 100644 python/include/modsupport.h delete mode 100644 python/include/moduleobject.h delete mode 100644 python/include/object.h delete mode 100644 python/include/objimpl.h delete mode 100644 python/include/opcode.h delete mode 100644 python/include/osdefs.h delete mode 100644 python/include/osmodule.h delete mode 100644 python/include/patchlevel.h delete mode 100644 python/include/py_curses.h delete mode 100644 python/include/pybuffer.h delete mode 100644 python/include/pycapsule.h delete mode 100644 python/include/pyconfig.h delete mode 100644 python/include/pydtrace.h delete mode 100644 python/include/pyerrors.h delete mode 100644 python/include/pyexpat.h delete mode 100644 python/include/pyframe.h delete mode 100644 python/include/pyhash.h delete mode 100644 python/include/pylifecycle.h delete mode 100644 python/include/pymacconfig.h delete mode 100644 python/include/pymacro.h delete mode 100644 python/include/pymath.h delete mode 100644 python/include/pymem.h delete mode 100644 python/include/pyport.h delete mode 100644 python/include/pystate.h delete mode 100644 python/include/pystrcmp.h delete mode 100644 python/include/pystrtod.h delete mode 100644 python/include/pythonrun.h delete mode 100644 python/include/pythread.h delete mode 100644 python/include/pytypedefs.h delete mode 100644 python/include/rangeobject.h delete mode 100644 python/include/setobject.h delete mode 100644 python/include/sliceobject.h delete mode 100644 python/include/structmember.h delete mode 100644 python/include/structseq.h delete mode 100644 python/include/sysmodule.h delete mode 100644 python/include/token.h delete mode 100644 python/include/traceback.h delete mode 100644 python/include/tracemalloc.h delete mode 100644 python/include/tupleobject.h delete mode 100644 python/include/typeslots.h delete mode 100644 python/include/unicodeobject.h delete mode 100644 python/include/warnings.h delete mode 100644 python/include/weakrefobject.h delete mode 100644 python/libs/python3.lib delete mode 100644 python/libs/python311.lib delete mode 100644 python/python.exe delete mode 100644 python/python3.dll delete mode 100644 python/python311.dll delete mode 100644 python/vcruntime140.dll delete mode 100644 python/vcruntime140_1.dll delete mode 100644 scripts/assets/x2.ico delete mode 100644 scripts/build.py delete mode 100644 scripts/installer.py diff --git a/.gitignore b/.gitignore index 72704d9..7cd6cd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,5 @@ +# Hide cache __pycache__/ -# Pyinstaller build files -dist/ -build/ -*.spec - -# Installer data -package.zip -.installer_cache - # Hide x2 testing files *.xpp diff --git a/python/DLLs/_asyncio.pyd b/python/DLLs/_asyncio.pyd deleted file mode 100644 index 4120f51cb25246e0b347a157778960e366ee7199..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63864 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

aj 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%0DCbajm=$ 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

S!2OcZf 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 KO}5n)8~*?WEgq`? diff --git a/python/DLLs/_ctypes.pyd b/python/DLLs/_ctypes.pyd deleted file mode 100644 index 4a7e5fdbca0e85894c265556a9d63def8649f042..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123256 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 diff --git a/python/DLLs/_hashlib.pyd b/python/DLLs/_hashlib.pyd deleted file mode 100644 index ea40909b0430106c582858769ca950c7a81442aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63864 zcmeEv34D~*)%Trjgg}_Ej0W5uFlbN`CJPugosa~c$V5^Ii$%#c6B5ZX<lkgGp@S zV`}QF7OmBQpkYy|FI8MxgP;V(8gYx-YFd|fVrY$R#kkb@{^#EN%n}KUweRoy`ZfIS zoV%QR?z!ild+z>__v2O;&KQe;^Z6Lt14w@s{(JnNcmrdj&UtDS+dcf{iF*vzmnRmK zSGW|1vu3rkxJoH4uCA_eD8VyKs+H_TOO&b_n>{%;HYP!mzP<33%r`IIG)8yt z&rcn57~#9;wT*q9!!2Xq;c)BN_c+`<_6@)anI35sc#mbb@%T3{ZX5F>p1yPJTO4kZ zaMc(Qet?G;SCp1hnM2huKZh~f%~5RK{kN6sIQ?vrG9ql$Bvyc!8$_(-62Lg_uY)** zKa8;`9u}*P3Y2TU9%WE)h`;{p(6*dWiQr%?ks5!9zht+)){V5w7vm=mj))J!R~RcwcG`;F z#f+VH8PY+MGra;Z=+Af7>k4sxKVKJa6x|-q$E28BClf)5=X*44j1%iA$m@i zlNyN2q#quV$#ZZ)e-@5sudD$g$%tgd>u@Lt30@0h^Fm|({X?p@Uu|9yuQrz}%Q6cx zm#Otf9LD7xX-6})-aM_}s{KjT-ZqZ5Y=mov+XL4L*PYkcVQjn@f>fKINoa+jRP7}z zyc^-oN%J-SIn#K@0iP+mgt1)hbyZUneWv9IsM>&vtPRdtj5Yq**zgi%o#{}F4Nnm< z?M6jy^cfq{k*sR3_)J+)Dv)juGdBJVs6NwQc|^3&w3mCjLCvkI&5n4V>5C%ZHfP20 z0%mdwf1@%Qs0?jkTuxets=ehi4FewWkit<45>Vt}V`B%fteU8S3P_d8YdmUfd=nm3 zd%@arMS>$&TWQYK)@0;rA7rk|ykgZppQ)JmsPBmDE%W(&nf0FisqqCpXvER#(FCdm8)5zzo?TPAkNs>35;CrcRte^P$eEe$RK%ks4ZZV zC(J@Z{QyL?8>sc`6S57)pVofs^YuOtOskfiV5X*NNG0MM1{jLGJ`n=+PJ&6&y!HR^ z85>VSTJI9#vBjF8_)Jd}ftv}4^qF>oIwyiGsz##G2E6|hNdkC9^ZHEp0=4fcG-sU8 z)QL){%?lEH&p=KQ^=lEO^rnF$wZ)XfTRiq`TE3aN+qpJmC?WtmGe zm#Z6&Q14Z>Naw=;f*ysX05rlB>PeT$zxewnQeuY#x9}fDZf@;Y~D9F~CB-3yY|-U0hu*Bym80 zy&Q9v+W4+JIaj+hT5UY&j#IVI)RrutYRuk8>SjU$>YtCwW@`hGcGH6>z}k|XkPk7T z+VderpJ^A!Q&Tu8v3W~E4@jeLSv6ZizO{LGLN~%z?Q`Sk?1UovaTrH8B-9ZSAZZ`L zHbAxUs5?*9=7(s?Y*1B6Q!>E@74yrB{F+k46XKA-HRU7FsDCDbx`DxX+XljG^l5*{ z)m}E<0R?Vb71T%n8v(tKwnA3GG&X!jOw24-j1Be3?C+$1KsxWF_gzU8UZzf(fHJ(GKQCtU<1gHE~_xc*MM3goQX-%yDA`rsaFze3dMa$a0PLJ@kXdlV_AgBzY- zNU4k<4K9LSaR&Zk)r3@4?Rl#v1WrAf+EmqU<@%(i9r6x4AK?xAN#QaJGp}5A<;s15 zu6Y59?sY(;>-*4?*Utdz%yRVPyEzf`WCPN2TP$!Ze7Um^7=Lp8KYYGCvLMgE(_4cd zz2i-xj<*dB1vSa6_o3@8K<3^DK-6cNLV_T>@fv!A&y)&D@e0bGS42IpiZ}8r$nG;u z1b*L>5S6DeS3Bf0<$_V*^j=L}jd#e4D26&@0SKyE>_Zf8F?o3#p!cn%61C@hy`por z^Z3{eoDPy#Ai4KRq(S$8*}HQ(A;+dso)**Zp-XufE41O>Z5WDsZv+~3V9S!_7&2;A zZC6y<$AUBeN zX$Nv=Lo{z@8W$YM);h?fUH)Ui+%hWS!hfjYpCiwWhtq(z5c>MnO44ogvrX_wgLyN& zq-(?iHEY9ZR82uPt1;Pu&2{xK&;y>eFcEjdk+;Zo6FY zyEi?AU&&e@YSVi)Ncv12#Bg&~eBWJYz^A!XV(&mQx5R6Z2y-cz61JFr)#fV_qE%SW zIJMcGfO*0C1clEElw7Tww{R~yASC)*A4^+o@qqL$;fS9 z8J&}MG`HF1&C|Mao3HBuPkGI2y7;KDJDi#-6XyD?-Kb}7i^FGJeh@~#z=DQ?=~ct~ z%ZxYX?6PWofZXinbr?tIb;0$(^&3Z9$qeV!!L`D*ak@6pRaE{sz?lT!$(u@do*WvMNByL_gzr7E76Mk>A~As=L| z+6OeRqDi||`x-+5x)CpI5g(hT%gF(Zpdu;8NQ&Gtz9ie?i&U^u{}+R?fkqZpTZCB> z2GU5Bq-vRgkp&1}b57sR)t=AOKFZVnLD}3_B1^ng>!I;b8Jyz?a#*!L>bNPuRVY9u ze8L+sw1oFL{+FDe#)Ck}(f*=txW0pQ%6Qv4uxg#@#-P~nHnD;pL-rUcPO60VlFyWc zT4~+fNE`%8{nuf}o4!H4Fi1Dnv-^rpanwCEB!~>VX{yeX$PrWn629XP#;O8E~CIsEEV0d zj_O-lkWi3z&}WKWPJ;2$q+zYkve*;By#W zlC{}}{t{HkohSrqrgi&FV?es`U1P)5DP);H?>imF`ewwTub+cj^G;4-8VH3R2_;hN zuit~noe3&$m}e4JaJW06h{Jmmr~>X7p^(2^21*c0Idkhn?JbDP)m{L{88ntYeGV`- z?5D1px$4S&X!%4^kwvhVK+MLBbHL{@`b?$78peReN=RF6neXGXu3;EP`pyHnUiBL> zs&bs$5TIp1<4f@LZom&Ih_=Y=Gc5#F%-#y9{Te%|=}gf&>Cp)F?nWF$aUF5qVp>lk z$Ds9hOksOJLurWX=i-UI92l8l zqqGZ@tpepLj*>tq&3=?dfpU{TS;>P#7PU`yT>W!ZRhh|>WXMlmcmfCM%eQClQ zJ|L_ue#Jyxn%P?u>d;Y*qi>b7-CGmdWVl1ZE(v=iq$wLO>c5Dc7Rxtk{eZ#v6F$+P ziRyYptC}&yKE)Xu9;0Z?H}ciyd%3>*OfQj4Fr<-~UItb509hZO>g%v%Obz#Zq0Yu^ z-q<)Rnb2Trk-Lc7?WdOTe%`ndnaFN)D{BWeqLe7mQg)S3}XGnNbvxA5VFrp9Ch{9XIe#mI_vBPpD_CcE%DA5l=iVu{ujU-oMZ}0;6&OqZF z(CM9rwh$fh8dCR`*gm1dbD&v1({F*^dk(diX#~W@8 zX{5cIr+t~-k`?Z?fKfi8q2XvND0jmRaUh9tX6IB2-6%s3Aw*N6A{fm&;MM;FL&OL0 zkUW|Q&W_Ed3efb`*mws|!6M(1&j%VGuSK%}LjtDe%cn-i6T}u8I)7QKuuo|Fn-y=v!5eYFQ zXj;QlxbGfmH{^WLoe)RzRWh-=qx}`@KhETvV%w)EP~(~PzHnpXFD?YB`dWp#$E#YF z0uJ2ia%xDkDoh9q!98s;*cSn_IZNq#E0B@q;(3VgBd+ft+AXHJV9rW|(r_MNOSMZHa;z=t=D5vEY7IO`kA;M?+5cK&p zS;gEPBnQo;cA4IUT(hx+2#ralMF}=d^OwnxWV{%#OUk`J3PZw-(J+?NLt5}=q%U_=rCsQ)#vJz!?J{$9fhK-PAioK z#s4`KT0gfCU6#7;3P7#f*l^zkjLp0}-fdLt_oDEb%=20AEr?S!1Mk5%aDOMUwNmv> z9u2m*yyN+-RfW?Mpk1c_Hcsa*ajkg}wic{d=G3b`a~O$&tTp$wT@UsQ*2K z>(2`n_1_OFsy3+pw}jMxp}>&!ub1_ImS?2;^K`V|Pv99`e?(FJx9P|iBEm0-YR<=? znr|{4tL9@-O{zH=px(21%{L-1v#n=_hW81_vzActQj7Se@$u_cII zIX)Li1{K@NDNZ{ji*>Gh6Gr|Ewg&y0Fm~Y27;uvh|o!AU!%zS3k_&YW5Wd$ z%NO?3c=}t|PxFrEvLtG9IiHVJYhbA?J7F*EpQ>TcV;+|#R1H#NLEJ8Hz-c!~&b5M{qU}u{)Qtz_4N=Gr&o`0%|^!oBO%V4_;vN z9_|;O)Te04>X+!Y(cW3STEvih5*c0C9PiEO>{RS;IfIfar`7kjU}}2*$9%?LEv%Xj zSmHqxI$cKG>KpPum&B-h?}HILN|cV(p0@ze-=5b~E^1FV#U8Ug6S<^?NO$l;(4OHG zski6N6wBLFqXkW;wczm6`$!6)JvX^G+qwN+1D=ggN)v>>i2A*en)xz z4usZ^jz$i^Q1Bk{vbXMoldIondi~zdLH%&v5?a5b$Ejb-oyV(RA>?%`^*fpN>qEbi z?br6FldGS<{e0P{+I|low|+N5UO#mG#s=!w@yAoF-#MpTzogrb*M9ed-Va^B*)S}! z{d#&%v3{3ioof3fVX-)L|9ckne(3s@@;=S&3p>^N70x@=`n4Rl{oV(?ld4~rl?J`u zld&%v@6%WbzU)=rAG-ZU1ldn+UlziC-kAAa`|?iOVEb}7$bRNwfe~oGmj>BSALv=d z1mXDh^Azg$H1E^AewO!6v3~bkPPKk7|Ll16JLg|ezdqildHst1aEkSN_L5Vs-%pQM zze^ymAG-a{2-L6c_orCD_b)!x`sLkry!sVFUME#Qx`2WHcQWJOLT=bUo=sGx3$GHUjfzSkcQtM?ds@kdqn9&(GKK_T4&h|Lqzt|PP|9y{ez zP&TdM1V!z)64Cm(mq3JkTfm~WoRvoM#8$8BUi+jO@jjD*=b#m*v0)@iHYSFnmd4TG z>vzV)g>lBwYMe1KOTleCMb)rS+sIqO*!1QED9wU1!4OKhE}FT|P_^aJd{Tp@BENWt zD@(h8JI@-*&7Y3I5t=Izq4`P=SEF zp1MfN>mWRSd1Zr606VaMatKI1(|M4w){WjY%4a%^7}EFT@pQh8eahMJU~d{4OS_|A zqu>xt6jZtXVmIM!+Ot?qO-4&O|GWfUWgfpu2)*3UPkQ+^iopSIA~QDj$CEh$I(pK6 zZXU4u?E?+4(exS;xj4)#WnbYtL4lP!)}cPrQYuk1eM_Jv_6ZQ7btkpp7@x^OvDnO~ z4x1=CtcMqay{uc2mUa*Y-MzOZ6K(Ea%Zq*~cSAz=yHVap;GUC5yB~I6gfic4CPB`n zc(L*1#%@R#-!IEQi82P&r;+Hi#NOPpwBL6Y1x)`mYS`m_5R{>`&b1y&(!cAkw=C!1#Cv znFVZ5bP?<|q5!(CcjsOnr1t`He+2tkWbEYCB5avrd`dg${R@aRz}$5rqt_G3*e%^n zxX)>M!cadqJeS)JQ%? zP4QkS&`HCu66q@`-3u#pAo36v)7XY(mQ>#@FL@6SgRjBoxx^cfA&-=-K7(O%6FXt& zAPI%yI?M}CQ3ece7$>b-?8lICrtei>6nYRsB5duj+4^E1O@`b8oi;>NDpxzg@{#Pi^Qn<>0ma8mPwIe84fiwng0P&|&H@}~B_l5Ay z-sf?v_4as_l84#mJkC@O_C0ej8=8s`rkp9{j~D)yJVk^Vg>w{SgH`QO)HL|ha^lpq zz3P)R%cOT!>bVG{1&UH}t_taUhy|DnRsEt1!BrGQ%i~@Z>@X=6rZsba0xQEjQMgZ* zEUgT15^)yQ68q;?WbjQ+MgnYiOY9#I?)?^46??sZgnyqOf}Zz(z=~QQo#6dgc)}zd zN_!NUXcV%mTEt{17}!#y`y$oZo$hgI9sR2DSF!CN==n>ku=%?TeP56rqr5JWcbNBa z*rUGj-jxW$Y~CTFBT_s1hIv~M*k#}aQXUxpxll70|2qXeomM^Y8ah0bX^i(85g6vZ z8lJu*LHWIfi1GdyKQdCcse=yaaK1psjCPZ}hhPL@Sx&S}mp&=k1@Ved6CgWl_bCM7V=>kxtAkQdqTzE5reSvpWdeFd$$ zx$(%#w6{I0>%TOty~_I$8UZbth%<%+a2ZB~O~{L?6W1{mj^tr?GNhbVW~_aR^;*OSh~ zKrf>J!?>Ep?-Me*h~_-O%b8J^zxJ^ zL5O+xqvwI|mc0JVJzX?WV?|>V@!3Ixt|oHO z^$QH~`6j3@U;*i@&-B<7Ogjb){4jk z8~$2RZO_fd6_Nh5gPAQ^hMW;y#?6@h^0lKR+3 zYay@6{g?QR>Ve3gBf#nyo7)j(VD7}ZMNwhQJ#nssz=X(MUw(t>m9jQL#r+%lhuRt+ z*y|dXtwqw_P-cCnA-g%U1m3=3h`St~J($h0>=yOw+5PL!Beuavwnh_}2%Qb%Qy&a> z#pI0Gi@fI{%Yn#futC(bn`0y4H9qw}V+3+XSmkk_e_@y z+&WdPL3i8L>E^BYWY*t#Lc zVF1%QW=38C3=ARq_RJyQ&VDduK*MPB!Spkzj$MiD$m+QAJO zX!s7}9ecIC)Yn@~e?)ieeFb-PFjcg3TVeW^dMMpF{7oV}upOAo#lYLz`vma#Tg!%L zpC=zKSvLF{KIGlNaZMLoh{dOPvGm1TV4zod0oTZ}CKyBc+#~sK6y@|lu6R%NB_xV{ z%ii@w278Adaf5-%^O+K$39Y?<5G9<0DA-C|HvAVun9m7%9p45b)v*ZsKs-wA@qgewJ2o)X5%~{^}c~nP)#hL>NEWqnOb|FMGnYnDWXJ8UVBsE(u2gtO-SvF zrK~)7J4Z%czU6r_FF@Ysd$$p6F-@U5ZF-5*dzjb3G#^pC-69e0n~H*tAg3tkDiriA zG}zaBuaLv5{-j03gJ|UhitOlp3@BKa#y;%Fxez#fPpJ1%6nV(18F5+v1uKcp^cDxP z<9LhRgDkDRqh29hToetYO#TrovG*dR24yrh6c7b;%f@Atc|K)sG2MxJ_)MQBkPNm`6mF7OXqe5w{9qDh zO4te<4YG8n2veXk9;MPNy*_wR0eT9XLW{h{Kf6!2V!Dpmg#y9_obWXu+;;}efLct8 zd5n!>(2=_^pMsZm{w*|gWb~d##Z!4xI5(dlc!;k1%%Xy@SJ8Minvo)k5z*RPiV%#% znP3ijc^0$~=f#}jW#a82zXdv-$AG9Cc&)t~kO`{sDP`jJq6*?|?R`r`cl)E4AsSSl z6=m!}fe8IKFXN2wl<_LEamM3#8N>?8(EP-P^D?SLH1Q#d{wov(RF@(i`jVYce(W1T zeb-?+5PBns&pJrXcy|SI`iay1pw#<0F9uTjfJ^BBf_P^NED~YEa|oi$7XTo;o{79( zSHfm;{yPwceH5|t^w{kP^G%S03VC85BWZBqnNfq*-tju(1|6|YAU69Ehl#3wO1uRO zc_z|9uf&hm^D5Chhv)^c&OoxyG##{CdzT~Wc(U?cdpubgKuMQX7AW=J%{hmxp5WBi zAc*%+Y^3_-~1DgewZrt#qiilhP8XWEJ?BJowC5J;;*8W+`l=kTii1YsenNM5zg zq39MJy+)v~@T0%k#mjb5**;S{$CFQLxmvH{G2rHx;G?y-k@HA>rFtr><8J^|tnd}GiN?nBXgkDo z1}8HC{^0cooo#G8n}p1d8!@ZH71B;`%qYH&Ig>ZS6rLU%<}bPqMfbrvF2bScIAR)0 zo>-3h?ODWm-$;CVBTm098?<=A)U7w1@%bHJhtL|xfeotVl_283|4!F;F$tK!i|zE8 zUIkHpcr+FQSda3A0KURF)OTJs_AdE@YwZ>9t{BdB1UP^te@%|KC7h1Dwf+(6Pq)^a zzy;=fjzXGHACsqjYmULw&0vL}70wOj$%_&MPi5cX>C9vDbXqV^KROmqe68-k5B@e? zt{f%r4tpYLJ0Rycw(eOh7KXNUnJ8TJU-ucg+88vPcNOQ-JrZrPgjn-2zQ13;Kc6;W z#J&NZ#$nE%TR#xyo|wtEWU>p4hb~?oK>!8>54No9t(C0%M9zfjDc}krJ?BWjk<2b&ihm!mYC`Yppj|N8% zyHCWs9oiB_doEjBpk$ug(Qa|)@}uXL%=n|vDel;#&snrrjoDpl_-lO;sqQ_Lv~aQ5v=y279b+x_PdNI{!=o0uVa)0LOwf4^Rh4_g3O6qk5s%8cf5AT) za09mYW6vf%Y~l8nXT1g}Qr+qO8n|f*P(craXx>FUQR&7zI9$$Sh8ysjIra^n(NxXt zAnKA7AapG<5KV{ARKscZ&9Q2?Ce$G>9j0Q1RDkVhGBe(v50}N$js1Cnd>6q>Wv?cx z=yhGlOWPm-)bVJYDf)Wy1SCLa)Wh$g!nlcx$3(dAG~VB?91lwR*?c#Zz;}j&X?y|{ zj=KpSN$WB{twWe__r>~2+^Lfgx-Gb97Zkj^Fw9DWIF0NGJye6PZ<a(%)I z`FImW{WYFg#aoSAx!~yS(K)z)EcFOiT<9|=VoVF{i3bj0@l_+d`0uyU>lF-kw}P7f z9#YlHqi?_%7dwm^zQvSJ{8NuUA7Oq7NcYzXVFvNgVk*=Tq6pz-&MwZtUhys)MmcE+ zH8wnsXx#HZonlCo9%yjv^B^FUItz=-Ufdpq*_;mnyp*dU{T2TW8@!V}jf<9wz0IF1 zmM=|VT<%3`-!hffXLs`=__&>{HrECQT*y3Lojtu7x$!2A9@TVu*GCXlcO)d)hXw(q z#h`@x(Stp7(Z7S3ekhBzgeq*=7R;q0;m&K|G4) zZ=u^zzcioFUNLUq>@d?fdSMg&Y^0xd`oUMXj;Gf&;^AWp9b&{&Nv-=ya$pn+i__b~ z=$fR~qpl8CYkpmoYq(JBe7~T?$ED~-mtVE_adG4ACJ6i0yBax!dXK;&)iM|LY%y)% zAoj24Qu~erM&DJqUjwUtM*`KCcNC9kydQ}t(G-pQXM)&78UjG=uX8xHEJ1Axr}hH1 z>Y04JkzJQFh{>jR5onMig?5TRV2_$!G`AyFzG!ZP5AR1PfsE0u3DhRkTRwY__ZDh2 zaX@HU#tqXRWWa#`P6?rL!-R7$*yn4-^Wf#Ul7-E1(RcW_oM0_1z+fTYbh_beh~_k^ zj28PWFB~1{V|XwK{R+sr8)`Yd8-@cf3V3~QVpEactM5Xp_e|)ew6$yKg(Fo6`!PhQ z^s+cq+^XTdHVUThLVX2I3S$h$$cJxK&@`76_>8ec2+L~>L9dJ>zaU0k*aY6Ph$TL( z?A=eZ zI))ekSHC2}frZUoyd3{#KE???AEJ$dxNOuXUQ&jwdfR7;wWdRZ+E%_wlMtruV-V{W;wR&J6#y#wvKxh1L7{uH*_$lqQUe1dC?f!NQo5w=IcxH zn(4%zzpuT>TMYM4M(j1-@tpP?O=kE!4U>n#Z}q;CZ}r?s^z8REumkZ=#CH*Sy@Dn2 z6}abZG?ROlqf=vzTcFDVI(5*Eh2$EfihC$#zK<8r|9%O4@*Bb9>k{sfaN{!~ey4;lNcfI~MI8>1>gBdiaIi!uN=T z4@!8KgiR72kq@-NEr3Fh#!#Q_ay9+aF2wW zCA>?*1_@V5=#a2hmUr~O1>KJ&+#}(e622hee3?&R<2$)e3SX^+H%qut!UrXMM#2{* z{Jn&Kk&rzl=!}yvQNnBqmq}PAVXcI>NO+%wk4X5Ogzre`mGB!0<7E3LN;qHgF;&9T zB>a}#(nzeSPQd6d+CbKp6bxNhZdbPXU zkFeTlFLndLU0z(Rn3F~R3d9ta)cC0|fUmzcetdPXT@jcZpkHb;pbVH_;qPW*N?8;X$gu@w^kUWu>62WY~3jK6e=zeVEfux$wZe2KqP;_GnJ5csOZ z-!1WVxOoWt4vE(#VUL9KhY(P|OvnFk!0mmUgbRkiZ`8zjO%vqCxoi5`Wk?0oj84~L8e)uoq$4`H-=k8^984T=r6rv%@<87j+Bg|zQ93~kCg}GFM!kp)z za9W_1Lh}U;_aXFx=M5or{L%=abIf@H_zsy*_-BE45dHFJrI{2}2Li{=we`U}M8Wo99~+U_nat8lmq z=|3b2N+(?UTZDPlk|kD}(b}D5#ie$I=IU}%ME{GCr;;-mG*3@V5YbbWX;V2SpIu{W zFGV_4A%RX+0-~H6qXhkNvCh4$rrJIwCMhWh9$I762|E}k;h7R9 zN|-Jo7Y2Tg$Z-g7q(a7H(O!uOE_-DeDlRx*Y6-qv||H5K~D2ZTb zZpr!QPgO3MstmG8a|@gvsR}}%ylAW+$Q}n*dA3sHAXUJsXB`w43n45yuSJEqCg|*n z`VO`mKL|gtKi`+1AbSzQ3bY+7V%O@aBvvd>gkmk>)Bhw_IsRWU((q)m+adYLDxjnB zW&cSF7EKB|!Bs$8=xYZ;;(^go{Yb&gibYbz=%5gAkL zao1F#_m=X8BAvC{K&}8fieaCxLNPq11j<5#V{fCla&7TCXtlmR=NdLte++3~j6fm6 zIYqJf^$m1_h4X#%4Qu6pmKBirzFg3F<5+j>E?$fs8OJ&$aZ+g|Oz)&Ax~<|CRM-?q zd?Z~n|83P@aB>CHGPgeKQ~|e$DY*07=XmaI2w39rp!80 zTCzFW%*Qwkwdh+FZfRqLkrHz@ZbL4=&#-4-~`M<_~oN%0#O&nyiLT1cC^OqlH zw){`bm8lH|uaD-)b&*BFYzb8f2d|sNnNvuk1=fR@^V5=$ulc4b)e<@-bO@-g5yc97 zt{F38I?I?lBVF`KQG$P!nRMLMqF>fS>0OZgF{=;Z`}@rv|B1B$$v=o6jCnr*KQwX% zDc?yCn8XbJs?_i_@EIw&kL##_J4km8eu*7{p&Q89*Ek8$o~ggO?)aT$%47@h4^#TAtbhI=sv(%4Cd+|G3vZLg_t)>PBk zHSLWI)s7#^eWjt&b$#Uf1%ns;`euPx@QW^ry*O?^L&PK3`PieBvsb@84BcnK1|Iev zL{|SklfM2EN5Om<1tdQO!6D6`{~w(^pW?Ln1nB>66K1J^q5IYWi%>jODe-Sj%Kgvt zi zt%45lX_rB)rob+!Q~(dQfvy!OHKkaFxu$|Sy<%>6ap@XN<2{ww3of_g8jrp;MiRib zM9^wcDK5d~n#r2>Nfgm@UUV}rp)o6^-DY!1S*I*UuOw!%JDwYy@qr^e%wmm*|d{|4jv z`t*@s+X=b{L^H|r>HZRfRSJqn3{V64k&3Y2NJ{$Ew9YAZ;XV`XGgemUH-=VDcFn>C zm@DtPSmt)4~Rk-*L zt$x1=^I!df)%pIqouAC_?*#4S$s0W4Tqq}T*L>d zmVYCb_{P;IeP32AeW90JLla%tNesR1MO~1Tcb0PgyfwV?99R*z1GNryVB< zcgb`;-=RV0GlSCy2GLu*BzsBtqnUqb%b1;W&ze0e)t|cPe{p2lv#uyydqv6>C0Ae^ zzoNLxHY5EC{~4OYR>GOZk4ZWT(|I>rx*%Wg56QGXPpEX5&3aDsli7@Q;Q(BuRaH}# z4)hZ`j@IK6%x2zqZuiI4vZhNJyCYi1xt5<5p1A~{O)~o9t|eM@7?~J>xC)##7ANpS zT--rm8AQu$E-hQlSP{Y?#gelY;}dULnUt+OH15X~=Lm_*<#@HBaU8EMBrc!hHHF4; zyw;Go0*<#aG>+r7A+De5>ZCg0Mg8^Q6sjt560WJKbXVDkXT-PSVuHw< zaP75(i+cv;;X!fN+Dae>R(`*fgVSA_kekW*afHPEnDbK`99JOl>O$fKUK8RHsXb~1 z-@6`xjYK)gb`fTeGFD4r(Ke~@vRcHEiIj0^6xWKlpf*gWIJ&n?udgMZxV_N9m<4Ic zlDq|BE)xn%G3`Q}Li)htY->n(UHcg`57XluPAhGgxD;2xi}DsxDuBO#W2RwuOnhk_-7aw&Bhg&*tqm@Y~10vo>3hm zizbeZU}OJ2mPNbA@G)jy9AhNoi9`+lKo}JS9{XR%8=4R5ug}2EX=7~s#9_>6IGaWH zM|DLMh3AKv5syCKiR=@j!%)AoSRJYuiz?WFKQTUn#eaAPi{5`Gk1I!f9mNBmaDu}j z`B)TV$j6Y64W@~_Cy$E`^qu_2qkX)z&~gpK!r8Dtg*!+F6O|~Y{CyNN+0e!XW0>VM z+^2wZY?5;Ma2yXmfw=V)hdNMtAdGU6pCLaRoFBL$^u7}wl-G)vK5$-M4vY`cMfrZ( zA?ZWsHB5+M6Wqhu1Y0zlP%w;5NRMI@Qcvq4-s8~G>9KA8X6VE@5p1*}iAD89G0c;hw_c@Ii?rxO*Q!I`yaY3wiic#O>1KY!@&JH=P6fM{$tZ;4snf=b`pO*iV;a zgK`oE|<$VG@YSL23|tx#C(U&U>t)niW$?5%;+4^KfGsH$Hd4m7FjTo^(Yt@ z!1x_oz(2*gNAa)~aa;5_TP&mS4RCuX4)quuCK~=cNbd=z%V0}EmklnD!6tksZs@!( zh9MjG$>Ag~VvPPP+7+O4-0~))Jh=6G zc_Cq0UPv6|5E2$Rx1+54;W|Nw*ZcOcqKPCMv~gtmNVe-d#{LL*M3!^>aD>ne%JXe9{TDV%|8Qg~b$e)U?cQ2&{ zw;|%z!|l=I2i36-X}^N&LOStr{BWR-lYWG;2#&Q6UB@_>%js~5z#-b9VNs{xxMTH& zHsm+JR5+-dAiXujMX)%?BrbI%*Wo(g{14o{gcnr*e#GU%r0=14nn&42V=fhkxzs2& z?y)$>zja)E42!qH6%1$b=@=VQ$MuitiR1F>!s;jPBCM~rh02TKX2Q`I;<+3bqfd;+ zc#Ls75;QDG+W^P5OT7&VlYR_`u7=_nA`C2I9_R(NAL&DD24nMQV$26EKTc5F)gf&k zoSV`qezCAiU5J}A3*$S*2hltkKZ<1rxY4F)W&*D!*h&-h$do#|r$-h4$3r{zYEGXk z_Gk$ITKF4-!cxETNAt3yS~W-wt}Y1SetKk>wR;Bhrbx8eQ_N)8!=k9{p>%+ctu$YVWX3Tg93(ILBWQ?? zM4czFSVKIEatxxO>mZ*;M6tvb*wcd>*eP^AI6RnlF>Z~fanhlWlgElPj6>a_dwv-V zRR(xm4^LxfUWsuL?)OBWufa?_yc==-vP?=34hQE6X^-Icza2UkRL}9sFg6PE zAJ!A;2wwZ`0WagvLHigcp=~0IBFtirOCMw5`i8JBcc6y+(R(tA_|qf60n}YL!oP>> zA%}gYPXU8&emmCLSpK?PT=^&r>_@fkA{_BI?s34YG2H!1kHH%IY3xrpVMl}TZbw|5 z11>18;2FpbaT!5z*C4JPakQVI|9$%#_z*YL-+$iY3&}jPTfhe;yi39+3IFpRU&!Y_ z@9~8k{(pOqe{)pMvi!ol>_R$GU{~oOTTLM@m$R5?I`b&ZDp-N{z<5|wsi&7!7O!?; z6&FaS3xC)--VvFzcyVEArM=i$$Pet;hUi7}E-kFCu%%X3Gj81HO9ZkIR_veMVt}Oq-Ec=FPP^jYl#yq;i&&H!1L4-PA4P6f{ zq-SgBXJPs4^7vb^!UcABw!MrEkD|Qv$ZH9IrH@reQ0`Lxu?CU(F!C;eMrGP;ELE@d zykZ-gfqw~tvD?94c15W>-&s=&n&?JvOBo;^$m3L#S@fJss~tFQUua)PulrnVj%=%C z^z{nSRP18T8(ofb)4lRS+)8jeYu2&HB~{VRI5P^=3d|Ld0b=J$dW){XbGgczwSwf^ zTvFLM%!fQ!74j|Ow`ZUY=#L43nmg^VJkTsIwx|&LBFAFLF7g=hI7tss}e?>v;jJRoxjGy+>z=B>2Td& z;;@%4$Bm15s3t7%V=_k;SzPuILe!FlXt-Rry$bu8dJHuyJ3AmLvOiM0K0yuh>{UXT z>?(v%hima}5n4mpexq|$1FRb7I>vsfQ$?*rIR?K>p`GZD73gExgY>{No;qAxENx`sX2LG@gXdLAX2k!4s6<;Rs2X&hMA zAlz#E+QKqi-N0mi9iA;#r=8O;g{vkF~kY`W-;bw;%fpCVywGU8os8y~I<>0*oC zy9z5ST#)(23_}SCnk~y(y!5hy+`OEWbTc=;?57O1sHSmd218!DvhJ*67X|!uFHotq|p%<{1Ph_~Ai{5B?h*4o(a9M{f}C#^WV4%fzBi5pQ`(K=Zi*V&AxqXxB-o)AH7dctu8V zB={ZAi+CMxKojAj8$;vu^b^5>+eE&u@0(xNbED_`mEV55$hYTvmY;Z&$lvrm^Ecfg z@<*Ry{*J-z6DcI!HK=_Yl78GN()YKUl#lm&<{xMl^)r9Z{B_akwB&C??!ujZeLaJQa5IW(Qsi*S>qkF(g2{Q0syPgL~`iO?$BZ=MXN7Ycgm zGQ47y2wP;h*eR)DZ&<=-hL6*>6?e3->S=h zkX`mOAU$moFMp<>J2+hr>+e1+vOV;89qy8J^zezG&YySr@ypfu+j0Utoj;rhae1Do z{1c_?{B_O#Vd&}l-ccav-6R=^mhG$S`^F_AUDtPu><_xWPnG%g^j-fY@O6F1UE2_S z_ueeRC#tVLe&FsM&#&{>(ICS5_=r0~A?X%5e(LrG_qjsSi=_P-kotjh}#=PG7dap1y0)_+_3Nn!iZON4M{BNulYAl&?Pi z?3xyu-YV^hZXfe63{7uq6=B`}cO{3WD{_1+lJ>QKQ2B8(zdnAM(?atX>Gn?M&rc0a zcSw8LCes}$q3K<6e9`AGt>)15eo4Pe=Px}py-kj<`uH9v? z!X562HUY1Ie;oV-uZ5cmfAIb5;CtM3pZkyFaIX_M1bg9j!cQ<74@{ncpWsDshu|l; z49*Kb!FS*W;3xPc+_+5w&cR*jMEHa6K?mQTrhC*2PiJf+a0p%vw-bJXAHzKZKf$PY z>?XkKW4eRKu9e#q1a38`?upMqB?&K20HF-7_ z{@^>a!S`}MMY?{6m*AUl9|E7?dvF8r6O2+Ivn>M7hd&;Eg3rPw!cXuuI2HaLikk@e z!ykM%Hu&Bw-KYH>+#%o)d=0J#euCX_{qPg)gJW9-R3@Pw@DrQ~mk7TFP`~%u1HXRH z73+TX1Y9R@g72zgUg*D{iaERg4(eg}S4;+N+}kARf=h>=;D5no!ykMfl z5KpiQZVUVbTi|xXAAI+d?u5=fANOJrPw*1Bkq?1?K>bc9!Pnsm5KoYWC{J#gBlLcLcpI{|iE&K%Q$iYwWAlw}I4*@RE zhQ7hS0AfWHImhW{x1bl)-_av(@|Dc$fBqklr9AAaC$nBzlunxe)bg6EMRH{x_kI0b1aS;3ufRg&}B%8$dk4I=FG01$+Sh zbojRbJ_}b4e+S@)a0L$txGE2P!cXvdIL8*og5L(v8-a0`p}egE(mj7S{K5DAgYWs% zegALab_0iCEbgIy2>&R+B)D(j558khckO=$SNqdO=U3R+DUI8~1 zwkY^6I^9X{fonoM!Kfdhec>lK5v~LN;QQiqZ~RWUIM|lE07oxIJHtN)a3)+G{IdXa z;o9N96mSJx2mA!@gX`WV;3M$&!%y%4oOwI?C*bRFSHMq@ErAZePw))5JK(4Hp?AU+ zJOY~uIHdq~<6*QJ;BVm4;m5j}UAh$V2M*SV>@K)$_%{M>UXFgV6YUH55nKZBv9G}I zicW<;_>L&u9bF5@5Kr)WxN-2;0e*Tp^a?cl0e`d-eE{)TZ?Xwjf@j1B->VG1b4hnE zN3BA?0}jDiaPjaHTnd*6KlX{(R=8TwYzIs$giPSaeiHjBTqXR$cSq+Jp-ynEh$k3X zjQYVJ4R|Ts5!BZTcmQrU;yVE^FG2r6S^xR_cb7mIJu77j)HWV40}vqS&%g`_q5Ibb zMZ$~w;rJ~-M*Q%I??iHZif@I_`#JP193J^c?`Lx&^$^C1OKPhs68);OlHS_FooU8b~S19Ng7$xpQ%B zf0ESFCh>g8sefTyh7m)bEI=uCTRuMKjPqQ4-qxQOoSef?*->pPK8I0>uU+7G?xbQD z{!5vfHFoDD#Z!@4N{7>PCzTafy6lst`N_ODaxHPdBHg zPA{98R(yO4>BXsKsTuaPr0HoTGn3NO(^K#fwV9R>BZ^AGwf*@$ET1|Hshih zr5DXe$}rnglG0PtW+u&?UQ&{jk!CZO&9Iqm#TT7`LWbR3c2RLkYEnsANg8Tl&qzX@ zrYEIml-Z`6i&Lf-&kU-?oN0rlJ7-!*Lx`pfLOO9n@?H?oTe?J1v(|-s5^i+0fQHUN zH(Q-w>@Lq-OCKkeovYmKcFdYKP4=&3fB#AbSJRf{ND+F3>>50Haou5Zi7i!r{~mT+?mn>1k_Kr3AxDNCiSM-Bp|6k z?O{%Lho|Fr8Ky^t_|0L9;mc)<*kuUk;&(p$^!J;HProI5K7xg_&%FsP_AZWtOm$`K_&w;`~Ri068MRuGZ3EzoGLtv zC_C2C%kX5jU8bKGk1QyEl~&~mbw z760hZY`7WutjL3J_8X&XsR*Eb3Y%_)TJiqT@_NUeabC3C6TNaXNS+vbBt4fMu?y10W{ism-~84`Z# zG4Ka##9)2MMm__yoAgxYF3=mWmSC6wu>z!$&bz>6sQzMSf)M`oe-1G}OWb1KlCj0I zMcuMui`t&w-qGIK-qqgUj=iC6%C^L9=56`gR%|QUR=2HbTkE!6+xBeh*w(YnyRCm) z-1hkG%67~4{OykIb=%vv@7mtAy=Oby5x2v%d&q0N3Vdt7~g&Yi--u*4DPGt+TDWt*0%1ld@^WrlL(7 zH??i*-qf=xezUSUe{=cf+Rb&F_iXOiJg}KPknw=!f!YV^9@z6h#{<}L<&vx2QnzK- zmd-6*Te`P+xAbor*b==pZfpG3#I5G78C%t@wOgCEZrs|wb9_)Is`@w++*+a@hi4Qp*s(q;Aq0Wc8AL@C?`_RBctUbCtzFlcg zY|m&fYAdjxo8is|n-8AJ&L|qMJbYK zf|@eXd=4drkB#@|z?F1bqA81O@WrE^Rfk4;T6r>D*|^S>XT9-B4;!Hm>2OxtGu z*jy3H!|7&|;9-@{O67pYf}v zd7r1<+BbK@&mGS{y}$81^Zi?XTHbxd=Y8o3!~VE%(QCC?e?R@Lv)}ph@EfZqEM7Ef z)ADbc?%w;eL;t6`vkt3bYx_U2Y3Y(q=^DDEL7GiVhjb|&3P^{Dv=Y(?NGUBP-3kIq zi*yJ`cl`#BcM)TaG1YbFx5MfoKr6?*7 zX|{|smTAIf;&*M|V&xnpI3thSzmjg7TSaFoDf(l}s##59)#KeZSR%wVZ+ln@4Puea z)(YeqI%IpE4};&&cSejD*X-5#m4tJlyLl%!3xeVD;*~&UficeP(opq2$Mi(e9AWxM z6OD{aSqA3atOEN4!~l{i8%x%KdMV-$(*{)=QhR~;c`u}Yt!ZWQ}TZEsm?5G(pD3a`;X&@1LZVFYb%|}O87x&T@ zmMJ@`Tz$-m0{71DCYlyD92kDES^ls(fIqAzfCEl9GF({Lb9iI`5qtqB2tanxh5=6i zk7vak&zkkP;s0tCKztHZPY1C9n}ieK0)MHg!lib*k{ z0LDds%!@JM!3Yih9&co{@Mr)kA~JYoKtMo(Kmhm4_pq?=wtzKo<8m8Jc?o~`#e1gC z4!?vVApUbNxL}?idzpeizvTozJ@{(OvR{VJkLbCGQyFeH@O}e8^5X0$;BNwg0Dn4f zI(IPV&Pi zKz92UStpn{s5J#g{Ng~Cdz+=Y z5@Qn)zBftq)7tBrbz5wmBQcUZ5Q#f?6A(`QnAj)(nPJ6IJ6xmB;SZ@}?ZmQ>p8=bT8X%W{QkUzTxVG^5exM?tbpoupc#m z!=n)6@`B97mo`(mI;-{E8foPw&3vH{@&2A0A4`xZaWCC6;oB&r*OCw8Ln-|oHr{ow zpEC03Q-twr?(;ngN6F~9w#-3%&PJp!;5hyEc`hpA5S?XJ%!0DfJSaObH~))tWjASl@7?9V0kAF_kZ@5X%)#3wom{{+8i4Ae4HcJI<@@bVlg4j`v@x60>_I%GMwHfEyEjWQcVOBcBAZIG3&#Wq zy*ZD%eE@W{aN&HO*c<4o<0I8HyGcC52p@51&{lUc7TqYe0DLS5Zvz-9P zsexz9q7G*>)O;jHkT}bv7d7R8f{G2BZAh(<&lI~QgPi0zpZ*pJ^$;+*IDVZ}-7Sfxw>zQjV!UDs$9?W-D$ zIs;xW@0o-idAQ;_0m(Nyspn-ni^KER4o61Sl}KI}xq>0+jZ>iO1>1*68@#FrgSC$Oqo+Xp?jf1=B=5mny$ zwQ^}n=%B#l+2hYpsizryy6`gG+c>oMpVL%ux$=;e4U#Zbj|3pd;_{v=4=Kha3(U{f z2R^V?l;7VoqoaHN%qo$ll;ANXM+w-mQhx0qwS`*(wE%E_;- zT$66cr>PV85MWr6`T3E?zES4}f%|)hiYQ1@1#3x~4M~IJ5SBsbvPZpw=1sBUZmbep z%rtB5Z;AO(H7|y328y_t2UBT&rq_?urjC=}m6hxcMUNkj@b|0-ZuU;Avp8?T;`_@| zlJt6yQtQ9Xdlc|P&EOEhnF9BVH2tl1{V8o#r|S2~o?*<>jG9-K(h<<15Rqd3s$59E zf3IAA6&DwO3V6RFz%L(APghNc1}puphRASVBym4-xF0Fp9~s<50te=AphnsKbx`jA zDonpOsK~`>Q^NBBJOI~EsbU1^FC`TYmVo5P$N0|_m|apu9q^00+!K^+zYxGL@Ha(U z|FRzd7p!vmMg4|o|IWv90njc!*7pns4&;Yda)0nT`dxZS?@b}apC{T!Np#4vRe3ug zn1BF!m_V6Ef2{UK;lPTQw^EtHlw7oxBmpd5CeLF3%?x-R*_=U~h0zlVvjpeqoRTeD zsEDTi=CwXXeueFouEuQ}crK{tc5o^F+J#8~Gy634nM2)4UCK@XpWS@uxI zvA{T(+sf98W4pPoi)vE27&z*ViK#5-#gLEujq5or6043L)obD`unY+}3(w(Y z<5Q>LK2a`kl+G-ZGX(C*GC4S$9_h;Ik~SofuiecKl~9u7Qgo);Y!KA7>Q~EIN!@pn zu}h&zbQR1+Llj^XiNRk%B0b0vmGUmB*DFrU(KK4zU#(C}&ZaEmu1&(sH^YmD%PO;o7Gd;rY-* z;olOGOHH6^kf1)^Q7xU0p9Q$^S|UZOJKSd9QFgvriGwirR@>o` zlXeiwB1_H+96F<=wCrdL&1X?*nYJ9`vE^B^h!qZhV$d!U7lLLL@ctK-6%Om~RQ`%n zPWNjCh<{O{J&W^$;0dlhSeSZj0Ki%k_S`nES*EJsnWy#u|&2 zCs7P46OtxHMAzTi4_rsbUSmared}-L->;mX%k^qYSs`Ps@H~ycsrU)%Fi8}gKBH)X za2LkPUfkqPi&Fb8OM6Y~nN`SMEy@z5Y-{v*b&5}*fTp6yR^LL8DM28+VYwi6*$FK# z)N)`Xbwkb9bXLH?H$pN_8|&T9W`-oGM8S0?b=9))?p_ht46?HuZTMf9*2H-Ig$4jl z#Cu#oa$1Fnv4-hfQvq{0x*XYyZ_A+yO1;78K6g)?x6`1t=UgeT=L4(+UMxW2`y)jh zpFk}8Js*+BoFFHELp~GHSs$bJNG^-hM)7|*oicH^0f*uca-i_Cm|Qcxjl;}_dD}GupFFb0*H6FlCw^t@FH7`cdw1`y@)ANI#wqQZgG&AaktcE z&`rD}$J1HYXfdis$A?z|(F*6l@|5en^9q|2H*`5$4>0Z4j>=2GJrV2OHNj!ZOsv`4 z9v=xH(^W8Q+QaL=p1ZPExPw^RCUAHbcnZU4?&$-SlA9SAJa%)j5{6KsNl!jU=ep;R5zZihoB;oPYp`nSLTB@Tmgeng2jcw|+edYyk7( zSg5$jm&f9`0Z{*Oc#_Me?*{>wN7y@D@FPx2R`BJY_)*{L3p&B}ms_^A5l!ex;~7hM zK`vaxbcG*CHOa|&?dxJR(M)zyP~3&_pCYr{nq{9N1`rHK$MBPKz&$;7DtRWT`HE}R zC?73PGkLvpb(^~C~HD>CyOazN6vbCYsXrb+!Z>QM3 zg-W{BBg6v87kixK7|0cU$%C{OgVwf8>hcAVy!Q(3&Rcw*(cfiXi}BiO z+voWM&nx$#cRgAeM6*aSRS@}VkVkoPD#*t?w8;dP4iuxYp86%;d8)BLb1wx zi!h65Phfwy3F^oe2Eoo$s7+`%g3dkQT}PCf(>&+>I`74?xZSMQxJikSVDzfddx}?Advm>p(sU6e>JbN>b+Jw`%7H6t$_GUK9 zVZXw`O{9<0^`iy~cRAu1!xzM}&Ep!i=jYiNqjIWD%#KDW?FdzkYjXTBQE1gS8-$h% zkT7hJ1nv-Z4Fx^K9gXnpyVJHh{h<1tB`#7@lgCuXiQVdvFd z4<;v(9C&NbuDus#io^S&_8ic?=uZK!4yXdqbft8KV7bf0^Peb>4ELXDIT(jm!%$NE zdv@*@b(zp!B*FoJpYLxb!rGVpz(iQ_@_c?P5&rL|nwCAh-UNTFkT>;c46P?Q9_IRN3#?BW8P*tRThs>Q%w}`DXb^fAG?zokF!J@yI_)W z$zCUfO?Yg*_X>Kip7QF>jEO}S9+Py4e1ZhC$_YtDDl&j_G{-uO66Se`vJl$qP4dPj zGr39K7-cEzP0DZ)1?ijB1o4eM4Bz9q^Dik_xhpU=M)Hxwf@vGHTVg`J z20R~iL?n|4i(9&ST8@)(jch79rnV7UbiUBvVV)H4Qm;Pe#u}Yla`t9eFKq@SrX@UbT2y1TzclB%r-_&_E@)*Jn2*O zMmu#LG`W6+G)c9UJ!#Jc-1&oDBn-C z+gVEesGHE4)(}xks4uzufoW;x&NmPE@%sK_J=8o0pN(gM9<#_00~r?6JX-!|umhrk zWApQS3&|5cEbq>*D=NWcjts$Kyb1rdFy*8f#zIeIvgZ!_7}T(0P{W>H5+`21sv8Hj=djBzH{o22GA-7;2j7y1!O?cVdzQ4ienPyPfvlM7nuD0bSvu_eW^x3Ff z;~JIKT|TN>u|lKLNqO(yT>%`+b&MCLc5^vxWbb*=^*=3;#2W2+X{Y9ol%!f&20{<5POJ-H@C}WjB0HI)?fjrucn#5AN&&WdC@A1zYo+Qn_D#bYyTyNEFqI7{|^kK^H^kQ@ z8W5ga$f>F9sBZJhDTPxGu-xYHWX{``Hm;+I(B7XgnT$OXXgn+hUMLPPC&+7y3_?QB z$|46172I%CW4j)s3F$qe&TFDWKE%Vqfp{Cy)SAtjPUTFC>@~ZTijt$atri&Ea-A{G z(nf)0fWZjV_}05@&}j(Z)Za?27<8*1z_3k38{jH`UvjB$V1W~?k^J}i$lof{Rq6WQ z)<=;4kJm^3S>XQ$)OhPWX^gGBm+(@G8rH{RXoN~)`ZXaNmJ)6spx)a+c-*04Fr&bD z?C=OZpV9inx~Y#0X<5X$bL85*zTU8X$Wb6AEjNed`%0Xr_gYmH?~tJ(`{xnVztrl( zcaDIirtOWl7L{>7c5=ZRJ}-biV!2-s^j^|v&A2ij8f}rvk~;OMaQ^ghof%z-T}*w7 z*9Qkwul2k-S7?py{!6Sn$MrL{8ceMrcST4E(F=m*~c8=eTenhNS;*;G=*I8iKOiRx=Y13VabfFvqE5HN246!0%oj=mDE+aqB|(No z&1cOmw1MV!8fMER1BrCx;(c7uUyCW{|}Qe{o$Gb$#<+4bT67UH@UxFx+Wen1k4-U?7`lVtM~tZ21AvnMMk_1x;l9+)#4 zLb$1hsYcPBivPmrZQ9G*1Ui~dudHGnnoDb36K$M1Bsc5hEY@ zve^*4LwEf}u%aCbH2uXnhsWWaneIlzdQmBUtScsgxEgp^j0$o{C2@&0AP?)xWj8Op zOt<`;O<$J*6{x`0zP^7$|5l{gev@^mTY{Ugj)8<*NZ2#$`?4ETnK&dCNiN-!3gn9z zro{^%*JEM?Q-vpB=A>!EDwCv$n0*@K$_GsBSGY#oz9_)Myz?fFZ;9NeDlNsXs(rZi z>9GTgxN&}oDWOz6vD+P=J>S>IOJ+G-{b5Mc^;HX!*@SO$++n9NWcZS}mii!s*jj^nEj!fR zzMdFw2Uq?+J8KpH`p&s;^+Cq|meb^oIyFeA@&~5LBUY`x!=3#?;C@ngso}@Ieo3ih zNvf5nP8qW0i9IRMTto=2JH6D$#fM8ec^eJv*K(G(xNolRLpnn81{B4Jcy8HPYrKAw zq4i`n`;+ie$;2t?$d0?NzQ*Hw>lrG-CvGTKfob=;$0;Ltj7i}jJ(RBtwbL=gOxqHu zn@V+dHEsLo3+&u_@6oXC_&D0o*ixV4ywPB#_Zbl!-KY$CdaBp2Ur5-Zl;&Io`!elz zz9GX*bsUF3#0~I=I9-r)_kV?Q!D0O!Yx{+n_XET~5hBRU(SN~&AT+;R`-OtQfq7Bd zzJm4u<|{kHp>dD`!~nRA1s-oZgjy+>%Rh$aWn5i-DC&khA@Y#QsFBRV>kpEwWk&$MtE01XFaUG_C^7Jq9Xr!+IT^wz3ufp9-x9Z; zKo>knSUqsx@yIK0Cea{>$Z>1;aMw$P}oM<$-JMvw>aTO`O~GDDF7X5 z$@OD^^*Oe6lTY5yME93wlL{+o&@w2vzxJ(RNAnAChNHYZKf_GkF>M5 zPtIjHI;g}FD+qqpt`;-+1O+O)Poqc55&sOS!ih4Cm^ngV^p>oPw@JdM!i}0jj+E_P zPUJCKI?9@IE0m&r=^^>m=r;&KCzayS4V`g26vU}tR_QJ0a5*BBMT6416#_%1MM&== z<2*J!FbeW`vh+ek6QLz5C{UKJjEX`Jnfw!)3B!ki7gSZ*nztqDo+Xj7Oi>|=SOtzO z)%jv7sHRd3*6&Vt)HwFuOV`|DyeVVJSwbz-vMD^7bln&jCzsV2TC^*N!=HB;_$nwgv{?CmF%Kx~6>FLu-+5oaHQM1Q!Y)Qdw886;CCl>to; zz55ZX8te^J2&;^f@?}v+t)x7$SNPDdmjtQp$o}rIvlbm(>(tVkj7ea diff --git a/python/DLLs/_lzma.pyd b/python/DLLs/_lzma.pyd deleted file mode 100644 index 37a32aeedab7aba482918e10b725cd6a28e09d62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157560 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 W`q*ViX8;6{aMcYP!*^r_^M3#zfke#! diff --git a/python/DLLs/_queue.pyd b/python/DLLs/_queue.pyd deleted file mode 100644 index 0b8978ac3ae6c942b9bad96b2ab6afa30df86ac7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31096 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

    IqPYTi`Ur9M%<}@t4$mg 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 RoV~hgNavVL2gx_1{{u4kc-H^` diff --git a/python/DLLs/_zoneinfo.pyd b/python/DLLs/_zoneinfo.pyd deleted file mode 100644 index b2b9e85f00686818b66adc1e9f71e9e559c16d51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43384 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 diff --git a/python/DLLs/libcrypto-1_1.dll b/python/DLLs/libcrypto-1_1.dll deleted file mode 100644 index 6610e7b63d9fb17c452719bd103f4d7188f78e34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3441504 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�ceObKr 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 z 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 z zoaMM#P8`c|vYeePjZSb$091A-kd8pdD8Z0ul@(Qj%4*5{ur&HCdjg<#qC=uprXzsX zKz<}zWqufhGOHGW5PhRkDI8kGlN?;8K>fqB{&1Klg+mNNbmK}922bLD7XLgJ4woPt za<*#_2IX+LN)Cq;{<(12g?-3_vxdCkx-7Vp#{cPvXFV$%D*o1mcf%~sztT}=_RadQ)q*(kTq6Z@^sw9*TcT@) zLFZ}8qTUc2E3l3&dO}6MYxHRk`3IIX%ofojtK-oDpwf6z=?BUvqXYX#gmXBQYmvS73-N#MIGnP97CvQbNHGu`tp4@Q1_$ z{0g3+^59?USNeLT2yp1Y^3Ga6{#qLFiaUfD^wbM^5rbcp$vK8$M47eU2{z^zi>>{3 z%cHVtgrnm$8q9)w>=2xmX4lQb#Ph$T`2p~0_(g*-I8@A)VCaTH7~G(PH7t$Vf(B)5z~-Au!HA0L z(j0bSxy}J^Ew)w-ZB9v4ClxIF?!^j^^yU?1~Bksx`II(nTH_e`U>DK;3G_7 z^hEkoNczj>mt+V~Va&lmKzUMu?WACAzDX{CK|iA!)oHqoynVe@#1QBd#*tPLW2-$( z=d9>7kj@U7e%4w|ywKk(qUZ8bodXn?_n zAmW`#N8!I>d?OKfB3G`htq%OUa>cfM>b0;jGP?K8tzH^VFj256EqEykaQ=R2K-~BD ze*;3UzyGUreyF-UeqhnHny^b?Fa{Faq^?fDAObxqcq@e%_$y_$3N9;{m_WR~PI4e# zUne=ByCV}*!icFSVhUM&b`voTtcw)T`-jto>r#k;^Mb;$VK@9&FfoC6eZ&Of^$}Aq z4_&Sp$jb%Ic zdU2PDl1!F?gZZNk3)-ad9PVM#hnx!CD9yvRAf z_XxFqL38XZ4Bc`Kuqn%Ew7`P?k09Q3vWCsIOWl|s@S=zhlAFDh7xfjmlo$0CATLUD zaWM!#=pa*=rnRkHYrh>VI3pPK+iUHI)ske)nI`XIONz-wYynPZsrcd5k`AsDAr|Ai z33iL=Lb@&^-0bvp!})G>t26F1;P7Aq4zo=-Jf4z1R<|l5jE+K>o=#K340M_vmO!Vu zVJ14w4@>Ffuf=Y^+CEhCkpT*+Te}-8!JK`KaTyk7IeVH%H#igjWla{{U=9A99)}bI z4$~5FNHgIuF9nCpG#r*?f|PDAR=2mOn{^BGX)=r^!tg(Y|8e|V@o!JJ=rSDXy37I% zx6Ppk+Vo^y#%bhUbl|Y`4Bfwi4)^Kl_@IG~vlHm}xQUL7Q#kv5X{c4Xn-2Sdt+AL= z-%+Z9Qb#FOODQj^f=5i;P6-i4vS1UEKkwJk1*=u zpD}{rc#9Dn#|uWV96!Yfp5vz*!F2pwBe;&AZ_LE;3u87oL1K%MET6N#Z~PGF=DhXI zQqy(E`EH;>)8T-oLvviB!K5Zq{F~VARDrL3e)%u952V+v@w-bkkU5}XOrRc8^EXUD zn@DY>Gz=QUMDqQC#?ZyBqx}G^IY|ERLe3rK|8J9eK>yKw`YA=D1@QnWwfi)*8i!>~ z?q!2b8XP!14k-p4rX}EzX2M}!3J#fRI4sL_U&!cIda%9SecW5(KJ2Y@S9uR1@0Jae z_iV;hn{jqImoLnB)hrlQ0JV+;rzkKS{}l$57;D1e!89D+&8Az=W_-MX&i5}ZaNn}@ zq-+*S)i{&1D{0x!q;HrE(7m+3Pa*u55#(_d?PK zNyx<{jv=zHSWI8y4< zBVx%tE~`9_tfbXFkAED=dR&Og*aH*L<5J)YLk0@{B;fr3ydMK@?N`a?xM(P2jlp=K z2%9>Jtuec;Yb&uo0H7_>5Y-}s#x9mX&=lts@ay>@E*>#c^zi*aXt5w32XHROfw=GF zV@`0Gf3{-zJ7zxvo($m0EW%oK$%RnM^=v>xt88H38iQRwh|w5C|7*+#5Ex?rf;@hH z&^6SzIpCw{pv?iRk1_AB%fKS#LHPTLv?_xk*}`~C;3l9)lY}nv%@x$Sxib-`blob8 zF%3t-m?_v(4T6293A3XM*;-^F&BE^C>|=~|I*QBUcoRnG9HxU)0Bsu9dQ6=C8KbGL z7_-8h7$L39a`q8OAc6^^1*@}E`!jZb9O$?Q5GDh{Lx3;`5V8Q_Ap_0F?ynP%x3|~* z0XvmwSvQRqc;|8U=|-2jR(c0$vUI$3G3 zfK5)j*l--f{TPfuv9KPnB?_HM3ufdkn0vIG#(5Vny7}T`v?U7NPrmrL(9472@m(0d z^2H~ty&7ms6o#&Rv6sdb7+T*Y^g3zn?M?%ZcHE%BuVTp z!89Xh-(t*$PpNyJ7(*q4bZ;3p{Scru%7e(FAo(e@XN;O)y0Sn{O>k=<6f+YKx)-#R zu3&wJuv&~sB%p0|7f%qPw;5KexYdebx!5X*7wR5iC?kxt;vUJNRrG{XYUht+azGtO zw2Cc>Se-N)NxU|chUm%!n+4n1Kp!ru1)E@uvx>WzlDvpHMZ&#ZYM~3Xuf_g_u?%cO zN!oN zp3@9;(lXM~Ny}K60^7oFKv>NhV>Y(TA@QPdy_9&>xIs$1ZQLj&-Zwg=#3#lgmS{W% zAl=ast@;cJ8AH0Ru@P4@Fbx)LWekglRm?nmJww%mE0i5i#7s;<)~iO^Nr}YUMmZLem9>RRnIFle|!J3~=5yWxR&~6L2OD0Wbx`i}Ol#r4pG33yfG}0GX z_7X}>C(E8omc7O3AqD?My;O^2Mz!cnwr>b+AX|(Y6sSv)Yi*Eg(OD2*WFQ6cRbw4M zlQIzsL44cT#Ln*=CRqlHAatIi_Tq2 z$3eA*%QO)PW@_)8W+chv@Yn_ddRCT8*FS&qCbGa?blAqNc5MKT`j5c`MNj;E_C*ei z90*5kiPSSjsDZ^eP12-q8$vbYB^=ZiV;Zp3*)T143AZizyLmED(j~u6y~t`)6U}3C z`9i*a+nCAZ^S*Hz%a^eXl(BI3{>CnamrcU^{)ohfB)qqcbndd20|n~-fm%`rfhqcB z_7Z3g0<-OKagjJXIdP(%b(6%YadpYG+XxDl4K!pm2C!CF)G7;`GR04f`Rx3nu?T09 z3pr6LY@)(iKGtH(RN( zKA;9rUPEa0L1;~^gp4*tx{%P4S7OA=p8ki~-Jqb|7>qX6KzI|#FD_%Q?#BgLpZ#~< zAMcN^fBVWGUmxojU+X{zLKnKI6%@fP5n@AxK}jkIwvt2;_tF?kh3c{h@x^BrB0t!Jjy)t^EAUK+m94JzCR^dRyL5+ z9Xfa6e<<>fWz&?MW6LFt(EylrQF1L}mk`nU2N0EG%8iPqu`1Mmn82vLWMJ50%!Ze# zdk6E%tlLWAL+J`ULtO!j)D>`0si#>fuz?H4InG`Blnp3QmrOKu@=TAx!+rY5N9giz16T_!YUFv7heYhVt zLwIXR3Z^N9OJl>EyIFDfD z)Y&~7paF1Tl6y{&F34Y9HFXDBMdfuf*!f>@lA)Zl2Tb{}QlAbNl9$}TNI+1K&H0DD zq)Dlf!V(gtp`Eiv;!k2$FI`Az9SV@503aah(y=H_sgW5_184)BbKGS(=Yakh&CkSK zVtxiIb+jV(PfgJ%{-5CY3o%8*)@})YX{Tu#UiWn^=77dwE@hlFQ8P}Ss2LY9QKP#d z8%;?I#(Y0lhbbBfICdEqb(*G;fsX}nY*awEiMmW(%pa1Cvt81Bhxwa-MK}TS4>A7q z@A%<<)I`nde46RFa~)2IL_cbxW)PdGnQH1VQR9$;35R7ZPK-6OE%ekg&F(N$^D|ap zvLVDw4L~R}HSfTM)Zq=oKQvRb{D)_1HnFLQ&=irI*(;N zj#D)@<}KwQ_jd49%>p(zGNtoW4Qqs;xtg(oVD4uEni4Qq1GK?&HH+miOlA`_SMxv@ zb2Yz}=`sA^Tnz~9G+Fa|EId&2$dffqmp@q(YW)@c#~>5=FHgh-TM_FkdYG41`if1s zLO=4dCSn|%O&YUwJrVOe=)jMkh?xw{>^u>}jNVW;nbZkggWy4P;8cSr#6--u2c%jQ z(n5C!gVbN{9Xv1B+921WbLYV%oBFxLEKITtfyOz6m(HPPVMy6&Du?1P_1}VKVKf8; zl|3jVdA^BV%)-3d#Vm{`STq{|uqOSgr&^$iK(LPHH(k%d z+(7mfJPWgvW?_{0%VA_~^3A_EI?lg5TotPQeDg0IypB9Il8+^UOUDQ5J$9GD1}jtN z85j?^q~@V+4K+{D49qMUP3IYy4S_CIcBHgULHa8RF4PQ6hguHcuDej~@5V#l{*8V3 zIiY4?PF&6m%z#icFwjEKO&UVyA8j-m2)IrUW=TXQTo4302M?7TB-jqqFBN5|h0+AV zHz#wGI{hL|WBCRaDG-luU_tKazdHTmxBrmyFG2D1$4#_^2y>)Ah<87+i57=637iA9 z4VY+&xtxiX4a!8z!M&31OBO>z-J#8r4P`THfED8W1O2_X2nfusV-=Hc*0Y1z8340x zj$F$jBck&UAWD#_O=DGPqGctUXt`trkX`4r{X`%-oxX_{55fSDum^aC6(3!keHg5VST4*6M#3aj1RHgx#_7F{0I8f!^=%8~$O|n?Knq*lY zYLewud0y*MlPs9FBi=gCuspX%mU@U8mLN%z+TBlu?bB&RSMEc-cX=}`Enky4R9<(U zoz)qZjj->yX_HrPMmj|6Q?x+XB}{Q1Thnf>&uFG+neiwkGFle z0jFR}thSA`jB2%QrkOTQT!z*EOg(R7Sa{n;nt9}Ho5>t_ad|v1HhuMLq|Y~VAJDc{ zdbWn16UI{yv?*n3ykMV^B-rr+3L6b>ZPShMf{mWv$DV+s_N$I8zE!gs4W{98T&CZe zXPRf2A2v^a_@S9In)7z3KUD&%1XKyA5>O?eNDgjjjssvOCs1i^mph`fMfGPo1 z0;&X538)fKC7?<`m4GS%RRXF6R0*gOP$i&BK$UO?eNDgjjj zssvOCs1i^mph`fMfGPo10;&X538)fKC7?<`m4GS%RRXF6R0*gOP$i&BK$UO?eNDgjjjssvOCs1i^mph`fMfGPo10;&X538)fKC7?<`m4GS%RRXF6 zR0*gOP$i&BK$UO?eNDgjjjssvOCs1i^mph`fMfGPo10;&X5 z38)fKC7?<`m4GS%RRXF6R0*gOP$i&BK$UO?eNDgjjjssvOC zs1i^mph`fMfGPo10;&X538)fKC7?<`m4GS%RRXF6R0*gOP$i&BK$U7W&cb02A%4q>^yq=3G#D$;*sPS=vd;t*S4MGg+ALX97 z5F=;-1NCAW0FV<2iJShBpvoeIUOy;Iqe<7@V9{to zv|p&kTdC*7g;I+N_7NJc4H6^yMzZ#TL2ja5EN;Fc~0ymV4qv49OpDY>ybF$P+lXDwWXQ1fh_VsP)%u zJHj+$t5V59g-9rkvFXxJcf%SD{UrH(+s=MHG`v{CI~x*tXKin8;9hI53ahr3&)KWt z#5~T~n8-P+k?-buZ5OmoKBpMv5Ae=oD1R9FRn}g|tlIDSoc+kp=bd%Pr}8_kz4Cc& zu~pp1J5M0*Xm5dFUz}tg(GJajiq~!v#9ZKGRkUS-m=7epvp$j67I3y6oNW@UFICUk zX2uD&RD%Fc;stSuF+qSHCkf(Qqlpuz8#z+z6f(wX#4MT(7TcVczW#^XfAiSNFto}b zG`N%$p=ar2o$L|~j!Uvj`4Wnk4*T}Vmr%WQkky3tuK)C6dwT~Vi@iT@9imBetghCC zMQT=`p`*^?Y|hi&kWGycg1#XC!W>K!2N{VsbK=#U$bqs&NfXT0$%fg>4P$0yW-iV!Wn@0GFe_{Rtr?3S{kdjp>g4;C zzTVqh&M^}&nwIh6o2TJ$cyUprReT^RS&W%zkG-0|qeA!GuUUTfn>f|Kgu~_4Up#{s zS>0rDa)b;s>uy{`-ffS7_nCK^6Q?26q}2)HJP!f^0_L(J-uC8tLTmeQ15Q@khB9{g z(8Ep}>)2^?6Hc7C41O$A&)XOl-nQ{Wx z7*us?ykMV^B-jxEZBt;Ew&}1-^kow`n_x_8ziO287R_e(Tn(4wGX2&((>%lcuzC8! z56zs>oYzGsTfL=9K$XBxQUaml7waO?=vVY|&YJF=eazKjvPOJ3LbOJT_eXJewCUEo z6{*o!M2AJ(ZV^vf#IqLhYKvH5Nh}|0U!!04{^R>C11l}!)Cfyrg;|^Dbo8)@<=Q+; zV&z!-t5;6_+qOE(z%tyAL=Cfck25#QB35dPEQw`f?Jq`GW*Ur^ffcwPg&Jn_j0d1`P?U)n0zI9p#mgBx2HO$&dXC7hKmdp4*)jjjQgg-VU{+qWxKS9DD7ZQKW z_=FE7{QX1X4|{F=1qr_)B>u8DvmcZ28$;s%w9O()_~S$3|Lmdmb_xH`kof<;f4WV= zpAZuNjnV6$knoQPiT{;FZ-Rc3e^N;NFO6IN2MPa}koX5ge!)xl(Y`_QhYE-_=C(bS zfwiOvvv0b-RVo;l+^ZHUVAi@UVztxJO`FF`c}N{he>FKIa)+`~Xz@~uSnJH~sV!oq zYDg*WeQ?GgM)cLJ5YXCdpFY1zq{)_8gVyGIl}Nk)728B)XEiple@`+wvs3 zqPn2#`QCe5B)SY;&~-fa!DNZ95na&Lt-kgniLS^l=sNwL_q;?`|1Rh%56^g1qAQ^b zy4DFd+b`9QP$SZf*%9U1 z1aGN?5?-z&%5K-aK(-4ujh#`BE-Hm9CDFpabY%1JTa`y7oNx{uah`tW-5VsF@a!FN zJ~H(a7sClo0=YDQLz7e}Pt9t%ad3;J7c~x~h*EjdU8kcvE~UnOqy6S_mR_>^0(pDn zBDq%pwbaCa9Qf*=EWL;WL;w)ET`uC(;Zkbo(HmYlZ|OxU0wzIfrCcQMDqKp~(g(M!5mg0xktd(eiE{CRN(#j7rBw8T$(6o4t z4817Pf(8#wOYFF?_as`NX`yL(CpvPXL<@90G%e4qoZKeS0_zG*%g9r=e=E@fMF>sH zHzoUTmS}+rhNk7^J-=vVv_NAzlVa97%y8@4U1sfmE@!KWIwsFO+ScA~OV-#Pj<8uH zZTCkBB2DWqp$Yl9G|fNV7)LV<28?0i1Ba4qzO<|HoM6AIv9-M&q9Jj6ft2%D`Np`jRivxdY-!ZH%zeE_-KX{UuBYqfFl*u=>m3(evxglh zbf3+z7?WJ)Xs?&vGMGKG5Jk={?Nn97=O9(=XpZ_qOX@vwI#mMaey3SeF^(8awR3Zj`qe z<0!K-nqlW$V+SADkGbfkh0|PP2ORj0lIba~v3(C5rIpKg*VyO-UN#v-G(4tvjqQ1$ zjj(J46(JH6-VZdDiqOUdIBO5g!-1{cDwCa}E02i5_w3{J5R zY%^6Zm%uVgIRL*vne`HIMze`B3M3TseDo*z=r;jb4I#VN{jWDI(R4;d3|LjbZQ zAUi{_3&WW7mifh$K-neHK4cK4EUXkDt7VOr;zQ<ztNWMU_xnwcpy9L zsvT|F1A>&+Fu3N7w&eNIK!7ruGzOBj2!K(mG`WkjE=DS>J|tmsInCbF3<+)=W+II9 zgV(!iAJDm=tq)jgF-bq)s7P~M0$7<2EZF~F7(np7lw&M#y=xSQVyR&_|Y&73^)VKz!B;MA2^e4 z&6lvke*spC4^~?J;{fHiZ)!TNt7eg=iBeA_xXk>;$tE{{v5GaS$36JsVNj?kau2w8 z98_w`nC-j!Ui=>9YCOydxL>}w6Lf3pfChj7Ex*3@Tzk9j23gzAuEJ7?YYvk>sesf3 zFy(8QSdf^2286L7m0^(D;-vSf1WBb%dRLinV`d7G1bGjuDx}n80|=`sa-Te(OO3gV zv#&}6g;iDVGv^xw+xy0BaLU=2rZKMvYO9X8i{a{KM^|~>1?SI#*s5l?^Lz!Llbc2! za`9OAvgnB$TxRlx%c7@lbT7{+LSlvki7F)0i;y^i#6k}eUL=+_A<^tUn}KEB`l7S# z?ULUiZ$(R_rc11k@?wD?T4+s3FeX?NOSqh~X}ahB1ckwRxzRsk&)MHMPDB4oH+W+_ zJ8e#)afEJgHYc55pu4zUKTkTpxlB5zy@1SlZ{m>oAr8wnyH7vGq=!ynwppAOCD^a4 z?xDfb#G-6|+qP^S)XTggBaF*AluhNdoZUv^v)Xx+_*kZE_Gpd6IN# zY5N-`r(Es*ndB*}y%{h*_+WRn7Y)VCaF%xhj1SHid8sDJ469**l8p_k+Ciqbm#pm| zDpYyMs2U`LS{B`hT1QW6bO9zP8=Yi;utZqiC5%q6kAkUP zO{PXxR`=S4_I5Z%jl)$#zIw$f3qo4W05UW(A6HFZ+0nOQ@Sd0L<_J zWbtr@QT(=C2lSFze%+?;nMq?84x^0@=mi!3X%cc-hir==FCcyv^q(F^vv z=Jd2QqwZtgz3$J@O_F5iGT-ZUvc3%K#?(ez>LkAOpzIjB?+bRg<{*=iw}X1?CtTx3 z>zYtKSd^~Xz6>3j${>k+a7U)L1;ZMw5JR2O!%Wn!IfE53Q-5U- zSNLe|e*IMUm7t zd3rQ+ZqRkTcR$Pf>BJz7u21i%URU&t?9shjgf^U(wu64TL01}0Sa`>b4%g=7$+t}8 z4HL#$4GS{nJ~{u9%iNDZz8^njcqv_7>Jt6OuI8&c?_XHFD8&AQhiS{hrQ*2N#x@pM zZSr)Lyy<{#L6A2j$n#sAo%JPn`(_P<^i?bbL%R(A(_0eW+n`Qu{g>xZRP?F@{%@5) zi2V-%!^_pj;t&!9-KGgT3U0YsnJ=*;&l-^Y&mQ&QF~AYu&jx>TzkQ? zTLP-c<-0583BFtbr5oQ(U;m>EcP{9s0IN!hOC|^(vXWDbVSKNOU|?7S0>F)|=)*4n z=w`WScnGN20yo|vL0u21*ys-YQ;gaWP_c7$Vvz*(O+YP^i$;WiY5-J^1a$+T*2zV? zg@B3~kBLnZ)DKDWa?$P~peA6~o&qe9y5>(7k%vdHD?Gpm3R4lnkE}{c8!Dd~?*&aTP6~=5qgms8I ztM(!s!d-nen#SHi9X4xXA0C^UtoEgPKCy`G$d($3A*cb4!U9NH+Fa2e%N8Aa2!gm0Q@~5h1aYB95Yypc z7h(#ybFV>q9xdlsoNn+4W3w*f%5+_3$wVA#+S7Fz73sRHQ(@^k?{Osd+?B3NKZeA) z$aG!fo^)O1Edyidkw5QVls|<^8M(MPg>ybK%8=nLOV{0Q$wislErro^JV@n{>n%sI zS^%pAu&nbqc(>#4LaqmYl*nr8CKb(UA`0>-XS96lG*zOSRDmi|rK}<10RF$CJD?2gg<%yyvKRXr zBdu9+_B0O`tMFgegas=N{+u3%6ax;^5^zW};V>@+hs-n_mSv_}bQxD2z{(ZLK<0gg zA>9n-bNQTly>88u-Pp~=da+yGw?ptG(3u3?a{?BwZqjH>5qILC(XAPSYZOo5HfuZ% zLw1^JLo)y`PN3roQ?pr@F)g7v8Al0pMS3z2z?w4}q29G*1F*f@EftXH?Un{+nMXA! zg!{>?Kr)rENCr!%6VdGIsNSqgt;GMhPQM}r=R*vOo{m(XkkBzV5SCfzb>JERlO=#; zWfongVr(TW01Ofh zMEy2B(%@T{x)TWyLh`Nv3uvfR7vqdXL6TtwuQ%9fJHx&Jycz!LlF;K9DH= zq>B=upF$^t2&|;n6hS4uP{uUz~Sv1s&oO6-x`o=x(;>ufMdty&OJ(ln47o2jR$;hR(DJ;oiy;xKKOB|H>DcaK17>PyP z$C}({7L>WGy=80*S2P`SvCcIM{X{IwdT{4}yPPmoqr2xm<8>i-J1&|=BfIJ6SURhv ztGndHdF-vqIzR>UP;dt>io%e{XEn>SO1rVd8Ol9_rLi*^b^l%b=s!WOo{8YI3gQ?H zHfZtNtmo`}0-w_mrdwMCbAmv0$7FfY{t#b(s)OfI z5sfX@Kf_KO&VHW>m$&pn8v8Odd->I8vZx)L`SJ%@8t!8ItLXj3buqQ+FJyI*M z1&daTac3FUs(ZpW((3Xq*Vr%(whs2R?4q55i;G<5um#&#eYOU^AEicnw=pQL+At`I z1O~|?tU{9ng}|Ckz15yg4dZJp0gVNL zc+bi$)_8pgn4A#k$QWb^3dVP(e1$}8h=P-;TB@vK5xSW0A3TPpnc2O+G zCM%HUG816d{-l2aDnjZfwF*<7af5X=*mTJ>lW7mr1z9nNGXXHAked%wNlim~;~F>E zawYa{G6iJMIMQg3Y|YD+xJLL^r~PQVONdstIK(2BocFqkcm zhAq3DS>NFm3N)&EtSc}@!C;uGTwoGF0|5;A5DCnUU4d}~ff+6_6pEMw5X&Wb+86|7 zv7sXv5JLka@bp?&U^WDU!NxceZ)a+j+;>Sz)(3+~=>Wo2eP-c`WkgD2pAPLyDiI27 z06-rl)Q~s2XL*a<4|vNNfzEs3jB#khHlPcU*fL!uoACf|l?%4DgK2n)l-V(353_iT znl-w$uhRZ73QO3m70q^5{%5*O9lYiGj{8@jG=aZdL`(MTc+TxmP%34>3Mc(cNzysZ zD4nx2rSpdQ(%HdDXU`Prtf`jHh6~c!R4$#<+|oJwW$C=ZE}b18NoNoCZRduq(T)#~ z>`~bL#fXXB^nFTnulAlA71y&O^6e{T^fL6Xx$gZN(yx#2*KqA8aSQtoJ!_>OTH{UluqI)HGaNT!1s`?yA z+5fA3rKMNzomTYg;sblGFG+L1>pHY`(6)KGALku&-s;HQ{&`_b{-}awJHFm|e)rFJ zWxqUjeZ;S}zVgEBcfS$!+OAjE|Ng$;#lF4ow{O1r;9LEFbMV(2?6Y4qzI5c5AFg{` z9BMo9!p5A%&yC1#UA=kDinU{&zxWHsN8uk@KK{j@^8a$hr^26K`lRTOSN>tj`>%gc zw&B`$roZ>QcRgR;_{H2!fB0M7=Qsa#{%3#L*!0ctua|7z^wsGtw}1Q0KmPvr37mN{ z_fPDRQvCa6?tj8wr%vx*;W>M@w9<`j%hjXWQb5XM-1M_gtKXaxX+n&B#jg#2>%XfxgR<7F$ z%;<3T-jlJw%Im(a?l0)Z7U5rxTkUe*O_axN#xkbvJpSBQbY!W4-MN8y^`>n?9Nq+r z_sv}?*dC0O-Z0l;!(qUj5RHM9{$FVNvHy@B`_ZlOVw~aMiHLW&3L;)KD`pr3@itDJ z8OezmdaHPtcODPtMVD23tmF7n(Bk#HGa~U|7GA|%&)x)_&x?5iUZ%@l*v!(o99{vf zMLyo`TY@wvR)|ZMWeCxe!x^KHy~*^YOY(5o_Jj%PjC(i+Ec4P6*nm z8S4GG?ER2<`zBt-DW>Xqy!trD(G3z)Udc%G@VaCN{so*ioWq+dIa_zmhIR^Q6Z!p{ z|BDg{v3y|CSjA?%sF+JUjwkOjA+x$CATQE1?bmd$id)SCw_3&R=7D=`6CBv{a;+`Z zh5atq`pcLHI?Mx$Z4-*@5!trXQhV&LY!f_E$wO2UFG%LaQqJj#;+!?ui0I&Z72ia_ zSJ%+dHlc}CY@vz}Yo09?`)YRh;R943!0Dsl(X-;Q439y=W0df?fh11o<*?W$Bw)rW z+hUtEVv;?|hHDej7UECDBt3&IvBv68*uj`J4=l2!9spbk=rQ(YXAe=#$hA#4512&Y zgeX>?2xE2n`|1qETdw^?jFE_#AQ0j!Lm|%hBQEm+!44q2QaTXvX$5g)Fyc60o%kTc zNit#%t-8KbyZDJgV`GGkamirr|xwhOJ zP)@gIA=Ya?|@DhsSNEVy;)gF}2wu;qev7E=7pK$?McE|pz5ms2RvoQ+od8Jj` z!pD>gB3^gxiRYZh<9NL8n=E^qli5GK#X#Ck$&BBsby8K?_{k+vz2o6Frt<`XEC+C<4pb~`H@ z_om~4N#q=(n>SGE5WDxpdfc0fhi{Q{itatiij_zeH{j+JJUNS-jSMO)CqaE;BZF$9 zn=N#6CMzd_&BA*P05*kgHZZWPoCNlXA_g{%ZZ;9|-3-6S?2hUcW#)|O#sqiYQoK-Q`Kmc4us~oD;A{aAK=>(R^ zv1CfDnU`mXOeqGJ?scD;?{wGCucSryZg}{#2uimcnpK~*2RgT?a<{v@asVLhf!aM* zxgR7|f`rCdB(qX2N|Z9emExrs&RL}oC4kA&Ib;C_bnWPYZWFVF&sypr>XRURFKDJ# z$#^;&ISu$XgT=#O`hHdkwmaO zj9+D>4w)KFSXS@$%dUMqw8Rm(Bd z_cF4W$$r&x4q$Q#6*FI|R0NvR(i<& zQK=)y(963qLzmRKgSESdRrU;N@$Q$i_Mn;25+v=z?vIpKb2$f;7UHrLcOR%c>V7Ay z7%4O&+OBjDwOFppIXLT7I7_H<_MCr}1v<3*@i0#n+`@JY7Xh})?NxJ_mR6DJ@hcIiOnGC(_uTBV?bO!O2{P(TDy z!og^(1{IQt9wgFqYvv58eIs3b1%=FRDAXGt&Ff zEiOsz&t%?3piZG?E6(+(bDSXPhr_1w$;_%zxrN~eC_)+?<*7_p1uMJ#N%i2!PPiDW1}kqo6LlA-iOGFVT9x4*|;@N)X8;Nj&O1WEK$ zLVlkqXH_hE>!VJ#w~IZ*NfGGlM_R<0c!M-PpWv*%)=HnK@r>Z`Asc6Xl=6uOXDuGh z!Xph0aaJw*ex7(5veU2}nfO3cPK_21A)+&0eI6B+O6>kWJ3_Wxihhi?JC9H9_I5Eo zxeKz;t$FFEKR#i-?IU1?CNSEz5#3K#vGK|xBm=wP|MYmpy0(4EZRjOC@b55O8KMkV zl)=hRYOLjm^RJB+dSzP%f)41*W#puzF%qos>f19=cTKCSZeev#* zl{?+;$_ws0E8Xr}D)+i~HZC%_zbwUT(i%*hroAL zX#>*D?y44S{B?ILz39FPy~$@YOigY#in&qjCd8}jN^6jA#=n#?-5c?@TPfZN#Q0_q zzQrw)g|GaDj1;~5OY{atVkChIF7s9Bv;>IgIPM*9DPp2xsC$>5a{n1v{@jAVMxs+l zWFmC$MTd893%XU1qWd-UbM5HoLart53oU6WxaE{uWi2G|0Yqd+*mNJR#9RFy2B#mO zr|P~?>2^7EBAMrM^nxPOb@s{8xOoi67B3aZbRZgV-iWwoKRiX>|r z)>5w_M7xhy?sYjIL1!Lii;2#X>jQv43E-?jgRysPTGp&+Ga|pwsAS{q>a{JqL1YMGwsdZNtbTy+IN|+!x&N$?ITddDm2{% zG{>9^nmysJ+6$T%c03*K8h1hC3a9)+G*e(vAA}#J0YA|8K~3JFor9bB%*qLv`dK;Y zRUA^^#9`*!I6V5l)w}Xf=3&kSAxWdT)ET$nPS`Kx8TIgd7^@%hj1CLE4v77!0Hx_i zX9Xb32)I_tFo4L%v=RHk(X(H7`K;_|BRKRA#6$O#`&2xN4*11MCyhxygMO?O?eNveJ->|kSwU3ZKhGZUS<@RmR{v%MJhmJ!h~?M< zB8Vph@sw3OO?!~=IaT|rNYlEE)9WUkH(hjFhkP$ad>WpQueg7T-67qrT6{|bFB_*1 ztHvdZ+GO#b2>SYKviML`V+6gA+hU6_T5N(b!h#R5BEQyxqEYC=I>gvtCMVX|B7T`X zusT`WBRp4}5n*2Kpf4>ZC)VmVIc!%aYhB^n&G^(}vRIR@TNv?tverqxUsko+)*n?p z$=aC_;T3pcoOyK~eT5M)b(<<}QzMeK2g38s&b+8(u^N@5exIx@V--CNXKk`JHIk4< znOEo1=NXd|s|o4U$YgCPVa<(B7V*@)E8_XEWbGbSvzDQ(N!Ct^B9wabYA1cTF*(u0 zP(~$dcMwYF)!-8~qkfN?g~5DI&=byBFiM|vlo_3>59Sm&!@+6?He(5A9N46fJt}O* z2D1sAsM(RvIKtTt1g#t|JHBtYNGWPHGIEs6wsGW!cK+*-w1qz)yl z0t7&x&}0k%E2jvck7RxUhFhcf3LRlg0p}m%vzn~6fKgC5k7a%)&~E*V#uCaYV3aa}42}4mMZglbi~h(>k%~vs)jVlk|i$ z4SdpPIu$;rcjD7$w|+j2gmW(Vq)&G$e5Q5c(`UDSK9dONJn%`M^Hlhp+lfz~-TL{A zBAoNVCw<~m;d5RmK7DrU=hHwqGr=c)_EX_=ekVSCcI)SJ1mRo)KIv1S3ZI#s`1IMW zpU+6bxeR>L=Rp-dmvrLOXSaSn`xDM*z$bk&RN-@3Cq5OseOPbGb{pjQAqTrj3BVrl zDLAGNiYgpG6Tq<)dB}D-_Ca*hx?L2m6+@O^yb>6H6A^zWF#V*Uq+|nmf72e{4dGpyU>r*h^n4h3nOCL{Fc&b3}($|seaa&rBZ~YPq8Yj#Rs$IGgCin%+XVL zrH`~KtPKrj&1a*2)|fA%*h-&oRai?1X3b}yKGtTEiLk&*A9huE8xhQ#&pQ3QF>gyz zl|K2Z@Rk(Jn_`-eNM`BhkU0eksq{%$g~KrthvqFbE8Z!jqI2m*&s4TV<|TS5Jz(Co!F0mKcBkQtJP^FK`5+#Y%0YUW&Uwwavm^sB>WR7rA!m}^t2J-APX+O_w_(NfrzPPLK>pf@z>8ijZRqnr7!s^ z-238hAoo%T{vP9K)4CHOV{sj7A=Oy&Es^dVsEA6^jr0GntQ8( zPV;X~u-aFdto8*a;SRjMO!wSxoA5LhJv4Q5elkYd$u!bVW+QDHW}C8)huJbt+a{eC z@T3z4`1s(GfKLVE1?t!~P0v|z^!Z?{ip(`m3*4>tz;cEwYZ$x9=v^V z*b=iaq%u4oBUsGbjJ3tS5uS_sV(jx&**rYfIPQhmq4c%NFs^<3ll!Pj$LE!m+G78| z@y`562BgTcF5->w?F6>}FGb7W@V(I;uMrN3F563&<(aqL0-cIxPN*T=mNfUv=g;Bd$sla+Ij0HWI#+?E*4-Lg4 z(M@7g0&ECGlaVsQC_+f1eugnj5*5|Zvl-M$7*0~&T6n5 zQjPws21ehkhSp!hz-nN8&1$e4QVk=kfe|#T5#g_a(KYzMAeq%*H>4UvSq%(>S&eS~ z8VRfh2D+>UyCKyW!D?VA%W8D@*GOVDFj!?Z*bS-17*+$rQC6b|v`0^KyRk;4E~_|( z+Lcx9A$FJA8v3PQw_P#SwL@szW#FW4K(mpuJ=wcH9;&76zftV3OY7yydh1WZ^4Ei| zu(7&L5!WbMyyn-)Zj4mmC5z~#;w#9QAR=?uZHm>Ibek|s(*HKh3~+bs8v8=*HBV|e zu?$8uJmMNNj3#`$V4up0ChInpFz7Gz*YS50z7TsG70rV|DMkN#P@_O=!H=U=F8X6= zy=Y4Z#B1M-3}C{@^#d5vLc?}jjoEmaz03^mfgB9g`wcv#JaH#zt}vL)}| z4jrFpm67{D?7a(cR9BiNC`eHjwx|?s=*DHR(b>H{=ukW1m|L6XBPSd2n@LoRd4efP>t6V$K zAt9v=9nW`uf^2^DEtBdOfL>$aUl)#9dsQ9?1geI?e@%sh#e>pj+z8Ks4*52uTJA6<77Ho?L z{rx{?<14FJKl8QPH)a&*$17@Hu2&}y{XoC-qXo0SYJ#K6)HJH0Iy1F0-qDIS@Qj4g1h8wb|^tv98_(EsAuE6grT|04h77rY)bir{9oW=uA zT$+SSg?Qm2t`#GE@V2#hUE3>N2fS@4XEW|h^|oPm0QYBm+qQUJ$GmM?rR$u}wZrGy zU)jD_gcquDWYy6^dzzV6i4UhPsNXLKmw_Px%@bzhC7# zS$TQCuW{u^Rd*fmg?{R*a<%&!pZ%b!vT@0O34upJZkEq=0Gv#!3UyW8g-LWa+p1h!e2tGCtqNVJD&2!Z zKHySwmk)ye>8iU&RH z28pM!Od!-U7Pg+`{p*CcCHy^a%a$3w&==m)cJJkOud5Af1^(C<>h+ew@){<^n(Kp1 zt{z`w;AwB^u1eQlOp@iRyz4m8(MZgGQ5kB-k1Y8U4*R=HFa>c{)BkXz*JZN&JGhvV zveeY@3T6}8j*H&Q&wYTukMMUCe>d>w#NS+B)1xyPCN;g`e5LCo=b6dzApDQ_y}ypI zEYC}xpLkyM{P@KeGWu!8L)rZoY50F(8s-k?rxPg zwD^sl-*f$m5GL=+t_=uCo{|DueHcT(IpyPMf#+FaFtp7V`V4mVg)a2i(>#gFw{I5J z&!`Lu?N*-BiXQw_ z_b(w}UjJYX`S+Wk+W(E(2MhQg=0ysrbGn0a^lSb4cy&GaH+YEu-c!2*To3XPzoU^o z-dB5G#I?qt+S~N~SbeW{1;IP@1O5G=K`*F3XYf&^$_+mG>WURFzdq}sAC#9nUS7U7 zP`}*qa_uXQwQJVB`sy#g>f-Hxfc@hix=7jUuQxQ|P&LNyFrVS0_TMc2enG+ImV$zU z68pQ;{{qcVD6;e!E^4!kBTHD!&^|-f#+iX1*J9;0SsQ0Y^?Nv6_FHWHA7WGUF*bGE zu~~l@t*`?)gG1!=k~wz7M4OFGkcZ;|OmrviG!*SS3b@ z>M!5NCol1t17k_2mmF}hw%Ykz)vBkHh5U+zEN{itz*asKH<`J{GW+1;_AE?fh0ULv_~viiIqXvG@o!iB6Llnk6v6*A+9=RFupuKf$LVZ^N=pWG0Gh zweEv_GO3xHct&UDpvlZ}KGQDDAQ7vg;0zwBoqv$b#97F%Sjcj&XBOCkP2!Nr49yZC zMs#MVsVJFSPACL0EZE==lNpv!>pjdTlg!+}GdeS%t81o%&m0tHpe~}8%p4{&pRSjrd^D9A3xJQB%wz}fQ8J?d%tD3@;24=v0OpEt7R^`y40sF*U>2eSn1u`* zz`bNf0r+$(GZp}!Hkru|;L~JA0homh7r;}KlLf#xOlGnJ_y(DY!!Pg#QAX{rSkjlG*khmKorecIvo*zjvPCFc7`lNs zD(9(|*nmw3u06q0QW|1hd~zOn`W!q}Z$!_J_C2tynJxWhoE6~!{sejic9855_ykVb zZ^NCi2Z$B86nGxqM1A}HEA5FL=px*8Jsw6 zN*`dqsCb~j;!AWw8LqA`D6QOw64<4Xn@IVGFy3t{5@Q@1No_6wZ2vpH|1>Dj- zV!h)ymgof!tm^^VK=Hs%OI(P~>v)(8xx#?}5AYon4^i*{oq`8q*usO3UW12J-1ZzJ z50^m|Ihz5mcvA57;{I~-z%D94e?jqZf~V}9JFnqkHbd|mzyn<*u?1T92AC5(5V{r~ zbkG_+q{6j_%Zn1HaeyFD9b=JP2^HQdcwo&ANF5M7Z00HJIq+!@uw90`fER!y#X}f8 zz@FeC9jAB<&Vs>1YBSrTkq3Hgfwu}kTY%Zif`#A!E_tiT4&g~{VCn?HfOxfGl0%~@ zXrZHZs;;_a@8Y%QZFYYR#>C*zV zI%zH)EgDxse+JTm3)5{)L!U^^@B)<$5DbzuA*hoUJBxeTOVR*5Kx>j_{RUQb(q~gi z9|vi1N=zp;4Rqyr9-u=JFiqUOk)(+{owPJLbVePdj3xt6H7T=30HHeNu2jk$pd9A2 zrblW(O$V8ql#?K9CgrRkD19-M$U2J+~Qfe{0JxVx8( zFsOm+sv-!T5k3P)65&G$=~&%FydmzC;mN^m!xMvs5Y^;FkO;>!j!`^1XW+y@Bkt}Y zCo(t+suD-&obZ`A{H}&-2kD%|dlsFDcV#$s01}?~3@;={Ak$nqRssb~uph?|9(^@% zVt^BOIa(TJfJ1Ljq6wW7J`;x<*08LcbfT%8h__|>x9B7*pItgvDr*c z46NcVW6Y=wi-M}e6gnq-CJyK{_}!#Kt6Fp-9=_rC!O6oD*@Frlu&g2$z{bGIR|l-S znso9+>_&2uL@e9kVIbB|PVz)-GdVF4I|Ymk1F&^uBu~I@A|uk03SdjX$uIyLBqwWVHLo#y&DE#HgKz}A72VE{HZ0)TaplO$k+;A9wp?HvKY zmXnhtU^jx3uMXIv5x}dPjF=592Iq!_*AjA)A6{kn%mUa=;A9wpb&!)hTUdW8V8h^K z7=SG&C&O)F>B+i5S3KD|6SgwW*osrrixu|}CX{hTH%a!&Yv$-vUgL~1#-?xz$22Zu zucqHB{vb%pKw~vYk7U#&V{8hUGSJvdsSQU}96*qkfkr<`k7(G`Oof|a6I%__F%^do zcV(Qhj+93qzz9Lq%ZO|#~EQ5kRF++Nk>_jWhX~~L~6!C`VePwGBGF_KOO=WdeDin2{4J)$VIm&T=^+$5?5hT&BPU`jwqxEUkjvK zNi`EvpgN*x3X*CPO)*ma`q4ztTF}%>s$V0TKupgC!w8U!uc@!9dKW18F`OLv{>ya7pPZs05 zTni45_1gn~iS{7ch6DM$7d^t}p@VsqkGpy21kXEp{*<5Rj35&+JpO-4+9j@Bz|Dp~ z;pJ`~z2x8<13Z*0%?8QRY|yhb8*Jdn$ke>G)Bf&D9atbs<&h#|zl3Ye@bW*jBkMGz zvQF(~o4m|oE&G_stPAaB!5X!HZ@ttYyq&En^;Q8S_}nkjEOT>6Q8Gn;aQw z=!56Sk5C3}+essb7PGu0^JrB9Ep##M->L>pq{Yv6G81WcGd=cSu+~JseZ%8nY<>!h zZ1{8h{lbAw1DxySNMu-k9;OJu!(YV@{Hu{(QMZpND0TZ9a2UQ9Hp8~({=u{GH}W^h zj($M)9v;<{@bG2%rE;BvIfkcr;We7Qq9Dpg)?-Q=PJjke za2jxT$5GzJ;BSCAvUm<<2e#wg%`9avOW9n&Qs7v}Kg09q@j(0--#jC<@wiF!P?Bhe zy<+F*cxop;q{riU`ZC}9jPD_#0K}|hb|=Z~!YgO_9;A+6#M8`pi{nSS6+1Zm%=R=% z&nhHd8Q^(SQZGZ6kMAk@!w$M=+c^4^f;<9iC0^4^f`H(dE_rhGQ) zWytdJJtd#KmnxrNQ+ght?(`fa|5u^uv7nT1D=Fpeq?G8M@bGRlSgw@nz!wxe<%JGZ z=DOnr+YH6=lE~Tc0hMvnQXmZvb2>TC^?@@YWW$DezpTIJdP$7OFiM}FL7|32am^a zbc9F0aA5P4Tm2mV=MI)V;Tn6hucuQ>{_NZQC3ueCkF<0<-o7@r{(;La4!8~WcY7Yd zqz-qd^#$_#xUcKCBnuu({+0x5-G9wLC;1zQi51<9oVZ!qZ~A`Zj%;~t`rSBs!OffAh<0`PW-RZE zpO8dOzFD9}wyc@{L}W~4!9&xZ#LhE5!PUp>`^I67;m(`bL@#Pr@#_$6e4-bNqb}cp zdD2*HiIZ3v zcKH!fYBwqQvBa#W{*r}KE1vue@8P2=ON&KLzFcrj8{cy|vgP^d%UcyC>^u)7uvGIS z^%p^DV&^q%qL)Bv*(U9QL=>ycEP5D|wJCG2t`0;{KIM+BC`PDRAgK@o9OQNk`4B4W7^ z0oCT`oX4asdMEMk*k%0{b9MM6aTRT`oYB=K{nC+WzkeXV2%1gnusfk5_UNNv8*~5BG59XBH~6aL}*v>a{_56ZYXlt z5f+R{=4ERv{At)=tTIov>?SmD?TLA5$iTHH=b7yV$X0LEF2r}?U|Dlcc+?Rdcns@w z8yyH=vS5R#(Aw(T?$<6P(9M`Vh<2ezIuNZpeh@VLn{ompNMPWx>Jk!BeFxvNz=D7P zk^T2;-HH8{&O__&k-kGa5kCwfZme9Mquba>OyIF)4iZt_2H&zEf>;2N1NUnu*zTMC zhIXPyx()3}9BacPsXr$inh6Iy<}W7^)no823m6Ck5IK0ib|iuJ$?P(;BR$e%XjkK# zL8LmCvu)T!`{OY;Tmz%C;9Df3w+ysAh_v3XT}^~7y@htQM`LF}_oKitJ}SC+4yuKi z7-xU(4(oRJR+Gs7d$DAD{NnH|4~2`rpxT9d;_St}t%lA0EWbm_?;obo0UL1>l<6Oc zv-7Tw8TPItfp#I#H%x@2D=;I@K6_cOVe23X925eVhH30_y`HP?U_3N^wZUPS zc_Yg|AmxMbSF^KTzunnPTw<8GnFR7OvA;T-jU9%KH<3VoHuh(;ak*jRFbU*m<2n*Z zx3Sx>aVrVrXX79V!11%%7)vtibvZ@?`5Ad52_OPUsmFf9$h{447ovc%xxsNB%Z$C4qDsHybuC&)>#?Nv4fA88&w3 zZ{uDPNVjp=sL0iM8@Yhxr`wo;n)J)wD*O5Se_1HlI={D{)Y#bzk zVb)`G$_}GbE>H2uCPr`I27+vf^Hn{bsQP2=T0;TtFQGj8{I>hiRU;-BXN(R!ZdwET zbhpf%;+EYLy-r8083sp~uPXFC@CfL`T|-VafnZSDFO>R}M@9!8H?3h@x^GsU;+s7X zy+&_r6HJdVUs?SD_y%<3t|4cdkT5765K5PnTSf;SH?4tvx`XCVanNQ&6LiVKz(A*A z{uyu*=*?Y2PBgJ$P&z1-29$3`2Oc-AfqlA{R+r+XjgQ`>U)BmRAk0@d7*B5jF5NZc zJQE}arB2dQ#L@9AsDMtQ*tk4@8^=f>-Ny6{#m4UZ zZQM%&={BZID8qHtc^kQe<)_=2j-c4spTCWTK)Q|T|A~$3NFYBO116a^rrRer4w68A z^|(C4#=3bovh4h-Fc6YvUfr_IEIYsITb*HA-Kv{dc78S2&$3gjsv9)Svhy=&9m`Is zw7M-@S$2N546^K$`l{P9#XI92z7}y?28#=d+ zm}9hD&w)f@3DY03W9lPz%zDJ`7(Va25Z1-R7`MkaUC+uZ+K$9!ZASEv_CT}~ME*p( zC;Bwm5mtjm=AbZ2nsi=`-4fK$X8|a$5EbQb-o! z-doHcLE?s5a07nwo3##RNHV+QEzC^1T8jLa5>UNDyOf-;iJp9Mp|A>e6DHuIgB>Y*{=;mztG-ls1EY-$;g5S zD-Ms*{X3OZrAqIU$`&QvZ&{Zkln5wOPtXL>f6TR;Pc4*2Mdm913i0% z45e_=p`S>71H^5+IbLsAXmub z*rT06st^wLMdnW^xS*ZsIWBxKi=}oA%kZr)Pc{sVB>IvFlAB<*uai#0CfgTaVTtLgQ+7oOpk&OD@>0L0#jtwfRCdBQ>M&- z5A4Xt(IiZ9D12mtsXI4JW8lLI)7T&|g>}J4Okm1{8t{P~`2hM2nBq|Q$Ocn?ZkV11 zA6A&29t5WN;tf7d3rv}A13s`LAE%Qr#i8(#1*WeDbHlU?d{|-HH3&?Rume821g1#C zAs^V057a`vMO=$R;Uf!7*EZ+I=~?h$#p&5WaEf#u@NqUmoHADjd|*dD&L(k+L*XL} zPM3yr;;!ya=g3}jbxp8_Cd{}XMaS)s$ z6$pG>6r3W#hkRg1J}xG4ibLTe3r{m($HX6zM?(0_~GLh?;|6MpOGy zzL>fT79EzUUkIaoMEPRxn{oO%HGad)bwQLbW4ZWeIaa^*B?Xqd79Ua@>9*bB4(Jk z48`YZT|bIXweI&#<2q1$e#Z3&QGA+l9j0;JC|@e@u#H>OjPld0>o%?HNBQ|#w=RtG z)2!<^th*wJ^7FGUGX2u6>kk^%eZ3jw=V#t2C_dG?HO+>3*M?Dip5}F+{8aPSg$?sA zjiLNJ&Fe<_spjQJ8Pzu5i{kUNt{=sxT6ccm-6%glpUOhi6^(z7C^#eqHRT54D`ZuVfyKFKb3e`WcFc zbUn{>L^E#oE2fJ?gL<)UGAzw2D|0{UJg)to^(vsn3D zTHr;Bdmyg& z!y6h_garyFop#beFG|0Q4jEpujF+T4U@y37Xx#z3i62Z&h?m2&+6yu;`pvlB9dBr$ zemOQGBM;(sfehMPx?c3j@RDUXB;5yF;itWIAM6-1vu4GS-E$H1rQxh7pn~&&0qCT`;DuOL7*N3+i8bJcpFMnq zwxG_P0fW-4D4>2h&}xwRYHdNaKNAIxtSE5g1A-TVnILdy2Lb2|9|S9!Gg08rjskZ+ zD0n@bfr4eh>?rW(gMziO3>5gAv%-KH9zG22&Okv;I4cUMU=F7nX#0vif+GV4b+N24 zpn~&&fja{RC0S8G{eJbffX)HF2&qvTgs0_be;+f<`+XFjr*-`(KGnT1GmYy& z@%b4S(QAfr9j0;JD1Ug~yz_aSTryGXeec_6-IXEt`pVF6uORQJ zGPI_sD)fBCqR`!onPjjbrM$|-bSCZ;@0H9 z{ckf1KIW8#-nS#}zfZ1V|I$zTw-ASh{lA+0_TMZ-J<8O9{q33Rx+JIRdSJCt)rZw+ zeQT;-sv4UQgT1Q84`Z_1)Fr!*d$EJgSbfuV*1aup>((Fog5;y}jcQ<21EU%k)xf9* zMl~?1fl&>NYG70YqZ%01z^DdBH884yQ4Nf0U{nL68W`2Us0KzgFsgx34UB4FR0E?L z7}db228N-5?DN+w3{5!j&wpC5Ff^`Jc9ZvD=eZna3d0*d&*jbdNbj(}`=3e*3Ov6) zS%y3V&#$j>XMg9ypYtS!2TDA@K7pNk(OoT`Uo)Sg+WyXg2MP+h|Lkr&c>g=Nf=~U) znR0xgZAifI`a*lXZ=VkPLi@dqSVzheD))re7cL4dD_Rut7cUCcl=R%0%wOs1Q^!|P7*(0uP zo)!(y9tH;`p{>ZoDE5SQkp)ejjWqrKhkVp_)wR{r61mTI1q@8`gfuWv650p)uK3?pRE`4r$8z)FbQ()G~{}`>7zeW^pkRd{#45Kv=guFvF}NWHC;WL z6bl?ULfgOqUf4|y=wdzA^!_yUtW~Tf&d^qJ;GkS!L6^(Z^!tA&?3#jsgE9*Cw9^^d zM-7;A{e?W3lnV^Zq_tK#%R+la1*W}bDF&=^ErI#BkORE42S!l#dc5g_@2Y2$f`NnC z5bS9u-q;NlB<1>!dNe5)Sg3%xRyk)wEMdX4*Q3I%MXV)rAr={^fLzdkE|;h2cR!Fv zlY+TsIw{xF&bgtzu2n#d01-!yBp3lh6ah%KX@KKG*Bb=lmPWq0hiAniAdj3$R05AE zYoYCgr)?{M>3Z5(q=1QccjK%?WW_<51)fBvYuiHGk+#hMD7YvVfC9_Aa571m5=S#V zr3Oq1QP)=6)i%v`g)EdPq!x$v@ob8cormQ~z!Iw{%XR_0*?PglB*j_@bnrAVCi=qB zY{HhAWFkqos*Y`&!N3&Z3$+#HgBWTR|T9m70Wicj2^5X>5{{KvrC7wyUa&3RAELYm+0iPgEqh$5CO^@BTtP z9)ZMCO%+dNQl-%TDD{ZcJS;*hG)uh!1L|T!Rp4Q!s#&Ntd#E2>a5NzVw@6_ToQeXj zS-(&bcH^u<#Ku7hr2dXPZ;@JY1$eWb;l*8KX0Axhqe)G_e^ha0imjNc&}-Xl2oCKi zx!I}!?&^i4;N)qp)VK-(e4%b^G%aj<)#FL2$&&ae$i`N39TyJ4}qDTI9kw zuq_zJyTrKDXcgw>0y!!LK|WPLUZxv+rZX4DVF98EZygowpb=1bFC@sB1?q7{As8Aq zsHwEmz2agJpMr{J3c$)jom5xpR)zgy zLSEiFE^i%f(>$fe%sL+>d*y<(nW5u6sX)W1SAr5iU-5bj@7k__RZrTiV z-lNtW!|7bKk5CXAHr4_4=25=c+qT(L8r7SDez1qSL)_v0qwET(9bBElx}aXumD8qK zbVKe?9SA_YFPs;Oa(Dyv=z|AEPF*|Ht3^Feb zxkHUouj#;nUQOkYC-zR@6|YOpLN_ioYqs;tD;6r0R4f$1iZ#=yScP9!vDjmwk&ud2 zZd5FES6^DO&~Jg)GF7o=Co5L*msKoOD5+TJz*w75L!pmOq5FH@*GSG0|+O7cc(FJroTs*@>F zZ7mu{R3XJvS|@`#LpM+LF~zE_B}-^+A674<^)ZHvCw)wb=|`2Z!l)N4T`Rji)4yXM zgI-MUV`j3Vhy+QQRlkRt#oCOTC4I~kvyVaDdViX{Vi6kE1V%%LB=s2YvX7Z+^f9wp zH56M(!O0cs0;}&N>0{vC(b2}`3RDU8xGA<`YO2)QDXL?E>F91#Pw?$Nnx)=I%B^^E zsM?C!Lq`hzm`FYe4#EfD6)7x&lOR@ z0qcqxQ(DCfu)Rfk3;1&)DqAk}8|vYttmLCSv`rvgVL}?NTrNn@4x#T8rwKKH0#Yfc z0y*%EzC>i4q`YJ3Wl9bti#J9I!BL?B@W+i@QQ`_qe z{p5AT+0Upes$33M{*2MdZW|JMP8N&#|g>MZqZ?Z7Ana4>$c-!#aQksVfSu zTgM-~w|4rP9&=;O>)n<1MZJ6|EUU^}m!CJ5jK|vSpL1Dl`ww?-F5t@DxPdkAcb>%? zST;MkVErN7kVWm)g7e8Yu)sD~t>2j#5)E0yJ{t{Lq&^!BS%p3u4OwO$H$DU5^Hw=> z(vXGJv(eyVP z0zY?SE%(6Ua6gX6a8p^r?GgvK&r6lq%8CG!R1|bnzTM)c7Fu|AoJTvjX>3M|#m>9>sKhPUBzA?a*k(Fc+E<-$9cc-Vvz^D| zYY!KeUUwaVMPs(EmhE@ox%g(+)zE+qaUSl+V`vk#akvap<+ekmQWFolw%FQR_VDRI z#MRGot`(!Io(^5J`J6>K$I76tu9nT?Yk>1yZG&xX+g+B!@7ce>lux@}upc8N5*T-QRqHgw!9ty?6gG?SdRc&W5Kn(K%mdSH+1 z0*kpqVa|naLJ3oFjwR1T3$_lj*IIhTwS`w(?^8;EFx{@}p+1N{mDl@3m@Y_+ryq+^ z3;Rk3a3}tSt4qmmuj@PS5>>WS7%g-ann3Hgs^8U4;c4!*pB9#0gGTJ}KBWPe=Ai3l zs2_6E{_#E$oWej6wr!;sa2VL@+G&U$=z#H2&Q(ft3C4$WiF3@jXxJb8wTSsC<9$jC zkfu)uz)U{fE7Dwm$as2j3}6rxfPSxm0(;%{^FRTpZ>2PQ1qFcfsv8Cdzy*Lt5ZL3_ zl?ot@rbA#hrMV)KQyQPsA=XEEhYaiEcpI#bas+6%#QGKF4?xrH5B_$F`6=UlN(+$Y ziVlFed|CnR8W4}CpN+8^5C))s6{PF-o;Sc?k4Ib=fPhI(Twk?M)dG9G#nw@Jh3{^L zLLloQTRUHFL1oY(P>9Qc?IJjiP%F!6eM$~h8t8|%UA*^2PBsZ=15o{f<>ui_6O{;J`lich$59sts&2sgESsUwoCwMKFCSujj&{eRC zYe#LzT{p#EY<9rSelQMhsNUHC2GvV$c2UPTU@I!B2DcU9rhhC@aE08o-6w6P>ne2& zZqR6e)URk3lw-DHr&RG(2SV4tDK4F{?R5!wwyU-?u?2jCnUi3=P**RR zIcVz?F;K6|Mb%)o2+Uj@>*@<#Co?b^Pw>KM$Nv~2;y#bjm+upmmNenqjM+znPs z#P+Kqp__z*J$|05rE1z#yPw#tu-pY$Ow!d$ZZz9Ik)xs5DVheeM9sih*FfkhnSq_y zWVvqYEqj-MS5UM2JQxi1gHJ*61vX9~-3MkJr8rY~U9~541z51hFN=!BTwo2>YDYzd zf-Z=zoouQUuYtXx0eJ%UDv>4$EZXZYjb)QWp3s{4oMokGqNtt=U_5jUNP!ukqW1GJ z1R5hj_e?fR;5>8z0|+QN+Hek6>~i`Vuf17VAjYqT~vM zX&^ko9$vQ-nCu-Z#uEF&Ttze&bs2_eG?%Kzb^Fev@qt~$LdCj;XdK-tVh}c4sOB_> zLjJ1lGzYlcNm;~4*o=A#E?dP>i0=^FOww(G8-X1(5V@S>)XfAY(R9&P%HRtzhy`nr z$sL3ptOarKN?q%D)D>7o>@!uj4^5-nM9jhF47H!eP#{~?Mq_}<1C&Mj{_Uv0V6sJE z72hwGaq5;Klly5NGKn5pw-UHSlSWf1d*k=y(j9=y{e&H?1$oG23)+5{(e}?|FOX7s z`lRY~!WQMK{oib~|3{7XzfHj|u~W7Ghat~wOZ&gYX#df}LPX(SZ{+k209BdxFgt+5 zVurctO~0+s$(BfIH=$a5X*S|d8of_tMeO0)>vC$Xs)$5{cK-6;rMYY}Fru#K0dM_PA*^3?Pu9RPMn zKS|#_MN8=6*iAaACFPPUfU=t;ksZQ9nXWOt)fU1tvuLSYx<9)7NmZegM4RYqHua^P zeT6Ufek9T+JXBB%Nd*Yuxq3He+a|{G*a|$hxWMm|qM$b@i0bj!%k)sOjGScQ$DmUse7Z=^5WCP#F3K?-|I}lDnNbnsILG?J3i;yJ9H|5}SoZW> zp(!b#!LlcQ)nd)LB!L)`V5K2NxD_7z)*>vo3H1S~Ds;ptTm`}D1Brb!AgV|_Y>Idt zY_;B}Ff8K-g}RJa87oTIXxL8$i+H^!tiv)bP9zK&#L#+Re8rpgZADmsRgV`#SEOcL zP_ZJkxt;RRCTrr`(Kkz&D2#pr-x(YMq6lUvi>+O|07nb`-xT(L1QQQ3oy3~|z6(NF!9c*Oo)A?k^#Cz+Rj_eF1&3fn zst6cvc{zUAhznJ%u0No7a3nRWoj_0sC#-@_gCGC_m!Zs;d+2k`rSBl@nJSE|c-g+W zhz**Ag-VS$m5>lD>@w7emJRBZXi&IBtEK~lL7~#Db_AgyV?w$VVs}J>h923rArz!% zq3~%aFS6o!`<5a$P+$?kpwb}DB@hG;yA4gEse&dY2Baq0PU(;^b*i-?00g5`=x~VL z5&!9SZ((D#&^eVHF|^Q;DZyW4#S(j@h^-Bnln{`r!}(>#6kuYHQmJZpjJU$d7Dq<| z+Y&Mw8qjty;DZ8ygF`N9IKVc7KD^w6Q>v6f7)pS*z0xZ>l*UyvV+0km*}&*nVbejWLcLlGV?F3cg??-&pnJr7cp2kTN)E&r zI+RmlJ>eeFgpOs2_9A8@qsM#{gN+QM2r#%$Swb~3MkG;aX=E5wD6?p6Vp44biy+EV zO^gx%CeaaYSVAH^rT$dSTN)fa(xU)qfOgUZ;BC7ygETm1@I48<>CFwhV`UX-ZcrT0{oTN)xgzM}wWm<}+$18X~!{?UZQTg`x*m@`@+cD%|S z(gLL#1+@SXowPr?1TcnPB@7!#G?!K%5YI)DEt5obdMnMA35^Ok6Em=tX3L}pb7U60 znJtsq#;BIbhn6WzGtHLi$7q={nrXyxAhavll&J2=XixwOiRDt;67V9?oDN*Q4My#g zcut3`-uy~L_xFhCfUF^Vmf#f;o%olkeZk9#QygScjg0t~K!wB~dIO_(ec)IEIvu%s z+YF8+q!W%!m4Rafb>hLQCK(V*^d!4C<-LL#3GVd9LT`mZU1B;NhI#`G>Jrsu=nHY3 zILWHn6$d%ldnx}I+(>+vsy|Sduug}Rt^iP%z)s0dXxX-W#nA4}i~Ovn=Zh59peJC^%X{n0$ zqR3Fzm1%%>$_t6l#iW|$J)l0?)BJ?y7qZ&tD7Sy{e1~r zH}9U3ySv7ge(JHEb#+Eoyu~nRAil?ATl9fQixUQRc=n7u3njFyi*GOO_Shn>IHZ6- zGJtpoVt*)Nr;1z((5&m(E+RwFk3`UjXC0(SlUAf~h!jdsO50oiwp?5T2>0??~_T19S18xv_Gp4AW~ z#mc2yL=?A(0!u^e(^>6nn6@joppg};8H=5Xcfzb^MP!^DO*JiAg7{(GzK{Z*&Kbm9 zki8(QrSW*rVKFxZEfhf`o>w77ij_;dMGC)20ZT*TqOA5cOk3PEX)Ix4;MX-k`T8R( zUS%YQ1_>Z`G!;LD!!vx&z^|)SS}EGK9YQ)G0YbQA2-%vZ-pvOM1iJ*m+okD(aAi$1 zXYjTGVQIZwg5%>5Y^Jau1p7^eQ}~<#UzZ^F3&`Vcn*C?IV^mL<)XbL1iWeF9q0NKk z7D6fQX@Rq7($}yhQ50jiYaIko}~|q*Z6lqurXp zH-bkE!D0>za@F_7x|6atuy|JhR1?L`sSr%Zg3CO^Z-(&|I{Qr5!lE>$!68%PA& zSF@=A$=9}LcDuG9V7s2C0};QJJxUB?5m#I{v&mk1$l4RUc-qy;{gOvXkj@A+5!gkj6j5_R{{N1ro{6LLKxuIAt?ckRiPxc!8^XP{*@d2|G%7~c@wsZ5?z z-m<~uwRQ~8%yeyGuV7f4-2vrEwpWnH>=h1*@!iV!(idbPK)M6eZjpQ;j8A#|lqY9x zfXThe;X9QWc67})51|Jb|xJ)rn;<%6{a-L3vh=db*Epc&x*A z%~AKZXLU-^NVwP!W_P>|o|Vs??rs|%=&-$P=vn#JseW}bWXkSH8$2r?I^BIXcpjG5 zjOLBLa%!(+G;hwF^)uZkPI`_rbJovXUa&p}fnf^W4NmP+Oz$@*o9XVZ#na8%jO21~ zWrPH=FFbT{aLG%W+ivk|&31*gbt@9@3}(|ES&I*wQ>QsxSM-U6PJOfn(JY`#|CM|t zy;ed%9M+soV7iBzWc9`Cv@@SJp?F&nZBPjOJw zGA@`_F&LF|m{3qBQFzifgv*HhkYsd_96&^!LWUlqc5@(61U81& zFq#Mp!fTWYMb$?$82fWD6-p346+@-H8Eqt_LmmnT0O+wMM_VD65h@sRA@0{fVGh5FLYid| zHmzy04hM)pVG-!X96oO36bEe~aJr`}zm>ZrL@@fV!Pc+xHBJ7vf5sQ3 zIiK2p^DIW2^mVIn`G42c<+tbIvNz;*d$X)rHH7u5x^DrXUxlAv>V$u@6)%F3fo(b? z|1ZwHO?4j|YhD%Moa=;j|GlCx6nV3(SGF87x1t2=dS#2TycT~sXpkz_Nexp6U-wF8 zn}3*lC9~b5|3)=1s)11rjA~$11EU%k)xf9*Ml~?1fl&>NYG70YqZ%01z^DdBH884y zK{SwK{=CqHL(lwaf!F>oCmyx`=6@+GD7f5$QNj}YyZ^^S`kejD*I$NFMEi`{PWz0% za+Y9*J ztoSdud*8_%NpI8t2!dqee{@d4nQOl<^sUh1BFwt*RNK2d8t?Mi7i+%I;*!wfDaN%Y z3vqFeFZ8S{+A-YR z$<5s>?aRCIw;6w&XC-ihbEt8?v%o>j$8qReJi=6Y^?jIEtf3}|(?lGnZFga|k88aC zZA_W9I*7BYy!>rGACY@FILZgc;Zi5(9E%>4r*M6{@jxrz!Srh^GtLQU0-T~GaE0%Y zzxZJs9h!ifn6@avnW6f|ue3)oX9Iv1HOHv%wI10%A={;e=?dViL4gBG3x)!Av2;R?eR2m6zm68e&1bjyNH~F3@;0%s36_AO5&-jK}1x`_9%}~G@o_&sTYil?QVy#EEPsny@ zNxA}1{d5Gdekuf@%IXRTqku#YPSX@nkfH$MK@7|qtQ4>rFGe|ClqeXDih6+UOezA7 z;XyV;x&qjWWGWyN0jTg61stWw&?1Q7;21YVR&5QZH>~x@_6gZ8os_NsHWmR?O)CP} z-l#U96?YR~;51DE4iOEPr4ig_$j2J26wrbfqY5V|AB~Dq02-U50t5l4N&h0U$uY(+8^kcj|kr_CxL zvtOdAQVQ5Zb?l?)HJp30)+5^|WV>`~x&k<@9;>Dm0jRRN0(x;*dZRQ1_(e1W0jl<) z9M)i^fNgj&ii)bL02&pg05mp91qcGzVXIC}6u?#_QvsO>K)Y)}fXurH;z|J;6|l{# ze*b~uYik_bdSv^AY?lJUscqp669`${fik@RP4)(yBEM{(knK{;`I;*K;NAe+&u_9f zKm*o#Wc!3{mzJd~U~q4MsQD&)1Dv``x&j9G2Fj^`Z?HE&{%bw5eL}WN z%hMGwxHsUY0=~iCz-&=~Y@d+r(%I<>7~C7ErUJgf-av&YK(Xf9^~x1W^T<58pp&O`PXFxXHN{KSUwiJl3m;|umc-9|*`h%6*- zV{BJ{$c7V%?GQEx+;EI!qyT=8QcD0~0c0}070iu$Cmy5&cVMD^>%s(cU;tMUBgPR` z;rHe^*rHCLWvJ%{H(A`1Z}eydwA~Ex>)??w7G%7rlq&I}D7B92`!+OTDm8|aOr;{y zsy~>bRIKz6#~@Ap!4#$93N@VQr9KVEM|b|kvj)`$m>TH5gqKs%y$;+eMkM;7fxhAh zh++z)W2AqJ!in$8_{sErdwCh)jb{43a?5o7WdsBO1Q&37FL46`fx1mZYB`S3sAWTH zkOWecI)X?wqn$sbQ57IHOr*M@&>TqJn4#2|SO%(A2Ggtmu#jpvXgX5SSgI%urUp_k z;xrAZq%BoOkP5^rq%y`*QQDV{)R;&eY@|lum>sEEMru^B43K_CqyqARx>h2!IyX|A zGn6`lNWH>32oCHuMyO3S97$cN=7m&YJ!r{ z)A&OgrLqSQh$rfTxq;f6q0Ky?$S z;5C=8T9TpE*vJ7jr>|O0rG9gL)oKE@H78Krjtr&#&+t__g7Zxsn*>t*L@L0S3#sK9 zN*zI@=JZvosnl<-uUbc>_U1;aJ42}>h}4|Es-H^j2I*A4YBjjAgsLh?M4NhBeNhEc zgHS5amd>!?#$I!&kR{3$xUoqg3?JM8cNZ(rQH^$F6?n4I>bCHSeY zJuqhu2Tj60dzCil$wFMXjKe*1o-A5vU)hVp_Bl@$!ypM99>b{Z<3R*!(XBXos+mW7 zar7J)42^c+2%~K{I*v^uj8m@sh7Z&@+rbwcJU!3T{d~*KQyEKR!2v%{6THhp65Ys3 zYY=LQJ{}6W#7!PbB3pwbvNbS~tw9pm8YGdep#c_Ym;*T;zVKW@!L6P4cPo$Fx)oAs zciyIk5^vMb-Mn0Xm<#r*Ts?c)CNFdU%06ZaAl5Vu)~Nk^{9!T9nf+JB?7uQ*|CKTO zuZ-D$Wyt;u)nJX^Wmx0aVO?M*Es4(fy>qVo#K_WT^3OnQJ89$~s$|1tDx#5tIP0&V zltFS3BiV8gcQdoF1i#>ht~dNN*pE#!4+F6AhCqymcX0ERgWKoa+`dF}EG}dltAulHEmaxJKZr7&l*Fv$~fXu3}hs`d)6&$@Y?LZ{6E7cI8Gc+3M)W zo3fB=O$iUxa;_ZQ<|@ayu*3nn6$M-P@cMFok>SpuBdFE!)3~%9 zf6oNvtzE3?tvJNw$kmJN6}!%YlQ>$-z-C_jD`y=qV!*eqg+qRL9amp*x_K2JUg|b~ zTRo4fZ#V(QK-ET2LeyJP04^$aAvg_Sm@x3nMiOdM6i_(7;56_luE1AOaDX3d8Z4xE zF>0^aea1ovg*T({y(#53v)uhsE;hSK3;uJUlUH=M?LV|1M_o^x!lMDE$NbR#X(66H z&u4TYQ1&J~vX7T8vmj*HD8@H|!32jj69?=Sdp_p__-HLeFp&O3duJgpC9v6pk$b9% zjuR*y7D`c4Vu=TfgM9p|2>c=JnD|$>uOL}ZaeC+(TufYQMDnlmjPEHDmK! z7@L=3*nAIv0S7j}aAVWp$AqL0U-LmVQ_@spt~Y{})woK-o3&-!U=@ia)BhCPH>cai zXl={8A}5y=oX09j^#{L&rBdoIen-28-)UftyF?sIwA3HGOKZVm2fQ;GOXjT(;uH%Y z;Kn`XjXNSO_jGQ>CVEWW9aG;rR^44w-+LdHO~O?E55*5_W8zr0PnFv`fo1mIjq@(; zNc5EUYgKIP9~;H?-l;tlzkwBVq)=Yf#w2dy534e~iJxL{>nWr-KPwb@78IrmbU*~^ z7lAfXAc(o9{(vb^zX;TX!h z0v!^8E-QgfM2~8XN}xlgK$q{t0($-0j6^#N6@kVl2DI^s%OX&b2vj5j6)Ay=QU%&C z0`-YNm`-g8SI<~ezuy$7PXr1Z0_`^i>VrTtI>GadXjI*uSl?j^bV;|+nD}vRBBr|2 zEz}_bT}oQ$e^ml?m;zn86Ba$IJ(SpE3N$fsPMb&z!$QR(P_YP9tOP1f6{t-Fx*!5= zqCjUUP@5^x1raD_2-Ic@bO8cA)JarDPpZ53)VG@g4d@mcA3vkr6F*@H)Gh)IBrWux zl|b#LKm&KeqNlV+5}GN{JqeVN_*?`k5rIlXAgsfJDzu;^RiIW8s8<9EQy{F*xu(9= z6sT7ODli0UH3jO0K#z1{)s;u0N7UU1kX?f#RJ}Fz7j+9wj33n=h#xToIw%5NOj_t4 zlt2effiB(&iyoDFV?d7e>48M22!zElQHLgpK$Da}lTrmbBm!L)fiNxOlEfF}=a4DT zWf90>2z1C4=rRNv)7gSeRJY#@3wKHjEJJ4#i7y`A4Ko^o0`a}uTW(suSPFQpc>dYBaAl9cx@Y8``Yy4TH z$mI~Z93mH%F=AD6q{?OKj?i)4?!A#y35oo3oXlANF*50U`0^Q!d5mHkhM3era-rMZ&V=yRfs?pN}!5Vfvmlep90<9y^*B4i%^p4 zE`rS+!(4ZP9}iz}rvw$&-l>iP4yAYExad5F2i7i%gQN3O`zc&{0?)0fw{%vx_T;<~ z?y(SK8L8`klon;#?=QgJx{X>J^4GBlZHG;}P~U+iPwOwSqrJ+rKVqNCE8oVWZa)?e zZM{>!*E&(Z*K0=!aqWb>(R#OWb%H#{*TpISCIx9!S~J!vuY+?~-%ho(Q!N9ATG|b@ z42W9lu+(x^wd_b-#_G*fWHzo5&CK5>bm9?`OiXel2OT7r3@#o9$Tv-X{%^tWTcNVJ5B7I@x6 zK+DFw&|>N6>oyTB7paz%uoGyB8E6@9*r}t%3_A_9Us$lY|^4} zfCaEs9no;3aUCpXG;V+;cQh^`KFD4}B)-)WjT18^#LUJaVJ4OrX1*~oJsTJYG1ELG z%=G4k8LRVBa@#vE;s9UTAByh90lv1+h<4y05Yrxr9*4KY6+rLM?!kwWhY~yZs6(3= zJrAFIKOc8%1p05b{?&PkWy6JnMPx z%ko&CcDgZb=8v7#*!q!IJEI19wKM9FS36_<$Cyi#3m#kYFC08=n)QD=xijX_EW<_D zewkYnN50T^)8^7V;|tYh%%yqG7y5a|T$%&E(1wh;G;jJskGVsOz2*d)C7587^K({* z7B4d|PQpdb&*={>t}!o8!9~u`Sr=No-n=*!7msNhthpQ;fH3kO#78jP0Sq=Ur(*+h zIyNw;V*_(KHZZ3n5qS8!-$zbIq5Xb$0oEN;`5QCkBNNWwtgVvmL=M3InG7tC#dghf z`xvc#d3R*XYt!!@qupG-IdbZmimow{lg}{2W07QdtY(HsLNYv_;dlCV%<$0o%@21b zYwgVN&={QH#y#c@d@7vA43BBZ@Q}OXnBgI>tz(AAO=fsJj0}%)7^!PlPO+86NMdVv*sY(?f>G!^rS>5MQKGD6eYcP(#M443AaLLW=5^ZIx`7NV-R@O81!0 z-J0o7A?rgIdMOSwrKWqmx*lmDkh&SG>M;#u9n(N`E|3NSshi1y+%To)*x-Xq19=c> zAaZvC(?E2okp^;;X&{dx4P*k+Ky;}&Hn_STV}q3X4AMZFRIx|{(di)#konv}YNUo3QsXdFYP!#>>yax0sl${SLx1Zy z^rv%yToFheCJS=Il$yCBvzRL~3%Me4cQSKDbg7XmBDNlfT#?Dh715<;uE^?o0BV81X9Pyg4{5rWEgm5=vG%5$*xu zvaOQs63H&9RoNx;xr5Y5GBKpaVW!k{eo@mXbs2@mxZOG?o#;#;=>$R-kOR443eBXG zN11f;D3VU(?t@G^(S=6RiI{pa5=b6I(upoKlTOf7Bu)KaRk27q(di-SgzvB_8$z>+ zKd6#URyif>#4Xz@*)EX`lvB>~7syP3 z)DE&BH%zISnKF)4pmicSxi zDbtXd!m4aY%_=@iWu~lhN@|K*wpFrSB55kMDotfRcaR#{Du&cJ%#@m*D=L~u?WWZD zV7QLyD>@fQUxCzavLH81shPeqf$1v~kiH^!u?DLtHPTna)(;|m8vdSs>D{k3V$##k4vec?vmigR4YNWInQsXdF zYI>%qXd<p=>CoA=sIky^G@vRxu+F|{f!W%@3m)((6X(P?GnkVK zam%(!wo4?Pr&gu&%;yeLBdf=d8i$!uTYBx+-IV$^@3oQLgI}YF!OfJPDjcnrYfH@J zpIT=8{9KZM<{NoHPzMhi+@?zOw4hA2Si1Gs{Zz|Px^*P@_?*c4fj?mB+;O#PUTP1I zON;SbN;i*dPt8m1>v4(6M%E4=myl|d((B_AQ;qPH+4bWRGL5qL|A^p?jG+P?<1L3ywGBCH*WJm0;r`7>U0eSEAHmJuwwB>>SDyoMM5HF3;|eydGx5j#L8D2 zL(s8ejv*LW$vuX!)x^p)WCvjkfmm@6D~=&yC7c&lEba>Y+uPV(fmUkVz{*f?)9z zEdHT@r64b?Sp1zD_igR(Kr62Y0Tv_&4WSppN9uffA&b9L=O*a`2$6{)jIEYo3}|O9T^A(s4#9PCkC^Lnn~!r4G<02%@G%t7 zjF{`Pw)u8~?ou*3xxBmfcXW zGGeaF?LE@MhJ~&Rvfzi%uq+rc*JZ8ac6VLY(silv4+Si?k#b#b^Pw7m1*t*sbAv+y z%ZRxyYrhe$3v+{hlgtgmY-lQ}WHEM&J&63F zN0C32K>pA)e1v)!`9pZrp-o2q&@AK+;c>S%0r^AxMv7Pb+BoD7O+)_BWaJNRVE)hq zpAM<_~RP{?G>I4<#Drm>DKWA~}H>+&FW~C&yI65EE-u z!cZ9|xx?Id6>6@#Ag98^)OPRbbKz~&=feA~J{KNycFLHuQ^uT~vi1KTdv5|CMX|(> zCu|4{32e})pi!e)Gze;7P@|w`U>9a}SAraZa>^n2I07VyPmaWZx(=)8^FT!(-gx5y z4=>EIA>0HAw?aZh6T*>$BL^h^Z*@=aZkA*Tn!Mlp{ePR!XH#?ZR8?13S5;T{Os}@8 zvvaI!!XB$SG0&=wE^OQv@x0!h`ArqjtJ7Bc`hB>6Ws$Gn zBN;>P^z|!kUpma!?}MlBec9J<=g5f9eEpVu+G>xlU*IFDm-zavS=i0!>z6qz6+1t>1n9p6R#dgssoZPuivK&67Tc%`}LC*!+rhsJy$u)*YCjr_bl=Co3ggsa$mo7H|kdS`en}__KUAy zc}U(`U%!4YeZ14xZ@}0M!M=Wvb?zMQ>$kAYe{S^ki@oluTYUY_PU&j%^}Dof>_A_? zK{MNo_x1a+&EvCt{cc&Gk>cyOu7ECC{rYcM`iQSz`LtUm`uZJz`o%_xtQ zRkdpt`}!46j{m^d@67v^Ykd96W=~)1>!)iG7|<%XWl%_))_Oy`wxQnV6dRELCm&CK zoP0I;WAeG=SIKvheglq-b1M2hCuc_}+|D--h{fzn&^%v?Br1zxTq`#!2q=%$y zq)((Xq!-lo)V|b))K1hEByW-_$!(w_cfalS$SFya6DQsL=;Uc*{}GuuW6ac<6Q<3W z5{ZA2vtw@`b$gGlk$oN<7C)$eKiM`g^3f+FdyPp*m@zGGTEh6LGiOe|W!j9#?g=nl zYYGS$^3cG+V&V5vCG}{WMU9(nQI}NUGkq3yy56P^i#4m4KHvzy+|qO348@`*FTpLd zIxtAPHnWGKCWm1aH2a7$KBjE3FIh}a+m|l`P#o+VgBHhXirK#p$ECC7%7=4dkQs&a z-ZCr7uBolvz%K#6 z1pE^4OTaGyzXbde@Jqli0lx(N67WmFF9E*<{mjF96EG~W-9ab$C=e&79KyPjFmuQ@Ii(6m@rDIo-H5wq zGH`;8C?D-W3sO=^j3*d(WK zZf902%~GM9zNNKUsxsM)Mw3)xj;g?|mS$Z6uHjY)N|<$jn$!xDZhQa=n51eH2sWwv z<)~T|XkpeJHc1C%U9MU8tKygvWY!%psS|=s>JhVw{j(V*8IMaxh>{F8uu3M#ER{zA zKT$e_YeWepOu9d1wVEj5zC@gWP>#t($Sm!ab(_q(Tux{g2lT<{6 z%u)pr(wn6+QxxzMrF>lEl!{O%Gs-ebWoBL{v%1lNaQ#!)bj>!%MOk8&AK9BkwMC+i9I3ZHH2(wyb z@=&@eGuH)KVl|2|N#!!v1(Plh7dfFKsuEK=+~;yr(>*JcjpjikQ47heg(7`*qjAQ_ zChSK>-~GtgWc?`GcRz}5!hY1%S3m07Wc?_{cRz}0x_;EdS3l~}Wc>*1Abs_t*e2^o zy?pnhUVpzI73+n6GO747t4W<>MC}g4W`&@Onbk9L`qma^>8PB3RELYL%ufrjqUj$wLKqnG zgWcNC|c&4w(lf4$FwcX7ZrKV;E$J*h%9No}m#kj3Exm@iG~f z5{J#;c!@hiP;(G22=*GQgguBs=CVnIObeUGWfPAbz+$MzB6H!5kYFq^$UHrTajcD- z!P66W5hTGd7kgV8sf4|VL5dMrKW0tbEHMJH7zqv`3(e3VX1JgL$;yl~vdDtur}g5d zk1U8gIQuyy35~tRs$dXtNHIx+hOnt(5@IqMJVG2=FK&zo$;5y|3T1p)!lnpih(AOZ zb4VH*gN-$Xp~NB!f*Ll3O%ntWlQH1YZLS+<3d4v)ik%uXg-sDV5qCXEgwZY$HdYVA zi9r^1HEar-B`G9qA)1&0lr!X^j~ljrJ?7%4bKZ;k?hi-xu^g4+w0b)3RI?46+X)fgF83RaVVUH!lyh7H^lPji(ok=8F}f8U^`_Q zFW*?sQ_^_(#xkFh$ICZX8jE>s^N3`f|g3^pyDzh0zC4 z==&%52nuzmXzEbW=um3jU-m_d8|c61%`l`KT?VoHnq)9^PBe}-be>~OKsR4tOh$1W zEHcu&wZ0}G+A`}R>aF!HDX9saKcQh^);a7$qI^=vBQB$Y$5A*;QFpsCfz{{c+mdURc0L*LWGr$S7+LB=4=iO>VABxB`_RDmQr6(vrP zt7Z?**xkmg+ld4^SaEVzpm8&IwKwZ_Q+8Jev7JC3jq+p&n5kZ^>3$1LnV2QwiEg%J znO;aKp*9&eOgbxNMXFHnASP4t@DSL9AZTI-HXM~E@?~b-W;{|6&(rFV!d?jKj7hf@ z0~XYTSYtzb&X9^B4@eL}5<;c@4~Ap{cko&;$#$KwVwH!?JEC=CeR_D~h%->Gn~>w$klJikRes zDJPbKp~giv5Y6Dy1)5xu3aAC>5ln|sa~(EEVJ40wcq#-f5l#(p;ty7iYXZ%|=r&PF zO&07q$XnKJ#&j1LK|>KEaGg*ES+|w4$U4ZGtAeaza005DDqw2HciQ9i^}0XKBR zF@jQ2H)sM1ktk?d29ru$6ShJV@Pw@U4Np|Yvq>-z-Uun3(H%ri8MWBm#w0oeaYLN} z__-cnw#Li_fCMws19KFn?24cU5mbgIj)>C`Vn|O7z?2|Tt2k2vN=@ssFe~P6fi#&Z zK`BkzFeN~Qk4H!g3S1U}X3@^K2!}i@LIo_sa14Pi&Lr#x-t$dD<=-_4#=l?^aycta zV-k=ZXxJp|_B07qO>GjoGJR>tB*b}YgQrQ*T0%1kWiFEdpP^|(p35fC%=h^=p}@l? zRFX}=0RQ4_!a-^RZ<|o{H*G?XzhD#4Wt+?<#QL%c2R&^BAdPYnk};wI9tdbL z0C)d{)9w1)$?tNk9zK_Q+q!<1`&dHCSk+uB zAw?Hr9#wOu+>a7Yw-1FIjM~6SK@oa+KR#zLEHJ`$g^&aSd@I7AhQa zd&2Xapi9|ZzK{7m&E;`#$JzAobZ#f-a&XMIxwzCk8t0NUmuoHO(x-~n@mEc!qvU;> zTt~^HG`)^?Z4Mpvu=`D>qp;#luA^j`n^;GCU7U{c1g^SP*NUZZ|9S# zG@6Y{qs6E+nvY7YeSG9<_2jgcxy7}$fNhTg7PoPyqO&Te-MxhF zRZR=V?}0G<8xo0sBV(M0o(#ywc>2kr+FIwK=>c1vhb9H=&Z?{#AK*MRCg5OJDeYic zRFf2!m0vS=bXFxFKLfJyGaws31A2|0odwfraBTSenC26m1!FKm#)Z?GYs^|dBexY5 zps_R@B#36iX=+XqyN&1SFp#DPFl4CC+BV~4I}D}i0kZ8`=`^I_PBW{L2Fxg^xlUll zScqms%Bgs}ti2c$u`x6iY7JBvB(qU8-EN877$;U2 ztu;mE3-60MRm5}iMo)w=zW5-To(N`~xZE)#j1e|5fnhWw?Q+a?lb!(+G=wI?rBo7J zkdG$9bQ?^R!cpTi35z!QNSa$hDjdSyH5KG_*Zeiz14*~ThAQ+hItwOYI822>l$^J- z;7N>$sjwC!yIY^Fsmg<*ZN=DG^X9DeF?6N}kUFSjtxxMkiM-bOu7NX&iZ?&=@vQY} zb(JQ1YC-Pp8F|+F+~*TE*7`2T&!p_~{;sy?AwZqR$0J}FYYAz@Oo&nVG z#q@jkI5-e_c|xr@eZr){4mh(3#3m(AtzbtvM!!nmHw+-ZVO` z4Wk+Arq=1d;!CJzTHHuHX%Qn`MSpSYv^J#H*ltRl=5Bx?ZepF*hSv;rlj`)vTka+s zXTL4R*=%Ev<{4@?w2q3c2WiasJLTwTygSEUluP+N;4Cr&^sZcrGYxa|^t|`$a=vD= zQBNiHc$(VEs{VnO>Xe>kc(2ZCF#TT7yLDM}r?u?$E5_b)r?njfSlnX5Vr<`Xx1O$5 zP3xOR1M(aikmu2Wyu_I~H#UfNs85Qu8p8sehvo)kJ2R)m4l+jKBnbob%<-|qjWK~3 zv^)3GpnVF)>*v^beLTkNr)a!>jK=GSX}o?8<8`xi8W0PaX+=(&T8)z)MvSS>Va$$2 zulY3HT^!=Ebd8mB79?Q+Z_+I_CL_ZQukGyfR7qh+XTf+3!a#i0FyQZ;-%{UiXS|0hmGNn;tsS5!>z_b{0HUQWXNUQa?xd z^}u^7#Mygd83xiPs8Crj3jIO1zzTAZK(xCJ@mK&>!f%o)7!I75x23DaU?db<9%Go# zrpQlXXpg!$!3m1rh3Ft_GlucHMaJhCBl$$52zzQ`tWSrP;3T|zKS$_wRLFfbmk!cqye@Oe)X?&PzUc35v#0 z9~Y7Wh?i2vOA&Ypg4{7{e-g9hOd3J3Wd%%^oCQ-b+DGFoV|?ThAEYUBG32M?3NR8B zgBHG?Ys#au%P>dFIDw{|s@Y1nm{2rL0o}aIaq%V^`ZG_W1z3Ae&FmKqjOpnIsZm?T#kCjw{Nek!4slz;w2pDGJ>JCukj}Cu6C3 zaIG`k0KfWew!!}*a1z?lLr+kG*dmEg z-(ec7TVVX0F_KS=2!+igg#}g#t;?09cZ^FQTwzP;7D=R9@KFFhf}$bzQ%DyO1L!&U zUko;cieN6C$sq{qlJlV=7#V6dWjxXY_1KgoBngNy-!|n~&F;TzQ;;zD->@mikU?k$ zn{upX7s=7nrd0i(vMCxbZks}GiMVT=O__^K!ud933epLrZoX~G;hKYg+omA5@V{VF z4%ht3`cl){l*2U#NQ#~|rTYJbP0{#p*_6XbMO=hU`63xcjj#RhhZ%TUZ4>7XRiJ8a zgHks>aoZ81<_b&b#4{oh(TLktjP8g_F}kd&uGC}CsJ?+353?w znd#&L{TPxOjRXXdKs12=?mp|R69TxqDq(ebeme1V`l1@-Tez=>pvJj;d|m(UtmE2U zZk^b0d2~AQ^yVVI!2(X<#Gz0VUEZ4*ay#z2PTTFT39GAL(TS&<))b1F7UrDM4wI34 zC)8-`OizdGtmBMbewa{-{zAtWaKAL4*8E)p%bc{ByxF>h{=d*ALYu!!L^gYuKyzzh zZ*z5t=;rPcU7NK_DC$paGgkJN*ylz{0r+@R%*RV&O3$Qt!-7RRMEKHawHi^cnqM5a z*rXc~*4$lgaCmd~I9rEi?{Mab=I(EUW16|U*?Kf{ZyOQYyq(S5t9kpHV@jIR^Qa;9 zPs+J@cDxT7>UfG{6@_*5rX~_>9xrQBiml-nHlO+MC}s7!8WlBZC`&~qVbRZAyonOM zkl`~#JLo->#;^Dh>w7MCzqL0&rM~^vQi!_avawi-L;KQ&DxFv&vL(wws(7a~Zm8Ig z?yv8|1_BeZIDv31pc*YUWYdHAe`6E7hi-3p6FbAT$>750{(WHoU^Zjl@bmz@*ogC} zjr=@S#<}81ST3s6Mypa0Z9MnC{fRg~cYX=@CE%BUUjlv!_$A<%fL{WB3HT-8mw;aa zehK&`;Fo}30)7enUn_z7*I&~92k~C}A7lg|4T=2^t~h`HgSK~FX#WGH;SUn+;=3OF zWK2d%P_ci61uLoQq)oSTwnh%1v?*D)qasywSTl#eJIANj*4}E zUs_=sAbf-k5EQA>s@`Bz3$1F2#jweezWEB9T4|FCE$LfY+N3Hgc0jO7CAO#v+zPVk z3UCd#f>FYz`_rmcSg~6G3RtCT6liBv_gkWBQ6R#mJ8YE>T6DQK_Az?BO?LpF7SvnS zBQ~{Mqh!J3(h;I$0UNY2flVq`qCkL19l}K-g(6nnpBA;6NKpZacmb&#tBaIP+HKKo zva#>@cd+SpfmE1PEwZU)8Y!z1*9P9Vw+m3ky6x3t5i&+6p|mluxXP@l_-)ANaf)oCsoX9 zRmn+}TIllTb~ZJ`vsT#_ozup?vX5G=1t~OWq0QA)RtSYRm6Z!H(uStsZDrLR!bMJs z+RDb;3I%L*d2>69y3JiHMcR#qLUZAR{(1`&V6;swwz>qUs1-I*t7@uMv{fpz@LE}Q z`3gyj)PicIZ~;;Q-c}ZMox4^RX)78E%>_~&EKGngHuZ?rB|w{6ZR2WTctkpp@6q<|IiZn3RrWRQ}G_cCX)xsjNTE$wWatl`r zt1b^0IjJI6E2e=cfKEdKRMd3OT4kf5&|JJ$)K+o6y45&iTod*y#dp6_ny_ER`|elq zP1vu7`tDalo3LMv_T8^WH(|e;=(}G{Y{Gt(;JaTXG-1D*?Ym#iZjyc_zK?0e*M#9p z@Vx_@dKg`?l|{GKrk=5+Z@tMT9krw%ZDrZE*(TLk(vJt@;-xm}FwU&_P_JUe_6X>g z%yg9C(PnaY#37vU93$kyIAs3sj8ca~3+E6Qi9?(bhw=1}{3J{cxk|9uOn#DhgzM@B zd1x%|YMc;<5{t~g5{qTTVl(+yVlk3^_tC{89ByO8IGT7Q$IQf7N<21`VNg2aj zJT_7pClZg$qmvw&Ha3$-Cmv%+jvX`}nTv0X921B~779?f$J)A?LIL72mgE@e;&Dsk z^l>)vNHGNK)vT?XDTW{(<4BH>h-P>YR9sk&2%^Cvi#3R)U8j!hM`5RdUBMo8r1tYaAQi0b*Wj!hHo5RV8z@Zy|{$3~jR4#Xo1lNvUU zO%o;&kE2PBii^ian#V}u5!Lf$9-AhiANTgHEbT6CNLu&6G)Cj zH69yn9%G0{7ST0q9-AhjBOYgy97nr&Y@~UNB_0!eo5!XJ1+CaZfy4-bT#R)jvjP@p zQwZ6xd2E^xGI?$*reL+Bm>tFJC}tlOYk2x?wz0x@EGN_W#d!3EXt5xVeJ$F3di|Ht zyJ^pa&Ero*y=1y$y7&35J#9y~R;R7}X}>+?!~H9Zyw77-D&@4NLdTqzt4iCK4)Z>L ztAEF@K6v`xmpi0P*|&3K#An{;y<6zsr#%4*mZ@;hf9on;@ zpi}?YXZo!<;eEbx=OT6O+v$e!OFw^N)4QQY@AIS>&kjyFPJ2Ftb^q?>DQmke_ddV(y6PqCZq%*#z1@j5+4G0} z;(ea+;_|y`Pl!$*xA|AUmpK5dY;K0BqW?cleszI|!i*n!^X2gZJ-(w-8_zj>n9k8K{G<$eCgm&f|u zvOXiF=WS1iFYG$wW$*KGx>76cIT0As`=|RST)Eu){H50`auU@0Gh)^Z3VwgUl@OP!Bh-N*ZU zRquN?uF1`^-ZXFg*`=N55A!}hTD9x0&!%l0b;Zzr_buvZn(TevD!643?HOWd*ETey zO>4dPIrjg!ty}lV|MvbL^`z?q@TvtqywIq0y`l4W#$`y`8#@1FTmi^-6iDL-i;Ow^ z;1y#YKUiuk!2x}l;R0EH`u@U`)2?1u!@q}!&nVoDtp?~T4E(c*&WtAmGU-zcG0u$X z0UL2NA%oq?*ob_a`Ihj7NR-QFI*S5@= zAqP}vP0AgdmNh1KL|)dD^Mj08!*b05IKp=wvIgYZB5{bXI%HXL2gl(M-*m{5b4QHE zp$QIOEny`w45()1MkA}rN+D7yEUvp>f|8O&f_09aZb;MfjL2H&*a3!L^)@vh8QPXF zDzh`!#nPmNbjX>0=ggc|C>4YRt26z{+)P_k9&TCjo){)9sOYv2_1rRaXW9g&Un?CmGV27;Ne;=U9v3H@#J*>S$uXM2AhvbBh5PS!eq6 z+>O?#eB83)ox(6oaR@mOyIc;K?VxPATMm14c+{rb%;dmx;UtF~$YHNlx0R5tqZF;K z)Kd;ym>jIUVK5V7MU%MYP-=}r2EUjygm(iwSZKP0H3sx*@G{JUP##^#q12|!;!{qL zLz+#OO?g@!sSb7@aE={g$j}41&34&%-ND$kCt-5`RZZ{##p{%a1%q<8D+J+Ru$`yiU zMx+9lAduv>MPV`xf&fDb+9aB0O(fzzm~|_fI^nGWg`k|U4jE0F`G~OUwpnyrDYdIB zWrDy*3WganwT^*LDLiR7h>qbQ2u!C~Jv9P(UuXK5-2JwwL%5~j9ncu7TFEs61zm!m zIh8s+V;_1(sm0YZXeNsUu^ocgs8G)sle>pS@g6d z2)te0I1{nIeiO07Wg>><=KW<80fxv#C>|zaSnl9}Mw^I1#yBzyS#BFK$*{K(Hex_- zvD-$(H_k@e1s1wz{q2I z1qmq@M(_Xv*C=!lHi1PATD(vvRNz5^79a4?fOmO9ig=(-C_qSEQGizf(72Axv0`Zh zGo#$ebF5g%;OW`n{Kg9nix`H?Hq-te6C6 zP6*DHxmS_^mM4ggMb1}qyR;<1<#D;M<*PqnfqvjdwI7RLb`I-*!N=}gLHpdDb@Njw@tLE>#TwUWdm}B*+uH1z+ zy}o*QqbAf>@-j`YuO1Gg3H6m6LDTE2hfQxneI;An^!n;yb{nU!^geVlj4ezoC0F@- z&rOnJ?a02#$aAdhU1)7A9WBPv*asmEl<{)37)wWsv2-*aOE)q#OZ(;F`-#Z+Vvj5= z(Ze*df{9Qyr@rNS|3l+{B%v{S52o?|k^eu9|84k8D*0?z0st3Iw{)g=o|zLUG5|E_ zM=_oOxDM$6?#!L(-DZ|xI)u4&8jEGXPSWGS^!WBx+`Y4;06k9m0D7bpH$3wJ^h89~ zyY7Sl%ObFZ00u*6bo4As2vDK`Q2>>1nf3L|-Iu!40{f^CMFd2->?SQcK;vW)91!Jg zSkIDAk7I<6u_QOVY!FG0Q>uU`I9R@bVNG}DA35F!mrlR~ms!kJ1Q`UWt(27A?KNs!!6(f%HT& zK}Zk7SS~%5Q{d9$;R=@?G7ChGOOLw(FX>TbvAR%~#j+1bH8A!X$~BN&AU=1pfl9l? z$FmI>&r>mqb%gjR;^E>GNe3oAI1_r_B|eIQ>J^`7?tz{l<#Qz;NPIj#g7`|g_$c{6 zNeP5Xj6;ZT8`crPQH=7?B|cP^XEcyR z9Skk0Wb8GR*C4rY%cmtasI-^mqhtmbpQe3vEgz2#nfU&e>2oDI>X^QAEWGiq zKIADh@ik!kD2CQL@87U}uB1vG+jokKkJ&yXTRd#v&PLllipGWbs3W;t2PI>@Ixl63 zxb34{OoO&h%e*l0G25r5UOdDnY#*gteA+$=>oxItYTrfLK36KHj_o@w#D~tyQZz2x zx2w^%j|K>$^LmJn4;H+{hstWUk1{w7+CF!_<}?;v&Xx0u3Z}=sDn~;DWAFTyb7nhsr=t zXtIOKa6O@U4kUKyUY*Pil>lx^?a)2ornrEv0{8jJ9V!#dI{=m8d~1^!bPu@Qvlvu@ zJiKr9cBOb2?xxmnEz!epH?@9i=^logyG*Ka)9AOB^kKN0TEDf_kH&Y?>bI5v()ey# z{npYz40luOx0VcIxErhA&6f{qeS*He_ut3|d9BU6!0AQo-;vxBYe&)#1u59S1G`MI zWh5!ix* z$TFmu_U&dVrjaXfVFGRWF_pIbm_=KD%qzjxAg@w2ytn?ym>ZDc+WI3SDPV)x`oozq zC1ATVb3`mwh6Xw_#s}=DdTB<%3NBXGJ@8p%*FbY$gIJ%K4mUe5yWNLXno3DtWOzD-|$b) zGSeazDsRKSBCIs6QDJ4F=e#5gw6-XP_B&zEImaepb&3@`B2W?#!!Bo^>XO3F&as2B zPKAyuF1Zi8MD)kL2hQ}HG2(UhUR{QvEjDMUE-7i}OrM*Z=}hm0ddYZ{?KlK9Nq>ORlH?g%S5T!mp%9O4+Rp7B-y31Xb3D z$W^h@HtCcNnP9}p*hkyYb8=uM0B6Cpt_{$5)hU8V+RYO zT6PoN*z4?FScW+#Y;jRtQU=~{L#m2BLFK?Z4dPh2KGh`!;5z&!xDsAPTq(bv>Rb$d zu@%W&tbSp^(@7e@NvBZwF2qTYGc9$Qf~782-6CubLk!}R;ngKYkf{xeUg)?I%!POF zk4-IvOiRkJ*oW~|3ciwZHwu}CUI)Ht^yVQ`aB&FSg?5HB@{}pAmoXlXfX9fC^JI!R z3^L8}kZI_hh`%7y638?O%VMw}MKog>Um!9x!+rmnn_vNTxw}wWfe6F;NKvQc?%+bDB21`t6cxA^t6$TKBK#E!lp-#!oQJ@D3SVq2z=?@8Y znXK^oukh~BDW(fTQ6F7ahU6gYWOal}<-j|Q_n1(}k}BY0XT+GiinszL!2cuQ z7h9o_F%d!~MMdE|5nyu5;2b*wOK=qQ{?UxXL&V_`2z4$NA zQ*n=a(D>Z_La18rhw$q3{(P`Uy&rAv7An|7%j16$m<;WBo=_3NLa5t4gi5{t5QJI= zp^nepqd-$9GM4d;cIsRZ>UOtKE5UYz1f{B@sl8XYgi5{4)%&R&6ROtx!B+ve4vL21 zS+2F1d-GNE#NOa|0hpIuGD>Kb9sxFqYgtL2dF2(169$FA;h+kmFDt5iiuqK;i1K`Aj!vgg}X8iO5$D$(=>V@p8Ef*PO5^8hU)txS(y6x&I2-TKbQlDMj={5mPX;-O=kVGB3O7WKv zYCU#!E|x9TV^>FD0TZ>)h3u+17oMF9wdw8ZE)Ss!yLuWzHRo2;XIFQ*h1!&Mm8uA# z*0HN*%BeMMSHGYbHF@r{SO#@3(rOg7CS$hT9koKT9(J`(r0Nl#f~q?v#ffJi>WV&L z)iv8l7Lm4rGu6h!0@VrUDAofRis69S9lqhj)53^; z;9*?IprkP}u0XAhDX9~jc~}l$c86g&@r=DhZOG$l=75aAI*@S%SI*2jAyu6?$|HCh z>lruU#ItLQ+IaM8>dASGjEIoHnnxe56BSXk1ffyV8<^ek4^BLT9-(O@G=+_B4pHwb zWMs6chHB%{=jsG79#IQ0y8{-Sc=jowX&zw;EhT97K7*G9n!UqV@f`y9=&E^oiwU1e zXzs3p@jSB9q%Aa{X`X&!#p~8$1kzlc1jz_wsmWAe41xd6(L+plPnR}kVk7Fz=I9=5 zI}BvC*ekZ58(Avr0`J(`eZE_(^jt|hTo@Ltz?L*f&mb{_kp;#J#i5jk6R*!&u|G|- zcgw*Yn!Q)rVw$~Enq!;2PY#Z6_AY4~+Uz}YL_)K7Nb~IG?vIWs$!xEh{bH{g(K$cx z)j6?llfp&z9=!U8*Q@X>U+n93_-D2hiEV3E(pL)EYR#3)s2fNByaIssuSw(3k;CDu zc^tl70@%oPnjZcCV)wK8H>lLNpAEezfc;qp7P9?W*nT#Ym~Y7p8SQ72%s;z0v_erQ zV!^>^yy`L$@BJj~v8uCkEcPXf39)_oG60)>*&YU#=P|H?g(vpatcH%uPW-}YTmfM( zLjkb`Oel{38@t-1Y`rO9H5xfUNp;4(Esv5%$|L0ABOVzwvOM$u+V6Jy8TU)TF9E*< z{1Wg>z%K#61pE^4OTaGyzXbde@Jqli0lx(N67WmFF9E*wr-IoTtqI@T4dZ*$g-`K~Z#u_EJI@!|8pd~@3tzl% zeAjV&A%ySTHx1Ue>Sa;ip}z5Lqk`EPG%Zs2MZ@?$b>SQB8(#{?*Ou^&Xc*taE_@Sx z@x8?Hg%Q3f4dZ)U;9HiA zl0NK}%<*9>G1$L`@m=Y{_ndEhrHfg8FCl!JS2S4P4OEQkyNssTeDL=!$9E~=o7*tH zf4cCo8NG(>^8k)7obcV;Fut2y_?G$RFOcKAjPU*TRfF~2_oArpa^LvArh?fSmlHlm z!}y+e;ah={7xI7p`~PoCpfTS+N;%3k^Y=8X;}v5vw8~`vIhsy-HJRi{N;)hA-C>U>05K}HI)^j5@NVOINa z?B;`Q=kTe0+HMEmV#3Gvv4MzH!i&2P=&jO_Fsn4OgH^&7dD7Hqt27I{#?AAH)d)>I zp&3eOMiZKegeHN|%vP|L$Ud_}aZC2To>g6NDgY)@4Kk|3jX{Q0>kO-M(+k5CM~~Jx zQ5?N4!3C>iI)%jv)^n{8>FN2sjr<-y*E{G`uvHy?u4Q_$_L%$DxKlyc&EcF5xI?{A zs)?ssV3UV)f%QFSR*D&BUk~y{TD=+Ms%= zjU#H48MSC{YKcT`PQBDjM9s>mb@iq;h^P&(m)c~amdL2ZcvG80)J*kKvl6vIj9L$G zYQu@zxO%B2616#uTC6uU6H&9)OKlKQ8_uZp@}@S9s7awoBCsDUVJ?rU~&}uNnyQS5eDe9Jx z>IJ%Gyf?MRb<08C)Ed_Zy{R>>TTb?- z*0^q&;7zS@-7?XeTI0IqY;S6f>y~r8sWqZodQ)mdm-MD0x})OYuZSq>%nnNG+CU|> zrcL7Qf(#wJ-k1jD2^Lw2P5!?uRWG$Vo9+nAfQ8s(H+ue$LtX>Dr!+w%dh(0 zAmG}y_pY5+`O<0u3k#nuymZ>;Y5|{p_J(Jz?_Ro5z}2hwt^VZEDeVOe3=9g?w`|c` z!2bQO>)(6oJ8cEL{q{Y#e{p>BTLOOc(R&{a3mQ->;P&m)wjcQU`%nQ-ohm<79ek#p zfKNVI`Q(Y@veyKhHtpSMqqZD~5%8s#=Dl?G#Jy7leDJ}+4}RL}g9-shkA8dfjpx$( z3HZ}b8-B9S8h@LBZ@o3-t7JXyf2uTH$WaME3;1kB6(IB#IT-@X-a_wJ{5pZ@&Y z>jccmxHV(su{V|qc*`xTZ<+Gi@IC_Ge}A|8AN}WRodv9^Iau@lb@?L%eCQ$hp{FnZ za;JcoT{h^lBG3;4tn=}-K7)$u|B@3`aFJ3cI)`m%tB4}W|3sUf@H5%Ayt?)&dW zd!sHDu%zVAk{wr^ixTj@`)<4M@%gVr3b=1y|9$Vg`iV)vp+n~mt?IPmJptFR*R2oU z@ZwehJ9qw|^I*q=a|CSDCb~`h_2CZ-`1RK{U+4FqA1~mtWj`#NbmfTk0{-J4U;ktN zzFpx0E?jua!r`A?u~)#Kf8O$Q%FM@l2{>ZJq!HVD{P3cHVPSD$$?=hk1w483%*k@y zsa67R+!(U)@-+1~0q?n|;+|t`=j;%$Wy|oE(e2yZEZ}30r95`+A6sS%`1|kw`F-ZV zov#ac*PtO!kRWDb&z8&(hfFFPS(Z>S<2c8yi?%bleTVJXA zM!;8Jo%-sp)pu9~+_R_Oo)`Z8#Sj6jt2b7wF~tc29zXu?<5APoHw!pt&apY!FID^~ z;DiYaCtOjmX}W;F{WkEok6!rrDFLszV)zxS@4w|M0sHj}?AN023uXb|d8hX~3x2)s zN&z=)Fl@Lc%bqLX%{PB{bJ80R4;Ap2U)KKe(vxFv5wKOOh*q&zwYyiqFTQx;i@>OU zp9}c#!$}Vxx%Imh0;Zua+M=AmF-nt=6^M>R2ma$ByGVuAAF^n}8O}ot7C1FZUF1 z@7_LppLz4EQ395gohZw^y0V*q1qGiK+^_6kF5n}NOn>CiO{=~a@VV!%e6GjKZGRH* z%{L!>^MiGr?-B5Z8+Yx;_ltllR#dGhx^M0<0gH-Ki>`WnYngxs zLodT@>6#}5+_`h+&Obi-k0fAn@?FV^KU{rMz%^?!*1R!i%#8wW-hAoi8xA~MEMSiw zIX!;weFi60E{`1s7&%AijA>iW0|6F|X$lc=v95rgp zsEm8oye(j4WOC%y%i``9aN@+DCqA|_#~|R9S5CY#XGV_=0)F}B(_eP%D*s2o@4h?o z-TIM9a|IkU$TsNBj?1?Q_^*G>`q$CJJ?9H}{q@gX-}Y0}tpbi4=NQ+jXx&%=OG^t% z_g_+blYld4Zkzebdw*;a@RCcEOBO$Dd|JS`xU1vt8j<`@0rmPweOz>yB4B1_m&_rB zZ@ntu(W9>)m7dBvDB%A6_wRpg@n<#x-+gz@yJM~$l_sFW(asT(+Ug|%@4oxw-KW<7 zbDe;%zdqshO{LN!0wTFl=WpxQtG3>rn_4MgmoA@oF+V$Gs(`a*WzBm1+oSmcKK*p} zr^l`6_=kYIcFo^a^U2rI0$z31rc0i|JTU-1WZf2G3|jr-+n>B0|!POSd;SZXaOT45+d>@ z$DS4N+_@d+e!S(+z5?28oox?}d-GZWUw(PU%fIK{IZME#r1eQJ{&b{Dz~JBx!79`@#eqHtfk^Ws%=}Cg6evH!T?SC*d_zOt*6UchUvnSD*kgkHx5?9-=xpX(od zW{iN@**&voo&DF>0-im)`|P(}4)+%@C@3r_GF)#IaKM0J1HRF}S0LaUZ;X87r|erh z2{>iSCsX=6_gybw+qOO0PQ3HV@d8#=ZLLbZt>{Ss4<3Bv;Hm}hPZDt6yu7yJyu1_}OQ#eb(*n``;9B%a&`m+_NpEM8Nj#P3@l>eEk~& zzW8GBi=lR1s(=qX(CLBu{;@Pj!2kT`kN<2NFmr-{#l>oI$morE0`}@v((Bx&+35nN zq}-D-=a*~G3HZt@kH3;zb6cE%XUW5Pw+W7080y>>{IH#7s`l*0A zU8t^uA^0i*hYT?fdH&MRe-+SVYHPaE^4v%P=g-fdfAF1}WdeTk$vdB1cSrx{1ia~{ zXD0S68oFz~$=AC(ID>#q;}`lb5e3;{zz zx`qtB@$!KJzWw$CZ!g_(W1xVOCx0=yU;3Ud0(R@>?Dp!ZM?VlSF>!O^v)>n%3wZi; z?dgKnrI!iVw{Oe7ZTc*-3i$cw&wt+f2J?pk+U?iad%bR0DPVYbeE2d`^mhX0=f9u- zNbiF`2zdGBLoZ+PK-Z51yz8#QyEbo6JR{(wN#9SJma{!rz}Bset(BWEkp)ah_$}e% zFYqOm81r)KZ$XQHNl<2Gbf3V8&)hwAC>(*6NsmtP3{M zqnQ=tUB=NG8LKh2_Oh7Q{Vx>$zddW{uf1OaehK&`@PEGq)Ih5vs6~m%@O5C)DOpWZ zmSASU<9h>!Zuo9*q!N-*o>}kreywVzl&0AG=?(9h)ICyKN_D^SQgT|M)e7=m`wY)6Bie^*Yimywy^2FQwK_=t0jISyu3SxPKflK>fNGN?rypr2qbOFW zY1k$hrl!%eCw`GrD+7|cr))skxa8jr$!85o!E_cDkbE{csbi-SL#^TNgy5C|iLLIA z57r0ZZa!#K6F)N}Iej^`Dj+eO;RpkF$<={R1Z#Iv@&iyCJc2nLRMn(z2cNBGbYD%Y zHKp~2_hiEl`B%;ePARBGkqL%*X`Es_D1sEO*3{z5754t2RPd^qk$5IBr_&#J`fmD{ zcx}pK`r6t9_on6rr&a_fhOMssv-X53YTfFCxOiPZ?53F?DXSS4b&n+^z0R}|X@~oJ zGzwZjwaPH_3j7a941ErhXGa1Rhb1uSBxy{5aweTvW_KJ9;>*vLz~W-Xjv^0MC}%P- zZARDhNk{4Vq%^L4b@AJz?UvMvfJ7Pp!;-GCs_m`nFuf%^jaDXGrAw^R!+KlD4vWEz z$4$?-CmN>imw-Z`+$O_PyDsU7a%PW`UU+YL=Hdy46KVLZ$8S4+`|t2ovp8|($BckY9}e` zmDDu+j_4C3w9>^nrstS^mD)5*`VqZSyCLZq#6?ZLfT&{u6zM}9{8deX|NnkV>#u=d z0)7ejCE%BUUjlv!_$A<%fL{WB3HT-8mw;aaehK&`;Fo}30)7ejCE%BUUjlv!_$A<% zfL{WB3HT-8mw;aaehK&`;Fo}30)7ejCE%BUUjlv!_$A<%fL{WB3HT-8mw;aaehK&` z;Fo}30)7ejCE%BUUjlv!_$A<%fL{WB3HT-8mw;aaehK&`;Fo}30)7ejCGfu`fz{FY zXiVW_eXu=TmpptrC^0;>szp+GVc#XEYuQJaXe+$T!nYpuJoQn9)v<){3Ju>Jayid7dFlW_|; zu_vkt+ic+|nvN3aD6;UCNAO6hQ^`CZr{@)p|1lT-u*Txw`RqmDZ{@lZ=?UmKIP^)@Kkt$?09Ru?d<9IZ2}nR5C%y{u;9o;506yPby5d*b6nY9_t}r8lg~ zQPgZ4g<;b(3qE_6Uf4laKYukXuv366eeOs*XC$~VtrF0%DxDp-?1Zm}rb$!7_;VTt z-~xtp!eCZkd6k|tORqQx6ClH2Se3~R8G>|^G$dTZz$p_3@Fi_pXh)spzy@PG$5CTbRcHU>LOl&ZM9};(L&D2qMx<8q_Jx# zZIT{{kW)_t8Wuc&J$Vh+k~#;N)pU!R0n(f)ItnwXn?V%v`Hs~J+{)?#MnREE=$mm& zcnernaRtm}p#bBE73doZpk`@EIr=bJ{poyc6$+ybQUY5ADwO8NRw1i>(eM=v8?_xL zkI$7A0^?G~l;95y02SfnJTUGttU|4hKtBYFdw?_uMRCKdE@kp^QAKN7r9FM9zEA}m z;!cKmluk*j_HbR|TD6u$1|IOKFK>-vg3`1KI^k9-9C~OKVbFAfo@hv`ND16(1r1|r z#hD-_Cnh*!s67;uKfZz$}(s55+lA%nD0x1*IWoQ!9?L{j!O#(?= zgC?1wNtV>LkxZKwet!<%tWz_7q~6Ut264h#tV3_Zs#iLvweA#vg9Xuake;WPa|(DD%iL& zIwYOwh03Gkk@5(6_ys(er#JH-H?;(O`&T{u>s?nd{~AR8wIg${141wCU-7l;3;0*E zi0Ap&P|d$`7u%qJMTf8B9o_!*81t)+v{KE#7J2yBQ%3mLbZ!Z`8516wdu>?4rLWSH zW(k%am;e{1aSZTkIOZ5k(#ZN8Y&Nrki~+c3pyB2iRuCvW94ss|*-3IK%chL z2e`eQEU4g$@IqjW`&f8I_+r9F#*N!0?qoSq_$&=u1uF%g0RP93Rgi&Trwm&KcZY5t z%dx^|au*Ah7zN-XAu=stqI4l7CkZoE$bBqB3RR*ofcsbol$t?!c3`neIn2jWOE9w! z-wF2cD4mjzb;oNs5+0H{SVBc18_)=6Pd*l?gpVZ-ps}8sMHoCBqz}!?aBCJ0nPz$W z*tIankPUn+3522{QU_ke4bUYzXAD8m*-UkC4?dTCF{`A@+0r?1K&{@^)M+hKG1LJ5 z-NVU#2PbP*H!>${BJH67lq!U<7e{)NiWUVEcn}v;4h6tfG8KSWI^j4#%HbYaR^h`z z5?`D}8FC)dHvEV1!J`j<%jpnBE_AfDZ*rVPu6Cf;iO5MgkVsY?a*c4hy!Tv~9tpym z9%!Z4rALl;ojxj)c}V7Tnaf3t!Tm7VfshP}x|tWo!}RG>;N?xHiI&ikBq3fXGE)Rd z6msVE+@>kDr(lPK3YRY;8SZ@%&iK7=Q~S}T!WTDibtE*maAkK4kGtgI`^bf5lTX(! zOfx)p8?3yVN<*~tycX86>lUWX8)2s{x6S!h{*gX` zY`XI;B5HWy8=TPqJjUu67^FDvj=c0VY{Y$G`1~*^Ja|^F&4l*$K8LvRS?b-~517;i zFH(RH)nr#q5+KGpumqwYJynD2FH*4Yx`@~jV?(-%VF9x|xS%)Nd!I!#{2~#+MPPrO z-$yxIV%R}Vvj#3?Y}k5V5JSg^a~5g*uMuISVcs~A7Jr$BzR@&#V|(4o>s^VMI8 z{glIWon?e4`#u z)WY*FB3BG&P>U|04Ti}NE#RGkjnUvh7LWtsj>9CaH%l92snTqJ0H$DGxJlh@l6INx zNb;x|QkI&dd3+w8$@U=;W+LOFUeQrb$*YHY8t?ZW)YDirS(kXaSwhyU!ffvwX_9t> zz7bSGJX*>)pK@2PdSBU4y(vDW9F?oy^-xB&*P+fas5;2@FsaCLfO6kh1hw@M?}doU zquN!_C4@WY2|ee$YUk8Le4AO?hFZqSQWc1sOzKw7jRM0{A8{)pM-SrF5pqgFJ;e8% zN1P&I?*`v%miC$LBjaUtzjRQxj~rxDkz+w%k%sCIt&jY0uex9TH|xFwbssHD`#^l0 zN!`fnKCywiPxjKcYyPIbQ6neF7*E(oCYsb8yd`Fnve%<>b39cpr4)uI`R^*7EbTSh zUr0vt$@X{XbM{R9XeEgMndfj$e8~3K7U8f?-}7vQlrr3H0u_91G4QaKc;^)yiN<(g z30)>##P$Ok6MV1-&-=_$cGJ}x7%#Wi(;H|^MNhlCB8yLvX!SG#7zjw)Nf%yQMtJS- zd_X|ji=*Z22rcyvZLLwXO;1e4AyZr^bK@y{SWi<(p~cZR%w&(IIL4$_%CODIJIUNW zW0woEiXkv`^TIVhU|6^mdvUGsG_z~s<8f9g9X?GoAcwu^w2JoyTH?y!e z$S&+PNe9vYBB=izfEGro)zUeWbb_p(**+EQXUS4_z2>iJ4KF%Ej9JS6`PfdFr9zhbma%zhww>Ub0-ERTAuy>>*E>lS=b31!lG-CiQ?x+HbZq zvjI)!HiXQEi&-)goLO$$mf^e}slCSfdmX`D^VbDeBiq-I*~}b!d`%i6K-vJPKHh%9b>V;HloGQ46mRXV8K5RCFz6y}WEv5;-(42aN_2zHmQvtZTZE@Fhr0E&(mz5ztY2*S=K zwnQw6Tu~8v&^B3Jha)m`ukdgV85z%D5|=dDx4~ED+ZCqR#xAeQ2afEjLLCK_+{G(X3)zIa_bC&xUc`Dk-5Rbv;#` z34xB_HI%OCye{hKxEgg=(h6}Rd&(^VTrsSITs#FJRY~(Iq}gHi*{C8S>G*JyJ-!Dr zuO?|I+H0f9J~URAFknR{&9mwzdmN1JcP<9dLC>pxY5mnNty}$43H3g0Plz*1HK@GF zENw-_6)=xVTI*IDnN1hP!!C;MDi@ts zvQI=;D12^ ze7)L#B3L#In*atTwMM^>E*d(CEtiTe+Ki;D2cvO=2R_7CLn)5Q#-h~}4HnMkk1J}+ zyMv=KgXUE1=7Ux>=?Pk$U^jndQwtS!pH;0ymMzhsEZm;hMp>Aa*b=$6q>l3HAAv)0 zT(+&|02BrcK=?3serj#tEEJ&F2nAN~0)g=Eg$Ls?jyj!XNW|@*`R$kZ?e26t z4Yw8hcgAGgqIBA9U@~AO43--?=7m|*Etb@CVTPwu5U+sGuPo`uf^6zx+Aq!_8x+S( zgVJ-)6D?snXSTCA`mwWamY!#3bhWA3R&}GbOZpFCgu2UmtXc>P>>emT7u1?I>Z9!f zlZpvLar<(^wASUaVOlF}$hWTCFh9hGi9U6QqHZj#d<^_)h;LDVxHGOQU8)&Y!?kf( zzC=McVyaa^h8VU1A;Vl!90sg9{0suAYzS*b4?E^=RZ=s9px;8!x2oo^v|2@Z)GC^473EPY7rr}v*T)bIj?^6!4D-!fsZy5IW2lG;6)D<| z_Ot2Ep(2qM-ETHW-x%JEKj1nwBZ*x!W#>fWXtXD!)33zlm|wywoO(RW;)pXy+ZBiH z7eiQyp*_`p-4opvhk1*oXBwKpVgAM11zReL{r^x<(QQy_Ggw1|_0+1c8AZhgYFNnV zg!vcZ^cQMcDyr@%d@Ib|w%3ysuJ(`u+VlMSlRRBY0(42N;@FCmH)5>Th^TOwAxwwu zBT)yh8pMbi+^E$+TmQzGY6SnR6}1ZNLmn6j4yN^xOdo@#=US$q)-L5tK|S`fB&l@s zXwVZ(?L$a9!EOz~evMQqsHfGDq_t>w)XETzR-%ApwxaURs;IVuinOWlQwc&$ak9ZC zTemankrDr+Qwko|@&Ejx4KsHO`oOFW96SVudUXPNa^arKA$cK1*z1hZv&7tjIGO#@+D$od2s4ebMp z=7D`fm>IvhVPG+_udpwMFbRAqjzPvq#bGr@qR*^FXQ36>JI9b6nIAU6FfALGamf%} zqc|Q3Gqmpqa|TiwM8nX2ZdlPZLOd(I#X~s{;>fBVwxWSaJoD*NYPL%}jIb;PgAvTs zN0NYKsc#UDF-OvuM1(_(XZr==GL}F;QDISc;ZoPa6(L+s#HQR0VuXmg_2Uxi*3T`V zZvEWyaS%6}V3>r0A)w;XkPM__W74_by&o^^owt0}!Ei%F5LRIf=xZX{3K8LwOGN#- zh<<^1AR=2BnVNVj#yGGyT-OZI&@L;6J`>sKlB`Y-niWiSCdea3jU4g6I)(YSjEv%F zIUx9|0GBD{>-GP02{#aqmZL}E2yGiv?@IvJ(|ZU$UjpFoD?G;WK^;b09hW`dnmYI( zyiNebk%iaX$&kdlc<`(cfBwcg&u*Y8;TUi#Dq(!q8`AN8gj5RFWrJcrKV3u}cgK%5h{^B?p=etA+*PpCy!LX0e#K zV|sxe(>YjnirXz@oUse+B>`N~u`@DZF*s{!b=*C*>{P8RbudvTSPrHK_+cyeVQaHA zl!(9-VY#bGO2c6r_hE?pu&qflqrf^8Xh%Fy`d`h#nE^}LI=HT+nIv1NSUa`g^}I_u zVUAQ(t+Op5%EeJcO4Js5BODy-t|u zIx#}%17b-1)d&3Mup?TJ@(Kd_K>=$@;5|Z{v*+}F{)zaJuhG#^Wx=yl%OXd#JUL`dP zOT&-1Ff7Ub0arKOg<{RltKQ5~%;nw(LFzF_g;Pa0ZWWf&GP4D?P3 zu>?UQyN^6Arf1g?66q)LG@3aR$!(dfw8vFEjl0^@=}=irsza%{`t8PSF-ednxRD)I z_aGk+0zAb^3oFyuT0O#*o`-fwqZQtJki|1gJJPemq-x0AB#j8g481fLs+b{}v4mzY zm7#T}+kuM&LELhE#6kow4M+2{9Gqd*2BE~zJoErBE!PwjiirojR9mPu>JGJ~mlD{+ zS}9FgwI+8dEzk&UXUz@OtlO6ARy@M`FXkaLXd-?ad&Z^CXz8ucbPqMZfMP?dq1!$b zn<+Il%|$Bq!W*$1lZl4s%ux~O61at-f|l@1DUzZuQvU^d6J`mRAn7(<1%Tl22vmh` zPy$uE#;g#o!5T<|f$#rg?_J=ds?NRtBr|~si4z4RB1)>UL_tj*tI=T1h6zj{Xsj2g zBGQH;tv8O$C|1S5B$aV9idK)dwbh>9Y-?Lvtp@7RTo8f?0j!FbDrj4Gj2G0(#oPS9 zzqR&E!o^dyoWAdQ|HqGH_Fnh(tYQci3&4mUc!4wz`mnngVc8d3c!_n3%g)#-M8qv)37j zY$_PIj@|weg&B6IZ3J*g?OHN$9U0oy(zuo?&+I1gCKUtMh0iJk*C8W|V5j&kUNk<} zJQOS%pNHK|IpcBqkssNj@%iR~EDE#J$btZ9%Pktek9i<#fNgHP+%uI?q+inajVwAl z5Lt9;|Hz{80~ehg5-U_b{ePvbzU;{VbI1yyj~2j0S%1${%Z$Hg^ZPo?65@*7 zf$kZ>h&v9i>q&*twoSokphIj;DFPLu4g7Q%xq`h(l-Lx5KYG;jQjR;rHBP2H-v$E@|s14nOPG+mXxW z#>hJu32AoV8!*W+a5EdXUgKuak#MycF^*9T8efQ-@H)98xDXV>^H?Jhrk_ao36dO$ zla5M%#G2%@43X1M)*+qLbRg2puw4e)CdLw@v1MZbC<`as*8#rxdu4)g(_V zWadutw4l_5kz_@3UNAYQAUQj`lnc+m1Y{_Js8qdgA;MN<7Z4Bq@CXBf?CNobpPzw2 zcJ;KR86ar&G<^IWIpwv06Sx&C5|~-Se-$XgPb5p+$M8*-y%79OMuWy{wc`Ihk*^Ms zs|4ArSjwQ;+WD)4X6L6C%48pLU;S>>-H~`{M4-KGJE|VMU|%crg{7Bya8hSAZfifq zNJuO6zTiXa2rH*nC)p@+QI|Tn`LFL9_thCrs;2R~A^}rF4_sQ9cyF3zhG@>vxW*tc(^K4`=5*z%QzTr=34Z@~ z#QqpYf#VoNyWh2PQ>S@^ZQ|f>WzU-W;rkO}ChVz>2d1fvvhC=}dVojzABNRl!D-cFZ zB`5q2?J=A?Uw)Sx*c*+U5eYBOj0Oq8ylGP6>=rN7KrAH_;W6!rs&>*SG@k@328g!3 z%POp=ZCE@asLu_pjHuPdYd&xNE|8?3`~>uW*g(8T>;) zY0ix|P%#wXyHfQMYs!X228s@^aUbQxC<#xcK>c9L+4bU-9QR%=aUc43EnfJc8w7Rb z_9B)NLBsGv-`1jA^oqE5m$e`27q%arsM!UHJa%{b_(zdeQLjUucJq7`Fwq zK!yr`ggb?Cvkb4)k%z;BL9EsqcOyL*r)BvPWkpUSzgn5IE|ve(rgzh(A@X7B@qXJu z3*b3U72%H%{XsJ0VWtMU{k1|Vx;6PwStA${abHOuR~B)%Mp!i@)ad9MTr205hv$^S z36vQ@ANcCm7wmC3TB5l);X4*(HlW@7)pFrfsy4BEOQuw#-OOV1`>d2N+uxFH!`w4j zY$~}=A*kAB!ngRmtT$?ekm8mau?wLPyUvh||%GW>b+U4=t{4+f3pTN+ z%_9jRX*5hrxw5)ccp@W4>7deWZwzvSWw-@REOhNoSFKG&PTQM7S7vy5+h2dJ!2iDm8@3Q=0~S?QCY`DXT>t&}h%MhTVX(NNF*Wc}D`Be=34Ypo?kJF;qZH^>dU!O^UTVmJ8Ii&30ivMUL0Z613@WkB4x}$`Gxo>* zvRSk)v<#A*2B(H@_>KiA?43Ui!Qak+HPIjidpqBjzK!B$ClvD4Cc4=M+BwJE8xD!2dxAv=l%jyeWT2Juqrh zo%^hOOQzMirx#4d3-F9cD!L=ukju?-?$Zv({cK~nb#g=NBitZVi` zq$wPbM$@y5V>#w6TW^Ix<1_3ifDT-VGA=>Tm26 zxBa_`m-8v@eH z)H|t5a;1`)Dzo*Bszqx6yEG&y;AxK-hs%ZRu7Pxu~w8H5ynO z-r)W8gkdO(=N2SKv9!VCokLeT1D4}MdAvKYdDZ;kb?Bb0zo5H*Y~$5=>6~~$dR3CV zYu~U73`w7=V+gv=EOwo5FMRj*lh&&@K49sTOl&~Ac$dCq*15L9t3g)0sBBK1`zq=+ zd~eW3B|gl(rXRqW-7`1ZoQ@Sl-2=5;`+4PBa(5#z4K+0b!&*0f=sJoWkDG!*H6g z3stEVVX+D*pv6j(zf4ZEON&&pRL&L*C_j4Q2#spBSB@Ku7H_h$d<~sjlw$WZ&#_aw7H+_nPgUG7*K1Thk+YWUNY>tb{ zDz!PH+7CCp#RS|di>tS;EQsxA$XVi*{?XLng6=<)Q%597q8`?!PEXec*3DYdcv4P$ zUnkue)&GyNq}RS)+t7-aJnn}#hB#znIUY$wAt;M!EvT4JWem|mV>c7X1 zCyYB4Fa7j;dV!Ogor{lltVZ;ry4F3udXbP4u*^R)>h2$P*J?Xd)HZCySJhh`21f$# zxLsP`3Li^K$ERzP$7`LdwNs<`y0P$;thu1Q*Ov7YH?;HqE%Ax&gRfiq?7kX)&idks zEZ5@C;lAaiMvLTOr@+snxpm$FQFj6eFLx%*AJ4e-liIy*m-qMMRq`TnoCe96vN%uZ z@F&J=jgQcy7iB_^p50Q-3V8?E0oJ?9}uV_d7P`3EwzuPT- z5S3E(7h7uF-#d9MsO1HK`iMo5kQ$HIm)xVRUqSoYxUe-ci;_G2waC zn3uezC0o-Of7__Lt#;J5XyT)SE6%HRUyP1=5wCQ%^WYKDs;5H>pMxHQg zCgCi0Ku0w2G{>v=6;A8s)++}ZSK6D%h8pfK+g6|}TGbU=c!R02BkG<93&pKPE{vpn zIeyg2Xv*pzYXdJDG^7AW4R`Up53uF9Tbf$09Ohlf!X2I_1kK6cXCk5Ic3SlQK9n0V zk+RBB9nstC0^9MY&W-KwBtA@snvN&mNk7_MDmk`cu~Bf=G`}AE0w>#1Ct8(Myv#{F zikIUDn00FxNaDRV^z9RGxY5rl3a^Y<>8!avPcYUi7wF1 zz-vR-DJn!X6+9tYwKBBuuX^E}m@{ihZPnJO`vM@W4NZ6fuvU4$k|)1F`CFA5^$t8w z?1eYHehB{rIOj!gj|R3!M{SI6sx=*+G705cZD`yI>%tuWE~*e6n9+t+wSlhM zs;1m$Har8b_@8WlzmaFt0)%yzbZfaKQ z{bBQN%9rc?cPd#DMK>d@Pc&JM(xm4YDj&F&E&tC&0eRA2Ho6baXTlwZ$YxtPr@pN zmr0-!C`VZM{p|H&mPw7I#xC}*=x=GE7)M{Wna+OKVUrqi6-A9ih1C3ElrVi|#FgQu>7H{%7wgp|=h)ixlXd9E=9pVsPYXB7sm2~zZG2(8 zp=vudBu^c?tD#hqe2(;f!%+?MTo>1a+s?YCmTC`cbpXrQ-6R6Kfl((}~srEX++kl36;P7BNHKAw?R$5nPV~6Jlfv6AmUXRexy) z4+a~yigtP%7NlmV?HQ(R!wTun0Lin%tI|(8EoHPpf1gu-9I=GZ`=yS3wm8G-$PDn) z&s{Y#{#rvYz3U1OV~)}t9l`o=Q)feLjMkLFKu$WnOQdLFHKUShj$HN#B{j>F`DN1A zzS_H;7JB74g4k)E%Py*8utNUuD(*KjN$+XHsi>*cknvP>TE?1wH+qljz_t_n)DAPO z=h;)NBg$AfPff|q@BjEnduuczh;@rcDAiyft#8@ODeiV}pu|+e>BdGkr{h7+oBbm0 z3jC(wS+)XjG&O^qmJ%~aR6=XK>!39~dBROij_Vy~iK{@-`zbDWSpCgyn5!9T;>uu2 ztiOR-ISl^#@G4p>@4g6T;p0}<*Z=tSzty+Cs-|GycdE*I&tL}L;kE|AdG)crzX!A^_2w!k(2dE@E z0W2XASz778n=AwJ&qO~g{GY~Pt@Yat{=eH5{+e%z;ZL&~x$oJ^P@PC>&U$!M|Jd3d zPCMy8MH@D9at#)iP2*b`{<&mXQOQ$~3a4eXkTNx7#4E#cyju+~UUwt=K+iylpp zRDCQ%h};|_u}u@SEcK~%yXa1QsEhEm#`|gc)^t@z>`?fng96(}ZHzWNZJ1P(xyWS3 zU+xK@h;qzvK>v6C%}^+B;4559ak+~uI=0)ecSnMMB8B}9uRq0J>#2XiEW>2U8(at9 z>|JaQpHA=O!?d>zyFUt;Z2PN)iBK$6AGa{+?_H5LCkUCc&x+;_zlR;WFXlUK1j=GYaRkrAphQ1~ZS=O0%!`(I3){T_;c7GL+gSx9~E z1KgboIDzNe97I+Ioyt*^x-{3@B&`L$7gI&HHyDNS@W0rlolccyt^A3kCOE0nioEYZ zn_-(K83bSJtvuWS@i5?ba9`}EG0Eh!?`rqMNGhJ|#SFVe zmW8!Q%e^n{0_)UdFc`V{XgcjV!-w>FxPL=Oj_ifLZWf0SoIi6i77+SWaAhCTw zydrU8@Y+$F*GBOHtLu$N70Q7$RGwWGGAA|SV!F&6WmS(|o^M4o&gXxOEw=wFZ2$1X zFEP{d?!TdbwUhJDe}8-p8?r?X+b2_GCn(tRBX?*c~aBAVxI+h`MZ8dmnjj_*3# zx|!=#Xm~dJahrdEpWkOa0Ke0c2dKriRCvo#Tknk(u>Ea&+RPTy;o=?9X3;1wHp-OKF8&6U zXk#927!wN8>HFR@*gUcoL(4W7%yZctCYsjl}Cl=HuwijGJYT0H6 zq>iLfprcTqdLMan`qm4t(jEQ7-Ssk59x!W(;xP;$S_N*?d|IlrwrbsFuhk|8EM)*W z{-k;rYcD)m_+Rmq-G2tZ?GlV*i|wI(TYiEqpIxs5vW5NozkYje{%en9x!-cfm_}AQ zL7@>>CZeebO89hVZF0e~Btlg##($dZavyhPc&Aa?@%{YC zo$={`-tkEX;9Zx^xBLCum{Dvqw*Cd#d>rmWNQA~itA#^-&!_x}2>IlVp+WOo8{ z_QkIE34b#1u5%w_iyC;0+;tBOq|;QCJv#Oy?~>kbh5die0O;fKzjsR6p7;Du-I1(65d(P4qX;qiK4BX7vp)bFO%o=f~vLga{ z!EHhG#i?qI9bw7|hRc|$Owj7Z?jQq2uXJao!KJe;#i~pA=%OCpG`p7##wK8X) zJy}Ls(lb0`KlzuRFNR(Yh4VF9sfPp1-AF6!F;|E<74N8fM>B(ZD*d8DL}&kb|Vq`z&P6;>VP(%=m}* z8GnRM%^7A7Hcm7%{yiRN+jN3ujk-2cjT!8{#M6YU+KcR67Y7 z8GrGlokW)=A(NIB_)qfEZwLwu}k_bB)2ZX&U{q9aed*O{xe75z1 z`o`l1+IT@3r9htXfLcT7^;O>Mz|eXn#b)|WP$T37HQ2l9K%s#g8DbMxR{Jd83SE?1 z?Y##KfYSuv6#SE2q!R_F_AI73-Z|1W?BvB1_RU4cn1jPIJEj8rIX*saKdV-gmm3Ne z=`Rx4WpZL#K%r+e_vnnz5|HfqkRq$&RXUu_@)a|6E;AGz!$denaTp1_eRI_8NC zZ}Wk7vo)t^ch`g-;DZ}4H&O_kjRhjfVYQ0TI9$he5sq^?H4@miZd{bx%ioY((6lN( zz@&7`B`@6CxC6_tFj}GGYOOh{P8QyjnojH}xNIIShP6mXqt=I}YzR$xE=wPY+tjoMm zMKAL=)K<049i%vioF|1j_;C(gPts*?g4Ax5g6i64;#+8;>) zXz#7>rB&~H=R%VKHkQa67;U!NLPB`>8|w2>affBgz7FJsb{8N(0l}7avQFO(OZ_eHAdVC$3&te& z1_C;*pw9G8rjc+f7YzYeiHS@3K;7U9BY$i{zHEzDJ#pD<(PV#%f1FR161QHLvC4S; zd@{}0o5u43Kg(Hk(sMk-U|wE~*SUHfiIQjr>aJwhu$*+O)AAD$h=xw@ zaj3U%QH&tT%ENLNMFe26u*?3P%GSg3VULnK(WcutJU~}Y#*BB(^bVXQCD^Jrh~TkO zoL0)6a1cJ8v3-F#E```vDw)6xInttQn_4Inr-qlSSy@la&1 z1HB}T!nMhMK6>|#V9!giS5tlYe}!4b2y~uGSEJLQE-sMl~2mYUx?;{ zC~6pFE&Z3fY})vALzf$Tf$%;5>n!1`aF&Vtm+6{|PVI(l!T+z42(Vv90C=-*)H-c` zxcUv=BZef(*8w6G6$_jAM<28YCT){b!wUf5&Y}R&t5v|<7kASb?2OiSekVYHkZ-saiawfuO>Hy_h!^Bqo`&wIb-fG|p{?lt*zv2{hDPx*HCHsJLpSV4&ylKELa72CvYpPfjl8=m)9E2zC5`a04z7QvNnKV- z38Le^=uP<}&g!X}7nh3qLg%~5^-jjM(2j7F9bs;t5jwW<+p~@L_nyN5V#~je?pY&T z|3UXTfR@MZFY_C5Uvk`!IH+qBg0q?wV;`jB-^ztyt@p=A#pKRAXw-Hmy<84(Tkvw& z6mcg%NNnCmy7#3#ZwIoKXP@EJHs{Z8+9OvG?w@#o7p*93C4RZ9|p+< zPvV4TI3b!|>7>^rv=shDHK$p z<4mCvQ|PqZw#~%@JCl>CFd>hs1KVun0F{H8%E2C#Fg3q*TwJreycv)WJPj7iS%RA{IBXaD+1&q>IAo21?TRZY%gO}w% zag=?K%_if+tsTX<B5`MkcJ1Z*J`f#s=cHNK2RV{(flL%LC^Y%8!u*j8g9mgqhk` z4w}QYy4@Sd(LNEg;j~=M-|nfP;v<5b236oZvOkGEQ#Ax$2I*yzy5;2ny?jYs@-kR2 zUoia@JtFWrj~t?;Lr5x^Tl9#4={z!ANdq6z26i4P~E5k5N@O^z=}_Uqx^RTnwA-n|b)c&vX_k!Eu{Rl2VS z5u!P@5u^sA5ET0&e@uLuqR{qbR# z{D`+dBf|Byj_c1_>pIuc07cimi}xt+Iy4m6TjvOM(mHn6%M`a@`Mo4L)BiW7_s-nF z|Gc-To43d^pwV>R9(bKPH;)V61esZ6IcsN8lpU3qE$Zi&kgsyZ&Z6pEze2TDnNfpH zlo#AXl-02R(qiv*#Cy9GwO^vLMJf*T}DiyIkniEEW0N zUPWRbo-z3!A%tYE@AYdj%k2(RpVwA(O6~Es`&MYecAc0d<{0Ogj@@rg@q)gG_#ktL zlR3p^X3p?|pYjNg=cmS{31pi*BnuDRwPF&(ug2}j040l7pBN@BQbu|sAM~-gsjQKA z7Mt%oAjFvKW_1#Hj3yw0h;ST-XLXS(ZOcXbkyt+Uzw8tjnNXAHwg27k|9rsq1aKMs zGvV}Br!*+#179;4l73i+{{@`9-bQo0o1329CUv$_+m)KU3KL}2)^Vi;F}`#$sf3Cv zOc7b8ygO}?lH^r`DUvJTRK$ijEtio=$vY@174JM1``BIe@!+%i)op(;vv69@wyln* z)l_tg_j6c#ori~W-W^Mt7>%hEN!4E^jSW@`?@-PoUvapyx|BTR{f~()u2EFu8>*X2 z0-@JvyG1Omxic%4&IzZ{(nN98Vx6i5*BVz2vy~-k+g)FWur?J#y*!n=pV1+j*kL5G zm7p?`*vfI0V=Cj@oY2F3s|I4peWp%oCR*1?Boim*r11;;iMf7K=YQiyh>+Nx7rJf? z4c0WLuN|bRo~ptv*YmggSkfb*hrdAGXu8d~ds8fQLyj51M@Pp7AP|;@ny148h6(ca z7n7@wCGGa=BX()SR5JL))6t=(8>ry(&|I*)SGzCNG>kTDn*S0%X+ip??|%2d(86D8 zTn`yo^KFU!ys2pFt@~%F=@<%&9i#-zZ{*Bz>GzY1Jt8DstlA1WMQJlSr3`65kOb1RL8n1sGiHa9w$z zgVX$$eoij#qtEp?sWFeFuJ!nt-}95ecBS?44^Z^3^op`;+urOyc2RH?1RSaD)o!sj zDyf#ASF^XHiAzQMwS1?n_U3KfsWJPtrSlX#oDDVoooZ-(j_s?TSk|bv+%@SgFKDcW z+qp2dnlz0zy~2+7Sp%SG0}x6Dza(43$yGWoZZwtCs}T<7509n_PYS#*`|l`y=%}zU znqIxgVS7Dy?W-t1YEVRWrB^Nr?$?v&ZZ~Kz{90hTXF;?M-8Z9v5n@gu)oDrax94cR z&ou7~^?r!n=b88K=zU+k-(}tD9k zZG*4wHy84`X&`%8s41)mcbE}fNAlcwbvT_9T0ERbX(aBV1)~(K!7CZHaa1ustM#WI z)qlhrh*1u8-r-n+fBR#tE5^rkY+%$4dH2a)N4$dE5i%uSL3>#Mn~_CU@)}k~UAeO3f&1a|%3~O;d6(qis3?ZC< zBw3@m8q1dRM@5D+25MZargYk)MjPzSvIT|GnX?O}j8L)GJz7VEFs{yR zD5*9nLSLml^dlvNZsO-Y^muKbF}g8b=gCQA3lUc$eN2%V#*#^`(__I}(#h zvBaVmcv8by_|AbjfG`+41|FV~%%e-ErHT%{)5We>Gso9V>KLU~k(y{IeV;9vY$%Ba z-bl_JjM^cZ9EVF_CiKM7TFOf~5wbA-NTW#=9Y{mHFx{VN7=9o-xc^bx$?(gW`+xTU zEM2h5Gv+VuT!>*Tl?#N<4zd3D&Eqm|tzh4RsP(ae6>(rr?HBuk(-O0Adh33>@;$sR z6K%G}t<88*SW}iH0WRq%AR|p;sgmxkRV&7ZK^tN2IL@RenO%P8 ztv>T*x#ehTns`~vgWZNq90ZC)6W=O9T`ljiny^u5w`x*+su%`JG}{mgCv|$gcP@Sv z?)Jp?(?U1sFyYP*x|VjHY8%#qj6L_EYgrGI;P2x)Fz9L0v`ITCm8zeg*%2!t`^X5= zgtU^QW5IOgE-q{2T_;0_3}FkFYhUPtLyV1WU^Fb9-i9sG&7zGlm)RcpJ0)4M3cl7S z9-&Juq=rnRYw^#O_nGtSJFtGMofdq{m3gVjT;qL)JITU~#{d=Z3SS$k@ zpjvSc$Um7C972Xx@Gz<^yOBScH4JbP2)pUXBCeuJfaiFUaA}f82$K&9h0}MI_M@H} z;RjC(uK;uIRbTG_7uW8~-f8+(R8} zZ+)7r4NQglvaZgMzGra( zyhUK~PPGNYuVaOD-_l(YE$^LV;lWoNUD*Lbra4lpD@Pv~--b^51~G}kk7`}Ijyfh_ zP9OeTVUkjp=ek`+s!y->7W_n~x)X}LY32EvPz~)|`?R70vV=5*GMMN)(v@dO5$X%R zd(r%Q%ODb$N~NxA5k8%=ndZ&p10{w|B(P&1xZ5zOkfN ztmOV70Yt={e=F))*JeD3Co4iCWVUDH3^ndtmLam7N-^0HR6HZD7IC(Uu!B45uREjcJsSrH!=shpD= zAI#spI3LVz4JO)xPSvWbU+&q5pU~o<4hWVYx{QVmvhmf5nMh+IOOdL_<{wTpw#@f5 z`5+$dLcv6P5TU0o_XB59L2bIV>VT{NTC)gA|0B1bFWI`66yW(6P)NDFWIvIb*JGCx zIOKrnN+app`&L-RB9+G-1Fom%PZcs$?<{YJ9ykw5esQk5+9G(Dch`@!cr~HO-?w$h z<^+O&0M$n+Pi4g3Sbu}tJ)ssMGRPj!H+XA4wV(}9Z?44gnM222uK1WDXXWewg4kuA zKKuH8+M1d&>Z8p4!ktcn&#{%o{c}YE!;(RN??Z`FmToJc!w>GUbo&~nx~zjg8M-|Q zYbyRs(0-T^bF5-fmp5UTsCKEhm{SJYUnmykJae6(XSB-BFoqA}J6m?t6xNn$l<>?= z(v99Rl-}LDa&J-YUV5Oz4K-gK;T*C-=IWWDH$cLQ*t$E6fd%14wi>9LykSHsxnEo7 zzU02?)&5$8UX6ahd-vb<*y(+QTdE%x?n<3i@<3ds;}u}m|EiY}{?OY8qiLPHO($0r zn|YW_XQ`ZP&UgQ0hbf8#W2M<;cRj7n2RM)z58QaSy7NLpp z7ImwOb@CQz1S0<3zgJ7{l6CyZN#)`?x2fzdy||A@-CN2Uc{H=+3q@vEI_V8~Ma7Gv z4gJh1Y)tIj!#>pTq-s{Y8*{q)mzcFRzevj2(LIv=LcP!phnWY=isBO{ql7X;Y2l^& z4MoUtr}L5MHQoici*X7V=8!u@xBt)}&7o@l5z1x&HP8q(#wZ4zk4t zKHfFt>@;sNNX)zG7rpa7q5Bwy6ulih7O*P4JHAKv4I5#I&ZC$CEVRREk#CguF07%# zfY67Bw`!qZz zZF*p?w^LbtJWKV=S|8`t(u*0b>KspaSM) zqH~d;?{4qIpEa|WUWkTj{w&4F^u+w&ze#+L5A@DNIe=QCpyx1Hz*v6b#QfNS-YFz{ zoyKAy(Y-YmTbZL>BwOAHGIA>XJ#UFnZygTJm+V_q)l0FrP)DDO>x28cODXX&M;MwjeUBK129y;1qB3MCc|Wi2R?V(QQfik9R^U`eIZ0F1D6VFY4LtQ8(Pcrd1Vp5otl{P>XEy;zqE(K zbNs?*+QMxrd>DnrIaQj;boZy)|Hys+Ne69t>y@Me zTVMX$rTq9z`5)|B9{YJc;Pt+4Ygmm1Qamd-Te8daXv5fGV*4RioJF@oSr80Lg#|K! z#l}V4Je{<&qg-kv;CpCUHy_>wE%_&>$Z9QgPAQE$&j^#|nd|$N&;p?j!>>QrnxO6D zCxeK!A3pe90}ol{_MvuV_cr+o%FfEAEM0vvP|Delz9*quQIU_avKs!)zX$VG+bW+y zMH{8IPnYW@r=s^mcq^Za9h92DBZcCn2lNW>=LI4F+2%eOBy1_!Hx-*v(QoEyA@6_%GTdhVR~Kf5(HTRzxLI#(jI#tp{E8xFV4WsTxdO=h*6MZ<|5 z!T1d02YSx38)!mH{e3l+Dq8p-*j^O4V(d0Ajwb~HAG@DIVxx3!Y;?Btk8J5PDV<@( z-tlTEZ@8~+#?^4?gAHou^n0^G*$TXl81wUbq?`8~Hh?DVhFfWRj1>7ap}+4LCq7`RXcq7?t2;!Pwh{|GiAH7>XLxhwskDo`a@iHlfcR@>Y>`KLqj?6gj@AGTC8UGL@Z7#O2P zyZf3f;o_LTzpRn$T6f0+zWa_xZWW(kgMI7y0b^!v<;w=D_E>=Dv<%=;Q!i(A(oX}) zrhg~JBzI3>t~9~>HZ--376ubnhVOtjNhVm*dr5sW~L7uE2EvuG1z2YjGb1OI{9dpZdd&s7EA;LzAa{>-?Vwb#O9FP zC@L3m2=b?iIk98-3Fd^FwMe*I zpZq=iYwF6%)CKB}qrSkqSq!&ZWW480${a;n4_^W}xReJ3BNa7eD4(nP5L4$N+RLF5 zZS`P*%75*yQ=N+A>2@}<-?Wfrv%NrXfyC`PgrMsCEr5zlanOV zL@6R3JxWpfeKakqa49)XDmaFi(U>Qv(X1VExmVR{o;iBFN>`6YB|C#rc=LY2h&(u& zD9bS;C)6Zil*j6v*s-Y3kCw*PU6YzO!0Upu>ls5YY;Gjdy#!6DxA zV#7wg-#gRaePCzWOjckUP^hD_;6v1TuDZ}j?BY~#givBeV2h86s8;r6kxS-syR?yt z3eeaZ87O~yBPOr)P&-ST4^mPURw2`#pN(tSP?TP z?BcRk8Ws=rby?fsuF7c=E3>v%mYw?l$%o#xD+~J4mwJHUtrXtLujtAkK6;@CH?6Sh z=A0HCX+)%+6*+8^E*YmT1c2DxcECqh$53c^XQSb+b^n~X{|UA3i$1Vtj%5@?bF#$q zrCUWlGFf+$g^9CiYiN;fwGhg^G=3;zU}F2hSMYJvq8v(x9v%~Nsy>W|Ld*VE5L);Q zqc)~b3Kz%r#fIG9y!HeVU3{nwqn({VEw^@<&*KWqSV0}p0V&MOMQ=*IL*6zhyGZpW`ik%XT6) zlv+D5+uDn_^nw8k?VoYT5kHm9f3Qz}>}qDd&t(VIxVTk4IT^DXyUROoJE*?BxwU(l z>bc_$*IRA4UJS$->Am3#S=t7Q%&!t(&b!FE?Q@2>XH=ZL#{|$Yq_I|oR3~`sW8fm2WZIf$-&k#TS9Zh^K z6mJP!M00xHov8`AfsUT|UxBc#$*7wr`Jgk6~ZzpH(*&*!%O z^Exw+XyRmN?nt3jHs)&9LMFgXd3*xw?k}cGQX4(Mn#%1$oIH+7fN311{52x zwYr$E`{=xKTJ99uq=tCl*HZZzcq1f=Sy4-YIlFwsyNkSK*YhVMY~2dM?%_Nx`om>( zd6r;^ss0vr%TP z;s%oakr0y;f=H0b2?g%B!sLWPeNCz}x2HIg9BG$o<%FOZtK@{@sQV(8JUg?Sjf3FhxO@~Se2WcRGj4j;ZPN01s-sQ)Kn7fGG8D2_|@P0IaXi!O0!*6 zx9FmO)0(Y{9R%#|g|>*Lr*=37HDFe{^Ucb>eIqL? zDs3d}nv~PudlDmdw&LxXik}K-#1F3-nbSKv?FZ{`(pMkxU=tl-Qf^+QgF{CoxQ3+e z;3^oZc}CZkixP?<^tk@AUT5ad2X~Y-tVxYW;$`JIT5;;0UwybhfPtEp5(0@ zFaeC!UjA=D?ov1ZE0m?+;ksu|Nn6U4_y(>=7&C()ZXk-;70wBa+N;WfWYM#cUE#s^ z5=xn|_q&9F0@|3r%11IapKU9Z0_?gO= zJmv2k!_oY{ot%$X$NTVuL^(3Evp?9?F_3 zGH2WxdiT#bh)FdANvARg-SLLh!4t4wIFbHFh7PE^sIt>Rch8ULlZ{fX{X#dkPe|rN z7cvU>3GbU%n1gR*_Tc+IO^J$}wrGzv@trut?T;yFLNGZl$QRo1{dOl5CdU=J6U;Fe zN{0PYZk#>k#&OEQUT6lrBgn#iZ#}rVqq28h)#k46_Int{(sJyzc8T2lZL_n7%nYfS zP#9pph2r?%!>B+_Qs#NO!O50?=S9sEBL#mVCD6xbN{AK`uy+e?gzt-Sj~>>7#fL;bhX zIU1#~dFM@FFWL>Y_0b1Ce}NC0%;%Q`8cb`)8r^Mr$U}>cP_!}wEs<#yx}p70wLmPU z>LKcNh?#3{?Fkv9p29!fgGeWpg=Mkyy#=aOc;B-HLrseTt~}_C-wT;i-|$-MeE~5N z2wsX@Udp*O5xAA{iPEtg|DPk0*{aZYTZ!4^F1BBa;_&~IjA`~FkZ-E&llfrZOx6)} z@2&a0zM07TEK+agHGMMo7UKHtz@JM9@@~D_tRO3J&a9nRz{b4&q99V99x~>-Ec|Em zf&YwTQ&}VJXbI+c)%VyXC{(2x-e`1Kg8$7FfM2z1S&<&H<=fe|_@1}QR_wBt+Yr_K zwR}SPmENYcW=SUQalIBmCt0tf{PjA-U#|mLuYuY1;!Bu-H{DZc$OT%JU7;Pi%`Bq8 zviG&r#(p74d52wW9e zrb}djE^jd8CF3wWPn_@5GI}jouF35^{l29y+pe^*;y&?p{+akqbb))=3$PGZQY1@c z{PRCkzi3*fei7!QJ=7Rn90YxZln`4bzm`$1C^=g7`)mW*g1ogPx&lwF>w7OeGx z=2XBsPY<)bW6*no$FZ;Jwy*RiQSNcIn&1146H<7qE~*IS+&5%=y~s(dSj&~$hU(C5 zk0u@+s#^u4y}QN6+v{bAx-WEhs{!uPvNBV>mB^}~%n!L(_MS<9QT|b@5f%q~-!mrW z_z;;f3UtVh5kaAapHs5VJ)CU$9w)gVgc3p;DcVYX?$f!=L z3Odzlncv--lt{5ml69^7n0MR1;o%g}?Ha)ce3si+s~%B(8YNWd))kU7EGVOH@AaFA zY=jGz-$miQYlhqd=6tfG>NA`(TclR<4ub>Y%;YmUT-?$c&hP^GfUt(8NGSW_H45kT zhi`MC<@>GX>|C&1^_*#3r@JaxVs6Q0u&7~_qBUunLZjRH#p-ua5gh(=JmWR5tL2?0 z+eUH0k==2(CO!l$yS8UFynxqp2%HOYmCoj)Z{(c?YIf zV7f}LtorlS-Eu=yQC2&~mV3BamPinYA?GYWAJ_QdIUqq-6Pp!FghCk35tmc%W07R# z)Q~0AqS6fM7po_yf{iHnDkXH2IFsLUerF36P^vtG&`u|d&{u>*! z{hzjL|JB+4E9t+IS~RVmcg1Pmh5e=868LK1C)by|=ux&6i+oP#PK01SSm|S3@9KOq zMEGwi#d$u5ae9x&40dszUq3y2y3Ejht1PoAoU8C|`3VIpr$mUtdVPkty~H@*Q)1K)uH;6a@P07tbn(=f$@RMx{ao2}|X0 z;1!q_#fg^<6_h7_-E7!lrkGMolp2r@7=B0o8|EvrjXZGMvaBR-?oF1ec%?T4&rB85 zNdmsrC0f@ewl`c+!!sp@Ok6lDC*kGUc%&KvH+_godcT0oYq`#oNpa|-tIzSw?@qcAh+A&*}DkB->KC2=y*Q6hD%w671F zA71Mc?jWtWCENJ^g}nT9R(>Cu7nFaJv+^#Dr2ZP}n%HKst8{8|osd&=<}IdFC|b3R zVAg=LAM4t4jsmBdvuWk{pq88EvZtjzLDMqRR{O^#d3!wHGDqg;p;g|4-{gGjXTGZ2 zJ950EpNj=*lZO}~w)aH448ILdGyxDlfxXY4?z(X@`ujNYn=~vORV>R1f+HOK(O3D) zVp#WpNW>GN{l*n1$CY|jl1o>yB%xcgCIhViO0NXwgYE-R2JYJ1?(e<(RXb4ef$Ftl zf4kHShi~7xe48F$jU8NpOUDPfV+Xr0*o_prts~JfwCAM6`$OXuq}$ZXkJNI)1g-T> zfI?}+`g|2gKU->oIgG8ItDlMYOX5$7=?Zya@#!}3U49RAW?L_YjKx(Ql>2pZI(M!1 zt#MBsta|(Si{Df7aqN%d5??QsADuspNRnq4b5b5`9;X*l-*Kl~{Nm)Rt_#&L!cz;J zbUV|pL?2TT;SW3)+uOTlw#A$k-N!?PcL&~HND=%?`r20;1^x>z@v$L)^wjL>GLK71 zI$ffM-(c{@5ehFy(#l2Ef}&fJ)JL;eL*t)!w&C_IdP<;|eB+j7JUc^?$EXy#wO#dk zzChWMP;+^JVwv(#+R-qhIWZgJmpDJ$OxXecwGn!m+z>3Q32&Ipniilh(1yeFoZ$Xv zT9L_c=rbZ!ZK1_$P&rO^Jw9(%+k&c|yNBXCxoG$i{uD&WJtSJSC4QhBc}^KUYRoZL z>>CX|+*%v@acgMdDO4q+@D#7#4}}V$rbbf6haN6F1xBg1>O=e_vPE7-v8W>FnUsfv zr_?~BAI2^_AvO3GijPkXt~XT_07Dn|;E~4XrY7ftANi-sW_e~=F!A2dXsBjIsAf$~ z)h&%VM;%T;j6%xmtz2(6egr@hJNkvLyIKUkq0Mm@H!k_ZfSlSuXL>X4udiR&DduWs z_cRrJZ)p5rC-L5~*A$U86DZB>j*u=m&Fnr&Pq})MmkkAU(_lvTVZ78eux*^g`?>Lh zI8$a?zRLRu_$6A0GvG5PLn{l$xlOm%GpY#AxHo>CYD!o)`f#y*Go3)Y&yEo~Cf%tn zr!g?Of+L8$pLg{^-fw7+qQ|9I1v;J7xID5i;=Q7$UwReq`$jHoEi#*ITQ^rYowgnM zTpvZwh*12(wmSlyEf;WC#o6YmU9$KLlJ0Ce>$elc*X`uyW?MIf+aiHh@UvoUs&LVF zBY{;EsR?wZ3iC`jpSB%&iMD=DV3iYiY+H9=ecO9^Sz)ICs7{)m-7`p|pW0KXpEG;% z^@FEu9ljlpvTA(93h@N2?1NxcZ-o}$i7$-^x8nOmzVUW3*AjY)QciA_7w>mr`ft4nLw38e+oUnlD$CiSG zIsOsVGb!%Xt6z$ASX#wKA5V#z_MHTUN_5!Z~o|*58uC|uGj;7 z!;E!pVn;*h-&>8&&AeRy{%m)z_08Xne!ccJGd@OV#2y`0rzhUajnyGo zCEn{7KhWz!{~<~Ez&f{8mp8h+6=%YX#k?E9K{Dd|TdAin=(0t>ucEb*wW{6R1Ro|T zO>8&o(s%ke6`n}Wdf!nvUuCR95UIgenzfb#Y_wOr03Q42- zGF)s};-q4f+k9SCyP1#=>&&)%>OYKpr~UTvy;%F~Y@z?nnMU)cOv(y1^}c-;B@29< zZ=WrdefC_m0lstC=-q6u<1aLl;UK3)dLpBuTH`$p)yY^)>SZzcsf=!k<+DG9{nekp zaF6fZUl|-4%X|=-4U4!fdi2nJdnDBc2-e>Eb6X$n;6)R6QoX1}$#CT%bLYg@m{fS* zph+=w8563xCRFZCS;9D!o-v_v9~yN?9~0^u&_;0aADd7c1t(x~lf>;^O{kg7Sl>*M z%Bb6`8ky2JGh@`t)I6zA=Eq~hr_ZtLF-4n!_4rob_0UqJ?%ic6(5K8`+}`1~1}pGt zv@fz5{j5bcF|DQE-)}G=)+b)!VFjT}QP#1}Go*dB*tJgD*DFQ1GG!)Z%lv~W8T#Vi zsJdyonFY!esWMH|S#4+|LTP-PK@E95p?whf53fR4EA=M*&MfkAIt@nnn#V40CQ}4A zZY92uXkk5LuI6ToUAFAI$ucJATju62@wNNg+HG^RCy2 z6EBTOY&xawrG5j~EqG6e7Fu``dFCEarll=oHpS0RycY;9Uc7rt2T5?}13h^(-fkOL z+*`l#P^NKM!OY`=_ww`q@5aOZABf9@ArFFH~t)c zWD7X~+w0A|CSE#4bMhzTwk0<8XKHPm_8+*8dQN~G%~N-4LJPl41#_t_)Bgu!wuhQ; z0|trr@?ZA6S8UI#xgz-yF9~xbJ zrXKUn<5$cec_(PpOSufw3?i{vh~bZSvp+t;(9T1(%}e3H&VlO%)tunmel6TMNq1Pa z8JO6DdVp7vvd^$H_OMz04}*`b$F7`Qv(HQ=P;%~x+GGo*u~MbOsnq5b zmW2v8Ey^{|{nSR;DTR%u0Y@$5nH^+XD9xEWUfXBkb_S*vjy1LRFY8~p#c!cdwdr?H z&E?Ttz-$QH9IJVTcEZA6_|0i=wRt6Ffx_*6bNlyg&Tkt>K}zj1Q~=}z4I+1dxR;%y z(Vb=r9#WQD_<`SCN#ExDwrz8M+W{%Ox=q`Sn@?$6WdPwUstwjGa`Fw%S(l}MEvota zx2`H?uLxEHGcP#RKa8x|KQ)z4y=*10jc$Pub&3dBTng;Qyk>&G|MUXui1;{SA5{i$a8znN>czI*A-$d64qC`v*XU|2YC9;1jl-6uXaOIQT zuE{Q5>*lH+-$ddn(gtq*5i!15_n0T6=i|%VM51w2V^GH^ToP`{&W>}rxXw=!N#|m$z67r z>-09ZzKpl_c6ax=P~fcj6eq#_6KK_0st9C?m9{>i>8Qfp-ofBh2q)cL(tfFvj80;vH`+s@o0r2siYBhTNHU9S@_@ zG99#;TQS$hL3aVT*4@`T3(FpO)pf0a+38K6#xG1}rD?@f)AAlcb(;K5L&is;#5+-~ z#A$^fRDt-Yt>f9}hi5AsZ7W=(3KN^K@1EfmsDg|gV4e24xf=SXXoCj|^j191R*YmT z{?Y4-QL!Ht75!o!HuRBXIxQzq(p?jAU-xcCuJeQN?WfV6NRB8(cMA{Nh+L_QDQ;4i zlm3&vaVwF$%iH*6VSbG3tX$1CqWkiRCS|&_bgUUj{vW?4rxoI8^L5Y#>c)}?YDWl% z>z-ZU9RlTH3T4^3*O{6{3#e)4?(FainF8NFIK`lKPbC)jRQ^}9Ek{z5#(M8T^&+Wp z{WO6ZS}@H4^OI~d-YWFxb)fq^ALqNgcTx8U=kF+Mq5>){*g%b>9&`cGbOOkgpq}@QK=i=Q~ z@8 z7m-M~`qUj|f*Jwhiiwh0LX^zUBIJIGWsJIG@l|q4`Q=WqQ_gP%zo67uB5665{8sZ@ z%`a+HC(3U>=KGTOi?ZnzN)s(&WWAUQ{gNvF!Q;{xPcwCuUcDd z8sgGmp?6n`!W zae+sBb>&I1{TC<#PvhJHd?Z<+lq=(JgqCd^A+j`8bDXS8>QL)??|!)iSs;GV=)t_7 zV1+hM&A4ksUi7|vm)_;Rp8YoVR8FaKF=w1nb;&QWB%@9kne#`v9&5!4ykDb!OHJi# z6Bo%(btd;fo|}JVw4tXib@+n9kvU8FcuwN=+$-~IaWFeL@&4dz`qjF}z1FioEp0xY z3x8+4<`rs|?v}0N3v%Npi4S&MqLsH*?iU+8Yl#v4nI18w)9p2OdT)=YdOBWQ*Fe0D zr_w`)ou%uEF*?5XW^oA`2+kp;Qk?Z2ev}Xqn?D7m_-sW5mGk^>i+vT|gyq}n6ySdN zj0k3}2&QvRmS8S~pYaLiD3fXk=0&7t3FaWuMKGtRXkxeT_w71LU;kZedTw5IWk&m* z*fIE;L3q1xx^@rHArRCp_41C?>94UAXMd3->0=ui@~%zp^j?R%MuonME&ZS-i%B;x znJY5`+MKb$WS%T8{dpv6rBM|0uXV?k)KUZ?1gFeZF(nj7lesNyuYX97?0kmW`7qLZ zj$@=WQsjm4^h>l3HnXtN>@}aA2Fr_oKJOY|yOgfIHuwY9rQ|BlFaJ-cq&fU zZxI3muck#d;=b>7$p!XYyGbY6|Hs~&z(-wO{r?F`AZ$)hBH%{UK+(9Q1T_%Q3`}$)gG5om zoieKdF{y$%anYsHt_uO;NJ?GqW6U7pP5`BVk&z?iBH7h1Kr_MmNvmN_9b4moh z8>y|W?68qUYr>B^wj`Gc*PdBS-EgF~v`oGG{Yfy8rowW0+Y@ZQ_RJiL5|Fzzf6syX zebByX*Z!pB!sNH?o_~it{t`vV7ZY#$?FF+EKj_1M|E~lbf%(QVW>7fJAd!sCkL2J~ zwbyW+D+?M5Q!9FnpqAw!3tJnw${pPtsNd2*xtj#UBLCpN?mxp8H&oX#XJQCsGIFL}gDQj_vR`L4!n`FB zs3j{A+*U&ks1nwBg#i*{ck1ZPb}Iqze`g7%k%ck|6o+x_X&}&rimePj&Os zNNRGMNTLu8myu@s{|F}~-Q_~Sx1AqO=XcNQu=AGkc<1?h_bYe%@p9K&BPvpR0)Cl? zRb(5~&86kBvXEINA+@7z86WQe*Fwna=e-)if>O1kwc>bOAt$9o2h~4DtAfsYFq!ch zoTFpmH&EK7nQ;u#S_>ItxcrVsC{guA@95EqI&Zi-Pf#bW(A{MYO{x_enHsG9fhzLi z;g4*`eM)LCycIjc$aEr6-+D+XZiM{T+%2f&5+wn_iOS2hxKdIZxiyFB?E_BxT(qQ2 z@$W48S1TZ|UCHi2yOIdSzK;hHYqm)sMhjdm>s1L7ueY#f-OPdbCs!gP_e3`4nqH{r zxfxrUd%=!Vd3Yz3w~atIX`kkOj*9Z!48Vkc{E797A1Tmwb6|?yEYR);XnUC!{2x#} zL1ykD)%v=b1JOb>7X|7!W=*}A8~3~g3o~zxo)Ru!8Y&zX*n_a z9M{>J8EuQ4-h6u`Hab1xE%M{)?oSMBxh8yHq*J}cx48{lqfuzHOr*4w^c-f_n70T3 zttzKcMVn?K!r&A=C^*Q4n$y=D39EW;p!oszH=rEESn!Q5%W8gg_k>=}%TaB|OSn7@ z9KODSV0CF`3+BG2^XO~$V)0%mlWtbJAapguDAx1`6wv~|eW0R*rYu0%Axm#+1H|Sg z9>_v?V#&eq>{rNQZmrqxgl(9U9*v`VXb?@tmXe1VrG6$iN|k!Lt&}#mee5D=?PQet zalEacw3U*Ar|DkXmegUCx-MR7N?R#)({ux+gnMVwf0I0Y!QYlQyQM_l>XvdMf4}GN zCI05}_Y3|~S^T7}@_*uMJ9)j$=wlJ{QpwjXNsQC3l~ z1#X7lvY^fRf2s}U-=JR};rZ8?TO~kPlT4sm=0^_w-W%pUD`?CNaj%;))9Fa6<4W>N zVkJ1cy%P4qS>_q!4T%yJ_DbJsv#7u-(k>NlEHd}eM$!5iPmAZ};NTam+Sw~g7$dZ8 z%^4|;u_YtfSak}?%X^SV_Q?|Ic`-07-RwSIf*$^?zgPjZIzigARK zhvt9H@6Pcj-Pw~!VXhfwXBX6wl9;S!=lNQK^%Ade{pxx0G$&b%hIZ6TUmZ8`+xJ1`rSC-c3N+`VGR92 z9Uqn**lU#^(M#pYDS_&DT6H^z@lfyC>EH{@(7!rF`lLwMqcOCx(>z+`PQNHfpSov`pH!1a?9pVkYjS2%llz$u&ZEg(a?J7CgKmJ)thzb2rJ!1p zgciR8jJ;}^IUYcR3|Vz^+Y0?j8yYi8?Ic2mjm|V9s~qr-(Xj5YRrO_BG)pC_CT4B1pW&>` z+C0t%O~0VQs@C-Aw^imC2HTa+gq1n5@q-u%Eq!Um{J<{5s=B3iBr;AlAD@86N)o9! z@A@`q>@?dUtj$B~HrNV_sX&QqD4~{ZO?O0DM=?dgjAh@i>Xc3~Tdc8mg_-zWx64I^ zciZZh%`1MtTgor_JLiLLDP8#7%HPJn;Z4uqM0RybYA4*@yL9Q2+9iX3yL8FO$mo*M zxwHHHKf(I{Et9bHT4amR-}zdbr-y)-s7}hiu&)v5y;YRvv0_3_oSj?Tn%z9?C@vdv zTT^aD`vuXC;LxA8BT}>`I*`{4ht!J*X)pZUAHgaZYWm$t~*t9>pv>~L0y^H3B zy5oUIlPniKwF&_I87pZ=QvXTz3m#8&CHqq;g;xbvFdVz8g3*R)WaDpI~t}eh0 zu~*lJNQhi*#se-LfdC9TLI7jM!~X!BG+!|T@la1bJ$RIz>($giJe*Bih==#;{qB4hT%MplA*MX!L5y{6$gjBl1g!Xuq{9M7ZxwYJOI=5TAB|6&iTQr z58!Vlm52qNOU7|;XSn<>p<6h1Q8j2L#YH%Fh=&d!H|?e#dSx)pdxf*PnLw2wmrY|A zeB`x+itOZOydExBpyd0nmd<^VI{X9{tGxIU>Zg;pIYq40lfDpaJylQ2`f~3;uV$ zKl6=<|_$Ix6xy{><7&6zDglgZz#07hJLfVcg9mIb}FLH z?ne>l-1HY4uDoK9)h``^^mskw0eaA-8#z&1vxr6^w&XTT_Vs)23Un*CgXW0Y72mqXpfD7&%|Pl^;RpC(Q@tX?}w zY;F=*24nd4m2I3d!~7geo8y#_(xf2D#h9#uwVi1+Q2jF+2{w_}ZF0sEW6TeU3_tysfSE}Ib3tf(J z%OU&2Sab(%RbBoEd2RV;f-~*&8+vfq3 zsc|DTXZm9{4YZc#aBJ?ewpwl9_SjE{_)RGw@d+P)G%%&$wbtGRyhIT8$_7R9o+pr3 zCxw{k7Rp-~?ZR8%5YlFu5dx6f%<$|TmFU){V&`hV#oGGZ*EeB#)VJr~akPV~f<(z> z#VdswBNT2Om6ZjDEI+{9z?E3SihC`yKM*oJlEsZjPITbbgE&P8>&n3<6N8c0KyYay znjNfD*ar$!Q9!EGYsKcP{-K>eK4uFq|7zwZV#(Mz$~il|iUT~GG_O7u=YsccTa#|K9 z(=Oc?5Z_UE0N=NIkEK46)>&%S zkC^`*?Awp5>$2UqFTvRnj%zl9vWacGl6-C3Ix?GHB4-bjdE%;nj53n0e@^B2uKw@) z6hXV#r+4=cuo#5LfsKm?z1kf>kiS^=3f!H2!uA9hwI^Zw4Fv=tD?tdn3U}*Hw&2eqQMyOYcg{6ZCHIZumY2|L8V+ zzXS6`g5J%rE^PV8K+rjv0XXsL^c|;oVMp;shm$E@q1toX;0CUr$eYiH!C~ZdNbwGF zokH`D2oh6`d#aA;VfDb(dJ^u)j_CPfr^bPh#z9c`RN-WDw9_a%2HJli)u(T5_JbaX zD=;~pWKgU%Nd?(q9IVCLf_1vfV~&-?Pt?-h=s_EXz`d*$W@M#?TLGpTK220addp zP~8;(BXJ!NijBc1_0tmX)vCYc1ZTh704WY~-xn(`k0)?7xPSBl1tzJM^HN}bT8X!| zy5YtXE+by*G8N#)?%T5#ZX^QA3nA{N@~*72-3MoX0pBD_*L|*Db;I;k!G-T2*KzNd zcfxE@-V9UIH&djf_P|hWe-6>9Gp?f>igEe0n|&IpNxa8fi^8hvomprbYQ-*MrxR-_ z*jlu3#z;147JAphqG(sDwLZ_C=TEueIO`}tIyrH^r_ojdXKl=+OsIPUg*I^wlQGV^ z;k5dxw5a93luxjs;Ue(l^m{m5bTuo2*!C+)_qRwwaAC6~zYW8wu%tFUmkp=j^uH@5 zEE{4=IB!L18i5rT&dg18a)ImQf8B`+JSeKTe>85VS2|?Vw+snC@}jQMEauSIvwGA*c<9Sw{1N*8JLfMg7@J;xP^aG`7Wxe zOHy+iz~OG|L8<;X_Xt+L-9OZAMQBc-xwLXce`M-8{IlF!zp$xGD*^7KpS!2FjygTo zo7W;k_Ds4w96PJE^6goz%jR?|T2zt2Rnj@#h`rW@OGg_cX>V11*@+m4OVcV#TNgE- z!(N#+E3;(I0s3_s8^Z#mK>*==+fZ7*j4Qcw(#QpdGmku-h)K!s6^CQRD72P^=41sI zevwI$S(_qhgh=PrH%ZHIZdg@BVKPy9Cj+KqaDMI7Z$^K-)DpSkZ?GHp#>&FVNUSV1 z+NZG-by;xXyO|UTb>BdlkAkxmvu4%}#Ju-AAm~Bu0X}b| zM|%FIpu+zVcP*`Hx8R&Cyw)SNsf)bl3mW|KENsfOh_eks7%5+-YsPaJ8tXmtfYGrY zsbOXY;`CxM8R{ov(iV=X-R%L5b}J-#ZM;Qt{}A}m!IpsYR7#dkW*c+@wSw9a=OqNS z?uab7$+R6lJCi3F?Nc#Vu}v7(UXO&kjX*|$thzAEW~REH0V)b1g)b)*CobPO@5n@E z9ygCeZ9|VvPTP|veZv87k1c6+mK?jcOggrn#bpO?junDNoLjd!=?qC z2ym9gcI57(B=VRHv=JDv*3`(JwYDH2De$(kUzAsnLmGLL3k zH9I$&rD=Z=zZKRMt3&n|thFK`=DiWh>zucvByB0xrz6%z%p&0hoy=9~KWk>ZPsKCW zG!m?8J-p&T)`sS@|3VXXO@Bm%<{qT1BE?ku)yJs1V#UTXx(cxfg~`aWKL`AB)pPM1 zkQ-<=tan&n!z^0W(m61hBBugo_K}(&&h^furx~T~ zGToSvs)VQ_9lmS;(?dmED(_2*KpCi+!6?KPr+L2+pmkHUjBu6S&2u8OT^s^{6?(6> z=00+@u6oTPzrL0DM{0NV}nZaxDLCLCCo9y{pV*N;=Yn?lRNGe8IhvR zQ~%7Hj(JNd9&Wlio(W2XZFdw1RGmw5eA(%}b?M&wU$k5Q>YNMe<}dz>u!Crb-faKD zyd`PtZU0SMGq7xc7byzd=`iV~!+~EaI@kpK%qn6p*)a)%qvIoOT0mvMI03)Us+NPM zowXn(>-CJlFBe`PF5xXn0X~*}6RnvT^$WH_PX}1g+gO8}pwhb9QHJ*JX9qN~i4%+7qY1#|`9Io6GsUNh8d9~#ww&!nNS zcTS}`8r)SQX$q-x{I$R*lgE)-#g3*J1Y#nngoU-~aEbt#38~QtAK_F*3Ce!KN5F0V zw%SUec%9Htip_*S0y>J$cSVuRQ_QX$+v{@F*Me689z%x(s_Xd)Zw%C2O_%MaSg<@X z!L!+DE|y)zl+e(^nO8*!;#aUP09B8b(tR&MV1n39zw14V8hD5C zdiTjQ@Wxqf2Dt7Xke$o1f8I-F$R_Of@h00zuGbt?78M;fGtJ&1XW&75m062i$Z1nE zdxDZQ8MJ2)vvQoBM=1?!T?sQGo7>*u-dhTNuSIa7vFe{tI5D7y4r4%1Vq*pPH_V=u zE+Hw}FOmJ~*$%{axe{l4T?$^K>c@8&8I=OE4P3iK-PMY-lEm%Z$WF5!bs8D?G!LmI2qH$du=mbVcq}= z1zVdhB^Ypc=J^g|aVqes88tsY#K(W^&KCcXJS`RosWO8_>t}&dP<=>K8%n*8hCzkD zLt%$cmJ$KeiO`leE2fl|@1pIVZrG)1Uz)$N=T+k!Ku8!E1t$*ABqnmP4(qVB?BAW` z#_{$cuAm$oWCzFJxQMbd)>CGoU*;CSF~t+HkE&1PE!1eAHZq&Tq|87&qnX!RB5%og zB+Y2qkz-(G(Jp+4(vP;N12dbR2gRysor&kHWp5R^6-}ogrU6bXCN-Cbuvl>a?o2n* zlNf0{&$iJ#Qa^>F_Gj4J(R?Bgx5To0QA2b9uao`F?U=r8K13VVS^3VSLs`uB(6L8-3-Lf(F*Oqr;2xH?iN0rm6U`;y$3I>|j%Kdt0`Fp_&3zpUhrZ;cb(AMP9%-ACMZ zxEQdh;CogTd2%~e|RN27A(&x@z{1~IV z_@b|-r2QHzs-roVohK`PSKwdjzU<#*pXQ6#U!Nwuhy|H~Hn# zwqX_2_Gq>JVp7}tsqNRA&k1=;ct1^72_E7M%t2o2U3`mUXLdIqr=WZ65A@fVgB=Nl zm7C!s)WeQ&(VNltn^8V-ICaKTbL)Ww%YsP4pIkGmZ8Hzkj3lvF#!9kYZFUUTZzdzI zcp>LT&P5ZgaX~={cGn$zjb-@CMSXoC_6DiO^`1&TV>UnO#<1koqZ7VBIuSHmJ6ii< zgZ%t!Ic;0f6I2xr>U50BSTp(p!7yH9J~c=KP!ntgSg)IBvGjD-JM?QBQS@G#MXW+j z2WB%T4!5VD_*sj zanOim4;ZTryvmgJ-lOWx$X0TN4BYltRzR;7O{Z>f_TN$nf|!u^y+x7%BI#&fD=CJp zA$54SXqRV&Y0bS*sdv>I2kFCe`0E+%N;rzvA zG~{Fnsa2a(qwg0WxuH7pCp(bz;%b}&5@O_XzeW#o+JWJ5gbF*C+asJn6#qito}* zYhzQCf4?&7|62i0ojJHurFDW(b`<_HDTvw46sU2qO4^oo+V57&? z3l&7N=CHm{uz_J&=5(8KhdB>A4tc6tJP}A(IZTSRd1{a~D~>+^$YVE=*s*W05%m<{ zBeuUa5?PD?9+-tz!2GP3wOT8>c0Hqudx2JQA`N>4>=xqq*KZ!75s8e0BXX$;)aZOv zO8gSI=R?Y(TX!8s5BL?DVj5O9ci8)B-c+f+T1P6cjAqvbsweUz607!su*%$bsK%Z> z^gxwa1JU@Ql}#O#G>+}sR19=bsdzDmOhW?k?3FejF3CP;{APMT6|;r1bDGpF8%<1&yf*b~_54U5Q#EdW( zx{y}c5Boc#>u3S0;%Yj1+E3bgx=lJiF|K+yt_b6b-$Y3@HxK;0b&Na7sx5b`LLP&( zbWpZtx58YJV}Dj#2DrwY&(Ee5fj5@Dt+y+3Dru$OUqzKGxOct>Omq(jtXf+Vhe?Y` zqi0$;&TlnctvYhKMy^3e5CkofVObYub~EBc2fEFc$S!L7fq)Uq-h!-TmZOBw{gi85 zTDd=_Ka!l7ylw(v5o8Pz#^5fL%tmEI8;{b4R^oK~9T1VvwCOC4gLS85mM0+KHDlTLL>;Y9B* zx!&*PdRlzFwwqO`tj2J4k&4^cqHeuD)Cnt=eWl<10<;j#-zDKZKj9G)SRK*6mwPe} zHhhUj_9i_9>sBzd=0hodv|s#2iU;dn@Q1Hxpa3D8Vc4NL*p)C2qKrX3@6*gUy@?*^ zO-j4*lW4`ih4}p+=)}IyJTVJdqbilaDSKr_i(vixcQ|8iIeJ;FFNZL|Gn+zg2cFv zaN{~FXh$?xGk zCP0pFMW(U1a!6AGS1QTT))X;g<)<=l-S#C6Z!l2*b~hr3ok9{enJN0f6Gw87-R2_> zBqb6UwNaN%@>Lq;a7JxciQ^opwuA$tws3YW#$N@tjnX<$ox+#c_#D~BCYX(oX%cVS zLgL>8*IL6__Wo+qTN*g(37=T3xGZq(2`eEefur1`!2EuhzY*(6fptR%8nKSM&21{FM2N3iDl}Z&%Fzli%onlB|B?F3C+p3o0KusfSZ13OS#h22dv-$?AJ-*qUeIY^_%TeqHU(Sz>?cpSg zVC(q4TAnl65E_4&bEtTB4)bYOqo*tT3}}%OIAgO;QQ>gW4(ul|xT>Irsyj(MNAkdN z{6G#F=rHj59vEy>M{5zEPM9$nRPVD#Iw zpU%|*Z6%rC+RAweW`8-)VAQ@{^BB)PAk4cJD;u%Ov_> zYDF5eU{=>$mY;|3as&njvp4px%RnZ4eOMXrHig?Qdx%YW94`uF6wKKW53mps+;Q5NHRg+AW`Htm zjiuA(;1+2(GR>{~OKt*sovho@GINK-1P+L2guUWoeJRm;l%aKuos(Lyymc)y)=^qA z#4e%{*_}>4JsnyI@2~rf#(5l#G${^LRm-kGjT}~I?~s9a*3}i~S2d?sgsPf{R~$FH zS*PuaY~BOCg8JuBUu}A{*?c_-L;QsAD?z7}1N?+5lyD{q-TZ_JN+>4ba6jQRB^*Dy z`6x(a#m%#uHI|C+@?7a?tBNYvMD){G_9(w}KS~qI2H>S<1Jt=_(StJj$QXf>{sbK35d4^?xG$+yb5 z73S=L8lUZzotfzPtHWV$C3oL{@gN0#KC?hV*<8wT2O5dU+v9p{uPCC;pC#Ei1(~$^ z`}?!nL#tni${EUXmNhs7pjBo~r}p#g+vMgM=AJO~6=}O-fW9WH^e0BR%F500CwG0; z5tjNv4)!*~eWxemM-J;^4*9#Cdf2_R6||2iggoBC*if`K+B3pE`_|`p7`RtTbSs|2 zc*+y&t#UZR$yQ(zJFQc&=($-JC3Li#*mbSh+jb5@4@G>EawL?|og``~lJG{Ce7w@a zX=}J2(uoaJZ>uaOZ`=BV8{}rpx+792ZWY+yLc&DKzNfg)TyZ!|5B9wm*^4X;`hIF* zP=Ktog}BeC@x9I7Hfcyt57wOunPHd*7l;}xGga1rqGNZUdJX`@b5<~gh^(((UXdMm zcDcET%{3>DJMgK2`Q59zE@?4Y@oWzb){Sw^tsHDE6=sNS&WIS}Aaa(=`~#T_va~wO z4ia)`M^zjau7wq@4cAWM9^Tk2^N9HjzEIJ{(y``Xu(J2CNH@HBIXzY!6UmGF?*h(| z!+J>cZEXN_Tc9s^g)b^OxFJ}zOiv#{e7f1hwc(+?c%+@Cf`PjlLU}x>opf(wZ-e9h zNwEMsV2eY0j>9=REumA$0q3m%Gst{?6r2;Pw!*AYIUZ2io8eOa!B_eBxn2(Kn$ZhR;KJl+f5CJbL*F)CO$!1XnhzRZIV;J8lyeEJ<>OOI*TX8r?BN-+lwW#~2WSZwOW)Z0aur*W=jiXV>Kg`vSQeQ{e+O0zV zB9}PP4hWsJO&snLN87|T<`NPehlA!!mb8icj63IQ8~h8dTqV{@U;YQ|2P-CIZ%W{< zwgf)ym|66Nqx&FWpJLv&EP1rdEA=XjB+vmivcGavddWwL_F~y@9qaFfp8wd1(S4a)k-QyPL_qGC|?ZNn_XUN$NX30N_&rP<^j*a)4(fj3u9!$18{KaL* z?0GXTUwF8hTabg|Xg*JB5KLK{v*k`gpprp>tN7E8Y?N2vkdhq=Af0ja`)1e8ccT z(WxPC$5UvtQko|XKPu?036!kxHZ)&2d_;7@Q%oK}*e*KRE{tk6pF-CIUAmpDc^^M) z-t-N7yal$}+`@$}*GF^q@FSx4JcV~I@zsVOQK$9-AxO+=srbqPi5gv4=h^c>jgF5r zX?{*q{#5!WroyvhiU73QJn*)iMokr^!yXEg?5TOeDNA*$#Miwuq;$T}rdq0dwM$J< z-BKI~?7<{Kb&sd8#yv_UW7&PVGpD{TXVnq#Mpf-dj~=L@wOXBDe3tj)ZKroPa>7L| z6$kHTp3xJZXoal^AzA;LfDYh|*wx>$XpDrx0pv6~J0V&3nL6?9Lz zm%lIg>ocT#N`$|U`JTKt{x5tNKif^;T?|yr=T-VxK!x|0e0I2Ni53K#YCS zV|%!9iH!B}{n@&txNykP(QPGz-wQsOYOd2+*?N=Irom4F)z`5_+SU%9u*QtT4B|W` zbO!gntopJw+AG}HsAj=h#Nm?>hmnPg7R{QN5QX0n4U@W~HT#24tUMgD@^B<~FaoiC zT4Rk%KSsp{w@Jj0P_s4rk2W(4*ob(NL`zwv&EHfy6yjcS~6c|iPtVO2OgtO%dxL^=QA6r zKv|c({#k4DK_yQ8AacXLC_Kt-lbi6`4|$szN0#rw0oYcX?~$zj28pQVJD8d-DLyQ3 ze}av!VpsHaN6fhn@j>|gI5ufR+^r3O>n9({y1~R8e)Wcxfa{$E{LKGIba(M$o_yco zYZdWi3II#nP+k5{lk(rn{ zzwN!Y@ozw7-#-79r2J!$U)$$DnUsHc2jlx`QvTZ4_UwOJQvQez#y37Ge`p8eJ1HrD zE+)eEZCbYG41!r2N;AquS^HG%5e0-RfI;-an>Z z=a+I3M^5&S>>QLThjWLWh`#5whSS!gA)R_e;Mug{M^p^*mN_Y8oZV=0(Ipp%WX`8ZK(A_)rDh@w-vN*FSa$jLUm3Ax=P%p+g*hI4*q4r?-qE7m?o$ zqr?p(Coq2$?0ykPhm8z_elA#4c~dGRg=BAi1?P#^D*mRUOMdbk)9f5?Vva4?n5NQ0 z2;t$`F3A&p*OIl0Tx6hd>l%t(|E6U5{CGFv*lA335fi0=GUOj<2hg@8U+Y_>97F1P ztz*(QloYJv+WgGpxe=R&i(F< zTuR=n!6OdeC~{6Rd`Gsy_t*q{-**J@fDYiBm}eZ&(N1xg>~p@3K5g4*d&gb)5DClp z721!UzyB5-Kt!!mzhtCNYO&pUG|5T#mwuZ>IVfn2mF*0Am>0L3Z37ex!#Y!S$G#Ny zwlz5~rzxp{XNyxMEbA;7$Lvp`W*h?#jmHZNJbMPHwbbF;OExpw9C$Y15*EAC{Vz-S zHwK;^E6LMkKa?mx8pgiDCC+noa{T)~m?y>uo=wUZJw>?x8wd?xDh2|PytjgN=UN^) zI@M&zXl$J*qC-(1j-!Cgq2tMqmCcANT6aJd-IgrVF?52Cp%VeEdn{m)b@H`3#U;7@ zkP?@K<_yoXPjs#}x8egDtox4bFZ;6r;>oMz%=Q7}dJWx3V~`{ALrH7$ul)KPR?g)A z@Sh#;V#xf7t!ZVpS4|5n!iw}O%yqaz`|tN2T`&1Yu*u;QPz_=(7C!h}y#`gb2wNDu zgqJta;^B_HMv6S_vRvHJ+h~*QtESjZ%rv|@bUr(mEyx24vOaZ&_7rRid(*Qb-o(t< zImbw{yY={%*lFgPrf*&3Y^uG*d+{YY;T+A{)r-PY_^Hx9xV1S<@#F2#j~f$Ga?TrP!` zjJIA<)`d{ze1cFTXg!WFJI(wZ^eXr4AK5B1b@0E15)to)tfm^$7zjfOk(A&U$>SN^ z(Rfa0Jlx!Ip40xAY9<5CrqztWwYW7$E=E=!NpA1kw3iW|pZ^B?7<3AP>d~|?)c5YG zK2*)kN;LNen)CTP7c3L-3eBm!;eA+g+%b%8%|27EJK7V{t z{-Nvl%s(k9KNT}&Tm9m3oQ}N!vLX5<1o{s0 zl>Hf~zFo2^dWd{;qGn_D8-eN@ZR)auP3Cle1oE_==Mb0B_1Ru|8YNdJsk&m)(Atg!v;IxrW?5u^uLfu-UL*n$S-FR+! zEqOdG8c)p>ksLXF+g4AYRZG8iYftph(l6KEeUvsabpN7X`P8p^+O18X`UtglbG)_9 z2Pf!Pa(hm>8>e66MZZ>2vS4}Ae3I#1GX2WcW7ZkJQp3BEuV3#@zE-y`G2aIhicDbc zx0Qu(QYZ?hvGZ^l>`9a>2!=d^?8C{S446LFtmR&9erWv{5Ox-u6NFAh8v}E%LSbta zOcHD+=r;C5U+l53OgJQu(2dNdLVUZR+99HX?2w-ygv-3xRwx!6Vh%vN(|ksIM7V)6 zZHTZLgNJ*KsMvBr;Q<9`>-T(EZDqt;;^^k*kZKV0W9vVG6UJJz@MGkv_%1!tjp4xE z+P|Ilak|W7&DsdT|4+a9@)P$*je&q?wPUOg!qtP|}NQ7krZBgnIs;l@$279shKqnFjD z3!0wVG-z4(y2DAvQ(`Q)J*#fYOo6FMitEmC=H5TDDNjkcWst`cA!c07Z#v@UTXoW@S_pLPrLw7 z3Kv6rU@paG#U}}X9?7&m=;Hv2n@LK&3{(!F*O-@VIcaPx;b6?!B}A zZd5!cWqs~GF+DBeXCJLMFK~T_3!K)w8s$_9F3oeU=hM1GUTMET2EW4>PMjD4-+An_ z*30IF%hR~EJ*_3^&8@k!tb0mn+N##K37UZt{H8J)to!mxAY_DV)Z>8qYWds+s`sOn zf`*}80{_v#BN%DT3nJbq-eHFifH+(&Mww1rDzAl*W&hE%kkpVjD%X37rwBg4cO!2J z4|CHw~m%<0x)a!TZxBuQl~1h0=%ca9gm*P(2hl zV~M$rsxD$*|D$d?B$T!-lGd8Hx$34vQlgz3(=;8RShF6&T+jV5hPv9^)KffpwW)_3 zUaVwdr> zt5N7`6t~s*r7~)7n&67v<%*$xaxPd+)k?rXc5_t`?}pJ?VI+3F-Sg12(G#T1Y}@nE zHVnTJgG6%}Kc}Ic+5c4y8MSFuMH$h4(12nWw8p0a6ET~!E&Ep$b&lf0y{5!l%;P1J zb{94vF?6BxsBwFxSbGKf!bSf$Rkto(!3(h+_XlA2p4C0&&-|_C?*sl)NZU{8{H53j zu>L3flggW18J!cz`#P0kToXs|inD@s(}X9n z>_3u2eC%JC_r$UN$L)&Yem^5a@}rJrv9jyp!o&tdykOmAS2;=<* zCA@6gI4Vno8l0&emBU%8Hmz|~u03Nv4!5&L37xPW=SVIpX{BwNz_QJCG z{Ou*dKQapQ^y>K31J(E2VHL9nC!->S9T(~xSS+sCOFM*NMPj26$j60S*Rp^1nqyyl zn3^R~>PPD29wrv7`>~pjWuH&FK=VTq^%mh8vjFhBZ%@N5ZS*3$g|$7{`x=aufh-BO zU+pROD_Fn&F~E}P?cqJ8UE1e4)3 z8Y{cZJn*#6Y%{Z*<-9iFtn#&%^Z0nPw?2~F|72-={JXV3$&CEw?K|7RPhHEpoS0+V zjv%WHij`f&1k8I+(Jcz)4sB$v{`kGrzeM#P+*f_r$*+4Rg(?+p_O&m#okMJr9AVcN zOYF40@0al^?ig>Qi=R-_I;)S5MJ|F0zJkGv6c_>Pgd%~KpMQ2Z?fkH`91~2n4M&2` z6i?_E&FKMO!Wuu%ySOaxt=fyrYF?XpRO-yLrPC!6D4ZkV>v6R)-&#P<-jFvw zUm=~7mwZZki)$|&n_6Z)@|nS_gon~8l>Ko!=La4-dk!iI0SUy)*wCxYV7z8HbJVpICLf9)Af} z&C~@kT_DyPPGQM5LybS{CXL0@xs}w`ixE-r2u@dxx|V`p(J$?-OWf%Rx3P#akVJxM z^2HiAmzf&SKJKU~`3oh`c~(897v;v%nOO!SBeeh)2V#)AoP0AEFADs+#bENa67JF& z&$lh;Ml1e3wR8JI714RheFiOOg_hT^C0)p>^DVf$mi)N( z=L_=*2QDaWvRUAVeI2Beo311g@#FXnBgye- z2%vCkqP9!CzjyJYL^R0Zew)14m*fR}B20Y+4NSD~4FQup{~XO@=U@E!w?Owb|KZGE z4k|-X=?r2P6|C@n%*|wj+QJ{5H9Gr;0)O`$>3JnP6D+@fn6bquk*0Zz)#^}2wr0%9lzIQrh zWe@A3wfu`BJ=uEb0t4%0E6pY>NA z*0u#dQZ4)$rQT4f&`w3)A7A+F&LVF}kfskJ2>u1J>`pf6+Cjm(2WW}6k7|z-V7DPf z@X&o&k0?{#Mak2JR#2f>XEb5{*S~L|cp>tDcUrcw&)8vew6?ylpP0=%Kf~R)v$oPC zj*G&8NobAcpmuZ?or(%k;fKYgq?RD)PD8ZNEI^lKreMRZU&9=<(l_zR!jH+o+%sAM zq1Kx)4jq9v{*gsc=; zfZl|DSQAZJ0~r?fPSyerW&!(}xeF;*du?BPgkED#pgrcU`wlrr(Hh6DV4XNl(;NI_ zURG&$32-%VC`or4K$_fo>37{Jt+OdWHS8OPPs7t>P91qdp8W-VtpYF(w!T15=ZEzu z*3e1C71ze|SecI*wbO-E+^CuNth2L05ovP&@ELE_zgO`cF_;X-gVwFo+i8wRSinsm zrdo{Zzi3eubaG4JL;vKkw^{QZX5Pn(thq2@p*Wer5m1HsMAI-*XdY%N?g^@w5gvLn zFEP{A&*1>39E_1vIVFs?+LtI3>;82&-G5_w?RN;FRRt&FMfOExwLA{tt=m2wyQsbCY z$jEocoQZTGZeSsl#1ed`wtoj2w5@miIG3j#rCWNbEV3SrWxe5wpJ;dH1HH+A6;uR0 zocxo;5)o&C5h7J+qEDz)i+)qE8!xDu>ff@tdYYU05b)4&boT3W5Tj09IQd#c-nait z;`IFk?)f5FBjD?Qlkyj$O>Kj$FF(Z37jY(M^;L(vT7FC)?+Z!u>$K+&a%Qe~IM(}+ zkeTbc)_#^1Sekba_!*~pr{Hk_%D!e%mcS$&+lsbS^wS%=gz(;Ow?+55T(S`p-f6x` z$!Agsie53Ms->dh*b$=Q72WGbxiS-*$8$$`kPS=ovgr%m6Oga38$ovSiAh;==vi44 z>P}D=Z(9?{hPSQF?N<6kh#<45?iezIbv^l)Y5ZnaKl`{wy{6!7W-~=}+2GK;{+j;^ z^DA@)i0a*y3jgYFjb&CuZLd~^2zIELXj_8+(zkuB-*>dH^ETo=J7rDPP#(#&v6;MA zVJ$;%%&b6}@IsilbGM7f?{OD|vI--r4x3Owyx(%uPA==pJX!}GDTzI6wS!{l1-6NSN zJo7zhR1pKj%C^dD2}HI;%9omn+xs#F4V|r3q>6ycNjY$~s?1M=G4WPN-Kq-N~u5?GgwkOEq{_*Fy5uztC zB}n2`EveCfH#&Xx+bK|%s^y((N9&QmJ?~FzzI_F+9INTr!;{jUxmq5#(;wrR#*yi= zVsi6}Jy6WIl;G2JkOEH_Qi_8dPELg--a=h5J#@uq+!_lOEe_1xLJ{Ae&s#LIa>k(6 zZqdNVrJ+HsDOJt9%(s^OaQULx=vJHAGn(Zxy$uSs_eXLuF^9{Wai$3!+dBNhIUqwY zaOYBm+edMDOp^c1$iTBbj<3&RNahvHWQYJg>@x)6qAzE>+uX@}lYT}nO&^q^JC<|x zR%faAc?nYGp~1?VQ}UTrp=K4`kDsae(JrO2Xs4>?PQko4w=PNz)X1^YTlBNM=U!+D zm#^2e1Vc`Z=k4U0J0sBP)rz&D^fd{V<#RHFF-OmSEi!3NWkY(TSq|$!J`n=(o&q6iwvocn&xU z68ZUNKigEyHpR4|nc3u;zrv3tF5R1ZpR)XbMoy_LwbESceCZ#Efpw_%@Nn%Fna!&b zeO>PQYHW!QJI_2|Z6lM&X#UZj+x>rCirug0aE-+2<}VhFg9W~3&$~^8QK?xM&5~z} zG~aA^f|_5nXxqqikpYSQ#TAFxOOn7mb#p&3qtQIQ4Gz#4s8P7;pw}6Rp#V9BFeIxe zwDDsW=I4~K@qhn7k+c>u1$$^u?qg_nv99^P{XXOY?iUw+k)ihn`=_nF z>iHv!Hbf6eTn;^ao826y*tHxzFO9cp&dv1my`HNo27=}3gTo6=x;*^Y@nQQL>L0G! z7*HAmB)Qb=#BY$%MYGddxPsEUG+1<4U~UBrsA(MkSXR{ZFM2K8>FfKpt;cGeFZNgu zrxE%`>v7#Cw;snZpS`X}8HG$YH{(FfKW#nk_}s0>W1l-%wqK7C*MIf(nC!Rl-?tw7 z;Ah2Puo*k~#>R?&<+M8fMJ8|B!oP-)Td*lM4ZY%j(($i85BvOUweBnuR9^gRSGar){OjGp-M!R4}rQT;r{OItHG`7H;-%>9yKOk=Oc6zsEa{`tdy`IdCHqTh$bED6B+nn-o zFM4|iXKrpKNoEUn6{%MW9mr#Mi5ZESiy77M2?y!Nz+>dGxmlpAPnq@1`g5@z=ANe|XtPa$&(vJZ0HS&6C_ zyQ*HI>e1$8+r=eh09dMDOP=ZMD&ods&%Vx=KU7;_`B$X&Cg|6_&O^LvadGnf?*DZ> zDS5!fZM5(?@K>~uh5b}-yTF&Gs-a>Q#K3CShBFp*x7DwV%ZRwcAU3tw{CvmlY8+($tGZQR_cUF`1 z5Xmt5uY51|HQkr~$^sXE(k$8Ik#jGIc$E!+%ev|U<@}3FTQ`QQriW810J4QNN_I05 zt+bw~YEd2HA)usKW(G-bZdIs%`I){^(8&uCctvP|F9cE>~hoW8);ZI0*kCk@GTX-Lj>8j`{F5BdW+(hX!x(m>M8d`>?8 z(NptfG}vA^i+zUjR@6<-CGm`=!LKNBh4~4pjy*E_+Qb!RnT}QMYt~@o`KD{=^i>aY z5M*nB?uRe|20EzeAnbr0G|G8zJ0e&DsILCy@%lYqC)3t{h9&HvzAJxHynOcXcz?e^ z72ZL4`s+uLcKvPpr9a-DJLCP0*;jv!t~{7BJYL=`?yx^MzMm$_-y1Jqx3BV-$IEBD zjyz=N|5x-L9n8m{f1-S1JP+=xd>2=qXWyeJ%kl7vg};Sb(0uR{;6R`huqel!Ls+^5 ztUBm^rR)F62jc6UfZx#_BN6c500_dSW*6^`}1 zMM%y(@+pCc(S&9X*WrTK%(4ZVu1ILZN2ngl9%O&6F+Y7ntx0uuFG^82?TMQ9BynCWUxcG)uQ_4mLMUrEv!1t-Qn+zC z_GL5RJ;5&8Q{yfgd zWO%aE^t2%mUNURm>zmRXAZ||$R2#wbHeJ68djYF^d(n)77)cq3PEGRH_>cObI5A!1 zb{Zd&Y<*1|btNj6eG>W7$NdUhA66ffRr~!|@+VUd#V|@LwAM;<2gY0}YnD)nCxDwa z@!0`}{%e!`{r?}#ByS_DI-}XAcXzWy9dzyQ|9JU~NWAQCa?6AHY-^20p*~e%pEdSeUe_bikuD{FU^?N49`^@}~ z`;$7)oaD-bnuEX_tGvu1J;jv0$-t}j;#;Zd>pjD^OEXd=;nC!1M+Y0!s%%dGv*) zIb3b-fhnk1XNr}2<2k}$8et1_FXsTw8=9mw(lw5K^tUc9SCWLk-;GqldXDH^F+eIR9+7kPI1vqzV0?wb@MLBBp z2K7HNjw;NPQ4I!Q9|w}UHCPwqUpC(nnw^#c7q1py=2*V?!hgSe%+-$6O=Un>&$QT@L zygTjdDFhOf5pI$`&d#0UZ3{ty%S4AK$}7RLj3IX2PaD;=8O@|b;;<#vGjfZq1F!T= z)Xm4Ek(LJeRNM@L?;s6XLOqNYf_3lmZ_{tp2B!EI?4ASk*Qoqgn?ogK%a3mbo_%4n#-ELRQkzO&|UiCTB z@3@P{p1Z9;y`8*Py&1a+cZpCS+D&JgyK^L2tW8&IInJ)kVeKPCdHJr4ES8xB zstagC_unVfNuI^Ak=aOh90;{=z1}?bq@6}}4~pTd7R8;jyLGTDC2aFbH^u$!FwT~T z=;%!I(XFn=tF}4oAU8V8yzHkg_EQnQNB1=ieyZX`jX^pdV4ixLq2ZTpLG@FTt%+}$ znGXLG2^0G==Yh@6hrD9if>rQZ(|-=Gbg@%2<=Lw)TQb=}3hEoC|nL5iM1cK_3Fq*M(32b>AyIQ9Jm`I1-w`KqD$ zdc${1zIMrHfiMK`x;_K+sl&m_ch$qmqI$PdG{J_$s{8>djtw`cHpR1TXKTz|s>U+^ z{Wp&K&2^g(7W`)|?UYlWt12b;o6@>_l_9EgPtQgDhIgQtAYArk~pAQu`{k%oO>l z(muil-7O zXGnT98**7}o41YWXU9!l>zXWb+d(IsXNOXx-TAUhynfF^;`J};nEyL@;T7Su zm0v!3)9WRsz4sZ;22cR#h~a_DbUt_^&~U zIOB47p9#CNf;PuN)G*u7pO~GGIbIa z4xPTlnzGCQn_BUGrA)WX>HwEANot%!&HfS~9HXi@C+ys%UWBKxMNTz!?6-u3Y#G$d z*|42t3Hi=9ARVJ%TVha>kgG@#gL>zA)lHU=eHL>BkZ5Bu_xzq>vFtH^tw(LGHRcKg zd#C6slcH;a6kQXg=+bQq7h>VU1a5S&Jpc40hflZ6Wwbc)ZSREs8AF*D=0u`5GRkqu zWnHcT8NZJH`6SmK0Qg7%kiO+N9IZPTz4SX2NzB=eXPalo0||dLUVjY6nhxr_`+$wE zyrqU!3;RN>I9ja+)XOEP+_jKLO!uO6X?NZfWz2~?yIkjwf`uaZ<#y+zF1VnoE#bOP zR-~3|G`v3$_QqtHWh||ALFRia$9!Cr<;}{8tHd3=xEGl4B`WkiTA=Za>}z-^V}R?M z02c7@$8YbC<*-A{)5vTrB}!`dZfyy-#kjB7HR!E1p8^ulxvw;jW%h0?H@lIc`f##@ zweIgQ6Q+>3Ev4->K^$;DX+OYJw%(~AgDev9*(3^gusnMtx%KVi1_`rR`I?U(g@|=~ zlwRr6*AEc;ExpUQH(vg1PPrYFZ?~S~o!ipGu0BukaT%P~Sm?O)PIL z@%zLU6~8U=N$e3d6XeFS?$mCmU@K{eFGlj#GG4#?tlh^q)QxYE-YM#Ee2gtVzQ^KN z%RahqUL8ld*5jMH|Y~YvdCV{5~8tUMT*AH}^Cf^`3J$cIcCL==irISXW5{kwD3I zB0yTiS}fcnXpueSt~MjsDYV6dwR(j0qzw)eU*Whb)@cyMoXbZHcezsUg2GboDn!9| z-3dh31aZ(9Z;iE!tnsWT zzq!ixRUG)wCEk+epGImQ%+-)hwQJOweSTK;PM5UjXr-Q37Ph3dHiYly*cK+V=R6g@ z7{g2rYiE8n(`MoRI{BZB#A zGnmVM!NSS8sW+#$HZ-S|wl0?7t~i;2>X-^XTRX@7$J4H3=k-%?K^;|feq9>g_HKCL zhiT!fo)3g^8az(8a{$BWN;&m-8bkrtkM9Lz=cK#EQR=On;aP<>=I7a5*D>BVTS6(vR{5FzJ#mH_iwW(Fw$SbTN5vWz8`aa7^MB02Dc+bSCXYW z@pn!!)~}d&G0ku78$w?%SMcmBlTqSw-BUlXFtia2bU$+{^Dqly+TWS|8?jhbe+ z*}JTI5vWW(o<@o0K2|sVGP>z>vjY%muRbNp=%q!l=9YM=h$j^Xj6uevUa{YJ58F7p zs-X;r{B8{4Q-~fax`-#XdXiu8U5S~5P{Y5de2`35=*zEG;M0lT-+6BRvbp_I>W1F- zZsE4(gOea?%jV|5M9NaoujSwU?oGhnwBfB zOjr@8Al6DZFhT1iejx*5F(R%gb75!>hOcm-WP?)CHLOsajWVT9AR3m={W5Nv4ZRg6 zYZgK#?oKPrUvJhCrx~jk|8v~ef&NjMBxWzxK#17+buiqg7goNtjP>Qz1s9=(9Q#GqNHD)#<)lS z6$VPXsJVhLsuqp*iJF5MQZb(bANuxB-=70<6;7pPszkNQdcqvgI1s~DSO z4iiP)wkvk}L*`Ha$%tq_jh9SdM>5n#VsmX9sGxG3lSJ%JJ6utpLi6s8fZFxuF$}*y zFeN|2VWUuu{jhcvx5=Ih5@>OBW(f0GsCIOZ+EKlirloFuZg!xi9JEVYShO^7+j)FT z4DSjzyrviI@Cr1%-VCpxfw47TOHYq54~|29f<+6XvqD3wt->i9jgNopbEy?r8CC`J zo=;mXH9}@!{&Tshb4q}zLn$c(GAiH6nUf`>LRzpkAai$G$sBvsOAGP4ws)@E`f!0M zI^$2*OV^e33{E*$7DX*uRQYsn9f>JCD5_o54E1zSOibryH=Tprbc!{d64dPMtzUix z#QZlEk>Mvx*F&_;%qcT`{MeB{PeZ;P~*XaRkAI+_#O=&U-RPa4Tw4SUdCuR`AKRFfFJmO>#m#4`K& zv_-vA?^FEMr}hd~4oiu44_1CZH6>83=rz)1hBTrwVW#dv<%Ge``>0#W@r2wmGjiHz ztvq`&$KC_0X`Oyxs0bBopk|CZEc#w3QMuwdP24Wma(h8~y5>9_FB0n#SvU<@kgwGCdml+A)S9#iXRY=!TQ` zY1%G=Uf;ffei)>`B#52b93|D?MEqACkzkPspIBxi8=?kI!7kzTwukMRN4qlP>qMl2b(d)vllVtM4nz2>E&7m2qgbM=9o2SXG zHShl1?yxKg;u=__c7MB_6^MG0SU!7N0Z~D`O0q?MA5$?@coUPb_}{eq{`K96<>%N< zo^(}{+v1aRo9c8>F_GzZ%X>Fp&c&9cC5`xFY>d?2{1&HuK0e^Fi`ttvhiY%uMLRijQbefy%I|vH|hz ztCvYPP+1ioK>Qx|bgY?uIrAC|z9{o*$h$o@0Tn5-Ar@JaxD&`wyykfs-0)uzH^B*b zUes)`-??6v|G^in<<^Aft;ibYIxD!r7`%*$Ek_y9|GA5`y`M}j_tm-2(?K)%c&`3T{O0S#hkI}vYh$6aiug|%KF-VNA_K1CJHoE zr3uue33P{o69S>d0|$X7u)ABozLA*iDPM4VG{xTSV@l)VwvwQ=E#M1YeJycf@V%@u zWAlWF;gf`b$4L-mG!fIgApjvo6G0=%F=G=p#A;p)#3rl>#A=>T+@h(-i>Bi9X)6Be zI@$%K)f}(@wrZX?tqH398X@R&gWHtqK+$Q{!PwEfAaatoMd&#wO#_FXPpoihP+`CI zf9Roxs)X!n3C)7_&2vspXK;uXO=tMp{u3D#f5;6bl2f!MTv2Bq60G{fw@@~dgH<2E zq&&F91)HpJFKf-rOvl#Q*1p1YeZ5WSW`nP11$>2pkWZ5gY zw^e4iPlXy&FM3M=7AmK-Uxw!Bnn#OV7m^h ztLvkCB`hjB-*ntdt4<=?RYkKl7C-+(0U{w}CC&K7`SBp}@sIM|dI-FTQSp!CNWKSc zyx#Nlp9`?c-&S`&zt!I5sVzaVCrgnm;$OWHI2oksZWPu!y-{ByEER9g*PN_WA^26a zp(%Sd0^!F5yNZU&5IzG2XGGU7={Uu;#GXTQ62Aj2v(3xDp5#3^NM&W@3hG>kWaRp_ zJyLRA4ZLqrcFdc&1fi0N_koz86C=BPY(k+|jX70nW3$=F86dK~U}?7@1Jdwe4S%JA{{;8~`~L`h zGw`NW!A40pUbESgUXHViLI7-;#59fU~OIfRGk)`iFNo!XxzyVP!V zt^IXzNC4i8;WH#bP1o2n(Ts5d!%$D&n%F!~qMd1f+P@WeKKxUGr;^|A@wb@gEBTY} zp1iy~B8qzmDV~>?ohPrfr{ll8&Q}-ykCZsr-&h>i(rEkWtD&h_;5efD2|;#c(kV9M zn4TSDkQkj<0_*D*O_2fqXJuq8T<^PG+;C+-QkJy`W6O#3lZ!hJwTvaC_tn8k?^m*NoWp>Dna5Pej!;XZi?=3GR=IXJve~+;j<%+ri>cq}?jz|M z!{UyT;%~q>XOCr!CN@HN=>UoCU^G4|wf%xmk`F7dWMBvJ72l#D#^N;%uvCDu1_fmP zqFnp6PY8T*r*s~bYM(giIHU1>DXCVKbkXb@>oitIc-X!c9^|jA2!GF6Kxwr<7JNxo zP}SaLu?c=N7PMnElag~;&=7KkomG}klh7z%LVL6A2QQNajUUC|s=+hiwQvo}|4V8S zWvfNhS!xmG+6$G^f1Dv&|I+zKry0}H`k#HqWy}gYflos6Wat_j^La{C{;D*z!^U@{ zp})4D0$S;q{)P&no;dVrwoY8g++4pte7Mlxx9|Z*umFe>XEa(ulqvwkZd{1n*s$(g zP z0e++2Gg9Z4CN@x4N9T!Oq|WJ~zDi?nm%&ha`68<~d;KCkLtX=B z(r>%?h=Jnt#6lj}F?d{IwA#LJ3X7xJd=sD|hymwZ`;@TLUCjN@*}o9y2iWtn#0j|? z=rDkc#-EZUIh?lZYjXc(vI;WltAB+-ok{0hP3MKr@?ENUQsuss+^SY;%hI*k<5ohz0P8Pb8+WsK6`q}YVD2{Df_YA3m)b}jwo zSEKf0`a57<=9g(RdJni|!AV&GZ)wuhB4R#zlv`RFMQ1&JSQh4x8`BeE^+PowXPRnBwWbNX=GI95BMNSKBel^*vcp z(z$FgV0|njliSvVJG~x6diX>+_@Rep`-KoL7NjRBLmg#hIEzuxn$Rvoeda|7?6E~g zYN-s!KviPyQ>MEAC%B!d@%EQMHY1*zv!N;{V%ONelA@i15QivK)#nqXbZQK7>S^J- zzWSe0M2+<^$M~}6V)8#znf&LA$^UUu2F(f$pHCG&!VKc>f_-*yo;&86V9 zU1ZE{Ly;YI^ZcH0e}&U{h11za9XLfsR}(X>Zr&tMq*lVfoh2Q5m+CgL=p>Hh@+b}A zXTwkuMbH|Jzmddj5_P4?XC&zkl_WY-V(VX1DUq7zAndm9K~MZ>g`PDRbkK7p8FqNG z!q+=pw&?~*Q^L6gu5UB>;{W-rHSGEenzroFLp_@_9SBeVkvF}w) zkCaOO?L4c7(13M+b{nwB33;KN8U}BV_dU~J|55lP{Qu`3E}kkS%2VY4@l>gf1+_nE zqL5jwv7G{qMwxPwK9-tW8nc8q)g5c99*`=fuFG^?iS?*W4%&jQSU)x6Vk;Lv9U+OD zZr|l0(F}Cw;q*W5O-7t!PdHcZk&vC#O^w1hcDBsUA}KiBzENHEvm#OimpKOrx%1%y zc0{c#cZ)4#9T#$L`UzO=#)7TQloE<&xMzk z<#`fc3EuIVcVJ|Ahh3fc1lbhYX*W(l^j!3oMfqy8huVVdTU{tk7h6bv3%V@>HhjctW5E*X_-eh>WqvXu8EI}n!vrTOC)9hbdA;*#P61UTo zx_Q@ndS>_>m zS_O0Hma^A;D2t@x z&VDZ`E!Dw?=23k@)*vhq^pbMq&e{6$f_C>1V zpDIVkO0e~p(8TEGn7A5QuVy@Y@AMY!nW% zZym4DCI6trnoBbeR_XN1GtwDY+EJP@e=)O zDtx>Qu4{Q|5|rq^=N|6Z)jZGsUD&lI-cPdeq>M{t!&dfF*;2bvN)v%ErS*~0ZsaBT zXYnNMr)@Bt$-~l`XQW<1aI#IKT$Inn;D|Y z>^jx)g+=x+Wp&&4X7~wfKH|G+(`I&FIq7l-q== zi;L#|L?YS`VSB2Q(0-7#oE`LM(Q;@PZDCTllYDA+uy_!kXK6uz3ovkXx>TF)A7$7{ zn*zhGEt-Ep`g~HS_Qb0N2CFQVm+w=O)1D(}k8X=zz{wRNs_(b;mJVHtpTW{V)wM-) z9~a!1=p%6Y8v980f`!tKd0#V~@P!n=SuB5`pV-6$=k%_4zQFUqsshhz{9efKeE#A* z|BT;`(ft44lOzAoaS->gtP-IcydIY*I(?u{H=gw5t06Wh@k9qmC!(pXMxE)?vsIxS zg)9+gO0gR>hl@;$3!QoB#g)y7>sEX@vZ~|b(8bZ7*-_4oo}R^lb*r~bIhPL4jpSSG z*~Idb2Src+GO}N_m2KsR;Sa7UwYI=>IE49%-!u4qoZs7=XOF%{9p{HUFFp_6%>VMdox1y<{?aku zsxX7;Q)3H5irEaykAE$(9hM`zX4DXXhtni+9_7T?7UI_17l>fkh-i=-XScJ9lyyTv zwEZiVk@0J?xMlGp1bHL}wPj}XuU|*FLe&& z{j1o@tp2J(EE^IO^FuLtBcwQTzsA0r<5$T%Zd5U|dQpx<ultb7%DzX8M(6%VbQ#7y6ssnD6bA@!)u@-1iy1wgHK4>zl9M#0%90j{ zn;2{G6PI~LwvVT_%dsi(p%UkD5SBP6v{S5j(~U;IloK!h;cqxiSB_etLn=jvpmUtf zH_;pnK;pGGxC-MjS21)siYm4z3{x4U>ghoWo)p3vfX#myS?sEdg|8fB@H~uFB$qi; zqDq&fV!_kFY@bk3$u||_a)S1X>B}4q38PP!-A`i}s)_2USU*1C;HR(tP!tXO5WGL+ zHjvv2c~j(hT3OocEE4qHsb~IL+@NGT#Ekc?He0rM?XPis4(R|=+#HMJaPh$kNH(?Y zEhNhFj-zhPk>iX;*?<9J=daXN1@=?pMDY%>YP$!NXn(D7kqScN9(9(0=5&*`8V0O) zq^xrLI@q%&KC6iJ`4w_9~818nsD$Z_0)Im73%@ZEdG#)Xu5> z8+LSKquR~*4JFD)hwP-=Mrw&&NFCh%Gxt$<4Jk#pTS5pfTPS>iy=J4aL{+>dRs80; zgP>?osHRY~lJ+WKT~{&?J-s?UD?ekuC^VG_UFR|E*%`A}#93)76O- z%^jwfXk|ik`wVpmbq$zEybLf|q1RI#UA<4Z{hwcmQUl~Gy8}@V>-Tyb4VPb`ZKVE3v@VJER8Y(cC?m+ON{6)j0JM_c+i@W zV|}*Z{brJq2g~;`LFYbqKI9wEGNGodosM!(fI+L(_}&t%k_En>H`g~a%X6F7T}wqP zWp&}-(TXvWtx?twSL1Jjhv9v^SZzC6v%~p2T627NHK&@R?-bFf;kbyV!uu1Kuu$Ea zV!eeZt4x+4RV$H)L-q$FMs&VB7x7FePivdKiQxo;5FW$tv0mnzeT7hi@@mB(eLsMy z+LDU(j`rN_Nb4~v`=Es)dQ#y^y#`obwd>{+$nR}u7(^+RVeltr8^49OJ5^G0+qFvV z4_M2|7wMzzDsu7+jiLxAOlvJbzXb>$7h5nM0;%v#QpXKI;9}7t!Ws2Eh%M@6`_4%~ zA~Ue>OBmWAg1%g(Qfl8wN(T0VyX*oeE7k_GaBcPr3h*bp*^I^~-xKa9TK};$iJH_3 z;BcM+^(SPasj2jQ zEaFcIXGbW=mYB#}g!L5V>2e{i)c^e9x6f--`r1St#b(P0HHNM8^Q~6v#{8j4ropffDde-N?$rSAP_WfT*vUEGrE~7Q!8| z!)jXRFlX*Eeb46A6FI<)4#VIq=5C46VoD^V-lp{tFN35mt9+XewGa`zvURmRK zEsk^9sh35I(U&(#yt6fS9V%IvDw=ncGU+(}a+9g^MSGMO5w%OkiPS75`jl0~ zDbbsHS^QrXiZ6Q*CH<_#W*GsZgMK6r)`%iyDo|fljj6SX7fHcTqde~fhr&w1!M9MN zu}KZ$1{6250Re3XWwE}~UcI|ao>Q5<&8ee`B>4FD>X!F&L*5(mk+6oG&Ye^p{kW8# zmZLDhZlZig598F!TKRMh)oUf$whPVJtD7Yu54g;+tA3N(#V;Fjie8r!1k;$5G;KaC)%yj=DDrJQLn5@I1-yAUgCEp8wVP*1^I5y`J3r zHNSw5#G+s=m)N~<-=%b?7&5~HC1l3_1a>Tyh(ZTTb1&fL9X_yhZRR>%=R@7;xp@C7 z{(nvpD9gZvfJN{<@v3UW{s7ekw$&Pw!_6b%;v_>O%gQ(7lPIK$aU%!UqPxBfUnt3^ zM|b7Q?e$*FsAvPatb4nbB^3mJ(4_*wzrY$%N+@(yp_&!l7g&X;lB}|?s3MzHK^8RiFlmp`Ocd=7~wGL8>N-kurB!m4UfQg6Y8_T=g3Z*!v zqk=9^Zh1?Ec?NIxJIHL|Qsr_1G6&Ildijzv!CbcSF| zh7XF~n3KhwnIlS7W_K94Or9>V^^PfEnQ;EL^ZOWoKXKl>kl{PO3fbAZ3YV2+gbO5w$fN0h-=MAS5#Qr=CE^xNEs6eDUgH3zX=!iP4 zIs*kJSBe$;P&G4RKG{&Q!m(l3QwCFRc(FP4tkNI~sxM@C_z_0qB_agl z#b@8nY%=Eiv^pjiI^c1|cezPfRx&bWeORt+<+#1`Azc%*dX`gHAL>%Kes=6#bi$=w zM5#>w1Es`0@VQLzImBp`tswAuHV!^bN{FZnCQbwwL41up8AKK~&k4{R3Dqf6;m-gz z8W)h$&K6ZDHneFDFJd1O4H>JzwLrwj+=)NIayuL0%!J%jlzKKlrzWvd~Yl~uLPMg1| z4!C5#JyI}@dF#HPtM8aqWAI<44712@4y*9{?ph`aDbue!-wch;g{3X6g!DBFG?6q6TNhW@R6ZZ z($|%m&&20~z%fQ$du~{cHfKeiL34#<>C|)q4^lu$@|kIO+)V9vIDdEZ`woA9D8 z;yLsv7kd1xLeYaQ4u}B_EH)Hcj0Kxrtxp&&&OhQV3j4C9`n>%Zf-22uemzKbwx}}^ z#dLJc+cj}VOI~=WeItuvVYD}4v@N%4M%xMwO$+(QWi|1#&|KyetO;pPYL`h!G($Be z|1J_Z`rj$K<)Z(+#j?AjNJszE>Fn_IX1vsaFjWsq{EnHT15`a(Mt?iwW)ujS6^ zM&B;)MV;PtJm;M!EBvT`8})mrKW@Hm|6ZgfM3kHMKK!vJ;;}-+7x)KQ147zI<1(T~ zTxF+nU9@B4I^!GLzcW~DTxWb^<2vIT8`l|MyX95abO%W`wGqHsDcKERtuROeD3#iWQWV5CJEP^IPkcC~s<}}!r%1&s z&rZmU;%cgQKHfVFQ!c$~hEAj(lM;;>nUjStbpqU>JN7*eMNeY`^2%GAk`6xA% z+Jo^y5RK{`*}RDtU${`mN&FP$hR?UJ;QlP=!x}hMgcV4mB?W*-BX|U@7X%eNRhB6_E7OBUk<9X`)Rq(U z$*0}sxc>FTA#vMcJufYj7D0BdQ+X1NE9t9)_II=|S>oI*D-{V~ki<{Vbv~ z?MHmmEL$R#StHcI|Zvei+M3;zmAqH2N{^n~fz^x-W7>NE5CUjA*>H zdos2bX@!I_1K~)nm}<)4hip)OA*xU&&NR=JD6spnG8EixN|SS>IJ?1p+Dqt3D2Vr^ zI!d~nN2MG4g$~v=`2@4rIBZnW{7KX9Nc+D?d*jDQgHW45LD&!ZD4&l&f(7HjY(?-I zYn2k4YwYXrV51Ty{gnjk@ z#%6aW((tlITKLMt#zb;|vTnXb_tki^iu`sh)6R9t+tM^Zp!gB?aWUeX;?Ss7*$_J4kXmHu_Nfo51#-#=FGqu zVIXi=FQTb0BkxI4Q7Aq$->Twkq&F~|*#RP`g0(c7%8eWa4~<_SJha+=m0>AkMl@+X z-o>+6FgseY^=i9OLCn92Oc$K0Gd-j~O^>#Dqp3rEx4tH=iWfJtdty#)!lB9-}C;L;}3NX4qc`QyBda4v%K>KqelOTXH}|sV0)eN- zQPvyyFDB#wH>t@AB;4_;B{%m{DaqLZ%gc&t{-Nr|NQx3OhY@Ybw%@_DAkoO@<8k#m zg(PdFd`b`mwxZTZm;bAh(d>Nik&+~{;?>jVh*jnFg+w}g4+NZCPU$gKx{gep2m&c;CYI_D|tSIzui3d;kO?g;_20^ z7cNZRUO7Bu^VbWpuYPj#{(lomS|7fAAl!v%__^rrRCplX#PQrK=h1ud;;ZAh3d`B=F!_N)jd*9Z<7#B>itg?= zzd|;(GyFG<#(tVVe|M8`7a<{#M$z_udR;wuW7Wo+VL-v{76;%20IFJj3l(3ZyH0tA z0zB3i)*Dv7uW3tuwQuB(9W8zu`4;C{B7J1u??VXFz>j7SFB2RFhXlqD{RRWiA&rLeO8A4K!S zHL-Z~jS@#)i#OldyJY=13oe{i6Om%kGnKb%}9H;n&wDX zeTU|#c-NeVLsOop?!B`bLhH@G?{_yGTkoGK=0?h0=KZN8jFx|?S$M`c3MIgTDy!LIc0U>gXLTj zwwFPuHIioHFE6>0SevvqX;^*BWWiR)SJQfv0V)g2i;C3QzdoV~`$KX5k%NBIAd?Kq z$tb+%oFKDf+m4o;aK$5N?S=!^!-}6&u{kHd|b=m||p6DhtL^;fq-?Zc;A7 zI*w%FLiP0$zRKK{0*z|xMC(mr5ZhN=ra#W-Bd5&dE{1207t*h>|5~n-#BW%3175J- zRNL;_3nv(#m2IRZ5FhDMSsm*(W0NbFe#Wy!_+*fZWX7@$ma#u3-i<5<>PV+Bw$(nm zRBfv@Af(Pn=176GF*=Ld7k)%D7w{wn_yV{(7X~#}Y6%FEGf1?5db}DNCrd|Uhb0i@ zkwA%UI$pf(2HlD)6%2DKM#-c;iIW_H%WHWWdEmhp91#z?ZK6yng36K;>e;7&yDT&X z_Yh{L+G^`cA}!7Ir|)W!FyUQ>|9`tzJwJ{v)q_@yL|0DDG!p6bff?x^@!Zi2o!(2Q zW5W^ErB=u+MO6&S1XY>1|EiN|gu8?~(TE-FF7KTURO}a)LvZ`9BONibiAs}kvy^%_ zM(F>5$a{=T5`m(P4`LENf*eh6@Q-U`dd80gX$Hq~3D!2rub(pY!Tu(d9jyQC@l1^5($yUCNu~mdABg z^uvQ4r59E(!=I8y`J^8D@Q=Tx_{U{ur^3S<`kM?b4V;Op21Xj5B>)O6HovspV zyOwwGp7grgEib9EEaBBbL64VNPI>X-klWr5CZ%CIu;soE+Lzg0oqwpCzp$^HKaNtE znbCPB|M{8x%lq#$`GxmbX1Xqa!yz5~F{P7HUdr2(eh+K-xcQ-K?@PRP)ZY#Mvz+p| zzY*f8JReL<=gDk_#%Ht(U-+~O|0{INOhD&Z!}oXKRsUmH=l}%&C-=mE>%mU{f39%p z*MYw-uT7_`#M-XqZMtp`e!AN&Z=1@pgx5~^&B`dx)3v;NXY5hlXt%s~Re9mAoz33?{>r03mk{=!uxsyaSm zftJqI@u2B@xeH%>l?(qW&WRmh=_l%|-m|`eZvMjK-Td=w!MErr{5B>G?=c@DtPU>HeDC6a2t5{OfM{ zW>4@t`?>8+<5SWTd|Mj+%PSrF*r)c;-n-NA>GB(Ug1U)CUdVt&B+pci%AKw%F;xv33|FWLoZ%xC0 zIo&D$bL9Y}CF~Yys&qVP`V39Of9RI~U{CP9((q|~!ac!nD01o3*X^%B zPw)??;nU^!>j{2V8vZetKi@s7hxU$6!-rh>C-wr*MoVhDuO%zBJeIA@iRq=ABBI{! z-5vnKNHr^fKrFihM(k^@y-+RWSNRkvaIRnr-w?lT%!HrFmfUl45V%&%l9QM*aKI9~ ziyuE9)8cIRMyr-vg!*F6ULkQk{TQvA!&f9EK=aOC;;0esWj}cwHm_XU?vKfFtvF4v zOQ^hs4;E9SDIqQ+eZ)ZUHo20O#K+?h9oJE=0Io=Of{N}KRuryHar=1lAfsyeT#T3_ zOU1e{kbU!`BL*T5pB*-zSqHXf6tR^ z4_UaMB4d2g8qWTEh7;^+c%E;e_)ypAg9X0&M+Ma#{(O8t^nnmAcr*LTiDtj)U0ywP zc9H3AuX-^&Mf}C0yR#zKTCdX62aB7tKh>&Sxv`h1Q~$Ap?VB*}Xm{JlDB51Zz!idw zrIw}y|HO$69v|tq$6>lwMZ`ybE&X^ws}vedW^oZWp1f!ECD}a#LPc&hu6gF~Ar5)P zv+ZI%sDD_fNaTc8809)qo&ia+!$Y-6bn2v1)4PdyJn9_7#Rx~EF-l|X>BZ8WZ6o`N zDbtL3x$8;n=%u2|ba3~c$V&YuIaLmHt2{zgSz=E0Q(H^eSFxha?-ZOLGxK{aPy7MJ zcv>`3I|be*^b=oi88+hTIi=d-*wFg$B=IMbK`~a3{ zW-!)#_OHgtSz%tY@L1jv&Sj*;^8PXV1z4sL0*;gGD%s?AA}w*#C8xvGNhTHl0tXJL z?X<&J|65+9E&3iW-JVUpdKvP%zy1y3#cqx2A#CUNzcWo6jmpy`Ui@>BY?!bg8bXCQ zFfxk8)8{5W3*SmKv3TuF*O%{?n27bB2*Xz#36(5TVn}uGfSyqlCQ-!~dboi^k%U}Dc9_J!K#b2H7D3#+9-V76K z%~Ufd!jBFsX7zDcQ8qXA*+#n%%>hb(&*W|c zaE*rm_0<`xn}r%TI@HLu=ZPs; zE-7=)ACZ`AUxglPwvEh}&JzE7J{H=c@qAP~5w0?$H|Kl8W%fGdnylxGV+4KNTl1~` z#if4JIB8V4C}Vg;(>Ky9!Nq3c-rLYqiWXIi^PQHhWA~%lRS}-yELGRM8va%XK3;s7 z3%onHCoq|%y?NCVt~N`AL>YriX2eLZwrrW%Te%@VTcikaw@4tMN_DJ9d8F&_<sg_zd_JwmBiTU7(Zq0vII)E)w zBCXi-zxqseNgv+*8DDJK{F4JC#b)%Td@hZ#PZfU#nS!9e@wC!bhhK%&V}s?KjQ!(N z0C2cG*@t6UG5~7|PvxT30cWLhrPE~eO z8K2zz#U1(2Llghj`Craa6cNFtLp_!47*U!PKEQtK3wkN@z@+{Azjpc3J!bl=@SCd| zT<6v?Oog@~{(XG3;()ZfgW85Iw=K5saFmjJUp)A3EK~j;2!-4RuZj1iI`(DXJ`#+X zKPSsxA8b?^ZSHk%^zB~W=UUpmUUj&`IZ@CPeqGa?@zJ5rJneM|!*SPk&V(z`PNYt| z^*j<(Cxyr2XRL$jZ5P7>n2r?%09kRWcyCYI;fIt**mr*Znatr1F*WC>eH`p_WNhg) zndsHHNT;fIN4%#$cE$ahyzkMz*R%K1KA+IFYx|0%ebTh%NNA7tJ@Hvj?Ykc7w%7JG z;XmoIJtA*dt3RYbh}Qerlvpsjbput1YRt&e0A*lpqZIlaxDuWDNZanmIw zaX&+)b6wrN$#~TE2X*peqKeXGk9O;yTQ<9*S!o}e#M`5szglxx7HTVjG3)TYgo`Js zfJvrxsGOqwi;&b>Eg{b)Nnog2u`HC^M~zSnf5MK@rP&dGl-RDG@F`6*0G7_UgkN}| zQut!buQ=9uy*-%GFYUfiZex__U(qFgIhzFz$y$|PJx2^v9bH3HxY?{~x#84wnbUNc z@4{EQ%xmop_(*h9=FW|}hK#dLQ*?FR5$x~$=FI=7Gpc{(oWUiah#jJobNXBg&4)>R zP+j;UywjyVm){?9OAvlPJ8p8BSaJIl_-(w*7ajcmF5iU2H$#plSsA+HY9&4je+R!0 z$gKZz&F{0N{;{G6^vLg-?7m9VW5bs&zr*aXyhSKf#qRsDMAAWrgdoE0eHX5nlfQG5 z=5>o8ikjOW$Ku$9RO+>R{=VF;uSfpApBq`a^7j)$!ae!hz}XH^&EKZW-&X)E#9z)Y z{5=WRwD_0@;qN*2S-41a!;8Y-`YdKuOLBS#pNG$Tk}~Rq#ZPH+iJ7VvHZ;t#ET}0%c zjE`~PqQ*zS86N@h?Gq9A@9+X1=K<#K0V)w7mRzZwH&QI;9bGPI-5uDuJqF;_i3FS@NP1r zA7w>w>c{v*9PcXA8eZl_#8P>{yWFr^P=O8Koy~as_cB^`dF3ov1=Dq&(Qrz2>Nz8B za2jJd=e3T=@YnYH7A-sFxt0&|M>OQ@Z$=YYbBM-|YvagxPCk9s@}Lit&{VC#Cie$)N&wl<{u{`R1CmPazLB$ zbRGSv0`D_WU$uXWuYxNljRm{ak;kB%Gp`C%_L+B@F0*FpMlp{cTy3rJEu!727Ng=h zqh(8epkR4*)$?;d;KcZxky4S!kK|ookbEA@fa2oP7FDyPisAzX+u%?agQ0e51_mQ_~nY7>kMCDMU`2qqxMULhr}>ObFAQ7s4w4$#+g8Rd=A{Hs2xz_^AfOC!?6ri zJ`+}+8ISk=p!4{9veUcRui$ASFL0_fSn--cw4Mxps%Vymajyr5(*oXRbxv(vLcMI1 z-{%6}^$J40tV;yE%m>)gF-cM|T(`gBZ8f~j8AGruik;qNQSn1ZUp96)QV4yyI^Ui* zO5`AV@=wKNW}Q`HH?tCr-b5riB0-%s2vIeerWuVVfUrIK>(5Y|PvnvBqxddr^C^6U zRDVOK&qT=O@Bffxu+pI4rMw;IBc9Dt`*K+ds{q>J>+Hv62w()UFO+qzGJbIGhxVW# zHcOZ=i9LgMYd;Zm8nSGN(~zCW+fEI+iwc~Ei0LKWka>Jp`ad6={z&75YfJfsYcC|2Ql<-IOIpygX5=wb`y0{iUPe^%uTQqN+d6?nyWGYxrIo9-=(v!VhA}w^#TLtXydy$8hGl@PR$& zHp$L->IT2Nb$;lR#;?!GJ=Ax(3*Uj?Gwhq}6~Cb_d~siw{*SVs*9|=QCHAD>&QG2G zD_rHaucoK^+B7`$>+8bX>|JzIpQiWSY51#L_{N^#FL&W{ADig(=S%3#do6!x8a|EB zgFV6b((v@hhb}%hvhCMR`Os?xAZhWW+tc=mORvY={D-qI)J=Y;{Td#6rTM3kjfTC# zU+%)^hTQUB>PC2zKSPyKrCnxPIRj+CI~b?ezYfOMrivA*;@dwPD4T+^xIYAml+NUQ zE7UR&do0tm-Z9c&xGYvGy<+{7GXL9uJw|E!hq4*5@wEY*sls6f+A1YoAQ@P zQRz<2XoD_q>o$eGTizd3dBhZe8lwD_%NY*}R=WZAep0$VaXL#iQQ7#9I5XYw(^SY3 z)_>=T(4Ime_6nJxt%6i>zfTA9?T1ouym$iuBEA1WYO+ao3f{*H(P*rrQ6x92WNtep zndnUM!qlrYZZ-Qp_NW2W7BBojKFr5+OC`U~8??6{lbs><2TCCUF{r9_Wk1rD$viA} z&_Rh)6;94uceKeM(>H!}`2XWh^t=FU!Q~Jzt`v+{$%M@Z=0Jau>KQdNb=N`67o9#U zUEI;c_128?(l|y}NC0^qZN=b5*{XFn3}6IaKS8g!M?lng?Wu9o%aVJj{R8|uh*R|< zU)^pOmnyJQcVT(#c2*etpx$&KIJwq;|aRMI`#r$K&CZjlT&xc%n zrVnKLj;!Zdd^^tJUl6k>$xN*wM#-D@W)XLK5MGTg7l_R$1LB@{U?YUVz1v)25I#5* zn^~gl=lj`%-X&9NsoXdAX!1PKr^s_Er8+E}CmN5i@Hq0PS-7863k%!Ku*uRUvGRxt zGM-7oHj+{?RPP4-P zca>|ky@Yidel_+|nB8cM2vLaR2#_4OyOPQ|9+j&VZI(BF;c{nBoPnVHbN0I{5@)fy=c zdNElpH{gb#{X{%Wkx;R-MceLeMwj8yv0pOBjL#ql+S6qXih_@o)yXel)5T#6$dfFi zEZXk%)h~d?ELMH>7pVuLsmR2rO2(C|cdB^QhXXxHPT&?^{W3)P3e`(b2$9l?^$hY? z!AvN(lw1Ir0<_TqLdbunCJ>n;BO|zrnEsWiYS`#}UsT;5aF613HHRL}@TJLbyrqZk zn@M-*`s#;B;i=JVsU87?`06i~cig^)8I5Y*iWkqW)iLkSMfH#-#_+eXP{vg}Enj^l z8Hhq*S})uF6A2H9AHqnHY!Eju6q{0{ex}2Ly3OZMx4LgLZJXKvEd9Da)x^iFRD(Q6 zTr3!-L7D*Ou{xf%C(8W=t?T(~c>xt+67bel}KQl=iaOXkRR{|gAB=bIshWs_LEeNlp17-<0&LfgZC%^8WaMo zX|U1u$X*OIFoK3GK}P??bb}o85`^0zH*72^ChZXDqBb0SdwN z2WtJSFC5A6%T29_!J2zf)EsKK^72$&10}w{juLOAM5P05Hxik8zpU*&)two~i;xxkyaq7ue zSZHPWJ3CK7Gnr?ua=dJ=Lm?9?M~6}Ou5hj9A_%e`TR|6sJT@jxka?mi2tk&=mq8E< z03pc5qzXa4A*#B+x4x}0i5K3p+Ues#_$GJL$C>^6mvpXaedJ25)U3UtMd|#AQ zwCpKN0=HGO*ELl%8KKOd07|Q<*O4TY36jca>7b07Jv+wD-_xyWN;&dxi=wAutx+$~ z>;n}k!bhktmGUJ^eZh}BURWmY%NWpVEDuU=cXwL&q-*H>ApB&WtNjU%(zWV6cRw~# znH^`E5N1rmAtajyfZnKu5nP&fKt9@ulL0xbkbA=nhH>-XfJ9q$-1TFGe*wt0Z+U61o(HoO1z? z(U&SNe;ciEbLal)`lk6~mQ%6_)6W<-9Z))bVn+IpSf+PPADWT=5K~{*^!^#?wXf`% zf9IR3Wlwtic@_4L<%Mp8TMDlp1-JYH-(sG($n)(yyAx%1{OHcd59ty^R&N=u7FSrW zkVuM$MCX)cg>%he`-k!VH3ktN8wXXX?R~`t%+1j`rCE^*l~}cch<`C}GN(G`A7nH> zB!rC@Z=z@I2H~yLS@|w5WJF;^N;u}K6sGlW$if}O;)(I2J+#l$W9W@Hbe}7$j|7D| zSXN(W%QB%-R^HK@%2JZ8VWKRkJU~48WPJ==1~RVi0p6W&d*B@e(geW+#q6$KWYLk?zpoN}HZq=nzvZfD7)&CI0aQHOu9 zb4cJ}oxfTFB;gh;J|MDFek29St>3%svneLT7BY-4-c@-dh?%4UHi*~$$khjz;Rb;n z<0LaSNMb*mF^;^@3sb6NBT5vFj5eGw6;~Bh$HojYQzP?3F^)$#hj>ic+N}le?;Z_0 zvuUN&WUqQv4+txZ)mZEbNc#ytMb=ls2A3$6W!UtxFtPGXhU{`d4*n0o*RcD6th-f= zchM9ic#ju#H#U|baxq=D+PTko=NK$9Ih~|h>_hDu18vE*(Lt>(q*3lMaAE;H=&dB0*hOd4- zA47vbmCH$GlbX{^KK@2$@z2B@c9;v6x4c~`IraGwr{oN4$TL&RQmr@w42!hyP9& zce(TDW#}a68Uf!TuHMswTvW+xTx znNA<+@YGs(YKU_AlNkBE?3?jj;KboEXnb%_x#FG%ui~ACk(#?2MrJphCA>96r;gOD z)i6?XR>R1=hO>Hor@2@)D9rVChR^{V=61s*5OKgt!t@BNTx? zv!P6a-x=8R%q*kj{gN7Moo`W*&JPxg#7DBu z$rH-PXS4?jw#)23h|jr-w%dJ+dhrqO$%c2yByQd<+q_oW&W-UQ%LtFA?4bnRZ6NUu z-=YZ=Sd-&h6r}bd`iPF&LPrIqqokjLUiB|!7a0{B3YJS0ZoXm`dqp6Y^Gs(ELO9>3 zSPc!Zl0XRi<^Ej6iO4B6=6@hP6ymMslq#4zF^d`7yd0q7D zUbBA0g!S@&&=XUa8CLy*J8SxKU2{unGtEXNdjb6A$8C##E>i8%&n5Cap$n)G#syW+ zEt{bn1QH@Zp=xV=2Q60MyRffl!FGkQ11;GB^4e&Ty@gc&z-Bq;9;@u{s0#-}q0 zEm!`vM1$tIDqROdI1DEI5;w9X8J_X*8stvNhWDW!_rq1Ud`KrP*|{+oziKI$^Xgd5 z?q#ae?(i*&P#qmi`?HYwzD4t7h{MGN+grA#`G(5i8~IoGrl4J-(eVP$<_lNDG3~-J z@NJoWKFTA*wG>lnnNhLEsCY#U+<^6UgEwI9v|1R>nrY;_@Qn4GW*PYvj*(wsn1*u| zuT)1rgjddiSLBx2OlFZev)qV&1-ERZy>I|$wbs)H9)nr5O|@lfNkKdF8=uq|Xs2;J zdlllUIorWonj=E$6GaW$S7zUVy@*DX8u4Jh+;>T9Ho%I(ie;R6HKI$268}}NSr@{N zqyGJ~RQ1%Q!j4b4>}aN*56F2C0;xAkbJCAR`jIB<^o9cg(oGf^O$2Yt2PF;X(qR5) z4^fzeL01{#3Hx(!x7pUZ3xaSNbV~wf*jHLUklQv53JqFo488@qgin2Z%V_CIx+i;N45GuzTvf z)%;E4?+5&y&EE+As`%?olT)F-o-g>@&foj|y~f{K{#NprsjvR;^S-4(z#0=^eH5tR zrYgKQTezo=F~oF)pQqBz7Bq`Xf^X4s6OLNY;z7JHAGeIQ0=JmC5NO$-+Z4zRsCQ8#X+tm#|<@*SqKsrC#=ODUS)K2d*|$>fe{N|33qg)J@3Zg3dCtBP=dj5>5$CY& zJ`v{(qdoEY4&t0)y-)B#%&pL9N&mpYI^fQFHbQKB!%L;*-ILdlTm)0(;Wh4^ICp&%gV8qwMn&lo@G) zah@^Jv_5RCWrbzuEOBf}xhww27I(!GGZx$)vgYBG^mfR)dOEv`c#no+H5}mD9*SMP zIp|x|pUKy;?D8}=&#*2MTR?|BPSPEN91C7~6Qi8`s&($#Kx~3*;SDrQNEWQ)nl@Q_ z2W|CG)DXn{tQOzF51f<_<(Gty)c4qgml}c}H%!>34AU!V2)J$x4c^L%VrHos~kCO)G{oZ5V6w}z%RhrG+M|McOkTXof1(>L-J zWhBYwT~4Ka<1fa^)tG?xMKNFQlVW;*qf#(&_RwzHgb8(Dw23wHz9^>ezA1*)ykJuk zuP*x*J-jDhKp%{O`=Vi=S4Tg6Ou$nE8(euTXE8rR zVu8guIMTA2{Ph8IU!BHf=i2`~4L`tz5Bx^5bb{e?xRBOPg9qLn$g3sUL*FP)>}HHlP# zL5z4uY--zo?8Dxq+;OUQxaGj)-*9mEEzX|C4NsB2z9Jp|6Wm+*(m!$-UwHY{S2U*R zQ{Vp8Mb?NCTBLmsoZjhzoV2GBg4%6Qx$XI!_V|a1f55x;9GME}h=Ew7kLR20=${05 zlgwh;u~mD{9xQ22{``@}~{@mEd$ zx8yGzO*)N%uJ6;L!?GI>6DE*;@CBah1dabndcPAL^*ntz?20EfZtN~#QntBU5+@5I zx~sqMRyle^{Ixod?{^!0(KC6o55m(*4ks+E<&B-u`>99nl++Fj(4T#?a^J)iR5XO` z4B63QyJh%izMC0X{2RhU1l6rCdL#F*CHe?>^sB5$Ucn3UC|eSbP^65*@{sj{b4g`! z#j^uF+yuxu`{-Zu^#$y*gUk(XeP*8SYx<;*$`D<_rkW~8=L=YWO%=C4qq9bq%IS+b z3ja?~_o$l=n|{iZ44hZdlNd+uo+^&?KMTZ-x9!C^Y7kb=@CDz(i|Pg$ZPr?KCzrjN z*~Tp_IVN4m^SY4VxP^>(+`gVd(vYQT$h$RUBn|nwZ3-k8B~6i=IWORDt}Dyss-(#m ze=CQq?%DJ^f9;N6hArMJzsMnw4t^QOoBck%Ns3>l@|NZoVGDSLcj;`{#bqGPGQ))x zgoC~f+x(f5y0XoePdRL3pfUvTs}bgj1DIx>;XO0YQ%(VqrHX0XuC&?`cTq~ZKOOdY zsG@^?X5&)P!9GL(GlPA8n(AN*t1WqUx)_InCcDMJKqpg7N3F@D)36Q;osx$A+|C7- zfH}fM|4mp(_=k8>g8}!h{bXI@+{vXe^$-l&$+t$!ipX0Dr32~RqtuaVI%>qk@!?ens;{ zWLv8%xo++kpqAD@&)}ub7yU6mMEOWH`zw!)B$GEboz4gQrd|C#>WR33%DbO;X-rjX zcwkcl5F&Ww)DeQ`N>GW9xrb9syX-SxmTpX(PR-Pcu&fGMJ3`i0{ER|_cPcc({WU+U z`e&k;J9TffY+utCN0P}`|1L*ah`6dPAWym_19eLtD0f@3+YY}ZElJLF4_?!jAJ%Y4>>@cS zhNmEMKez78LsCCHeofqd&44fr1n0 z&NrSEm7+1}) zQXh+xC%|{obo&$PQi0oFljLnWd6kpwx7Vv=Vi}~wulyuVPU4_F)f_fBGFiUidf`Jy zzYln$QSh~E8l}9G1dPN25^q+C*$i*HTqO=p(<7IU(BmQ?6g@^fWtXp0W5_*Se4FY( zFL_6ZjA2#^3GMr*fvE z`10e0Xu}!c;BiW)lP4 ziwCm^e*Ck&gpZenY0?+{I-47Q)dyLx8jZ*EFExLJ0gVG9+wB2VDTnx#pSrk8zetMI zmtI)8_1(LMgHAt~7AudYvLmI4vYbdztv)={VwJM2m?FyxE+S{OksKUN^^Y6_P!XUp zTnA$_Sbogt*9p{DlqV|>&@*FZsrs3L8&H8c?7Gs(0kSgAOBEmb?{faABICGuXXk5N z_Wqg2&GmYF;2%{_s>8=0bE*u1ohvKuRy)!LJy}fW9%>_im@=FI!rh(a5Z=+{ZFsDs zykG0`3M*E`3V(7Bg{X25cgtXsWTywXkX%7q>8tjGLxxgF6pm~^f1B0O;Tx;F-J z_`iiOgT!L=Wa@I^-pk)@;@Td>_}Y>^Ub?=rso@pCL)0`Py+oyYm3~t%QYgmm2Kxc>RuqmEwU01 zEf=dxvajl%K-KbqZ|rhqO_E!HZ9w^^E(hk3XlEwt&3kwRDiG6U;dvyBh&%W?xJ61G z5^eSxY8`y9VXcb3?Uhi>*@3}qOf0!qJe4brox7{2eh?5>qb2w9V#NJfgI5|=s|;UF zGqcxl820vOC@@$dCz8H+q6C*p{8iPh!OSXe4%CxIZPQTz+0XnAX2(x;Bdx_J^Y%LF zcy1}K4S7Fv;_=}N-zc!=U@lE*_uep$NPFKms+P>{ZM5Z;mX>nON;K7rqW^`W)r6(O zhj9aY_0%@gy9}&LRdC`_IH2Q5D)Cpn%k7cW9BuVhN0)h1ZK#Q6)faQ`6t~^-&J||g zaENbl?)NDh)9AEVpl_{jQSK?cHU#>fL$oz9d@cNF{xN43(P6-F#uab)LGf{$>vm5L_(rv)T1Pbm`qdH?uzJC6$>fVRL5dN}_~9HYI^xC{am%kFDP*7#{BwT@GvdN>cjfofX{pwdUmkB=#pUSlQRx5*L z!4hF;?XZ7Qt6jv}yhDimKm4TS%dCfKBHsR8$NR5ovwf!=ChAsL&~AxC!+K6;@$s_1 zsW+tt>hjE~%zCWH*vhmv2h@GvqFCPcIGrdufN933qjoVe)RA0dtDi$T=tYOKsdq4w z?VW!q!HIbp6Y`K<*a?ZIz8MV`Rwo)IXKc%4X|Tp##kcsVEC%eC)~B2d6MbtqIVJ7S zqVW=wz3Pp*|0=43pLK>?`f2IXUuoCSw*bv9X3j~JaQasL?HVZow_8&kW^!zldQvUb zKC;~^-rtcY^nADVA=Mw%Rx{COWS&6(V46!@M_j1R1#9@l8otI_j_O0)&Lteh8c;x%ZULe=_j{t@Mfhr;hR)E4 zOLHnYQUc`qrTfI|+6)hns2hGeEHRawd@md=`EDei)oy>u?3(N=mCmro0>nawC?e>^ zf-D30h-NaP5A*ts?Z};}y!W>bQZ`P9B=!jps-83B^<@o;L`WuSf4NX+l0YjV?HAf9 z>X@vs_*$w&nO%q$yRcc2A$*Xcg53Hk*RIw!wzlJw_Azg2XT!J?P6stXmX3xTF9dN_+@dn`Fv&6etp z<5VsKLN&Zo?@eme-=a$<{q25Kqf{|j2WIDHn$8s0Eq=i1-TTVq97M%Oa=>FVPe=q2 zw3F~D^ew6iR){P__cET6frh0mfXuBG6=po@Ox-PBeMC(Xx@z+zdV#wT%B4T5`27jx5V;q;B0Z0nWC*CZZhkoPWZHx3?92q)$3b0Q?&QyL_I$sTpB)| zf4>(#k$(q=kLKSK!UyqhdAQFrj7Cr5ZBzy$x~eF75dUT+i}*J?*@u7glR5m0pFowK z6}%f0i+~OIo=qv0%wYa`{61Ozg!e~~jgRNl1>?g<8_~A4$pfB2c1iWeMFs|}GpnOZ zaTJi2cT1GS`ATi+hFo$CX?)`QBvaOj5if;sE;c?gt8Vv+e&1b7qf2v)y7m)IUyyh# z8xs$9#qR)(-*8y9wxXHC=hZEN_@v#V;)mTcI)2#2d&7xJ73(CHvTy$ks{+*&-@-}s zRlqtznv-mmK94p(5p6%wck6wCAny;agH!JDEvnD1gmtXjZYdQG@~%v6p(f*5VH{{+ z#IMOsTuI4%q*+%*4)!g&iT-Uho~6$mi0ni)5XQ68M>$bY-{8kIgOH+;L z$64XS)W3cCH#=NlU}?Y{G&L_tOu;-tefj<~FA%%5%>N`C$gCM~J&;jXj#yzupD|A0 zS0z&H3ZD!TU;Vit>hgq)YdusFCxR)=SIVD1jl!WBD8QhgkVEAd5b~1$m%Vd=kFvNL z{)Su#Az_2E5-rNA0Ro{K8n(?gNE8lfNf^@b!T^>w>;3RDHUfz_yjB64|!RSp0spv&6E z4d@DTfk(|eoNGySO!0}upM_E)Ki`9wZRE1Zg|r3SD*h}|Ly(8DTR|R+g_K1-hTMu% z(3h%{6w((hd-29>+copEZOeFu)nwbMcvkb=v>@9yfoC`G!};yOa~02Q9$WhU|5DPs zq^C-Bmw1}A#Vc;gwx#nN$uoFiw(WR+pP-y>{4VFaH@{Eu6!9MBw}R(Yp4WJ6Jr4Yr z(xXeq1gUKSY3UhVGkc^Li+u^ zlMYr}jj;5;++QU^V_sbKyXzh(EGMgRJ;il)UOX-7Yi-lTamY-sktyqY>55s^sMPJX zPcw`7ve*4dUe1i|jn&K=%V{s|H3AP6iv_a7y4;tF$%?AV96uCp;v zf^Zokn0f3hB~`=SloZ$Gu3I9SV3wD?ZUR}Jx#s{!D<0!00S!1;m_L7q z-7oD{FM6zN$q340(HNv^U2i_g_61e?ACsz$?%vWKGmnC>*q`|^f)b#ldW^2OU>Orj zRfHkB=&%lVned9r^0;1DEHnH|-O)z+ISUhVz&*r3svpeHh2nDe-Shc*yi~9UTf7BI zTLR1FBtTqk7@sbYm9lt)eZq#iMyT8wNcU*$?cNm?;W19e{_C1+*{68O(1Xe_K=yYoo@zho zgB!8~a!sF;*5~(8XU&mbb6RSnGnO*ekqmn)MIq z0N$Fe?``SxcGxdziY=8O9cgS9kVn_8oie3EPP3ZO)n3!nG;)8QQ8EXSFn{jUXy9oZ>Vl~zoYq``6qk9#vMNU;E#fP zyUp+ZTsJZstFXq(l>cZ}h5`Mns{QoY51%?|LKuh!l$xwH|3}{U&!oK_zwmo)u?1QANtrYMfRlKCC@WiVS=(pL2uRy=< zE?iprirYTCiTfQ&u^}J6+86Hk&JjoBSlG>CxrXWBGS;|S-f#LeHJtYI)JAvV3Rmpq za?~`(V^}`i(kwC=S@iexnztsn`$$Z5)_AI#Kmr79R0yb6d)b4z&!js9y>l09twG(J$7wnP*&(zHh%p6{EwUUg033R+E{08PR0 zTWZr5P^vf9Shrz*cQ0KquPG9Oodm9wK#Ay9@YYzjWqED>Ledqvo)Zqsejk$x_O!5- zOE+YHrm?WK5Oqx9-snIP(Bk>xaZ&<#;)$d++*Skg6mu0WOKmllxn7`D8z?6_SRn>( zyVv97jjR3I`dUxx84 zZj7xXK~Y_7ewE;9-2RsgLeq<=vMu8xE8}fsjIFDS)ohNQM8-k*d$iI!+ohjirJs~Y zFMS12$C6xw6^CiCmGl&nik-0sl0N^eBzxr83i2o8@ce1s*y?>Cy~)b3NN1>d z9XAp42U=yf@2?3~(n%zB#nzCp=1p`Or-G-lPPS|$SMWmyXL)c{g&rJG#%cDo^5v6{ z^k+!#CLq31Rsg437Bb~c)&ldh7Tp0mgg-`GT!N5F2SRBrdv2Q3rv|SG`!wfCD`&mr ztlLuaMqO-9!PLc8dz|h1YLS)pHqr*0Q)X*_V~Qy^N5B*u))n_Zh5b8wpln~|*spGn zvpkb$TPzQf8cV+kl6b@kF6(gjIoArVT+45ur1(eY2kkbM}A^U z*=sun4P;Bp@LPP@C9;=BJj9CSaQ89u)Wq?#!eyKeahD7}D$qi6w*soGbeY;b5-Ww&9nnG5%`-gv8J%dT40hY%ti@8uW{#_6GgN7KW2B_pj2wPc9XLj;le&>QH}8AG_|fJ)i}cBIPV z|1s%mXe+cy@iU#a_mdsc2!BCvS<38plhgw+ftSioT1N!|#vbpQVNNLgJ7?PAsax5n ziHbUY$tarl3EG5!%|san^Q~L0`CFU6fNx*;v|nd3ORBUJEe;LU!A5_o#E`8%=8h+P zZmcdg8@cLDFIIyqQQm>ei^;Kr+k>+4p|PUA|{F2+WZ^{NN|Yv4g!Z%j+w6HWh{ zd>T7i-UU@}ArGj!qi)yyVe$L(Vzbjq-@CC;bo*1(^7c|3e>wDM9{Z(6N3jKtt&J_K z+f}oM4Nm`$s7dk-a@k+ZAe)u_CGoNcVw&5w$6`2=0|_oc`K|8VtJ^iFXzF4sU;q8o z_Za!eG>{Vw%Ts1=uy98#q?Dr|q*v|VezM-Vp3EtR=zE7}&J{5^Tk zxr}!apg1TLXz67815sfGqQc6sOGJg0NDxhk3h6myLqym&L)m!~^v2s$x5TOZoa+)) zz7l#VXDh-#=8oClvRP!9!PZ#dVubcr|DY7}nc<39WU0^@$Irq8Yz>(VoDAqLexZt} z33gD?Z42^kU>gR~G$+#4$HIgE5;=Doy6uBRlWqPRw05MCA9h1oo6Ab=1*TV+@N zijvf)L|_1H{^@4`FYcwW(p@F#gw0*bOYusdvD|pIq=!FG(+_SKwAmKS%z~@uio%l2 zz~?2I{v#Id)}bCkn--MV0-xI(cJ#%Ny>D=77gxPpYskHK_`w8T^PDi1DK&_Hnp|&D zxI9U|;85Q!*{nq8q|~kqaPGs7j&i}A6qX@xN?;eZB5(dI4}&(8ED|$yaa$ZJ0pY`+ zNjp+*c9a4d17Ai@VaFz9PxMUve& zPVqpAK_1vKv3P?y>3&7T^2K0cVp^b&E?{j^A||+bI;ljXDupk5rnAC*7)*p61%RU( zX2w=aHK;xr3k8P);oy7u;8R-bzdFyZR{OupUUJfS&sHE@ZYndMyf;2% z(+QKLqxc1ck8DD@o@UfeFdq?{3YGk)xTDlvl?;K7E93Bn(mpf5$_oA3MPf8cEzb$c zObun2Cv}=#56Um7P!GzLtMs5$#%ubQ4NB7RY5SrH?8PhfyfQ3WaPxqKVUglEl9pv{ zPd30xPse*aRV#h0b4n5CY>2TI(Vb$W0?(vs?8_@`!i6bu{t2rhqi{|MR!0lT8&wc3eStJ|U zg2)33V$U)On~RU_;-p+sE9fG5s~1v`-5wG zSpK|MI%Bm5SXwOCOol5jjQ8gctmY^N4udz{sW=Z|eDHiKIPyV?`5+4|bZeH!*jcu#IgRs* zs$*E4q)1tX)B@$w{t5(xKdMobZc@x~9d8YozNp$K@vHlLFQ&ucQU5T11(Vkx41|<) zF~9Wpdn)d3`a5RcKzzKvVX0s<6Ho$5u76r$ECmd`Vj647%7OLC8VGmH@!9+&ATCb; zalHkEBN>RP8i)&tLpK*5b$4Wz;>yvlp*8auYe2CxL^mo-yx$yzU$2C(_ zH&V#6!!H#J(<{xpnqT7;8u)FCqV(o(Ntwv-^K#iIOk;1F6o5V2@6+_4tuu3gpM?S1;@zv z245-@$wgRB1UW7ml#xV`BSRdu;CWPMyKWTJve)&ZTjAelr`hYe@oH?ur}L+&g05fv zRr95#1n*jw=D%19nf_|qBtEi? z#_n2{>%V9pESv(Y8Vfg5DwBuurzMxaJyHJluXOo$sPf};;Y%rB&iaFKX6SL@t9u77 zeKo4u68tbF-kfmd5zvAubS8)OXwH?1>RRU}HAnap-JFG1bxu{CP;@COh4{!n_>k&8 zM~>5oey-6D(Z}e*OJj~-OX2&H(R@|-*XAZ+e*#f!Ql$~GFv5+}b3hhmP{4HSbNpep8V zes#ldQN`>u2dH9hw&LI6x53~aI69RSOPsu$siaXwx8df$dB%Oe>SeviOkQ-K_p52k zoHh1vc=;A3xTORpK+=pi1&;>Ni83ssVvfJep+9Bn2%?o)UCK;+@uv-urIYnj z&fqW*Q=qx}AdcL*i%_@5Tr10bY&JJfG)FfmmmA|^ymBangN6+-Oxl?BLa;1Lm9yl}CRr;;H zR<I+U2f@nW5`t0d<_=Bo#XX?WUwct=UCF^{TrSSJ zxb8EKW`4z4I=PI2g9bpM21u?dkg+LnO`gnE$kzUel!0WMM zP2Gu=$vaYdHl^2XnVn|59DS7YVdLJxgy}vta#nGNVJJE+LXXU}8P<$!^suX0(#78= zZjazv*h*h5nAsgwy9?(F=-U5|yNvC9rKOSMumb6{*hHYre@q|Q@3MS?S|{edx<=I~ zQ`{wo;@Dj-{)kBpA%Gm1Pybm)S#(?BxxHj;+(WB!=U4iwaB}&QFLkM}3dcwoY(XPl z@fPB}apjFCiYmVcdz(NxEX#j38@r|Dx%1u~Sf1-nZB6M~XhyU2d!d=ql|8C{(cd%r zYL=fiCqC$T47fWqAZm~_r7IcTxAd23b&Sljsn8m}1r4H1vkLpT7KH}_CsPe1(kLLa zO*zlpN8C*G%fY@V`k8$GrHtV)pS?QKd*Rtlu-jv*TDeL~9Xb3m*gD6)s0gx;`r^0a zNT|*qy!Mnje{erP>imJ+CN`asnGW`jEkomIukA*j3Zt3ZHO$5;A$x+i37?>4NjBTd zf^+c_cE=_xyCgT4MbC9cUp3Cn6|;iTnZ`F*H7)g2mG|P5jO>!M(Z>Ztv%(`&WOv10 z(ag<0I719Xqj!@ZA1!x8W^j>T_x?AZn)KL8$~Lpmf0W38?K{K zvRMC;I9B76hzpPUGYj%Mb0DG%r+BVZcKXsdPw86!v99{Dx|mdwnjZ*r5Sj_YFdZyD zkxt0-maeha7L&q+SgO-B@+?sSJ{rbTk4+~9m6y(zHYiVYL63fYR0 zF~%Un!i@)iA|Y$hf1Ho#9(fZBy95d?r;6ZQr_Fx*lLRLU`Is#nmOMybS<(V4xy;*H zyL4%pl!leu?KhJ%Wp2L8Ja8`Pxz>C*p1-D126aswZ6jky%Oqw4hxzFWj}MsFOcxo# z-^Xo~V|Kf)AwZAH+?}Ap?R5p@DE`d&Cel~E_`>=kDTDj;;56P4q#8OOPGdE1;qy3* zxYjJ7c3-$WQ!ttPCdC{D`KE*|Ubk9z))~$Au}$98+)!=)0k3%{DZ-b^)|a&eo#rueRXCLHS1rr<3|+VQcg~X~3U3YU(bXo9i-IfX-z;tg(-qn=5Oiud3Nx_7|o_ zPi4=i2|-;8_H3XUcIL4;k7wJSk5{3h2Q>G{`Y&yu+|bC9&`4)! zWI_(e*HgeUXi8+t8-x}OBYD$Wj9z9%AK zf!r4AG-t9&3V(=!W5tg+th>eog)fcFJc84{XS)`}vizAiRQHtbzV366(Ts063FB-^ ztl1lTN#3!n+N$`=*FD&5ONOJkWVoc$iV9U%i z;GI2HNHF%>Uj`(Smu|nYCr5D#m*WH-ue7J2C!)BS*^%Q|OH|wJFl)#^t38ElIA}EA z?JL|SM%HJDj5DS18zsTK?p1rg@35FCvDSXO=%B>OO0_5T3wLUZyYLHfLjpv!A)2mY z#OV4&slr}+t#BAsqXG7HPipruRWF-fz;LHb&#p)nc}gVQ0@)#$EjNccK|T&32_G%` zMXH_xpOS5U@Gz_5t~spl)I`6#?BjMB%cD!hhv9OGi_OlUH>#tLC#Con4*q_H)NMt! z;q?FJw>Uj{`BH0!iqz~!C7@=i|0G3F%)nLfj-ohY?*uLPEVfg{G~*ez;PvLYMONcv zX#XwN^k9OnO-#uSvplHFZxI$!R+3KW&1neWZSbk}N90FD6)~DnK35dQcrsqb1tsCx zuOb6^t4z+)xz$0sV5{H0Xq)19bM75ZWg-Km%==q5_F7so<#K}bsg zY9hlJ6bMYXznvc!fD(HbAe_ke%9-NiWyaj>=vMwAwrq~R;4z99eq&=HnLna*dZyon z5*CWx`+cF~pEEAzxLajN#E)knAIAQhty-xr`mBb9B#58IE5{rJo5fpXGMBz#uN7`j zX7J1N(?ip_&q>_wu=H?Al#o7hw}D$*b;-I^<8*TNP(EnzlXV*Ui`R@Yc_jI|>{ zMm?^OWics$>$N|FNFChTwRF3E9PCfvh%m0yjCJ9OG4oewjZvwt@F;aGtj0#uA&Vp0 z*g4&0sWhNKp+FjG9#q8&)+7pU>#jq7v(_(V@8_gR=GPahp<(|<3@|Mv_^*kvx@9r1 z^oX*^OKN=;TsWF;-$I+sIGhB%q4%P4n{vr*RCM9Rk-9Ydg=CI4G zZpf5wsKtt+v*cRTXshv%`yrmeTK_NDKYrFT&hgZ7f0)e&NT1GbQd|0t{DPj1i{klr zd*w{Gw+uJ`U?(#(jm4JJLfQV3;NHvq-OT2((jC#kac;^iWVcni%cuAP@a7>>&{eQm z6MloYrY^->5*>Ecp<3GV_Z71|8z*r@XXE=Q~r@|8QW}F{>I$na}htGhx%&?^yLVIwh&|B>zbyKHfb_4UQD{rw`FxoW&;OnC<(H#7%$L1)N?ViWOMn!5z6`kc`_C8MzGsDL z-Jkrx$RxEdoIdA`Wc*R*CAEWyN|a3{DD&*Knn5c}|Qo#4@m~!uZzM=(f9C%_WeBV${VLPQs<)G>&6|oVgj3y8g^M z=8JvNV=7Nh>ghB=NhQ^**_pX>VF^E;)K_ENhS$T(t`_%|h11WYW=|nY1xJv*ndT%4 zk1Ub`j2?u!jj=_f^AxV<#-q%-qsiv)E3P0g9#0=6S<$u>u*N#g6C~#t$tgiZ7ZR;v zG9{+?;L7aLuFSP#$hn(F#mltE%X~^=-XkWtE!`w@TU!=On&%|9(ZkI>C#t<)y&g{^ zEuuYAw9~vy(%#V_?fadlEg@}mD#cY8YiZ|3QboOq&$s1sSmJY=d=@4?KbOxwiO&}K z%u%0fD9WZAAW*RmtoI3Ck3}E3(tnB^WGO2v!EXSElVt0fBTH;R#+nxlQ-_mU`l=M@ zQOw`Us&TY3agRA}oHT&;uU9yP-5XzQHi}b>G8qsIIM2D7S{A+}sG4w!anZ7=i;sLI z+ct#9;CYWHbyc?QWS)sU(|GE5uIIUv=f8N+$)k<${_p$42~xMLwt4yg>f52}Lp447 zq*BqdCAP8*r+K}6u;S-=u&dt)3vesEDeo@UL32LuaYgUG*37F{`$WHL`S|{sF4bcs z$sqXc_TX9w(xfdcg0m;u?6qP)7TnXrUKi!XXN*@CN0s8UT8vJ@b8^L>7~cMeaA$>q zcV@JW%7%<`{7&KiOZ53GaWG=zvp~2Mu^o-Ak2-i4=MH$hkq}~?t{A>_=8qSb##3$=3|iv&R7FN{}5LyMBDqEKOp0Z?GZF7cveLh6!h z-PkcfgB%19SWggjayaLF6gJ^ezh%F5m$_sHJ&hs(J&Kg|FGARs4abj99!HNczRVb2 z5Zr3-<|;6T4-UBox2sy#Yi&=Vgf9F^mC*$AVTd>jBHS&Utug~pV~!#}vQqV(9`X<6 zJvdu7dF5EX9_e{vWnm4mZ)k7-NEu>dd18Q%XA#RUA-VXD;Z+avRrv*?>~%82N5n@M ziYrTs9^P?`tY(@qC{Uvd4{eREZ)jit$uhcBlQgzNl50}q8?QwTt^kT4Gf|saFxJ&F zG&re}aZc2|G5UJLG=P<1&CtVI^PUXr5{C5%^8*N~8rJBO|B4~i^SL)`5W_)#g)2Wm zi)zkLI!M4x9&4%Jn*XwvSn0P(`m+6{@5ryU=|lfZmjUl#d}(~as${P{hiRwHFB1L% zyvFHB7FVN@an*b2B`$q9*(^GT>Xp96Ub})ko)8Q~S#@)nm|w{Hw1fr3)?6m5kj>or zOQnFT6+XngOLmSzc5*lwVq)x#4wYl+r+SPEu#h9_xF}Wr348`RfiiZz8Uz0TByZ^2 zGIY1T&{z*}WSI43J7Z&v>k0c@u2ZUe0fNAOk)R>CC>HIY;S|Qz(h4_RMYV!?llg_9 zq@#!mk9rEsd&{gwNsk#pHOzwo*IZ0TqW76$PV>SNl+t15pXTvaohU^VL6q`0v_iU+ z*Ub|;mNJS`T=iEsZ7Wf28k^wRNSIn8iS?1Km!jGM(*Eqk!ZP;oz1iHEFmip0%G%a(NF7;z0 z=q-zG>im8~Lp)zQMi%JRrjDsj+Xz#|kgiE0w3!Zxxfj`DE(3D^mHUs)+zJs|I@*oJm^ zGf|0?;LXV+W$4B5oT2~KTYBiNV!Fv1#T7vm zndmR*zpNM9IwzD-od z%Pv;|ioGWP(ee8?IFn@U9cD;e;B$p!hG%dnt6fH`5TgVCVYu?!C6o2Ysm19shSxk+ zLsn5N+i|iJKSf=qDYM94`;J;4G%NBd@4lh4OYF7HyrI9DQ{)Oys218O=Y+$f>LGl~ zVRc98O3Is>lP=Fftiob7*B@u;S*39J$r&ALrWD1}BDY!vIaNWj z;LTs@9y-?<7|>8ne@Ju0CXTl3L3*TBECspd#jKi|3Hc2O%zmR-eG3CzLVot*SLg|h zBtIoeQ}{_@ozC{3PQ#>C9+4Y~V(sK~B9K5wiW)@CpxQ=>@s_DFSd4EUNb_{tO4r&) zt}vP+y#?jv9y`44FG}Y}fnd4cU-Sy%b(P}&XnH87#5j{i70~2$j9|H}XETy2xJpbLk_$1F89OA2kaW)`B8{P!NYx zq%)FI&1~y-fa`zSaJ4l>9+s{M=e&uu%lv2!kNT@QtcocDHpZg##QY=TdAjPbQ#DRf z;n`Fut1GQlbxM;JS}snsMz!Q-qe+}24Ce;M;c9SVYa`Vlx6IHxsoqsT8(^Y6v(T)%Vezi7M9XA(YoI|{yoL| zPVE1j1^l96PvU=_7jc&cQrkS)OPo`N=myi))x5JCHPc%%ZZ>~s2$?~B$G+wnS%}0Ca2_+%k{Ud3;m`c(;`*i<40Rp*Vah;at z=I>|dhOw03k4GK!(#+CbLZK~Hoe(6wXw>i)SKB0O=1zvHX|;{)oD2AU)Z)=$)ethd zUuJp`D??ydf+!1B1mlOVRiqEPoMk?AvBkF}okoLOR(hCAz_C>EueIOhq*5;@mGR|7 zT_1X?wUSJem83GUl32V<=c`Dia58gP8{(_NM-xcJ}j)_08TzsSmPD~EdM-*L)u%RUQ)&Ob!wH!mTr@^x@uXTA=kiJs8-w#7t$ zx0iQ9 z*n>tM%8uMM*&F*%C|ITOp1ombS6P!MhReVGgZPaOl zAg_f{Qv$LN%XAVKC?^<7jAY#?NC=9ueLzx63SMiacB<4`|365H!DloGTP@t5ob82L z?rgT)b3AHJn2@xZOcA4RdSep8w$kb=0Y4Q(RcNzE9HJwoIKhCfUiQ9IMo;t&otqg@ zZ2)$5pb&#a@JPUYlZ=KX0h|30>&bh!cj)QY|11I0(Hf*FfD|6}C@b7*a~YNo3JW9C zgw)4@myLdaKRuB$#k`l43fwk%_7Y%D9_;^t_YU~+yHgcnb-<4R8p)15tFJ_nS6B{|>Opu6bSX-yaQ(5?tX8_9ea5&mB$8q@62)~X3kVS;59N3+hV%*?dHpP`LH5V-hO_d&M_8p;&*Mg@7fVh$?cfhOF_{_eNWqOscH>J1ID+DuUm^Mk~=J2@<|N$#YKl_YU8c9lqP~7o;!h z5Z{h|6W@-Z;JZEl(otW_>Zp{GaVJ^Xr|6+EcF+mC(3poExy!&_Pm#Gqh`ADz{l%{O zfr5Ks$IhkF8*9z!9D_hw$`n@K5n^))_PV`?OjrFNouyG_S!I62n%(eo!eodG`DJV$ zBrZJac4o?7%umKkeH0?pKpVFnvfnHCsfh|XtWM+G)8V_U!*^weZ*7*?mcOW7d^r7X zFYip-0WGsG73;|D!Ec7sFP0TKG#)9-mD^eVyyX1tm``f>PX5Tk z?bA-C5>{}dr%<;VUumP)*zB^8XcT*|*f|B*>gITwg^&qLfM_V(ioWsafH)qPPhUUj zfaT}?v*m04W0o%6e3RWA(cPt2^nt5^Qhdkl^l^T6h?W1B@%-tD{GlB6zCSid)+^>m z;yh2ilO8fZ`Jrkp3=MYU${u{T`ByeN#gNcrV4x4}I#%s3v3bh=r1=mV($IFNN&v~h z=0TVQvka1_jSU+x--w%eB8HV{oeM*8XnQ%G!#kuCc)J`3-mkiM4)61d1c)(l*1r;7 z#m8zVv#^Y~>swlKjQ=RnZ!FwP|0`p)#@I6DNn6>i!rk{Zi)4#fjle850zXjaArbJ` znf>-{5A^AEvoR3w|6!P!9;W`!Q~a+&lotyrU(`|@`kL{+IKGe*U#ONNXUf`bU-Sf1 zj`i=MY|<&~${)8V>&iTSlyxP$`^~AW;aY>X~2e=A1Tp_v6}0Rja=A}eK* zx`dxo2)D*OHH(v!aNNmJVi8b#DrF(p1?EvuF7*4u7oguT&SkFp{}y(ESC7w_n`e$d zTUERZWh8c8=VHP$Q;Z(m;jt;^ObDKoO(tLI+&u9O@dQ~Z>~0FfmxP%`Ug3{D#`5M0 zZO+{e5_jqHz-R!VXvd}Gan(OX0p>;)U|0Rqx~x&EthMG5GDO%{$aJs02?Lo>z$ud_ zxn(Z7#H&|ubY^BJF{yzQJ%(`)U1)xD5s)wUg`SkJeTu-rTR!ExjFeD$S|7ih$+%61wvXh-Uv~LKFWEaJlde|@8b~mulLV?S`$`e_ zc#NRPz?~y}9932$MH6H@+575Y;N&D5a<<_?r5M5Ft6%vRCYNOVLgs>V$r^imZ% zLqa#I&^v_Y5aCr3*Gfc#ju09{M3IUR*F)w5Izkb5CkhT%yejB7hRlogOg&J1B^;8k6-)_4AE!C)gyFy2( zelt-CB>L?&(ui>Dkpxh;gV`hMv?HuQE$=^jg6ajjU;vQMppLMo+PtEGP^Q8Frotq` z+D!%0GGCnL2j$jODCsy8MD9OO)hbT$!`4yHQ#2I9P=<4=o?;C8VWwkAw1e3o^NA(l z3bx6vH?QffHf}L%Q*x~3k3f2635o|H|KiJp4*CxE9QkhdlS$`!4%Oa18UAaJSG}lw ziqM9tawmQ>{rv%1sWD@YPx^B@qiVD>=J+XZ7_SP&XdY=1BtZUdfD`hA_J4PN{F0}y zoT_ejc*Z&$-x*!l{fn)DjSaS@+ZR2862})lb88A|?&0?JMO(Y%aQphY*!#YrQ**__ zX=pPCJM!Rgq#POXL*u zQ5|Vv_HiomaTWQnOat>4;*~J%3q7n7-P0__)i8HS&>17rf~{%(V}q?3{@gQ#s@m(s z2D!pm9qr*-(wp?r4C`VF<9sOGB{17#bG6JZJ*CbK2r)Ld4bf)2_X)AIOlJm5gF_>V z>ZM{201($607@$|&$>$WKoKqtTuQteTZDY|Dz8a5y&T_*Nm{zxUi&p=gs?QOD5{s@ zq*!{teX+iwmzUXV#pzqU@R`jS!d~q&GNh^7259w?zd1uvc1Y83nZ&sBo%iv}Bz^V? zQO-P%a;DH6CB_t(KNH+Yun(hXM(JfZ~9Mptr&OzNq9f^`;MIp;i6D6Hw+9)Y9 zEjf{RH6xKHk!X;)1;#NloJ284=)@#1vD-+B3WLL5 ziFef>Lj=gDuyGHot=kxp?FpY>ZH#qVIBEV7Qi9jQ6>Mt`GPh#E0AqY~1F8awUt`{V z-OgBZ#b6obh=;=P78)rNka%on3-Wi|241F&)qe?L|2`K#k8=%rTnLtk8n0E@| zk7eh?{}vOjq!?Rbx0p;$%C9!lQBJa8WJ$VADWO5-tem5cUGx(n?_9Y^RvtFU0L5669R-ph;6n2G)7uE0Px zJTvWea-IoGW=x9KnkQaO9i?-fuJFj1$37BgmXr{^!dKejvzK$D>8`~-L;8c7g_SQAlI!gTsOc&zq4c;GMT-}rg7c^FZjuf?~c@>J(~ zt6DMt7RPJ`K0Y>^??N(_d(c{0XOz0*ZC*qedW~O?F}EaGlga-2$Ra*%{s9fbcFT$> z8<72B}VSA1N@s7I%OFDfh$ zn{E5ZP2SWMK4Y1A<0J+sWpb`Bb*F-+FdBH8K?q?jdh3C^@Q`AY`&&6(k&ZGSIZAc6 z2$`{0yha2>Ubshgf@a~Nbg3ttb63lbn0UY{$j*_o=C5_nv9zJVvu*yNiSu&8Qqs#` z{6TtI&dc>O{|X}}m&MU#nsryGB=#BX9VzV?{QWc;BGFmuTt`vHA1Nc+cMBp&pLkw7Ga)G)VEP9VI*%|$X2cTqo7B5xTme}i7(++R&EO^PK zyaCJ5$pwM&6zHTtw<>T3jEwnrF7YHq0Rp;Pg>VdW0seFyCWE6u;eN zk$$3C2u%ioC+B&GUQ!S^#miDiv7bFEaNZ!r-bJzA&%lsUVvq$Xg65&TH)l}$OHn7$wiTI{L)Q8rL&1wtmcuK z0*4Mbi2#qjV}25fd}C9j4#j&cSvr2Y%@jQ1i-vAnSAs?1S!Jx++XYEyDun-XKE3S+G2=VBHlYP16w$Y`w;f(FpM%=Ex<|E_c%jQRX)tv*b^)0C6^-@yy7Wr5}NGs zlx~M4Z1)+v^nNU>rPp|OKda?v#mlJGQf7GDYB}yay;^!wqf)7_aA)9Yp_d+GdE_TT zlwn-3xJ-iWUxYxKznx}RgMuM&xbkxNSF^otLizH3tY>5_g5 z>6K~DcWt|#dL$<(U_RDELGCl&FBTsWk3EoQGu~rUbPRH+@u_*IQm$Iy7bqJE}>yZ%kqnCMXw^np?vV3gltzNuc{lfkrX|Jg`8m3LTDZ>XoF0zu_R6XXa2)c0-KDGyZ#w!gX zVVf^>k#3mZ6(evlHx!2FAe6USKij*lcC|6_yZd$3U$WwdE8Wyv7WSCt`AJomNX^ox z%FPYB*vJ_GaG<8DxOjWjhBr4{Cbf5Nyo{<=f6GN~ALw-9g4yv{7LSX+zHjXv3tz5V@f1(o_PR*MOHlT2rOQV znq3Gd*A{`Q_B!F<1z{$J&$o+RiPINWdbdnBCr^|X=n5!eCW?#3 zfNSVXG!&1}itza;DAt)baiB+Z4=>U^F>h(J*IwQX;$THB#e)`He~Q6_)*T3lq!H^a z58`mE*Z9KHUwqSEe}RNN+9@tQ+VmHfjMhQ!T<6qCN`^P_2aLM?` zU^DbcIERK^`aEW)bsqD93|*giz}}3~#k{6M^NoQVVWmVBq@;FqP9-i8UA)a@TF>&M zh8uuK2*pnY$HF3K?Tm=8iEu&M~F02Kpv=#UEi1v~OCk z;mPx+!Um#2Y2vOX54sekS6|^R+~7@p)m!>1lkyc`;Yy@Sf0oy%EbyeR_k=jT571t9 zuJ4d7RXZO~i=R@L*g9#mc~!dAX*;-oRSC4l=HRe&T!B7-(9448Ddtkwud>umV3A^# zaR2f~%<&dM)^5fswwhAiET6HOJSNpt^zrKrd1D|96BvGR74v9ekVsEpM~1X*LH9JdZvt<9sg z4f*ZHYMnU){coayhc;HyrVit!`StTPub!ftW*INWUV%+#)E4gf6?kZ0Bquwyvd;Wa zE9(~bRm!>_^JAGVu1lCMKFB!8x^I4R=l=<2=!SWklZB!KwDT*LhP> zH=;rZRr1C5%)vFM%Ir)o2#wh*c0?X0nKC$wJj@$bW|80VtAG$sFev^6j&mqU&IJ_T zEn5HSYzB+jq?wlmVJB!k8J*ZCQ?xr{z_)xRw1!;VZc(^?EzcVtSF#K8!`U*0Lf>&$lu zj1)_TU@N0FK;D!Irn>F}3z_zom24bD#O(+7h~!1SMh_@ViT_BE{xXb_MPe~It0?jz z5sFEOZ060Fl^=PPUw3F^eq;qNJ_d0No1k_i7&-)%@MY$_uXac{dm}6TxoUIREf-_1 zHLHkl8>7=y7y+y@_nFVeB(OY>;cgIj*phIVDxthcIS7=13lI?^6R8heEfQSyDPRhk zKJOmtXRrS;DU7cf2l|c6!*_kN!`csRb~!;OTilK? z>{$6Tgj0Qr#8tn8C~mSce<-vW8i3=woJS=AywFbK8f1qrZbta9Y*{pNhd>E|HeseP zCsf9RmQi8yuIj;P3)=h}Z2LM6ubg$T?u)u;SqJ+;*<18fxr)S2>4f0f=>hDi;>JqD zx(wiUx+1ge2bejOYa1oFsZj`(LSHv77D5=K0P}g_9<<%z3o2BaU_Puvo#x_`g{XAV zMCCUm5TbGmu{8a#+x_8n)UW+hc=fp;U#Q)IEU_D&V%h#R?M?Ji*paFL^JZFYGG+WU zZH?R^EmdvWphKPJ^JrQUZCXJB*&2LGVj=AZQtN1a&PZLeMi)BsW=g=iqt&L7Mhxy| z64VZ9Pwgn_I8(< zu`hPW(%gx?op-SG)FIg0b)%*PpoeO2$9!}O&ZWm;-|VUK76o_5#7AFwNw6e6(A~1O zn-lA=5V(fD<2V9;$LQ?CZzbIi^o!l9w|vHRMd69-k}d2q?2Fz)F@=TQ{I}q=I0ch* zpQ5t2s~u?B+u^q|(-!E?j~tP`5cQoldyAaNYiH(e3khcl>%`m*ZbZ&2jn$qnIaw{( z!X&eqyV(+u4WDn$Ix^DC@aO+&n|5NX1~l zQ^JJ3PK@u0SDLpfmd{={PT&)Ox@@PL_4cSgkNjpMd(j$db31~Nau6PKZRZj-~{jpi6iWsfhHpk=oz8#5tUD|k(^F}u(u1Z*y-&{pZY zFd>PS&0-f-0e3mGzyi)*HyI`;0m6zn2+tV;LbLgbSS)A|%GyAvXb-}hnASDSB&)PS z_N4*%1_}s|dJHCJuUSVS?A*?yue6zza8VB9D0&oz%@un?1T)Sb6K`b1R$wP-zxh_S z6(gf$VB!T&)CC`(DEL@&a2s^L4<$P25nhuzXs8(e3EfMSG)I^8CausQ_BB7i5H}*b zM~Or?=|q1`B>I8*f+P})w3uW1UIs3WS84L?{A%mKT9x`+^B1JFx~*FqU_IIcc0Xh) zQJpB8>9+Djb*bi93W<(N80vjCN(MSZ>Z}+Ho?+jBlolPBC_-#SD8iN~;vZ&riYVR^ zO;`J{((5@%y&mnNCAvzzp9FJ1MHX+_ZW0QA>rf zo#|90$MDrQ@NTvw?6qezbw$|4oHB+u-Je^k>=PQ{z9gT=-qW35!b_!T(l{}|z+F#C z%cdV}34Ykc{H>5Ylpb=;0NVK*I(f(GG*xl{M7Y; zekv*iAw3f*6I0$CxSelq&LhCS2M$3E+Z1soI8iQ0I7PPFf-hAwl{u}6wbi!oH-Lwj zTSklB5pim7nZEttOEv0Z0CSaW&wq+B7A9mIxOE_#?yJc1iIEeEEK$_mzN*rfDgN}>5>a8I>;(aXYVC?mG@>$P6&vL7kESQ%2_>7Xmnv2>^&;=f>{k;$G&0ZL6X!}Jb0ez>loVnMi)JaU z)STZ1Dq4jS_e~l9cg*xtxxM=#l6i6e!%ku3Uf%T#6SPnh(A9E9T6_|=O*_{WDKhP3 zN={MpZi+SUw(gX9XAg~&%CS!i%G~<}xTH4HA|>rAP}$kGmMJU51_~tqcykJglX)L= zj8G-c=}l=Ts?sVFrF}{Q=JFH;XiMZd$V)P5SSld8LPr&@xS~nFj!09SiK{*xA`;0H z?UsJMn%CmSg*8s!06BOf`{-PZ90~DT+=xO$7iUKO0taw9GnjSI7f9W)G^Q9VErdPCU z=$eu!H;oya^h}x|6L2* z&gqe+EW3IoB9mS^4NQvf?KtY6q6q(QWs1wY4kVL=J$_Bt(+7FRwg8d+C6Sj?ABKLqKUqe!2($Sg;Z4CzxBMxqXZM{wL)BkGVRKxT8`K8W@2ujOBmE0z7V?l(Rw!r4`UhLP`;QN{wpG?kDzjUa#ZMuq3YkdzJsM!~ zr)~Rv^K{kRk+BDA^v;b8$u%g4^wFO{uF{MoZPMZO8tJe>_&HG-^_1Ld3s2AF?>qsB zy~-TwNc72}>Q4lITnSB);cGH297w-;Loz>kfw0$!t5bq=VZXA1a|d&6@5MsF(YFXq z#(h_M~I<8P;IdpDO zoGgdRPZf656LYNk6rMwF!?M1Y$@dc5f~G;okG=F;PyGwSZ`k(woqv17lj0g#HlYVai<&-k^r`;r(iJtCfeG%R<)_XYf5nRUil^HYC*7_V zGl?lpeN|XdVNI8+o|4LAj#vJk;6|^RC;hV!oK3Ky|BbPh;EquBDTncVMcYg~xVJdH zxa;GCq8CTPJ;v!pd@dc3GFbMHx^(lu`^Nbphwwup^(_&h27X9Q%6cW?9AJ8`*80^? zwkc?_b`iq_@V6^J$PYgj~Up&|4b=~?R%bB}qqSWOsIB%<lYhBQjSJdCm%U+oUo|+ZniB0+gJT?@X!rf>jq#Isyb7)Lz$sr+vp45z?qIlUur9(<}H15=4>%ktCZV#w)m$>TULEUTgDVw zXT4Ik0TGHf#2o8&$dzI&bz-mv;rCdzXWxw^F-HTj%_9X0ehO?0 zSmBX@M;3)<<%c+3b*f4#2No0C`;&{J$0^Y++S{0%A3cJU(HvuPK~uDQ@WT|j;kexl zN1;$gw~0l>)Wt^u^1VERc<$i2ljlL6hk4H6xsE4~N5Z&+GK)Vs!jh3LZ~vOVu9=;e zi;R<%)#c!(?O{umaA3n}B2E-pS2DBv%(x_&!lc^b>-X#LT4cJt|9#mHX0(Oh?`C)z z?bR_t+D1Gz4%U8-YV;-{@+glwQ}R6mRVO4Rc_7R>EIKfE23C_C|TnER)Vo>`mD zzPD9ZS@Kf&TI8j(S#l0iUV48ExerlZ8b}?9sd1?CQhfg0B^AfdLo9{W@#BJQgTEA; zVYs%9EqVsVSECjFo-s$ahI~G_xNB5)}83Kk^TamWHvh8uo=_n0HF1SZpHjb_Fidp>00Y~>0*M~j}|ek}Dym&6?R zk|vs^-@hRdtK)ew$3^e3CxYdwQeBCiom+YH`1=gm0&Foq#FC-mCM)`G0VJHWUd8wKm(h63G4O99uNdnS zBe>3=7jr!MEF*`0Coj%$vQkc77ITaS0*m>t8`;^nU5@?s zSo?^?e9cQTeYj_n>P)M#pR2!dBskRakbIjMNHtv&ZjZP)o@i9j$ z#Fw%j<3n^Te?TiCP9^7-oY)+i>*Q{y^8A?NT#E9Qw)&4X)}c?fK600khZ0WL-+`P4 zSy!bHKUN6Ak8|Tw=6IPV4dTnJZdd)K{Maj&+Mih;bMyg_NHL}0W|RFvfn)`&QEr2+ zObR}afJiT*RlzYwg?uZgm2>l%Iy0UAQWref{FX;)6CBd^aSLI+l*Oj zw5u7lu(XmEmgkr4TAu08<9`>lMRR|OaS}egNZ~g+u0+jt2v16bUs7k~U-|zVp zozui6?2rgZcS!(|xT8U3AZnKrC`TCt>mfr8%CNaYXPFInW{NyOHc8c!RId8V`HIdR zBW@yOfgTg;8Ck%uF*iRtH#9RpdVTwjpZ%2X_^t1G4qpjVor_G7`YVY(5{D7`ahY!B|SnA(nX~Z#}4)c_l(G~ zE#rysG%%sg;BoPc;CY_MJ`!64e(U*_c=+P(-BV$UQ!~1z{wr^2m($z({@Enxf0{3D zPsRTCehL4s*lPH9EE5wfe4IgvuV4K(f8#QbU%lXC~;&z1NYSruDjRPk#)J+VkAlX*BCtO*f&n=gm1F@@!2*)b?7KrFSp&`JR zr2L3qGTuVQ@Tfn+$96OKvdtEquIwJnYU}~vpV@$oUWBb0XYE#r-m219RbsAYci&_5 zaD~&(_EfDm|16HK;L-+rj11O6pV2H{eo`?I|7|a(hmm36$7pP(9c$2@DfV1XuDz!> zS5!`w23zupyXj$@)y{6auK1@u+WId(m7O%!d}gicLaQs(6}ucb(Q?1qZydCjnx4 z_D90C$;$v{b0s=`kw6m>H_%BFp?}jrnet!o%(!<1A0r zGEZqUsJK^9@kG1|_4OF%YgBwsP;qciLB-=d11|v;FUgD^=Yi1<^fGQNLhYHCz_&)U z#$@hltQ)>O?G&ac&9qZr>P0YsTMivuXyu~{- z&wl5!NRW@v)kV?yE+bFI>3ZBHaB46k`cq|ej1#qU>TC*H^1vsVbo|s`pv&kCmO0`=5d{x^H z6C+%fOotW^`7yRLJdg6^(?brPV|e=V^ygVZ_+Fm>vf>l`c1G8KEx#S-wKKcL-}GjW76IN)7yFnD3krE{SI8-`*h>rh1?7a_sRMnaPADAFfq7w_&RH??2YHVnm zcF>It)m)f?J2Hb&QPKJ*7DU=wr8QBkfVczI+3Q%_+HL#YZr9zf-RX zO*>426AKCK_Y>`RnZjYDhTX|@B@3e5-9bQ!JUFLmb!c=Ts9i52@H86m;12UIJziFj z*&O;W*JwujBcZAfohG^AO%F9j=K09 zWy`p@nyPY5Q$sW4?+C(($??mEbPfK-#hY#$W4x4vcQ%%Mp47&%)85y%@SKv?m%Z(B zSoK8Q863ZQ?Aog^@A?q2+WyY`8c9eIL1~_g$Rvo5cv2k%pbuH;>>HYu3{yP&I^F|!MZ!7-&Uj4Ba55r}cGCLZ82SR-WgO8h2H_)X8 zC=kh6423D|ZwV(thYj^HjkfiDe??ed%XCx4Md~U8JwXo5$HiJ+go6h7_|TTSuFK;uG$8knKbF{P_>QP`tE*hnqF89Pjk+yG4KX9R4f*7Cs-TUEw#z z)6rij8ei{qJRO3khdM0Owa6UCb4>0!ov^PkCftM#jOA5ehA9gC5`_xbXo)2RTrlgELSWEtv$dQ)F zLP*CdCjH?gS71f{;b#BO59v6hePda|N3^}Gc#fa1wEZHDz=T038z|o9K3*5~%_HoD z51Kuipo@Nev&nb{-e=zkgNM+6Lz|&L({V5vt`cP4ygqu@3lbG3Na6CowLuEMxCR^a z{yTrbAA1}HlJsL4{NOF4b*3+|_v}9IVBNZCJ(@zi;hZOgmzK8@7gmf9kX$DJDKaCu zq{#&2Pc)OxV(AtfTi9RZc@wcO`@f>9LF*ulu-zY#*^O}PpTYc=G|j_^eHve;mFMyA zBL2N{^|2+7^6w~~GyE$#O8*-&^r%S0JpJeVr*v2-GyW_85)7DkbaLB{;bf6G)%s=? zz388%_3^{_JB#9x{|~Fj?ue@<_s0n59F8E-Z=u?~bn%3ax7{-Wc(oL!qsG()*Zc zR1kk~F7eMDT6oIrr?O1jfXYr+Wv3Na_WnYl4UFEGz6sYqE!D2~=evP`iG4i3+3lRr zBo_#hZ-zt25CjSMj%szeN8M0nAY({6!#eP8N$r{-fK}vy9}>E_|n(V+J2Z!W*vG zIS}Mu`>5#^Vmwd(Nj}E2SzGWl4`?Lh0{w-c&$KtrB3oT-le6TfWYo^Q&+0!D{Q2y) zaBbLU*{a9(UH`(-Uv^{d?jyDP??3qUeK(GGv%}pb4gauu(c*u({!ur!U1{r-!W<(F z3m$pp?2lgaxz{fEiM|l|N#2cr{=(1hxahbG+1&$M;?<4j?Ws4MTYJy!VSmM2n8f}- zQwq#l@|DM(1OL1ub1Glz+$Fc2wqWE(*6#iSzd{p^-8Kp-?cE{{{;2wHbw+0SoIgp_ zaxi`e^@j{u8u0hd-BkIjh5RS(y`J>8r)u}uZIJ1PmA7zgRa?uaVREyU5h7jwn7$7i z0O7tDhL(~o8Tq5zdDm{9^uJ{7vv@UcIn8*zw`6wTAzVchd)!*%)6@nabIvTM)P8F> zKNROm@h-a~BkTR;2PuBY-{?cJ-jJUYk7vE4hbCwWcN-i+@9C|BgKxZWCJhmuNIxeNTi|@+RS8;1y`m|j3L3roE9jA za7(e?FkBpl5t~MNVEmM#E%6icf)g$mRqvs!r1zn;_w~x8H^EJN=i`6-I`>juQI+<- z3<=+;OMBm7*Ws5Nm1ho#n)JXD@r3E3?mkn%gl0VpM!cV`=Y{rpjuJQXa&Bsf(?~c% zW4d93-py5Lbd$Rz5ADo_Zb>Sl#bfVsHx=nf$4Ga7^#;mG#Wtj}_f-FsN8!B5T^f$8 zWc%u>WMoq+`-|!>eT{XvJU*<)_Ab-@revf|Rn?~=UFit>Z+}$%0~Hw|yx^hgHXhTA z!R%wz517Y|DIS;bNXZrIq}eI$q)p~ZKjbdWk6P$2b7P`pBRyi;5e~*wYLKLM9#R=erQ?sVjZbnI!qahfKcNlF|^$g6T!q+%R3JR8q?l}RP4eg_#r-2hOLk7q}a-Iq$eHmQ@PUNN?VtXZBZLi*-_QW+-Q1OS*N>8 zLurtT5oNQ_6cO9!s=83_z)&#~1`^Dh=Kry6Dk)7VQ*xt@OL_;~*nT&%g?$_D#?Ew% z-5aZ_(z())P)9npm9&+~+}IDf9+3oYL^r~CE0Tz@_AWSzn4(AYw=zj3mVb4e;dnad z{ZV2nmV(_Bc!4c2WeZH_sy~#9JQ%?3)nx1yw|!j&*^W|CH9=7*1EPP`Io|zNsPVCp zRG%&sUT>(4v>S$~VU_8C*ydE^q3VU|d++UJ>nU(v_1v`An~uGbgxo2)(MNG?vN*P}oiffeWo)udRD(}Sd)w2o9qLUu z$nll;8?cIr)02@W-N-bJXPDU`-owvS%cIwmAjI%L+Wa->@$QxpR~K z`kW3Pjm)B_DDKphw~yk|s%4QGcR|0qLD_)cK*=yO8R>BOKdjLBPvIPasxr9b=1M%DqS`G$2rLvpSqvdN*ubP9biWZ$sYoD_yxsu!z!D(QIYqE6 zMX(F`jQu9tSsF@oJ7Y6I`!o*Q&g0!uD#%N6roGqR38We;hXJW!CA~h|f-@ZHNI^5w z>wu+@(imW~p2m+3X|#X}rH4TjT-K&@W_BMfA!RrWU9nD~s zbV8Z~@VRbekyRGtuE-AvBQh*pUCOJ?!xfkUO(UTMz5;6*2?fR?^+G`+lzY#BRpmtT z4+>JC1WpHlRDGgh-~0{;Ev<&aB7j!OAhsedS2_Tt!jn{+XLNX|#uc>IYTCg>d>)Q|>^VHWlHN0vQywl&Hez1Vg{EP;9E0nIXjw1%hzP;eg7H zz1W+GY$>7!Gdee>JPj0h6UDY zO2zh~AQ-4CgJP5H6thxK@CNDWQ0>4Xbp%nY90f^kSATw$sYz(su(3LRWEY&6X-57gFDYo6;J>_9V0wo zwJCLl$}bB99>t^9^}3NEp#qJfMyS$!y>1HGjC_R=ph*UWQTw5CR?MjFYtW>=i?!#e zW>0WPWld-X)TwBLvVgNyma}gHx1j%^=Po3y{K*XjJy^#PfPq!9RdHE*XRlA$sPu(lj(1^WxMp)cOeK2%lX7{UO5C z;B&yN>D&-a#hN}ZMeW3!;r^J>cm3hn&kEHfK0gTwCQ1@AQu>Ak!FZPd3Fo!e|8N*> z&)CUN=m(iAh3K>v_(Q=wQFD1KGV_`p&157dW?}%=Bcs!*`9OkN!FuDx}SUs zOD{%fTYyktz{q~lg49lydXnvHF_y|B1kK?Ct3^EHAThFe7b%z`j$*)L&ZQz&ccf!4 zk_Dd^!N!n<-HH1akDQv^Xr^o%IRhY^OW;(*dm+DD%6QOZmwm(-=*id~48lqmAG0+W znb@M}56C4%ql}`rb0t~(>L#N?&P{pNkEo^uZZVo1+k+s(Y&?i%GYBAU0Sp{fjVdV} z8`xh~E6aA)=q)bLrQ9cHj zbf1`4hh`6q!vH>cKa+&^93wv@HwM^+*2$nO%px&p@I_jg8I)Tuhf=}l%!|)O)!S*4 zRH>k3N2IYkDL}HgFry1)FsPHP3k^&Zrg4{5AtV)?JzJ8JUK#*L2~SJ5u|v|q?8B;` zVgpo0ybNgaTWl72n?mVHNd}vN0s5k`>Wu+f?EXBQ$XrP2{X`~O2VI#LnZm7Phi!j2 zlNrPUWwET^EXkOlX80DHpha#_gr_FEQbT57=1u46W-{`sth^>;gg$2dQ8GEK^wqS< z+M>3{=&61arqDrdCJP~VnJgT}8Z|&Q6DG^+!Hv-ZU}qNq%ao%4So%4SD{(_cXsGM+ z_E|XZ3~f-0DR3k%yDVV{g1{(580AQe2F@n5l0=?(Qz1|>3K}(yqL&^pj4aqW`I(sQ zH0#LJaL5leV@8C~w4;T-53#Jtk~K~PtQu|tHR~cX^6x>@GiJ(-i{x;6KJ<$kq=qi1 zaO$DvO3U9T^80D|#=vYsGliBSxYKG-0a1ZA9$EBMb*%}@u{Jy zj*?rnpg{tj9BPP$Glqo_8#;4?Az#DHzA$C7c2gdvD5!xLtqG7}B|u=4NtPh44}(*L z^pRD4wJ}5uh?#g;-O0ow?<_$Y<_*zeV5$$qG5KUn+l#HyymVEMg_Drto(dsrie^E{ z&X~l`A5g9U%k*EE9VI!~&zGNy1(G$eBOWk>1U9stiXuuS$AT_t49x(*Sb!=@sXtT= zQ-Lb|YA0fv;Vhx>z>!~tMG6+=!IWGzWEF|l5U~9m`629av(D6tWbuqHl&*QG8pW)2 zf`D#=hd`?4twzgE3;b|GFSgwcp+c&Grr?Sg3`anPfof3hJyuxcCpUp>G@OD}Nlet} zKg|N`LW=DNQp3Z7EIk598;$rEGc^k_3y6W_9b}1#)wrwIM^Vgs;bgzLe9HU903jMU z*!z!qjGL7AQaaWxn~y0t=ALm@F>?w#3Cvpdh+U1KKv!4 zebU2A-J6Pi4dLA;p5qIDD-~Oz9!|xEz%Vz40iL3FYf{-EX7Hq99cGb(FooD=cO#yn z{i)b(jMB|+?7}LYR^8-gc>pPdv20V`dhP+iI`1TP8nF{|Dv~T&$GF&U;|e$SM$TCk==P4kF2Wb3tp&jv$&7hEn_EH`AbBTomfhwKalh$muDxI6YUQmy~(4p6Gsv84;;P8qq7r7`@j7M>J;5pxS9?wP>Jl6cJo5e#p4~=(Et3K||y$a6f zR}=r5+4ecdE3H0Dq5RnkOSuh|3ENqUNtTQTzGgmMWarig=J;Y|-!^{#%+WT(pGdi;24wAT$eXjQm#|_M}VfFxmV=>nISE=A3*Ub4(j|V`FCUu zN4(prn6t;dWT}O5+`GJt@OtlZ;=W#td&eudKJHyx;eBZo=fuqMZmT9P{2mJMZo|KB z=jtZH9`CDn;b=a}$>-fRHpNHzx0s!d=208g<5@zQC%LERawHDU+#EURXASjsD#&A z>3H);C%msRkH$L`XBjMR)_|yUy4P3@P2+#(ydv&BWSBxBH+YTXc{`4Z=QynBH0XAfIg@gw zA7eL}li5;|h;$?(U2z&CHYT`ZF#DzIcx*!g=T98(OpSBrUJVon--DC;js{yi_Po>n zM0q0eL?X74_hoS!!pG7NCA=+(*am7ScVf%Qs8OYilXKPe?Ont9Fp4rXh+{9duPu*9 zeg`kA6R{`5QfgF694Rx}^Kn*G$8im)2jfWV@lbtowzOJQRZ&g*+Tm28fvzeNcx@9ntbz5|Kawy@+Xhd6m}pA*}s;>WhH8$KC-jLNE1qht4*uBSjr2wUK|dJ2@> z$QQUzox^>eTUBa81x|yUEsl2}Hm`cD6WJK|R=2Moo`|h>+E+nR=|@c2Tcm5q0!c5% zBQKIE71`=|E1X!n6M3?|tBh=M0tzZ%&}e!|nR%>sVjY%imC$O7QqAQ~wx13_HjN?Na7un`Swvm5qTxSB=LV_A<3|*0SzE&90#2?6dGah-9{Ed$2 z>cb&A%89*U8dE01s+4UKLHBX5v^o)KcR2Sv)?o@zQd7k9kQ$FXPsyUBG2y+Mh`r)K z;6$RLx$?|1WjIW7B3sm-skpZ(ZdeIEN>567+Y_-Jw&Qv%m!^reE1;&*G(v2m_)+oL z`T~=xoY*qUq#BqI&+}ZF468aK9ndo#;J_8is(|Za41#nutWU(&QD!9tiiy?U9)6WM zvAz5l7cdK~1Wm0dF48Or(SMW)+}jJ?I6CaV39Q7c)UmM4>v3W)2E~*IOb5Z1@3SLY z6W%WP0tdtz`Vj=Jfw(m)Ya($>aj!QK+Z!|wwhp(f3n4YC+TsZ+XaG>uI3Jw{kQCnZ z$chLzh#I7g5>Re1?ZZ=Q$P!4KZ2N>R80EbU2-?>RVRSr$jv`BgB1@}zQSU@n=8J^g zKt9q=VRnE(+VcQ{l4inr$9ok<)qq(szd4|zTA9EI*fJn48wjqNKx|N3Jm8vT88`L8 zkRt#LYzf>0u;oOSMLKL3Gq%L53d<`XCLBTSmAtHqY*DwulIe!hbpfmFAXJA7TgWQ4 zF5(LXqpHn-CV3uJ3{-=v(cT^q74V1BtKpI9L3&MNhmd;885d{Wq{)JGl;bToI5oXB zmJ*daTUs4LsuYH#U{+*h+}kH$NQMPtQRqnEBBso;I6;eeeiPm^23m)rsxJ|HGmonE zA*$3gx#l639v8NGs-eK8J7_V1O98CrAY-a4aP^KuFy{L{(BM<1vtOqb3sO zmM;nx7x1)Apqbqd0OJ`hj@L^!Ap!u^YG4#+{ae{WI2|IZ5M-;%Eu=IgN(0v4Al6Si zyvS-7Rf7WxMvoMe$20y6f7BXrtF(YCX`C`!D{82;HfUops1mWwN@Zkez%lJJm~Akn z0wumeFi|?XVK3}Dm9CC#pe2$Rh_YgynF1|PBUT8?K0vkw-8m}667r>VG%x}tvAvXI zr3=Op1OHR~N-RQalUUX$WIf#vSyomFRSufaEpqrU=h&J^G3ishD+Uq47_ zj1|yT8WeXZx~5T5YA|#mZ~}B`#FROa&VczAD51QPq+lG555^&3@<7Y#*F2W2(zD$t z)Q`?Xm0k;>8jo!*V$ygqDSkLy!S*v%28Jz$U_AD6JhI7Q&5U0&(TKH)SQiB&MmHv6 zFY*C9Yiu={xIpxV>Kot_G7D9fstyn>Y*AorFN;`l_Cvt*(fKmEtx9cz-LaJxp`!vs zRe1Xm^a7O%E2Z10B&rctX0SCaF5$Hf;l45`&Oz`+sUBwwEr(x5>D5pO zg93}|6=>QCP+3ThM>tz!Kggg}z46Fi%D_@s7dLuNmckI}$(K=#k!|$XY$viwn#yJL zSz9v@=UuV^;7v$~K{mEatRpZkuC&zDSU{l&0X<3#acVnWD9hUl29%R?<3C|lODQH$ zf6XU3HMUsu)fMZ~;@+1QHHymGXhvXe^AS$pakVtu3cABxNWKvpl6AT@y{f=l;!RTV)RKQY^M7iM*AQanEGcChpPhlPm zFsB46%-=7u!Rz&*s-+IwUXRmOZ^rW$LE5^GuD&WBd)-B*|^hSqlC>U!zE@U#@;fpvjxTp z!0E@V=>uSO!~1|00!DK`E209O7b3wJ*2Ut*;vkPILyR>TG45t!ka=$%Dy*206oC{| zsbHsD6Rp@zm%V}hZ1P@%BXLkArmQOqup}VCf`U;sHkkcIBvJ#r(*R1m4s@s+XBWcz zG|^>IK?pXPX3fU3HvH;<(*l;6u*qsaR9@u~)z7fL(wZu==;8cwB=qdO$kO!Bm{uyx z0K?eoG)1-}a0(h|0BY>GykIZt!@Ma~j?&`*sY6UDGbOZ$!qPM73?~mbf8ySDDlA1- z$>NG^(A1B{_M82McDk&pLo6w#4$M@FQFVy0LT8kop0`*AvC{)nI4)*Q8x&LpOI>E! zr{B?#!bD`6eI!H5fW1`yoIGXyY^gv}1qN{)jbwrG5ioF6#^-dH(cDjH zm4~`d9=6&+ur;`u9`Ni+8XOmM4?q8tYl%6a2ki3mzraFg7|SVOkZx^5I}xOX&=|TG zN@bLuZafOqWPM-w>Y|C*9?VAc%nKMX{SZZF%qh%Jxdi2a2kz?YNT+JSIf1U=#q7}h zL~&aK+uDw@;yaw&s81L+qi~r1$qFv`5%7lKp`x^T_)n2$*ikX#JEG*7`NC*%pmiqZ zMtxdVH5Sz#Wts-YOfOL8A^xj()P-@R7ECjy(Yw%v1ErSH%L(uIiP&@aS<4`+4hEM> z`qX&);mZw9>`e(X{u!AiTw#IF41}5GRVXL&W}Efu%qA1umPI;>MjF@VI`rilW`WiR zgN?;;eJGHGhnY=x*lwzWZ5V&A7^58@W8B*+QHI*b7dkmNdZ=MJ^ARA9oL0{wG>tdF zdQHq6ORi!7$(~(JcDxQojry+6jz;`IV@v2F6c(OQy01-6h&YjW47n~S92K$nlHo7^ zeI2#bsKZLV?JDO=C&piVT}V*&M#3vuS)+M_Yve zTp5qOi6qwKBpzu?MAoBL6R~H-8YlJ=elTMyK>yg-%Q5Tw$EtH8n}dY_Y>_XG0`GB6 zlPG2lt*Jf<62^KRF}r^driv|D`^&6Y)!-?Q$6g?TmKxL?zM4m;l;}Byx;n8H-~a^M zbq82RvZ{FOH>A{e*12d7AfUVMF-sIMtd6OgI8>=s47+TR)I2dD?C& z%hzP7u;;m+alMHv@uz)>zue@R;nsw&esOPKF{SpoIKJwYStb`TIRsVtl{T-UW;}KW zDt;`(nbzHXyg#&@@J$#W_!C1dkFpCAyq#6ArB$_zq`)xLi9%m(ErI|LZJWh zV)_TfKLwP1-le3inax$~ zBq5A%i=X|5O;mH+NbhQ15(>4|ZwX$GB;f6$JNMfA2s$TMV0yBjOWlRpPvBn*8&lMA z1AuZ!%LjikczZf$8t$0(_^z()c|+}K8SdY86}J~9bd)JK23(1JR{L7+;vxRO(@_deo9Se)W+urMb>}6$ zQy3a)U1qb!|1qeh1KG0Vwm%nfBRky48(b*Ec{V4yxjWdewn5>WBi+n0Zpqmcy}vCr zrY-ZwA+5Vo*@%fjOAMJ*=5$WV_g|yh@2dZr)PLIZ^FI5qxM#H|i4(F~IH!&{sVa_p zz0?V=9NCM2AV|^sMp@e1ot!bd%0(tgZOBL5xa8*oC$O zMt#EGpT&(<>D(>EySBTvM7~B~n&H?gIOdMoAdWq)`<9}oYPJZ{Gq>;OG~O@lZylC- zc}OdRi<%5So$MX(GaL`*7@rnx{$)iSe%6^iR9C(?FcmZMFwX(r<|)usU9+x`|ItkFgPP9tW`qVYj{ykj_qKgC@jk<}^ouQ#wCZnzWuPJ61M z-8E31SeDFeBnWa9rI-|}2r4ckNrz2>d>~dhvxy}5BvyrmOs*)DQc03Zl|m5|lrN<+ zC`Gy5Oh*;0=U*ogb3LU_?=nO1;wvCK!BP7Y-P)aQ?VGw}ra%4KhQ|R-xr+dOz76pc z_ea0e28AikC7^hU9MZbU@Fa;!Gi*5wOaDW!)gM6phUzMF-(MBn_K$8hK##o?&&_$> z2xQK9+mYt@cJ8!I^mRMzxYI$ojKFoeZq4=Qk%O~RokttVpQ>G#@HTV8b1FJvO}utP zOKs9?PtRc6Wmf{0Y<>Zu;6(p@jl20pN3qVkwYzgf7oXkDzfXD3de0`?d#aqr6v3SQ zH3gRFDSGNcJyMkPd$M6!>#(%Oo zp{PWVT)8ZO_9Au0A$T61*2O$i%F=A3?R_ELpqs|o}BNMo=OAKxi1tqz|a>qVB&t2Ibb~IdGn4O|BodI`fH$4GG~w{ zJr0s#^l-0vx7+(MSG#u^0r<_6y=Oo@#u+`3M8&w7%_Yg+>&wC>CD7%1y9o*Rx*OT) zcT+Q(AiDv&zf?J|oPB)xn2~^vHG8G$mJlJn!`~dlmhN zmp(aiYr0`G(vr~PRc>zVG3k*j-G&$WFX`QguT2RJzLHiXM;=t+9G}4g7N;HfregE0 z%vQ{yljSFy51UM;((3fct>od*pz>o>7$vE`HEwR)F{aM!R{;uaa2s}Mgw?5bfZT|- zFof(igj~;&L3>PXdkiH(Z5QB9Hk9y-*?H(I_2?548C*nP=h zcdfzhio;;{8Nq96Zq!ExVt1{@E)Y^LxCQKPf$Irxt-2FP9q%@Pmlbp@|26Q%hyuPA zG|7=~t9%Y^ukVK@u&atWZ)X(P1xg(zhp&i+{!kP#$~$$st2H zrCtyZK2(|VHJFdl`vz)ZO8~^V4R5EibE?FRRId8?RKxQ$0qtJk2}7Kt4HnY7`rQMCCQ*vX?!5njwz0HUrK0>NKLJ*WTbH2j3Pw`%Q$h@ZoaJIS9v;gwS zV%}TEHgnd}C>lUHG=N-o?SwXP4;;J)LyNz=HcLC0+=xgb|vlY((-CP#?y z6{P4Zx^0^XBu#4sW55!w!mCU6R%t0mpRE*0<=b!HT1|kkHcU!4{0^CYd@{441fi`z z@W=kzr9VJYhchfRwdo^lf<5BV9FvTT*SSQZKH1BGCdhioL!M8-KZ0G}du^GK3|LoU z9YUf4c~@f;)dZThMM)So0(4u-d)|IPoj<7$l^5j3S=Gi6K($S%bZrh!zYu=f41V;X z!m{t$8US>zDN4#P1d3RwO9CmfPD9ir07-3!vX4DOx?8aKi}gy>(3Z-EniFCFb^xm5 zixE}ko`Yg@8O4@cuUg){X8(jN)Gx!j5Mg2eiR-J)DJ&*K7Dj?Dy_hR1Opgbc16BPo zS7*Kk2m)FLK@5ien1h=JbB1Z;$YZW1z?>O%rlQZq3s3~cxUZ1`dYkl+IcDwKkQ^UIG{ zeS9{S7US!n@WL=dlA2Z`M@2XzDrlbmAY#p*yzD^`r?RtMdqSXS=)I1H1TqwG1pRp( zC&G?9iVs$Z@*(KY>w;#GgJ$gJL(resae8(jMwuP!L%pG+_c|F@L#^~QLejRN4^5TO z9ox-KG^AZp!kBgIjh0$(gy(vMg$}Zjcu0?2&$Zn2$#qpm5&%pj!KAw6$Uffbfaxg3 z8QTt^=~GR5P0lf86j#kG<%twDFG{Q8w1vk_|Y^R`>xY8T$C~Lu$d8c z+eu25*{Kyqvzt8T z%TDEyjWgBCU*mgQS(SOYw6{|fwB9XuN(GM3&m?R2YJwlm@1ZA+r;YkWjhXFrou5s8 zc)#ShJfd7OMuRv9GicMh;?lcMG{E2D!X6B~UPSaOuIB3~`r$4U2u=gjxo_Bts0#gn zTiIlpd?ymUECy)L!?IKZ|9#4cpx)gnj>Y1BE(#dAc`9tE=(_TAD?}0Gj0mrulgqYRCc| z_^`x8?kQthEnf&75X#$0b&z6x&)G}s1%itIPDwieFFF~Gb_1HdqPYN?qukzEhX>6h z3z|Lynoa|nT?0UKlsj^p1r6T=(99|Z&H4~DyDVtZ1~keRf@T*q6n6kQ27(4cl-`1- zll0V(2ThPZHL}xoSeoJOdXoT6ah3oyaV@f%;`&jI&rvkwag(Q-A}rR5Dc(lvsw1RM z8#RDT~BZGGnO|dl;w^8ZyZOpf?kbD3O`zIGGloZ|o=1G;_E>j0g zv18wGtH2R6_SMAv*bf-ujtsgnV503q-a;?!J3{gTH*D&wDQ+q zuo(W~$ibkp{G)~f|7`lWX}5(*z{27j{d&meDCT%2h$>DFe+E{NPY$Dz0+XuxXW1P% ziRb}7;E=2+3>xP7f}eayBlGavmCs<|Y(}jLa(L*HrKW!kVAhUE!`uQ7HH4}B z@IzR1q9-R+!gH9AqBDDE(Y(XvU>G;$Nw%yEvJ|>K6**)aTY3uva{x#B4NRIiohncs z!2mVTEeuPQRT!35_KN0#1I@5lLz$t|oG;MQELl?2i)MXP2$Pm;jDDveHD{Bt-l(o( zHMgyx=F-_ob0ElQ!esW+xw@LF>c3OXy?X=d|M8RQj|CPF0Y6jTPZZ4@J zj2WH1a6ftWQ00);-@YFJEh(cR{y#W&g_&6bHyyC-xGH+@$*d}yIfR=XU!7n650@MZ z_WVgn53Fx?XLPx>8{OJ%NrFZicD0l-HEGx-?}~Q?6N|ZJ{nK2m#h`wPV9nf$0f{OG zCSqbRw{k$D%KnMqW-`;pzh%S$bQ1?)0~Z!w#Jq%twKSw_JJPi~^Xu0qP4UL}t9MG4 zi!u5Um+2^@D6{@Qo{J)x*|du82%39r(kaeQ7+|;rfb~H=Ss}dzfOE>`Ldh& zMp;SAjLbKx`&y6goKQ_Cmh?nTOx7B|{D!@K;O4rNH>HlXeS$M|%#RK z(h9T`SLZ6YgBYzIsAFi(kOc;KiVL~!f4->j=z#lWVmRZTnT=;N}lbH)6j&V90^PC`{YmGnj zD~1!-xXeV4cRfJot@r;zfr9WSY5BwT4e*Ckx{0|Ee}?-9Q-pSX(s1PA+j;!hKpuQ+ zXMqQsu2DEqz|NuoD0q70mJa?k7;&1@tHTP5b#<`c@B6&rLvHS#wD+71&C^;l!*%iF zd?&u?RX2CSo*j_qR{B4jsP5TLTU*D_b31sgj{G<&bC*rZUGSSkF5&pc(}3nPm8BkfBx?nr7uV20Yj3_`8WLbC!(dW%p=hyIu(O)^P};{|PN7>TEoX&~Wj7oCv>p3dvJ(J{C!AwI*>+$~C_o<+W zDd%6J;Q6Cn+)N&GqvS@L0h5u|!q^$M-j+P{|NA;AZa<|}< zKer^h=qx1;*I?-Vqf@!t>yz2xO0xg~7A(Bzi<`T-&Q)$VvyuUHF#>0VfA5WIKy=Yd zG^j}4D>BK=nOho0rai)8iJoA|waRyHg%lW>WbL8ZhD~{$eFRFjoDde-V2W&g%*3KC zT}Z*|o{vH(%&*-pjAa;SulP4ANb%ORcVc?+CWaXXJ;jWMDq+;+=yBdqDMxkBBt))n zQ_qS0zM0qlhu{s_>QdfOgbuZ|ic~}KM*o#hnNJWlf;S|fO#f-~vNfGv{8Fpy606~e z4f8%L4o@lbZ?+E={+I1TrGKq`X!N(ABY<3?p3j{yW7~=FeT{z?V2nK_=gu5+&-|5y zwIMU+O8n&As_$#a3_g(lo8B@OTQ0kJNfnLvFZ>+5s@+Yjmg^nuPxws0xpVA8gv{Ah`--v(Se67Qg|B)0&V4x!|7$|#ZR@K0YLv^ixnq7Cv~prqdE6cq{A4$;|e1W zGs|6E$L=_`x=`FK5f$Ipu1^l^s@-Q4;6-CX$_$%ak09!>a2G-J&aA|(-r+SS(RW?tAY zH%Lq7d^EkdfBREE`3n1+X&ojq{cQk(^fVs`sDIi(E}Z` zqMMiTw`-phy(#|T2WCZ|>QdTvr6c1|-rteZ`zM!E)S)>ZHaTd^3Y+rbWM&10-@rBk zQV&)~TfaKOG&Z-*RZP(arM4e8xD6|#e_o6H)bycVt5J;_Qq3G6c=PFb`{o!oH;Pcq zu4L_cw~t`o?(^K<9qwtzkm~EtrE5Er?f!XA?{>#)ON{AMNL*d-hB2Mah&CrXp)AFE za8(*VC#D3kd`WM$zdIou)0v=1eQc5_&d+nX24R^$zs0~+pALoBfBTy-UjEHh;r_b#p?Qc#1e`wN`GnpS!};N#MoUxs?HH(+qB}TxQcJJzw5s@0CC?U$)6A z=92MZp;62VRBq&TUNIN+?A*&tpz4RnDUb7@by305dl4I{&r{Rj%}G%Nc=@wBDa-UK%AUt7)x&v3()6-uh?K0=JA+ z1JD9rwGS2kO#4vjf5AR9`kT-Js@hum{+t!VjsN*>z!fK1Msl(#m4 zK`ZMMO@X~UISy+UxAk!K%LSGGkLQ@~n`A3s1qay@RFJWsYJVkKd#aaS&mZCXi~I$% zm#>#a^CK*pQvXNOC{vAVsPa~}9@QBk2{iv#_Phm!?Z1DJ=~9b7zdhG9-OU|)DWsZ# zz6YzNA9`&1TZ_`ylYZs8Abs25=_lvYFKtspbH}!XHQd`jhb{laLV8`NLi*ATK@C?A zmj3t1BTN6%g*N?@Vfs%Emj0K8^d*?^lwXZNF)cobwNcb!OV3?J>FFxczq&a{zizPf zmldUF20;4dGG-(?f80O4zyo-1@|t*WI3?-)y0|y$?nJ}J zn;Y?!Bx+Y9OZ%MKb|YY&LEQuN@-EA0=J-@6c;`DWqtaV2` zdr@8IgnB-g^c%xP%{}DNjK*J(<5FwW&95_@Hp_)(&r-4qQTxrOPb_hk93YwhH%M5w zb5a%00QwXe&X>#fski$@ey#m7n&h-F7hU6Dcp9lQ%PL(heWEOmqp)*KVV_n%dUxKf zKiNrT{$!QwUCr!5Ww!oOD!ATR^8cy0+zG?TBYA$BNhQLNUhgM@9eHSGn&11hX=moP zag@6wy7(^W$lO+65?wr>r#L|`k`S&8EzaKj+W2^bGdjBX_fX?3Iaf62PWT$00w?EQ zX;Jn@zZN>khxUjoziBs@;wESXJDD-Hy@>|}Cy#weOC3;q&!&K*CDe7z-Z;){I1mW=9_{NPd_YC`Wl~S*V$zx~$ zn`MSNOUgiuf8Hgu&5o(*G;dhYyrVUybnJP^@K~CiK)GXo$1GgUmzQYio%%i%XU?Rr z`Xl+?HxVL5g`GiY;23~;6Kf!aE6*-Q4!0%SceCuh&VO|B=){Vsm_w)M9)vv z_t~4PvbT@*rqqD0Xg&r2>A6-Ii-=*g3LKdAIfPEk4|EJULbQ_j`gurZh{mC*bn-rN3S zvc)3ha5j-V;k46Tkf{U-`KS-uWZ2|=Ef zY_A+pne96^Lv4i2zIbg15;bI6U$+TkSDADyXzCS>~}Wx#O|qRxTUy=#Lsku}ER&#?5NxYz-`VV4B|JGDFZFqN*-4H_-SG zQ4>JJR*{>J$Y#w)+3QRbs@RI?-@sHhr625mXO$1RG5t(6#q5@}Hc8_VXeh4Fux@<6 z`fS4sRl>Db{5SBM#tF6-;sRbFQ^1g|f4y-)U8%j%EimH9JUFEP>ePR~tTv6NUh31H zQ#opO`jMoW+g30A3W)^TZTtnpzkES6*B@Y$z2!eo?ZEaXcg9pOc$Ax&*R{W-bxc0X zb2iH&vc$a(a`_M29G_R*c5{j?x}1lg)@T_Mc6QFi{j>*MoFoSfWv=%>c{Ajpzxc7n zui}R=@}Dy|Hr~6!CNcJh1zYTO`H=suF@{eHAK$=l_J$?BbxCa$-{T)GWx?9O2wwTe zPvQqmMBmQgw;Zvv{kLeiet7%+SL~zO-IVfn`_J)P_wQ;&WsPQ(;zgJLGS-NB_epW@nDBV1UHkoif)eNPMu^Y>YPG(uXQ_7Xd=4M)!uiJ_b)C$rHm8q$%{%a3Bzp;! zUB;f@veXF1+*1oUXKj<2Kb-H4;*tY)C3U!)cRTd_2u$ma1Hi4x@a_{Io>U0$rk|I6z?T#~zbh=Xy!ETO#GJCOEHuRWNW(c{i|)}7HQ z)Yc@umZx!cm#(1EOo`%ncOw|8-DoD{$JE@|ZpwOQzt+$2(z=-gLt2L=V!!QSANI_r z_b5DXt^e@ofSOsF<|Aj?R2E~a%lzf6O*e8$2^%CRvPzf4N-A;eA16p;6BXI{W&Vv} z3DuNgM2cnU)^I4 z2HEU4UMrY%=|=PD&)KW`Tep_zv&~=s7*n!_6}O!1_ObckSvFyOy&~DL{N{+;w>nw7 zoD?^ku;3c+M~2TU%R)gww;Iw<1@fpe^Y$OZVo6Y z(<3_&a*eDzJjGhWQ>*35kC!}P(`fOa!@hagzS*E(sS>Rb1RwDFZ=Cm#+puN+M->;6 z)M8!vhNL$@(peuJ2bY;`@Qxj;W}AknzP#fIZnLfkVHu`^Ac={%Y=nL8Eiwi zrk`1+CZ9Q|wODQwCP7t}KotOEu4B4F3$884>&!-$AG`d2=7 zgb=*@J?}JeHQLIq7tFP%SbVU1qMyxoq#wolvr3$POY%jA;b&YH&Jd0V_xrh15ROY5 z`ONVSA2%X#cwbkhtBv)Z8Qj;i%I#(4bq#AjW$uU_sF?+y=CltZ52t#i&vNQRl993b zc@~LAu$bJH+}wSBcGR<}F>8{2gt+gThh>9LiGx6;a?R}L2r9o{bFBYxvL*VFl0CyC z{#GkdS}So2&fj%niT~o4X;SXkZ$HoTvpgFhq1XF++HJ9{Pul&{?~NUU5_sg&ux!K*P6V$8If5t33`v;EIu@}?U0wH%Xf zc(r9%(mN;z(OSP=ktc{N9zSUw(OE1|w!>>9zi}@Z{d;S zM;s+M|7$8sAppmc#UE)Re}Zf3ML-*-5%L@Z`~yRL>K)9ts$UfNbA*^+bc?1r{|+oZknM4t&;<^G~1u` z=I46@Cm)}Ul1_2Ys;v0~3vq>W6|0^qVJtv2$ zRE{zmIIZ=6e35$QPi^%veu_>2kf+lBr;h~88g^48xa@IJ^&GyWyvM5d@K-|oq3ZoS z{R(G3aA&hns(LmfPKF~vXF_^2Lr-R36C77F*yHCjz{bU~_A0+<_`Y}@*>!B#8vm%^ z&11ov_5Q1v1{$pY#2aC`2@cW~r-Qm5U`q>xav0|>{ZejfUxFFbEdMg*39+{B@0uKI z{g0o;x*f`&Tro3>Lm>?_lH%Luz6yMU`^5ENfBkZ@U z`6kh92KAi>{stRu!H8cSMK6i>J)gYuz{@=IYFPN{q|AW}?l>WH;6(4WC1fs%Ua&_= z8(zC*uD0?v5&)EDpFTZWmGrjw|A*PUh?@uC^c zLsJdgZXK3t=)8Hsoxcezy)~IN`}+tMx#@%xe~XX8Yp*3tVnu4k2BY(W_=|nU_H#HB zEJ>6Jze4kG7v|rt)%&pihCW~tVf^jtFuxx*zc=ul8j9r?yxqW2KJy+<&e)u6*f{^R zF#cBC#*F<(n^}f6_8$r6{XW5dzMfP3^C!Y59mOQ@h;hS?wjElnf&G;CwmRK)=;`IC zH-=8#;=a~X6a^*(aH%P$p()!xPqo<;{+3w$Qgl%#4^H3Oo?m;<{F*M(k$fARzJmZ6_8InBi(`<6@Pe1E2w(H|LzG^JRA#C zfzkAylO^$3F=y1;A!CN;I{)vF64&oBQdC#eJ|WN5oy#R|^RaFp7{UKF7DE488Uyo@ zLj-q&3IAswqGzxaa?FI>>|Yx%NA};g^U2LVt`x2}Z2DVcN^}=>cJU8*A&+W$E{6=d z*~A=di!7%{vK=yAsra)*4S~6C_7Y~Gd;Hw>W<+Vta|?E^RM_=MtK6mY?CQ%b|9dC| zG}!EN-RXKGE`@oz6z6wG#j{_nXOsnc4CtZ9{uwpRcnb7b#ixuO`xH6BoIgZAw|Ae) z&y@FXdmvMTc9yJTZ}EOLgM3HhiGk?ZJ+=NDa?s{Z1w#;p17170-TWgSAP3502K_R!^=ub2nLy_!XookkHWX!JhccT4Foqsq+ zc_ufhth85NE!~XYWO7-`!x@vN4~;#QsKYw*9~&+Pu66KgI2$Vi_X(RDrQ+Kn2hzO0#DZvG)+GuetfyQ zWPRu4vNG!BpisZDh>X#cw1lP;$vvl!)y%i!x#l6xop1jmntH*oT+`5=Gx_ydNM10^ z;k3Pzoy^;pFF^V2_BQk!$Bz%QqU1y`*c$h^%A?Kkp4hxQSAJeYS2j@-st>FB|z+t7aNG47H*5}KU$=Vo^A@fSuR zUV{azwC7{ak|(8mb0_R4_`v@crZ3jP9bGi_Xu0VUE^*!I8B7sg;JR>PsT(zo`KxJo z_GesDmCB8JTN*yLDm(wmJLkKqInHQGPj}f;7EQ0orps^=G2^_X()D&_)6Lm*Mec&W z?EG?6_R7x0Oe!zoxIcnD6LfR}5De{1jM7_1V`Ea5Lo|0gyfVkda2Q&NnOJgpM8p2* zy_yte-oWQ0n}Tj<+#Hk2H4^c-cp*ikbEQM4=-e;wd-`e2gJftPylLJLfy(yfXyy<6 z8sPrHC^&W~T=6<<+moFgVxs$lWaoYbf=3hP>yo7;A=U=u3FY_;OHtn4Eqqz4~?5bTUZ$7r%C6(zJ_ym^CKh@L^ z)6e(H+e}k>H=ds@Z%g9tY*;q$1%_GA8Ip_sO61 zYdgMHifamdtzG^nE)w91zA$L@y1zvDy^K27g=_Qf{@g}DcSPQpk;qx zoO4behb%Gg+w8yfaezPLlIhMP0EzT!#Y+DLz4b0>!mLnoe9YKWH8v9eGAt9lbRIEa zwZ;4!85}deQnf|rtELgm*ca`}PqdURVpLEBRi$UF6B(`KPefjKG6$>Xt#*DT(>~$- zF~#v^1IoLk$;nMJ^;0hLv5qndw7qWVR-M+bu-PBY8!nwW+r}@6?m_5Tl(J2ttkeun zkJ#q_jwP1JQ<(!*^Vm@E)k-I`awwtDL=bR*uznsai{7KSP=PBsgPCullIwHMc7MQA zUGe#{N2YfY)TO*Mafoz=u(jF$iWYYUC-WKO1Wv2TVd~E-btX~Cw!M`@d8jLewu*Uo ziIF#73JaaSbw&F<`t|8bbEA8Kd5`344w<)$31!%HN<4Mmuhm{Bm+o6~J*D<`JI46~ z*fzfDb+r4ZMmFS1zf;@Q*B-C!b~Yo#S2%sEf0%jxJg!pmwzTg*DmA0)&gTOc-|Ecj zHr6Y=)|$m_a~l$bDkK`#%>OJCAl!OgQ*-0GSe8DO3l%vpl_d^`QF}ax-jqGk2s&!b zQLkG5Xa!e>b?F&ha3(pUBQ>VWzle!~*O}QpT;~40!vVK+`4i+Uw$Bg4=oaHv8Wbv* zAO6$1hyOI@@Sn=~#4*fH<|TCE7T?Ju*r1ysV>$?6YIlr(0zIM@eQN^X>xmU*EIV?> zCHT9@cn4iOe>TD`u(L1;5M7sO;LkOt57YNutUFoZHiZ!$+8F2Y+%UfkfiUB$s^|sj zveXRD;vD@994%SAYQf1Ik1SY9C)jCRwk#E4mb`J^iw*Oqd+W(Eoh&3JFgKN(RA%Lq z6yLz~2+ASRZ*HJqN!C=3G>k9EB<|SnCqKCaT)_?3>)d)W~@AkI! zb*cI|m_BZ#Me)zzjF+e)+B6|MJ9_V@nFa00OKZuaO{%}djm;~;Nbd%O8MGr(E4)6bvYHs;tQF$;WC~vAQuR`!z*!@p$ zVJO>9 z_=lK$!9vAPgIC|=m3--?c%*UdeG*4RihT!iM0_71k!xxtOf-?3G|MkXE8^J5ET8UN z?ObJ!x69nY0txO?eALUBzV&{_`2Fv%Hqt{O9y6<({C{O(Pr)m#j`Nr`f7dfF_4~>s zS=P$ufX{sO|+6=qtfPjOOFMP9Gxy=eb&jcoa_w6^!>>TMh0gjb_*!tr--L5SdE&fv zsY2}{B=%rjHnDAuuJb0z-5Ht|_;W>IFZ0q~9np=t?(KCOI$P#hKfaefdQ-_C5;F zfAnvjAo^Qey0vGLf1x3<<#U6RxAzs1r%l$+^!%Ip_2IBQ;rKhOFZTRGXSHV@Ghj0s zd9DBTzE=!9|A5QLy28Dc-N&QPm$pKQ#@)9VcMQW7YqXGhFAJ$_{rgTmWbFOP#mxWM z0$H!LXCPd*L}s1;Hoaz~;joSu2d`Wo^R#%we&xXrxElk!skHc(xGX}O9 z+^^#&Vx-GNubz63Ez0?CydgI5#mD~;MO1g}1Ag=vbAub+yNf3K7*lkA&j z7C=agoj0tsSn_?DG&1A1`OQ3WpD7z`ZFYkuiqY!8zp(np>VVpZ$;Hb1H7vcmxfB9Y z@nx#)TwJO0Mc&WCg8u$35g+^|&es1+9t{&{n<5o7;+tWF78nr(EvzrE^Z)X666wn% zzI29{_H31-R`vL|S`l>b8GP1~i)4%mDHsZpmG3w{NR{jctc;5jt)Tu3C>LKLv820) z|C)7I=gxy>A@V2|^@jC~<)>MMEOQ>$Dx{p22U&vTzbD4Mo=0G7Nj!Q%cf6tJmU)Ua zZ88%zvknRg>->qV>xu+V{9)$oE!(`?ok6_WfdwhnA7Kh|6%IVD(QX=fEh&k`ecCw7 zOo_qlPtNUEv4d5d*;(GVjFVpGEe)27H?!a~4h7^LVAAjZ?87$UNJ=a6$FRugcw7DN zG1sT>Kg)6%lY;`)2z$bK*ZR4jnk^88{D>~<;(=m&9#6#jynXm;hum_uv>@Jq1$~SA z=2pwM{e&-n1PngbTjSKOk9!9;zmQosq;FZ@dWYrG?aI)|iqtqbamSF>SnMf+c|KX> zpBRjkp@x)}seQ|6>$9mDD@`KS%q*#f-BZ0q%f&x`i&>*?Iqlc{uuEo6Z6|t#%gguV zu3^ROO(d~a(L`)%4V*Us>R@%ksu+vd?vavu^C?48@8|qQ>aAZXsrOB!-U|PJAwpUD zc$MQq|HlfaKLO!I@@+0S^FO*jlyA>JmzQr%e35+Hz+Zd#jm$=TvfWyuY%It*E#xBK z(uAHrXeafHhlY}Dz5ngt)ys_KK;A6~UOjDw_ZkVe*&<`d$h>efV*}ZUXRQYHRxs;w zq>*sj>}PoLw(FDtn_a?9G)uT`)B@X`%hkAoaFghwsyV8veTWrl>&*I=5oybKlE&B)!;T09leMqb`QJ4|CA#RFlIU((3iy%B2oNv$xCGJZm-RB$rO0b+Ok~RMZqj(1rw3X_XO3b(qnt--on@ z;^_CEwG4Zjk!Zw`wwp^F{aWIv*V|PPNR9mk(nD6_A3-2#iM-AVq|X|GG`8R`(oF>Q zCWsAV7H^2U=L?3GmWu*;q!hAsaRPg5kxGF)iZ5^SKVwtY{0d_8!pM6TQ6%fCUL46S zKqmDflf2%Zp)#tU@NZ;BAWxbFSobVRq6HKnNi-4_gd|FIND?hZ5-s;Dkn>2Q$t3#| z4Cw!1MVQe4{@253<~bX7`QK*Nfvv@Ss*RrK#$K!9y{(&n<7n^1T5ciqlYb;7 z+VEIrbhGm_NIA|x`Lmg~BX`^&(A|3y!<9&UmpJ$K-$mqSV;v>dMu7e}^u2zwHpC)a zY-?Xz?)<*qP3eS*-f$AC2;C; zPG9dv5(b|$uM8!{?jf1Iksw8VzZAAqlf=+UB1K^nVbr@L^BkoThLozVF>OBuVp7=$ z&2&K%wPpsMJA+LM>}EwiZ`u%zdL3zDB8sx!#!`mR&yFI=HkN(IEHS<&c&M+)Td{($5th0Y~o;2t{)gBQ_(E0 z6xnl0Z)D0VUG1{7B|9X|v8xSh=JhBnG~g7y|DMjrW>1pWVb_!FVv=*`ZnK)i9-1zP zka4H4jm4z%;_MPkG_0O~Hd_VRGs9xiXbw?mYx$Vtb!jupX=~Gt)n|mpoQo!eg4?R~{?O+r1j)1iYHvlyekM zK38yO0XxnHHPlX{de)ym(P(JJ1HJvIb;DKjKG$@M-K{;#Urc}ns^}S%l%}2+AA{k5 z<+a^U^5pGDwU0u|R^*z9D_QH8^RoM2N!!4h>O<8(fN1Qr=mpCpPW&%nNoq=aONHz! zvlQd{Un=})_OA?oEUI1z9r$1TB(F4?)SlJQZFah$MlGTLha2hEbEf}GCWhwO7&RA? z2J0+{5gHZ582%Y=O^|8MJs8i;jRXOzM?1uGu#389To|7EC<#l*|iXM?Lw+fb+>?R^iEcxxTmbP+=Nqes;?KYqaOK=cd zmfXQ&lwnEte!9oZQ_)sw1)XliO7Ih~Oth}ztAm9sgF38*YrL2ePngK&P49IzFOQ&k5Y7rQ@cx} z4kaiJP~S5m@E3!NdWP&Lf*^k&WA5UhuS`W3j1eek5dX*UY1IwEan3t_573}*y`ffd6zG;*1 zF=szH-qZ1h-_1Lj^Y(0guluvY`d0R>X?SM7Z=k|{*K-pMe{4NRo6efepwN92Gdj&I zfB`A5#6r01f2H>oPLC9e{ue*J1MnE9anDiWH}79>IXm9)QY%Xo{mNO{uN-*mkD(lx za;dk^mf-X~Vfr*X%`5=pTrov3e=@ih2tIE-V8$+qCa@A2=slH&{2s1dlN=!w;O!o^ zgy?)rrb4qzu!A9tqPqO%ZYza%GRe@&goL!b-S<=*9m53q;RtBHbGej}S#Z75tiHsa z>UorZkNwZGeme8#cY%+p zx)%QvCcprJiOS0-(V$H`Xu)U&he{4i;0(<0@CB_eG!@ZWMNJec1ay+>^f=bG+G=a9 z-uAY()vJAJq}65!kU$^_P?d)d(5gG6DrkiOmHfYJoioWK^3Yp*f9?HWKA$k>?7h!^ zuD$kp@41u|Y<=+#0mDXfHCUKmIk*eW#d?bEP!w9E1=adDCn&WBD)Y4!?ZeK`xk>#= zvYf@acv~QMygF7oCpYRm9}E3?(Iprig&mN=5KCsA-B7U6*Fbtif^5Hx4Wor+g%3-@WxgF@WR?#RBmsG}%tnmeBApYJ zoThTPG@7%#)US~$Ci$}|TH;&}1$&*pBoMvMZ?&%gubD?U+I6_&D5!|8(InGpLDFQ` z7fQ)n(y4<;#k-dKNA)yBBF*JR>tOCo$;nDsna8tqPNC9%!c%Bt*m)xmt4-z<$7^z! z=izks?w^9Sbo`bx)lXgEjr{gisXfDXzq)&!Qwo#Z?zENJS7h_9|a#nB33lrN;>2d=*A8n1q8(drT8?}mAPL7343zxfWe z>3Q5}_PMY##%f<44t-_#@W5S{>nXQV0L`21_O}#U4)R{>^%D;hg29<*nXmcgLu|rD z%c(JaCBSc-FfErM2LP9KP~QJLaD&I+b&F4a)oZ%3<$|s@IUwYEAly(<%bso?08Ef$ z%1z`D0w+QI=RfHZ|FWBs)2~a1YPu63CbC3KLSD>L^~VdcPg!0hnrK)#T4n*DZDsjO zuLGQ*Ve-Y=nF^bp5NXzZNVE2v@p7C15PuT~DF@#B)Ab-!{H8)9;d%U-&V=*ipuS|A z&IEA?aE%a2UNORGqFkEI(3Y}+-=cr~iZ|U$?xQHN)_ISN7Yb~nNp-%DHor@MV$3hn zpR}2Wc+|c8q3+vCl}pGJA7$E#|>F-y()^&O7D z#9!LkF2qF=Cwq3heDkpK7J*7JNay`oc450&kfUg>>Swg>R#x1#GIp`~0+q=I932H> zrb}cIVPeEg=KigjzS>-{O|~qm}|x)N0^YZ@a0| zbkup5E-9O|Tiu~Xnpc^2LBMn9rtP@%Q}y3VGpW&3A8j%(UPcGFa7tlYE!C0x1Kukc326$@v`na zxoOndS+pfN{TI*`vRU!EfdwJVO$_$_syB3Pt6E^0g(*7{+aeaTY7_4QJkyis<)qDR zSV}7~%v_A-Sc*JE5pw0Lh?nG$1bB#0Q;asuZjK9q=p2qgNoQa0Y1bqXExeO{+-P2R zA8|f18`FH!;lXTC*|N-58^^y0w4Oef-T)ZsIM#sZ8B%wEx8{Kg7VdzM}hmt+|`ok_lb} zZ;eP;`nlF}+RYiL`WfeCY}xiYV`)WYgFCH>*8bVurzv6W-L3l>Z*Tq=N$w!u?J1R% z{Q+u?cqwdg?W*6C3W$AJ5kb8hrM=}^RN8B#y>(13AG+-+Zo9;5Z-%y~Nl&}rQ+bZI zClk21YkMB8algle52liVJG{G2X zC0C{-%e?u)&i2;grA&R6+03)ll1w*;*k_HomAYGDH!3}myimGId3b!qn`_*!W@;<@ z_4Gyt^jGsEboc;?AMk6rllrwmnZTbEYKDZlkeT=mCMvC$X_N)Yts<9XzRa_#rH>Rd z-vxoShAg!@1ix=Eucy!Vt(1VT;0xP1(){2B${`bXw;#~KxJ`O5{9Y^L#v4x7CbJE8 zOGf)+QlrkBEE^7KSmz7VzWY@($TPcZMe$eFE+-gF1}oQSuF)f~>>7dSXV68{)9HH7 z5BCa;+9)+I7$kx;&Q!$=MQ(pvkJm);q4)Zz?Y>~D;kKw~kT8eEt*6Lz%b``5#jNTP zb`QUv=zu!w%@Iw4tK4y#AAk+?FcW2oU|SJAbTyz%699@LI71uFv|YG3(7DW(x>TT$`};3wlf5O4JYbvizK3XZTiW=*AvsoXfl_=b!tzPbzhN5q3>+2JKG$_6ew(Fy-J2eGik*niXOUDp}Y zezRvf=kU;-mj2|=te!4QH6z`Xo`awBR7+4ZL|W8KAvOsUz~a?iSpg?7#030t_a{zm=T4#7qUPOCO2kASO4La!^UX z=R@#*()f_Y=V5N?##Z_c=Pfg7>7`p6m9pGcK8X3em-^kw5ajbEZk~A z(D@x-%o#ZR0l}QpafOq>O|!%wu57p;C1yJmsN7pny2CDgM_Hh$$*~_WTUn9NJAu1b z@_-6G5?mQcj$Jm@$sH$r`GEFDyL~NT*ZnOIQebLg#5mVnz?qUmNcoG?`@``CQ%=1X zXHcWN)wHKv{i*W;jR%_}M33HJqNSUsjLO-}r-Q1CsW6xdJXNn*Tc?Z)Z*Cj!MB_O) zkka&HPQPyTxmDPsdh_`a8J}<179BOMO-Avpu(Df>-xf0&#vci-l$hYS(EpU?I_wia zQuh=mX9%(fLVC$15w|YY&aLCIuOkkCbiLIVaaK%8rLnmR?P6rddi6X@sAU@j5VE9&HnB}mXV_HRVuk?n{&dyCr5 z^H9CArC-DN-Hnl3M#vOca-nAB%s*S%i?aMEw2EL7rAd?@o(0`gRihfvKnaMA8@2XJ zCB$JBx*oNI&>gb`HfDFq-#)SQ?Qr8;Bt%KK@xfYpTl<$Z$J3=$r=;*v-qfaor|xvbhnhlxw^BWB*E7zzx~AU(|y7eid|8m8@CU;3*9JZtksDkYBHJ+WEC-| zE$VD1YF~vb$v!@L0Y(nElDp?v#~pE(vrmb z;Jy_t$`EimusMD=d%A9gCH<^~dC`?R<;sr13s_F5e3uTFayP%K<&L(3FD-aZj_KJP z?WTv@Pb*MDL;>Ra!IaBBo+s--e;GG2_4G^erq!XW`fh_R5aOhc z7A>uz4K-u~;pmIp0SVnQpnWn`(M2J03ld0Gv9g&@n4x&2_{J4QC z4=^{9binz^2awE7tG)TzqwXZc7(^xV9!P$NkbR8!LyS#4>~@kO!L?=^K+mXPU%~nA zP@Bv|<`cgSzWBXLr;ynRM!!}B38?%5fqdDFA8#OO`z8c~?6hj>=;~G4Q7oLk_1g{$ zr-#Y06KJ9Nb=OxUi}UpoJu&rhHsjr7PS&9`nbUPBo(<8-oiC%!P<`P`!C%m7^Gq*E z;i(w$9=j?~`DFxRI2rbmt(Ux4qk5a=Yh)q^$ zo7=by=Q=*tB5GAslDL}QqFBCo_-rghE1##?sMF8dmEu;gU+Y5lj)|NDs(Ygqe?1!` zQSMF@!}Lf27c}p&i(0gE^PR z$qmzybuE#8tI*9(b)tjYCMTkUcZiWE{pstE71YLx#qh zMqK0sol%X{k;r`=Lh~)LqN$Sj3o@ywx)_fRP=^{TeIx#1@#4Wm+0=D9R%CYZwro6T zm}ll|WT<7)*>W7(#L!_)M`C&5;PEBg582?)(W0Qj4o@wjj@J1Sh#al641!UY|JClI z^$6TvBTp=xa<~JV2#M1a3+=t74-Sxl_)o};CUY8Mp*BgW4aC1qN-UX6${q;|P0C_Y zBB9L^4~Q>r(6>#u^o)gSZ@P+LxFN0E`h}E#-SLwm_%C8;3Kd) z;&Ua4DR&>2VqpX1@^7HC0MlOEX1CW9y&J~juja!Q?7gn5ntH2Oazt-k@0MaJmX)$i z7z-xROR;b+Dl%`&aZH_smRb_E=6C0Necu&b=MrIk&4pr5K}GY;tsnwRq<*f0t8l@y z(8Y;Y9jlR{^f~lx83#E8{xA8UGtljP{0Ki36Kr=NdRPoBtm@6|4Cvw0zTJf$zCsTb zrO7hr;d@qo40^bq9Hv4KSF!Fw55GbS(8Fu)>7<9>Fvml*<{twM^%RgL&7lIu2%$0^1mh<K@b2w#%lemfDrf*vibZR+*`|IP&a>NU(h8CTh z{J!^`7tE4B@`W6zf2DaVakJlfm57|@$M^TRaT)>fC2&+}JqU7DEYv8m?^oV5+F5xr zWd*$vaeRM!jq^gVIbPd?z+romVY6v4&&Ctp_tm56NztaGvDhaF}WJ-(id!O z%rPhIz)u*i*om?A*t?UnaHk>%r%sM<1fJZCdAD5B)agd?n99&Cy&_J8P{ont*S5xz zSDLi^29-g34QJQq2+oL3K9nlQf_WhZntdlb;m;|_f;;C-zq7k)ec*0E?S$Hu1Jb*% zkDCSTWKIwpe1CFcc4%2S#GBb(wf69~3YAyJQ>=eY z)suu4O%A&5t}giNKU5K}_-k4xKi{14@Ym7s^U#_o$kFa87hnFmhqb=J%nH_;LcL(E z!PJ}P;{Rfr?dqu*r5iJC>6UG5S zP*=&A!g8F$%{)Xr&{WwXf)%AqA-OQS#7aN)yV+Xnnp&)uMlcbbUVy* z-a87~-}0E|Cd5$D)d>q&KMj*A=<0Y<<=w*k2a|U)f%-b%%CT{G#PQNRyHO8G9Ihu~9Os(vOUv$FvK^Ih0g-=pN@N zSZulBhT&cHJGaGra+RG{ZSGGw#-ty8Np;Pe{sJTAsdDcYib--MXrq#9w`kdRNXhx6TZn;`fwM+7fC}=kaG|N(gD5%7Fqvc$( z|6LI1KiJR1;ottxFf&R&cEi7CA-%M!#Q+lg`_4DI;NO$P98;waWf}N)I<$?-Q$LD- z^Vy|JH3}#Q91RsLlkERJ>P_R{*UVdj)2dH!o4l1Q!3R&&NL&9js!`_0H6<5QOOfe_ zy@1*Ev^OmXpFA-$co^Z+O+r%w=u0@BT;W`xvalC>{X(JmeCy3azac{~z>$(V(H}S2 zP-cNUw}>&9FiTl^{0W6Ml7<8uBgm|GbMiIkvEie=oI-0UDNEeUVjjgaRS|eZjA62v zDX-2YJVnILFpKS=wT_NFE3bZe)n;W}w%%hv(h{kq*vpU!=hgOJ<^1Dyy7x*A@;b|V zrT6kW+k4G-U*~$S#qR4o?{$g$I^TPx3+ntv2hu4$G(|Cl+e-!@Wdt#$%lI|r{)`kN zuTbXUjFfy$c{C%XSW}+NNLivO(oDMMEG}pA?(Fhf&*~v5^_gXuao0q$<120ms~o;D zvkWc?mBY7YrsPYC$xJDhlpUmG`V(=*orJ%YYr4^MuG=2rinN0DcE4s`BL&MzNk6aX zc(%n>y~|r+m$#8!-bQzMEAH}UcX^xMO0}3Js)1zVV)g&hPO(Pbk zN}-A`pef@3%j5&$|3q?zX?L-FR|mf*s99AI|E5OM{~(R>@BI1U=&Q${V6BC|Ld(~o zhJ6kG_C+`=t9k`G3h1l57eQamMPI#E_0`MZt6cgjQ29e39LFydTmnpgg}P80>&noI z#g`Xt88fW>2(>Uamr-gOWs%~*4wbUf8K>E&MO~6x=EtHQMkUBHwd%T5!_2aMGv1&%sEyisgieuBMxBRm%_> z%!6WU;*zNeDY1+NCQj6bOXKSV3~u+D%J%0$Z>^u?Hgfo7Uxg1Gbx(16{%Na2xtxJYVs@`s-!7 z>J_tN%x`|7dli?(XeqatZ%fWfiOzq&Yojm;V~^*i9INF8 zDdgk~PhQaO3@zAPv`g^;SNNVL7qD}sO?HIq+pfdIa!gUpuG;Lf)1BI?SIhE(D^NCY zpYM&m9E5%awNBISO`%l9HKDpia~{nuyCS%;%pZEWEGP78`Lw`u^?~Oqwex`|aKBwM z{!Xr}XkR%#Iq)YnW9a3@qv%KLZFUGz(#^e}xt-3n5}v?g91|lW&dSzV z&xoqH^_XX_l%J!XStvib&zvPcJ)a5kV^xRwUvvx{ZlAr`JKUDuO``b{W*t_w9DvMI zfAU2Bc_P?f5bcA*mqv8Sk&??;aAUHkRjK zR?FQ%o*l-VzYYS!A7yi$MP9UY0;Ft{8dunwj>UG`9GR~Uy&)Ydw@V4f@^^VB+)>x} zQp+E*auRrT*__Zs4e1zD)V>~Z*@048lc9-wF_r|>s_pG1k$m5ZLu=7WR6PBO9 z+&T-MLszY^<#U*HcmG!2b^e4Z%Jb~#{`#NpE*9nddvefkGJklOBy6ot2Wb9wlk00N zBHX3-@L$^7_!z|Q?rax}g@!H1|7GC5exj9-m}F=JTei!zHzaQLn;-m*Iyt|K-I?zE z;y|4|M4H$CwEe6b+gHR|`Si^Ua|gp9l5<~?V1D&sXFraMQRg-D0F>) zE|R&b8n0y$z|EkBX!7J6Zyb^(=qP{8E&lRc+j%GcMsLd*@mT9Xz1y)c{n}GyW7e3P z^UC_6navw>OI}$IymFywr_@W;0lj%cMgH{Z14ZNIdC)W1Lv1i`xM*EE*_OZ2f$7Pr7yfhR^(Mw3_NVVQ4%xXXqxBW%P*q9L>%qg|E22(1B< z`LwZ>@38lvY`3~jN;xm@-h#UH(H?2{w#GpCWplsk6qp~URn`WEpa^plD{%%+SNmm^ z8R!+V;K`H6-7rKiqsikuku@2lc9?;Z51e-dLatMu0(-z})C8<47SSbK+FW9UO@Z=P z5>(7v#Si$9yY&!&{QoFR3~UNqB=X)P04)9))#?G79JF8_=XCxrNsJ%x>TKyktkzQ$St{4|$*BuAG0ngcm?XY@^v9UX zx@`6-;$;gN<%|PFuB#Io;1Ky?`fs7M641-G$K;ju1v=3z$SlA4SAoF=ejF3fNvYd$n zAMH_oCKdpX`pb@slwQcyc0GS{9gJ$~HJ|m2+_hxBhKj58NUOS;7Y_P+$u*%zIr?`^ z9GG1;$f|zJ&A62e*$czSgT`5qxXxd+zRrzNkYQgDcnW`;#o09AZ*M@9L>w!t9aqe9 zjJSH?5R({aiq?mdU+>M(Fd4kiPn^ON$>R8HmUAx>pWlY{TX9=?ulChd>leS9kRs*1 zy_V$q068UOpFv>br;^@m|3e#1)_Z6tKic?^F0$&VcN!n!gA!+AZoH=V19JCa{I%Y` zWvMowUAi$+S|cz-uyl@)M)M=#l|hss5gkAW!z$4^lXJ1l!OxfVL+JTF6_s%Rd@14i z$|lMU!^xZ5G0Cw4Ppyumj4#3o5Ug9Wt+$;r<09>~yEfKr^WlcH440hnN!Uy-vx6(b zcMg#3sINI1+H&JkWlg;Hg<+A?+2xx5QMBWtj;DX*!ahE%ef3&g>MyJn<86LhZ0;&L zSUc|bw;b?$?*=@nqUXV?5d2kio=5+=wQ$pMQy5pVn)P<*zsompa^)BH)MQz3HIGJfn9#m(xI}+k=*n|^kY@OKbg)k@bzgIuqb3vyUOuY?1`N;dnJqi!S?a0_dj-$aWXmnCV%dEtNf#eM= zTIH-O5!18(V0`g?7z{taLyS03gk_2$hX)sMx7w}k_!sWMFpTRj>%}&%?WXHvq1E!V z_ogdjp$2){chf~&<1J6iZkmC8usqe?G|8!rZ{4r_s@%Xiu#Xr3^B{MHN3a0CelzC2 zo8|p%j=wAKDM~C3V-?KL#eH^!niqnvq$j1zFjHPs>58X$90P> z>*?H>+v;;}^m8>s+2qg-dW6=t_J$$32O+YYpV-26b<-tmKvu<(cp(b|Q@T=_!{94} zvYbg^5FuFwk1)E?dew}4%YOOq97)puH0yQ4{n~Z$GX^{=MF6qO8t5;ZXjSjxnbZ2s zIYLJn6OdyF!8KhMPQHm`A*FUxDmndzG)r~|NU!yXy5fO-NN@FxVqj?^_Jn{QFpN<9Rvk5#o8pJrvE}bE`^1&+w*Y$DHq#hCH zW9i#ENKTIApbBzb63Gnvv4=D}Nu$~NZG*`n>*M0dbYJOA!Lp1oWBK0O>3LmcK~`;i zPqsW?<39J0=P%21QB8c0FA(l|fxM*aN&j-KbasW`uB#DQSS`k=oKlW_bsjGCuVts9C0s|koz=gIF}#({&y7iI`H@jm%IG%B*FNAhlKF%OIijJPjkb|e%rwf zgUN-N1?3!^GcG>Qb%#CKZISaM$1eR6vTz|bR7ECO-)0kt>Q63o{>t!K&>CUq@?4E| zfWV}r>Ms>xHwJ<;3T6@yvbyA~cD>{v)jF(T(~PBu)=|#QH{K)mi^^- z4+hM8LB&pVQ=8fU?VatZ*L%flYkakCu@3a{i66N58hC;0f|bgTIL&hZLu>`KekZ zOxAtNqD2ri%P^=2`=V~Wz{bf>0U;B5ND`iJZYT6o1J9M?8^%O+o^X4M# z?wOP_%PyVbM-GF>$xtk)UHTY1nrI@Y!`~$FRbax0kJ}D-#~o~iz^_uS#5>WK>t&Rd z8YvqCLedqQe?ls<&y0axXaWw;0dhu{`QbMOThw}dr&r2aI*ddoRg(PjYp`8MgAJLr zsbEEJK}+-;G_xQp(f`$33$mC7$s|3rE--bqWM*mRYBCXR%s0w#>OfXi4Ym z1EUU<)C_;vi4eTl0z061$#%y3IcJ>lxhP+p@p%a=4^cVygdY=sD?6Mx*B^g#KsYfu zw;y+cj^`69jc*$O?bWY7F@<`$gd_2Feqp*k_5`{6_pG~gX0Sw12O^2j60h-_svnTt z^|VlW%c%*D_j7$K^e-3K;L?N>7Aty;oy=Js4X%zj1GDW=p4`4;;J90|7rYHUshqa! zCO_%m7{^ZbJn_pzIv4n$6LaoBNa6Tv`(^me7B*?{6<3?(9IymMi)w8FHXX z+&9E+3}wI`lxQtc_DpEUqRmzyZ@_!}H!&}81nSZ`ftxn@=L9NNzZWwR+#QlXh$IVHRyJo+LjG;MMQwo zIc!;G+sUg{E;tuaV6+q`J(un{$uWH^6R3GP)i9 zX4T?%S|4){1lj(z$qDH$B+_EmRRck0XE3T z8ZkMe+`I;!f_*#R#tZ>rGBPKkd5C8#RKr^Q(FP%=fG1v6_F0wkLP8+VMvB`hDX=tWo$r#2GKtCQ zcGBJ;b86lN4eFB88+T?4m(FKmg}Riv<;xGxg8;>&HaUK$smUk~zC}FqD!DT8vbe<= zv;UnRX3T!;H)Zx!Mi!*TU-6AJAnTBvK0hrZE2VOsrgVoSgonEhggNupp}~B9wXB0T zp`Ye7disw_ojsNIo#;uZ_MY2KLZvYNU--X6Db_Y0Xgfeu2yPIJr-_^_Y>XegY^!XSl z{R3KfcRk*^T?Z7Jk%44%W-t4Fw+TGlePV~p|D^YgDL(V2-Ew??2DKm6g%R&I8>$<1kGV9-Vo6Z7z+VuJlF_h-u;C|L7^D>6Q?q+c7 zJH&Y|^#Lz1_?8<&Xe1lm+~L-Y3!Wu68Q|_tq-u2`*i+)XYhH$@6pNNklr0%^U0&Hx z5p*37ZcRI|iuqAEF+VR>^|nAHPzE@}u-HIsN06;XGgowhP~XN}%2UwHzb@1&!Fn-h zY6?vK0CjmDp48@Rpe;sqcJP(fe&(W;`f_T!`kpe*FX0sjU3_Gx`|ZOp#4-yg>mRW6 zCL}QsdHNP+q$wcnIwj7okO`2|~LIgtptfi*-b69SDa7nJwi0Tvo*k zNOp*+OfS(V`qlN6*+I#WPnS&Y5?xe{(FCo$$y~|t0gDem(p3c_QD205LyO~q4kH}x z!p~UD0uS7cO!#?ZvDXx`)=lQa<=RdreCl#EnD^LJOf&ZRABEJ<-z!r~&s-u&p!bkd z*jwo zRO{^1u*{8tscqac1?<$BQD8k_;kw|fz|JroUD@RrLAa(F$Gd|%5@!SVOY@cQYWZ^n zb~;GDVu2Shn;V#m1F<{c92M&XoTpGYKr7T8c%_wy6wk0QXKYV*3UkA5(`1%5*nlzfZ9}bGI*Dyf` zZYQ(;QC;f);G^e3{MNjzvIB0jUP>%|{B73J8Lxev+F#$Q<5Lj?3Kntmbv8w@M{(9M zcRQ}@9B;88yvu5(KjnEDd%;cRZVx-z|4jOiG~wEWV0{E(ZN7xW5|eW1tt%sFYu^6}1-)Q(G0I9XV(~qyS|#Ce{Bj@=NGni6h`#|O z^0W^5VM);zZs8^jn~-v0=N*q9FC|{F$f+eTaDAi{3nAHR!>gk*4d#K0^dOiznXx75vs_w<1b_pE|@y_o@y|QX~8^blbhhav_wO- zH{Km{&I(KLh-;BJ=Iqx47snOZp>Zd+bM@eafEf2lAs3P|T&=n+5p^wWHEzD(uT z7~qCe6Jh)$NTP$|{mW(s$P*9~$(s_gn3P_65eB~lxG_w@M@Sv;ZlI(^FgJ)&0SFz= zY@&StNZS;U))x_k9FN{S{3d?Kj=oW6yW zfpC40Ub|lbU|^|iXJ5=YG8)9f2WJFiDLusC9mPh$3lZPCNcMCBRIdwsClwhpy$xwa zB)*Q#_HK6h^RZw9qm#j8*dKD2aGro2_a1Yrx3AgO@0PYPN@L zyhCPsNhauJ&iTRc$v-lTt_GLifc$fo>eFeD^^QZ~^}&dj%QpfNdK z${D0^U(}S*<~`SJzw9KZcLHI;B#7h*K+mLE`~o@3%zE^@Qdr6XABMd8$nZrn5%ugX zek}-6VmWWpKCYOXrlv;Wp|E1*${l1r$aiGXd+J5(@DYN=lUjI_=!)Q}24=hIA zgjsx^#qV_atz(+xl@sxBQ_^Kkip4E!X7yaYH7B}bfZmOWpXO=_x7%*6L+1?SK|11xL~l!9%VZ~~qBwm~So+!KZkY}_6UCWeDcU&> zyCyULkJ`ilO_1_tqToD);l+uHk!Hm&)R+Q<2B=`)9;D`i*RSJN%S()$yi!URgz_%0y3mmpP^TRIvqb0gdD#_`_yg-_8g5_ z3r*VQl;6on8<>Ba-!f;>Gfi_zEh&5 z6AMAnd67{4qC8t{jNO2Eyf54lPE5>GKDP577zy~!`p;Jy-vtV0FTUJ^l`i1+FZWV> z9`G-*#grl)b_2^H7zs)rUS>6}KQJ=p3IL24y~69Api8?&Vvee9f%2>39ew5*t!{bU>Qnq%c(dJ7$bi=HB&v7y9rHl}!ai)wm z@KrvHkIO0xX*~t$dX7ogbHqpM`Hff4V3{dr7$BL@nfr^JPEM^DddyW-k0^cS3BpRx z;r|41=y@QJkAAjn_|Oc0jDqXwpRRqxaYGtGPP~Uh>ccRl0^pCsfVnGJ20}vxSa1IH z07>kpJdMW%x6x!S0)+_syVhKVAW2eQeO7*jTZIr7zFj$Zk9at=bmF5klF2{a0EeVK zmT*G|^+ZcxZWjPSkhRfVMZ4~)T`aSF;FbhE2RmsDK`mlk0uWF_vpelnI8$m zMIz(RhgFyPc;bGN-1%Uv8jx%XfGjeUCNuLvDUb9b-6>Cqp$z+hdv~DmpD#-nm8(Bx z->M|SrVUg2HLB+XcIFkjF$@q#aH;r^qPGd0N#ttgz)sWra)gO4fFmM#+!qwNBp8=ka{@T41}$!Yn)=4!F45Myu?PR@D*=B<)< zXz!V;qy=s(p0^&4<_Y`X4^+H@KCF07VE+c5m(L08ZMIO>OB`nF;W>dT*3AiQcz#Y` z-|9ITpY_04yIw!B0*fOLQ)~KL{qD&w-_hO%w>)i+q{S>UezoO6LfCM#0f94&2tl3z4RDfaYySU6L( z*I2>Tu$;q$dp$AtMdC+Oa3KNp+y$@_mvR2R9C0R2x70~7TDpsO+2lmd?!fm_kwD4Ib^+9B9re3y#e#2? z|3R*(ypzR}GjIvN0_khaa?VdZ^(6vh#2Gt0EFm^Mk87g9gKzv62H|q05YW_{TY`2# z7?~g4CxE-rd0wDl3r+#tCm*<5bYSuQKvYj2+_<;sR-0n{MI{uthWZvVlK8h>04%rz zznBo7E+6{)61zLz(g0$MeNkBJE`Ni4a1NO4J<%WGzR z*B5WqN~M$lpWCRU&E1+VsRg#iB(|&#oZwhMz~4ouLja*0uZslR5h_H3%wfHtl!Dx| z?SdY1nG=!V!4PM+*@DMKk}G;?01dN%yF9MZXzJ znfI>p5bl=>RU5;h$q9kI$_NMggsI;k!`{sK^LsVrT!M(Wz+o0oMU}c{h|7b94M6Q8HC;6|56&s*a`dgEtG!P@MoG4VbD?Gw|3R^F2>I}nLFCXiuS0ag`sIzjgFJLbBZt3HuO&H zCR1&BcTUKbU;mvGdZ5zCSvesmD>;*o8g1VOGyOkdv?>r6=Pa3$vqWp+`gxhH(LP}Y zKB=4_y#bX;xzMG~ZxaM7vtnRT<9l-gckKiJ1)j>TB!1)$9tA`Zqz0a{vQuyQ`^iI( z^n*_yl9O^m%gRn)I*-yqeoL$isPS{o5T(g?(YCdj+rA-7PDL=hto$rGKT@IvK`sbo zKi#f+yF6e9RZA(c7ATu3T-VE0?d2zTcno?Jj?lW(wXTes!hxr5&Ve1v0gqX!cY1RI z^cB(=YW)bQo1><|+;@=@;m?EHaGGd8)!~r8KD&w7E@4DWyWUp*nV_dRY0XUIpUneV|q9n13?%I{jIET zEVR3sPFa)HVxgj#C~HkO|eZ}*pfJ~@N4vcc@Tgw9L$J!E4|Q#Zk% zM-wrpH`Z0d&0Q!2T0~ACZ_f+db(}ox=iw+G@EnM@^$6S{QdF#EF*j{$?JNE`?Ha1U ze1(DGzoL+K>ab1?&g(ijQM7P2q$O$3;N91+3=Z?qP%WK0fJb%b=JSGqO{sOF{1 zWV~~+HyQDd*NUH&?`);DP#A*-^Qc=3HqcH#bfK6z$DDw4l-}i=xp(5Og8gHjRiyrM z(a`&4tOUkvjpkw)S=nX1-QaCKinvndE{%X=dMN|Kq6>U=M4ah3*opClc;>1_otH&s zW_`Nb;Gb5Thu=H+RaYs0%WNh^cpdaH=*>VG+cmDnPICb|YH>ZPxDl!~&yKImi#pSY zWHhx+3p{V`LcX8{W<(umU}la5YBc5P#so5G zBcC?%)!FHL-udAfrwh~h-^Kc!)7gFe9Xww#;ApPDOy@zgL-+8Gz%o|KZHG+E3SsX@ zK43d7!DSHH>)NrUKn#jiTDi{3yDv^`VAHWeTCV1k&bj$Co<1_a9h&{4F4eh}I~y>9;4)N| zg`wTI0x=VaZHxwDdkKukoxj|Yu?HquguKZ!QkX0BM{{Eueg>NSrLM{V^Bgaj$s~FS zvn+D&G;~IQ&`f<()R_vjP6Jw{KJyB~Rrzir!3`?VSq*U0MVwIUWl?3tL_Py(rvbG3 z+0WCT`N{k&nE>uI09P}=NhUS2IqLFhz7v4sGX2GJXxgrz1^|}1|G2V=kFy>c3e8TW zg&2DB$&@c)PRzrCC2=eHtm&RCMAcDvpA;~onj?(&LX~INit^~ zA(N#nI?W~gD5P9`*`+Om1-5|Q`4-0;65(ry&zqbap|FnZq&V!XlAAl`Mw25xr_?i& zL(p=>S#8EZi#QwWDmBJ4Rl;AgHLPGA{4)18vvq70eyueDO3F1ITPc)0uSas=dA{cO zUVq?@shm^d1)d!A%2+D9>-PG(0k}x6Zr>*CaJAG~rxiBQtn5X>^8-|`5%nnT2Zz^C zEJ)LhQb0Lr>|!>Ux6lQ&d_dkIs;Z?7U~BUg4q-xpv1#2JsSmPC_y3P5m%G6lIJSD-mm5^3OFXC2 zPjr#7=iPp7$ zUe02{ZkwPpxu2kDeXuULlHlxs+gP9awA=S1CaE{k)plw^$Gj$V^Im1hsw9N0}kySuMg>RLt(Io>`Cjyf&ozZgmfoV~E+7x~1j=P8*jH znG>koowx^d(8QOMzV#*Q{;Hx@_;QQ$*3hq;)kV&I%nV-(OS1OfggZ7aV zl{jnCYr_^0Lg4L%GRTF3AUEm_ei7gP_#a&~p{1M3N-(?uI!yySXK-WdgiqS`&!;oC z+gZLZd|vNP?{4M5#kKrZTC2_N;bRf&ePI+7qT!RniiOveL> z7yGltV4&;+!S0-^pu%q0vX*%~t#&}x0`ISp-^{=Kx^+S_cPs+c@&aP9l^4Kh z4~sb1pEN?I&g-DCF1@7Xao9%Lhtrcerx7J?Vlw9(!AWjm^DN9C`0(?vhlwEi>)jjm zx=oU90RqJfoDlJvsEST!zQYJdQ;-;U34+&eY?0 zY-6|Mn4raD<#sRHYziwDSn?CW0#s)u2aW)x5f(z|Xg#f4UZn%-L)jvnXZj%iXeA*k zku$TnB$-RRp7SBAe2~g3!2S8=1Tr~(WiWdDexC=>cs)N-lb&>RCw+*?5}55+m1~94 zE4O=K+hugl>l*c&6%@*-xYasbt@moJ^iI0zbx&K7+HN5e%-&45toYw^%5RoPepNep z#agOL$DbT4^azsnVc?Zb~qZTSrYOcH8Vj>#Myt^nI?J9*q_Ff;^aboeX={}~;;9Pb!TFaeY) zRP6ntte;HB^2v0qKW1I74MYF$%Yn%4DO#$7>XOPwvNv6hO};e_AEryn@iSX{8uPuA zo-F+a&?$cIhk=CF?v5|P@5E6vQE;P1%( zs+*nHB|EPpTilBIdT5vIp&i+$O184DwfQXz(2d35t1Ew@kR6av5J3diKK5bNstC@+ zRy(#_8#z#-2t<#j7YAGMg4`A@gZ&~%d% zhIVUHOD&dCagh|&=8IglY9>7IIFzOCDPOXj}W*gxf?n z7O3(gX@`w}f*J*RFP);viJc0a8*J(TUUN}?NTN)mpKn1`!Oy z{Bie!TQE0eDy5tpTFEoNbj*;fFwgmJr+bIt8-_=GDFjI=$8pI`Peu)wXM)K zP0?h}pB^WmfTdHTxe9D4C**W7tiMKdbMfV~5+t5`%^oxhvPs4C0?(3xp6_u1|yDU@W$ zz{F2g#KLCrQ^MS=+3u}0Yt1So#;&76tm1Rg(7WaR+*?2)xm!bgEkxj#G4hw|BPF8v zeaj{1L^UgzP9)#aHlL8mXf^dhm~^~Ib; zSrJ+K3I2#K{e(PzS^fz_`5oHoi#q#g*Gf+PFj|^|K&x6+F~Uw>K?i9P{Z@7YlaP8dKiY4Hoq8*uBAjCcIeI5wirM|z?9}W0Y${1ybsTpZ zL=#s&%4yA4z;MZvVi&@j>?pe*0Vp9DdXf&d9PUJ-1sFJXK8z+E~mTYE|c zzLn<7`t9POcIw^y-7i`Ne{Y?*z}nsHb*_8q0{V?Q1eiTqp6Dpp0ZO2tL85LI;D5D| z8Ey4h&fmQrvxb;V&}RDv#V7g&kl><|NLO^CFh%$@51qI$W#N*$R=~=tEAh+Pn)-WH z%GeUsOHmrZEoP|T7KQnK91bnx$T`gR{a=@zKCe~GaZi}#QB-unX&vYFY{5n7wd~9T z`)ler8K@fO;-b@ZCL2s2DgZ?#1d|KaPWFFr2sr3HaD|u~xYEZGl!-15npSa&9cnG_ zqXyniUF$f-^lQyVL<&WMU5W$u)sg<0C^spK9D~wj7rJKmAgbDP=q~lV$X`W1B!T1)lqw(+nx{Yn zM1t!n7O{gHs1N~Av!%qsUOKXj>)VIgGKSg+S^~11Nym{5dXQ}TMITq&!3I0nL}x)b z$B6ALs*&WG(Ide(iD}0v2uQOaeF7qanO+3zgp<>JEP|jN^bh8B#hyD_OF%a3(#Qrh z3&!p!^VA%wF2%-h&|~rhUOphQ>EY~7;~E4;&@Y|HM!$e~DgGqb2C=$en>4by2vY&4 zuBB9QjnFao4)o}lwdThl&z2egKfyI={PM7%;E~0wh~k$IKI`EZ*FMBWF|Y!sM?f^L z3S~2tkLd|TDKyVJE}nViD3>vKWSomTHQB{8M1jEmBm>Xv>yBrd%sfO* z-SEs~YU*K!_LW_`lnaBwVwl*UO}AZA$IEu^QnMC8HQT;S=55Pme3{th^N~ae9}BiA z0ecFzDS^}xY*PaJIx(N$e0~f0Efmt{9k9<{A>Ou96Ick0cMngU*l1)L8x(#1x- zpn0^D9MXjcz(&I;Cy1ypjBDZff_p{?a+)3%b2Gt7$hD%DI=`+Eqy^JqITz$ae07!+ z^T&eAL0O|Cz8XPYV=WnwVkX%AI>kwF6!=8`*-BghO4YSLwabj)4*8#b)LG%#YOfb%>>i__)4BknYcBkz=_L*mFZ ze9b~hM>QTnmd25@(l~NOCW8k|1N%af3G7=Q>_d_%>{}k}TZO{S$xC6K<(GEMa7WSR zyB3?zk!h_K1g3a*(eN~ji5T+h zEDlVNu$V-;5f<}%*SqNUAy*D_2LLMw@N~WxvhEH^7MVc*5Bh^{kJaR~9Ok+U({h+{ zidBrXL%YidxL0IYPO4?L_brV49+*(MdqWvaFixsvf@ESfdHK>l^jDbux6Yu;v{_lG z-}!7ugfYT9x?+O~DvS}{k#`X41o*2-`TQ303t*w}NK6{Z?`VEU^IObsu~^RTvoQA& zSMSmkv_=pH^I^K+GML1_%j7Q~&fqWmEE-;|olC|ZJ`jKT+loOrveWkqgfn{>#*sg~ zNDMLD^}E!zvqb!n+TI72j=UJ$VhT>N4;&*oa6uPT!y`UwJImY@GAZlCU;%}*N6Ky_wf-aZZY8z3TiJxLyYQ2-t*pB_Me3s+TR2g1brkdTOnb)!G%)W%Bd#hu`2!a4*bK7;M# z^tBUmZwUTHE!pMoc3a`}{QRD-Fh3|4Vx<86CaDA(h<(4V#M#&xkKT52iIj_NUorJ< zr@oTVrbWj`xKuaT5GzHjp=1;-&wd@L(kB^@8^7%{UT>V{u*CV)D{96#eHcL5 z@m#Y|mX0V%{2$9%Z#fOLQ5b2zJTD^hQmm76V;rw;R(rD&xl*Fr*bg*`uKjz5RqH%~ zod*Qh>djy!PFt7|FprWNmLM}k8bS(bB`4<@q+=xZ2qZ5d zTN)ov#?mDJ;dLSMP?cHZchO?{TmW#^Fl`;y7~*yD;P8hj49IRdRw5Hll^2w}bDzn| zW2Vj;!%Wfr>27c-#>nYpetxr?YU_dZpdMKDX44l*g>be-ld+A)Jp zOZi-BN0z6FiE{#gSD^AS9s#jH)w_~*uQr4dx@cAV%)EBDUHNn!xh+5DKQUmM-nl>0 z2l}5&(E1^R+3-0f4Jsd@D3DM#NVSxbvmU6Dn(mNFl4qXRdq|c`R|h|^lb7`H?4<%v z59C^dwPqitSa!UPzRslloP>`%=g{Bvuy1S6V!an~*7Q7*Dp0=ILDSiv=O|4dH>T(B zw*68(ko*S8K*F%aCsG6d7T+QQL35d)xnyqdz|%fE@B{&fQny?dcsd;HQM5krbU)jN zo`R5nD`g~o?D*d7!1rpn*byz}y)__Ge>;XYwLMyYKz=oIo261?iTs47_O|xXOK~o} zqk-_OboR<#L$X>frDadT_~HzijY35#MZVG4HJER>rCOJE+JsY83ja$dP7 z^va^|s-*;dq9@udD>)Nx0CtM=$(j(*++ss?iv#Y5ch37QYi9?4n~0{1`gHo+u4 zoSge(q|c_<(|%orFh4mRI)1G=)k`{`Bzf;2cQMWvcsCZ(A1n|g{dD*ZAmi>6q#Vba zaMxm0)y%Ktzk~+vi+a4}VaRnqsdC7*{MyTYRi+3Z~`@U%733#$IK+g?P&Fi)k-Vo&salzUz)D4#;f%`qnk1!9xKBn&{ zzJ*k@VtRjzSqq`ai`hI?fANwxP41%{Sg>bp=1-mP#l#9TPw*~^A=%RXsLPf(WKHJT z3rUu=_dxvKS<__R80D_~%Op}zc-DK<1y@NySx`y+qgU{E8DEE;?dECDXAt~R_gL*n zIhq)p`KczAy;GuI91$GuQ%t)weFGnxpCdbz&X3gITuPEE!D+kRKcwO$1 zJysy;>v&VynAbf_pR>xb&S*66eM#EjMjts%Mw%C(OvDlYPOrCR1Kghe+3Ts*zC0Xy zD{$A>7=s(eq4g1^2Rr(ermH&=J{fBKztYS=cYC-F&Lf|7Gs6m5MM4caEhSgW!$Dg-FlMv=)Yt5P`c80RrV!l`3Q36tjfJI-*u?@5fm0M7MB7|fC*-vF z-abr@$R|0`;C3*Ld5!Q7=IbLV>gAf-F>>)vk{ybeO6A0WJ(?$^tDN_O*RD{Kw%&Fx zBea7lJ5+bm5XrG6r>;&gj2&##mRvX_pd%z&hmG@O@2czN@gcB(2 z7lDW%fgTy^mj5%*2_n-|X|2g}C8?DHR@4ejTYjRR&;-MDUR35fQ1XKLWr_Q-SfaHO zow$zAO^+fs@pcmRo8&EA!?o5NZ^?QuU#O%(g%a?{NZ#gZ>ZL-7*ntu*NUgtVup)fU zr?sZ~bhoC_(u?Go)q8;Y;I2sW(jNE7evu+y1&G}JB7Wuv*e?L#?ed+|PDqr)^J7ob z6XnNFPVblFq?smh`s~7w1?~`A*YWI{qOMF?9b-Dwwz)5Jsc(^bVak#{Uv3+WXc^E6 zd_(q2_ho&MV_cjH?^GB`(@;c_kdt&68>n@#2s-KNV6|<~{Y12mHsR8ME*CsaE8LB2 zF8m)^tKSV@BGtt+TxmasXy)JIyy%9{U7pR0moeicCP8G7;o=5d&ByNLRaYg zr0+jC(VGtx+nWPV^()bgCbQ3MV_@AG`!kM?dgT;BxQz$ef8B>5%rez>i3UX{Z*^l z=JV9v9?oXVw=UH>%(ofi(cLYny*_7II~SJ^!=wc}Uq3ua>DI}~+&3tWJQ@N!T8csT zp!>*)#Or!m)e$nF$Pu`ikYsBBxIpD_L0u9+_*i*h4t^Yx9q3~J&uUt|$cmho&GEW% z%lgf+>UxdLYN@9}(J=k;e4S;#wX)Z#kz_@-qZNUaF)3yJ!o9R!o0s(!)L zx~IdPD$%=NFjeT~G9r<2ROm;~9_XXH^`rSy@ru zZUZ?K5hD9ZGJ!AvZMI5>Wbe!a620po{*kLq{zveiz@L2z&FhE*o9t4}Y5LiBn znO@)1jkwAEkq9iVP6yuoju@>8J)jc5bj`J6Zp|y}wKD5eG>*;`KO8se$-td`AU3G# zda6p__vQ2(A9(8gRBsVrJVe#VCab>3FDK^tsa|lOl_dO%1T1ceGsjYi9zzZFVjWkJcTEuLbl!kgiu71fJ?a0ItgG0I#v9+R1C=DBX^H zW$dX|;NIm$ptOwm>w)KTPg8?YV-HreJOKF?Vtlzot$kRUmkTYxlc)Hp*obwD0L{Zpvj;Ty@i_L>X!45eXrSb^qPN4&hhtB5K6G9Nbn2eX zBUijR=Xdfm765b{%vaxmozPQj-?mSo=QUk*gld)xK8wd#IOTc~!VqT#Do+BOqRtnh zNS%el5HaZ~CZeK4*YeS&XUdONs?9w_iKl{4jCJR@JsO^`D{yV2noQubLKA^5IqQKg z`Q&1#B!#a3kG*$+kE*x={{uL7A3pl9wHVOaga8R5FA)Ww_-LINQG7wrN`BvS=I-V}P;71c z`~Uv+W7vD|%$%7y=ggTiXU?1vokXIp;QhC?rhU#eQTG%4Tih4j9mIZc-&riZ^_RCe zMIUnKe9GP-^7$yUR266LW$zXAJ1aQykmdB>n{ zPT;UJLsUAna{!KCFYwZd?EkgLRQ&ymQI60Z;-_7oIRpdbFkAuW@zj)kCI3QnMD;4! z%*Zd}Ih1sA(FEH*IS@@?i&?P`Wo@4&_UoL+I5$>S( zoDFYc?8x4})F1m2DuJyHA4jQa35IZ5SXJz{#apvx;qCBtuUUWgRytB2(_WdFc0JjX zZoder7r#(mz+ahLd-Lgpxqg2|ts-`_`9+Zst=W8+p<#FbtFYmLNExh{iDV^=vjnzz zy}M&|Fj@IcbDs~X$r0c7;IKKlvB4;nEHhR^nCvqlOygwjw!h{VR41gk>J%l#VQEs_ zIoXopj#SQ>Y%?5m{socFDsL1Vi!huyFIwS^ZFPxG+b98!x!(phOfVWSADc8+-3 z6@v9=PXz+cLq9j?SYVEuefY;mWHwhT=|4B1_vcM0ZurZSIwoz zL;U)jVBO1*^o~F~cP=M~_HNjf33t4VVJ*JG2S+&A3sb%(vQ-ENO%chGTu^W~ujZ$^ zg*59(776!LNCeKCz*{0VG|oPc@FEL($L!9;0-+xpKyy&{aZ}B*-|yqQ#Hp7|;wEqh?_z_b z?bc*35UcqpCq>Jo+9^`)NF*y3B!Dl_4~wOR?n_0R;vbj!M{}%n025lHIqfWb;K`QR zs9nIoR9w2kfBkSKW?@V@k}B#B=25Z2pzj=B;XWxe$k)RjVxryE``vck3?kxlXlJml z57mSH3&mnc!R2TXOQvYwvGPgNW*`H^zBgaVE1rh0u?K;Nq3}Vcm@a!G$h)%DzwOQP z`y(>r5Wl7yzdvCHN|!&4-|hIDVawaQ(vr?|6e(2zp6UbRvS966orQl; zXZW~-2>5UG1pY}2|BZn?^auD~+XMVZZ2r_;ZwkM6kMK4A4|9Or-98CuX0|Pgip2Hp z_|U5BVAV;SIAsAYK2)J$4;S1`PJhiSyvdrN*?i*|hD0({(3_ej$?bs55&qf+(t|S3 z_2uSS|M&F-I*Q?33Ui}%&K)v^R3ZmNY2#FtFl!lxr(kkAJE~^h-*FOFSohU8@Bbt!8^)(Oal zxA>-;=EP;rG50VcTeHm(EWKE7+$P2P)huS7ylyraqiB!-`$t94XmMv0qtK@-d>y8y5HQL$6l4aA~U1aH+ScmS7olq zY3F^AyIw05Fncs`cX3MaStPse|Ub4UhlpKBzs6 z6Y1W{>E?bqu!8ZKxf#jnLy7i^={n@@^w(Sp4@6+?wQ!8=jfk6`D5KzrGsWC3Yi`9f z=o;Z~zg-zm=7Taa~nC@ z(gq?*noIEiqSES@$fnydtIT;AFS(SpR5!=u-bHioVcN3l#T}VSY$mq8klLE*Ixo`# zGNEP0_VvK+qd8~IZ5<)By@S-&b7)YP_OQQaoAWHoKW3B(0)RkMFc4u5_3YWKwVu`r zVr2h=%~r9LqTI_xR*eGtSHNB(Zg-5z?e89#_DFrh%wRHMdt#}kO4b=R*Sb!*TFmJ( zm2OKgPagMK>NuC=F{aQil<^|5(oI1k&)OY};$W9bf}>dSOTFm`b+ z+2fz#3!d`d{xC;j6Jv^vBX0fn?;9kvRglnD!D2HA+)Hf=t)&lddqhZT{q{=>k9Crv zNjGm}5IebMq6mAn@l+K;o*8@=Ivgw{6C-O%Y_2Z!20Cjt>B^73W*cB`k_Wf3i5^R5 zq5Eg(0&4&A_KWtlZL;_2nGGib3hCYX0#@lHVI4DvNG)s45PlQo_UhrL@}blSV$(ZA zd&EKK1og*L`$?yp7HazdUpDemVUE#X*XWJR25}&}@Be^yV$7g%YfKiio!T*;x9=Z- z9l;_=E&9kIj!?l&^8zoa*yGzoe8|XIZJy4SaXTw&Egnb9CZe@lt=BF7HG+f#O#(@g z;&>ZXf;rV(#aBDxbcm%BfGcMy#pYr@K>>8H^Ct+cwgI{_tB;{B_JV zi7SW3Kf$V~+9Wf{%n;Sm9tnOnSK9MEs3yWp_PnCW(Lj@Um*Td&J;SD~A|+IGX)#)J z*j*+o!%cE6<)c?_p5LO@)TOKOlS z%rD52s%DOGmt(~tg#7nsk-bAqK4J@nJrBDzChtha!B9`yc}4qg*@_2Al>OgkqFIZj@;L5u?wFKK zpviipqWNwwZE#SohQQV)M~G$}1G9eTO*>1R4eur^Pft3H%qpjt`w(O*u*x_Wj*}zz z1R*n~wJ&vdG`!u1J>aZ=Fh??Qasurw8KPauZMU*UPeohggiW)x~zFKOBv-p`pfr>;Hp@eB+E5{Qv1MDUY&%x1cAiI260T7ix2un=T^mUGOG*Qkr z!#H1iL*|;qSf7w?h&Ya;H%(I!VKMg~9q!7n-h4bylo%PCgd*4}_uGEU9hsX5=0eK$ zr6&B5k}q~C8^VO1iMss*Plep4qHfNx3BEbUrQ!j*eL*Ne*^G=OYPw$#}1cAR#?}+iG6gX}RPsO;Lv0Yv&FyS0)kPE&u)zkwABpe_v&9 zB*niEy%)r1-bx@HGEol-CPsrnoORa2y7%n??|~(idkF(ZyVS$h+;2ini0T zT!c3~UZT7TeM1D<*zr%WXH=9=n7Lt`*Vr%2eJK`o^~O*>?nA?MSKk+ zuCP%S=Sc@`N`{GpK>XyWdxC^p6P7KB6mjeMYHVo9bA0$qa6fZ@MKBTpE8d1J_*ZN& zLl4c2h1(#l1zmRdQ_E>8~dg@~jUEEn-e+O(He{}@7%UtT7?Q3Z3Bio}UbE8Ra zw+tuN`$FAn(`&}XGKk>S`)Ne*{)V>eCWkPyJ4D1TxSfQUg&PsS!st_w!6JLZ?)xfo zv5Bw|=Lz0u|7})mMuw~q!P`mhp6tn8_}Bduc}u~r@|GG|Y{Qh3I?3D0R+R9}NK=-a zAt6d|Cy9G_88*^UP@29$ab*@OZ&!=FP4)i^A;cbl$oy&5oqSqnP7t9flm4rgMw^sI zJ2RJtVGf~EbZT3;bl2>I5iEzYZJpBXt*`QA=25jdfODBlCxwf4xbN?H3Gw2-ZKuA} zlvnzX*uFvc8FSYMN^O7jwN!6q%i&{^gP6j5bF5Xx%M{KuSmAPNq-aBhyDEellKdXh zC8YPi`$fK_#mg$hi%g|m#mlD1)a9af>r`l%3L90raNJ#c5K7EIva7K~Yyu2b@8*op zSRL*Gsh{$>^ZeByqE+Uvon|&3WQIkEjol z9&gX88pt*ydWPA8NNk-Yw^F3O9Dx{by;Lqc$dN0p^II!q;T)x3y0qbPtPQWCK$d<~ zRgfGctB(wGg@qnFgDa!-q6!5)doX|wliH(R`bm1F)PZD?swb4Q^t+q|(B<3*V6T&s zX=I=*XOY?2YD1NEne;_ET!%_8yD)+pS+rSv$>xG0n9YS7_M_~)WkLzDA^%sx7bri; znCsDLKVR^5jtEp$=?i52ulW@PG$u)8IaynxB|O>VZ1B%)1ik%XVP zsfR}0eoj&%%RR$AIimaZ6Dv+4>u{VXxri}Tu#4$_L?~I+-u1qoeVpWVZ3H9s;f|0h z8*E==hUn7W7Uu-TbsK2}_k<9Uy9pbwEE0aI+!igEri<#0=AL|^KuF%#*eo(TRd!i3 z*nxT;*l(Fk@vejA3wYDn(K)!c5%Hmp zBJe}YJ8YH-yLbPtCj?=7%bi_{+>fP`xJVxguM2gj5L6w1jEh+BaaXXYTVYm$*g*2d zIFn$J0v!$mMXB=xYs|T*hHL@g7m^uG76e)kn>9?+AtOfCHKw#n`e9rfBp`84a-ZP_ zAaMO8Dx5hM8$;_6BzmCGYNj?*iGcL7ne&DnfJtMu6u0O9K4gURA(HvB2wR%CF_MXq zgydCbGiiFeRihg9aq+buD%@q%Os$9-a~B3+;@N#guifEp-epCb%=P3`MNrl+(=s>3 z3JJ3QH9~LEATEtt%hm*5yX%|;chs-Ds=p&K)+IuOz2n0(?`rg~|Dq+>#&RbzB@<{dI}pAo7X#D$}nP>r|r9(0$u4P@%VU0 zt`hSQFPs9^Nnoth#SYJ0+LXa5(|%z|lM7e<)e<`bm9(H(;=za**8 z>%l1~Pa5-%GaH@2DgumrbU3JjbKym@0KMmT|ZI$t|TgLIarn*0B5sSqGl-e+Qc zqO}7B{_DVRIfI6%Kw4|Aw!^17hrGf}>SE;LNkM^0DRx+Eu0?)IgG{ zg<5rR`-;-{XFn>aSFNe;N+H0r`~$HBlXH;t%HB0pU-Xh*OnG<;@jBA3pgQT#MP$%x zCb>i|bzmArPkHSow%{a>)ZsurtOg7?JbW1Eg57U=>G`CmN;8%{c8Yqby-5Wl?n@@@ zjqZ1Fa`aZo8pdOt__0bw(gT%4t=CH5R`MFGo6f(=$Vm;q4P&+(u})tulq&j=IJ9 z?Ur9@KUSH1gq1TD7uVG$Q#WL)%2H)pCwj-{SDUK$wYg_VFqOGd5~ssM&9iLFc@=WM zgn}Oict%g_7;8*fB>tQhx@-+H7G9Nj=f_HQGhf}--kP5l8nTTE%75~7N@(mbe?cS# z>Z3`t$B27wNyNRpEaG0}MBLZXUP1qL&EN}AR{sa$GcnL@z2sT)PH9n<%kJ!|Px@ty z4imRSFW1{tJ1(2Sdlm_St-~(Q^;a9=Uw0L&O7nG_^GGjeZ*sbAGNkV(Px37MBvzR# z#m`TiZzvo)n4A=p@8|WE%$Vb36P zuv4!(nym!pb?2Dj`=aeq$No6qEeA+Ou)SUnt~kSn_xtY4k*W2m1kDTRVaGA?Vi<34 z<|5as%tX1*=BGI~>-1gKk5+OY{BjzJ6Yn?N4-u4l{;jF>D&Mtq6sy*9j{Oi7^;xI% zqcMp=ef_u9x37rA8(1^8MN5~?*dQT+hPV@arSDY@#=HmcKQL60n6drnUpuiPr?O8p zyjg89D&J&nhYeEBUd6wF+k!un9d^s0s=4~xMN$UA;cYgz!2plTJ5YZ8^J`2!arCfxx?CVW~ne{ znfU+b=)}Hej5~OnXox?=xXI4pCB>i}xy7|0a(->CyN88Q%@(slkD+ITP*%f6m>a&$OJg0o7tE{4tY zvA~e5q5xb(bgTnV^-{=xMv=b-jZcw}GR+vL=Y2U#N}O7XVenN7;3bV!bLKFmfQF(+ zuMzyS$lqWN#S8@gqZa>B!T&zse`iFF=A`gH3j71c;y*8q|31zz@Gs~eXVL#;#G*eF z{{T+E%5v5bMSs!r+nE3Kl(THT=Zh&RBoPE@;LI||?aL6362JbETOzt&)yAZ#w_h~4 zE3v5NJN*fa_8}WA@}2uF`Zw?@g^_5pSXQTjb|UV7#aw0gn>`L_Ky`rwq@#AbHg+zI zP<4Q5WMi+BOb~>y4D8EUbBLbxDS*zKG6k_wit-Z)cb(=t;ejK~^> zigm^LJfcPC3$MNV+V*yuC0-N$JWutJSdl0D`_Ooi{jq_bzQ4*;(PFVe(g0g`{F>a1 z*b%DPBqlHppEZ;4Gw?)wmwe0xg&lLjp>{4%-0Yq^%C_!PkzplQ9g7?66E?oem}7>E zDWn%^sX3s1sml7uu;IS%ZqbV%?WCbu$rfjjRSnR|p>&x`N1u zUQvF47tl|O`NGIfg%`msA947mS&7>$qqrY+JRS4C^g2rpF_L#!gKOQ=yyXXd9b*s0+z z5pb!+oy?d+kZI`^Q7XT>N>1~NT#+i0vcYW=$ttZlBb6cxHCaoX>=hYC0_z7|8LTq> zt#d~85WWg$>QW+xQzihlroy*v<77o7-cYg^r;bdTdiG|UDvRlkuODo+U)S(e*2Pb< zdhcbnNN?N?vVQmxi(qY~Y!b-b!gup~i;fvd{-d`7zL~EUA#%?(efT32BBN`TJU@tq zm}jmBqGh@rn6Ic_MM%RF%~#bFG;@5_S3A0Lo;E91+R>znjwWSzO{%$CY!L@pGYJQU zGEE_wgekQeq&9S4YkrK_<@l3jJMl}N-oc%FH3@u>=wI|p zG7775mwm98Inb6UvQ{LSD5qc>1qLb(F%%@Ka~lpKt}Vo)^Clf@RfcB4wu)^%SD5xU{4vp-oSNHMD!fnY5quhgXs@2Yo+ zq!@KS3T!naMdM5fs4?QqY22UcMGi_J?Py%2aOOZ*aLjWa3ugP5r8kY&ks@qXc@V!zdzExtTt=|nqwq*Du#zQmAWa;S%beuH z1+rWX{#8wEMR4evd9SqlDLb!0Kh4{jkt>jXCuN-E4f@eP^6hBycl8X^kbmSy5nMJh zcR5~8*0KJP+sxu^!tpv;{Z1d5D^{C(^zpHRNwki2sLV1l2jM;|sY@}A@>M@Yli76&uE22BxC-`pt$aNhhlldp1C)JExzA%22N4ozNdrt*QgNUUdeB9L+dtrxC4 zL5&IL6&A5FC*H!LVN`owtE8`*b|U$;Ml0S9wnE&f8cfNh#tG;dZk!5X{j28 z-I=;12v&x8jrhpRIC)PQKl;Gdo8@H;XvXg7+~2D=+sieOT+-U@UTb5kdg|kgY+p&P z9bTztH|&8Ms=P*Uq({5;yFF!$dKm|J8EZ6S_tswQ)jQD3bpg4g9hfzgWmY`VQ)|EC zmD=f*I%ZFeXnNm*BiM|#HlxQzY{6_Um0}aqT+cmaOCdwF5y2iCalcpUW3SY`l?)FL{TD82^r=6G{kd%b@V8{->;8;D4d9gJ@| zT$Tf;Qr+&-;T{Z{@sHcDtM+Iw!ndRDQPfR?`v|c37QcXbzo{oMlL3x#m8~S?bEjj!hMAb4AfJksWv~lCdIr zHLm44)v{X^8FDtJCp53IZuF!!XGpWtpF8Bo;VAo7ud206GGwYw&M#O;KTI`Cvn6wR z(z;9)ud-;?>0Hh~v)sW&N#_0ZPRGA78o)oLqWrJWe-Q&+^}|VwOLOeHlz#Zm;Uqb3ELvm;1r>37i59hE6WUpYyEBsfSs8;)g7L}H zA8Q}i%ChC4m!;?<#!xOD(#Jd=^X()09aj(OR~8lAKBSMVEx3S4A4|-6a&#EmK|Rfi zB$KlG)WbBm9;qSV8B?XInW$@#IoV3JiK6dU*LNs$s(rTMTKHFl znCyq6b{2Yh0U+*JSVCAla2f{dV0#mujI)V`bx{G$WNKO!^e>uSFajMPd6;ERX;8@` z^@D~bRY$j4!Pc>HU&enjH%qo|ppDJY(iX7yhYqD?@cA^<>` zLYpF68u{i8>?vNCyHS?ZsySX61+=>xDIiXC1U74xnMTDL5 zCci~*YqYR9 z@pIBUb9)_xwJuM{_ADwb&5crBS(IxdxWIm_^enf6AkXe|6-Aq!9UHv%kwqN3oy6b* znFPz=3ZJ&h%_@it3AVAhF*Xt6fQnrIv`(6ri@7atFZb`&;ZE*CWVX!}8!Rgej+r<^ zo`?*o2XuEZHa}T>HpL!g$g%xdoKe;%$NU)O6I(-7o|7E-NfU8{#I2F%6PtOylV@E* z(#D?df0Far=X&R}9}+-f8`|u+Ab^ykx0mPjLfQBlpd5EXZmd5Wd;6Lec8pv52Nwqf zx9>6Lf^{eJ=p+v~Kr^l~_n~D{<7eOFrBv{&C?}@sXLn4)tNqAod!;04})t_$3$7B#}|)@Ec7I{2r)Dj=2Xj z@Qdbntn$_zk}8GCg;6~w)2Vyle*2%Z;}s?pXZ_nw!{2*vADt&_))>n1TGNIsmaxy` zeV}FtV1tV<6ioERO-;5+p~Xp5*q0Qke=2Fo%8Qat4z|dkdFV}0gGI0`@O;;Xvqvi4 ztwlNP%VheU#Ee`sXCHbfd8Loi({wlgT~l^vdi)%9R{24R;qL2{Zul;{Ow6B{uJ+}o zXLfY*APA(`IIss&MBUSKqm*H@K4QBD?Vcd_uO)Z)9(54zGLLX``2~*+%Y|@vLby#P zhRE%SaAQA>aB|`WMVb9?Y(cGuS;7tcCSbA43x&i;7jd65Gd2ln(gbwKA;}4nHA1T; z;5HHSdr82*4ERqIup498csS3lP)fpotqjuX%Rs1OOhSY>%$g69C-Y7EdZhOCV&PO6 z7L`Hq9p7Wbt5m#%DqDlQnUe1(oo!Up7m(&iua2Xrqph*WI_}2e3{4rm=QbuLNsxw5 z35pO&mNCPxbTS**s*N340Vj^`?Eg;~ZHb;;D>wADN7#X`+S(XdZ(>Jy{)6a4a^SL; ze^IW@6RbVm=KEWB(c2A^_EqOYZ$Eb4a>c5gE5tPezCr%c#bBN2O6G?W9?q2$o7l;p ziVc-P^A%2ilF{7VPuSuh#K-GPMY4|f1s9K$Lf=;r(&#je7VUiC!1BTwo`} z!j=h-Z0meV#O6Q6=C=+8LAO?H+gdD+19TT6d-MOE^8cCrtS5;6<`16hFA0C zOYeqPaxn$sh_AAw=6NT5H zRi(N(1rwr{+w<1M)|BgM{;#^VH#OcaW>pJQhWv~6Wx?TJ6cnA-zv%QVxFiTih5E1K zU%vNN^Wr+5GWo_&wtrD1%}yb%!YhX8^bl;6HK)5J3Y%uI=zAof6wDC5T;|n5x8i06>IB9!Gi;n}9XX_HTwF`Fs^y zz2s=-8R9tc<-TBG4df{h^5mNj*l3p!$N5CF385_(F!F0Nd12&38h!9V8^WqcN_mz( zkd&~xrjPGi*VLOxf6t2kOSeldB zf+xfJ_^zB8-$eEL+s~lHRF0lk&#S)JpApGyXx~D&iL1Ao_RCMIFZMZC`(>Z=_ zSp_kvtoq!r1`>;o$kPedH##T1r8O3PIB}|PI7uy)ct$Q5IDj~2D9{JqR!;u zH`07VW$=ysD}2+xO?LEofoFZf z)o={vjpaW0w!mD5YQXT!$2d_C46F?Xp3#9Ca(C5c;%4eLFnlf3$amoxmm5-qW#m^l zMt+51Y9}bKh@IYFa|XN;!Zg{LS=2BXjDG^RY@)w#0Q(M4(FY#Gz37|v<&C`lZOmtU z(lO9R=XlQ4hHH1W(QfIE2&H!w8}zTh+|ArhC-Q^IurGvWNpA?N(Hst}a56UsnT`uf+Z;BnA_En);uJtASRK0X3{g`VX>9S3)-JeXh%aX?;A+zDl zyxIwLnE$tn*A2R@9&6&fs*?hq6cvXLyglEoc4J(IM;qcTPo@mnB?V`8De zbHSp<4fVKccY@^s$xH(w>lLKuMF1wCr8IRG@d&`cb8cfWFml=+z(_9J7QkGT0wcgZ zFai-U(iZoODZ$JQ8DQU5 z2JPN2ZIJY=au0yI^embJw0qCAW6s|8%TlXMy65$czJ#Ef_HXYgHayj!-FxOytmHHM zB_LA$amNf5`U~N^P^@^bDQ0_C*tKWJrFs^4Ztpm;V9)(ZQ!M{8dj?JirvRmT*wHhk zSl;KOSZ>#T4NCQE?AOeqNkvKgFD}j*G$fPAh|*T{GKNl_(F+;LWv6yRtU1sFxz}F!t?(@DBb3R zklUNN;E^B7Tp-iHbKy)j7k0X1vXK8sd~XV1`9e(3MGd2bPDuZd@Q;dIZlO}~FH=Lv zlP2z%0i(PrAQU(#h{1g1XS0<%cF>-=$}NWp_G%(=$EF9}?mQj}JmpTv3uZpGck&-; z(rLt{Mw>gfz)FEYc^4tzO(E{s<5DwMdVbVtZTGR_mKV~ZVA0Y&j5#S`VYp+5rjXN9 zuby)!d@dQ;W3PrwTcB0>XA5n2Y$(;7o_bZbm$XX3=&4H(%7IYs*yz7Tt20xy`s^vz z9XmPIqMmv+X)kG&g3(j2o{K*!>NBzN_zT`y;n!}#Ew^_2>03gkvle)YFI9Jde%+Jq9H2st^7|M9!gC7pWOc#JB8SEQTJQZm=y@X8%y^ThVhVegZ4&)~-bTi(RzC%?L`UKdK7m9ij*YR_uzk11Z4`eCCFxwT=;+q&2f zzv-pCCBGzW)$fV3o~{kQU3=C$YWRMFj?mUk(V{n)v7VrXOWW6QhU0AU4N6w5GvnED zch7nnZ6xGUvw{q}OKbPKJ}L{guL#wKTd5N>u76Q9+nnSN)(#l%v^TXkV#MVv$xSq3 zi`;5HoGQY#qcLZQ72Nho&EV2Y9;`)!b-0iJgS8X;gli{a8Xuh<7Tb5?Jgi+6+vHvq zSGL|#r&8j}Dm(ex{C71W&mNlcmywG?EMMWHR*V6nZXJTojJ_|$TmydOF;`7J#Nxn= zlc<;$T$0NRSLX&xpNb}ubM<92Ph#*3`Nzq}TX^J0tUDF%ro_+g<{{|5D_6K+(s-Ao zd-)P}cZL!J3WDxVKFC2gE-8^LgTihLUmn&k4e})ydstSY<}vxgY3Q3J&?UD7=K8OH zO`hB*=Dou43b|ioWqjqf_6CUOByYW&G+bz!8r$fb!&&p9=Of8-Ux&ZdCH`+aZA9hg zxAGtC$>v_-pTb7zfJ}bZu~S=iiT}dpV7#917p{BXf8Ch7rNlPLB`JJ4;}25y1IeGt zQ!k&_5u9N5-LAGcpfmW142N{>SBU!<$ADpOG8aVCT2>-vyiyyolwl1-#^;l_F!OFFz^qz2_sGxFx_VbdJ_$# znzc;E*z>9tI&-O$Jne5cAn39P_qX6C0pRNJk=?zd#6r*q8AMN1`L{_| zMh518Um7>kee5oI4+fqH2AXAWCNJc!XM9DIga1sa3?vs`SSQbr+NysnHF0A_jfTr>i@3&NO7%j*OtaTfxV}MX< zy|9=%uJX_T!ou!Ct<-H89a#8#DH=^4KeT3BJFhoNt>e6IC|Lt+reRWkNjh8tJ++-- zF&}IIIT(){0ZBaoXSLP{UwvOtVLRIFHiqD;tZ4Gk4b`}c3Uk463WI+9$o6%rM%sy1!s%vcp)rA5WTHPwYAgw))Ck^(q zrP1V|q_9XLJfA{_&m-OWw+oEG{5mNtt;l!l>0^zQ-A-@c`$0S`i zcK*YXBN1*BP9)%{imh_DdZEQ#^_L}?CJmAIkQl#$ffd0(QzD#82{r^hk%&A(#3}f& zJKr{neNcuR^Fg&GNOPj1kUn6rCIjuz0)Rzu9bwzM66wycAAryrz`iY;St}Xz_2^?* zbu7Nvv2K>>k2#Q&sdRO|6dmm@m@kMJ9ax~C!+`}0q|#A=1w-UF6j(9K`w0d zglfRxi^~|q_-^SSPkA!Aa3|~m$Iaz34!N@f23JuoTjHWV`uR=%#1FPKz z|Dw&7T~p$Th653{*LhkPr;tVu2)bwxGzu-?C(?MfOhHtcddQD<;R40Yf?WBf!GnSU z#vb-b$}{Eq-1orAwv?{0uHkK&dfAq>l81TEa-56y$;gER?WDzhkEcz%PGs6$0@$rq z5g(`?W>L>C_zP5@s{9mSpM*ymmk5`+jgm{s%zwnD!Z>I=%OT)x@;wm_jdT}i8Z+x( zH7gX7xm>%+j4It!S=S5(92%(u3p_8IgXmmf+p<7sUb-wputXqI42X{im=xpyxrF5d zb`V2MVU*6=lb{B#d0GG%{N2L@N4fX@RiMCt=^8j5A1x@OngQTTJ0TOJzywu-F~$WsCIS8;a#e-`_i9VRfi0oH zE1|%vp}<8lV3$Fvr{O~m@d|j{FyKV-q*?|~qEf+cKqCo;SJo?c=PM5-!c!Q;Ka?s1 zs{$m~qg>$L_^oR}D~pSu`|uy6uc%An?6EoIZq{YV{JGK!Y-46nwjgH80szo8xsFNlMO9 z?!!uDnS=N~9qp${Zk3zDAXChx7?uLcHe|X&;nIslxY`O3;L`j=xRxrEoyj#5Wap;@ z5{*4o`px&*GPppJ#{yOlQ)Nk5VGW~KbtHsMi+|C2hydLgxq^5>c*E8_l{eI6RWo<~ z@1=4eDE9zaRW`KlVxg@YxPdGuu38yHZK7Qjp?3K!O~+?Pk{~qp+;fKl8S6Yw=-z!v11NsAi?vsR3GT~AW znzgDtiSUDz>2CoqliElG$;!@&aD6E8t;Y~}mjE7QD}mT6P*!1Xuo6UAU4{muJqtBW zIXWEJDDS>RcuSZ_-zgdR0_{*KlnB4hLSc#2Tb}ZKC37K9Ebf-1WmJJX zIg}?!e1);#UdEcU5-+oTy1;6$nBEFK)d%2vs_J%S@)7CuDih zlIvFAqWltmi^&NFSSD!}dTLgHml!(P_iIWoi|P-?c!YNn;pynPNfIG!v9>~%e9Aln zz*ap%?YF|?f@#Du#H9H**h+;*Zw`1<{m^XS`fAOaocE?Xw{F~+Ky9L+Q{L+C{CO=RMlai)8?h2#Chm4 z3sl`^mQs*tuEhdcW`F*F8olqf86az^aFHuB6L@B7LV{rFd`FDe1|wV{0Ye2{<9bIQZQQYlTyMQ{U0>AYZ}#qfNq2n9A$TOKS{21wO~02Ouu z>w^*xMP|&WC@s^km7W$R3lhzX!mo-c^O@Dw+y_-tq~(qqp04&Ws-7=ZgL9QsEDrMJ zo!R%xf(>1TWO^4JpFO<8{+1(aICh1dk9k`D5fL)h*;QGmI2DFmyM zqH7d*u8>uR^iDQ?!66)2s6|->QLhX!*!2KDA)r;^qZ`*#WejaCIPDo6a)W z4bLY>J~^@i;adXX1p#KW@WOP40ylg&84BI-y@Bv=0^tV(;Xeez52w?QbHjC{7rWud z0^#~Vcv&Fa90)&|P9N%q*O6Z0hMx|EHwD5k1j1Va;n&mY!(EKuiP2>=U;s_b4TRqc zgtrC4AEa}H+;AH?oRD3#=DXp4V2=odg(m{xtYEyALcTzFK)OWK4Rg`q=t?&{C=kvI zga-%0`GIgjI{i#HTuAyPH+)9126dg`t37KYw6Bo>O++;n% zOKk0j{|-w@a$$j3u5I+LktWd9&N*>wcxV0IR&X*2g)~ww7Ir-I0|(|6)r>EWDxL7n^8#p&T{sV-K1%l{-u> z-raxkPdj>|uDYrCw<(zKvH5OZyjj4G7O=77W!sfgd(BvrFK`_9>_YP_5iL0Ub!#J< z5cWb6aR-;$B>-dkarX{%`{MQA)&6sixlsGQ0X*1@9sXlpBd?aqn1bfvW6Gv3`0&p2Uzo}@i-;oY<8Stg zO^Lsm9Xm4qQJ+|@Jx)l+%D||c+vi-l1Z_bB=HBeqLnKDS7`zx}5|^`LD&HrwHVSYH z@Kb`fISVv?;xQglIzc%-S5Dg=>bPfs?6qbcN08vVffmVLU4iGl$dm$9q9Cs|$1A`z zyLcJ9F~dLcs{G;MJ___6vMOL`0|1 z?7E9Y88?BIA_f|;r0L+_6JYOqYP|gNMun}hF#4KIIbxa|>nzcFZ@EX`eD>{n`&MY* zV)kvCeY=FWrnv0e;~ueBCuTd#yD!@|#Fr=ljj{5szj`jv9CttBk(;AAWQb(>4k7sk zFU98U<+N<-CMPNE(dZ<{`OL{r4q^>CvCzI3av)#d9s5qqdiy@jzE3mRyt_9_jf%a* z4f5Ds_NW9^>VBTPh6TlP^!QpY-bj!cMB_^kZ=|oeOHNFtaeUk_I^*~-`{v;|*S>i; z?k#U_{|+>ppK#bMSa+s$A$h>Z56S`iRpua(#GfYFdS(pA?bT^E~dk{$Uvx+j4%v}n%_?)Fvq0>fMk%bypzXBAt>v^>68xr(^I z66M6*T(y5nL^8!Vf+=F`Ko>dNSuAH|N=(~QN=`MA#0doU@mJp`2%hQ+n9|i%$8+<; z)e`4AIl&h#q9nI7pScP-R=aW#_tefoem?_46cT78>Mr-;0$mAVXj&Etpg9+^H6;o3%V&Nss!NhNP`~-i zUA)UhUi8_t%86IkpPJ~YjGF%NumFh-u8;zXn88hhxb2D?1U(_w%FWio9F@WxlZ02M z$Y`^N`?^SiFN{S#7a)(Ha9$GxGP31_airGYZ4qC5@y6utVxM|U%HU?3o^yR33Q1)e#G6U zB6-QQNb=i`;8Jec+(G1Oj$fKGrRH_VrNzk=h!clR7rW@IHfON zeWc0@0CONy$MQz=p^|IPpPizYoy;9%ngKT;T8MJVt$#Etn7C7#rGvZmmd}OAz07Rm z=iGK(XRKD`=+sxj1RHd8%rJ6bWYt|w^pE6?? zeLwi&uJ0@V*!8{due-iq_UEqeE#2Pl=nn6puK8!7K6h@DbbbGNH+&?1)iu4P^SfP7ox-lSjM|-<+_oZ%631nEIJV3@ zemx29*b;M%=#}nR$NXW9JdnlCXspE3eeH>W&?oYnuJ!lr*8W7d_d7b{$6NoRTYK#z zS~Ee=BDrP=P5bONQ2*l2_)O{7VGEIdN{pPLrWNsyk)T*6KhH?uU0>5|9ztWWH8qtN z!p#{XM9ys#Y@r5^Ei^AmoC$YqvALTSP^wLz9eYmjMf+BEqkp0^KY9IUJ6ikSyXp%1 z@AjgV0gq5$_h}mj;S0q>zFGfsuQ8*wRb40*Z|hw}s3)C2`^Vcds}2h;-Y6ZC0BOnW zOEr4l=_o#teDf0~(^OwRoyMK%F5~e}UFrQwm+=I5`8-oa1H01nDnh(Jmdr;x?y2#X zezC8hqQ&~jKPL-m2#tC=JzQ)4@_U_thuSv5f!RAh`yP?9T|w z2(l^!eNq^gE;X14HoQXc zhX(PGDrsm#Hm3a?_uxH8yP$*CN z^5leSqXpN97L`RE{1$k>qWxumreTA;oF(C`V4&&o!c)=h$@h}&$;6&XH_v@ zW_y}`ag{SHm1j<2(GqbhiUZHr;8^uq(0|u5GlXw7sEMcTvjV*=dGZK;{C711c8b^w zB5qY)P~$y?-0KLJzs5a02(br3Y}a6&`G&hrtW*=Pq#`t{31Z-ivOOGfw{36as^oce zb$ere?91F4NI}WF{(h-(rr(x4)RwF|cY9-5tWQubcdeA8B4cUGp9sL$x=*;~^;loG zF}`Kr;rqshqOne~R~=N)6P$htSqqBIk3cRB805s8e38;!{`n(OVwG203zj@$36Osf ziZAQ3OM$!i1iled@J*9{N6H2_O#(+u7iDE8l(9;mT8aVad=uNp)Yqka^qYHM{>C24A6~Ur z9Amo1W7xebW_P)8C*ig3lEE^MBJdy{TLJ z*H(2+|8=+YT?qHi_21~F#~X@GzwUVNfnF1Beh=TpO0SO}*(-dN2)+*Lq5Q&Wdtd(9 zSZ8|M`meldugWXEZnNdVrwIMRmP}0go$)cFTlx#Mt#kUsZs~=WcTGQ~Tl(*?kaRA8 zP`C7(If2wUeFuH9^tSCA$12FCcj(*Rr1xYhD|e2xh20F7GxclCX;kQLs;Qr~pIx>T zixBX(3tUdyuQ64ypnkMrSiQ;5R`MzTdiAH)YZE)}uPV0^<8#X2Nwqb*alk4V<+ zczds^EG|19j5XxYILq3M*uL8vb7KQ)UX;~(hJQhal|*eL>17+rmMnk&IVq^~lV^E4 z{ktBO-ZejA4)6?R+$6zS6xb>sdlSpqV)IO`BsQCyT=|vF6WJ_TWpY%-B8R1sS7!0S zGD5aqOx{H1;sbbb64&^exU7NC&&X$YJPOJ)PJ+N=7!8)FN(~e-q;*vNDKz}FB9Yts zTz#ivXW3#-y4W%1HEjQ_g^x0?X0$TLOG~5~jyo>Tl>Z1mT~$-Bss8XPi7UOt(hUxVe&?`aDAG;)0IG&`R>B1(wP7pS^~z7`pG zKEr2sa6;N`Lj?JP5B4^%-T`U;Rh=YO2Lp z1Ec?37(Ovdb>&i_&r(uhiuT8#&xC7|V_}B!pqareX;~lqriZ6zRVl_?yZ8`+`sz0X z8u95y`4Z@`fK49oXCMXZgjia&qq0B3q&^FeF4#{KV7`N9T!$Er4qZsjj^<%+tx#E~}f&+{A*dvbbV1okLe2m^3f$h54 zeD9BfwrfD!_7vLsTqw{o(`&HKjDW`a`DJuZONZ&;-`tBzWrf&fXL~{nZ8PeACy$Hl z-3xtgTSd)w6d5GXyZn@u`EMo8VH*NG6k8iWF8p>(lvCRN@H9zettfTo#zZIij5Oa zZp9gGK!F*?h8g+(bepYtz_zQOb#mzrmYtTi>dgFc%WqTg*fx-+`=O9DeTx8%mu6HQ7EKg| z16!d{p&+9lu*xWtLCn%2EW03Lp;Nj%7Su+$>&(G04V^iW%vINfhFx7;RVCgW;pDiP z?DDYkev8GgxemG20oZKjm6<05uSDJcvY!vW;J8AG^P6vOn5Qr&rAZg30g&$JfJ%{W zFdfp#3-YZdIh{9V^H!zv?lRkMl7@dQ*;{^2GHvx&*YaTYAtge^KIJ;9_!`9oeF;)K zq3?I(^J;7ThPD>`nP1(i?K~!3w_ZJ)9JmwvMv9QJP9+PuFQdR0AJ$&AkLg3%2sQbr zD79PrF)b->?d>i{+bhe6WkFKd`|Lun_$xrNITBp_Q)zawj2Ejg1sC7R7jjf<4!z!R zUy=b)ObI(CW5h6LJhx&BjB@L_Bf3nzJWr9?d>bQ0ZseTKG+xGCoD5BS59hymCH?Q5 z1^#oez4h;ynOxi5rzr!$AU4p#mO+fSu5Hu#%JVmQx? zOm;qK*kZv+>({!lFoK?gsJ8?Hz<;1s|d+OM@m{6L{7`YMq+K~!$0=V_|$lydVf~k zBxI_2?;>r4<7PiHF1_p!X)E_7xF5OwL=XKY@7Q+z)o0p=*a(cgv7?vBX1=sBPbc7k zzhuuQIi?1jy=yYGoh|inUFtT{mF6H?+VWeS=)UI*JkOn2KKFgrSNV=REf3mN9jRU` z0nM5;QCT?Zus{VC9;EQO;t;gU{^4Tg3JcSI*H!rYAVOBY{?skPM zao*MZCyCIfjt!;c>F1b(XjQQ89`aD%J$w{afBAA2I2g6Za}W|Cx53PS&mISP8B0Fk zAFa*IVL9f$)bdk4%kupt*rDYXeF=h`C{cvv&3#|)hQFPskUTzCP|0J|{hluh&LZxW zY<_Hw4YK}de>0v>f)iH((g zb70uL&1=Cr+R8N|>{;j?Fo(jyx(XoKMI0NK%rZv+_99ZG7U`l^nGzv?WO`^lwMzxM zO7Lpu_rzJ$ zT5Ly&(yRE_Ri}&ynWr4tbK|xyUN886_ew(Ds_JVelCt7PL{e4it*|jrzuWrS%Clcj zQBe{f)|+^^D#I4ANhb6h%jif}o{j)3M~<1-84Ol-fm@lZDt+R(iGom;8%gw*1rZC; z-jRf?g5~o_UqtLM=n5k9_{Pv0iOXhvjKZvTdbMUoZH8%*iXW#<-4}=~T6@`*kH}22 zb-eu365QMWK_^Fk(_hD38asB$P2L!(hdE&8+t|SrQJ5TauXzt%OkIUBiB7XQhT>if zZiaf>J7pB6C!vCpkZ53PQgQb)pZuOWK6Agv;{WJWdop5-!+{4;zaW2Knv<-Y0P?wp zYrDC$Q&Vt85W|HvUX-+4&03>JoLKlx=X?FlP~twqj<3Lfn}#PV&rZS50e+geav_)! zmMal0VWDO)zk{+t2>$sgV%u{{*Y+IkwI^HqJ2BOs8A#dA?MZd^1GXA_>?|KG{AbTg z(O3K1^nmT}Wy;KxQp|i%XZSF4qLSziWrd&0Wu5h{@1$x$Fn@#xN300io$J+gi1y{e zq_d0aqUM1)+86APX%$AvS7=s=WyEFURMQeO)AjGw>b{%1B4KOT@9i*Jb=x2O>tw|X zOZbRv5%#Tcx46#*+RZjrrJ_q6C|n_GR46(6a@DI^LD=>X!{X+h8$RBaX(Oq~^>|UZT`>S`7kzLPR z*`(fof}K|Xrr*YKHn_S#mTrV*D45GHu3$2XD-xH$+21Y{d)JM#Jg8(93nkEf3f*;( zTPtG+MH9p9dnHv=7u>CRM*7elCXLskx#}adE}RUun-{K-wl=l=gj|mv02*38z;pW1 zLGtt_PwuLDE%Fj8lpXlNqMYRl{<7(AuU)rPy%P_nT!Bl7YCvWPei-KR3TYH8__Zd$TADEi?@bXK<22dwn2y-` zk8FnSX%K&o@51kPKRkUENiiKa8^2B$Wkp5Q#@8Wh(0w7y)`I({$%1Qy*AEg@39rj_ z)*iE8t{gW5W@m|iB`>BdYI*H#vBs$W>G3>j$$pUAGwCbOHv){o{+$*z{xT!VG{?O| zxBP(wnI@xRv0(N9)oX*vN?)-3De?M}*%8J%L5RPRP^HBcN?&0fefq41c+%rwkskX917)J*slaGddC{oiqC@Rd`|sJhE2-n; zw`Y6p7G%*+f`l?yD3Xd>gd(SHB>%8a4+ZFP=;+&=9$}%(At?+GCRA&Vt%& z%@6MoYR@@Z_D|QEqXZ#B$<^jgwWZFP!RPiyb2-^cH_Zl56+ZK`fiT2h8E8ONOV!|e zWf?XuKe%`uJAr!nFW)KsfY;#Z`f%x9r}uhRul++Q}aPL?5N#91D;v$IB| zm+UglIqo?=!F|x@zM~Wvc1?cO(Mx1#O3NQbqSNyBU(oXLvZVgloP#BY9g^uDaj0;_zQPdDYY2ABfnZnIX1xZ-jdo`2*|LX--|)UkH=uv3MH>^kCi7 zB)GnKi_e+5(tJnOW_IVdf8DdBpnn8gi=*yX3ZQMXMI(lY=5-Ff=puiM zR`E0H)_!=4{0%?XKA4kef3R*Vd8qnvJ_>VwbS`8++GDx<^rNuc>*O-~VVy$!<^P2q zGx?uim|pi6n;WhK!^<6aet{B=RpooK=YXA5=`e4ZP?^01zO!9N>;j)+*V%FxZNsiJf_A0tI;;37(@74d#x8c9yP#!P zyH2tB)wiJUiq7=ik1zj8`gZ6udSIfP{@%{8Qu>|4*~zUUF7Pi1x*vw!zXjc`QJ1|# zcV-@1GK7<$u_8OJf+dk1jd#j;_yuEnr#X!2i81{ODZ^$AjZGXjqqyn}ah4D%@;U}E z=JxZ&VVB=Wgk_kSIsjg40e)8iird0SpOM`q0Nz51lsT5g4x3GZry`8CMWWqXPv6*0 zlKSh>LPh`0a&kp|enoPRXDuaDjclM}4lY*HR+J+TV%idcAiHuHw)&eB@eP6rR8f)& zgLU7gr!CL(kH`y=KT`w(wNF)nVNF?K_S~h`CgoPq!IB63{%0bI?f{5+hsoF~P*tkS zE#xD*T(BkH9j+Wl=nVKRHMGsCls%Fuq8g17vtBmaTvfyEu*e=wJu;$#iyx2%KgK`Y z+AT6KF(coWlY`CT(cJrovek8Yacf9u_e;rMH;wE{PRRI=g-S+qF0x(=tp9;9`=7`t z#pu*?m;Nk7LgN}QFU)_dC+MoTx7rR^$e=IEP*I&l^dH#co5bgf6-w6X+!MEx}~FDQ(}mHo)lr7N}AEd z5PJ-DwBl#esRBJa%gHRVn;+U54iZBwDjoi16?x_wmI#6NQ1UuVc&p4M-xpRBGpy4T z7VS}{)XS+)rqo}bDeT57Me&Q07KPoWS&izysIUvsp?u1Tr;|V4pT;UX5iuRdKo*9a znlf2I8CA_DgM~~)9CW-DpXf({?Q(ORT~Y-TUk%ATAq%Ve;Ev69S(V9v^qGMw$zl^l z^F0fs2y&JoBh<4aak;moDzHncJH$NT3CAO)=BK`{gg!Vqs#oiQB0$%ep_Akj{uV3T z6{+KDWrAl%7VDLu_+RkX>po5uU*3TGfh@-G8t$dmE#?3Yg2*zVtgv;k7?v-wuTG(u zMZRu+gd`IAH=Zp_mcDF0%>`{y_XnxvZ;WGrAwnJG@R`1{`i-~ksyZH~J?eJLw4+H` zB3?^Lrx@vbory6S*+rmdHe)0muQ`Or#|r%9Ky#anq&PFtGE?5YfST1(CcV8fsdYz5 zmv_NWp6B2AorvPcapg$JyL#YGw(!~F6oxC7#ZgJ1-F?T*RDEd9@&3al(cNhJf?1T` zomsI;In~l<*gn_xPV7Tk`*Jgu%%x^Fu75Do*KEn+OZ0r<1Sn$Uo;>mpZ>w<7i*w!?IZ7`ZTh3RCQ_nw+iZ*o<9z^NA{J?P zl;Uf=4*;8}p8oo)UB$t8ABB#vgyAZVIg2uHsDH@+};@9{xs>bn?pHVeBjxVJnW6ff;iDe`u zK&h-0AQmxBv9uO+ z^)=O)nZ!2I(%m-lWok{?MrL=a>R&=iy8mIClD5xecx~9tKJ&95b+n-kcM7XQc=j3X z!e_L``g2T7)fPk$*0ZP6VFMiO*#L_>41j&rHwga@unL~KoG0jBorS+6WP2k%AzwnV z?Z{=*pY4?XGuqNU{gF=T&oei5Prt2G`nuBH(`R%_KdlG&6Fa3}(*yidI;DTYbNBiW zvgwO6iu;^kepOCq;Y>^c0}uTn?qEw~qQU0F{$gY>J5)$PYY~-vQ&W%l&Xr%&P6Zq+3DhP`B~FPXm5o#$N>R-rDkYqNiP8_wjT;sY6ZZo$d)n_hNvJ8+sf=~6U9H@Higy;tJ3ED)TIhW)5Z?8Ks4l*s^k$ zh#g<_Y+0GzU9Ak0qjt~M|HIy!z*k)z{r?Fe62Nc+7{om)2#O1e3kcR+OymX%*ezE`4F?G@M%HU-w37$2m3qP3oEMZ}>P0H)(MHd1Ns5{0sI@TgK*)!=qnj)L&j6dp8{W zTR67St;A=AS!USoS$QJdlg*4r!bQ12TbHzEQ#pJ{!Hg7+6p)Pl7ACFxBM3O z2|IL^o5q&&i08=hC7-d9QfLx2LCGW~Qtaq>rHvUGs;l6K8);IURk6}-WSx0$p{N;0 zWUCK1$k8jYueH+_j=k6Q zq@BzI_S<*xhIMeCI%r|JdUMbIG__zgX~63y93+x4#mEkIAeoQdcr&SKGwqvMYt7uR zX6k4L>wl5-gwufmoN7DC>)?aONLv=?|%-u&v+>OED!}S#{V)m@EJ^Sr!k@4S9 z-F6g}cpaPPk-Nz{yH}lgkE#>QpQF_7ztr0O7en6XR_+%nw~l`n9K=6v=7Ac{HvBZw zZe=)|-1Lh8EH##1bQf-TK-C(o*oiQ!W;YcX2_v(X`&kifauT=jk6&B6TFdFRrIy#a z9n`W3p_)>+2Zt!uYl|zCd5z{qFl9x&c#m*$qimDt&yIJp9)3;Z$wR|t;!KVge<`-~ zUnzZ8eSgTWaDy&?_;ceH`<~6ejd$}8tmtS$1;i)b=+?5Qb$3I~K%iJ0pI^!MA7z90 zCp>HU=GiD2PUlcl?pA9c?yO5brFaLYJ%j(BI>GD6AO6)}o%D~B{bPfNp;MVQx?xni z5dfRSoenT`mc@@PLSlR_K`|KfOKRE64(WC=R=QFmroim8T17P%#*aOSh40qvpK4*7 zR13CxAWrisI4Vt?$)mMOMneQLn?cQa`eqg3p3jenTXUQ>717}f3ais)VOC#q57Et- zG#xeGLv83}SNsd&6XWh#WT=~o`Vr8@OBj_T6((~8r7h`sl2(@?BC5as&6VzFrVD;e zvs*QWeofoAP)iC}fO^;46>$E>a=h+)0;}2em(pT9rDmu*i8-m%3017QGKO~|5rm}b zHR+r!9a657PF4H0uiymohsIC#mk0MvfttTzj}C%ICItnFnrPhc7%WLZ+>ELx$WIQZ zA)oB-WSb?(yXS=4FaU^TjJTkcXcTvrE)s6=oVnHYgP5Qa^Bxgzl;t~FY!Wv)L{lym z#j}b=@kFM41PAx=i8q+RN*0>T%6|jCkhStlxDzm(I|2Wi84u>$^sy2kaUUE8CJ5yK zpOl$ugZmhTfmn%Ux^t*ovR*5J?)>%M#5y=-_q3!`Yd^R;e6w%bhw5_oSi6i=$J-fI zCy~Uou;uo=zBwUiNqXjm-_I`Z^M_^SujO~9J)hqzEB|tI%S?VYyl)+9s0iTwV21F} z72Yc@&#s?o$^Q!4vsH9+s=bdRvE^SXGfgRND;J}S39}r z4RMs(h3sg0rFFYfmOV;p;~mVJNNP7vM|m9h$0z;>h4(&p{mJS=mnO9j{ze*Y;Qx1s zVZz?UsEjSQhg8s@ALHa-A(rBWx1hGV&%~(YTG|;2S>L|BdEK`+HQiph+G`cQzN)=b zM6`$b_H=(~x#zsR^F?FEm4T4e$x%*W>16+o8VipSekyWv! zdWdv5?1}SH$r*Rmx70{SA3XN!Gnwtue=ZbVHog|2jc4#>fe|F@JfBQ$-4gTm`$~KT z{PFS*?Oi?H5YeT*YmfNK_A>YnHrdXx1P#@hMkKG=jHTntSVyq` zN8L6|^frI_!t^EZE52=8wkUi|?zz30fZ>T!&RQ)bj=sK(S->|cWBtRi9>~&)O6HSG zkgwMC!8$=(SSHX}JQpd6vvcAA&h5Yqn zAC5xid>ng2au-^^EHVY#=Vb-)lXKn0&;d|$XvDc1hLV{WPweu}Wu|U1t1Jw6QEv#|6{bslO={G3V~RJi+_Qmj+YNprMv4sK`sp4T+Y8uw~}%@14X=g1`5?R za^e4FbzoCgFu~(&+Bj6h4i*{AtZ7z*PbRS-W%2kj0Y#VT3mzl8nbfrXTYCe8uu5CD zS8Dc(S6?Flj{rb~FUT&uTfPO6FI@Yv*@kcVm>6fOE*P~?vvj1b_BGsW#i$%iXHMgOV19-+BYb=^rT zDrhcJ-&cKM{ZQ*#Onp)~qq!`q{pLRd`43O@*t5x<5%?VJXOml#n%pKtfN3teoM8v0 zB>?|rvzNNBFf7wP$Nz=f2kn2?+P@;z{#4peT}4TC5h>`v!A2(@Ve*8?6i*wSxc0&f z`}%TVKvTB7xOrb2wVm!s#vVJ|O+n9zG)*wCOU=X{-tqT^Dw4gWg5}uk{>F|3Bhz+~ z`m=)T3}SpB1LK`GuRE(5B^kQDjztgK{baD>J{n=L)gI1@`>Tq;sq*h%f!!~LGOWlR3u`cHtZ-NJsc|nIx4wO7ubfcM5k0W#*UXRt zMuU|xn$~G-MEhU5RObvI&PNZRMX;%Z2vb$NdEaO+S2lzbhFxmgi)Qz7*Pg)d{H^c_>VXX^Rvbswws31>=w$fkmZtp2)Jm< z6GEDDz(tN5c%?6RTiOBftB^a}S|%o(0z*I!yB@5~mLn`+4Yomr)yq0o)cZ(S%NE){Brp^Kt1FgiKDD1{RxS z4sD|i3+|&!G_=r-_s~$RZpdb}=k52CWM|Y~SLoE9=xMJneqZgIQ#op)UTnoJ&K-dy zg!i5qnSy;1CGTC1?ZXW#H9vbH{{oxdkzJ~4Y32I5dqk#`sjeL!5dYKcFxW*6J9G*$c0EyMVr3YCo0mdWQWm!s}BBubynC5nl7L7K~bE;;S+c zUl`O@x*jR>PgcWUcg6bs-KstPAhmn@6tn~t!_v~R^Jb56F zgWbk~>Z94cqEifSKHp7FZ%pC6J7{4>cX2OR8IxNp&r0#}v<3+4(usiSgQ<~k-QR3@ zH|*}=ojITjy!&Ls`_mIWy!&*8_wR!Pc(1TB25-r~9A4=UC=tZ(59}LeMW(Y43~I&ypxW+i5WhZ{p^PJ<|n=48rR?{srD zsp;EE_Kx~qe)%7Bg**B|EQ#V`xLBTY5xI9r>@ z7^({@`0N{H%l!|wlYLzy95dPEedPiXKfNH?uywP%^`(OKl9A7^Nd=R9{?JYCiiiO+ zR-_Pd9eTCscmO(eCq%qD$PlrIJJZS-A_~y1Jt9VmK?PDbQa?S|s4Fe-4U}yDCe*F{ zS0_^0Ha#90Rrl+cA{9|W$Ju~vgbgANx?bNk+Bx9dn>_X0P9q(tr*K*}^{hTSLp?2p zsUFhQ^XL7ukoIxNBkj+|XpBjusOP@ofO=lCGKRDlPfH=~E2$@ZLxy^;K2p?!R0$9Y zl3f9smr+vkp{=KnuPWJve(pqe1@u#rMs^w%FG%F4=x4kglH#*1yT9j`DOB9CT|hs( zS{Xw{^LJ9H7@18!9mcqOk(z>f{F2F#*;kEYOZmD#5xBc8-Z?cgnah8IJFT=gFUPQVO7Pr4!g#_uzxEl|>~rg)yAV z@njqh$tMfl`DGd`XXj_>uhxC2ZlP5TxrZSM&>pJ0lLVojC!lj{&Q?^c5@B3Io*sBpB$iHuOO+C z?2p>q4+?EWHNUqb+U8CwYN7=_FdapVg%uGwa2}Zgt<;0|_`DQoMQ)=>NU_v~|Ab2V zwdOfxuPsKAvT3vXMu@z37J7G=l`m|5qp{M#oVFHeK)5Q$Gv3zxQWyfA z#9E#xd&&_j7-`K!PvEHfN8y6mv*wk?Yf07|E%1o={q;h`1I*F(ZY@jBFXX@#+V>c= z8o)3-(@&5>ehR9ug@mlaUVrX|ng%x9Q@vmbXgv%ohY=0e%V-@>WbiBPuo2Fz2W`>^ z!wX9oo_iEUhXxUquj0<-`C!d7Bq%{Gm&2z~ysGW~01O8wkWI_aW~_Sa_#NU_VI3GjV|>f5Uh^eY}U}A^KQC7cePEB-$r)Vh81p$tB)-7h(amhOgBA$G3tX zi90c0vd6R=&du6ub`pcRo{e3w-{HHjyGFfr^dlodA@Xtf1QW|q!~H)M2)1`{Z5LLAJH@m4C!rVdle{|L)|>r z%f`G}phtoMy{!!?+7@O^QU_>2#=-qMf!8&58qOEjW`;B75H+o$oNycW`zGT_ucy@3 z?P_go1E+%xRnQvB%qb`nSfzGihGgSB#odj@+*n{rO$(<5gUnuM)N}?#rT;`2HTus? zcdKE51Q(O$39A0WN*dc#^F1{canT_44=@)}kJUVR}mtbnD}<@ZuE9W%cP!aCK-rth#em3o~9+Yi3- zjBeBmaNu{2SI-*j`49;Rc-t5xe$i50Y+oELY|wE+xIrGX$uid$1PE0hout2p*dao! zw7F)`dZ{~-;XpHZFr(CJR7TMa`&lb9Xr-}+f6SL4Uf48SXliuZj8b!4bVUoYTDFR} zY&_{S*6uz7`;SyuR>PiJ1x!>v;2^x%u%UJJH;op+m6+IrA({Ra^7@x0{*smL-ZO2) zm->ul)m?X8(o*a3S#2ytwx&VNJ4=GF7{? z?k+VZ9FnDH8fy$fv?G^a%NoT=oYL2b<+5N#(%V*uFTIaj!sy)hQhh;R%iXShX@%zd zri8FvmDDa+&7PKc3!72~huOc<{5EypX4_Q57(G9B;hh9tvpXxJesR&d)!kwo*0$MY zQ*7nKArL#Uuy6=ljlejyTblVrglMj?ykzC9%|gmGJ`~L2 zVeoY*>W5cl9+kS;we0Wl_OIS5lm-^V{6g9neKD8I-BXAN;dglB!vRoX57g)1hs-S~ z$2vC}kWvgx+(ot__fse{kQTaly@K*uB}Y@;+De6O{nSW>8krVC?p@FjsoyQIO{BSM z_WXU-@9gW|%PmEHRXjzGX}xjoOn z=LIc^LAODInesk=YF2*in6CK~vhwHj=$bz)D}OD&JGb8}EC1MT`hTyFAF1H$+fDyX zS@}8L^nZU={>9z&KQAl4jb+gpzNuOH&kyaIKOrlBPHxxyVOjZ?cGG^Zto+NnY5zT~ z2WDF1FX`C+XmO_|pIsN5z>YZ3d24KhXKl*TYZp}O+=SCRUokJD^ z8Am;3I%0J_Of7K|3*+XtFSrK7ROr|??L!YXVJOcyKI8Nn~NS^O9x^c+3Q zjo3$HOMJvSzxHFbK-4egYw=g`m%49VArV=RSnB6K+uMpS6<6Wh;uN{URJ*$&4ZH1z z?dKG-+)xxHJICW#Ryv)$MVe9BoG!Q!s^I`NeRdZecrz9)Apy=Y^#2J>`6 zEJz=pqF}TAz6PfURK$^P&r*GdZtSgmUGSnq^(Ea+-bZb2`Qg@CA9Z#X-6U^zHN)AB zdQTT0&*vP{ndfj~ra8I5)!W=qG~!ewA>F+UH=N7AiIc1Z5lxJx^SsCe(@L-Ube({$ zsPE~gbzwxj`{_0s7pl232qTh;qc?=irfuW^!YNLXyZU6b zx=Ki!P$Rl09;%azh|RAnq&EwrSfA_eN7(t_7KyY7S4eaOo_Drund1$vm6e!%6mIDk z+Qq3Yg@Gj63z1P#imMBndT<(&;|l1LD@GPKRP+oc6xMK?kyoK~aZD)Is$mj;Ujw;VFuLAu1rR1NCEYMYLelIZ^%Ge<%W9y^g;x%Y_{F1m z4($s|M~};mZi>{8A0Dp%mYHX(irfXCuVXG`oLri$NK@uLzN-o9$|&DI}{Tp>JQ?ou4(qz`3n5L6tAdZ72c74}Zj_q<5#ET|ds+z(2Zo#clsmm`d8&E1hC@sgP?W^=~vOV&vR zEZg&y=#X@W@|mK;N$Suvn%?eQ>o7TqjguVpE_0)4nfkv!fMM{rFY7LN%;t!6JL7yi zdFgi6x?Qaux#pP%9`0xY8?7%j4p;dtwP>5_T{QafzLBRcACzMa2WnFC5%c8t97&9l z%T5-hwFg2Paz0!Ps>NNx_N^jzGGlFVL+Bf(QM-7;@Z#JsTGSrE&x`I7NK8_$Hn{^qKWiEyl*w402FF>w8MhhY4e4Y+ffI0QGrNNfVpA&PgSLvF|m zUsDR)&gpJ(gk%mc@uU9a(vEYOh|>T!HfVq|CNON^R81+U!lT_O4jhVhNg8)GzLiI4 z#gk=WqS7EZ5kIH=pOH-DEF!(lq?}u7gbC;X9;q)Mo*GlM#QhbMvZisyaef$=e9nt# zsl~Rh@8no@VvB8CcR{c*JFnx4`(MqB{sq9x~Y%5X9FW2_6|_*VI}S zd$Th3zT1PPT{&g_sI|w&#~oTRwmo#+Y_P3`+ElS=BMM(=t|%qk@HAvCT9^rCJ$tct z`D#Y52>8NbFsI*O44$uuZ<2L)qIsr>MW zrSw4&X-O(J$coj>G;NLO2PXHG@f%PDr#g#H;L9bc27=b#U>xLzLyu0{CK5lP=RuS5 zLXRGmf6!4q_Gsou?m_&W^D&;rWuZs&D&nP|MaFKPHc-O$va0&>9C!aw+vQjw)$oG9 zXe9Cct1c2I8Doq46`S_hvx%2kJ^@i@q3K^h8{eb}O*n28X(x<~tgJ;tF`D9z+Xg?v z*m`^*-Sg56^i+Alnxyh|Svk1>9f&L0(t zPwEMNx2cRR-N@zom**dq%jeO#8&}Rhs)v5{(62mq`gmRkj33=IwvINh*j~{Nj_En# z3Csat$2TYdWWR!Jw;`mgAC zJz{v`mR)6O%v_Hcp7<`ihm@JB<5{BG(*}?Oh;V5n^9aW1PLE*7IbnFJUY+O9*fl9S{J+jjZ|} zHmBX(4ASU2oquURBdlR8G*^LLWNW%PPb}|PB2eV$M~gdZGnJE%BrzG@PjEeo5VvSSzP&@Z}iT&hMN$e(Ic*QlK zz3FaRHJ-_~cP+k)T#ex>^j-1Z8i-LxRDn#_P?UUzB_CBPg@mIeZh6o_r6NzYx@U}C z&$?ernF}nFs)Nv@+%*&!K*Kh7;`gZCXLW{v{K5Lnhd%s4%+;K=~#@p<9NY(X1v?u z;KXkvX?5Fz2;DoOQ3l9Jhr4^ADnq?DW(I`h*Tny(f6Z4uuo1ttG2o(C zmgdA~q9AP0LMjDCxGga6CExSf%Adhay!t#JD)%H;geK}Q5}cw1#c?t+FyfA56Cw@d zKyaLj$hbtRe$fq}5IZhVsG`E%jSjMccR)#xYj7du_=Z5D%k6>eR2^rtq9{#3?ZIEx@|2--a?-LAcaKFxh! z?VeA&Y|XG?aaF$6-3jj(tsSpqn8ZjD{k@XyOO?ZGcLGh56qcbOUbr94$0z=nN&46g zSBn<(iTK>#fgOw-Th4n}=_(U_l~2x2Re9Zgv>jF6p-Cbw704WEg!TGpixXvhrkY9# zZQJZ+YYX}$NS~Inh|m;cbnXu{liC1_fF%P~L+~Q#>-EjL86IB1sG!Hq{Hqc0$8O)X zx+AUVtg}4b*Uw;ywYh;5KsZhGA;y7B17cBlVG&U8gUIffUP;(fEuI6c;Rc0r0W$*` zCMV^efgRTm_!RxW)zu!NU1_U3oaLsIbAOvp@tk`1(-`g?vXbgq7g@BU`8SdFR&}e; zAG|yIZTa78r+9)le??*+_(&NKY_Qc}_xHHS*IE%J_{N-W`Fk*g44Dxr+CZJX=m_E-EZw7Yv#xs&6n>k8s2P7aye7%j(~}Z z0`8EI4a_2OGEA}oLRoCFd)+KXt!_IhNvI;VI*zM9ll!SxjCKhuAjVglj`ms-KpHXX z24P|%|CGfpK7|W{e=VARkheF7YmdykhB%77AOXnlOiaZuv+*c!Yx4b)QXD9M*Q_MS z9@XBo4TV_NUP%2>?BI3MN#Qx-VL>c1MN1i`%)f{wS`X8@Pyzbsc&Cm^(c$Ks5 zs%tbCp(^J}%?9?It}MN~j*Aa9AyvWGt{*Mnd-jw*U9NqE=Bi8g&WFOJWL3?cbSnVw zMj=r_ZIRxm9ROv!)8gJaa=qEd6^$-}=#>XPhbWpDPA z?@i8xYDtqtIQHz&oSdFH_2q9y`+0TgxSeeUFDQ?F6u$OdMFB0VkFE~Q&F=-$YiAA4 zi4Jhzl_8`4=)p!k=b_GMR(pr8dp@6yP`f=R5UIb$xra>fG`rp+XNGv8`-gsc3ubS0 z;6W(u$w^khJ^Yt-c4{MKt_7yt?hXYLZlk1meYp!%2wj?H0TYQMvsC2%eM@0tA=2X&oW>F^4_LYG3$(E)YDTf%0xee|KqjV6?f4 zu3(HygAoxJs|3dVS{uymp=mIZP*D~l3OyKB_*ZXrM#O$;Fq}AeXKb{&#qV^%#vj=_ zcx)^Jf(3gEjFJG12R}+- zwh5pNHa6ho3O20p4R3VDM*lPz&&j;d6&v?K)ij&EQf|jK_ORs&2xJi+(ejW zpll4@9;4E2ZX1MS;=_++AyE2>j(0B{BLX39?#C=`gw;w;Gn^Uj!}in~`UVoT)jf_t zKt!s!U!AOd#+58c1lDYE#dz_Ypo@E@F=Gt8fnLPhL!sJyrihxO-Fb%@&}iYv#)D~( z?vC=BaC3rIAl$J_YxdN*ZbH_gcyoRHgd)FL8=!cH>ug*#L(nP^jvF`-K{!6yco9R8 zMxzs5CVTtD?)2_;_FG=-ptDOneC%!##WGjhsnXA=6tBLB!}Mv1#AXgHr0XjK>15&> z4JJPRdDlp9BA}Nk6N#OHg^1fWE$+0ze$Vza$>B}U=9KodOO35=l0RmisD( zx6qBp+V?TuUZPkZJS>#0YGXC&;a)vapJlS90h{c#VX*T5;Z6^Hx<8-q~`lUK_| zHPTIaPb|v}3Mi3nu8!Q~sSQYHjziiX7x##*2$ipP16Hdbe6`Jd09)Np;ItLB-%`ZM z<1t=T)NjMZ8X06cXnNU=d{qlAOX{||J=v}3^vzz{I9&mKE|Oc7;_uY{bJuI+?>Z8Q zT@;nWtSF1KjMZyojDT%4yBX*=Y`ck=C6n4|ODqt47b(%=Zb8(`994}-xc0a#F>wll ziVe6`{yNl<^2dD%CBWcY<8}TY*!I2IIZY(!+Ntq3h?#JM&@RrpI|4=QYH#TWrqG`e z)cD~2R1GC(YOKS$qZ*2+-6(ZBleK-J=kbb{(I^!+ll9rQK5LP(q@!lC&JMEfQ zlvchK+Psj~uXY{h|L^TKpGsR<}0VKO8Ubn8P#W!)5%NToJo?u#^(c z=ihM^nAfFe+ytSEcb<3dx#{!1T4zl(HtyOrjp z^w?$#7ss`j3O-i3>oL9%orMEY)JC6lJl0Bgp_&|ImH%q*aO zm!>sLE$a06Bt=%Z1j>^xTjEkEplAA1+%(iH!Ez_4@3ga@8b+Z&V!b@nzt4htIR+l- ziS9IUZlJ!PFbnE!Gf*3b+n;euN-%*kg0iu1hHjW^$4^X!Lb=UMzjK#8%in=#YYG=Jt4y>`g*&ZSR_c3OJ#y1Wf)nH16x17JtnTd&NB7o>)J2A}iT->- ze9soBJyLtrMeZPW?a~DlMU3fEjDsr*a2t&lc1k@Owdd*~rDIMh()Hq2H;qW7B0u<8 z0|&D3u_Nt0GE!E#h(JNk@BI>g4HpDMEVMJr7I(I6J9*lkQ5_a`CDmbJ&!lf7W&_jW zhM5;MU3UOzt1G^hdmO@U%8~id6k8leuZ#kZnY%aTG(M(>?7?{3n}?yX-XAEk6; z<3sXm5A7`nQed8U*BCns)y=WCUX-KY9?+vIUK}*PwAJfhXYidk!4i-1Ti-v>Scgur zAh?f)_NY%|f@&Hiapt6&J3a%DopW4FV&VccS04N=4Mu8H^BD$t=KrwtlwM9rpx#SRn-lRz zZg-##H%ub~a0&x(5(voTAi)B=nlxOZaW=aSb6wM%@536^c&1?GmLo>yTx^4#E8IC` zwMLK$@b>@ux!9JtMoPcDB(rx1roC+hj!lTU`Q-c8VydH0$T zI3eR+)7HtoW`%nI#xi%Iop6SZT_g4jk8N{P@%0i{q)qF9&QJ??WyWgC{PLBuA3tHL z=jLH|4lMthY>U#v4dh`aUes^J!F3$I0c|g~Jobt^$EdB@J&7JF-o7)@)ufiR2GT4Q z`YExNou{RF9}Z!VN)z$IFnCAh3!m zC<@bP0!86Tu@qSz!wt3kYsN?>ymq`8%VKvO%gzhJQYj9RfHFiQ(zecA;_Z}cn>yGj zy>Ed-4v7ETJ0?;zWu#30tgD4`g)!N|HYT3%U5X!h@`kRH^)ELXYr?{U->=QY)&V9Mb#OJF04VckOuxkvnJWXVhGSqvPdf@cg z_{2K5FjF+;T=kVmTjJ<}JUok&O>I_CldkGf^bhL-~ zETM~~eA2~;o9ug)JB9Xne^xc~Ra31ii<%1cMNRZyUV3D1f5|CF?dIZ|PMr*Q(|nsy z^rYd~t@1T6JU3%Sis3%E_7j0*(SZfsKo4EAZ|x_!N{0=q!{O~q-9GAY{nZV%W0jNV zb4<_P8U~cc^f&uq^Aq@+UB1$&%y!9ZFbLL+3+ukST+ROYEl)>{fE};?u6H#%*Zn7l zAF0I+H7jxn@rO_3Xg5g^GJcLR9M!y<6;(z1{H+hc5YT^Hu-X*7{)NVafI`ITja?Dm z*Bbw)%2@9Tyj!;$i0Zfuz3MJSHT|k+?ayWGe?bqyd%B^y(qP;^fz50os-MMwh8ZcK z`+Y}vbPT0XqheU3l+hn!|46NI3yTuObMCi9#G#Ap$FVKJ6-{vuB1LSg{B-wqIT#2R z3{t0mS**_3ZzvvvXBNHPu2}8FVG^CK6*~b+io*=b>iwIML*Q>c6n< zF~9$qkd&>n^68jYUXU%qzv9CwpOHzV zgFuHO&xsB?eN?_}JC5+I>g+(N01ah*yt9-8oC406v3#2I@}7?lgRVJ{B0I zF7i!V zVHvRLSJC8la$MP6jqfa<`0eB6xyeg-y(%F79n4;#_i&7z{7|^|lg&ky6gyerHtmpN zCODP1xjXPu;IEj;6LyQ*m`VSDnItijx49Qkq+-wdt6X;YX|!RR?95i`%TfO?$qnc! z^?rtV;_3o=)_Kc5OM|&gRKYQ0SoGd<51O^U*}J}s!LNfUxltEyDq~L!nZw`EZaU!r zEoNp~peAI&Uhlq-PNT?C$Aj;h0afzB=SFs`EB(S~b8MB&H@1nrK!;Ybm-X(-DAsK1 zMkH9RCTH%evoFz@RQd@iN>CE zk23&I{*y%vmx=IaYIUctf-W)9WDST;lTX@aDfutKdZv*y{CYbxk90xmOqs_;n^T-z1xoS?b^+G(S1R%dDFJKDiaByv(>%B zN=&13vl~Uu-1gbH>F8|cLfXU(@Y_b6^9lzq`_=i2gM_*Htj^cnH2~qUS1s(Bc?dk} zf>#QKr!VpNdL=W~Z}KbS8qUSEfG`_Mg_$2o1?PR2Q5(@QbpMv+{voz6ozNA*+kK#c znr-p_;;MLfaCvMpC0bn*`dxk9ke|>-Y<2DC_UHkS#j^)`G4nmf8n2!nj~sxcndNSw z9TPL9>HEPP7uG)!+*)3tbH}j+H4ydxCk>u^Q&v76!Aq!F;`E9p=e@t~G&*(q1#$#7cAE1YHBM%3iaW;!M=@5uBRm z(4KBn&*v|f05mwj;GEChNvSd}x!&+yl$J86d?YP~=KhTm__fV_m%sREh3funKi&z= zwV)+~*a+JECA@#3ZyAVLkZuzgM58bsnd+LyjbQoqUJ(oQB}%YBpR}%on1p{CtX(c4 z#u08tQh~L(KA20Z8_)8$#op=$(6_a{!i~jrnQHS>7>Bs^Ai%zHFoRJMV>3g%SPt`lqKcKv>u z+Xgt+j;;lffj)5~IbL^5?IK!uOap}&x-=30pwML^KH3v?`t&l1Bcs>>10>{CH0;f0 zQuSKgW-#bC5_@@j7xJH5Jt_GwqV=1JkjZ}^3j0sn`eTZYS|M0W8Bsf7<(q$Yk}p~B zLY}}B!#~Zio~Y16qo26L(+W;hhqe#y>$xJYrNI?vq>Li7&0C?(Y1a!*6~M)8(XH5` z-M+S8m~~Lr`E;vWKwpN*mC}8Vg^FbIJm2%NPvC*@v6o6WJ{xRD+T1OVvmJR>+mX=R zHO!edDQ#|msKC2}p9*+I0eCXX#j7!c5=yJ|Joo17D%IxBWAg`ivNJa-qNpfie?~&h zmq&;)9)mIlxQBz{W2|`ca)Z-O^h!y=zZ6NyM2F+Y^>y{XSJP-Ggm?MSmO=@w&8Iar z-a8wPsqPdSPHq!~6oFFSfaSqzz3*KM#0!046+!_bP=1ye4J7DSY2M$QCcdoZmg!~B zCm6eI)}NGXTffp?ZePQ7#H*haQZ~!5uPdbA-^XLaX63}${vP6aZX#w4W&)dVH{T8$R-hO(Ism_W{u5#&_G zz|xf5R|{knody@SehipQY}Ifr#Gkr-?Wl|=yI??GsQjB&gf^RlPwKb<+IxY`R2ll! z9Kas6k?UYzti#7VmIzO+B2<^I< zyYP>`@OmJXLf_9?#Z=#4{yae`F>D?#zyM(=Z4GK8BP1PQ$issqF^Ad(K?aD5^>k8q~FJ zs8JVe{sFh#yp~(s@wOG^%(T_*W=*!ZBT0f6|I&t~>K`yhsy}4aV^r_!Vpg5y2X%Jn z^UIj&zah`t&t^Odvf$P6!ViY{X)8C`bWX~C_QWb%XI;-zM6N}_rQA-Dn^YehjyoM^r46o^ zWL4u7{s`&E^A~`}0&skyyli%MgAB?dbA@$S~&7MjCvgT(P@ht!EbHF?xxSNuBHfS7wo`) z#BMSV3kr{2tGwfGdkQe^3>o~l(txdXI|wkjHib7XE%92Ai1zpfn#UDsw75m#G<@1x z-Ti;?Y0NWPU|`M66`|m@S|zD z5+fIk_{SDD(j8~ZHB@KO1meXD_K>R(;ZTgDC@?D1t5@cfc&cfVt?mWmd95t`8~+MI z+%hxPw6s6#@&IzI3*B%Udo_kw5G8CN(0}CK-zey3jkEVX{7hW=h;RyeojV$R8&?MS z3SKLof!+8LEmN6^_#Jhbh-FpmaqFrku`knlSZN>o9wd30M#&{ z61*3rQEpLl!|o$Hqvx&)hHW{08DwMILUjrm=Z<`vK}7jg5&MUnw?|gQK2WKKr3zqM`kBUyBXQvnKOzHq#{chmQoY&U5a{wrD zsW~HO`Z+DDpZyd+CqR>NhUZu??op^lP;5_bQVYIkl!viwHM|BHup0JH?Wc@0o&T`L zi{Jzdz6xvWn@@3;iSW|qME9~vm}r#e#TD9itZ}!Q>c_*%UITsMBT*5@nbNqnayuO8 zKfY&of)4+XN=16Grlya#+eqo@taUuQlle#OjOO9)M!7I8Z)?1wO7(o79td@LzEAw1 zn{Q3~L60OSf>u<`U)f0N9~lx+QtW*WB*jZh`Ko<47cXfp%)vCT;-o|C<#Cgno0G%X z*G_Ubuws-d|D4V&bF=&VJsM?ubT63EXFGaUxi^T7pM0SOfSwR`&#izjHIY^k!?`xc zpt^I&9R1}=+(-%2{;)U2qM0>DcC6I-jjs6l5^Zh?^MNJ%s-S^X#ntE*7Q}`*T;ZEs0lOD1s;jMkM6!4CO$E z0$+7Sz@D+A1W?1Qgh=9p%4RDp$_y?vi{G@lqy8*z!g=fsLu?L+kn^52|7)MoWbv5d zSDb79cP+vo{vmQ-wl{lSWc9Xx&Lws9UtJEy2vYa(fs zzrQ4HZ;fin3ff-ttw1h)i&eyQA3!!|6@#dvvkJerFO|*`k<}RG(jRx)qw(R>u~nF{ z^~Wg4{)j;;>AC26sbhfelS3S^Ac(`mkxg&xv@rSWZ#-R{@Zs&FB0@LnzZjE_u-8;* zcmJU-GVIT`Uv7?RV^@58zucrEnZ}n=22WcaEI4sG)R_`p!plnt2VR$5}=qMWVs^|u?y(-!ayGiET%j;^Z(DuuiGqkR1bY^;y z9r%?>PX9M8DB+H$W=eqE-6Pdd7Hf|AEdHgf5|~$;8~%X}T`F${_K3jbmv1I_i4Y2P zI-;n>w;@ppNBeTp@#}S1(6g54r1!Jy`21d3`78LHY18Mwcb|t`_4{^HzbPv}-c9}c zv+`S*h0g8I%gV3nrvB8d{O1>Stv?|v|H5wCAC{GWb2s&SW#zBncLu&lJb&*?ch5<4 z+r>FKnM{6p{4}vcV`dlRjNE2#calC(w22g07~gJCj=KP*mfvsb_nG`oiSh0jovxja z3En)q+_xHu5tkf|xO%XzMf7NYA#6$l3+c9EEuogh;D8QQ#lR009RwMwY*r) z5=+n4cXCtxeTbaJ=}^fw~fPqAUim6*&ww3%*=mz*nel zuKjp{7cV;uNCwj3?poh@^jJiEy!h7sgYf?dJ=(KxqDpWl~XXEU-df$3m0l=iGQx9xr2hS>}z9z0IMambRt}eBR-9+4CHTix>u;OQ@$3t zbScbwEfHD{k!~S=z-2HvYJ?{ba}?vcSQbf`@h{Qv-75ej^~P?ngl_R3`f$+{gWie| z44w2ZVIm#WtFVK-_%NzL{};Re~FBU2LWRoq-Pg1bIc zb%goNVsUA9v)&m<*z2PTD956GF;ah3k)HfX<==1t|$751tKF1aL4oG1&#zqJWoi0GEB0M<{sX&e^hIx zZef%=ehZhB@3b&XMg6Q8JFy^|H)`P$Y8z2m49-y5;%;H}c+s0ZMl}i5ThwN~zOsGLlJvP@^^c#YyOO^{NC{J&h<~u$}fJmYyM$b`FC*O(7FEhS^2pz z(9Zdr?#PV)=5F9$m6d-&H~l}BmEVqd?A-osS^1B@-Zg(lR{ldj?3#aaR{k!GrE~j- zrSh*VU|lY*2}NSK+4(K{{_LnAk?xdFnkfw)F#iZeLbT@ZA8iQDeM~EzlO)#k`9<&< zQ>fe*e`fQwxprOd%rix)BZKqYdioDH=$<&tVTZnA4y$#)$h{>&t9wWB;vOW28y*p1 zw~!ic_@giWejm?E9wm{6uY4fTWr*5ghXMVlyOc8F23gD953KG2U-x%bx7B^$x{=;x zT!;nnO`kl^UVm>v>9+o)A9HbGGm!jaTa?%VkVv3a?FX9MPcDLMlu+nmuj#g_(7VuC ziZ|K{4V2!ka#K%FFpR`Alz9I0-^EOq3WQOgi&TE2H>j%*`^Or(XE9mz-|ABTE}`$s z>!;-FOFs#4Ve)mT+v7D&p}D8Ui{G#rZ*hM|2!9P(szG}GFe7N4!S(`YqE@%?)l6es zAYSSR^4RpFk)n@%Q-GTDAZs9Ad=B7ASw6c>(`L4i6WmkyX4$P%tQNabU}$@YW2Ilw z#1V7&ha3I;8!BJkh~kh_7Ajv%D1(yt$ur}}_H+9$NKGvSS7X8sdoP|VW=m>yCsPG! zN|$zx~-G!N=zUndl`vLzw=>DL6V14=hQW#{c z-2}a9BPds&_z5%PlM2h?M{VPFgX31jHYU~)Q6k)+dp;n&MYI_&-0qj#<+uahvUcv$ z$z*-`(`s(G+R?e5-KwJPJ1Fl@8=GA#B1#SZoCalp+69q7oj$7bGIf&6&Goj;-S@bR zK-eW0M)#(TlLPn^CoEpg8=U=ElT+Pn-&|Sjy+kD~R>m&AUryL7Fx8B1@IKc8{i@#MM{#gKo?pUb;P31pO2lD*B;%&bDUjK1Q-|sF( zKJnu&=CGGlQy6bIm})A1;v4JQ<45Htb^?(+n>b|=xGRe-n!9Y)?ty;v?UC(sJ}Iop zpYutdXy0&qbAHKjcF)xnBNdxEi`@?w) zZ*f>5OI$>1bs|-f;z?N5{91n>}M(tQp!Z*w`~tQZusli`-e;k?{o?+h#JN z+gm?nYKqP{zDS%%$FcRo<|KYq#4aalIj7Dqmr2aI9)xo{_a@$*+9o__^XwUitB3KS z$F?h7^nTA!<6m;74-CHY^ffI%(!MnLycH!_I7K)1EG_VU>Li{Pnp;R8yy28fi@mJa z(64T>DT&yA1ASdopW9EgO5DQca(i@i`(VKx!czAOj)j7U0>p|7 zgjQ7idaWeQ6I6214bYGl({E{2wD`x*M2oM7A6LNm*eV+g_g^LyFtldyx@}}pB0tpl zR?hUXdIoIV>?;N!2im#My*@XRw_2}(C7Y$uv}19fP!M{oXJnDft9>&!yTJWru@~x3 ztUdSWxjRQ{il}o`F6EOq`DFS$JbGc-=%aF@-z%FxqLNoBYnNb6`MVl7fFfBF1Takb zULKekgFRhA4Ut9f+x$;w{+A@5Q4`6h%7R`?QM^d~oxYRAEs5TRVfSm!Kg(20Jzo6# zp3;k2+l%Y(*i(n?bDa^?(FHu$741Fe$Rk2?$1(%_sI0%ZDSAkxy$OHPuh|<{$9NJf zhov*H%MhpK^Eh$x&5HKs%CSw;_V)Xqp!81JrTy|K@CB#;xqSY4?77+?FtXx80_ZUU_JH@y~v;XHKJTql@J~0%4WK zkPaWfloHXX%p_s}%8xJ{D2^5QXX%Geo?v5k%vyA84l)R#ZzS!}3ovueen^Qgj- za!XiZS||Mgt1`wTw%5!{{ED?=(|fwcJ%0of%dCdNb3UFuBh5pg!z`|pqDpZkc!*|I zrHe(-%-FIl!kyNKB^Sxn)V>-_?VejXsi5PdTnUo97{r3XVAK^DKXA6ze@be&;a-oH z=O_sEx`UaVil%ZT6$j_>@}i3Ra(2{=_*BY4B>{yDMfp;yTILncyDDN!t41t^oeLIZ}f$) z$}0T3pm0A5C#S1LY2DsXo473Sf>J=RAnA-C>F!L@#31Q5OZpxiCJrMhJ@$7<0mS@t zuQ$5U^ooe~)O*bj%7|RZ#Z)wgBkZ)_G=`Vji|MqPM%}wVmZ*q6Ce5U&O?aO*Cpr=g8Jw6v8;^iSbAEd4GY0KU7k~+meKBj6_O`%(X zc3IIh!ILPLJi|n6)P}XUjpZ*I%Z_wSs%+4I|3V{tTd6%s4L4ZWws`TYq)YUz`;p%p zRPCl$ZuT_e^_@dTYbe(~^CocppOa9hEzSRZ{{I*Q!Tx_fOIeoAilWNcVpiFIBKq8I zEbx>$VM`VOTuA18GW!a%x$?ep=+WiU4N(jOb4ci^#kFo^#x{c0WX*9|=evAgnf+ZE zdp`7N9|_MxDq`ac%A}fx7bW`Qz5G^A=(^ik$E5Wn&GE`=R*vx9$S>$NexJVr~1sZ3S>>& zu^iW?qR><0F$7J_4fDat=JSH(2_=vl36(vcxCo}6>TMg}+l+K?*t5|r0OF}-rY~%l z4X^KN+M(gGEj0&P_Fl?npTn+eCpKIt*Nagci=+yU*Jh0E&*yR_1%_Wm;^P6T1zid| z%*w=HNl$?x*LUzXMopmT_m`r-*z55t6HllC>G}BBjqjr8uT0#T)ldK-w)n+~I?|W+ z$ei2%Pc13$zxNno2Kv=2>6|uH#&Wqspy0+~NsRs@0HLR7bpJ{!*OPvbO(#l zY==A`%$l3Ax6ZPe)NQL-AX*IU-ikHJe7j(7tmPG7(y~mbmgM1B_QQ7Sol!@iL3j=c~ zj=i?+{KQ;DxyBgkk5?OK#`;^Tf2!My2h^uFp@aWpOPkQY{R1^}_`RBpU=v!^BJ?It z4n0;jjv$zL_$1aa9 zHxbmnI6QW7G#}XmD~GO%$f^jH*L$-w^fd*4nM_%q-;|Xf>cF{u{{30`EsML>pO=;Y z5$?jB+n<`1fAS2xzDl$&d8au=BwTMrsN9P+STz@*c;Eb`Q(P8HpA` zMb$x+5ZtAj7K&}cKie0UjUJL0-PFENe&8}cdz+pZZbUCombx2f(v)`VXJOAlI>C6K z!W_&~b^OCj_N|)oS(S`@QiF7-w1QCXGM-|l*hY4>Q0)v~(hPKFd&3{Wm%-fX4Xokv z!xz;|v`iEaGBL24;$f9i#@?e%@rZ6mw|Nz@@`7;tGv)Jp_Nu@Pa+il^bl=cii{{b3 zB=H@_7y#1841DLH3!z*+l?FsazcM*k9YXZYS%wqRr|l6Q`+T&}%9mqY8ffOo4xRoX zf_0oykQ}E$s}l~rB ziJ#FF>6ZlQeNyRqOMvw62I)e9mA{yDL&==YHQ`uusH`=Wb3z6v!*%GoJ?PWW#iR`h z%{_)m6Nr@zhAscNtD@V4<0oE|>^16zal=t7=c41ZRffuzU`E0dDfH-JrE|VO6%^Xw z-#cGMG-qbuJyH*k9#%SfMsD=L%GkQ4y*R^Y>LKDh94u5Rh(psBE30&D9oC*uY3Qk? zV;6_!E~gUhR>Yo{k)ZZTN!0bcgi%u<@8t0O@|@E7QLc9p9>!joZdxp&h9!mPj2n~_ z-B^jR8yy+(MkMdWio6rqkYmZo%?Zu>3+-y}UMeG>2>U@2nErls%WC$K*LdbUNC>Tp zUy%zctKzeB!}BY9@y?n`M&GH#$$t(t&4mAi#kLVVi8XNcfHonR^7-5LNW4r^qpU8H z+821Kef!@ewH2#3*F6WDH)sXcpP%t21)VfBxQelhrx_*V_@v##u3AEqw7udR&J%dyn9R%LH^Kl zw&~}N_Ts_(p^x|gMd>?B$&D923_-YK`2A&jdOOcQ*+BBK_nGpW+m@_x)ueh=6%O>gUF%eYaW z|B4a-7Pt)9k@g|w4;8G`fR)F<;s1q)4GpB*+5+HPNXB2I6yV&@)L8PrtA6DcDOmnK z&tN$wfTa`S00ihtgs?4Xmjag1pBD`&QFJq}b}T?cVfN87kOkq`KZ3xOCp=2BVsD+*-yCj#nJvOG8F{4QBC2pZJ{(_$u01p8@)f|DwHAFMz*q8noso6G z`V6uTzZD5lnnqK9kETK^AvCqS!IaP%A<5igE4dsSFW#Qd1)Nh7%o<;6&|S&i^D@b= zneNa#I2L%dGH$#2(?(XrE+k4o**~<4emi{nS>M!$YYR)`za=@Fe>^;$DU}uT6I*Y~ zuFhiz|`urD^km3VIAZ+l(Toxg1MS&86mPNnihCM<6}?0c=_w@#>4cXUzp} zXclZttD-4-?zeVwYSh=(+NfVsLNIDMO0j-e8Nomn1jlxz^z=AVLRb)irF*)_JDFewrKjqo@(vHeKce&xqgv18f*5buI|0)CDYL^S^ z_SUE<&+rs(K=x@QV>F-D=Xjj;a2wc&c}PJ(H_l_xqK9dO2__p?9 zaWM33_)7)C;^9x6k3ymckfX`!C?0}oL#VE5uO4oqbrcTkSdw5+ zp>mjzzt4&H|JLI@8$QGDMVEENue?-Ny9eMDS*X1==}|k;P|J-ZFNbfv`O8uJu|GEz zYG1rZ4gOQ8wLwPe3v7)NFl&K zUl{#L=TL8No)EOmTHUMhe2^eIJB1a)D;!YXjQ8Q&k(b@|m?j`KGdFWliocQe$s@mX zasv2mD&D#zfIp)T4V9a)8C;EJ^`j$oEy)evw$7w}qh$i7wmRemIo=bDop1vzqO_k~$zYoZNP<)@{KfI;;F&E)IrIdFe#m z9zjVJ+CnJYUj+5z`!#K&&F))h0BiY$l0@(=ySlT?BG3`O(y*wvQsdR7@yP3Fl>=S# zjhelL?An@@YWG7UU)h^Ob$2uAiUz+!B(@En)}y(DgQBpEb;x5%raG7+(K@QV{UtPp z390ibpNin`R$ExUD6w1K^C(w)WV8h-SMo!mndqW${kS1U>&aQ2m4zORBBfas0($a0 zP~zJ6ioI$TpLma=qYRWnC5n+Caqq?{HY(h3Q9!}s`R;iVskw@prbZ~_a=dsYpPtjd zjX%5RpVcy6pQ2SfS$9q(eSA3N)4v7-`qI_#)tSNh&xM{;SdR)RxanO#p&v1>c=f@| z=7Cy{oA8QDEk|xE4oknAE{RXIg;bL!6`%ME*OFCM=R;Sr;=dZ2Zv3Hl_Mq8)G43I+ zah1OXR_5{odOU_6y^z%k-4j4BNKa0MhrkwbMox8_tRWPloqcF0(D`)cu_vE?vJOR$ z@ROA-?6zhgK^c$VlP~Ci-`fzlg7XE#@0b*RZ{xHih2J#0i+p)!zWq(-cWD2xp#7w^ ze`u=x!@6sK_?NfeMZVn-bd}j;at`5Eph#uOw@2Uc1AM~(n3m$JkN!t@*woaOFbUTN zl?>_=E`hJ&oqfK$mP*O~@YeL{6VltW*H+`^2*Gd8V*~m>&*P7H4lIFucf*w$PIG&; ze7y{~ci#3RYP1nu>PHlI@6@NKtb07B?jM|(>Vb_pjyW$~x+em4QbBuhi~VY0?U$Su zX&?FopWV0QQ@tqY;Bw(Ufy2({^bHyT$@{C84(|e9Sih@>b(9ee}f|{cT3$pSASel2j-UD|AF21 zf5Dde549KHc!|2-%^PGgux+vT)P0Snb8V!dr36Q^{~pE~K@v_1&ML zO?Ulw_-82ob9MKv(f?>>#7*$^F)E$&7mP|%AEX{qZijHgdy9zkUG+#kGqHsW(^krhFW3Sg&@_K!%~21hdDb zD%;M}h}vD^j-VyHvn%8IU#MC<|2^v!gHG8H^ka^m^82qLgU=Fo;8|)&bu)`?YXbIs z$y_LlK=B>vq0@zOozZ6(;Jc*LcL##1Kdw`I^~ZH6@8_@S90sE(|Ck(64xh*PaxZSn zYzNRyf_t^ys!QC*40p(g)F0R3+qXZ}w;zcWK5_i+Id1;_=C*m`O?BTRb%Aet6bAi{i{5ed!P!VL6M&ua2JPzLFng8~e6eN_B>9`yi!BQE3U^tM*UPPE zf0R7Q;sC60s~*)OEPtfWGP!21sMKBcSapFr>;Gf#T;QWB zt_Geb2?X4rM5Cexi5d+mx~O1$BnXOBzn}U2Zg%dx?#!7pXU?2C za}Iiybi5lMNfry_O<2nL08Ixh<*ZDgA?lO`mO+^Ru5YHsy1dJPzytm|YG1vBtBXkt(bgIExerQIqp6Qck*W{wn_Sfvs1=%Vjue~J7N;4XK-F}478R?t zb*g;;#WkgPQ8I_qpHZKRQi@eVJ68@eDDOL>8OLy+%J@tlkW|ch=enYC*Mj7Fkr%^|W@XWIem-kIg zi{hL!W@#tZV;`|H7q(lr-mC4C;5-Gj@)T;_1!|R3wNA^?X|C#7a?U0;wpZJ?2r+ha za^%oRAld+>gfiSN-V-!-jr)H6dwpglf%X@i%JbYO3`t z@v?edLL^_k{(f0`gj8K7trD$< zKsjC{@fAv@tnQz27~F48QBq}J=X?xpghO;0!NDSRQP_I5!q!CldgSRx9`N;Esl)1ZfO-RQ z?SCu0blK-KX&wALb$tv!Utvj);pgGR3w|ykQtPAL1}Dr#o4N zVkb*aLwEuUO=so1F;|Fhrcu*I#?}*o_-}k7Ok8K*cCHZBDx%c=`V}t=tiK?aJ(Z=~ zsQHp0)&8A$!S?fr)E*ohSu%?O3x9%5JMoCO_b^S@Bmklp_*-*WnfY-0KssEGxbHK& z{GR!*$MqK`z49b@T=h7Z(^UoY&zSVv{lV_lJ6uLaHKPY zezC`jnORDi?5;*#s^&e4s=clv6Wq#K6lXzM?yi-!5MKNup@K11#l&y(dwT=|krz&N zY|uP*zUrE`NfqTlvEQZH&*NU|$bLSrP(`tyy;P!NKmST>jQ#w#a0LwB{gM@Ks;gt! zSev8!<)fl)k^Qp0OwA~TCJ#}gvt)SGmz*WT(qB>^X*rIRSe5MpGM->&mqO3Kj8`zg z3}bj2_t2p4Y^IJ&R+w18C$OSWhH;!N_UgH0RNG=#_3yw`qvk}(g$c26PGp@NsJvir zXQ47`2C8`G1BQ210)9AT1rswqp{aT1kg1uKHwo#U6}3KgfYQRn0GYK-*%Jm~yd1?% z8>Z*)yvJmcj1w6^DE-1{q^JPPOdZPS7EkAe**k;pg-d^dP;Rw7M6Kt;Wja=NXBkji zi)Mr`vPLV=n&dWW##7#I5r#nTEKXLja^1~dN32mJhPdg=A;injK1*Z`D+2i)eO$F9 zRCE++idqA#)SV;MtXDVOOloQ=m$Jk2z}#osjnuw*aprf7Kd(_l@b~A@eX&K!G{cEy zGfd-+YhfBcwcnPVojyRwv@7Px%NLlOlvTV~@w>0Em;5W*NDd864^R7Xs{y!5C@Tw4CF`hlag{U58}tC*y9SY~wJcnE zzkNQZsSJ6l)CFU~38NfeKR^a8%ACp^5|3Nz;4l|)CH=&-FTRgN!Lvp_ zQE;Cks%Jq|A(aLhpr=pp-466La+}QB%9?80}gmg_P}9RX2|ew-30Fp}Z`HFWx5kWgDjwr?n0s zak!JXh(y^|IcoK*?8Dn+8mUd+yg$g1*V)&o^a`X5Qoq0zEX=isF*4x;b4>O(<$jpYz=2+tY4J4 zd&#z`oxSi2>lLA*Z>f~m6f<0QjQt1rgea91Es-dd6n^2=)dHd>dyTX(kxJH*APRRi zBnXxCho08z4@Sx4{*}_=VTw%l!03M`bTW_Z4xOwMZa~w?9x7JR$v+btqmv)6l5VcFe@5gp zLhICMToW4&A?A$6O0wzE*lypBA_ks)K*JVdo!g+8Znqy9!RPRdQLL16&>5xR>Gz9i zyL2i4B&Ty=fk^MdIlm=Bxzez&k#3dz79nAW6~nS^6>BZa?3>ocQwWT zU#IE)#qZ03v#`_1a{B|lc$anhZ3*d3?0Y+=U!IU|q5078Ee|7f%zjunj~TMZ z|NCXC{Sc6=s25`JuBb7Gd!4reS|mvQF>q+#ap#R?`d}(F!#!EW(i%+*X1Rx$Li2?( zIit_)2sks9?Lpca%(Xie6le)~EUH*=(X>YGot+)?rT<$tu3wZ{_@nP#Ik4 zV6`9eSt;o0_zP=e@{i8!Cmf8O7++vXZduXF>sGmIh4Z9!d_-*x^=Xtp#DRxIb=uFa zBAxN~EBGl;t-K=Tr>!a>1~{UysY*e3t)I*;#m0 zUbj?d^*q=G^8&b!W@#XH>59# z2H6Vk{k^)3LTCPqk=?0Nw>71DRISbSfufo%o|CxSx!#@+2^HzM3mJaSfenAzInNxAk@BT8F~Z{!~|CJ)M#t{nAunqvUSv8^mZf>J#X{ zY0b}{Lkas$+`E9U9KR))QQ-O#Ae+P&qxsB9>+Qdjm1%gPp_G)(x{Y!MG=XaEHA4MD z>DLZcd`{(WQCv1dhh3>&Uw2gtC&o!uXnww&H~GV7VA>N#X|?^3^k4Ou&3(50Gq`4Y z&3!8S{rS>c*X>6Mit5eaCrbqvCP||Q-UBj)GT^yf)h9Ff!kaxo33HN7lU9(CTD2h& znwe&wMEiW9;o440G6meP`$E^iv*9!84k~mbLzg-Zpgm>Q%uKZfaD*QAFK=fL0C%TU z|I^^a5FO2+5MQcLUuv{}4McsRw6lmRQ&A(cjT#vm`zMkTIOD7&U&wP-rmI?RRjX#- zC;>6Y)R2u!CfBVu(kk(}bDz}A;0UCA5zHag<@$?`I^r}S>%edNwUESa62aA#AlX{} zL|t6ksp@Woy%&XN9n#w4IoXxfOypk-FF=aNo|nB@gW$z8R|u%#WW&9zJNhK~xspiZ z?;)s|bXl$P>=m4DwX9{-m29=;6+&^k@_h|ydN~drhV}Hxq&XQb`#l&221VVkc(WdS z-T{8GIGw{-+FJ>${tNBxgmmlrGIV``Ge0;5+Txlgwh9y(Mb$+~caXyL>JHu0db(_f zO*4FE1(^}A36;%jNdGHu6yq}W0$=~6NMoSw1lMh%u;N;D*r}wsw@eOvelv*utn7x+ z>t1c9Hraj-c|cW3sv5*cX3vy5*W2@cLLaujY>L8vSo>6ywE8Rl2=I>L+J}7*!i%0 zYv`%R`yekMl3Vr5X?=^(z|oZ-MxGP{Talc(W&M+$OjW^=1lu>Icx+8EN%l(~RfCwD zgngTkho!0lCU*D)y5wGJid82o{r7I(fcCNO<&m7bhQmfO7{@YG-_w*Qk~7bV!UFdr;sgUCIU`JpJMzJ0B#K{>u$P}&HQU({;-x1gl5+t0AguF# zOP)y1mSO!l6urSU?`~c#Z_=4!l+JbAJV~s@Q5ss0W}r636Y@e3OPr0B8h-g<0or#te1vP{#x%I=2b4|8aFrUfj+mt{}rWWKf^jc@*D zV*ZmEKE`pH=@+Y}V@2k49;^H;fMvH1jg2%?ru07#a7K7uHmOhkOAXG?ywSm_ypG8e z$+?#ZfN_}_erAeP^3bWWkcTS>V`L3EEe7M=pFSs}AtZ$^XF}S|!1ClsPH#W>C)KJH zlvl%Ls*ua91L}+|=J>5z_9c9yuzw#sp~QAqq?;b zZ#WENxfoUG2}zp={cM>I8S?;$0y(f#+mcAmJ06WzuYx(O{g5A5^b>mO9? zz0wM<$VNtn(}r`;ob$nYjPuRx?&q><;4bpO%lHBtHki7>W_Vm4*q5Dnp7x3B=HhK; z_}pRwVqmy9Z?dZb9Icbz<&$04Zph@{#>`J#w+#KYWZod@DxRp)zezFM$*ObJN_?}g zsPVdo%%YXkxxcU48Ql*&o7Q`BC~XvaPp!~{Wg@?xVJsdkjSctuvL7bC!WZOu!`E%| zhHuE8ykPRsz!}4j!q;VZTuN!U4>y%l0<|v(+I%wyo0A&3`C8q5{9D<0P@O-wm|tJ& z^2kOm1)G5-DXr@!dqVrSX7islp8qGert$xDlKn;X*Zs~6|5D+~%t0U=JUnw?Y&Q3b z6&he?Rlzt@jz-}BGxq=`JEdCuo4TgtIkw~c%hE|mB#{t_=@9#Myf;7fqcTgyp#5n z(;lZOx&>T#t&rIvh+QD{fW}K%|GrU!I&aS_XY350+JRpUpI@nUV(-Iecqi={NPE5# zKE1wagQDlFON$gl%)@QTVXj_$TIkWuX9-8_UJg%ex`uNE%g(9u!&}#) zWZ_u*x}IID?04 zQtX02Md9x~UBTbA=+$ufJDd)zfZ?FA-NPl#8q~VMEA7X0LN>rmfM~oQ6Fz5#&-v9VK(dnrk=n?7C07B5H2*2nfwkcf!-eVY`6R~PLLTAoM8`!CiV*H;E_37d2rCuWn*N7<5tO6l7s zfI#l^$o=mpb#CE{!sSlx>Gmn)Hfm-Q37FTA2Qb@ToGl<}vL~~t27ExfLNt^hx(y0{zJRjg4_rb->n}}9IZbVn3L0c{LqU0<=b>%!)qao4?k|-4n(JC&u8kmVv zPLuth)AlDtnq)P!H1oR`aO9g*A-z%Clia8(SnDYYuW*qd*EkZ)$sH_OfZVk?kUJn?TUz+7!NA``Q4v3LDpiv=O2$^p8{!BS=E zLJ(tD_AD8b6qm2-xiS+)Oy$O`tsZ7H|>!i+2@rt(8y=u}bRk83r=d-P4<+ErOc z{x2-Q$g|2bPPPw}7od{M^7+e!Y?+UPP7^){Y_bn093?KD$+P4D>2yc`>LgvOsFa3t z8fOT&yW4jmOf_nzYk(g9tVYmM;U5B>(SE^)1b$5I2EmLx%G+z)loCx0lmj9D-9ZuX zyOj^I85yMQqobgU?!@)91lU##b4id!zc-8PJrMv>KRQbW;gd5HI;YHz5 zx%Qug!0L-j{Xx`Ca5jQuX90@vxEu7!Vc18GLF!sZoUBI$_IA-?7Ue~uQS*sbNe=~P`4 z3Ifhv=8zk+XJ#l*53T*Ab#GF@sJWW|lsJ(l8)zDaOBdNUjF#ST>EnHvGw92&Qdjk>b|aM>O>kVGT^%9kF}E zgE<2uw@rP{lHOrpLa2vweYl>E%Fqn7FA{OnPD8`W*J%GEzl)){nz|X9<7J6simI{e zWN3z=I1wG1lfkU79-4btj-x~K);ZE2hQ_a!S7&IhBZmyluRuc?6$WP?3=RCHETZ*h&E|Uh=dw2FDNz9An;b6TN0e9`;9r!A_o7E`Vft_~YHtuhcT?70!bnE*=}kiCUP%)%rhQoGpD#-PbelE(b5lPw%Bbl9H(;NyP-aAd z{TC>cQPYz++Tc=oR@z09+9^3~|1sXoumO2Y@iipn(chhUJ(OSDMecmxOVQW3zoywI zC_p<-lEXPSLiMdiqegfU`xv3<8s4I+Gm$iz|D&Hx$-n(Uf12*%^@r70HMk3T=*!$W3a+Uupl5)SbJe z>PFz0iAhF#y`14-G^m_L2(?%!PEJ((mp`F9A&3z! zpQ*9(8oN84K;M2iWdrBN%DyezNGPckT;LQ`lp|Vjn%(SI1@}{Gjm;(py-R*1L%mlB zpmYAG`v)~T4D89I9YC(2#SJQUnDJ41_|kC-B5FC}-qGV~EwXPD8IYcz{piqhM9Xlh zl}Ii-=si}1y~6HNHyIE3@ecaL(}l=cIU+JHuTMjHJFDt&Gg6YRd0oaD7UU|C6~y$5O|gzLMykuS=jX{3szP;0kOC3DTl;H0 zi<%w!qF4wE`tlS6Hb!3#Q=eXG`}pwUTWPiQ?K$10WYWT=e}j@eXZzWysU3%MC(;2Y zzRg#SpO+T^dPjfoQHCM@MV&r8A${u9ozss=NWYW)ZpZQ&3F*a0?417oG4b#Jg}m|d z4!wxqXL;JmYOy1H%{K{dpPjPWIePL<04wU{>gYjm0rqW*MyhNXIv9W9`2!*n6T-$J zyDBV8EQb~TNgRGR*`LrrjnS2+~IVJP# z(vD!Xc^&DmlJ6)EY?5vfPUftSJr@68wJ(QH0qtcs^3LBhsSyeg9ye9*My|B)VNq0^Q2qw@}WR7(wnyD?VXv0iJiw0FPaZqDg`zado8`agcW07(VDRRyG4N1kp zA!hhm_G%@$uIwaNZzI{2ZDzZA`?&2_a$?Zv$Il5t10y*l#|I58>y-=$8u|Pb1`W&- zmK+x}#BUkDkNr=eTQgRit>@7bo0(ePyaFGn*iO>QQRF|99YT`}TLbvQ(zAc94x3cPMVa4Uz-7Cm(s!CgJzsj1ZQMu}_ z8iR6AF65swDkulh^q?m>5pIS{m)eb-^BFbI>)QYIS4~ z?O}#vqF0u>6RGT{PGuuiWmiRU=ydAR+6xJF8Bddm<#1Yx%;O4%UzYA^C}_$lt5W>2 zS6(Lg?7ICya!y_#S3>aE6sbJT7am3_PyQ5pg!CF>Gex$di*i-JT-6)M&qg3PEV=Hp zOd|+8RGB}eb+CPyyQ3 z_XOW61l0y6!ZqfEK}ZsC9QueXrwuHp5&H|~w7#1O=#M3VYcI==<*a?)JC#_85o`Yk z5R21U8IVUvF}0%xJ&{7+9R!Z8f9-{)3t>oDKD5vjq1f$6EWxM!YGl-5>!-HdM_|Yi zmHX8^tYV7mTYf^ov}PhdU6zK;?#d#cb-3^{=o+NCeW7lyg~N-3sobwNf+HYBqs|GA zfE0}?4~{^Sa|G@chcoHNnfBe6K?E2X#UDFrwNasLi~>FWC!rs>=4IMA9P0x$LVReP zp$QOllVP*SDAcEvgO3>XnW0LrwD*S>&_l9dFAd2~>!0J-S4$x#%Fkho>h8hZn=dp(xWWINY#*rih`Iqq)h{`Z(SgZ%!t8 zSPDyVs;}^$zPk4_&D4MTv)cScpU>za-#lG%{uGNG`cTEbd7{wBWY@g$P%mrQh;Yx- z3hRy31|hTf(Tte)nS~I#)vd=GPl}CYhWYW|3t*7LuC$*K0;<)ED?MgtW;S||%(pTz zky6>qXZ6gtf59s23!RZK-en4<1%7HVYBb99nnGR3?z)9bpSSy~^S~zi3QD+Z9m<$+ z_@xc?7A{xyQ!3nKKYRs+;4TjqJu_KSSIO>~HP6xsRjsl*n?hCdV~-j{;zx^SyEqO~=1hR@=LuCH*t-Jp0mk%G9Y zg_~5@0h;WOdJE+Tu{bIFt&sKZzQ9>YRjIzvSzwc_n(S=lj7hpBYkIU(_A=E>&CiOX zj#jk`&n8ympxh#F%@j!WCuG!!-BaN8+QU(7thet)??JxVO?@*{I&EI0q$xj%fjLuy z`5}r$!F(~rR8zoU#XPnXVeV6eD;_&8id~l+tgtIEgrU(ELt8542*2ea&Fu-@QszQa z5KNqA-;Y!(%AhgpCZcT+h@{OtAx7tfa#8$G6xVd_bNjNL%Yd?s%^^^)pivC0Heb=FGmeS1Q>YyuN=azvGf2(!x|^q@V%&sZWzV`mQNgPB;1>=z3cmzR z!(3_*l#;=$5De3NfB@rL8bvLSSagsYDv+n3C4xX8{xO~Y^Mv%LXm-c+nF;CdvP5)D zAD586V85NyPfJMuf^fXNoDZDgoDcMNa*1<;?)DX;VCmE`WO2(n!V z6@TWKE?JYK+9<*u@kO!1UUs;e797xtAO>g&X+9z*!gHe9)z|SQvHoj2)<3zk`uD(C zq>N7ogOR+qgTKbl?R|95z+Y@=)*KPP1yGEKsj*NbVc+d$C!3Xi@0WQ|Qv}Sj>ii8P z8=`iD*b3l?S~;bGCS`NgmFpv^o?`Z!!fVlw^r1Ny=9`y|;DiElj+ zka1};n@<5a1vO8Js%TT+Xhl~#6`i0eYO)W7?o!dAFgK&bpvcD$AZe04rjWbtQtQF+ zN;?!QP%G)@F{C7Ig$6Mkp;*PoIu*Yp3DzhYS+1KR?Ql$sEo8$lc)NPchmlC5r>O0w zK7Nq1n0o)msrP3TH`rwq&CVa>n%{@pYO-q0@>_Zu$n84KRyi{TIctR&k7$O|#+9^8 zNTgg7CVr(!ppGQxd;MNKdaQFSUPx+6xBxB`sEnXMfLi6>TQg^_1k z=it_Dx$Oadh)o&Ng@*{Ph?SR{f1!~s<~|vXG&I@Cv-!bbh2N9(o5RPGgOy9$&Ge-(*NioJX^Tt_H?6sEOg@- z;#;wn8l@Z7ONwmtI$PEA=U6>%r=IP|A!YyY&e-;38T9XuOy)(+0aCB&ROzJIR|2%+sK;WDaPyDB@_OiO!Gv3XRfRd zGI_;cj(sDf68hX9nmj`2^SM7)faXX7fpLt%YMBTV3!Oe!=8*z;={W-M#4Kl!Wp|03 z!~bNdme`Mheu1|1nG^W_#~*A(kYdfhb=m=#15aHM;XYvcn?GX^;gZniP2ZRh-jWdh zC?WjsuL}32@E5;SQW&@%mE{+AST#>^lVld{htR^e#D zlP|JQ1iPO6SrVw+uc5dioq#*i(ubUwt%NLFPVB+m!OVm_O-f>stct2G%0^JG@J5Orq3G3u5Pux369xk9i&uESKAA8fyxYJ z8=#eI3yk_|dpj$J+{j7BKsh&S*pG~;2z-`O?79c3lzeE_0Rk^+cD)L%w#(0fBt>Q& zE7Al{|Mw$Hi?+JvKPVdStb&lFDU4*E&}TygoLqfCT>5@&DE}(~b)-EPxH^0O!!k7H z;oUi042SPS%R1+lyJ1U)xum-z2J(Il@7Nrpls!<#qKS}mzKSiB*h6$|Cb1i`HU}N;ln3rR6rZ-4||dx znh5F&&kR66*(QTSgtR>C?(d2fpe=cQ=nsHM3P}SJ!xsJ$2WYeJ=^PqAhg3VG~ zl}v=luEUA#&!ZCi0a=j56y`R)9|2BDG=R34Mvd4gw4ae-3{7O0tRYsuClE{go`Tna z==a(*uz<%E&iDlHV0=dLH9!+8VQ@+Yhe|3$`{M#R`5tRL`5^6qDW6D2M+t6$EFzK_ zJQIL>ND@5z4LQT*c&5=RetlWZIstg-Mus0KCct+O;n@+|JN5UB6b0Wd@Z;Xwb#s5D znp+aZkE{E4+FVT?e?%Fh<}w+YBjJe@u%JmLc@D6~3$R9`b2wFup@h>Gbgox#~2N zp`^S6hCE3Q`h2D;q7G<&EGtZ?g!3egAxDxV7$V0};quC8w|DgGqT8VRUc?ZsM{`V) z>STjaK_ilIlTjGhkz9H7;>o;8+vGS?yUMGaFSK-reW7li5X#Uw<2Am@OGo_c_^!XV zC<4P$xMA*QS#Bzgz>b?Mg(x3H5p{F?i=qC4M^tms(RI#PFfj{lJ)zWER^hDqSv!d){Ugb z@U*u?69v#0(@}8yRSC;3C#iCOdZ$=j833+X!S2VULnE_Af627-kefIjJWxX?#$kM8 zMdSo_ynO;2&8Y6hqv}Je?Car09p1Ive!_4#-8)sPy8PQ@4>(@)ueS*AJH%&=RJ^al zu3l_seG=n-i|y&UhN{ty?r)QA4AP|ypLHJGFA|C&!u=koxZfuGE~mg_j~j`_@8wzjXP36u$A{f))#I zKmIwLK0G1)v39$CoqkM0`WC|R@`^vU7!8L%{^E1}C4DA#N3!%>8S}m|D67EH@%@MwPI;+h1qXMN zQ`UWmo|k!byP1Dn>C0Jtn^3Vld%Ms*eO@LLbrI1*fBMpfaQV$qQhW`P=iNOFbJmZT zy^PqtR52UR?NHE@E7zMb`7W6eV7JIGtJx}A*R;3>KHU1;W4&!p-?kM?p6pU*9gK>n zN|2L*i-;y}K+D6BB_r@FSzG;ERZB{yn77RM&jLS84pbTM3|7ar3+_voZuw-CCz}ec&1q zEWfR2QM1(aGtMyBkc_92%3`H(X;1wZpQKBO$!z;#UKEyWsT{ma6?yd0_Y zI9A#RFl~6nyZ9IxOQ;rni?yDMJEyBnGFUf$o=lOaX_Nh#LOfJ>i8fU9GZMW?MK{@B zaB{_6nDeEcj|ls$GMP6Ashoe8oHb4bvxrV28hxY!Ln-JP)(gBK5H1^R-xd9gT3v|7 z2+>M@iiL-$5K28onCEFstN$m8N6hy;fzR0OaXPia{*Xn6dti)9qZuBZtEfoJN92nW zIwz#*;X%>TOZ;JjF*=8Zqft>;8NI|piTtAa@Ef1TKg^AIedw)cN@ZW#kPYig8!~Ot z$b$tuM8;U?GaL?sGEi-1q=B;k%Ce6a$}BrV%^!q{bS9Oa*p9Bk@F!*>(-NakxpFL2 zqo~rc(Iy|l_9(w}ncGbpB(%a%WkU6&@-+qzeqbDqt_xL`@hb!2!`pQ`&Kg z#@)6V4A>&{V%CA8&p#IN-D>+j609M&s zYz5H_)#TO`*!2v3dy=WDOjqvFWg=;hVw&;qqbA=YA3JE{D9PaJ-LEZo(~I_{7Y zU3!5n8LxEnvt>O-nA^h~a!szQI+@oYg_Q>g+j12{u1zR8o z&J?E1{`F~MS-~}Lk%}B{nnOwoW~lOFRo1AfA|MS09-AbII-mm1pstsR{s)zHAN~~h<@`Ci9m*Nu%94Ubl2=tf0@dWZEFo3{O5-22av;>YL zaEt_wB~Ty%*oB_7iPvMTy1KT^pg+Hm(d7NOWuANtw!ZqlAik@51-SyZj86jPtf>X2 zb>YBPv>erytF7H*^H)}jfpTKJP)_hbtyy41u^dP2(a7$d%zEwk{Z@q+kfO~jW7}r4 zw1s=+Z0C}j?CA0!qFsGWm%m(>SGk`$GcmW8M-12LhE*pU`#d0+R3=`AdM$0^8`cVl zozGfpm!Qs}`HU__ISxII%eOz+;-K_L_Qz`Gwh5_VbQ-zV5<&X_PT)9ME}HDSX@z4P zw$VOYZ=Qve9gc+;(Nn;}3lx|2x;-0YKXIZSr-4l1hHldM1SY8~z;qG6Q~L+R+kf&- z?LWI+``3|mu}0lS`xX)7VZ+vGf6gx2|L+sN#r9t%$L@t2wDl!)cTNH9K>#LT$G)b9 z{K2$b@6Z~%X=zA*+78$+CMRHjRgZcHz^j1}q6zy6YJJ5?ga)|A$5&c4QV8~bPVeJ` zq0<*7q~Amb;_2?%IV}U{eAeCdGkpdX`0SRMx#pxg=0oxgIhfl^Gv+O+?D`-`^5?1i zIcu)ZN%}NxXi8zdxo+^8RDz{U^@vv(E3A^1Gmr8j5(_JS99Mct-QIZ+Yi$ zHAnQ$PE;t4^8Ba3C#sc*gK%Vj{%|>VG3ERQ!H#gKtPrK$d}yS)7UmL8;o41UDpwpl zS?jrbM9k3Sx((U9DVAQ|Q@F9jyARL4yrrqUV(@lodRAlIMzSuK`&G9e%}5AmQEr5% zMf@U=aK+Y$V-G42$-Hj3=+X0KF0+l+71a{M2dG6tG=xt{D4ow_H52GYq6%b? z#zm<>eP-({GxaU^TI76zFEeINH76~@>h5i|r}oC`Zc}6w*= zX6d|pt-vP%2CQL9$E6?Y$IKi+hiXnR75-H^nk>Hp0*S7qi{L+(U&&bM%B;_QbssVq4cpgy!}-s9_!KhVO9fjz!pVA*Ri9i7tHk!3YvE04_?Z*bp?Zxv z5>Tik0Y&lJAfVHDQB<#uKn!WxK*mZt8Hu&P2TZ9n+^d6GhWjO}E(kFNU93+5mB;!J zShVD7fC=shrYIb$+YE|y18~978G zml0QpF9Fqh38aI{G`uVWI7X*OH?=-wt>C(49MR8)6;*i7b$pu4cpC1PK}N58shRq! z5qLg>uV>7h2tr=}{MLwX(({6lxo0>C3E6g#JvAE44#t9+D(F%FrOUaokj|vRLI0t~ z;Dges)mNmV2(w`Hklsndd5U;W;wj+i%ahI1jpq%f##)|6o@aS#c>cokTb`fu{P!s6 z_xsCH`Y%=>w4`_HMzsXUJpj@FSBmV2;65^}zWKs&R1bpe2cA~fXOM|7@f^{c8riFu zj7%ALpr`Za2qstmhyVV%WzeX@aQ7RQ-y@X%nN!6&Z?9;mt=?e>0jJBm7LvMZ^mkhcmW z)Hh$YJ*X>QB#XrNV&Y(boBL-7rN#5iM>W4@KyBYY9VRJ#zs5W*b@G1bx5iHNTDISs zaJdp$-*gRg#&3CN8sV`S{?ORx>Nc|mPH6ClZff#}ysw1D{@Dn8QS7>7T85ep#d1g6 zWZlU$Ll5LP^BvyDr>g%4%jsd^^C9ou zlNWdjSA=eQ&=V^Ay%{ch&~KGBmElvwS{s`1kX^6|RP+9sRo0)n&Arwmwo%I?XrE-v zyt%}h|MP0o*&49f85Z$HRtvvR3so5Q49-6O22T)s)4}tk2-}Hx9=N{v3%p?T#pCuq zl-2AW`(PQyRZ>4{JwOK~npf4JanhiNqYW}?i{{;!xH_0Eb65v6RnVjU>*Y+6)LI^k z(|Ljis`|gktLkojZoSs>lE@Vq)v6xW4#QgCvXpmE(A#P?2tVN6Aivo`??$!d2zuX< zU*6x<3#8Z9-|)7m#!=t{0tV|Txu|9&Z_D**xH-$HYfHt8$Xn)pjN)5nYP0>HyaV7e#%_QkE8E1s zv2P2TRb2}PSU26xnI~}*-f=Bl!msx&!tWYuHx#=THm$WKu}AINP4Y&o?vNZC8H!q! zM7AEyl0;0M6SI;0PSg@7YLll&qZ3u{M7{0N1zij4;o9C)v1^H3PZRGZZ-a{IvA%fi z`x3)f-(L%(xU#rMTX4e9>Hh*Uz14cK)8O~W^sefKY9I}DEqoml2+~rX&oFb51*^Bj z`Ssr61nRP67S)qe1(v9Q$13~1HTKU;^5>Z0T$)?q3T*rj6n+A;39ug}b1CF~^rjv- zB5Q1m)DnJDrc+^~wIoz_cepeXD*Fe{U>3EXP-RvVGf7V=dp&doim?duOMLGiWvScb zB3axHspcwnmMc!{; zq^(_%*qbM-jaGosd0_PChV@p=RUS}3KSS|=JXzmH#^u8x}S!>t0o_%;n zTo-RjqH74MbJZ>p(_>gpd>2TL=dboSE)nffTw)S29DIIvtu3*F(QIeQ)Z(KFv&(PY)TCxuGc%0N zydn(60vWCbBRCi&F@nX(3V#TsC|U}J5KdS0)Ci7G1AF+%FfC^(4bDn6;YjbJ67nG) zDEm-OEYjq#aPITJmS}a2f>qFO1$vAM$MEd5P!G#Qlcn=R9Ga z+jwU4T+1_==O^CYNwava@0(G@e494~A10&&xb3d6x1l=6RIoVV>^=WAsBK zzY`D;A#*M~s=BVFH*kMi=WO5*E|ggiSX(iq@eSM?kZd+^bHI8;$4YGiWlQ1Fr@5*{ zWrXdT>{|Xv5IQm{85?E7o$8I+SM1S{M@X42HfS%!B@%z(v@j-f>S9wSVv2+vSyb>u z+@5a72FP|yL@VEZ$6iEfZ|`>OD|cPT(7V`1YrNWMi9p=hZE-p5zjGM78#APMtQh!^ z&DE?*mS|G-_OAeEy?;wwFPcFg^ji zBZb%UhDSxPn2{RsTCZsK&^M`$vzY3IKmDpW{*;3WZPU|_o?n`}3c3KjYXkJxgE^r!C9BoWgV5p^nYHPFS zvO_8f9$TC4D>NvAyMGzzRn~wkV@&#X{(I8f)^1`{m#?*ZGzZ5@)R^?ooCMg@ zRl@ZJ$F?QJ?}!#4RnjE)nDia0%;z1_Bz8>t=PK<#(KIO}QDf4-a1!Dl`cFdqmx%== z>zMS2D)8mncmcf2R&BSc&~+|b=`Ct<1s=tyM~k49ff3MPx z&9FXd=@uVj2ADxE>uivP)U#XDgFHbEa*i7096iV@69zd)4KfLFP^v+8;`Ja?AaRg$ z)F9{RL5`=XLC#TwoTCTX`H&jq95u)!#6P44*@@SK>=aOgoTCOgr`;f1W7kE;+3jWW zz2$M2)yqI#Y))DtRA5eYtklHg2q!x6)M<_u+7pZl?Xz}sehOCcHE52)t$!$kF%yt` zX@aKM2g6#X*mF5PBg83cNlG*--CE`ix{bQ6BF!*@)6)p?18vt7*c+UViDxX(P)Hc` z3}MhGy{8y-SsBFC%!K;;M)gjb&ohT-2G3PI6M4?%8OD=a-aBbOo;02vy#I@*h3B6< z>v%prhj*Sgc$#^Z@jS`%2+yy1?it-XDa3O#&vc%vc`o4@$K&VOjV0}eEZ-pr?4+MG zzftiQ9_xI}?0n?0daLt)&Is2VZv2q#ILgHz)X(EaOLtA(hBS|Ry*>*z-1V+SjUM-_ zqJ80BqspaF=qNXTWDlp!15J~n`8klTKPr+GkqB9D-OYxza!rfjUNLv$SpKX!%7(h( zI2z?T@`i?`*%?SwqlyhmBluGeV`z+{1Zwlr=rPCNS_4Y;qa~&r80FoMZ49}t#m-2O%c%3%9dkc-l7wWdxLbvgM!GV z_Ja#$%y7+G3zY-4ZTLz)$P*mF z=eK*UFTBA)`Fb`OR#RO|Hs&AeHfMURWd@({LZ^xIS}z+C85{$VLCYImFvy5EDAb0y zbc48V25|to6B{j)7aVZ`vPGT@o-fXaN8zz~-r!lwQ^nM|l4l~%7@ko)UY;VJlX$)! zW&NR4XAp?<2OuX@}=(~P=CIDkfvwbJiy#7)HhfsJRg&ZGI?Bd~$cJwHtnDTn)>Ta(n` zl%%AP;=>ZBiiN28&{?dr_m}*V59x%CQ8h>mL|(_}k}Z_%b8CsDAY0-0r%4C8 zala;dlGaN1u%3Q^(3mDoi?$}#yuH{cOoblebgA=34a;`FCKeP|dfX%X_}z6r+<4S2 zPm{LztXiNYpi*$6-%${#4z~wYpIaH~L@)_hRZI*_3c!*l4kkbZfEB0!kpdMUgKf(N zR9?=2RJ;1pE@>2PbJ``1qHWP3q-knszWsLP#i5n|wOS>k&?%$@<5agCG}{ws6(mAy zz}IS*M))q;_I2Ae(ES>irN(g3K5SKV;zsdGCP4yj4NipC8T+tZ(vFU8OK4Yd99o`z z(W-W|q05tkW zLE@w65npp+E78|pcZOBOL3QbO22{hQBu>MtzE-=sB&J;wtQdTuwo&rHax*QFM8u(0 z`L$ZLhop4(rs1qaXw8<@khZl5uj8?X&Qj}lsfxDh{fMKjMpkbJ3WG(LbAZK5L3+r-KjFS#oDfbo6 z8YOB`f|f|kAa2Ep(Ap=Q#cr*Y!v@EpwNJRP-6OOEffm~i&F>6qPa*!B{7yj}S_AeW zZVAvj;#UICnwJQz{IAun_7oz}uegZ4yVu^0nP_#>u=0u=hpVHC;o$^^%m1B< z0qRyFVAfj^)!|M>0dcN63b+oE95&q@B{`jMjNGsBL91SbQuRtG#lcl-t(<K$>{dPm&lVPWmG zIm6&U)*99dpt37@zchyqBVLd7G*Q}5)o~HFo%NW@OUYl#G=3P4Eu6@d0o((g3t z+iwv(Z5&3s;%U2TQ5Wz@*zxWmjCNbT-&Kp`(_OU65fbfTi`XTt1&Kf<@JMz^UF~)E zVv9Q9kl=a(9__YNe=oL3n$V$D2`ysZ9f#4b_T77XxCuvZJP7TBZP(1palE9mWY zYCbJdF7cg!9vBv1gS(W|I{?}zdA$_lXTt4mi+q~$`UEG(`ch!`7ybrB;H>&OX z^uF9He{!zJsmpT9d5hkjQ?3DPh+tE_H}A`#^RKSVdEDQj`*LDoI#*qqQ;wU(g~~v# z>)5}(BX(nM4)1bfPMpwuTi4`*e1mIpVgyaD$F1kBv+Hr(h|{Aam*Th(w3|2L^5pK& zE^fr-%YC9e`#f$5%8j@@=SE!q*T4RyE&9q$II-v(zvzsMW_1&8HFCso7dPPsT@$;i z^v>P;;3gbSAOL$3m*MicwyHrfV(DH3Maw2?7h}E^GO~7bWOu#>CpaJ%AYDgP6Ot=q z`aT?^SEWtb?yfyvHQt?GhRe6F#Y8RF#qzi-mhaf(eWjy4-U!!pcGDiOTz(UKywM@% z@|*O-&nNUqzomLomcdnA=@1Z>%Wr#f^G)@}G2E_hzU9fyw|x8e^)g0u1w@kGbaC_T z-K%2gly=Xza`R1$byj>E*Wai&?hg$w<@F1Wy|Z`HVLZKgGI+jR&^zg4p7(g(;JJng zb1BdHJR@cD@SM$a3Qr-=?yO@!w4sQcE5uAHt4>Gj^Vu(v;aelkwY(a!mpE77A< zeVj|GoZ-)#M&1H??s*b5Z`_U^jKc6_fn>V(YLJNgEU#rYw?= z6pQ48oE$N`P}u1Y4#SSb9(j}cYM3c_IjoTp>;zOh=%s*aJ-?}5S|wM?zb1&*#h_!~ z^4v~9(PoUJR*aPqV*!dXU@Z2FV?c=;%ffUqmW#zK)Wom3>x}vX^xmfW9ys%cbMo+N zd%PJw%r^sjO@y>oNN9Axvctz^m8N^fAZ-I#Y0D5$*f*>4Rgo;$xqbR zxB~pIDpjta<({V!-JHZK(f)Xw`IP-zUC6Z3FP}ys_w#0`I=_|_*Rv^%j~}Ckjlopx zb++B?y6x|*<*sLkCi}yuTz@%+HeCxJKPm62qm#%|k{oHQdoM+0v&d$K9?9P(eF@*A zOh<`{-ZtJT^Ry~c_kK5A&n;E<=)r=_vT$*7_43N>l;x4yU=K60B+!<5-FvNhR^#La zX5h0-S70#J76%{c`8TSG)S8hx$?=XjX&UIK_DmLEF=;Ky_A_+cV>PKn4<2$A*R%as z0%(u;zq~PpHdm{>c(iyni!#Ca`H%7Q_c>N0U&*f_EH|dB^Th_HCwy}ix0=cGcizC7 zd_9$_^PiA+b(4I4{^L@H+vD@|#m^Z<7xJU-yU!mW&GLlHl8;=`yqPueHLuI_RyFs+ zy{kTb^^n?pCM%|-mh?;>R{enLA$e+zuz^Ps&l01#6+;c{DDsN8`gOzQt@EbTVo4ad zMGM{2NukXYQs41bukEzZzW$OCzCt{#)H;2l`RjP-MzmiopvU}^eho?mU1s+b{ zRochn82%(?y^6^t)TlyzLp}4Y(mcMCW|ij4=d98KetKG^1Nh0dN(b`O$0{AfPp(xu zn4i8@=^6awS*6ANP~5{$fmJH49blEp)@z_uTF%cPt8@%MgRRo>{G4HxUc^taRa(K1 z$11&)AJZzG!jIo7y^5c5t8^MaW319je#Tp+v-r8lDxJ+w1@^bOTg`2AkDL2Q^RK_qfBeucClywU|;pY2tPyeR=tEF|SC*omeV|E$lYTT=6{*(i_ z`tDv%|J;pb?iW=*r1kWL4mh7r=*M94@0)&rXxuAjM5G_wbD zv0qYZuXRTuXICiJ`Ov8Du%@AGzex~`j`UC+SsU*Q6hJ!j)$^q}yR*)y?(P0u(FYjL zOzWyMozItOXL`mvb0$rS^+YBN1Z?+4CbiSfd>fO0*CW#>+8Lo@f?K*5xzQnE(pzg7 zw$ZMfBxmaHOvz3qao?cXu1BVCv@_xKhxXfPWb$@zWUip(zUj=aMXWGq~ zg6IJ4dX0I2lKZAJyB?VV@y>MLxibUfBjX@feBDe~XqtMq>rBE_-a{e)BJX;^-1W!| zlFoFP_Jh^(xty7DEUnxPYL?QzGqEP^gVkRx{r#JSp1~vO&cu<6jzGqW>B+<_wRrBv zI&%s+_YIoudSpDEjEor@nLB#y*2qjD+s>WY9Tba^?{CDHMb{a>GctPJT-!Z?pfNz@ z@i`NpEIX6tUr=o4&cqtJ`wM3bLAzQscRey=q%+c!_GE0lB4gm%Cz&}(U&+p_Ceyy@ z%&w`~MNVhnsXO$ig8tyc?I;?mr%fHF0nrVBHu!{JH>I2Et_}(3uULGcMvNWTVu@@w zCMu>Kl*PC*_diIiZ#qe zZ4Hz2wAAIO+>80iOod?l}M6v2+1R}4$x-$+bxa2uZ^Y(e@|IGa$Z3gr?Sq0Mu8^2;P3X(N>>OU_F2Js6QR zu_oy!c9gOKs2p=(ZMMK)2qmq|AE@NZk=65Fufh!KY9$9Qv!3@^FWGlgI){pUN)8oi z1l8nK>n{8Ehu(H z0>%EC2N!z_Av@I55kF1qgPL+0ZRh_uilQy!92E6#!?RHZ*y*>fp5nJQdEKA-LuK5r z$GybW;-+i37%e`Cz&Np6jGIYoLQ>-Sk#dWv&()M)Oed%j&=VRf2X5jG(-RzPEA$gL zw4k3jlv5ZcUbd96R9wbFU6jZexNiFc8DRE*HbR`5&7U)E zq3BXHMmB=m%H1SdHyQn3^re2$dO|c+%8(c>L~fEPAX!l(?*AfPnt3s{VjD_TcWzyvy0ap(5nnE9 zJ_j?LP{Z*4akZ`c}!4Z>?Lm$y#QuvOZpC%R3Hq)@`ur zK{IRpIy;Nan;t&Fj5`ig$6^}aL@|XG1}wIgsf9*OdK|!M2NRA1IPLw-2o8+;mq_pd z$9yn?({KRCoKW810?(Hl7f+l}&-rE3JbJ-2D&C6P@UBU~Sh5L7{LV{bFp`t;;d`oZ%zebj) z+Yg1|uD<1bMbVNMvmxJT9U3gz$Yi4w*6h~@H zWR=vm;m2hF!Rv=@jj&3hLShCQ@K*l;=hS~*c=GFY%TtzIehpCwaldNlU?**-@MkYOKmAx~yu6hBU=34xT7^)b~`1YC$v<&2yR> zV#B@NaDQL~wlGFpGtB_{dyLdmigW_oj>C0C()OC(Nv%9@@w~+I0#7Z^<2--j$)lME z^7Q0M;rY*E^zwLYo`3TEzb9_H(Lu%Ui@tTXQkoN^@p;C1&nQj_ZG@s#ewlzD8LqMx zQIZ=7`(UKNU7Vjv=zJWJybUc|&woisc3uf51dVRW@vxDuJP%90G!=43Sg(q{aD{&h za{DY40anlZ^yZr=i^34D*OF%(z*JE$Y9iFa9<`<-BJ`%#w0wk-1_6E z{|CnH(e-5Tq^_@ljwTt~-^R{YAtvc@U1uMDMJ-(7EuKQ1xc%*&k_y+eP~Q?Lo42+y z%Nshx2wjlo3oOZuGz21PuKDLtS~U0A0i)A`a=NU&d2#`&z_|EZ-M~fl(|%XsEJ?2} z&ZK+jrP%|o#@Sw5a@7&?V&i#lUTxJT3BU8ltr4X?EmP*gdYs~@-%hc?T?_ko`4@fA zeVRkP5SiXXPw$gbl^s*t+M=qWmQMSr${+J(th_l1H$#1z&7$6wJtDP%w(QwkD5{zQ%VC*4id#<}dU|zk_R~ivRSh#D zwLZZW(Lck}FnZeNB+SKD*JnR-bds+qrSc$D&pykZ{eSG834B%6wf{3P1OwcFpmB~G zH5P|xv<7jw*Cggd5(y%LGc77Ow4&Tp6cK2W%I)DQwpz8d)z-Gw*0$PO4QMq1Az&B; zR6wnQ;|>u82SiZw|Nizq_vR*~+FIN9-v2#5pK#CF(^-4%wbovH?X}l##i_%bc^e{f zfy0HQO2-S&$rp1t#fn}`6zmS>&r5UueIH#A^d>*(O{i`L$Q85Y(W$pi)+gwbd@msJ zWQVG{cBpHA_Dbnb-L1AikYyg7Dp-){Q%6G3uVjK5Nfk>D1>Fwj=XET|ON`fG*FzeM z?~_Y+aEPh&*D-F$hK#br0F^}An=0Dp!^{kj9Y3x?!GP7`#wVNcu{6T?w3vr~7yt*& zHfVg@P&KF*pF_c&f$mnGof$#31J9K>>EQs(gnalXnQV`2$l}h*qk9Za%WeW}Pa@4r zuk_!;){x!AOLZ@$WHfEa&2DOXRU*#o;Z!?4_RL->3w<_go+Y|t3Uj_J^fK~uXlMy` z`&S3bY@fzN<3G)14O$(oB>UBYk)oBI(kV_OD_ax02iiPP6WTmr1H|nf=t_%-1&ak}dD%B~5KTA~QFz`9ODbNXlM!5cmvL#!uX`eNft*+G*R+ zvDW%Kq9KI$o&-T`dTY<7wv4uHUiVsQn%>%LWg8Mcdq-sEYpOW&E&b1`jYX0A(3nOT z)(G1zM1ibWX*lpr?8k#3_TGFIC_LPzXRc3U`@~zh5%Eb@j!opTQ9RMKage9WM#)*9 zE|-X271@nt{;jubGlx^W{mQZlb;X3_ubKJk4E?Sk#Rk18&mMHMw-SqJ6Aq*YrR|%R z#y9ztz6nHrGap-@&KG)n8qY^@^)iFG>xL_D>TcJbQCW7K4F={nlM^CFg-u|mr#!pP zhS%aA5(_;l-TIue>}LS9>FGV2mh4+Q?US@ftbbYTtRB(bA|MRpMY3Nk^b(^G#8pzs7$#fxQ(Dd(B@+f0iOF`SFxOeMaV6rK_#B`TlCTO>G~+Ko@QH)rQr~)0yD3MMsk2+aC!D@%fw~bvu#8_-fvfEJmjS9 z0ld2b-d#t_O)YyiJ-u%vc2;g#?1H^3Y8T~I40}5?`=jkny+fnBBELYo9p^NzXE)@+ z$OVz}zU)-ld1Cs%w|@%;v_Oat{`Gq(ppW#(nU$_ph<(ye1Xq0$^%Kc-kNiY>xJP~> zJ>4TekzVeRpGa@_*!v$Cd5(TWO7qf^CBxR1bXJ2{#B4q@P}+O`<)pmCiH!%z(d`eL zy;ug8rHUBJe5=>I0HM~-`HA)g#XYiXwqfP19REI-yWg~c@@4)Dfqssj(su~^0|&vP zGp6RVI(B+jA^?>+80M^7jsK^Ba#1RZrIP2TT;7Zz11D3?Ov9#q+&d$ zM6#y!DlP0gwCybZKdP-d(%2;H_e%bjL>f0_G;Yk`|D#vVc(o{UH0J}KW-<133wyw&~g*+D8w4f7JAu2nJode*!7O+We?HIlFIQfie7#|kIFdE>DF_M<{*w2 zG#zA#!_vz(Q3g6?KtWK(W>H4gv|UinGgcK28rpVB<9xV7BR(G*h%}mv(xaOiU(JZj zSYKoZeaPa{qvtc`G~dYI;*7>;S~=))^kS$Ya`fWDzQ;SwziQa((CjG;zlNgnCv+__ z){8iBwewgnH+!)ao-&LNv&dE59M#1pDDKhl?MZrN-1*;B_~+(T_>&7N{MWwhF|dDF zHre%sH5#XG;)j9CWQ?>Ur%m~L1f{m>>+-cj!wGd6jX7NmM$gE!X5`ZlG{ssgrCjbR zv+g!$F4o~gZf?aInJ__O5lonlF$ikU$eAMb5n+XCASe*)Z&By-1=EmS=1< zjUDasqVtP+LCd@*n`W!uf$Z95XnW*yn=DQ8$VIbQwRzwMT5E_TU5ldRrL)?y5-2uJ zmgw#-pKYK32J`$3%EfE8>HKw$o%@4paQ#np_iUNp8eBiiU8JhQo{Y1neu>lek)mgH z*j^}IOvej&>5b(T6Ds;p7CLEye2~udL`( zd3@PDLs>Nc^$Tf_gfSB2g0F|V$w4U%ZJQ8a59J@pDk$Flq5OV#9|^^c*Y&hBUs|o5 zzoviV^|VE6gd?yQSnF!@iGSHttOM%-sms>XsvZ?DT`mRFs+nBjKUv0CNfFxuj+Wag|X9leTLrdXOy|! zT?%E|T@r0bER_2UDRw6XrgLsu{`dJPrTAHMl zqBTWOkKZ&an=5TaHhw#2Ftu0N`AS>vxpmtX>|eO6Y<0IS`!+I#7h(!8Od*$2PS&N+ zOKBi!FxGRW@eU9XdSrAD-ERxr>FT@fv6TVcb-Iy#iPU~Sqkg+>4jX)-z@N{~wLVD4 z8Ft(E$7(g|V2feVVgJL*ioo9*W)XF`w5XZeZW+Gbb_ap`Zu`A^nB74Ty?&CQ*MIcB zTkidKcjDSBz;kA0+FNi*&6<^2I;#Xg9=Gs;_~ck%Z_{%+)NDt}k;cQJiDhrbd0mGXBof5-ASgungy`-dl;|10<(!+^8j9#>(f za?h_QkZHB`n$pCP)WE*T6(?hy7fatn(Jh|l)FP|lcye0i)MRD6l&#BG%u~~4oe$Nm zgpRb0Vl%?hg(ej(F|}y41P_>$6YU!>KdCfcerc;EI11V_=*E#OdG!^t+V}}eol-x& zXo)xU)SQ~$=4!rAkb%;Zq#v#I*aPSjFDb{NX=2++V$Lc03hK7) z)@JLUmp@L+W^K|{Ux?bi!j#z(r{)k<0rlI@G4GtCDim~E6CI`htz(j&zP^%0g1ypB&9ma9>=0Rz}5dQiEJA{45 zywe`btZ$sYi@rRW_S)(^e?(ro~`FXB9mN_K2oOL+P>jml2^ zvy@$BI~b|_6Yj!4_o;(`H~<|W$v<9#e@al-EdPY+pP*w&s;3n*{QLywLUlh^ubHQ) z*z?SHLBD?*Y{g=+h>e&GwN@C6$Ue9Xz*O&A+=;286U~+1q@`F%f!bxD9pNPxHAkpy_3&zUfucpC5T zLoJZsOV>C-;QSZDP6i+mCORP~l|o|S-^6S*%YI#<;JWw};KHmB?|IJKqWpE<&`3^A zA3!_`5#H9DhxB5W)R>6r*&%kAG;-`4!B9<%SO%SpS6^;sj<;Pxq7nGSFUf%%k?uL8 z6ZCB}{^1U}`L;RYpz|XIY)3b=4N9v7JcL|LA3OinX>c?V8`jvJ+IIDCOwnC7E zSIp&4NXhprP^f9@M@WWFP1%=V{!b~dvWGK_uB??`ft%QXL@Bw4dHxxe3i(CCS7ezh zr~@iTc>WkNhVyp@J*vntqg=+<8H?o`Md>9uHG8C#3R5a<^hv7c1hb{cvQ}YkM0|yA zOaIFlJ5u2v$=FJbxq-bX9bKS9@JnT67mRbV?45{2d>GRCs?bp(oQ=xA^{~#v*KD3ML)C zUvn8F!1o2Me;40>b)^pV{83%b%Qro{=Sa#rEzbat?k<-=pF$FeDNHHdmyyRmn4 zQ0;csn?spxBe4PgeCmfUT!5Pei33U0pj0E}WVak^Zo8SzV9thk25Ax+YrQ8R(`r{w z*4NENAn`>NnXbxkd1-#Jy3R|Un|TqMD+rjSY5p#Rjwb3tC?!;P6K|D>Ww3P5*0CC+6>sOZ4Pz*fgM$KrVC*+?$ z5={ z#$mSq5EOlUiRuNdC4E1KpT@ZINQBBaBoUYjvjaXnfKCLDn+p@Y?D%ldUpuD`2wL$! zHn+@9_V?TBX4+A_LlfV&hp|NM)t1_!Qc=4n6=4Hsg3ujLaw;h@@fcBgHB=t`n$WWn zRf#5sFp%GSGljwvBzmRUdTs)NVftLC$pIv{n71(Y2Q@2$nq7$d@ttd)mmf|jCA8Gh zc>)_AjC>FV@>+ zNFv3`vux%8WHK09{WhY`s;!Vs8j)r0VQ`!@=j9}Fz1W3WsmSaDG^MeNokW2I%G-5H1mR z4lD0SgD*;s58kk05S?0KP9#&uD65%wQ#tux6D0qi)E39*at7|q$mqm5xTlW+nFz%8 zDt~>Y->S(XT@bUBG~2Se2} zRCf|@75*}heX|*)n7gK`ij!=6k~g#1)#}f)f-&j?|IXJ_me z`q;??UAo0wd8CTG()u)Y#KqEM`7QOgnHZ!X*;H&9?0yQA)whT0?$LwatVypJ+50%l zV<%>7@|f5D@QRz)Zba_Ht0z0vYoghAG)vM;C7BnSJr7d5&NitkQ-dn;)GFUHZP0bw z*Ug2RT&xKoiY6b}VV1EzorFcl^Pdx9K;s1Tm-@!JU?43tg5#?W3m$uLGf0wH_@3MY z5Fg8m_1j`<5NwHam2}6RxQd+59CiLzHdTHp3Ku=)*cn!*m%>1Au4Brw%Ha0Oc%2%U*>zh>SAD-xE+TDk8|+;|v6W>i63k`mDaL3!58Zj}Bal#hx! z{d$s_f>EY*2RKX>j)|#^q7nvnrrD4AQ6hE)Wli4Yon^Zw70LEQ;rAGO75)WNm? z`KM&n7UzWO<2Esz<@uho+$kqmK6q@bVHP*Du1t_vsP24QeubH5N72dI3eqb4{xW1u zGPg4=L1Y88~%sPz8>dGq8^xlfTn~Eze_cVP|INI%0hRt| z94on@mwjVye^aXLIB)3HS$U}*6d#!vgX z=~pd9Uz6%MEoCQaQ(+Q#EksS05V~N2J~ODQ{`KgeZM%Jl`+F7j+jiqsL4dF4h2>5? zKb4`f&5?!~e2mZvwXh@BsVs9NY7f4k458{(;gkx+o`N_PMSg<~f!c+5mkhp$OsF5` z$*V#RQs$>nHD&5fq)amBDT-F;lN7i}hEA>y)vW~^37iO` zD=q^q@xdo(rsb-d@qZi0shp>p-h>$)M8U;ETE6abIkvAUGe_1rhy& zer-6`eSap!YNzI=MTev!VFH_drG7~+?QUA@Fn3e{Ks6QIUeN@e{tNl@tNygJCmg3m zgX}5u>HDG2(f6Svb1Jmwldwp?mq!WN8O~yCKL-fOkF3C6yg}NwT9v4fjfVTOLgt;l z5|;DWekta~d743`c}$(GF^UeDhg7f$m$?L1#x3S-tJbVV=c@U0O6AW1s7scGujBk* z0O@fKQY+Wq)AjAO+uCb(Dca->y(}CK-Nv%_Iu=sx(XR(kt}xGC-3iJS<|&teMR0}r zv-bFcWzIo%T1DV&-IK)FROXW#ayqva>)O_ol(r_Mw6)G+WO$DGt!pa>KcPCs^QO&k z=QfY++Gc)Ao4cm8S?}5mo3mV-tbB%ho`05Sj)F-UhzW?xYRKZfXSE!bAO`JaZMeu60#ekd-|u2jg^eGtkf3rPtT1F z&vh>uQZ4Le6yXA7aFmG$8(Ej}`**)4&U+nH0MM3pF%9fyKGwcpEYtgF?Ou(w>oWw} zxeGM;?dkcu81Fzx+R|?`3lxxHvlG@OO8$MQnWN^yZ^;t85AE`P>GLW1f&K3g3mxLK zub5SQ`5UiWzU-df%U%5lH0p1}!Pe}d{<*bKKCN!0)lyA&&!J$RPRoHKMMyk&&HK&&Tc%D+%+9?U%s-P`fV#j4QFu)FfjiSj)wR|n;fVW#P>{1nh^ zZg=J77sE=q(vOVO(i42LX~+X;i-h$6E+d{E>;!lMZT`#DA4xbGv<5P zqblRqWMPv!p~Bw{V$3mDlUCn&?O|1{vV0DZmxtMtV_-02nZuavr131GA+4{sUu0p< ztj!ithf(P&al(v`44YfvNlMPrW>5|JcoK~WW0R=zIY5AUL#@5No61Bn6v zMtBmwu;+8;^|NgmS^$g@St(yQ(tcseNi{udv(wv-QV(l}04k6yGgD8q)%JJgNwGkE za`!6f$k3N?nKC7@(< zvfB|*f@jVxQ{QTIor<;+P+Y=HK;G5`S<$?C*HTGqlac(w*8Nr?5aXw`$4{GWCSiNr zx*#W|&?r~Pth9wbQ=#FuP+m%*(XP+}S7?U{9c&AQQwoi7g?{D=ZC9amTc}5Lza&g& zyF%BhkUw8#{st#(U67vA(7CS6XxGpuD%4;LWuz23-xVr!g+5iGABv}5)J%-xb8E9T z{d|SnBRh?}&WCE8Zu>1J4=7*vG7}Gz&TU=JqgDL^08SqS*efSU*<` z()P_HiVcNy%gnJzl0V01M^xfL|P=#CB67%NOEa|;RO zL7jVS9Sv?q71yI{HF-!CL}g9H)(s%foH5u|u?m0wg%;J6?_r5Srzx3omYd1g+w{8? z1EYvxtRseTRyuOp@+&tGb`b*~b<+P;+HZVZc z6EfByiY<=uG;Ok+H&(pjF^_eTY3oEtlxdAsx+HvovKoL)L%EQQNNkmq(XOF-i(V zQQ>c?;K-K$UMV~Ly{!pZEA8l6qN1?5NL*@3C3-AM3%Z7g{#A2b+Yg$BhBo=_vd85^1EOK^kJC$G`kb;$a;Y2$kJG`;i! zVPMDUH|=Rw2z$zTIo@x7hRyWnIk7P7E+~j=?-17>`ty`ZzZ(8u73E~gQw0_6uj;3D zH?X$TRAv*ti2s)DVIi%;cB*TSh+nhC^oEcVJa}BdgToL=q9PAV9KYH(KG8lJ%S}2# z=GESil~yy*{P+rr#7=cPy&nM?89Bww)jdg$ z77yV|=EwyIA@2fd?Aeen#-5qCkJDRyAnBmp^_~1b(Mv(@cK{m%)`PgD^njlOjPH`@5 zvzD#d`S(ypCwZ%7JPQtDE8c?LRQ)^?(M~k+?@S2f7w3H>^tqJ!qWnB|?jvKo_!ap} z8lF){`=I$)9b)u!LbsqwU@@(jxt%PC=~mHBg0gNDp~T7#A?(oZuj~iSl^Sr+=i~fYw4}#vbP9dfsaYqN6lqzdTcJ+T|Zu|YClatyOTu(pR)GmvP_p=)|+t2 z2=&p2h_3F!Chc#7aBkX7AN2RCj91-G`RO=)JV~K7kR;ZQswd5EIq$UBvB-Xh)@!Ft zXN&c9`*b@SoiFH%e$A6qzI({aUaY1$^A#HT2@Slc9a|b`HqV7z15y`ir~QNm?zK;M z)4-iPRr)o}G;m*J2(h7S9?g887Vf2m-)VJ23y+!~+7_lLq{2na9uUFlAL)UbwKpBf|V{=AI+?oVDWat-q}VkW zWVhA~Fr%?1B^FzQ$lh9Bn2s}q47u?U#h!n=cG|0$KZkxzUs!K-iZ;@;1#yc28+uJR zdgL6;Nnx?%yRsu7$rqEQ_hPFW)U4O@R?J0E=Cf_*VHf5B3o@=}TbX3q7h`@xI%wyq z#q8e4wNYo=7?EQ)U(6c2){5q-l1uq9S_{qemjg|UX`v^`j5Ex4t;s<8QnW0=8LOqT z-qcrpEyt9Kv2M&1q&xl0k(PzD!~TgUnzfHc+Rw;EO`++_OmR9+35kJtO#O}bt6m}n z<7a42cbRh~)rVb^7iG3uZr<#rw+jpO)?(K3CcR|~>nTlp<2WcT;+p8TwV^NPGr)r2 z!Ubk|8g*sQR)}3h;DrTkzy1=0_aCZa>D#I(Nq?M;u%DeCHpC}BS%K$D5n;mKx3^Aj zH#wMV99_%PrvGB+X`_{3eAFe*(`JI{&zhoDN``qGQb|zlek3q_;-g7sFX_?Xwm^6f zjJ;B4Aj5*1-R51wqgdueei@(7TIH)~Y5J%xG|l-ybFp3UjwqNX@hMe%4ML}iNDXzr zRsvo{Gx&9je{&&L2T1DMc%UgYt>z-p63zihTGC+(Xi4@U=8XPv9l z&TPY15!&C5MWeP6WoG%E#Dp)6_dw5mHqx{$)0}e-Q=4hqKiMNgWw;;Ytz0z79WOI4 zTiymO!bqB3CbXDZR;Hq|DJZxd9x4B6DW5ox^_+N4S}RA*s<;pkSv;-^afI{+TTd%} zBG+gr!h!_4IauRbt20-hPsp_uh3Qs+2j$%QZ9?K}6~*S;{XTES$9`Mv`TbJ%-xxNI zI_H69v%hPl!Ve=O?4j8($!Xdd@x+_$)j8gH)Q%f2*Ekmzt-?P-9pUtGao?jkKf_hg z-hsqMwkj^Vw=%<;+fl^B-mo>-uXHIs+YqSML$-P2U-2@LMhnc|BL_l>Djx4!gfI68 z)lx(4{wNoAShMVxG9-4)M?oh~$hHHcPGWuY{MJOTrVrExAofdVy{vTy7KUeu{|b!< z%RsRr*Ub44s=s+iGnm-V8^2cCv+kDYJH(s?)bvJzd6_vX=t8lipEZ`sDr(#P{4q|= zb>n;EE&(+~BsmMb_HkK3A(lny&vhElep{YRdADaXHiw$H6FioYN;pA%=UKA3loCXg zvIR%5)QxsO{V5$v$eOLaWc4N z`zAf)m|5;2Y^J*h&wR%{Xe;ZH7oI~b`#|x z%Vha5<*V2ZQ{9}3SbC@OG}q-lugiNl_1%s4?pgF2=~de#FSLTzFihim)F#VS)^&+I1R^pgBBIV#%!BpX#w%Q3ljh6K1Yh*yx)0dgms7MH7*R<5Vy{ z_~(?-5Pyr+h16bI=WM&q{8uB194ndPhYMpRh1&T)S*p$}bdHa(#OpUM_((YQBL|x> zAMxUk%^&Jq%cnkk64fh# zii6GHkVXl9DslXznHv`~%TH{}I)3U&|HM)u^9M$-6FaRwgRcebbYBlW!%nAs6tL4! z_YgLP?!hyMxCgP*M1Tp{NlOoEjx$*z=~$`=*Xg!AmXOW}2krnk z-z$s_FLWG#+DM@~R5uWlh3%SOjrP7OdWh{6gRrkK6znsuej)`!r?#%M9(UI2YCR%? zp>;(3Kj?q)Pr|=!riMv6g_ciYZGiVN59XmSt!?Ya%HlE5Bz)-r4?5P5l(QK9!p@?# zOlPehp*MX&-|hD_Rr7#P{hmTP|H18|l8B5UQ!;eM``aX35}8^iI>{^OC8}wKL#;{lnpo zvgM3PW7IM~3(MqKe9kZ=sUnd7i7!`VnbR@zrD{H!5E9TXUFt^)51iley43D4qHm0x zSk%})U&oB^ZcNFx^8xf+2(0EI)|if-nGd$dJvpKt_89ZQtE{=*d=Q-&%IO_x&`dyP zh|JJ{v{257oX`L-CzMm37a9=GZ@-f|u$25x6S!1{&gDDn z3yg1Sw(57*NASc-EkJ%}{X+69kSBJ~A8&_8hphLv(`UNAg+3S01=U`zxm44mbIS7~ z4TI@^Yzii>!MWsXg3LXQd^e)ICPx$jV`aOBbq|Lz)8K~nR(NCHcSzH)?#(a5x|F>5 zX*V;hE#`J4WMWu5n)&C3)QgQQPF1S|{)MI7 zN>33vg0mDj%anx9x7|K-yFH=_NXaZlsiz&M+WB>KV0 z!3@@YBqUfeUOkPH+{Dw+qpU(zF1-h<;EoUtV;OiTtujt<1ibN!OMSb3gb zk{>J2=jNiqS>=Ubr`W7HRfJhy449$1$qWw_!X$)+JITQz#NyycM9;=YVT!pjVVRNY zR;-+C>YVKARFhCm-LaNec^T_y{a=*C-P1szkEG~7JAy$tyFmT|qTH0QkHNh6mqv-jzX#U^% z@@F-JLQk-`>e3ne#q`jP+T9J$nwn506V@OxksKH&JI?M}TV%#6xZ6)!=$42%V^ae% z>hf*qEb@0MTe^)89`F~*@C72*qtRek^u{Jbuxx8Id!bUyUnSMtL$Whe!@Y`FAD?pp zUA}0U<)J|dt6gkz@y;bmivM1ZY*`nKq+`@CnR8G6z_i!+yM({_{GD*nz_jc5`yqdS z2gP?gffAsv<$EpXeoKg->Fn|a}c zfeNc}BCCS-!Iyu!f7(1L4KjZg@Qa8N`ZPsqfyyk4qJ15DrOXbX64wip3$Z2L*y~EbJuHv_HIsXFRz>S z6x%Hol`q=;jm~g`%CexnlT+J!X2;I(_3YA~-%WdPYJ6~STI9T4Hg}L6U%E?ssD6no z1+^ddu4%PnG`X9`bArYr4Z3$is_0?eH2*(>LBbq!9n&xg$}vZO5OBh^@<5eUj)fxv zGCDGXg*IAX|KCedp`!g0(T*lXF61z(nSmjpt*`Mg3%B(&{wdn$YqY0}weR;j8mS}i z+NWFve?-0)3ob1tUdtVPzB1;*sM~uL?Fj@lf&%k_EX|tyzlH2qqhdiddUK-D*1O4( z&(F|r7f1IsPgr}?T3bf}t>nAHp6AR`K+CM~|HfXGnv*|g<@iHN{cHMq{*}3!&~DBk z&6Kr*g(#|J={bI{za3U-DwOl!*`9yK{KCUUM zosyqcbND>DFKG254g!N^*bKpGyBK zJpMO({`S2<3+HS8Hiq<)gBsn**#RuO#kUxX>q8H7LSlBDa z8)kv3-)YKU7HL>cXUx^`q4V*Gj!D3>*!;}8aNJOaH8ou2FTRD|l`8S{YmzBWbT^Vv+umL?C^GXiN!};#A;F5@ zP}R0T?%E9G?ke`=V3J1;7C#uD%M*~hMG6JRDGd!l7-vZRat*f~8^)-`j#1_KW;aCH z_|~_bB*}Y)(gP5ZTM3d_mhTlAy1=w}}C%j1xK5`I}wN za&dBD;A{5xtl$6oxCHpO>(xR~X3l%t2_>uFn(Jk~_ZOQ=ZDu)RlOihizu#$)yHO)v zeX%n(^)}x_>?FiehenHk62YTTjw12u%giMkG-&K9tT3DHWU+#|<}XmP)qy+NS-(v0 z684tcG~WzaZzjp=>1={$dhvdLy?xg-Q!1Nxyx$U@S!`vQW8C{n_nu?&^{$1lj6c!A zn#^+ShCvi(?%;w@joHjMHD+IElIhfq1biQEbnrc+Z*{vPVb=SxOHjYtE(@}LuBH(g7eyM-Jz`8T-N!IT}Bo&OgJrCYV)ld$P&v>RzKR0 zl z3SptT55Z?`YkH{e@x;T8?jd>>(PN?tCA#;ooJ9B<8S&~u!ici0Jl;f+a~96x1?CO) zou0l6t$gdYT`{`m&XFn*dIczQMSBO*?3U)cFMkS zt8KTeqwHRt%6`L@4b@GMZ7|;Nr>^|29p&3d>44*?MET=f`O&WY26`F5{a9-GPOScw zyjb}h>}ob4Zx|ID9>mx!PAHc>NZGZVNh{v(Fu;k8&2@=FXKYHA%j_PURQX>`ugrPw zBQkF6bYBIcp9>@WSIi*k@T`h-NXB0Ktqk1z-F+3S4`$~Wzcp@mt~tVb5i1AccDGc7 zT^z1V>2_A~)f^Kq|C+sT;?mk}J)=1U6NzRw97EgC(6Mc2nhlsUgQ8qsQAqUONSDhi z>SSJb^HZOA`OwtMD?WantmNetC%IOSu-kRgwxHc&W-}Bc(=55hy!2bUuhU|NGl#h8 zY@AqdB6zG;4Am887A3SSiqe|6^k};dV(t#q)MVlAk^U8?2II$hV5^7QDg4gYEu9dA zr9e?s8Au$phn`ays{4iD9eQC_sLn2^hF+NC!Y7lK8>*`#*9?*p?}o+RaB(h)b`uOl zg?^J*g0z?)OUUDuI2IxM(S5RL-k|E^q&_e={+7jt!(Fxf;l_cxPB&bbW0+t%ZnGFi z-L^ZP$k9*FC$v^YX6j~(9(F9y;E10rT~>#&TCcFoc&5D1SD1TW(ie5j#e3}QB(Ay8 zQDkSNyOd;!?3OtqFS#kmeGJTHj$`R+O`8(8jB(~f29P@cZR@#@-? z#wG`U;IrIqF)zOgoH}lr%6$Yzv^U`;9Bcho{CCa6>MTy&;&eInRkIvApG5#G3Nd3? z5&dS-b?g31RFabpe1~97&NEl+sA!AMbxpHTsBSZ5XHMxMn?|VaHD2)7ReeruJf~)8 zm^N)_V#mgwW8)L7^};FP4^Yrd&<1VH-h&aUyV+J{o?C9NT5X3QI^FES!YIL!*$sc7 z2z>s-w(HCh2Z^TaU}rb{$)=Y_+PP)Ps3@!^W=S!u4diZRplG zk11De$dbTS8&!J?Nun%w)kZ6&802rYeM2+^G|NpJBgQY<{~Go#9Gk8YjdWbHF}Cw1 z8=h8GIyLwBN^7_{)LEiV6GW>mL>KeF70L*!Z{DkM{E^v`CQzK9I-RsggZ$pjqrtGI zL$0vGC}8L$uL6M|{)+Xhu0#>|KfWA{R|OlX_)B`LHU&b*ym#R zR#2CpxKAP1-KU^y6><{SD&%%^twKOg9s8G+LDRL@7C;S{dDn4Lw)$D%P4M^+K_}8$ z1D|Eg#~MMa;NIZuN+kAvPKl6)3r(bwIp&Ful4k}bbIjk=uq&Apw3%yewIxNN3Vd!U zEZ6)wDCuV0*tN)lF8h0W*N`T+O1t9z%e-6s1p3%fe*@THD+rgmF86!P#zX-5pOSK6 z1YM%zlU>H4DH#A?k!#K&-n5h5-P^`~Ykh?$};?HT!D-lJw?)UWF@MZNi=4@0p zhR1qg$WZTeDXuPhXH(Mp|AogH0{`Lrq#&w)0eovPGNi(PV3y(aPX0ADYmOt`W-Kkep_QLaqH=koWp*ro9;b@T%7brkPz? zdZRVmy};T-!WW)@?gCCku#RH|P)4va_Ow|5Xi6GqW=kElA|X_#gTHpIpdFiuDqhGM z7}M$ph?(F7SA6i5e1ZT8nsu*4ZHaIw5tAC57<@hiIym&E{SW1z4C;^z`zu@Li?{u> zQ+A%sj)cly)|B(;(^4P!uolyaQ;LAjvH8Fxbq$O0PFXu+@Lx*_x0r$Ifh=h^%go4LPM%Am}v!tM?%G^JemL_1@N z9N;0xl`YjwGpadcsfHG7HY38kZ7(nQEu`V-u>&#yz6a-%uE_vg^Q;Au+sp;CfV@DG zL~Y8&XSf3}T4MSIz(tD%*f%=^_D3cIs9+xp)DK!*1BD$xwO#_cG(l9myGAS)|Fwbq z2WuzwGgjgp(zW_aYJ8bZTAgz8;l(n4v)x5)wefj-Y4N5Vu^kHBdw}O(otKE)d(cBa zCT{N@irZV$mxJPe(knJ(PEH^62+wj%KEZ`)jbKiiZ)clOot#!Guv3{Qur#|szQ6gd z0{OBdvCLeHz+_}^x|dR*%^sV!r}_t9qb4cwJccNZz38i>gaXl?AC!35mWYn8VkeX2 z(@9PgR0FrU>{7CG$Ud%1_IF(NL1fF1H?K?f7@O@PvX`xM#;|IwEXO)_<(R0}=L&fI zAB_`}u;(5m702oVHvZ+2qCs3uyN`eQ9-{Tj$G^NE)FdZq&g1pDEA<_wIU(>5zC|jM zV8VH{kNNdN-gHRgr#wU&4rUy|^RraeD(5%iy4o-D4tD2_qd$ z`oK>5>ufD46su=j$N7V!byDhZA?22*)HFz$#Y3P<7P+XiUyU|tuYwQ8Bi(_*1;w1; z)Pyyb0Ev5jkVF9|>N$ZQ%e7h&e%iP;PP^R>k6n11h@D6)DS~%cws~$r0Q*uNk^`Fg z6E~o1L}Mrs*r307R6B%O7kPzYB5`d%32PD%DLJM6O9?B+N(QGidvb)K;uibCwNR(O zBkny@;kTMK&g^0@o4SmQu2+B%zV{;?*~c=2xlw&* zX0ObjVm?50X%)b%z$@svfO1xeFb6TwbCz=0%d$A4Rj~M%(0PA1>zA}=rSBr$BN2so z_H~JBhKWj4VJ#*-TkfQ(@v9?qWf?Qe+J#$LR`7s0SlFI0Unx+^1w16NeVb~*K9@qs zI>w0!P(o>7q=de`A$hs%^^J9>flpn7C z1Xmx-R|=!5JZnorh3?dZD}P+F{OrWX#(rM;-pTS0+#0lB@OkCetg!t_g=gF5&w=N@ zMERbxZwuNVlw1OI1OGM2@=Fu_eI1iYr;_f)^|w4({_P(I?LYi^<#$h(Pr_5zefh3i z-(gYT+U2(U_zM$ZyVAuM`U+rQZv`g*gwvhR?eOh5oMQ}UA$X7zy4xb+_ zvmKn97Vfo+`JP_T1ex~xeT(5RKbBi$yx#^$%iP3sLX34;n%V(UuTZTL@h}s1)E~JI zu;ox)r45iYYBkil&K>79g z<7V!VYXKevb0A(k2%>hw0E}-lX~>_Z^&G-kT{)iZ?iGm-u@`{`@qVL``|;D__|j}K zb1(JBJfXw144Db z=cKwR&>2^fSm>;^skf6V#^y4nu^OEb)|}R2&ST{devXt9(3^XvrCk!* zPrFAFGz@pqiy#p9sL-v1GBA6u+|=Gqs>(h^S@Lj@REV&u0@D*KI~h0qjttg2&1Kqi zU{4V&jV_=>mdOt(CPL!fm_d4vUqXbKr)X(PzZs=Hv(gon*rZ?ke$v^Rs8EWHBbS~$ z8;*=`?S`r$AWr66sRfB+mRc~&Y=Zq%a5oAPUx&aZH`N0b1Qxz}I*`wN_2jg)8Pj^V zKVADYrxXcKGi1Iu{+ZBz;k5TdSC;l$%>R}B%q5|Bd755n-%Ix{}{o71@ho-tLIO0Y^PtGHBzLyV1iVc}cm6!Ud!)R`U%)$e0VT|BGxaQw(HB*@h* zUY%h^GOwwXPcv<(I+vVjjt`RGB-yHFUc<6L5D{i;hS$Et`)Gp=v$wsX>D}I3k{HD) z6axa+*FYdU0z$fv>MkbHdq`83#9Ru$gchB}9MA)QB?j)XPR$Ra~*8OYfcCQK+5CEjWi87><%kkx_gETiwS{WJaNxtdo}$n0;|5u@*s+b0c7z#^#z zMs<7+^;9wWs)C%MHfJ<2DD`Emi}*{jC}LT{Nd*yw$i(K_&k^7JWV0)~CS0?AXsCX> z1Y7&U$jndEa&$!L5GcjEX3BS$-BpNZ^A2Zp8JoDP1aaAJ`Ym&i=^N&9Ski`g0&MEc z!HrX%jrX&75%jlFMh3g$D*q{MZF(XP8!9NzuX^abOKWW ziiEh-R@=+&pp-Bd%;|Nu;hI0RHd1;XghiDWF!Gt%5m4KGq%p@F!;5)c+fhgMw@*?4m&bgWy59k2h%|-fdvH7c2SM+p}r9$v- z4#CO*N{(rLZCg9jW9#eu{Ikl*|CRq=hXM86@(il(kRT;voN8|71r7<$TKqEK@NRa%_YwnB zyym+68KfY0G14|h3%p@%p&R8h5s9C5gOp3fk>yeW^ve%#!gv}#b&@HPLx}%wDT{%^ zNW%q^+3~?^$d!Du49@&f7J*i^w$e7V6Q|WGYFsz|Xns)W4f!qxLxnAzeU2=PZ@gOc;0MQuuIz-4dDRSN0gOl#5{B>Niw1b)TtaJ1H6lFjRL5bDj|T#1emYSkflDS4HWZ%Jy{b+yN3rD62m%6bw=T|C1 zJO;t&))U&AFCF@TLoP87oDs}+dyQ$ybRp8J%^Pi+)qd&DRY`xqMMLx30nBfje#7eQ zY!+dfgPG)>V!KA`R1s0^AvXtpi)>tmG>mDX_#aRplaq3OFq@x7k=DD(v4}7~4Q8sa z;2mpj(rXg(0{gWGEPqAXmzBmI$iIh{&GCS$epqy{sTj{vwJv`# zMNyGU1u@pROFHyrtxv2LfnH|5i%o@hja*pSJ|Oi6}D!<8lO|BUPzs0UKPCe5hKZBI7`%O<3c^w&p7w-?3-)I2XN;7AP9 z1z~qmBy<}miIFL099{~jY~fJ-vn*%G57m8Swfc66oQLTR@}~a#IL5@s+<^2ciRhX>^%%#GrtDJ@?{QMl-i)+#;@Pr*9oEchQKf~;iHU)g1vN3) zNLY(O2HU)dJX4QufqLPNN-sX!jxvF~&1@MzXK*t)0wH9+Xl3yQsfh=+LBmwq1wrwRYw25$cCB{L%wU%#THrMJ&HmC=G z?~2_*F|)vWOC`!Qs+pd_qVFo(%xc>;{7m)PjlqKMESu$Ss8;&5cH&_dmX!uZbryh$ zl?GNxB1YRK#)DQ`O!q?dyW8rHPFQNhd(;DATInzon*9d1N+zVWNV@)UraUB7Ww4lV zb8qWs&~2y1$DBsjsZPaPcWfv2M_v95T8AAhrpC%r3WUYhc}eJ+tw|Nhqf%g5f{yh8 zIkO~fgx!hI`Yb0P{3hbC&zhYtcSXQ{Q!q-prR2VLg=Hj@4Z`=_ui{YhE zqa~o<+In`exlodxIe;+qv+V>XP6!qWPi8;1uS280{ z($)6XeBR57tT^t+&?1hv)}@N$N#=0tD@hIRmTmp;Lx~8&MeyGGntg$Z-RrZwR`{D* zm-73+Ztd`Y9sd6x1Ki&ghKtN!{tQ2AQOJ#rif34j3cQN&;kEcjdE7d~bW&{>5mHof zPa;S>7Yt|-MX>lqocT{&U?^WE&v#MZ2b$kLBRR3wibKt#bL@d>1jh(unS@@gE#6}8 zK<{Ar0RS!{d_PlSH-k1y3VcIbIb+RHHbqN?=xLn-s-O5reSZWC9n^s_xh#;Zo!T7v zTYY^Q?e;dS?`I*kt69pAVwxwSoAWi<*E&L{|4s#%`Nnm`PrrjCEtei*?Wp;XJ}rn@ot-EZ`9HwGhkW(+(f z?KB3}9b<5a3J|_N*s`O$P$B?_NY_9Vu!d6%`&#Fp^!X9^{<)D!L~;Gs;xkV`bFkc0 zAr2~N{V^)7gJY-o%rI7#$eUGW7k{=qjrl&VC5F3bQ;{_DqSu+)pgZ#%)iB z#TcGg0f}%uEK=(($%>q}Kp%+SuMb4;HK$^2<AK?3mJaCHHTGu&zzuYu$bHq48C3Fmh{*5-Rc$m75C+>VW(&ZN@e}GwHJy7`w zO%5gp)z8|Jm%B>l2)F92``B6*7PTHo8J7k01)=&4L3%dn{~V!w$Z zB)QuWk2}oH+w^O#Bu3I@Ba4eAi)}3K;bTn{NlkEGMrQR~7WHZ7&h2&p#+gYE*oQ2W zeYbtcF&XY5*L?glo04ZXyN3ev77vjID}LjHw@#G-ti`+TRFTwehtx;~rjDgJ)ld6Gn~%xt$elsL3g$$#&r41x`q~ z>CIwe$FZV-vhlUUQp?R%i>Mwe83)zd;M&DO{S(QIS10Rx)Q>difF|D^L>Y~6&cj_A z)hrS=zZ4k~D9z{A)p?tD2?A^nmBhFK^5R3fmV3pu4$$({4;^e?SxV*j)Uj=&^}j-E z?_us0<>^9gr36O56#|78|8$r8n7G!422tm$$>bAP@QGv}4mNc(oe;?-mNB?ilaOsN z1}F6#WAvn7E~xg|2+K~aaRa;T2$OMUw4K%2_SyUso04PRau2!YW%rP0o^uZcW+@Lz z)_8G>L);oWX5gyRkO-LIi#`{U&fBt!qGemQ+#97xV(COHuz=aGE)*XhV!;KYHd^+1 zuG=+yCE4v$TYK0#d`xbdC>a3(B#7+4@h|#h9$hjQ3*q9ZYgyv?AIn3iB1ba2KpawN zX0e^6WBeRfo5rKRSRO-UNcvpZ`ZB9SJM8u~mH)bSU9B;HcAT$zTe^c4s5WL!MV<~> zF)Qv4?rU~;gIB0ot=P3K_wGLCFP2=VGV8dw)CBR3Of@5MR!WpNOQrMWQ|C zB5C*2jBH-9DN|iQS%+RNa@CRW7h<;iJ_YjczF>3%dHFGX=E`@Cr)~Qm^m=4a%dRnW z@-4x^iK*>Q3C!k_u^=0}z*JbK9G3Z#k+U5Qtl92e`4)s*}DR-NI)}q%J#Tx(iET>p(c?qtS*G~cY%v;?m-V(KVNrYKJPSY zxZZafMDjbiMe^P$ez)H_ytd+RcM8bOdsqFZbNuZt`UK^(QUTz-lYYW`XZS7`3Hlb#meQQ~*+1G-{U!sHi_uX%XvJ5+UJ&t6tA_Q(c1 z+bDkb{tm<2u5twM?C&6e8Kj8-^7(}TULwz3YTRVju>F%DfR1K9f4sZq60h2`(l$U! zAV1vt*L5{De)su&KGIMDEav;0^mQ!-Y7Pgm5^@A*C3*8^@?S!&ItnP=G!PKFi{QPh zZAn^)d0S?Kl<>eoxvrpg``$G^H}A!%{pk{poA~>k19M(>iNap#7&A)X@@C zzIdMYkXp=1eXL2mPN56jekSu|j@j|Jof49lNtF)Ud;{xQayE42l*W(Ah%|kcsVyOa zgWntedgf*JYc155s?9mJ*6*k#uQ`83yt>^U;#+!$QwE*C)CzMyLiVlHP(j$ zfWb%fd{>XqlLCIFt8$gA67l^0cHBS#n#$=}=1vBYN@srF;LSv>){3EmHG9PF&?F=B z-KQ?Z`(61h38NpI)7h1hfZKfztd4zbnc2ErDQ-{1ynVA?v{}(%L$cT4atCRo;bPiq z`&GBh{r^Fti$~S`Q!oI(%b^^F95HDQ)HZl6v7$P6Qr9)-61WKSRAqkFDDHx8m;-`L zy=wt;RE57T62Csby=v$;kP#kRN)=Ak57iChg=ECUQ9Ower9Ya17HqG@|qqi@V>{OYd77wzvhlWyH7kXqQQG6BK{ z+LTu&J~W}aEj(B@x6V#bQlnb6Dk7VL+OaeC?=}u!WJ(h=rV++fC||3iq}x4bQO~w$Ev4h4frz9%0K&*~T^! zWV@d8EnCd|ASm+`Www@ZfomQhadve$OO8?Fki}*y=7)qO?`M=kT;jNkwU6L4mHtS6 zhiBoFdkg7fT7VE2IF1Npgx8YZt1$e~j=vr_VPqBAr@x4}$4fka8!(8(Z zPE0iaVe5gZ`5HeyKPQ?0fw`Q|cP9DHeEYxUt^4~o-(tFT>%C(0&Yc|xH#@2J7Db%j zyL5cY{fwU9b8e^iSik!_zuWUsx*xh@V`hr`9A{!VTvq9ST(s5Hw}~vQ?tQ&=e7OQ< zee)Me#LsY^ex>Y0%M^I7+5%E7^K^Lk!TjGD{cr?cm?ujX(j3@JR$QY?oU%-o1o#q4y&Q}E+ z#`GYem#bJ%Gf=aE;yGvnxU#jcYJ#A#V)<(A`*|h{zSkB+8oyRGWar@$%_|aM=i7%( zHM^S73o51+L#VEt)V55||I|XU(Hi@P=b(Ao*={I)QZRdbVut@5Gs|z(<%?l(TeUA$ z6+n1}IU|wuu^4vz!_LzKmY0f^&^INym&=BOz$+<0ifK#(SCAT3yqtqOda=by-JfVi zGG;3Df~vH@YKzOwTm)61Ev_&R@FH1T8J}Dn-COe3o|YRmPBTE?KL#-B*p#LR&Tt6O zHTSv?j0}=3MJ+dtLGtk=BN)|nm7e#crtI0a+Y+M$kjBmBEJa$7`BU3YR(w~Zp7xUT z#<*XqBg05JTo)&qYYUcPc;(Cv=K2wfV^U7h^pVP3I@|;= z9c%%L9;gKMY<_xvW`)T}Y^5DP`IyuCRW;V{MsCW#k z>1I9=vDXH)_1AloeV6KLzs^_3yRVv4_+pU^GRgY?Tc(C?`o%;G{7xmm96tgJgC#3OL}1Qd|<|ZkgufT~=RUeRB7& zChm`nBw*0pYa9|;2M|2~!e4AAIWVHf25JdJ+V@ul3uFWd=rj?VhkeU@~-kMA*!Kyt{U(?DiKVjB+^-ZQ=hO zD@%(2!T+(d-tP?mu&(g$W#LEWTj*Ia6L?9A>Q7eE96*KzB;Z~TxR_A?0Z3ErV_R+x zfVvi$yUyK<6}tH>q>x(zaJ+JR-_VVFkl?PhS}_SFa`t!gZo%bP*IG%EMZbqFWLr2? zr!}<_#@mEwsP0EW!WlNz9KUbiCnPOQ-D5WT*o*VFX6w_exkb+}&pN$4r~RqLYyB6eX1aR=5q z_71c+oFsxEdEOMttMa}4A|`LWK*IS42VZHvX(pc}VZOz=6 zkpnDO)oxF(VR6x7ih&Q@DV|1)86sdUR!-3C-g>oIIb5Hg!RIY3z>t%K;XU(1W^BZ@ z%;=&3U8{9r$2DLbK;1+A=w3j#UJnCxO-#Q4)=<5IE0=ORoNdNIZQH`X_Qab9rsd5U zm=+HH`Z4x;PW*OF??YY+JO8(PwDd3ik09ojGvA&aFahy7w}5zL)7tageNx|FH2?!r zaG%s(KjhLP8zYb5C;*8&-6wUEc^-mrLt)v{jYoX&J+!AGJwCO)mLKfgp2!1DD37Tf z0=vn4ulx2U2JLNJY2mv{8o~E&<rB~?0c5;-A`v`$3?jFH@{{KOf6q_{{g#GWXLJxLOK3j9jY;D2In=?=rG@_hgAJA5SXv-#M%i)=XCk;5C794g|TuA>}g z&SrNeK@OHu&GzY*hN7)_Sp_|5F>CG;vYZ3pXb^|sz);=k!kRaibeh7u12dV{WjuqO z-U%@ac|^O~Z1lF8<1{t7?)^4aUat{n)&IkKkKu9!_pu)Eofky*bvQ+TF`> zsoO&8ZQfz+0D+y&IRLxZT5fORcxl?Ec5}KVR7;CJie79x%=QY`QQB1~z@W3(;8?;h zH&-rFvdHSWxBysgcChY9Zp9`2@9cPfVPCr|5cI#pKVs>Pw(E9WwwSx^XT?`FIRU0S zJR_W$VJj{;cAN&;Ee!@~Ia?Y%%&kpI*Ff#@|JZvU__(Vo??1_;G_-|DX$zqgh!U67 zsS*sUVW~2c&ZOT7GZ2x`F1Av)fUOj%*e+E-+D)S~ewmd=;SpC|cy@JVcin}@KTv_y zr2kStp@7%|E0n+emWotdZ3;r3_vhU2cV^NQ7Wd)N_4lK%S2OpX`|sRy?>+b2bI$i( ztAt_FXqAf}2%E96YW!?yW<~gke+M}`)NKi7fJC^&#Su@R=f>r2wgh-DMHicm56-@^ zvIHs|(MAcasCzHv-Ip^;H)@kG3l%OEkL-SjjnX~AM0Hi8G%`mc_Vlc(Q<6vTYw%1_CCt=`C@hLBV){Ro$ibR4BOj!NH)aAD=k z=}n{3x4CrP5A?R+0!0{b-4FDRvpMs8O5b9X4*4*XJ@}YBZxDEDgvSBaS>%lMU-pmf zpzdIvzvgjcgUdCkc3)fb4+o+$(SM z)VewRwNgxtqY$RPuXz!8|6sFWtW9I=EUZAH`}MxD)+j3WfK!g0v5$rs($E01TS@Fg0MtK$PBTX!Gk`qxVTgoxu!PIS^raN>kNv2ZwH-n465q9i9zrL^1v1mRR{fGLjcWM8A z^$u(4Ax|NLsLdbKRH^6PCGR=9Ix(oHsmKwlV*_`pt~g(RdJ%b7WayOoI3?%LZ_e}m z?}QZfLGJ9xlec}0dQ{)z4)uPjFLmDviCzhA=9pHgGktJss_7>>Hl&N?pr4wmnhr1l z$Mk44K>URBX4#cGJg@!qufh($05{O37t+!GPZX%!amTk+y#H-LIe^-?txga*4w_ya%5CzQDfKKbd2fTJ zso-X`Y`bK)O&6C>^-f;iwj!QdCwiqy$zyhz!}iI`I}qm$Xt%5H{*%@Bm}J@2a_76JHW1tsh24|L)QU76hl#pqWZbbCzp8@rLOcy83s|IdYz` zR~Pqb!!Dj{6B=GR=VEY4>~6KU?t1VsyMHCn&SgN~rOABn$o)*x6KMA%>;8@=t#)gi zhQCa;!hxM(Q>gGhXp3Yu&)=I`*W(Dgf=uehYBlUmz9v+8;;KE7!};qu0goR4H#(;E z5o;gVz=X8P81aYx)!=RVBXY#oJ_ZpY)|hIB9|3|H)UQNv;eN@UMlrfsMmW8t z{)teEJA-Vco{Qb&xG?x4HalAmtZmPSWIaihJAs*5F4_?m?X50)K`?(*Q7ouS%`|nI zhI$-DQtQs4KyavJAKn88`aB#zweEw04r|->PfG@gPs_JzAuuxBLk8{e50e`03jYPB z^BRNV?9uO$qzW}5wjMv47m8iaS_kKf6Ty&zOA*pSRsnyNtLRt;5slB&bi>AH-1Lue z$%Vd`7+5(jFt*O6b(+zwxB1jBCUp*Tl4f@xRWQpRmkYtfs4W`@y%^v2LB4}}jh?uq z1IwH995(IGrF14mBG%^{E8m+%;=B-5h?9)1>kC53#&|~W@=_k2kx2!YBL~5ww8rh( z4RMaX%i3yq3HB;rQ0NJ#3BjB7Qc^llkr?N2Or(l`yu^+#*7ZS_WGGS1GTy-(KPhvR z3i-$VWGr=mJ*cJWb#erukwtyZ~4-x-xbNNK$9aOu?_($08Io9s?g5uwDIC;)}__GpvaI17~pa^|J_(%q|JUh%g;mp?nd?#?Rpt1ty!~gpsW|e~V2~+xvUkWEeRJ>j&U0 zFVk!C-nJH+XaY`h6Y$(#n}9zob^ov6bDTKC$$nr=4h(hj;?BzqzwrA6G}vVwPP9HY zxg1{Kd-r|xSZ*Gf6nu`upjRBXn`mm?Q54boKZ{W=dG825q(nQvtrYXR1-S5*PhqL& z;Q;sJrlnJvf~JbulJSNeH2%u{KKMNzD`pdD2Xq%$G%u`)bFAwT$4e9fHrjKSFSQ z&_uNng0Du7-x==s#k^G^^#*N=E4}{`bxd|bmJVIL05sr(bAoHIo`kF39M1Q|2fao- z#Rs{aK7RdxagEo+Azc5Ly7oB3?OKfOx>CfY4^^edkq0X2`|n@TWu{KK`gvDQ0`#t6 z92-M8Tv@Ml^b0+1xIQAvB6#+!a%|z^;D@+Jq}FLi3$-CW)7ssr4*iHrAlYSf-5+(@BW-K zk?O!z@~#VxVowiG{Rfx2E=iZVQoCp5ipXc2^z#kDZ!VHLY~@+&E~OQQ4S)V@;pzmz`8(>!0o%QMtl-5cD>79YKPaZm7%#4zNJOk4KJx74t69qbja z=x`Dg3v^MH=8$Pwz7OhmKkifp?sbNu^}K0iI3rCG5l?^D8E*VOXC%&+ykA3tDM1~* zj8=tQI)d9#eel5V6%(rjLa|w?a+AT%${J2k>CaAgmHrQ_^pkEzED8SQe`+K~t>A`{ zX~|V@k$(O?l>0_lPI5=7CoFeiu+qxO-(XwdE!(e-)Vi;cTl|E=5^-8k$XP2@n7&Rj zy=pdFAEBvX&5DqQp+Lu-lR`i|@dgD%tc!W&>&ag9%MqPya+ps6RQMAVm`tD0L466R3%CuVjB!lKf5yWB0#L7!jrK zf6?bvne`phR~*L0&|C=ni3#4wz{rMVN88F@Fs%L0@RF#1Z~V4j9UBzaO*T@z8+iT- z-I&C^jUnu|)onyu<-V*F%8x6%A zsTq$2EGj*yay?hL*?Up&{1+>vsi+zIe}gaC6}N&*Y1-Q4?#Ccu+QPE@ zY6I{)5$;to@6WFtpWgX#N7P5mGR>B~%YR8no_SKR9Z%0Pr@5Z}H9foSGZ5SQ)-@-X zVtw0nHSpBB>-bA=n#e5WXX_p6#vZ0%yuXtqk>+ps-Th8JLR-lvCSP#*gKoE<58qzN ze^{9R8h))okQgAJbBwt?_zJ!dYynLq+wD4&w0=yxF+t79V|MpY$}MEE>mLVSuq?w` z5VNW56I7<0--sG;qm>HeWszF<4}j@P-cY+cI2dt;=4`$8ol>*%E$)N6>7Fk^lLuEM zxawgQF8#!iT%6N{s}tH0Q zd=5MTlOH%65n{{3`NcNvkY)e$&&xMUF4qCK|4tUiR?N~!j~O&%r9-BubMf@{ zod3kgw6iaPvpIddwxVx(ZY*_sPpRi3HL^S6A0XP5xF(7-$h0`<5P91 zdmSS6xZncnGp*C^WaWO_94F&b9=b$cFg;$3ORTqF!dKY#Fxb5#57NlLTO)Tb4;#6Q zfEc|afbL3D&vhZKBkWZzHiGRx3J#a9Zp}swH6qJ`4@vL_-8E57t6fc{tL$R=j#1-P2xayB?uyqqTB2;A}=VeZF6PZtbMyCDn zA~i)-Kd``t-QWI$O)1#qpZ{rNA0UDp#z>44lECBTWXULudwLdrd`3nLSR@+ za6!Ju8`{9?B8qo83lI8B=Ipz(c4S)nCqx_6ZT$nLnvZ*-3hwoZFgdgZ{-Eq$Z?XGB z)A1iPWY*%`mp|^L2+CLrs9DiGPo${^f^QueVyTmOv zrJs*LU8%;UZ>vggTr@WQ)~fU?Xsc4*T;0v--F%ooaCRvB_lG6050>Oy@9zsPULa)+ z1|+=oBZ7)?v&fi@P>sDJBdD=WE5`ZVO(TP`?pEbkaj4}u$a2&P+#$eBa6_`Oe!uOCQzO94LU%Gf8by zf6FHIY%o|DgT~^!LOamNpd9w$2GhPviQrT0$l-y%omy@Hrb^GGQfna+={`o4a*x&p z)79OB@?P%b_pCTQe(Sh7A3v-nTRNlef>d#Q{FZU=CYmbDt;;Q*i(q%e$h4Q(tkV9a z4XM7(bza|<&63pmu0(-7o}XmRidosko7s3e7I4d~+-1<-9!cRQJJtVy!nwtlHqF^w z|GqyW^eJl)@*`HSns>?ul;!);L-*fD|Oxc8`1u~Y*Vk*ejDv~MD0T)4~iw}0{D+i z`+^D!#Nec2X5>q{QM*p~<5AByqOafKb-(rT-z_SRinBGJ=!TZ(1?L%Sid>Ce(4y7Z za>IMwxW zaB*1YBc$C{P{pCi`Mp-_t|SYI`PY8G=@w@%SUJ99PVI_`yQj}SVddcjSMr?ohB_u{ zkvab>!ZtX_u0KOc1nRDB|s2K-1$BkK#DH8=1rw7;fRs7?Y-`;qf5c zR-D(7c(nH1j@<_*9wnYEp6i`FuYu)PJmTbeO)KlY;=IO_=XF@1?c{l$1(>&ZI7yj| zTBLe>{`<^A^m|t`%E8kgb~~a!?w?L8i=V4WLBpbt<24mHi`~{N3Zi>|C!~wtvbN=1 z!I8z4zWVF-!)fiRmK(^|a_XdH!DR{R(PAmz9+fZgIcD&8n342BY_q`1F7Wc;H0(WP z@Rktl1t$TPNC#iIJGe9%RwBsqUCYWV2UaAu4=Kqa41=G zIUVK8U+{g6ZS-{y5bt;KUIK3=c%^T(H1MVQx?v`E@IMh6oHYNz?vR}QJ807Lzt&^I z=00A^xq(jsc+HDbn zVgm-XRaIP@46_9*s77DrTCG0~&ac$ENVUF=T4}+;Z}~e_eXYWPR)b4$I?8!KTMaJ_ z+H*&jN9S7QaAWqRw^X2J-C-oXU=2_kGJT=6@qI3Hvm3JS5ez-0? zXht_b&x&T~9zGLZ*NA>M_z#KmcHaE{+-Qc@s3WUaovLqan3zNM;rVk9{CWXOm!bZz z)9dMr51Y>it3&-a68Y&@_x{~b|F;M|y6@4c@z4H%(8?uP0@`kmLs*#-OVcj=E`r+6 z|4yFj@&2!pg8{gSAAdu>bb50xahGn5uDlNr4jwo1cgAly>)`mGO}^yN_-D_fzz9wi zJTdktw~ZIhQaz~knAO2;d3Vi264>5_H&DRF z;T?My4(wgHaqq&Wy$fgTUD&*LVawiyt$P>F+PkoA@4}PzF6`L5aCY#0+yJ9FXI1fa zZSW4hKN&$peTfgq> zR==Jy~Rg?|@=%-K

    n5`( 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:ug%Nr1 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

    DPg6w5Imv8CRZ!Do$&aOBFQ~-_?I3#5TuG* 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

    )M~M@BqE&B=5|8nTR=p`o+>gX~{guUe$$dF0 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 z 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

    N{?yKMSp2fjbCqf=%l|qh?3|p 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%0AT-(i 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%0DlH$=a*mddYx$g(88fQ-U<@$xvrx;m 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%0D?ju= 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'Nd%^}O7 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 z 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 z®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%0D`>BnrDRF&9B^(2S8uxZKrQ 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 Ef2%MFA^-pY diff --git a/python/DLLs/libffi-8.dll b/python/DLLs/libffi-8.dll deleted file mode 100644 index 216de69e1d094816c7c2a3c688aa49e4f73ce9e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38232 zcmeFa2~?9;*FXA%BoM}+f})~CMT=53fCGpF5zr@?C<4v{AcLX^2#G_h771A6)3j=B ztF3L-TJ>#h>r}_K22cSe|_Km*8Si0#dSFIw5PN8 zJ||HFE||8+vSI{+^cq@V{XX?a#b*!yEZk zXFFV{c*2XZ^1G@^QfRR($Mli#zghLRQ)g zn!~=M_*jNXUn*veREC-1gNhV{)(8X} zhffry?qzMpG`OOo5CO1arXe_dq8P^5E6>`H-y`6V*{|N*P3X6(6rfU$)^UKt|;^wJw-bd6@uH>qfTvgo{K;J$>VfhK` zht=I-SuQ3pkJZNn%2j$*U{EYq8H0>0Hq2=9L{nCGn6)=Q5j7S)WQL&@mb-^pq_1l+ zJPnYd;#7g-S^eZdIjheO3=g}@>J<`H#OoCzeU`tzg-WmVX7vjLqm&WdwJpQWVm+n~ zSWAgfTG9!lWGZwE+@#WCf26s^B9@yfDX~b4Z(<3VnbLq_#2``59o?lR`}y<_>XIsH z@pYt?5n0~S;vbPxa}&Ik`tF$ueU?OBa!FczgsM5Abng!;?g(3A)XZcff@lFOS7};@ z$!G!V?TuK8k`u6&D%MiTx>vH6Ql;KiU2<0AqSU)7b!Dg(Dx`ZyOH>@A77EmQ0SYoB z<0YBWVet~Bu3UnNM^h`zq+1r^q)fY@;0IKpF;Es07!(8S%VN0WrZ#_AELi=($X^Qj zDGffC75iV{C{Y>2z0i^6oRpD9O<(C=)-6+4=b5P}snUqq2zh>IOF0V&MgEe1Da=TV zk7qIAc-lb<78<3%79biK^R=c0V|n2$&1o^fj1*9-b6`mjyDlr_e>z4EqN?0ev>bC2J&O9$WJHads&hHF@TPJ&Sp6@ zU?o6{BjQ=TJ6mGWxUhODtE)gQ8YL3mRYIXkFGRi(@2u{qBvYSAZ3yk_qPiI|D@wZh2zSIR=7DZQEstc46~D>+#+&d*Ta_!hr#y6&T)m2`0tN;GfY`k0 za46BO7N{-&{9cWs0r5u@$O6)G>sZa{!9E^8lnVT65dQ}5BbJxZi1~kOL|PwEksata zb{tP!=sQOec2~(=09sVsy@)K4bm=`nT}7;}G7Oq&wpbkb*BR^+<)$+}*EP6FUtdP} zS)<_IczuO0h*Egka)sqwq}|~EAj?V*HRh)x&o$;i zgDz}ZV^%>~AP+;E`%=28Wj8g)u-tK$Yh&uCASgRiB{)}Ctej zZps7oSP?!_rS59Ik}ER>5oZP0D!DVPVRE2M#g&`1gdpy?iaV<0&avESlLiMe%c(K? zNz-_0&tY;7lXIAy!{mkx?9}vDV(!Jx|a2P!I)OtYJkVsML z8FMcxk~S-9uhe^!wEioae2ytBWlCKsB(hNw6PYN=-%K1LDgXEIJvyTizA^kx75r8w zK%U{g zM9jM1iJC@60ZCTOSjGbJR=gOg$G^Y}FD!|E5>?y;0xq-w8+@fpHxmzm9lcq@pi8%i z9UIS6{$PxE)0O?9d*(4OlT9lFD<1YkdtyZZ7p!Pz3CLhT^AIZ7D>3)y3l2%ly^!D} z=9eg+CNT%_S%qF=_M;LGh$9Smn>`(~5*|0@s43-fBQ2T>a;0O!ds4YHfO!qm>k&Rh z7>O_zAsJyhLLS0A1gf{US%Y-r{>LcBDtJ+6=OLVJAYc8WDDcnCOl-`?KNG+|Pq}in zor#{QfGZW@O4*1jC2*w#u5R`w$m3WKz7iV-F`N`AQ*&h{moyM3PP{lX2{o;CCW)qn z&Lq%y=o*BYvHK(dJLElS;YxitE36=5R6vq|qFJsXCQ>QNKcwc4sfi2Eo9+eCBvw@a zz)v_u4i*IZv39VZB3UtYO1Z_iZdlWHPe57(5j%yQje$f^VD|Y#0c-o3I?zpn{U{g z6@mk4!#pFhTy;$3Xl$4t*y7v8x{IiPi?4nejralw0#zzH`k$JdK`;MC;Pvl?ZY1zX zv^BEU6-U-Oj~WNo%Ag+HKZCcOux#;vI-g(WDfyx)F!;aWeEtP`SmXJ8w#VNY(Y8Lj zzC>IvQzY4VLdJ56AeCX|3@8x_u8z(RIuAx^7Er#ux%qr@1l0V4RI1eP%0r}kA&{2DK&4^1r2Y*`{o92oWDOnz*odT%25Cum zR6#4lS(@Izfi-}e^&ikkY=yv`=8HU2(0T>Wn-vNPm9Pe-1f}_ARisf`91KfAsY{Xk zfm1*gTnX#Nx^glYsz^Cd>!B4ql@-J(xb_%c#FkzaSygPMutrf+3yB<4Qm&OqKR>R} zw>NvKxHxZh^H|i}nbO3lt*dE?7tf%skHur* z_;Aw5!i@FO9fL+9qwxu=viPP%F^sir0Lrv?RGjz*hU3j;vTmZt6q6|x`5$cXMb@xDMtZCe zqVl}yQYTuKwB#ikrTd_5X$(`>p3-P2Ji||xNZH5^sTf^ad<`h(Rb7y>RQDP7rsBY) zTr^-=t!=@H+flP!m3natB+UKT(knp2)F_qkqB^ohZ2uC{3hhIUaY?F2UM)@yO5$t&kqqvmj+{OOuUTBxL?6d(qcap zK_QqzMY;x7x^#?nCLby=%-_ojpOS)F!9Kai20vpBzT7nG@FN@i6yR1xmgc*%!VwZm zKuMkC&6Zr!-ekGUEH?tnIV~*`V>}}A$m)F0ID<&Q5?ty5P8L#?g;c%42A>9kl)_3= zf0-3WXZY&hV0FT4LFw+Vl33g~m3sMBQG`C-2i;1gf-+sLi?k$_?{l;+nU6>KvD_>< z8+lyQ1}O99!LJdcwVnl6D!k2VED%S)q#zKrwk0w$WMsrY1Ec{lwB*r2tU(b(a^Djf z88R~Rf57m)0I6WUtS0)DVN9hy3_$Hdt17uGE$)uP3Uh`lBi9`zIiU?y>fhi~G*txW zd1DIvI?>_MU8Q=@i%8eizpz-8ktS);S)iPam?DD_p;yby5G86_ABX}ifW<>-EiKwc zt@K%POo9a)HNI@5_*1@S6*k|IA>E^p1PTWV zr6qaPQ12Uuh5)Kkmn!+gPFH%LR&~G95%J^#fDJ8)4X#AfA$(Klag{i^Jlj%EKNOe} z-<*tOMT{GNfU$aUM^q`fQ>I~3lnakYOE&Q5jo1n0BxLGVA`fDxe%fH5`Unlc6M7A$ z^q#vZ0=?S^UGLGhZVHV7*$DQvGit#YH8&cj5RMNpsShXCq8rbo*+|sI6K(K(3d2HJ zrH(vfBH!vrfmAtOWP z|D2wxK`>T&s+ok*iJm@SXaS0Fb)=Pww4EL4DU9=c2Q3w7z!TImWX!X8YAPnqi%|cW znlx%qk`~RRMbprNC<((iQqm;8hUIHe3OYe8Q4&vQgZSDW)>@v5NJX|I#it!4P-isJ zb_R6_kf9jMhi{)zMvn3Uk`E1{HV8JiSS4 z*dG9>n#U>(g+zbQNJ>rKx>^ZW`Omb5(toKn7@M?)x@dz36Vv51=n8s}NAwLgHp=3-V7+36S#fGo|Q1OP%MARtCVC5XmC3gnN)?|^HZG|sR0UCFbb-AzaS zQ<=?mhl8KDWI$9hjGEtq)wgxrjd{PtcSwYTrDioCNOiy@7{}_$)D2oY9@~bgZdW4) z;ADcn2Q@;ppkDYEqM}O$E371e11eMs%TypZ zsQ%tcLjst;l*n-xZU@A^XlnL_~b0@Dn3c_PANPF+nD4cHZU3pujDsi!UmEs zm6=YEG$f=&-_e3`K9XF6F>{wTpb9Qm>KbGP9k3(5pm9eE+L5cIZX;H%HuP!Ba&Uap zRu!-XjNo;pewbvGUIYiC=Yz2r8ON)N>rjiNit~I*B_sjt+|I+fy5zam9j1Z4!+zA8 zarQ!4iu65h2E0ItN`!|-M*jO% z)(N17xSQVPXE;vnCe=k?c$@bE_KZOh)o7v_6!8w}6o+(PQ+i1u(SY5mGb~xrJiESm zc6;-zv3a(-dA7EBmIRl>L=33fA?w{dOPAmdwesd!ItCqTc?GCx3n|TO^O|Q1n`c)v z&#rHt-QGNFY@V%do~>=3t#6*Ct8j-kdpFO@nrGz>S(|H}$1$h@X7-?%1i(^SvX_S_ zF5<$B2Qe9RQ*nRPkO)As4>e+BOoccUDVS^w?9~p>M%(Sx?eI7Ahfjx_DAV2{+KUgX zVk0~+Q@#Ty{sXaIJcF39LVN_7@%ZRHC!yeV&mG9K234TU;+qo!)n63|$4p=#_;?G| z=smac4HOo(q*Uw5(w%Zina0K9D+z@l<5_P!I4>IxEdJ6NJR5db#hrmBt`*@X4ZbJR z%2kFwByFfv%sLbcjXc+?!K-vIs)H}{m(S|piz5s^UP@gR95y3iz$t>XZB>E^FmWON zd5sdlsHv6uM>^r5+zN^w;gRt+a%$Jps6EPmgj~C3FqHlpRFcUQK;xf|fv>l;|^C`0I zAgL*YTM?4PM(ExWG&Xl2kb)=xEaUav9Q=fG7#94J}c;a}S zTFo8*@6o9hx-0O+S(WNIn@8r)34e6(7)2J$2jQM=tcgvIGCTM`H4i8 zq+G|5A5#gZ51 z;e(nDaAbgg@$N;*9pOa>E=uhZ1uzYY<6?r~@@P=%Zv74?TuCM9QfW}{QwmQg4Wa;S zPg=B_Xf-lf21e44lOagz0*HRN5q>Iegq*xEaK}Ug7Q?|0RXk-kcf*jY0(@w7!;n{_ zN)v{ACZ0n{0YQz`1A`2CV4xqs1Eb={TRe4m>qi zVdu-5tA^!G{_&ct!cydocJFx2)zaJ2;4{J1x-u_A9Q@)YgGWn+t`^K#in)~V{_CT| z`Bxk&++skQ7~Uc{BO@DS@F?ZRiQpD*3tlYKj{_*79D6DC9eE3P5f-N8T99(=XyG;l zV0A1vR08ieo{Nx$TdRz$(DbDHb)y<5na#e1B?7%wR7Tq8bkfmn_AMHdeLKpJ#dSp* zM&kKzA{n<31OOadf%?`eeQO(l`S)Jg1aA|Dl9t@$mD$gXD3{e73 zILAt3tJ%nN8ZB0BRSGKXEDReCO2H{|*WpN4>Ol^QS|pv|{+B2#Vk9R1%16IYQqRKo zUjUJr2wvr^RCkKi^C>ox8;^C*#fuR>fu~%g*Go(00N=1oZsDFvWzZ_EPhEuf{38)e)y(NbRD-O?6~`7(9nk zdE`ayFs1J3K9)NQh-xITQl9*xyXB$^egfJX%<4x3DREovUZK(#0PV2u;Ljh<-`a)P zoSxD0IwEt(vqU8&#YW7zc{XJmC}g%aqf(wbwr)3`$?ihwos>?&DPaEC?Smg-8aD+ywQ ze;^l`k~bc^v$~To9wB^r%aN@9EJ@uOzUfduWkgKB25lkl=AK7_gRUxakQiYQg_3%~ z4-PN7Qi%CVn}LZ9K96@31SOCppk#H+@lZNG3^1vPY0(6waTpUyrymGfe%)!D>E|9W<>k3@%#&RbWhS>r9 z9ioDJWKOqx1EDQHB3B@Pfyi`~;+h$_0aS1&aR0}0&)LXFO6~{9z>{pvEond@nt^9nfTWrzNsTi;7*CeK zv6ThxxP>KE9JDb=8HwJdC{RkH%hX(akTUWVZll%G=+p4C3{i72mHZWk3+|?r(%7?D z1Rg93E#{5n$ACUEgO*jY1k=$8TJkLtc#C-e7aEqDtBNj(B5CnSa9j*mrg(B8rc0T^ zQmNpoOK*GVu6omjt4YCCTK!W<6lcFLf_-F&tRzpKQZIr#3;z5O3NF%aa2&w+&|u1Iu7Z9` z&eOgBX@x$LtPS{7`9;q`6Wln%wFj{S_XJI)hQ3@!mwM=>gpNZOad>KR*PN`hDme4N zva3j=!QtJ+vR4(3I*kHK4etCMv>KEspx49%pNR=RtAJ{wfNsOq+y%?F)ZGBf;?O>+ z)Xxa#m#x;%2*M@2{lb3+u<8#f3&dbGGF(aAjsGuGMS7`>q)VJT~qcPbR z(5s=}3|89oo4$0157ynlflfhkSz z5}@u(oifSMmqHE|(r^5D_XEAJ!jd2XAXj6$;IS1+0i)eV4UTRm1xlMq0m?N>0ei+O z1&ojaBe>PPJXfz(Zj(UPa`CeHYqp1yqqo@umPo1#dMZ!BMGh7c!71V19BX7>W7mkp!53EoyMG zqc`hqPCy%6?~y0LsBOgyAl{Q;)P&;+VGPO1c4P40yKR*LEV&ep*=2w=MHBrim%<-JTsD`&a9#!sr-hLWARovtG`b%9fy2Yb z=;TeQe*&b$a~1Ac$x#vjrxf~7vm4930y+DNUp{oU ziQu4QF#oF{;zSTHURmk$WxS7?*EVrF!QP^$G`u6);%n~6>)pJw&qkjTx=M<-zluMr zNq4Z{75kugGAzAVgmPr@{k;QWz=+Gx2pH1ZVH5>vhb)0nPG1+&_GKgBfu7eZ>@0NF zLbRn$htLUq+OopQ@Jjn|x`%9^d7e_s<0 zwJ1=ARWc^*4TAKr!*>AcNKbDX4)3EKEdR!L(ouNh$>NPCfFO1ngfaLxo)R`~j!4bb zsqjKw&DFB{G1v~?yFG1sB8>xSaR%Ojs)O%Y=^3|&gXy~&o_Nlx9i)3IS&XO83MsuU ziY%Q65&+ND)|-ByHx*nPJTl~;7n0uT)Cwft`1YFB2k>7S(ETdVevTKMxTzlJkGG?- zP*h5;Yg_1^d1_si+;BJ}7&GqSpfn`o>MR;srP2Oq7_-3|w7wQjrwN0vsOSOrNP|y% z(iiaVW?B$l?9!dRQvV8$j%hL)*F~-G5@U#as7@O$Lc7JeBW+i5(5}?MC)L8^j_-em zLy#O(2A_moi5I&7Ki-K#L&o3s`0J$c!r_Q7<2cb>1znkOPKdk^N%t}^w-E1vcM|Xa zba6KRj}#59$2n)Dn7DF5qD{C5q*MD-O7_y=hfI^3v0C{_~&l+d0yX zUwQ+thK0hvfyYU6@!vcN4HS|7Hpd?r!}pr-m=p>eYoN!Gx<5R%?$Ck46^3~5b%-i$ z0-$zjaefSUR`G3X5?s16mr(|vGgf&VEs5hijMBXdeEY@Zl&NbF%!N3HplFcHYo(Na za-;yXLtpxE!Od8exvi3OGy4#h3`%d^GtojEn@Z4>M`@hiqXKVZEk^oUkvg(`;U{YD zw2B-7WXC8h-z&(bQS(pok3e+ded@o59RV zFlKMeqI>GZ_m{?$a+P65g`V}t$om0mM!MRl5JrihfvQRkq9Z6_6gaK_EDo?<_*Sq~ z4~4^8rQYI)?XfI_xCG#rwh-KxdVAid5}Zq6#{1G1F#PnRWh!`s$suJY9)ACB3SAvP z-qWVN8^k{RsWw`|>IE>TaMNq+1FFZ3L=Tp?>!1T&A?2I%2*ix2fICWplqwLXSxlfe zl1YK!SXH1Ol28mRW4t*voPDu)MdeG-(LHU6H;KojudkyGTduCCDz}}JX-1`P@P@+Yjr$rp)bI`%7yo7Emuz;}zi5ZH z2|;QOu3FqX0WUFu;rOcxjKbffKo);-Wu(F-P>`uJ?_ zah#7gd0b&cA(A|f5eTIkcj+F)klHF?r78^5R86YWVjf}_+owq$Vm*L_PoN5VpF|yY ziQfAAse)mD4XwfLw|`e6emrz6Xq~B8a+Rr98$KXcqT;BKO11SW4t;T6LrXYpr?C?! z9LA6IOznqr)|)LY_0D`!YO!bqSaVtDv)kF|a1ksLM5AJ(W|Zl)D{{}k>ZVR8!ULxJbmwgFyoSis z&VzUAb~jD2HkYBk%v!&T>L21%uMpoEZ2kIgRH$Y7ano5BhKVY+Xor~mBp3EWf?UaMptA7_t}_xAUvEBJdB9b~5MRkA zv6ikPD&u7&zNost4Pa*RZNPDe-Mj23T0GeuMBlGJ=-?m7(Je+e-lcQ^%2)%X@eLT{ zzd!?Q-WGdGoU zo}QsJuu3Ge7ebZutPimjqT^uz*JL5|>3H=zDse0UFbZ0e#rHQHT`ae&0fUBFpdOLA zkOCN5e1E1I>@|Ybr3Z#%1^lHNYH@{1V37lTRG3GZAiNC#+Hl|hCAwKEbQY(DI|zBn zQ+d0ZuN=d2cQCOG&=^naI~cn0m!4~bk-{CKhSg>GVHUL?{MG!TVqu5IdRu(gA%|O& z5K1qzrVVPDHJ?ZMSQ)xOs@BTbFr>p`z1gr*c0bu9bS=boK_;weDqMNu5xMvWSVu%D zEN&f;{f@H0JZ?R3E)h|A<1xi+paDkfZ1H^w6E#U>7M}@_AE>2Zaw#GxXf(^%WuKm#^;Ul^36#DXe)$xO9 z@Kr|7O5!Fu_o`54T6K^AGPl@N$~SG==YCthZaWfI{+I3%<8Wb0s`yti(wOpP;sWGN z`4EF9J(}4d;A2{7&A0+yB*V?Omjiqd4OZO*E0Prs3P)FlyQrP6dn%YW({u$$049U* zjetO`vNH`#XC$^xtL{Ph7JOdQ3s4Trl;(>2f`H&xuso2yCca0qLN9)Xh_VzTD@3=W z;*-b-cr;)Mv@x8)_`}lyj>pn{>WTQZgb4AYFQ8b=XVW}`z68k`d~YC+cjZeW=yy`I z$@|p`bq!8aP!M81Z;72>7@#Eq==w9EA8!8c& z;=54!P;SbC%)j7P76%kjijVGsL>UiCYn#GBzoCR#eo-STKCAUGInkke-1Hp%>>DN;Gl*RQgK}Nhr_`E%nI{>; z8ny*SJ;xT8+#v;pyJ(ZtBcV@XN)dPbWcU3Th%p@o=V9Fjb-iL=HJ#r4YkFkyy-Fx8 zEcc-a%~-=b7f^|_0n*Uod!A}A&Oo~qG}Q97e4{2w2xd2!sDfl6O+g769W)>DLzh%i zC8T9Mt1qExXd!%|V&58?l|L&=meD$o(xJ;)d*Con!4V&ilRXM?5*-f~-_I~6Gyytg zFdnov)(~4ST@8rD1hO<~1Wk(BqAb4MkOcX80Q3?AD>Qw_pX2KSs{t%_$zg&SEbvC1 zNX8mEJjWr2uM0m!M2{-z=PWc3fhTBCe0iS5uRPRQIhFX+iU*$K(f72qZ{?r*uJ|{7 zz3EKnf8N16%otWB-5A5+w*3;>;7jUrG#S~7CHJ#(GL$jgajrhBN@0i=#JX2YH!7Cg z8=jG))r$gS-Ou3g5phoebO{U^5A7sY=h+G;i=}J*5Q`Kq)Slzcnki(MK}Kf*qX`<6 z;_Sp|It|LBsGWHG)8C<5$>s&J`vo|H3CgVWlhOj87*4#h4-`%K{qS;lDUxOvlr2JH zA4EN_sM+U{^$WYvvaygDj+7UXeHqdN*IWzSV%^P;d}ZmC<)lTkF~vEITR> z#9l}csq4iaNGTqd%QWG-N?C>Y5iZVwXjD8vY9Crv$8@<66L~=k0}CSs)())Idg?sC zM{Sh8!!bmJ;2_e8=_f*9&?H-bg9O4a%orgyq6Ll*5`~Q)OV`M**8-=X+>;>31Av*B&?G}%*@+Qz9J5)SoU+hH93TmOL9 z?d9qyk~vfA(jhIZKek{kmYEVzvVyO~D`5UU745B!cRjT?hDHe|fdCJFiN^^EDuX9` zpT0^Fo5zir0e?-3=^?(ONh8U@Qy7Ww5mvP%9Kbh9SC?|7C;%&D0fGs{@i*MRuiN>~mTRhMf+viR3)fq3J^g0DYYJce~cKHE&HjF)*SXJ~(;! zkBD(~C~f*_FcAYbaroGKOBiy%H+`DQAq7RnzBzv?G3q z!S@l4X$u+9@QoEV)#4}3imiCsZi}g%<0tCRfOYKrUr0*|t@HkQ2wAGNTyBg1T>lqD z|E0lyZ$V-DKVN5%ZGGXkILa2Ywm9Av(`xL$p-0X*Ind^vfiU{-t zP6C8mcvgM~q2E{x2#Y}uMQ}T7{aHGr62cWES&ceWF|Efj%qqnE2L-jm7>56CyujHx zR7T&$AqCQ27ATiD_OX`DXP6X*|E;}VS@hd>fqkhT@Xdr%Ke;?Db2=WpBTuy4D>?z@ zOSFR8q%<#sMvmXvYgVS@+vPPcspfdcI#1A z3mn>i?+^6Bte`gh@BanP&CS-#MiGx=!nLjZl~-O#pN8!*QTW5}FJF@us8sOtu+7RQ z^7F(ymL*x+jc-H`tjYg&Qz!~ihpHw*2*Ux=pv_9GAp z7|}GyWr~Xs`$`yJjR)hK?#}o^x$(_!Q7eEx=^W~m(y6O6(^Vs3+>%@vaUW+U#Tzt^ zPz)G!Vj#~^$Doe+OC9#-&{p6hVSLgN(AEcSeL}tS+IDyE+Wxvb(?;XQv`TknqUQEjt1@%;oRImVQm(r&lad_P8S0+bX^I;&<+_L& z511taW?mXs9{%x=KN$$yY-?$r$N7go4B9g2XUB_U8v(7ej|bzn$~li;`$pS70SgB5 zt0lsWEGs-6^McWC%xK_RneM_Uuow3vSH?ZmrB=|g_cB|ctl026b=Xk+aZp>HLJ($lhwnwO>+Sw>d z5ym^otz&vJ_3$HoJ^*L`OzT=5^Ma!i<|trVs&U3%LA#;ODQ$atb`8*YG40bmnKsye zt1ey%ZuOE{=W3DBj{6|c(BElCbV(n9my_5l(JNjMC}08sM;@Ln5u>gJ&r`18DHrgR zGvgcDqIN0dHK>VU;}~Wy0?Bv!v>U-NT@mbg8*Rk5;BkfZCphO(UtpF=M!UrbJ#BrH zkbW0om@WS?(w{lhQ~q;@de?T&Ogq54U4H9YpS)HnG%l_83ffet7-k~Ip_pF-IMK>K zF5pejC+Je(DqvivpAE|VTzMn;3;A}`?xZmq0aHHBvU#wjD1`S&Rl&0*GJ4qTVhTE5b_zIOnctgD@X~en(c0kb+R13fYa|hct_@4{18P{(-gZMEDM&8sQ2;140X& z;$0B>B8)_sgpiG}2w@e%W&|U`WrPO^9=Qx7L+FVx0AVD;RD{_GixJ*L_z2-kgl`c} zBK(YS7vXmVf|L^@1RaSXxm|E3x}>p`X;yMtszV}qdakuFJGVfapOK8Z+_YvTnfVzR ze8Kb#O>%)IUz?^$&dtm$$j}t<#WPdqrY7fU@>BEkQx_y_a+C8@=QULz(=;L9lu8P+ zUa^kZSb~1`G5F4T`5Af1X<3=gGRbpO^BoGTOa4nivV8~q7}Il;)BfDBan}D>(|jy` zGk+e;p|Gj-KLJNGNHhZiW&XT>&4Rp)`r;d?v!`vJ~uZj9TZDClKt~CX*(&<tLni^Qn04L2rdURDl}e^WdrXGUsHdUi&7?EJKhJZe5HE1QUv z*(6TP(EQ8lP$#TBTAQDrk)w&v&rQpKqI_7Kl#xF>D<@TxVJ~8~3Y7)6Om6!f@p}$0%o~TnUkf-O3j93OH^eQXjlx#tjB6&GNx&# zPtVA=uX03e!pK-vSST-#VRg*Tn4OjfcuJV$f-8rYo4Sy&$MFq`S$ zlupiIhA_zm88ebIc_by%5#h%qr{(5kW=*H#AO})CcV2R8{`9%HII#A#ZqiOLHCBC3fOR_YYlUrN{qR{T z|KHF5e;`0Q`FMmG@G+zyw)-0>{;37Syn%9xZzF6)n&L+Yhmj^-eltQI(xlUuBapwQ z8u2&K=f6jq^m>U8p4q^LCjEY*E$!$(Aiu(^(D`L(L-98VeUK(QU@B|?6UHH1K-LC# zU?`{fF#?r4`Ul8wa0p=;+ECnpunuXmK}-mfktSPYBy16~>B%Pf(w5$icr@$~YC|^3 zRs>oz*(T3yY5I>hMv*@NHoK#pPdkMK}b`)3LzZn^@xYSF1mv;9eoqz zyEulh8|4(65l$dYHdLFJ;bK7A(KkRogKUI6nhS9?LNU@5Uk+uM)kxPO&gqA_kao2H z$uDpzf?+CAPVuh@KOyaC&y$@$Boe+>*!mRHLq0ju@rZ9Kuy&;D5icDISfMZ3eH93V z_gcjJW8exw8zbUJu?({iY58!5>CFPBNRLPSCBk;3$rpPPVcQI>A91kK>i3C4{3gOa zv{{e%I|L)rq?6Ax-ft1X|k~#Jgcy zijk&xE5c7m|L^DjG6K^Cp+G8oZ^oggy#c6#}_ed1=cM=Ffq;gMZ*OaBK zAVVl}5{Mc3WM{WvXEaVU|>U4;T>y=bFTAtMj@Q(uuxG2+`V+-JSv zX`UcFbl2N^igwql?Tsz7LcV_M_rXt|CAU~#9PTT#ZXl}Ak0^sMNNe2q+* zlNQnzt3#rRB~J=_C)JDq$gx7iPoz$UC<2 z3=NU@35}5RpNVZe!}=i`9vap+qHn}Rc~>uMmZNh;^!PdxgwC z)$l&DX#DSJvc#$OqRZ$BzVa8?eZ+*s1G5NL1IP%)gQ6(?4 zo5mLRJ@>TNy3ZKjGyVT)=e)XXVdd@ip*N3}J>2q%&`a~_R}p(YPicA0bZ-BXkSjlZ zaounIh0-p=hws`T&H3c>*=wA2?f1@{-t+9YG3{1)FL`Twr0e;L4?-uFS!Sjramv!S z?_SwGxi;6_?dcmo?0g#Tee?FIm5;uwd7k@rYM;s9yd4{)>(?VQD0zFqDXv>r=bgIm zCqMRWtGYX_c52vtlj)AzmhHmel{@<_`0mLUl8)NV87B^2W8)vpTiNc9OYs|rRi=(# z^Jt+{>w&tUFCv!S`F^iwVs*ptn_9Wyj{NPpKAR_vn4(El4{5n_?&U+{kLP=LSJeM- zWOlc?Gg>HGjeq~AZoz_wdi8`$^G`2{8yqz}xoSy#L5X*lP7_j=rze%3=+w>>-gaT8 z|H=8`vGTQ}ENP=u2S4+aBq|n;A2fW|vpsj-2z7Njkv-63Yzrr_pWu@s!324cV2r#a z$gM*wfxse?$ej^^K;#{$%uCc-jV5nE@7}p-1$oU_QLbog<+QY~tyNkoacV)chQ00VW8)s; z)8T!3!TTVOrqu!`Js)-)Cv4eVqL4u)jA*w%nfvk%=Hn zs^v#3Vm==6;-gO%cKf0KHv^`yv)}n)i1Oh}2U{idjAwsn_s98{hP+sDX719T{kNw~e&D(F*INCCZzHaRkNh#` zV80Ka-{_P$vHV!w%zGOLUy9xrRyiu%XVuzAKc7mPeQ}DDPe4@ILgCeSc9wP079<=W zcHwXz|BauHFr3Vt+yCW~A?;3etMmJAh0FHn*WOtsE6S@saqPDj-TO`s(1(wC(tkPU zy5YEcT}V4iueOsT=3M!1-4-|JbKR!zU3GJ0^5s{yDNpy>q*?XFrGcB)Ee*IP2z8&ZP(WfugZwYYL z+`4}*Va1EDO4v?M$3^a5C%n5f_Tlc-oI^9Nc1u}$yYj1l{IR;jt+e(7mX4i2QeNaT zPhKQWww+ln0Y2?Hxo6i0KISeS)n|ToBpG*{S^tCQ1sz?X@{o}JjYn5#Uu65*kFJHy zk1jgyaTrQkIgiTEn4X&x(o*hC1um^zhi0VC1t+4ci@Xz+xwUE+zd$o1H%FG3o2i+X znx7#X2FER)X25-HZzTM8jsD|lw$;Ddr{-Db4|ad~@sBfKY^w258(j}?$=+vLHH|s) znj|f{_n=j}$bFU-;~L}@YN%qmDg&ZQ1_%5pLqn)v1LU z!`FMetbC{Iy`!yL<{#>NKl7WG_m*W`ST&&CC#k30K5Pi+)T>3Wa|zo*hW%KhH3xpP zQ!(+UCHKFbK1o{h+w^5?`iS;z?k619$MX2j>FK&3KmK*zkyZX)lB=VH8}5z%a`U>$ z`Y+%A&3k7LU17V(vMTp3w`T7>lw7IXUiUb4*|YiDR{8P|0xLV;7+(1$_u1X27cc12 zOhut<2W9-@W?aOQhBV(@S1g65t&79&zV;cOdhh+>yF1YpH6Q6Kd!Ns58>&ek>$c## zB`ejdu}=NQ`H=!TU^%mkvl(JRugggk2iiE74zdJSv&FyQ90=J@%+?mv17fbyIh2{CRoO zljO?!*7Hv0eZ4~X{?|Qsd_1%Lp*iQgr&QL>|8~Tffl*%`^WHH_`f=9yU)O#%Dq&&J zgP?%bt6r`Bcu88DX9=~>KRB^#$D?yAFFm~we*CxMd#A1>zFcr$;9JDX+MilNHtqv@ZXT}?;Z-WQ3lba>C}Mwg2jdv|tg-OaVFzqI+uF*6X zn3gRQ^_TaRhczBm-Q_RYk5nf?>-M&7{8@! zzUO|rd-#Y4<|^ZZnWC^!3mz<8)@yUOx5}^m8gPB>+XefEKA-rqc-Eu7C9l1wpMG4n z`ei0BV-|Z*(PFOlw;^LXX{OAX_+wOj-PX5vcD^6Zr7K~F2UfBK~2jNfPH7a3a5thoH$!7-oA8(BN&jkj8MdOPA? zs&M7rtzXKnU-nPB_s%6NI3r%YAaoEV!MZ-_ze%$HV*-_gjFHCytT(2*tjQk`Z zy>5U0t*)V3mtC_y`=ZtC50iZszcfnpUE7W^Ke;8fcYEXE=$%(q$$sn9vyaznOT;Jg zUW9&@^qtqNL6=q>-WK*Immhd}f9ZvXs?lSAesFx>*Vis}Xqf8#N!aa=cg#|bKEJkZ z?^k=SRch`HaN7~nb>jIWvnzI4?(JzQzW&|#yyf}hOI&ZgyxHvJ*?oE}d$GLB&qHE| zAK9GpW8Jk526ISJyEo-U?Uut>l`r}qJXxK*|Jf<;U@5O(vQgf)(N=X8hIlyG$s*{O zO?I?MZJId`or*ZkGgaoHax*ywr|0Oxy<5{ zZ}a5+9J+gi1j)Ot4=n7A|D!nz?`DSKpOTR=nM^K|k2s!Lz-X8m$mKY46l_URkrU(g z=z~=sub-EzTYG=ep0B?QsXzbO-W%THrw8YRulan{LcMp%n&OGWtIW?1 z1*lJiDpksx*H@>@4tf3K-O#uDcK)^PhOkRDYXt9oe$3EgkL<&dTCdzzCv*CKy!Xl7 zsn37;>5m>WHhYbmdRaN_rf*=_xZ!_vpZ~0Wv5&Ilj)T9qNRY(WkMCEubE3z_!6k<; z9lg3mb!_zv-MD)PGwRz9&M21^R6f}*`hNVGdB#>ZGcIjiz11=zVeR&B^2AlAhBMz> znJ!#f{YTvL{Lg0&ne$nipIcJFu$d{{o{k%IeUV`Gv!ImP^7SLsJx}XD{qV7|W4Eq% zAGAL5^{0XZfeXU!^gl4R;r}h-K$$t_g-4R*`?dw-UrGCZ%ua(8+Gp= zR}S3Smi2q)lT)+fSAL%P@h78tISYLJl2$v z1Ah7C&a*EyUwl)s=USH*zgAAY(6yV_N6sCiLN}!AU$;p5eOd5&1T$1Ta7tCr$(1D~ z($zh}zY6lr?)3E9&p!oh+5Mw-!ZXdz+KaEB9CB~viculsTTi-M>Yg)vcThm&wS{M* zygdD*v!l06>ObS>Gw;n%?Pz@@ zNbTZ#>VfA<)pt+t1df~@TYqB6vK0em+56{=yxOuMZbMO5dPIkG|$=H=A&`-hL>oDC{vye2DN&UmcGb#5&RS9(E84UelL1G z;Z4Djs8`2_j`kb#=1!Nxo44!2&q@8?;U?@k%%C&jTE zDvt;a3+WTuHzZ=>`l41Y@E;lBKiX>3#XZzn`6E_88`vXmPq0@Ih?Ka@(Kkm;uXejl3 z|I!ANPl+b1UAJx3{$o0J>^J+HRbxC-AAaaMZ;{#ROG8GF=tAU*M5kJh*1 z*@MfnJeD23_g!u8MUgv>B^si19d8}aR|a)d6?QBcd#mK`{nT$h8{o3&@#i@=GJn20 z`BCq?hVRwy6wkO;czou9GiSY54(o0n-0lAEH%_YdXI38kEI!=x#v7}rw4He9(W_B8 zxvjUpzwVvkOG_3E_L!RaMmx8_@78^GcHN#QqjKgS4jS@_zck*t{{hLxzMH@9_~ZQX z9U@E(s+HdFE>>Upx$KKi7dP~5A8;plnBOODA4fcSR61%-FTJqE#t{eC9C|kD`m6nZ zbB?(_#?tThjfEk%9+V{dmlt$;(7UXc?EI2#HTPV;zw+(HDI;=1R(I!a zDmG=THjck>qgVG8oA;)sKf5T)_8XmYVDl2GYuChkha&4fck!C(5;3i9)wz<_T3s|O zI6dviohz^IKQXYK;Y_4jrh-ghf;YVw$~ zi`sUdARPH@%I(+!|Ki2xPhI_fz&yKmh=X_N^}p!D&2_ETq5QyO0jFzBpT5(z~Gh-1mEH-!ZqC2N%?|<(I2de}5~)=k9y% zCkORd?ej~*I{8HEA0SGUkCu;GuU3#ntr5z7NlT5#Yb?&KgDiW3R&J*Db$%=)J|v97v9PtKEQv-M0_9Dt-I*oAACg z>Fmz-uPvVH`o-L&<(k>Y&Wfi8&ox`t?CkbVc-v($J~!MZY@Btg^Wd0HXNUM3Ke)S) z-Fab^$I4LyGgp5##VOJJ(bbQx*90sTq_1Pj>LzNmo`bF|Sa!%?@LpBhE`{g&O-z2b z^^P=;qr;*iPfh9j{e;2M@B4jOUUj_u`3J3%XMSB#`#@Yi;g^@D1z%QFCGNNM@t*#; zTj-is|Cl^<^^(;^A8vEwj*jq+t68%mHYKdEw#(%P;ikv2!*870CmcH5r06$i-WM-6 zn%>il?Db>E4sT4X?D+li7{)iS%l|}2S+KCq)nDh0>SJq}fG=22_#5I*4A2J;Dn;iY9x`*lNv|s0oE`59E z`6Rckd5i1cE1rK%BAhb(<+QC`!`~B}9Wvm@8#f-`{NSg>FQ2fqQK^}Y7tRU1_Hn=7 ztj!;zfBB`hsgLIg-oP35CC;#S?f#^G{r3hYExa&%+l!#g9#bd%iDdrA?m$B2VWDA7 zM_7MkL+wY{|HwJ|pU$_VOZz%2ca;vxSB@T2(N%c({>uLUcyIKEb7ysDK2mL*y?*-% z-P4JWTWpB&9h$sp*@GF+7Cl&}cYp1}fRChM0r9QeyA`}UyJ6f`r$sNKcNhQI;$Fdy zUB3nw7BBDY_lx<*L5JJC_Icaj!9#zV{^sq`gX+(X{r*-^Pjk(VueG-VoHGooyVqR2 zll9BR6|WCtUcD5f(Eqe>=D1ht`!D!-%C_UC;`H4K_va3OlB#R_bMo#a_f9i%`gb}Q zwJmw)<+w$s9!0dA{{K{Wrr}WbdmN{sY{^cxX2voYG-I8VWza%25+Q4mnj|u2NVYsO zQBu}H_T5a1YP8TGveY2^lqIs{STmLwaYoB?be_)jJmd@B8=ee|_)I_w&22 zdxkg9_55&tofK7TyF=%wL}9g?uR%eTPuVQt!$BxV1f1%Vn@Uv+i+%sjXf+;M&@Qn0BYbIDw;ajW>Aq+DCy4tK~VC zh4=&jLC!MI+&;Lz&mYuVtnn?=m*&Jx5*-gV2+X1>||iT(IxGHs5o|J8nQ{GZ#8KM(j#3YPf_{WY~2=Y zk-Z2-#$eW9_pTn0;oyBSRX%gU7TB?7iWsBb!g1)ZBEvgsd$A&V6y=pDYPD$}_gcXWZ79DR9#zeD%<(d=F`Um|OKE6WT>qJzP zascrv)yR3ug_w}Y-L(tt2bBROko8U_4LG25nq|(__~5s z=s_h+O*{2Wq1;#|R8Y zewxp{+WPA1a~EkZ1w%P&$r)5UUiKL($K;8h`|VFYcg7EIu`JLIjyp!$E5-aFLp*g) zK;OEYYcfPxSKp)Hllu!K6-72k1%V7&%LQery;A-)8MO(Qr?{Ne_u!HK0f_NCgMBhzq!ilgmp^_YI5VI~#)%vZ#79)ymDi05A2 zu}Vl>w6=oo3SFt1!Gz7P*M_)B4!z&ohc_MC`16?wyVEt|@zp zO+JTFi+{ss%%?gKM&A}b>buwT;*biD#5Az85h&%VsM0*?bfh8fGw5Wh#svFIr%8M9 ziiyS+DoMk@xir9i+OOeIp}UPuhL!D29%wnL07g4L-E`UU!`()d(}?C6{MFkyr{0?} zp>N5z2?n<=z3{Imm)1TyCx!s*J4X*zJ@6m5FH2XeVK*Bx6x2gZI^cb&e$!Nz+Y^+YYZZFI5ez{0;it$cpa8>-nwv(O{ z>a@Cn!)z?CgCrAP#4Lfz%J|Elh0Jx{@K#2;6qmY+87GM2P6aQ9-e-Jt%U6FBxoxnr zeAFmc>~X#y>)?)f9*|U-m7-ka`4L{rqX&JT%ah1REYo2+N9#9Mv?KWi>__-4Cg62V zJ|bYwfj~2?zUw5&xfXcT!>g1SaUE6Dwcj}nxSAzhR~3_88q6i1yfBR3O^{MqpcR!# zjY#~+EFETMX?+F%Z+$mA48Vl1O|10GJlY&s`zNyR&Bwk9gR309UQhr^qkA^|oAhAn z`b$4JhRHvkFps}TKSn>EV$zTHU!kAxhtb4%!_9wXFJIXHZ(OGbW7_#lrk#(__%Z1} za@`-toQLs$15hp)bEjb|8dQYaIbxU1qmn?a=}up2szN$*9Z+Upyz{0bUn)Y^4GT?$M#m zlJSXO?B6($#9o+ZV9HsGGHi;S6o#I}!@~eLSQx-(qZjx4TUxFye81}2erm+uz{G#A z5Sfkm_Md7(W+nb(vx}1*zT>O7{#UgJgKoNc3lCfpCJtjRsjvyr@nG`^^{`mYqWFr+ zn8fil$w15>`g4s`dJafyr@98wtzN!=Jl8S*%n;o&Spz#}dTtK4%Lt~udHU{+0v*PT z7&c)2{NQsng-9TANM7f;c00wFL_QA_o zFyB>sGAJ=xABX0aO7l2%!V4iZhKe$Kt|Z;wJ>)=gfmFq%SlMMXSGXQLrb}JZ;_m$ zXt1Nky`UV?HpncOM0@OOt`bf5>{dCt+jLMKiQyk@vGucFe{o5phALlDBi>L=Lhu$1 zxys|0syA zXALO#ih3fz#~vUR6ehR3d;(H9(If@Q;smcxs;`%?I{A;EHPKQ%O28)PaY590;diV< m59Wt7Kj{jdUjN6Mjn;*U9UQp33lFn}Plji*WU7_1u>2DcFl?>> diff --git a/python/DLLs/libssl-1_1.dll b/python/DLLs/libssl-1_1.dll deleted file mode 100644 index 5c74668fc00a628e86f01f8eddf1e99bed00788f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 702816 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

    o%Z{J>I#lIiiv-orwn+Vm_4kx&N~I&h;*{+ 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 z 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�J`oLhsHtmS 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 a$oZ9Kvu$a57JH}oQ|MDJ8XBaap#BGqFA)d; diff --git a/python/DLLs/pyexpat.pyd b/python/DLLs/pyexpat.pyd deleted file mode 100644 index 83393a1667013c33efa61f8d567b6d7063816550..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198016 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 diff --git a/python/DLLs/select.pyd b/python/DLLs/select.pyd deleted file mode 100644 index de0f24a6aaa21fb7e0f88301091e98b99bd736cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29056 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 diff --git a/python/DLLs/unicodedata.pyd b/python/DLLs/unicodedata.pyd deleted file mode 100644 index 0becb4245551805f265433f05936e4c11fff36c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1139576 zcmeFZdthAEb?-lVfiX5?gGJ0MQGy|)L{uaB1%^gPnj@WK%|pyXvIN1T1{x9q`GG`e zLc_R{g3T~_U3zbuCT)MT_mIgDv<1oXL&8sN12!~?A-9PXk;IT&gOiZ?eZK3Q zkp)Q~zu&*VYdCAI{oZ@+wbx#I?LA8Ne=$-Mi9~Ao%H>F8D_H+p4gLq9DiS&CJx`t$ z`PLbG-@COcvG={XkKTG$!zb^&<9F`-$R`>$eB}1q?-*$K?VB6!9K5~Z*4rE6>1@L% z?zrjZD;6%Czbve}>2IeF4jlO0#>)45kJN9xlkl3a-(R@f@KE7*4gY@OUc)1WPl0!n zF8r4d2l)mL+`sV>i!T-i4Sz1gzq>IA4_i2M>xPf2t;)!{-ALr7&z%MS#umid}5;@IMPvJ;mu`zS-Yl|b*ksHYx6sn+K4F@r! z=P!<|qpqbFERH;=I&WMY`Li>?-HRhlYUHZLk$XM>{^a7wtE%#8HI z*3mFWcO-HT{r$K8T`_R;Jp&}3{#yWbxs^{sG3Q?cy}IJgn?5q|kw|3XFqx<`@;o>` zClh2V|6dVgi+Hdj(gaulW{h+HwMHVNS9~(aXk%ook$L2}^jGq=UUBDLcWQ!+C-5dR zpTHHrF5k_!-9bk2NW5YaB9Ya2qH$ue}!^EThRtjQ~`d1uazvpK&Cl_<8) z^NKHc#eGxfsoA0xx_;SeZ)khN4dZ(%|ExdW=7D8Pd+Ah@KXlKch+jPJ6@TUxk4A^z zP}x%bO6Jci?l0GW&51-tMx(>NI#a5DUnPDdh#yfW64ch}jl49_>J{s+Z&gWpz2=#L zrgHsr1V=^(FLky`UcBP-UUB!7bYP;WLdENsc^*_Zy=+=PUhHUiq;>G7c=14MbJ-dD zVYS;b=?uMc`Xdd|;Rr1`PkAa@b0Sf^VNr7ArO#gJ4E?NX;J1L)gZcL8;|o%Ld2H$k zYazPDs~Vn+jvPc0Mz^%qMYo)MWHdT5P%f8~Yj)qe%PXJe6?aY#5^j%fS#Z|OPQOh5 zb_Tt%ep#2=iwizK^Js;8d-k+uot%?*dcBRWE@enwvF?5EUL5gSwtJh0mmQ~fQ;(ue zyv=bqUp(T8cbhJaM2cQRy!f&+_G+~=^uJC&F~)$7)3Xy}ty?uD=jkS3JQ{y9QS_&*`5%|f6E0md_@2eg)3=sIEXN5=S%WfOzw9!bJo*n(%3IDe@(ai;xpy?tI@As5$-3*rqO!E z2W?)wmOWGVokMuzc1@hK-ubX|{dMDQ(Wmd-f0`P;{7tc=)v0-Ns9cT?KTM{UA9=-} z2IKw{dKrv+m?0u+wd>pIslVpi_g+djVe#3>0UfsvTkoeI{$;t`8QoI5X8I_U;u=)h z!1|z~I2F0b?5CXKijG{P4i=yFN((=6;o`{DR`#i(H_L-pxFaW` zBlR{Yda5PVkSOMsHBEmS{vgJ*^gB=;2=s5w{MEF0OwHu2M{eDB=qR7a>f&U?vHPK%3qQ#NTOa4&7%g_?ryS?(Lg!wYBymP9F zeiYxNC(+^0(2Nh`OLsy{UkZr6r=Xckl;X>}lUH6ink?0_-j=-2rsJPIue{se9P!KJ z)Azp>@B+tTFV{#TFp^|(r(ZnyL@hOy>uO{AEtK;=7of;_*G@@!>yGrayo2tF2T>mk6 z$Rauie)cXc+*1`9xHh_FUg2bUFzFW`JaOZ)(_rb>C?mN+IWZ22WUDra_2US^h1StZ zucPq;w0eGY%hG8dj(Wv*Z|3!u6ElBTd~N1`p5mzSQ%q^legae5=CzPn``p}Z?Tz=s zk2bOO90nY+^%Wv#*?QYM*?JmsUSaF`&|>S9s(B|{OAD4pA3qPiesSs)Uw5hQ|14j> z-f`UcdSc)<`1(gzimxf->-FXOvtb#0&3MI*rL2&b>PSV2jeLR@f?2$)fhqgmeVW9! z=#~eYTA!XD(fsWu^pCO8p+ymI><6`8sqVhtsE&9wZ$`ItR$W~l{2iv{$H&TbOv`CB z8BPm)2&RPz@@D7eL;u#?)G;^A-6g+{E5-Aszt0*dPR;y*P2YYtW^ZQt)Z{_6X7fGT z%q9?2HnaS@W;e4xvzSjWVlv~V0gA7MrpQmcq4NCb7rwF;W2IhbJg8l_}$Y;1~M|3^c|PEW9VeUm8if6z9} zGa7929b?54T3JpsKH=5u_BJQbhNWx1`2BJ@vH33owLemhe*XVPY+Bfu*tbSFgqhv7 z1p@7TtykW*IsT8`-sYUxyo)Rw$ek$uAW@P%Qr@2|zU34zd@5O5{**WLR!#K5`IIaT zMRMixHGh6Nm3(gFdl=5hiGesmbJHs5P-vEy>%UD9q4^DjrU9YpLA#sKEM^QFfBw-o zt6BP2Q(wy{`}fFRDyk@ilR>4?;q%B!#b=(XI67QMT)Dnrl}AV3P}V>yUFxz1o*@oa zjQoq1tjWJbastYQ357jJP z`-$4-6o>DR+#QV+C&s4djbLki0|sj6XlUDf;Uj)|hgaTqJRcyzKnsCOZv7%l!t8gi?kF-Wd zwyL&L)^mnVGLxEjD2$W?qN0zVz42#(x_#~4)Us{p6p!op7%?4)+S5+^g^v&Kik?@sGVxg@k))g{|j9dHu}Ka zMrqTXZIdRG75yIF@^x2@xx+}rYqWqv~&QKX{UpV1Pk3RF95r?l`dmPxgbjkk=>{AjL%EmpZLqlw~CjN$jY z#RG}rngJRP^-z+E2q~yD_QQY2o|&IYJc-6}cIdpxLs8Q8`lg`u`4Hq>tPO0BHmB^#fp4!UWzE~eBTM!P!Be$n6- zClbYN#b;Y4r&g1T%2tcdv+2p=M7+4ovka#PwJ3w^9ggI;En5^EqU|);!+CJ%RhaXl zzu|bIc#`feQLl@;ovn)~n=HOuu78~!OUvPw3s4eU&sCMB`nn)nx&CmN`kQboI3<4> zl};Z^jsBmU7J1{@;#55P_-pOOd;dOyP96RR<>SSDaHRNxU)(?SEyD1$IbIxI_C;vF zc$nC4Xj{O@`=nRAZP`5@s-Zv{V{PU9bAwJm9J+UmP1UsQh(7)%cI8LfO0}zK=y-ea zHX8cTfFCyUoEk|}m`0Y&ZDjA1Pa`vbR8!u_l42H5+xSK!Gyjf?1|M%3o&LYb@w76{ z{9#36=Gu=NU+qQ=utN5qHEV^m660?;=@*YYCE1a5HaSm7vSf2k{a(cxY z$B}S7xJ(U7XJ)bU5~Z&$QokAFMVLO-}qdsbWPC1={6 zwcp?H-~+8UR!7)}gW&UQggL0_AH7WC%olS-$4G|AT-_ zpzp2nHLDj9SY6sU>Jj)hy}SGJ(#B(*1U9k&?|ye_V|R=|6T8gai#Lu%B5$Et*PcVD zre$>8#xqy>(!R9$hG(SE4}La|xGksCPVvAk(f15feI&xZP;brcKHM<6t;*UHyC2XCXF z>m*|H{JH(wcv5@dUFz<}X^{iJIW)asVA;lL?Slj74o$bR#h<)!@H<<3laa{y)^B`T z@UPniTh4Am&(T^@IRjw_)z~1EL&vfJ+`BLHf_>*UxX^x zul=Bj@20<`ebn+FpR<_A-y^c(5Bt0l!0!DaMmg!1M3@^2{11X=K>T=FFfg!}Ik$SLW6YE=YY!zY%Kw^Wxnsru#2 z-CP5+{|3<^wnwp2ZuK8j$2PamgYQ=OO*6SRt1vdBd4a7%l?k-@3yo;0K z__as`{E7~*v+`n+@uyN4%#7Z82HLrN$&(C5;krJq9cJaHd`TO%%qd{xEwk&xTeI-B zd5a^1i@dS1MYp^$RxS@#an_hzH2q)MMyL;dah|<$=!aDUmkFFJ4{spy;@kMt-KVjC z)J=7QqFY8SPJ&9>bQCToQJsG+g8Bcuz zjsL)rO;|atk5>&{^MUiY)rgMlAZb_Kc?75p+l5S6&FQIKIK!rX#u0exJffJ17d5%1 zg}XshzdTcGVDJM|`5=1(>5m5Kf2{N)r0=TRzEpQukqFN22X;?AgO$-bTps+;)S`LR zg!6c4bp#(kaboISB+)1)*v=^uC2b;a1p(JH9-zx$Z#{rm_svIMXn6 z&DrYo;Hs(LVPsSDHU5)ycj%Iz;W>yfj2aqfIoSHZ{;7+gP8_-5rJ?UtP2EcF;`q$N zK_@<>PJD5XSHx?+4p&<1(#_r2Q{KFuUYnp+ZX}97V~R!&4o0u6pGP0=J01Js$BdxV zrUU(_T+D_EP{m%8dB}$S2V+w^wc3kyKcEdMoU-(r8=)=ruEiWlm7RmM4ZL-&HSZ}vDr{vid zv0r@Cd~Ga}!MdqGh6#z{uHqrCf#wK-*6{Qf=sNRWvG2n-bD(r(4em)YFAy17&W`A?s6#2<*vFFA+;6xig+I%)#_?g z$z8QoS_P-#iwnP2tBMn~4V6fCkcEXxBn7XAxl?6LUts9BW^sF&&3?38ziXL#{&#Ou zX-kG0_JCx|D1P!V?O+4HQGG9&7Mgpj+HUUdx#G1p5X5sOe$? zEvK6DqH%oLbvLUE$e8E7ae!b-L1zBLY-6upCZSs74PEobr7&jjv~vB2Xvnk-c`h5* zUhpG!cckRqBxo;K_-(?|KSryvFT4zG^-R5>?P_S=vMC&NBC5mkv@!KR$qa+vd$U)p zy#(8x?s)TN>bx}*14~*)k9*O-UHAwU4gR<}(DmP}nt4OKRN1?NvZqgNK@ZKGH+3Ch z)a8RgbZztK%;{4j1io2i4XO-EU$-kL{XYomtJL)w@(qs;s?ga}w+DgKr*4Iqd38?t zsa|5HGJr5LoY%Q$LQSt<Yfdh z!;2sVg%Qc`fp*sY4Y0~Mj>q8%DrN5lm>jSzj%`i$M_wh!dJ($|-@%73--)lryIJQ`}~r`}^zQCr--_XAH*5&J$XkA9bu$DOSQ zn1rb`(F&I9C&}y;zcxiSuk;5;NMuhy3zqBuQYlR7)fMemI%cVs>68W>_e!NHB}fOV zP7w{-U~aIgM<$dg7m&AkM9rup7U^vLL$zvq#KmS9NiUpwEh5EFKl-%Rdhu{c~D>ZtQ3~H^lT>m^I;NbX zt?V(-+_Hs#qwF>WSZyx~TuCh3MJ=N(lhKDcGUCvP7Y{lckKaCU^KH(?*KfW3W?V75 zi^q8pQEIPp&pZ%)*xC46=gqedZmwPCp7|{G)D};|_<7uDEEv4b8(R36Z!LLu3mtAw?X`B_`d(9_>&aeCC$zNbrHGFEBhmS!2G1};#kKKi< zr|uJYW1OLhs`%!*--etyowz=Ttypo9c**bUGv>D z$0&O#MRwIi=!R;KZ(jHoPrss1{$NRT=u1Jw6cPV`W{qsV=;a{og1df~92eeo7u8oC z@Wx(g@XkD-E1L$pXL#TERpW!b#k#*E_t3<=U3CvbNZdEq{TY;VV!UBs_0UAauDZj}0yyTKG{?TQ^^H14xs6ne1U*ln!lQw0_nf z&@y^uU5*@VA>-vs9>z^mzT_c;e`4^M!B-6KG5D0hZyKDN|8vCb+4Ie+@n88k&)XiC zEIK$+p7D#%PA#PWb9P_pVYf*4Uv!4P_a>en=R~A7QG9mb9H-biFS((+_KhQnnrFQY z6N!tT^*4;KEiPHaHQ*w)SJ1o@@v55Wz?so4;Gtv36Ezcw7Mhv7Zo2Pvbj2kv;ig3I z1piK*-^#}-adYvU^h>^sGo>}JJ8=bY$N(eHq z!CnaBIHmv4D^?X*BIp)Pe4@1Q$ZK306x~l2^Vnj^8>jAlGpMPFwM-LMqGfX9Y9@R% z`p{T$jCdz-1(z1Kf1omS>6{<-}Rzu#CKM=ZjYAm!i&ho_HhNFa(xro zIDPyLnacG;@P#K313#W#KU?VHpwQH1R_Ht{^mFo2NHv%1Q?rF~gn1ORGmbCZLB9vS z-b?3ON0!L;3}PO7i7`#TMDFmV(gADjZf`n5O6yf8qxU~T%ya`GI{L4>C9s^~U!^59 zo*v#<8>edAc80a_%~LTEE;qh7{VBD9kFiq2qd^TToWHGlM-2t5Av*jqhU5g27J?h}1oa;yvE*72lwLHoPL-Hf6d-# zX&Z!I$PDTpz4pqPv-D7A@HBj$RWsGa>T5p2&KLdtul@(Q?pCg$yJvIZ^IdY~Of;yA z2RDmnYU0JSanIG;)!NWlwLdgg%ho>6so56)_~?bs#;LD%To$oMPz4rU&?S3cGqc#L zIo%!r&D3&p^QYJRCGFjP-G7j2oJ@DE{P#0C8%O(o3@ggx@tRTm({u|3bNZTU_w?^i~ab&5xs{lm84ypC(kUzfAr!J+e8&4talsQ-_I|p=_eK z8(CjHDOs=YGqiBqCDq7!-27zIugK%9li@=YLY`ioevNwdieP#*NqA_^{dF%AW@?qC zxODnlGSOBX6tuNx!rJFTXM44gILP=Fr&BYKz;(rruL?;N#ma zynJHo`@b=8#~U*n$24DKKbse(m42Vwz6fu*9=UZ}0^{TIBVi?{DyWm()og3u9Dk(N zAKFp9@uaF4XlUP@*g7v+x&z1DHA{BF_A^-r=4N#^pXL{TLG)WYh<<}^n%{Ni2j+O4 zIcA>MnWN@xt!E?EYtvw%*IKRr- z6c<=<{!EkZ&j**X^lJM7iT>(aoXv5A3;Jiyc8ZCw)H=o5uMi2bdBIn_p_!_CmRpTH zW!gd&EETHIyCzDIdBInve(QU>0M^UQfiqgK+8e$9(^4hs1rIc%TJMz5dOwr(e%4f! z>}G3m72aAk{S(GguFv4PXADai15&W?djt{US_zi!20s%d{}V-94q`Pfr%c%_hSFyi z>H26nk*gJnzJ$D5WW2PNOM6z?)c=-QyaDf#vaaT_4p|z^94hX&9L^J%qmijSbMsvt z=0kj>g~NR88j-2LAYYu*ojAj_-5Wd$KwwwfBf1|Fh!eWnvEWMty$!mqy8Mt=^MbeL z`RK?l;+&69*4Ip!zWw;K7jE1Z`8q18=77U7W%@m&5B>OD4Cdf-Ku~%wK&Vj4X_*C7{wgWR~m7J%qu8ZD(hstf6#5^dEkDM5MuK3Kb3@_pMsBEQk}YjNRy3-%B5}ebH7Ez^yU8o7wdn(t*~ycE+zD~Lg&A;&>2Lq zUG>;QwdnBAC@_7ThBxlgLJpSdPm24wfpx~-oW~sr>lmfz+&XG&bRt-z(}v=u1&iPK zi8FSxw&n$%QU=R@`aM=+GFbd?4!w0j^udQ{CAz5YcbPyg)qZ;$p~W>EiSHp|6OR3% z@kRcIQ4jZ7X+dkUIQ-1$nTzqYPWYD}h;FIcR6C!i5LKLzU-x!VRsyt*eatCb&C&9N zS98SQFs2)7EBxRy6IOUKdHEQHolUj#!qTtJ7OM)1c^h`kDR$uBD&`dKU0j8zXQ~GO z_s-h$15aoYdtveP)iVHSQKTL}G|3_w+9#j7}pN*$>`kyPo9t(a{!J#X77&&eU`)2g4yIjB8 zQvWM)<@&Efvr6y#L0HjW1SKoMg%P zTer$B6pe4=Mt`1mm}|Z0mg;e`>&@kVocHl+y>9&Xsw-C8ISyCbZOa;ZxYD-+UCW7G z)tY9fIGrrMiJhG&zU+=nes;a|!;SFmm`ogQ6V^yB(?b@Y6JlrWh8dv+oaNXQOUU@*Ss(y0?2bcd5_OQh1j-a2EC_`<2%AH>kLn zZ8)*5bwK{~#|XAI|40v~T2Fi@UVQO_$)T5PTTguVf>CE|rh4dDbqm`0dmQ-omzGzZ z*w!#ulPq#5zHSjuvOYWL$f1QPv}M73Df^$J?DYnJt?Z%&59lR+ihVrP_jRpTO@As@ zusiTA)6p&6b;W%HXK&S54;>rXHt;?Z)tUDl`r*(kHM;m&Aot?}`2!*|3!at=PVjKQ zh={`(&INDtlQDm}Ws4HH0G1}?d|xx;Iuu29o$ab)EhicvP;paOXyJX2wTG7ndSOlkP{cg z;8R*)-&Mdyk4S{R2aPAVi={`!*HPq0G5(@k)>Y}9@cWU4$+J`{cqjZW?1Z50g}AqS zm$po<_Nt=sqjnh@TsP>jOXaLf8}ppEE|RsDm;6#|x$=t<2JmLp-5177T|7~HK8|C8 zQD1w3MxC{024Y?@`u1P03|<_Zw4Qv*cyuwjQCiyxmFss}SI1{op5P}igY(Pv^+YiG z8PziMyNjv@$EWuFT-xWC)%T(a*3Z)em;+vM@06}4eywE8j-$dSz0G(XW@)YH9ra&v zu&%5X-ci3VX!0E6kG-Q_g7s0&gWY+$5xCrvfA=z0z~BYgA2sT7seZXeBm3j$)W&Qt z^2#;b2G7hZPL%84uRMX&&fYm!_-m@>-<7E^{gcVmV}=%PIA7fTTF}Y|=g8C#7Z|JN z%G96#tRhqL9n6s&`405zcQwn3i-`3zw9sNdVUexlZIE<}J*!~P1Jqk#&-=^uHB`ln zT!cIZ&&&tUX3l@HRK5BTS?!WeKQ+;f9E|z-lX{e0E-#9F>b)?;-bufCI&V`J>0zlo zljcdwT0JS{?vf+;V|r5>E>JAY&+`EH^W5NX86Eox>+Yd#1>I4U#|u}Vk9M_2VM7DC-C~MYdIQTE(7Cl7eg5em8F9@|pOi03=9Xsm zuQbqIqk;AwEnIyX^|Pywl<#{?FQ-(i*#40 zUHXJ;s3LoBTRy*L?ObGhe3wn-uUk8)8F?u_`wtR{g+FBLwf}%F=n! zd$O*x2dcS$FV)>3F)1!M@{Zwhy|1` zd;8^j(hKOFEID1m*J}DFbi5h)Cv~v2ux&pEZ*Fm;`pv515qU&#mfcUp$V)T-7rpU<-jwVAnl93h1@xmey5*PCcgUD4 z)jz~TPI_CeFIswZxHpI|RO0Un%FW~L$n+Ye6&Fsay;A+HmW9Q1j4+eAWMmRnT%g2g zyl#!KetM{%;$YNZ1?u+)On?l(CLV6gxu5uV_la8{x3%?vp@rux(b^genw)EUY{SFO z0Ozi)&;0Mo+IpMqQBc>&YPQD)1#H#-d$z}i580aI)}$;+uTRogWzD^p{XJ;=U31qQ zcW11*8ur)fiUD%!WmZLhR^%=)%>QE>b?V{gbRHj^ zH8j3LH|XS4xK5e#fDKYxZt|J26xpW){_bpBkM&Oz>;lY1t3 zOF9ta{1Y_!{!?-{|8+b8Ph+Of@Dn##cLVcpiQYc?)9Cj{vDvT&x+ro>^oqJaCeNpT zST zB@#|s!fmMJYhT;dkWcv?z8i1w<8Hb$<8*tCI96}J>E>H_{BTplhL3*a&W~&uxcSb8 z+duM&n;YJL$zAWK@Zg4<*0-#0Uf&c}w0>~I?H~QfT_0WF?sWS~zx`JI0hIN3-+bp? zx88BP!W;M#If}dDoq1cXXud-A#Fk&tWJFk}(2Z*r8$Tmghd4~rX>snqAbMdW%5#H- zk;Mk}^k8A+Y~XxgP2~K@IR?)JUKkNPH*!u@P2^n$FCdrlECkjYeR|{!=nKMBmDLN4 zn#e^~&k}>x7Binxb(>Uwt<_u`dAFr1XYD4@b$nIOOR23cau)pz^3(>kk>^ZeE--io z?bdEm&2^j3v;1dRJ!-vfzMyidE#(Q}e9LdCb;PPIOAYF=)`R%EO&Uktrn5t+z8P&j zsWVthjOtf>(8Ib-wckH0Qrm4XQac45sr_ezM=buC*_iHH(cQIG79$vxdbIYq(Ttw5 z(*}PisJ7}J75C~M702oxu#rBXF@|HA|8Dg*qSothUkILWG4+;5vq>ub0e;8e|1vn= z;F$&&7+h%ZEQ3*liwrI{c(%cF3@$NzoDtMX{G+D_bD?L@OX`(YeI0*z2|7}DhM?9RH6W8fWDoefK_nI$sRq7i z5c#aL^;P$Pt*l3F)dcG+kkUu3{s3+|%UY2%OHL#UCYh!a>a^;KVJ!pEIpk4{#z@Sj zGp(NsBGOl9(Wc;O2Im>9F?c#q5>*>OYDT&?NefBdBwc4kmKdxzc&@>B0i{psHc7t; zl7Ex*Ufm|?y+9AtZn70*u*!5-ooTJwO{PhB`X@=2Cal|J^SDV|tu+|d$qJ?B`Ig6W znvSYc4DAwAsi9VVsH(O6)i$%$kE$otw4ypq*Qo|LVYLx2ovHe(H;LyF<7zdO=2|@o z>oEzbHqKiN@ze~|oC47aKxP?;mVnd8W@`u}XMXKG;=84Vs!c;y&o_yJ8_FpOuMTMX zDcz{vR&Tlpx(?YA)H}OcV#)ca<{SAuU$SJhcn)nkAsB_`f*P!!nqbEiD~iq3LIEGA+#L~O1jR#vIF@~no4=?BH1Q)Q5N&3J?n zsUAsJ#CDK?=T%l)mDN^d9IG-eRhhIz3|3ixs#p;k={$obf$&PJJq(DvCO3nl05@q9Ov?o9M`Pb8e2zt71yZT@(BKIQry>CE1~$@aColTOZa0e-u) z$L;Lv&iT&1_H?qFm^MG*=Z`Eg_vB<{9j1J;(C(z1IQfHC{q{q2 zBh{PnbAD=E!a69i181-Rt8KHt%G1boeQUu}sF(`L@IkCzDC{7M!+p zk6X|n3O&wbG98!Ac(Bb)kmk9moI}S_V{HkieYXm{&`VEtIONUvuq(ZvvMHWkA_`CzW&#rg!$Z8JmWrACD(? zP^@#^WS8INbmb?LZYsWm8F3jorFMI+({mJNFn8$uGh)L5A~-UDoGt}r{@f+&zTDK!;KexX< zoyw+DPU>*dclP(B+cjV_>Gs|6bnXyK z$1SANncRfUIu)ezh?p6Jtd6SZ>+4Ks3;n%W z;(AkS1=@@j`Ak1T&B~&;y=2W(IIkY%)uTK;$|w2S)cgDjzQ6B(uAjf)Qs{@@{nv8* z8|zO~CQVLh9eR-_A?fzzG`NJ590Nd%^{*w(?{5ZNtB&~yb*3?y&gUljeV9#5BCaf* z{mw2RRD7)8Zv$`Z_gf16ll`7J?up}`aU3X;j(T+8>!q}(L3m=jr=fVpd!R_=v#|jK zS`mC2ucuLX7O$~*X;|!uKuB|{*iQ)XiSM2!#1r#9G2hd-qu+D-{1lX?!P7K&h$leV zoFGNL(^u$sd(Z>@Zl0Mz7XdP~=4STyBZ>WPG9dv0trbcrsVy_s?=~0ucl0}bWKmm< zed#z=1>)K8l>yaweC)&qR+|oC6z2H4c7wVXn z+MIspV84@OK#nTe)9-X;`f_Q;YeY~$QBL1jzm3sRFVuoMHqq}ek&fE|h`X77k7eEO ztSa=6^*6;N-t@J=d>5)4yCjv%E5t|j2vT4EP@e=Iz^9zg_969s5_*6#A>e?d0AGqv^jbce z%)2T>yLqGvFwvKHl*K_L`|^!_uF8M})oP=KRj@HgvJ@wPid`&r0U z?kqMDD9!e7xGUplea6t8HtG;Wr;CFr$!1FiWVKJjNcYA8`J9I$W|N^n5ZKd~ey&eL zOdsw`XHanq<8-p}UTB+C- z0t_&%0j4#;v_ne04wDtOR{utJA``}$n;<7A%;TijkgiHDodsF$v$o_$ilQ3FE2oR1i} zSqTlbxNL}xS+=##E}xn0niJ`>UCd_b#^!rlM3SPaJFMcJr73P^WKj52kob%` zka>=e@wpji0sz6Rr7C%YNpRC*0+6{t2(m8YO`%PJe6S!Pd(zMgeJ%>N&s9S%j21Vs zg!!-q`uhb)azyko|LCn0`#zYjSEjO%Xg;{)&@Q&80DZ);7vPh;Ia!57Waze&Q85t* z`yBYL?!hrBMld~bRJZaZ#bYPwbYYK*;7jmzd8$qfV;8onm2GW4)8oedaVSFSgJn}L zY-)f7CC(_=KBwb3KCqiiYN{QrUnd?yk$mlnYcl}hXcio+*@?qn$CiR4hCAZ7BLR0L z;En{`k$^iAaA``wDghP(no@v#=tTkYq4^lS^j}|NJND~3RNy+6{yNm)I;lYbUpHSm zz1E-rpU;Q!Eg*^y4G7>XtV1iV>s11(ah+5nfUmIbg>@K`>v{-C(*gJj>#$Oo1r9wb zu6VS=I_!*f>26PePYH!}EY)?a(sh0&y>A^$b)A+bKv67B03UOC?IfrTy0Ff3*@D+~ z7SuE) zy2c~x8Z!uOZ-1e;FO?G5*W2S4dSO5>4Cw7C^rG>5#Rq^<5UI8M0T7A2z;nH5`(6}% zujvOtB^G)!M|(4z86Ys$0jaKpn^j1}p%BN3V8jVGqa-(lT!Eb2L@&1i-R^dwLa#c& z;_OXlvK~AIb6DCAN{UX1>SEao3GC*JXSE6l};xF;#rd|cr z5eYYPDvc|9oGOt#gk3F4pY;0bysyst>b$Sc`|7-xPVCS*+HLG$HaLn>fr6yCE@yZ{ z?HHmAL@^={8fD=zL9cd}UiWaXggmoPD3}Qd;t>;;NH62_mD|SWAb;33nqF4}bTvR%19UaO_ChbY zB>m3OUT2+ng{9r=^fsC;j8M{RGUWCCJ(CH(Iiy5Haa~05c%n4`2qy zdYhU_YHG$L78D>uQ!^Qwn#s`A+ysbSDS)OE6j)^>%TGo;Ky}2d4vcb0)qznCP#v)* z%dVQ5t`v!Z4p2?#On~Y@TLM&C=D47M>OfESZ~)B#3q9;SJ?uI?ec5zZIzan-v;_h9 zy7>w{gnHNV;ehHb^dRp&7}Y%()jhJN0es}lCpw*jK%8~x_a0fxJvj*SWv{$aV70(1 zft3O)1eOc52s8`Ox$Koq0(`3tsMKneTCGy6Rcf_LtyZbkDz#drR;!fqu2QL0Myb>) zm0G1zt5j;0O080l@?T~l`6GTrBuR(0wb?q`Y`sOC z$zuI&whlL2kDIN_&DQ7UG@0IWGd<3r3C!BSI<4UlCf z+L~gaiM9$j|B4o1kqKG_EHlwo0SisERlp(>Z53#lL0bg|2*zv~#B3eJY$3#KCB$qg z#B43ZY%#=aHNGA8+*(a zN6c17Y?X!)v-J_P1roCr60;=|vo#X4MG~`BVr+}qI*HjriP=httrQ<(wpL=cSYozX zVzyjjwq9bkV2tB2TQV_QGcj8%nKZ^s8e=AnF_T7{=a@-j%%m}9(ik&ojF~jXOd4Y*jWLtPm`P*Iq|rnq zX3`ilX^fdP#!MPxCXF$Z#+XTC%!Dsy5)?COH0g>3lNroNz}A2_!2p9^22F+eB}_4s zMib1KNn^~UF=o;jGii*OG{#ICVh2}c7<%ss5RvE0@g3^H?(9k9kO1%{gH0BKKmyM*Fz0j%CEPyz+zG|AA1HIe>CW%& zNn^fk2kL9r4lRuNm8EV7qT@u#Wsi%Fn-0-?dMNL60P5i=(&OhcemcRP8&bkvSN_^b zup?{8upl2-ENQIOaVRI#sZ(c2g?OyT$LUS?{Y31QF(#ho0zaC5pg$x>W9v+o|} zQ~N3wUu&a^vj@xl-;R}~3poqzCrW*7&!sa*dwg8~#x-0bJs49xZXcVxn#BpyLy^ZbJm;Hbii4Lj>nGL~w3H1m`xi{Ot`9oZAq=xeXDV z+YrII4H2B%5W%?(wYnGL~w3H1m`wHaBf2c=Qc!eZbMCPZ;0UBh6v7Wh~V6Y2+nPY z;M|4?o@z+q$33u?EyNCh*0Y=8dYZ$(D86n!P9!}puG$`#8;~B?3(I)W6FvAldRz)~ zans|nL=X0~bBW6l7w1|JhqE4>X+6&KJ)FAu#jbQPC#xP#RJd*rfz^_e>4VI0Ju8|+ zu5t(;He`V@NY{5J4Jp8Zm;+J|hsAtGbB%g@cHo z0MpRaf)`9sz-rPC+tkdFMo@qwlAwU<(Wj8%9nk=4UwgC;X8^UY4Vq(_%EY+U5EO{1s#wgT zZG_sfb(7MggBn2fHLX&5lkrOXw+?Lp)hz+maSdR#N@O{-X%I~@4WcQgK{UlQh^CkZ z(G=4lnylp}Ygryf#T4>fr{=j+>*^A2;rqLMe<9!3>E#dR13}F974mqu@|9qo(;Xjq z^Z90gTgd0~U49{-%_YRf#9@75~=q75GkP!QUl@7B#Z0WMGQ zTLgHY5I!T_#pk>2VTK+IWJtyjjAKj=(0q4ecUt>&YFAz*)18Gp{=+=)CCo9GPj#iz zc)-DY+<9iQ&K`&yyaO^?pvc2~ssOkTV6Rt%aqfZI)4bM5ahnc|@8{DV$B;!}XzVb8 zEA}8pxAzuf@L)dG?vDW|!%brDXg$Mf(R0|?v0&=@d-q647_^VGDR zyY&uTh2`70K6Y~Z^KDLC=2^b2kk`cnS8&up__2Hw_C5e{lTyk{DFIdstP)r$utET7 zk|F}I!~_LY4i%I)6(lH9rBOZrl}7mhR9ebMP(Yx zLXO3s(}M#5pMQ`K%nShd(BlBULay&%uCLo|eB9tl!UVP$q#6bO-r({e@GT3p1cAS^ zz+(nuEO{gT7Pupa&7R}ZBF9xlPM1l5LT(*ic);^Ht_j>{a`^pu=0iq&%y=$^u-G%K zERk9j!hy$El)G2Z9$t}xdrzkbBY3-`>tO&N4|@6<$$5(0Ux~EWI$^*bzyz6tS1w_E z@cPIq!568QNJiU}p9-z_Ij3kkV_ED0&BWY5m?=OEkZf4_UN(pjDJs!}@3%5=g@Q;` zo9GC0i%>M5<_?cst|#MjKb7n8lTJK;FqdEFD#%LBYfcR*yo7-m~A7@8^s^*jk;7g@c0B0jU zW-$7S61su|^6ky#6P&WxU5qEn)5V8{wHv73bUv2Lw<&uYA2!Y|AZC{!pbC38T*|A)vuPwo*26nP(ZZ6zJO6Tby+@0p&J}1nRx$LPR8a- zIqw>7yfVbAL%b@)Xd~s5J~Pa88)n80qk2Q4sX~MpRUD+CjzgkSDQY>4sZ@)44r3}6 zqo%`{N(-p#Fh&^uW%4`t+BGKLj^e5i#*POi{jPMjkGG9%R$&lBglB#{%$tp1v(;l2 zp4L{PX4Bxb)sg7y^uu)Xs$de4Vure5g}U-N4h@q~F7Kn*#_^HBGBMoGr4I@ENgfbb z%Q!`NR;Hw^o75QmZk#ScY_o=f$OJ>P3D@gao>VFgj}8!L3TqHkO3zQMdZ@jM;Gt*G zMn{@%Sdk7r^~|X*F7Pzh!iPcaTtaHJy0^`rHy5UnNRdFv`QCNk;6 z7sFZJl!!O80p(5Va!*(QcI!QvpwcjrQoFz%9oS$29tXwMj@}_;#I@@sU@pzYr(Cq! zvt`AldE6kVwykAr*IKnUwe>Oj1ViH`Lr%*%;Ymj)Z0|~F?@HL-1r%u+BFhTPagO)Q9z1IXYpLX%s#`r6jYq$ z(JNVKy<$gM`FnDHmlQJ4w1Htd)aB-LvbR7;O%T*WuEy}e)|{wHGA}gps?v&f6HwnR z5WM*c18=XOoqVjwAYZ%MlT2GMK!+qq zXzkp$izC8@1a|XEUlQUYfW8FPm#FAP1Yo%U0;(4g07S*Z?)P|Nv=`Gx1`SX^1`kj` zvcQvJs?@__Y@f^_0rdZiV2Lo0vnzWV4_CrKh%BwfznS$2ZY&2~ZE$B0SUs zv-CU^sfSAvFv%BY;%6@e9H~6d9^d5Lb=2gpJIn{>LI=q4N2emg95;*-Fv{Vv0<<27 zfcV%GLo>-pGn7P`jU>V>9uXBw#~A6tX`ZXI`yC4Ktl6by>e8XCK8$b1Xn0J>;b|S1 zvY8~Soz+CDk$ZAl@ovg&1d!>}G2P z>X7Fq@|{#C*74Lw@fel|fqvGbX9;*0SR%Tj<2OH6#O-DUoT6wXf%924=s|KfqhJ?s z{a*E^Qxon6yfNkkophyHFtFUXX%U_|9nJB+NhKU~3?Pmn-I(RIGb?>I$b`=gV-vIm z$&Klboyw;2-7-R4r#*iF2*sOCz?A~41<;GOecR@3Teof8wr$H<$qT38=w^7rf);6H zA;(X^SU)_l65!LTF684d6wOJVofmSI9~wXqex8G#{GK56h4Wm_L07p5v|)Z7rn4p^ z(E{LhPc`e*rVJ{?d5JZRRB;E{91=p93?L*IYm=cncwA&{I;e40k?Q05-IyS6i8W)Q zBs7NUFdEE$#lX4;E1nMtRBJpF6p)n2;>3nKDj6FgX;)?vzcSA4z>vR%nx~o<}Xc(tm zQ#(t05#D8O}!puj34RUaNk zfNH|S2*9r?D4_cAGv@F!vMqr#sM9R3#k2jqegyE#Fg%P|oQqi;i&;4q0en~t0KP(& z7iL*rm}UF2Id^YXPs;$>8n{s~N)Tb97}yyHLUr?{^J<_EcRAY!ILOEt|>6@s@aVFBK&RH)e&c(GE6o2?ihb|r4My4m*eXorcowJX$Yb%}_hB@g&%j)~ zui5;;EcaPb!Tgc~(#^10E1yx^^WYw^0Ix+V#Ni;qekE@5Lg`4lal{PAuv5m$>o>j1SV2|W4?R|P;suFEeiq0&cakQKgBS0U7?hs zA9#TH5*;?gF3htm7gQv2O9gmN^Jf|zf?nvii&<%ae7sqJuU(JOg}4p_?dEHDUF_$O zI27VA%-GwwniGrKaDC$(w;2j))f|!xvMpdGh^E_uADcsT}9nS6F(O*-}4FZ3){Ke`SHI7+q-3wE0CS4stE zoI0*U7LdztJ;WCks3Q@2a;6v`pM8a(_gc5O%J?t=fmlp}yAk$GCQm%NPzgSN-2niT zeEF2fz6u}Zg2vC&hUcQ=Zz6X1001jOaY1*1`vrJcJA4c`bKYn`7?X1Th_nyq8T z4n_>?$4nWsWwbxpeqbAdZ3d=Tvr?>C&MN?znbl^6N0d4hFP)UdK?Y#A;P-?UDXv2U z^eY^oNK3L5*p z*)aJz2$D@))Q+7+yJVR#97m}gSp?82PxC7YqH`N{mn}wt&1; z(sYI`jc_5`%{;R-0rc@uwi|(m|2#U;&!7S<DSW$ zh-<+Zb7_9*hJKJ!5Wt5jp&xh#v+2G30Tw^b$v?n{gs3?Y=ht7v!Lf9w{b8H5{q+)l zn`WkjYV8Pj2MD{XA?9#4y)%pcR&@wGm-^s#{xVP6I;t^iZ`TC@fK63D;sdk@Gz+kY z?$7d)iDyrR0Php(Na%bnirLH{2Sy9Lz$Y079?qs%31V@|IlyNnoUR>^9Nn|2F^*?8 z(Mg|Y17t%^LPXsJc4U(#5SV!r`eQj??Gz{gW? zp!ViO`Y<1|yGzJQvEkAp(_oiG?C8-3F+Vx zW89=fAsMGY3b2OQ3c9q?yXYELDqBt$fBMAWo@`gTO-Tv;WHt*gpl!mtCi$IQuZpsz z8LLTw6tuqyGM1$xZeI9HG&|S?a31T$iC%xq4b2TqSc1hI6&Ysr4q3qBaV1xxjg%;m zGoX=(3O!3%opL}2N&7$*FQQ276EO;kLjzuRQShA(A7Rf@=VgDOOL5_Vm;siMu2yEZ z5Cu$aD>_IEw*aNs7Erl|v4Y)F>|AFD0WL*ni-miHiiLZG$l1-s0{jgRd{C)yXHitR zhlmWf43WWAjkQs^s38C&d4|X@7Qo!wb($9BnuUC(uQwVApt7r zWSjImQ7(SxxA?%aJ6K*^QPTr0Gk%=Q7ne#Gl8Q8pxU_c#hA)J1qK%yDsq~g^s{pFn z*l5Bky)~KD-?st4E&Ka6f+Eq;9uLd_)WKC>mV2xKqAPT#1&{%yJ1u~6_U_=5C7^4q ztk=V*)4HeQI`@@ag0`EPtUr=Ngp4^mXzGvTK*?&eKawLTlCgPQ4FdR)DRt|&kAf)y zt3rPvhyX?leq#t2?ByTh1LL&i5=9u0;YlP=mLO2Tc4tshZS(lTpnwg4iv(T)X}s2} z;LOeRat$hLIG_#+D~tMqVZo#d9WsbhUHQ0mv!jWqc2n-6xK#5y8;#MkAs!1_{va)j zZE`ASn&Z={P|C>%RR>vlqBggrC!g-z!fk8y`g7l$3NYYRn|1dv(q8%&G$T!NiqXxE#gIBNF*jA z5dk1zwXXjMBir*qTaR^2hP1C3%)E@PAsn& zQm$A72YA96{1wX3#ORBSN1t`DHib@-j_PbJ3yU1$igVo_xeg+7gvX3RW7*5F0zX3D z^0!qj6JWMHjxOrCfZw@de=aZ`ifuHPoODF=hC=#3zhZ|(%=)gL@2*g5#(^+x^Ul%; zU|Du6AVJxv%(W=6T!{;P0GkiRKLzttZ~hP%r@-1;bv0YG9QEcmfM&PSS@5t$>l-rQ z+=o6K-exo2wPdyy2`$L28!Yf=6VP8+b0>~iT}m-k!Ra80B}Dinp0Ul?oZ>edyF=qJ zx&iEB56isTq_xpT3}bEs1cLexh*MpEznd~|oUXs$P5Hl1>%TDnxFh4uBkyI=@&RcB zmOGBLnPxa7b`-}X_vD`9=;O}wtQSGaa`)KTo>D&Cd7k#-vUsug?j?8HPY*{g(t+Gl zEM)8w@pSQlK9K$NJUYCObI75`g7@D2JbF_25YWpdhll&G>*v#R#fN7OGhy&CXgzX|e0$LX2u@FHaCxZWNVA7fO)M$WoZVKPM zd}jTfBa>P)*O9O$3@2Kx0~&6hZQ63NK^mFUB{zKCu^W_$GF&uprmF0}dD^sTI|?kB-L3ql;5%j;)#VSVcJJhl zq9*V{6{*`OceFWOav&7`nnEpSN9_UIJ4SkWtQhba8Cmv)_Hf$fh~w!8y6Vv|mHRmM zkX?K`-;TCZ?P&YJj%MuM)5kq}(4!9|2i*73Ip%(#ds*Pf`@z4L1&+TT{Cip8DEz^{ zmj#Z+AN&vGn_d<;D8G-warpz?%K}H|5B|L@yy<0u!}NzZy)1CB{@{NgIb^^0zUXCv z1NR62UKTETS-9wB;i8v?i(VEulz&L4mxW%E9Mj)N;jsRJ?qwlHi>{qHzJG|*%YsX$ zyY}Zm|AFphfy4a={{!jb>F!aNPxo{$3o$BnS%@)iNB6RTGJwOgy)1B2=-}VWLhn%* zTz9W^$#qZnvJfL^_u3dTcXU6UUKZF9a7d?@1(#~~=^sd!Yj@sk95~RuEX3!bdu{u9 z*gJa7qNr`oUnE^BCN=tb*QkXl4~ zA^qHNuB#W)qx%h|qLD)^&VKbA{oM2$tNn)Uvc~?6-ZTB&u#=+~($7u*k<@0X(Oh!h zw`OX#_>%835TEG1BPHF>jf?Py)cU#U$8t4(AIk;#gQK6Dm=5jU$=;G)w0=vm*Q6Jc z-qX*G3-yQh^l0{?90J&l(sT54!@iVWNIy61Q|X2DbHk36UPwPTob2v}^ymYra+ZA@ zb+q&xy^N``r5Do6nEG3KA-#;L&7~L8%b2=ddLcc!{~=W2%OMteUwV#yZqNeL3+d+u zoiM$Ses0hZ(+lb6rvJ|VH&N{|he!HfMRm#aLi)KuvrI3fpPT-tQFSxDX#L#u3*G-b zs*2|DNdE(=Vwzq^KR5kvq}pnF(fW1M|4gdFrWdV8_rH|twK>E>y-m;2&rSbpsm_~T zw0>^-!?KESdeQp1=@+d(EUP5v@JN4HR%K2vBqh+#P5;xWI-TA#{oM42xONEy^wytVFO_=q@No$6!t>;x#`pUI6DHi#;TUFiqmjm z!4%0vp`2fIpG7l8>1D(U0*~gcpcJd+CS@C&al1^!8G+pbBrCx(LUBGy%Z;S1O?;HJ z-s_5`QF%;sgtw81Ax z4g|)^mqI#Ui}gi}bpv+3z*k<%&wjr{;S&--ipWhC@v4^M<;c^}$E3V%^ze^64qI{0 z#p4Wle0Pc!8_oZ!jg1W^Y>Z}y6Gdh_G&yyf4C`p>cKE=S1a@_E*ifQI;Egn_Mu&iI z)EZ!M>c?m9=WKGCD~)eSZG@GvxYSY4cu@eKMNWp=raKZ86ydQEPat&@y~Vg7T(3Cn zGQ|^t!CZ^8y&RE-xI?G*4{QQ-PTBN}HU4Ghnl=Q>GN4WE-YXHad|ZD9RoQ~&A~|@) z=4)(DZ-EVJi^KW|x+2JaYPSf!K;YouUsMWbnQYBkn_^*kTv5Ws4=jP~v89h6TfcVH zdQWz~6w0e70P9#4n-3A)S1*n{tjVD)M2}IDc{I{op}E3P5kWM9(AYEP!ft&%j?&IJ zO&6t%rkc$?Hhvc&Q#K+{Bs&bkd;vo{PZS2%lZIPeP_kj+#>k2hph{uh-_`sDIIGCD zB5cX9?ucQks4@T;e`=SqYvrHn+XT*pQ^8tsNoe3#Y#`e=keL|xwNeQL5TT4HDuDn< zPbCn5Pn@E?UKD)J>Hfg)i5s;6pYvPcMs2|7PEg7q`k>#3fzx$2Z38~-`0u7|z^5JC z-Lwt7@exOKH*EtxcZ?ciF@j9P(c2B&fN3~+9ylVqT^sOe6+(!DX*dmbqc*@sb5Y>w zqhByco7vE`L3jR!RWmLiz_5%3U~aY>_r(Gj)+PW9l6?Tf27EDKyFtdbdGLmd2W<>V zp#+BAZCE_#>KK5zF)22ZJ_8V}M*%@W#5MvfHM?r@cgLFj4nQnFVQK-#*UbaklOb47 z9XIX179IM~RW=W(2v>8_hFv?rbo3KNG8_wB-9K%-V`ua5j}00@Htul*&V@7KR5%fi zw=Al&0f$8|sG8k5;wxMG$aK_JTU}9KQDIRJQ2|i{ZLy==QQEe+Adgc?tbGI4z=r=9 zKsC6g2VkrxMkqEL8G&yLU&P>e(r8>@ zMFKl^&QYk2Ivl~>`y5W;?!0!fU&6!W7*K&&DAvYdVb+}fw|Um=Z~^ARXUqgbbvkqm zbxZ?zFlbZD9#{V!I6iv#1LDhO&BEFA@rhfbBHom^yfKb5Vv*h@KBM&yfT3rzW{0&| zVn7Elwyk?yfHQ%%b&m@`+p;*%TUTzL5??rA{B^S=8OGJkf_!l_c4LRSZeB6i&u*4t zSj0jSN`6(XFSS?_Uh1ddxlILf@4y|7-($rUKx zHskX`HO;1>vtAWMY_0V~Uy!c927x+@BX5>!9WJ1E6l+VaKpk8=dZ)9f4e5?Xw+>RZ zd-$%S!yDL59vM~@a=Q<2zbA0#+;0l(wnqFv{@sJ!Zozi{L>sBw5ZE~kLCD>@Vz);M zKkWbL#c20v^gO!5w4D#TG`jTKJt8T=)+@G#w9#9S-QJPDUq93RR~B)Z7#!Z%?lfsr ziLE9_y};HZWw!O|zbSmW{I^m2NpwE_2U2?Tw2h_BM?Z4Adqw{*fIZn!ge?|)3VxAb zcdjVVu|^~R99neMnn(ED0{pAofdTNZat8*$zsmE%8@3NHUUPDMbMTilFY|l*Xl?IuGW)* zSk7!;D0m{bcjF1+2P%lxGEFAlT=C*Va6BCmtd~9zzM+vVBTZD9d(^U{w6D;XsNKH8 z+d?+7dVn<(as7{szwz!bs7Shd+SKpv=nY$J&hw%-gf7YMC`=r2Mu!L-E9-}|K)VKO zf;`2v9KdkA2$ek8YyQ%3H~QaVZh`}5{dD>a=u5Atm!u4n;e$+$*bbp;8P+Em#G*5C z-qPB^vNLFLZQ*P+Vs9n(Lfs;*{ZmVtvH+%!nmqOtf7#zIql10@YSd0^R#FvOo^zoIhN1SiL6N?xlC?`B@o7ljMZR(>? zONUL3%LD-7O^rKK2P%Of%-K1>5a#S0AhNS_AR-T-n4JSY!Mq$`W-SUnhg=2lIcDU5 zQ@1elitKFz!w@HuAWfX{gcmS}Wl=K!;FQ6Qx_pnl6V^OhT5ZkdH<&eM zhGFmqFwFS?%=VUP`mNJ+0Am1u*;_`(+lRN979dEJ6J~T6pL2c=U`XCcIdK0h*!5l{ z^ol@;Ii^!s9E69|9RqbB8emLZK1p-Ar%7>I9ro`PV(~**=y&-UfS6zyaTyYt_d9Cm z#fuflh>{Rq>_pO|2ezlNUeAD{5=D2|Lxz_GuL=*Nz`)=C#2zyRUr;0nMKm2je(G_% zP%fo6xv)mIw}0GP5tiKBZUDTk0;cG<>u&KkPZfY+rVkhi13!I> zE&=}Fw?^Q{U-Z@}N<2U=iTnvd-C|4;`GS?F^?J*tkGI@r!U-r+;NNu1apv3lpSSgx zZK2#Ts82mHIRos>z=d!woC&AGiEzBVdAGfx-`>z?Z|t)G=4N~2c1vI_V7}eRQvw(= z4qzzM%`e-Vx7(YCckj5llumo|Kt}~Ie8HKS#@7HxC=SCW;KvOena??-HlwKo|{1G(3=-6G-Ze(y6H82^rf~wWObRI>6c^%jCDy3FcOk zohq=M-^-5J=>Wsc14x9L?>Bc_j+byI4CHK>T7rWLdWAv=2>ueFdW$0Eb}sRZm&X(NzI7De(LKpz1m7#J_ib~-HM@6_ zYjtN3!q#>UU_p!@IN{jZKd?|r`hhbuTqOG$3;CK!YV$g*OY#LrMzzw-H%~a!J`fgP z{nq{-RyatJ(W-s3gr1yt6G@MWC_8|#(TK^dvgXk8F?lmbF^6mW0CWg#8Itg40?8C3 zrir*#N+YnRUOI~%$7i)Uih^}H^N!>w1v3mM5PBk*HP=Cy0X=-PcIVH-9O|Jg^^#5T zG<{2a3VZqB-%cMWssv)B?%EwiHuYjM*AelU4(fh;<6rTHF3reyV?zEn+&ugm81#3@ z*hSph_;F7R<5X)uw>tlPG=#fYtM|a-e)AKH2@>a+Y z)Isa7`Nyy04VK-TK>0#ItgmSoH4c+M&{VM^gWA*@R(Mhwa5z*c9K-Jj&*7O6j}tUz z$1P(aQ?CPkAbA^#b)zB>s*nhee7o^}U?-R=o%<#P>Dh@DHN}kI5YCiq@lU6|xYmK( zfRb@D^Hd7M#1XjRdv=57FfmTsQnxT3(aYKD?6EXEJeJ3m=^>09)BxvbI9KZH{9=p# z;j{uTKSTSr8is<5!9uZU;jI2Zf0uj~kfrFqy_s?KZ=BAQ(oN4&e;NP3%PW`=QtYVD z5I8spOIeu1ZL%} zVPCM(MdP9m)H8-NB~*kq6{?mW<1>94t(n|IGIs)qxnPm#FFtmPT(RgIksqFAuF(oL zb|-0C*FluhxjoI&$wvAc25 z@(F~;y7_eD%!{7NHv=cC&oQR8+SvNNx!NCd+POncv~y4n=OSHHEgB?TAF&|GtX;}+mj8Ei z^v~A%y|w<)T2EM;NB*G4XK` zZ$1IkALA2Rx79k@y2+RRof~29d-mT`FU{RI495(_-vBg--88QZw5UP@IoBye=nK&F zh+v?#Tjz@os~Jm4kpB+mB`E1+1=0n|zUw=V)y%kDI^*~#@w>>7!AFs;$a?<~jDNV+ zGg;?TccoU-AlY?m$?;^uL(2r!2Hw$!8l;PFeQ5Plh;fko+X)aS!C8gPoKTy#>E@+y zW3cBp4Rzrl8tDar2RGpmqLMX{+(}?@Y!iYu3XAU7_|<3{&pu#y{Wmt8{|G)Rt*$!sp<_I zLs#^MS>WZS{_AFUc;tqwLZ1PnQ)Ts^91><;3eX*J$0U#y;Fk1~1N=T>{CI%mCIau| z0nksvtl)<>O?z~MMB@m>|D11?(dhdkZeR8Nk*hddsNjVE-1i{fgC5z^@-M`HHQqr? z`ZR}Is9`u&GP~gz?e!fi7!58XaV7|6`1sJ+k!-q=xCFH5K-a z`;{Nn{i4k$F>JmE){S?CB6e*lE-;W_yS+%xLw4VuCDqG87%5W!C@8+LGYm^srDr>% zjk!*g^Q&}N5@&`#o%=b$X3vDJ!r{$bJmxe}B;rI9VRunD3>Z1J&oJfUm~or*nA$`2 zwMtST91}qP#`G#l42{bf0TQz3E+59s;v~8*#{Pmwv?&{jIY@tWk37dh?WH@DK zRbcV9WnDW6xYt0>MXOmBV);mip<67LG$Tu5z*o#dC3az(#f76{%@kI#ceLZ8M#U0N z{##6X8HaadH#&ur?lixFdGi(-)SuWSog6~Khxm-PT6-Z0N|=6@fwf%9^f0X{EL|e83d* z0RsR5A5aNzgbU$ZI1>=TDL>onv0RQz|;CyZ|M=A zIN831efJJnbQDRc7(2Y^U?22Q1m1cuM21KGv$cYw>BugG6NRnE?7g;^)iyz?I2rkX zZ>zsB)|u-2&fa1--+|Hkf0>-m$rh3jUJ5?5n!JUBb1hd!j#Sv|@%9OXVmFj3iaCkT z6iECI(D+2f+A=vZ6nt7UZCE{GUE-!K`D|XX=*wgvs4;Iwa&wPAe+U}wZo8v)#1AI! zSL+uRCP{|5Ig@6d)h33b_YnN+$8v}|qpb`7y7YOYKs~P!`I7{Ql6F`@hSOj#A$QDV zOH%cEQ3p)N;9?o95Q6aWMaIz)-&>nr2;qJPt)m-*dfxD zPmEqhd|9v2p10n08cyu8dL>+83>YDWVY0bhukc+lhgfs<%6f%t9F$ph9_zs#Y?l0g zYVlq1E)7X1($5lPFzmkaTn_QWnlgV_uP)I$PodO)v8F(if8w^bUa(-qgRdIRIL_yp%WGH=(7acx7UGwa!x_0@8_zWT}siihbR z4Dn%oUQe&;uWJ>X+XusLt!EtDHOg$)1{j}-^O_|)fY*-SuaQh4FWhQ-U<nwn2v(5sT#tA#AMByw*(__sAFeTPpfJljbQEOISjKum2U`njN0H(ys3*ghNyZ}DU zkPL7)muT)?g%JS;X}~lXq=5^%0!Rk{E%hKu?PWUBKF2@~M2;EGA$=PIIpEtI$i?mY zh=rH+(VDGjsHfSk-XZk{?ggaIqHrT%V55KtV3`H-Rxnh7vnae^u)_!0)9M|v3BW`V z8UXP2VoOV6!q4j(Au-I70Utr!3>de@Jgpx2YBNtF{1JgVK%__W@ECajTUw8mKys`< zu_4k&m~H~bKn?~N1J)P7aE&`NFQb{+$Jr0eE9N`KM`kOo)(Tr7*N;&YFrr%^Xn}dp z>H{|Pr`01O)74|dX-JYkEpR1##28=me)V{1JSP9Zwcz8-6adsp8;1}0%GCz|V-8q) zSh4D`a@7IAY*%l$E34_I#S|qBW)6_$pX4r1z+9&I-|b5+G*uQJOCxXf1v&D|KtmAYpSD;8QQJi zK6f_=ADF&3&#*BO!AUbRHKd{Obi}h`sN)#;17j!#-IPB75>k2OO4Uou_mv=pMfA{5 zvO?X4URSgpV28&dMWv`=wdkMA)pquX&9``2S|1jE}tr`Q6(*h^pyeU|%!fkpd^A3 z&;jk5^snu&*Y>AtyTrA%cdhXwbL~gw+7HWhd`7_V@V^0V5`IirJy~6UT3su{6pa&q zR^Kl{v93`vZ`2l^A#nKLzV=^rO&q4uVT(LCdq+)}39gtXE>Zv*ZpH>a+nYu@hjQj9gF#9}x>zCC@90)Q z-9CU!q8F=M8)$=C$#qM&0{xCQ04bm@D#CWN!Db_jIkOs$9BJHe2+&#Ga0r|UbWt}P z0(8(AoUg2I^~$VB6cv^L>;=pntul>X22ur}0LLfVYqUVS+Z1LB_!DCQnsorO1|uNQ z5Yx4@5Afq^`VHAi%t5B8c(YxnbNe*d(ng>2!G0HCCdg;pwDBh`yBk6yJEj)@?SaC2vz_iQ9l*Ktcr;#6uY${m)6KL*mnEuocAs8P) zY&%O$Hl<#|ieSP2A1IiMX`6Mdwi1H~e`?Q7h+C5REPU}~U<&3mt>!rCuSAa32Z-SCY=|J0MY;BLD*ML4@*YOMkl#jI(gbmB0 zw4lFzgSxXnwS6rra$G;LL~8Rp^B?&E8uhJDMijTj;5eMCvryH?mP^CMt zRuNJ+i1F-S$h7#ge!+4x>u2oPX2V^*{Odnqu^0okV$_a^I6Ge*qsNY@N6~bk9Cyu!iNdktpSck`S4o|XHGtV>4GMV1oIv<-f5L*CNz6!m>H|E6AEF!p zf4+S62V~P&2sA__zK!MOUYt31x$0NXd$gtD!80shgx+tU5*X(_#|4}V#&Dc>3ny^A zT`9!?f*L>}#Q=B~DF*LRmI07LoZJ#6kvE6}@(WQgCFB=?DIv1}ObM9eFSM8T(# zRscRHTNN|2n3ypy+kk;*(IXu;#3t$(BR883Vpx>9Xw7yH^3shb7YhY*S^@15n;e&N4!>sRJ-H3UI_n ziggak%Rd0Hp7;j<$J^zfOVy!2EIuuHX!C99!rAH(Qk!EJObo5|*4f$N^L=@{UBVA8 z`PPs<>kcmP8E9SwCF+OMUwa?+F-#*;gdfg=?ISR>hmdsVVX|?GLHoUck8?>7mQWj(E}Ihd{-EB!E2KE$2bFkQ78LiiY2J+$=3f^GO7u?$}ifLmPyz+<3)t z*o<8`-N4c6XT`w`n+CE6abB&7e-sq0!ErDQmtawG*nY9F&DWYtn7mR5Th(DT@FQd_ z>|nc5jg4kOscKpxHq1-77;5BLW#zJ(j{K_K-4iC+_BjbY=y-Uqa#%k>TX8>Qglrxe zA5c>)X*j_YV1Y%aVCRpu&Bl*qP434Ji*KOnVbSJAKu1;w^38#~IFRQDlFqq%j4rw( z>8LxB0q{Wg9)wRl`1c-#XFd4S*Z1iR_O!$&3==GCf_+{TaSRhDa%WFifxw7OQcHM# zMon|VM+NZR{-wSx5eR-=^4Z)jm$2MR()haM3$~=jSd`q<|FdKcz$OyR9ikPKRc~0@ z3F|vJ^NJ|OIw*ndzDs5bFkNKKV?{^kNn`)pYdG{;)h}QifYFJ%He|IynD`2%ZLEAr zj2sBvdJ15=OLaSf^jL>CQwvJRRScN z0_FoduPh$7#2^OhfFBo01xqsqTR%D}0gC$&kZ|!F+(`2_gK$W|#%MD;s?v)OU zr&;oj?M701Mhfh`LYj&T`zPNghS!f;rXHLP79_WB0Ls^|{DZb4&#=COM{%$Nf{?Gv zhA;l=0~TY??^vA1T{bh8SX{hx3zc@)yP%K@u>&}^6KXe~M7>yz6@~u~W8Jf#+cwtX zJupYCvTJj?sSS-=5t+)9!YK zz(a;kv}Le-j%9EkwE9PE9*atW(1o!-vQLWj9jw@Iq3!*&+QQRv#P1A}|K^D7vlZ+! z5ImLk3xF>gL}CyPRU*1E6vtZslTwz z3#4axK#UVvP6SH+v1E5En=Ky9D$6E|Sn!ABE#-CsUXQ*33fKF%*C5+WfgP&MW40 zUkjp5LFQEa_hsESHRBmG8Up#&G2OND5xt7-BpRD!=v(B5-6~jq33a;QkA=CqX6Fo+ zBMeF`IO+fg927?)gW#kqjmsuj!nigT67T7Xqe4-_DY73uEM|0|7{Xwd?9^D-5!}c@ z*#VKrj>J-of>z@`4f4TGTJ&h=WdDtIu59Tuayk{YJ`$1LuN$G_o%>P*)SO1OqFAVW2;#I_}h*uG>B3?zjig<5`_l9_Hi1&tgZ;1DXcyEaJ zhIns?_l9^E#JeEg1@SJ3cR{=h;$0B$f_N9iyCB{<@y>~NPP}vCofGezc<01BC*C>n z&WU$MyffmR5$}w6XT&=r-Wl=Eh<8T3Gvb{R@056_#5*P4De+E;cS^id;++!jlz1n^ zJ0ac)@lJ?$Lc9~=oe=MYcqha=A>J|Zj)`|nykp`W6YrRK$HY4(-ZAlxi8mnLfOrGq z4Tv`&-hg-m;thy5Al~5rEC<8?#{3uNKQaG-`FG5}Vg8Q!4f8h)@o0|$?J=M|2DHb3 z_88C}1KMLidkkog0qrrMJqEPLfc6;B9s}BAKzj^mj{)s5pgjh($AI=2&>jQYV?cWh zXpaHyF`zvLw8wz<7|A1V8}Kp0OM)3M7L#2p}y)LI4RO5CTXQp%6gQh=c&rM<4`{ z{wW7>MUz4_1n@4zLjdnOW%*kacq76hfOjD<0(jR63+kf48xbD?yb%!+z#9=D0ld+T zFQUME5hnq>%N2W3;Ef2E0N%y2J;1wIxd(U`3xEJ`aSc!uc$Wv0MS(XSBe)U;-YdT~ zpqnXz0(j%`2}23UClKTd0Wuzda4{e=1JG(Yj=ag44d|eXt^o4pMgUPDhb%4vK2#_~c83A&|3L`*%5N-kFXApJHY9l1MLevHDmcg;FcAJeT{B7~C1uBXbh`1Jr zxE6|d0n81Cc?q!kuy|zp^s;#LOvZu;O1%IK{0@L=FpPA-cEQlRVD`g~SBwcVIVUvd7JoU!Gvn@z#}89n%V#2 z;S_U%`E9|6X|Y*iNS{wW_ZcBZ+S$(w^Ws^%<~2)FVJoghhs66W z&nPwn$DFBPQbip>FMe_t5^SaT3Lr2Bao%x*(VhOxSOUFw5aJd?R@LJJ+?avZ{RhNK zzt0%#l{+ci=}d)!PXc@yqIw>I9Pw?vyz*j@zLUE^`c5tb={xzpeeb*5`#<_VHQ`7y z%&ChaAm-~rEkYjHlK`f~Vjb`ChFX~_Y9YoHf5itfi0tKCGaqpmqTBkI62`SWKX4#Z zZ+%13eh`ecL40u!qOhHpX@n?#!45#zhZe{l7SvUAvZ$?&WINFU&23bl`r81zCn)gw z7X_xWVtCtU-GvNbn780ya=*A{1%dVIMVKu+tv%wlVAi{saY}*>mYZjU0^CyrjTMgO zJM`uW_{cfLKQRRAMr`K8Snolo8_(X&C0-Y^Kj>%F(FZLWceeVBnZkx*F}D+m#p=>9 zXr>Y2I&H0EtmX3IthMOG?mH3toW(HXko9PiJ zp+#Wf9W6A#TeqwS^#KJ^ei5F%X*xQ;yL6^x@WHdHO&dhFAws5rHvx>!335{1PLG zo>?qdXEJ6DeL$a8r|U{e4Ogn9A`u+?o4&RLs;*iBO;_|71LFX!&8s6?ybGYZc5xuv z$gNr{qw-FuuuWT3>0o}r{Kfy+KQ3pJ>VJXPlH5pX$FP6+Il(3i@~M0;!sG4-2iw|n zdk~*69CRSl+TR0%=28Bq^-bWnxNeT)PTDYN+AQNwi4=cOE5Qt-eNt$~bRexjg8a9! z0El79MHEKkClH;BIQYMrzd4c_Hdw$zLPw{RYl8lWIeNopzBHEW*@>6Bs96~m^s!|uXSSRHOINC+EM%B|hGyWE_e{dagX zb<{pZop#t<1<~4VGN)Z8PuWKu{!Bi#Pf!uv+HH2!93O7xeXZU3GiM7oQ?}M_-Ks>^ zea!q(dw`mhz&vyIBl${vw?d0Ck8=*NVl4D1XTP7Cym}h*&)XC>2dUUdC0pv`iGwc4pRf8 zIMQ!V<8ZQwoP}>t%rA7%TM!ExfH-Agx^UX28rkC9k|e_dwM#>gYYNPak))Xof=BW3 z?vzx{ACWQ5wpf@ohA$VR%N(AYT{sy2wd+?b{V=~W;{*6#i-I8_KoY-_1b3{>e~k!+ zM=+tkyv016GTWXzg#<85jBhv5NYf;L8DS7bx&7x}yWe_+TMvsAVm zO$FowvGR(p0i0jvtUk`WBf9KFGG(&-P@5$h8^FB5oMHZL&eU}N@b|ele*+i7xnL+? zFu+_R1DKN%dt0bRP_Ul7k{Ga-K*6d71!gm1cw0@-0tTJObmH=+t^Vv=O~d8O(vd3+lnNM>C`jlc?1lyy0`ZDmUv=Q<|oYP!7dlJUZX$f z9LvUodshL>=Q+n`C<))^`I;xlG-qY(IOvK1Mvr`;urLf5B8Gc4MH<~r2LO$}LYWN{ zj~#&xe*ld1a^7`BP4mWh%5t!|FO2HxZqnn!Ti z5--4*)2ZW6LGU)N)1-d9*%J7HafYTPxJ3nP&T;&&*w=F&qcB(B=2y!~P`w4xNWl0BT;3bTf~{{< z&V7gI0?MQuTdr!}$HWt$UgR_8jOPt!U8qW}Kfv~W;Es4dx5D{)BSC(Qk*nb=(=r=) z#Z_num;It}bL0((%nF?p+0JNdy!u(2!f$4yqrK1ohIO*@dGzjIuF` zcGOerrDe6-L1>ePjTCe~tuG?nZdjzqVddC80~N>T=MBn0c|!FB;zs~t;xwB7phZJ> zr-(9*4_JQrnuZDr!$Icl97XioIX-O0qsjQAN0VdYpnhsU@wK1w+D~}>_R;^e))NTj zH=7g8dOo~hjO1U2DF!R}J_kEyWVYk9Lxxni(d${G5|_j8EF93J?b1(2kd~VXM8iCp z9o84{ifsg+IQhs1+;}nD4g43;iTGHww)hQ0h4LASKQXp}?Rj-Rs;g-?zI0yQ(6c+x zZYQ=Ic5av4X@B(3n5ml^GUcZydMa#%xr>lLDAj#^O)wQn*X1?j%a~TaU79>QP}a*c zfj+|O5bC$}n#c4H8~XFScGP0^hQ9?XHx|%;zg@n@XJS6+@by3E^_c&CJ^pu$X^#2t z*W{A_5=&M<8NCuwhA%smSc^GUe$F0K@zT(95Z+ zC>ZKoRBUNUO!!$Wk8J=LK3#xbd`tkwC^0ze%s*Is4}U>GB=+5Bc<m?^ zw2uT8fbMy}!OuXh3<2)XO$Yv#AyN{pd7!tD$Z9t z_#M&>%w90qWWXyAuHmeFdgB!p!6Re9iuv-EH1{T|>cSYd>K%TUai}xTo18 zk__ci3?H)xYH)V{YA*|Z3}U%ua^Rm$)%wP;=;R=Qp=${(P4?-&bBu2dkqCRaxS z6ep~nW?s5ZQMN3(cJD#e{fTZj6D%tVBQ z&wn_wr+jc?H?h0c-oAz0VXQG z%|lB^79bb#PKYl|s`#vtgy+ZEuY%efXcat!MM*hKE;}6rukfxJ!#W*<9C4ei&`QIk z3@zKLWPtLO3i?En*2w_!fTfN_;<8~9T}9aZ9q{GQ$U7`GAawA0bRC?O56QKX@7Cs3 z;cl%zXNWx5M9o+vKFzMTv)wN&GK8;m!q}&J#TwIih*!^9W#^mhyvWY;?4%<4 zNl_ntC$-Uc9%ttuIWKANUSvCe-^m!#cV1>EgHu10`tLh)c`tK$FLQY>b9pawc`tK$ zFLQY>b9pawc`tK$N4dOgrt0T;l*>EHumF7GIpmmOT` zMY+7AT;5SGum9&>qcE>e&RkxuD@vicyvzeqXfAJ^%UkF2ayff?HkX%!EGaaXm+58- z&E>6gd55{Y!(85BF7GgxcbLmN%;n|E%6>Muv@$t!dAYbUh34{dd1VUC=eY&Xb9v8m zdCzls*`w2cFPDQRXD%c2CUY3?pXfE$rF7H_`?^!PISuQVE zm-SO-^HXx>^0MxhLUVahXp};8dD$tJLUVapc}t@(w4d zyu(Q$E-%8fex8-09Olo%CYKjsc?!+t zZE|^=T;3*^x5?#ga(SCv-X@o~$>nWwd7E5bR0Q|)teB)%K$Q6=hnd42Ugq*%=JH4%pC48bGXCI;SMv0JIoyJFmt%W%;63*hdaz1?r@aLn>pNJ z=5U9Z!yRT0cbGZcVdij$qujok!yRT0cbGZcVdij$EOPXlEOWR+Rx?s)Zr?hWH*>hd z%;63*hdZouf6g54kh`|hdvkf~+@CXtJIoyJFmt%W%;63*hdaz1?l5z>!_46hGlx4I z=KpWzaEI(M>z62VxWi#CZ{~1^!(86X;SMv0JIoyJFmt%W%;63*hdbn$K|hn3!yQ(6 zyviKzu*&0A=5UAXflDdp@>aQhGlx5@@_3aw++pT$hnd42W)63lIox69aEF=09cB)9 zm^s|xn_S+^;SS&A@@5Wqm^s|xo7}#c!yTebv|n`>`FoW4-ywQNQ{?>rWz$;<&HrCE zQKrz`pV^(5LUVu4{O>UHzr)P`4liUHzr)P`4m1Bd%>3^#^S{H){|?V{ zc{BezJkRCL{O|BQw{PZuhv&IJXa0A{4$FQ`X8w1W`QKsYe}|d>9cKP_nEBr!`%=@3 za(UT)nnH7VQSF;Tb9vdannH7V*#MhDb9poWJIws=F!R5|%>NEE|2yPtPya=k{~fY_ zHihQ$vNt$|=JIlKD~0Cra&jw$=JK+0wjY}L-(lu|hn$8=k@NqT^HC`@mzVQlDKwXt zQ(`GJmzQn5DKwXtb7LtqmzUFHDKwWi^S{H){|+<%JIws=F!R4dPG|LBl=9A7fJYY zah~Sh7w2ilcyXRSF&C%ln{siQ1R577X~uYQl0GpPCu!tApQL%+`8YAl=c6={J0GQN zoDb75a-RQm=T(vhoS!GQ<@_uSx#wr8a?Vea*x~#%F^}gbiIqM-Nt2@Ulhn=5Ptv$? zew?PYXH8-s&YDykXH6Po&zjVrIQ!lEWKyR$>Fy87y8C0Y?*5-vcYjpY-S05E`~O?r z{Xeem{y$fD|F5gN|KHW!|MTkZ|9f>8{H{w%*cnPdT;?p*#X!ZSR#e-`2yp4&f*@eI%Hp9Oh_ z=l0K{Ji~MQXJMY7L<5`zQGx;Yq-!yD0xS_y1v%@fp7;f7-`lcv1fJ9W%Trf0FbW zUX(w{`V241pQL?;7v)d#KEjj0Pj^xNG-?}Ow0{!%8D8}NB=$4B=>JLZXL!;7ljzUz zqW>r1pW#LSPvSqqll)J2(f^YK(D0)DlMK-CqW#lc!|WWbrb4AJnS{gV{Y@S^>b9MSNi{gWio@S^>bEYa|y{gX7&@S^>bJdyAu zP}E(te-bGgUbKG_DjHt2e-bMiUbKG_EE-<4e-bSkUbKG_E*f66e-bYep5%+Vi}p_v zM#GEtPclZsi}p`aM#GEtPu!Q`Mf)eN(D0)D6C-GN(f&!=Xn4{7N#00!5;*EE+CPaL z4KLb12>=W)+COc(F}!I1wDHF9qW#m>8^eqCPeKI4i}p|3ZwOEFN8LsHCkdqCMf)ci zq~S&TCzjaoqW#l89K(zDPdjl8FWNr|J`69~KkddbylDRo^a0Ri}Dxz|FGcyhXwyXEcpK{uq6G0|IZ>z!;A74{Qt1v z|FhWA=Zo?e{Qt1v|B*1}@)!L7u;BlP1^+)R`2Q;H-#M97X#^0;h=S%D2 z(v#VxsuwO*q9Wdj>Yr+<8r2Z^G%7KfU8;2&g%=YPE^KGqwFon$R&)Tdh1$>o7*w>H zM+m%m=rtE12TmT*!KplW6h1tU ziWhPfPL$Kkjz*38R*ujFA=7?TZ?E3Hdp8XfZUoFPdi{dA$3Ua>2W1|2v)3yW9io~7 z&DJP!z=5vcQ0CE+s0-&#s?NW)UalUwmIx&}VPpMj+P|vOM^0j#6 z*W!_1i${Jf9{II+X9y;|G`@7Dkt2JK{ zU=w&F$?$;&Q^c%cz4souM{ll@;O`i>Orm8CcSrv2U6MG_il!!Y_p z!|gB(-TFvkA|$-XrWXwz(wRFYsEz0Inc{Qq6%PCfeo#{8khUGOn8i4v$QhV=RN zYW9vsn(_TdPusmc0fmwDxZhC;i8fX4pyP%Lz5`x&s}^|sn%4V3>G7Z3_7)FLuh8z- z7zA~={v(|BH@#6gx-f=0M2izopnkR^TYXTicdHMorCX)5E!}E>l>P{y1(sU9GPlu- znRih_5I}|RWn`MH_y+s03R;14;Y^_as-P91|6VZ_0;q~Blyn3BlRyE{qzIsf6NsQ+ z4EjY+AJjj*^))`<+r~c7{E9lR%~x#hq~;H%?OzuSfA>6yCD7AQJQf5Bm|Mz>GhY&D zB~;^a<0LaB6Q-q5MGCRt#=_S6frH@1;_ea^rCbH^9f#coMAIEJFG$pS$4#IpfW1Qp zEEbB8v4TcT;}v&~Ts7zx4Qy6?)^VXyFD&wh7F~0N)hRj;I(*20x2ut}dULc|A91O~ z7w9o6*i`S_k}3+{QO`kK)|*LqwO1AD7tBUIjvy`tu-vHcp`ud)3a+pn?xyf6@; z{l=7!vChjTj~Z@}eUg0gieXg@Ue&)a8S>&WZehQeOZ1M@5zPnoU>eUz(ht`c$;H#u+t6Mv)kqQ`fkGR2H`v}eAt&h}~@bVkb z210#qz5J_oevr@MIf-GwM4*1OUi|6XXk1Q7XL;xz>Rjz}myS?AcKPr}YkOtHj{2)5 zW*aa6J<#o=6nEz<8Jy2Vb+H1cg4t0Qt2hYUUdf#SJQFtuh>|=hcLwmJ z+!?@waihSLacSyZhX7`Vnfy6*bmCfzJE0aZ+bO)slo4v`00m$SWQ>~rvYn#)a|&)z zoh_%LMWPQIE&{*$)auh#t+>?m8GHk|BEg5%pBS`&K20CKPEqJOMO`QAB6$YZV1tvJ zPNokZrVorFfJrwWrw?Q7_uT2R8Kb7$bfKE|57N?YU<7c3;q-y@f1A?&Q?F?PzD_rP zPEi2PpApMzwz0Ur+M5*kJL2GLy?(nM$6W)-`4p~D$lt2!&+Z7`KLvpYx+mjBFz8%! z${W$Kigv~q2*y8Avc8Xhcu-tN9rxVy9BmYeK+GQu_ivj=#)2S@x_b>^Ax_1vfMLg z;l@fSouL{Pn@gv>(=w>LM^Z=0I;k39TogNk^}F#mE$H=oK3{aCHMfK@P=1D(m~p0( zz#L=ktx*JQe%GUgc|=#g@CCD-a`7Y~tDRQbDffZ-2seWHgq8>w`vq(Cj7DKqMUw$; z<+=RGf0lQVD`qiMwC_&&#!ZAz!6Bz~JR zm4ekqaqpB{oEAr+BR$CQ_yP&RrC|VO@&i$X?^F5YbT;B%5njOR?R0jA`L`*m-lt9s zrf~Rtdct}Fp_s!147VW0*J)uGR;ElCr~nk8QzDRh12tZ|)X}YH?Q9^t7^xzH4wLnt zkCxr()$^3EkFk}~Xi-Q8UBP>fw5%ouL;vJjfiI9Wqyt|27*S(PX$O@URoY=C#ue|K zo_g;zz(iXVn6!%F&D>QQ2;cAwKN~JuF7BO%WX>uAOb`Jd4?pIx+*OB@>zTb<$ZO-U ztx}MQYiGacq*1*;88ygM8Z#^Y!b+X!99kcz4HpTZ6&B^Ui=R8k?^EP?i)WB|nEel8 z{z(j)KZr4?bZV^e-t*RK|8aV75z@5zI#nMtvt&3aEuS5I!;onQN;L9L8^p|0?_!!> z+M6!P-N^sjXx2P?lQtzCS@0407rks{UpKG8hJGOPKEy1BtorZl zs1Fe20)6eiQFZMP<{fqD;S80wxcKPn>7}z+{5_bnH1DVNA1Il&ukhtS_J%cn0w_Se z`fb{FquP7up{W=zWdfct@wVt+&|kP;@Do=J639qZ|8t7A{`W!L!PqPXE#B(e_K>8d@4S>(t+TM~0Am0`N zB>R9*Bf|%L4p}eYbI5uDpHtQ=3O927CU_6Rv=0Z=Qf!U48_ccYJfS4Sb&PU7f#*zXROw zj<4NWG;n_Z@EwcK>54)?#6Jfjv`J4G*e2`$oghHHce2nCFWO8IW?sq{wA!e7tKKMg zK5D)O$rth&;yZ?kDuY=^@Vo-^sF<}^c#jFuevftkcr=;4<+(QT&HYcw2U9`^x3_#q zPy!TXzY3OA%LvS$7&NIi$sZtU!$Iz^sI@OGzZOU%bFn5;0sf^@H{=HvP?8IENNjx{ z{E39V5zCCOF|-hK1xEwyvF*-9J`?0m)(283zWZik;gwxs@%AYbS#Ue~HX&}@l?p;V z-0v!5M}E+gL>D1{=ax(75n7D@_+oztxrmFwAA(L0v6;tw!3kRiq5@nbBC`NMei-ZW z^8`5x5(F(ON1+P9RacZn`)J&7gP-BlC7%YObaO)quC-=FgNiqEX^Iz-UH)j_o>n@U!iclZT5XjI(pIU{@sl?$&-EN=0u_} zaChX6IZ1WqOo*=kV9MeIGJtkegOO{XPf31x(1nTDI#y0OZvPQGe`^16YEWV z>rn8U)_mBnt+nE6^PQL3Fbek|`VPr9@^>6uy~>4bx&s%K(mQ%!qdI~bX>aWbi=^O+ zfiD%d@@ z!@}V|BBfSqol5GgVDfHVze9e__W>i~S(TfIfWG?;q;KF!<% z@Hu83fX^}O0DSHwo@4F->2t?E$E*YJIc6Pz&oS!&m??>ZPc!QPe2!TM;B(A00H0%y z0r(tq48SM616$lS@9r>s2Z5L7k-M-NVeoovUNMe|LB#T7>p!jEHHUkPi4-0&I^Q6@ zdB$hN9Kpx2|7srb88wgm^JgR*0>0+gd#`9%{FIQDX09K1KZN@T33N*!hyEz_1kiQ3 z72Dp9qv0wG2KS(lQ|yTM&965kWf%o=slcYGGZ0ueGY z6hv~!pBj8Fy_vN0+R-m~d)0{-OF%M5M_vcP>%!uXVhHmyZ`1xMAXuPIk;szwt)C+< z&VFg_qdF!$;fs`x3RqqKBl9RyJNuYb zZTIANDH;-_X1%%uvgT_P)@xwUUz(dct~I0a!+vRQSo*>-W4`D50@S!>Y@(*Q5QNIP z*N-cK8QFXY7FX0Gv!I5X3!4@7#w{?+H7IRMJU1)uPKn!AUPx>6Xz|0Q z2DAfz`kDtWSi2)l?{i_=#pF9kJDpzP`VQGi;+qu(jpuI(TE8|3v>+(eDlXw|yBVAu zB6zMfS+|#jKt+Pwb)qlQekM#%mrh3gnnQB+I;HQCoo75qi>~U;ue24G0&(8Fyt)7B zRcUni-^1oJz?I9_pSU$`vu1_HY%WI&K44gU=lB=4*~2vs`G2!`T-H3zSEE@_x!#s; zYT9?qyIO*ha8)+N1OfjTyGc>&YCT_c)LbXu+RXVN$e#Z$GGSL*aMKEtyV<2lOT#;S z=_uanvI42_8MEVt{fs3SvTf#!G|i1-Ge`_Iix`2MFQJjXh!pg?p`Vy@=O2_x>t~?T z_0B(L?%}!fxq5A#?E`%Icf?Eh?~9A1qCx8PuZFE3yfXgB?)YfDc&xc%blEo3M{>!% z@=-SC*<5Z-RZRJS0^4Rcl#*W}GuPmvx~6GI*)e-kysW07b+)w8wy~y0T`1FlX7j?u zI8Mg{exO~>yTUPRrRc%Jry!feO?8nbRNe*89mT+w@f zA3xHrz{fG)&Fz@$g2%oL)_?r=Vfpwpe#Qj`2x^z)q_fX$8MwP`3b6rX_=@7d74&KjWT^hEF)_4`+B z-%#_0SOgC11)R9}j(y1n0v`&Zv!8hJO75S4j(Y8g_u70~BR7!y3+DAFwz*o9sWoqR ze+I;;MV8@pEE+DX-#lD??i?hv4}kVbLw-*8`GMNS>+D_4aBuuBPrJG~J=>>ss2x0auY%8M^L)0?(4mG-_f-US zNT-*nLoFF&pVW@%?ABs1k5`@SGReT+dhC)u+1D4;F08Y6**n?S7t}6npTHq&C;R$> z+QsYaU45PG>kDcZwomI&Unl$eg4)H~XXsF0C;R$>I;7Lf)S6SbhqPO|6^*~WPc;Ek^4(aqV zb*MUH?33CNoxSUS$NT;VwF}#)d+2}1`~C;Di?`3;q5mE4`ybRHonHP9{m&Ttq;|x< z;tu`qc;Ek^4r%r(@6i8@u}|udzg`6%`X6z7S+w4E-N%4^Z5(QG-~V`W_ma-ujeN)Z zp$}>ow$Jln^gG@Ue^9%4`}`h8z~lW82z5xOm)FB6XpDVQJ7Qm-hmr7jKNLb8((Kje zVKg+xKB+_gdi8l25sBN&V!u8O*w@CPKJnhCy(9J=^Dr_V?}tXHLws77&^N{x8uTK0!Zui3_`RdoN zj>BvFIZjpF@3SV*Px$cop4t(e9hRWHZ0v?*V7+863EvGkOK$<8_qXvHX6S`AU<55r zCE33iSbv9}IU!%qiGhU_7+{(#|HEyc%!^G4cf)ItL;-NF@=5EQo@#<;J`@W9ZcRQA;Lb^C!xbG7be2%r4F*9BGdg1$+TbbVyO-sZO zVfOCb&+!aqXZDt5v}Y_X3`QK#5ii;lMC_OxNOzm*g>+<3bRO?p|JG%4lo((`oEP81 zn%{pL$IjiBV}k5Nn}k8bZew$6GRs8pKOHG?!}=MCvvGIRWl$cB%r4off(;inyHiLS zu{h2|!Vm0s!S{Cz+XTFyI|6GM1(MoKDK*PP_X}!3n{wA*b|fWdCn|}Cqz;SaIjaTc zE%1}FpHcl|OqXDXW^i-}`r%zj25BLlJBJ0?JC0k&PK;#8ct%DL?N}}|(2^z_PyROM z#_n+|;p^;=;ao1)6c5QCJFLR~3c4H0dB+S z%ZJ51_0Unl<>Fu;3KhvZks&(lA}*(liGhSDEK+Lj8ZwSxZagCbTaf|5&ZWHu1Vx4spO*Rflf0RAQHWEx+w{x)_aG!TB_$;Kw!{%b&i_qR?Yh0^4X`?Rs)vs;^Grf>_y z)vEnFVhP)E^X}uAebvaO|Lp8nE^B6Y%9#De)FUE5#H}Rgq-}lC^2?KXEZ))FAhw03hqGYZRwcbenhn)Ef>bV9i|5%r73p0v{zP)V z?UKa>D(P~D(8tVPDloPjm-Qp7G~t=IpA!Y`y**3X-RgBMHio zz?PQ8gdbvjDE<8?j9F&~^kb15U=x7Y(vlcEef$U7t{t7W?XJ;Zy-9pb;|r9WJz-;_ zo47)$akmZ&VKj$;F$<^wRX3*KWA=~-c@+*GLF_t4+yHeb(WN5t zcE5x5&C!iQE$!JSEl$>ugPWt#1074d!TS%kz1>q_R`hrV@|rBTF+vo02mAe{T-6QR zrmi{Z0Pr}Yt&7neLCP`w#z@WTnlp_UNj&pmnL>I8{(y{hSu6_w`kvC_APxd>Al^o6 z)}Hl11nFmTM?)bX2i&d@)^`sj#2c_ki7(b2+lS5hwEmZ{h-#WzKNKqd#B~E@8&Ko* zomoX}Cq@q%T)ZJ?AjJkJfiyBS&w!VKG$}MM0tIGf1N2+~G|1qB_YE${`T*S(zyLst z1W*Y+;aqNjW(WYex+wVEIp^<1!Kcp$>4@XbFz^x0subYN`NT%94i3;tInd})2s&o zK7A7PBatOSf*2>^UfMqlYa;1fvy0iQtn5BLPq|FLp^AWDhc zAJXTL`vX3Q-2eY)?oGh0D6W3*gBne6iX+aVMvViydrusvX!kz*44lz3fRH!9_Iyzu2 zPe!#jH?nb;7FR3P-DRYFo4h4LSEx#GvMyQdq|=w6;-Zzbz9^xyZ7F5j{G&&rRGn)= zWmF1W^=WImxfEH)H9JW`Prwx9lM(uUEnTTAC;rW=GgG01%XvBdLI?jHbW(z^*R4+6 zBtx#GJ%zH8TSGbvtvqWUKS{zryxg@Md%Cs1Y-;ToP^@cxij?PkSh1tvp3icM#=3K* zWm2;n)XWAoytg^R9vZ3 zoLqy-&fveL>=&eNfoCVT656P!z|9Bz|BTBO?#9w`rEAOQTCPpIv@S(ORdtf?e5iTl5>TUPr2u>Rdq{$Fvz9d=GH z)IG@}TF>c}Gd$i{|Gin`)Ph^o!c_p-7I*rW2}FoZT=|lcP_dPphe}x;cV$;2^;NnD zo9Eg3x4JW3m$p_)L$TVWDsOG(KR)^{MH;yClA;9o|2%@{7CB~0Wem@#Ek>g8k9r<^ zP_xmv1DwlqMLw;rmQq?r!u42DKS-y$ILGPy`&=7pYUhqlCB!SGZAmNjXO`+B(6t+t ze_d(0_JX_rlO5&Kay7zZx4^Zg$^E;gYwfO#R-nJDgOn6@gIiE=_O%sx+)2OJ=B7U7 zTXnT!pAPO0cMA#PN?+CoO+A!CX=;c5S4>jV+QC(v27`4|uvXJOtNfEl8W)z% z5blX%28vXxlsYAJJ2PKZ*J_m-DbV6tu}JYVCi~ugHEei%w=+W zuilL1__^LDmp3_n;9k9~$z@DVy=KEV;K03H%Fl6<^~yNg`Z;3@=U>0f*uuHkFEh4q zUiQn3E!>^vm2vX*bH)}<#D1Bvg_E*hW^Ca!?Uxx_IC1-B#uiTHUK!_fKWA*=Ebo^Y zTR7wUWyTh+0sJy!3)cf)85ahA&e+05f?sBA;j+OmGq!Lc;g=a(xU}%gj4fPjcx7C5 z_&H+>*CBqHv4txWzs%UewTfS6Y~kv~E8{Z8&ly{|r18s)EnMXIWyTgRd;BtEi!OvV z{Em3I(S04H~-&@c0C$@7{+zs$EK&npi7GGhy`AN0z2`JkUO zw(#OXzs%UeO9%ZjV+$`F^vjGbyll`b>uqdd{MRotw(t@_zs%Ue3jqBxV+$|;^UI7a zy!g*6hAy$?=j|zs$EK#|vitGT#;^2Q+2AEjeB+>(w)UH)s5Aj#s|= zYZ_a4-K$?_Y~fX}ewnd_*Sz{=#unpu^{;$yO-`q!Pert!NuMuq$`V+-R%ewnd_kt4s%*uq$nS7!Wf&iGx;P3f;`Y%zW}XRdd1 z#_#6L^={7i-JH4J%^AO&Gk!N`{BF+p-JH4J%^APTbd-J@jNi?f>s@B5^w%_gH)s5A z&iLJ&x!%ngzne4HyPBWW+n?roH)s5A&Rp;2jNi=}zsnq%{x*%@&6(?6rq48M8e5Ft zWoAvYrr9sX?=tD8zozlKIdi?6Gk!N`u6J|B@8-<)ZqE4KoVni38NZt|em7_QZqE4K zoVni38NZt|*Sk66cXQ@?H)s5A*7)75@w-`by_+?DH*2nUv&Qdc&Gl~9_}#3z-pv}n zn>BtnYy583_}#3z-pv}nn>E+FS>t!J=6W}4{BG7Lw4*7UOqy&xT*-p98YS?`DnP%^JU(HGVg1{BG9x-K_DuS>t!J#_wj0-_07on>Btn zYy583_}#4WyP7@NYpwCSS>t!J#_wj0-_07on>BtnYy583_}#4WyIJFRv&Qdcjo-~0 zzne9FH*5TE){HY`jo-~0zneAJyIJFRv&Qdcjo-~0zne9FH*5TE*7)75@w-{$ceBRt zW{uy~1kc_PGk!N~{BG9x-K_DuS>t!J#_wj0-_07on=yVjWBhK$_}z^0yBXtmGsf>` zjNi=|znd|BH)H&6#`xWg@w*x0cQeNCW{ls>7{8k_em7(MZpQfCjPbh}<9BsC=Z0gH zF@85={BFkh-Hh?O8RK^|#_wi~-_01mn=yV@_v(4J7{8k_em7(MZpQfCjPbh}<99R0 z?`DkO%^1I%F@9G!sd|`jNi=|znd|BH)H&6#`xWg@w*x0cQeNCW{ls>7{8k_ zem7(MZpQfCjPbh}<99R0?`DkO%^1I%F@85={BFkh-Hh?O8RK^|#_wi~-_01mn=yVj zWBhK$_}z^0yBXtmGsf>`jNi=|znd|BH)H&6#`xWg@w*x0chko2rj6fC8^4=2em8CW zZrb?WwDG%X<9E}>@1~94O&hKzoZTzlo z``+*?P8+|QHhwp4{BGL#-L&z$Y2$a(#_y($-%T68n>Kz|H=28v8NZu0em8CWZrb?W zwDG%X<9E}>@1~94O&hKzoZTxQ9_}#SeyJ_Qhb%VS2ea7$VrgOi{*kb%{+W6hH@w;i` zchko2rj6fC8^4=2em8CWZrb?WwDG%X<9E}>@1~94O&hKzoZTxQ9_}#SeyJ_Qh)5hMGJZEQem63HH!^-VGJaRjym_`5zsu8Urp(x4{BC6YZe;v!Wc+Sq z{BC6YuAUe3Y%zY9C%a6UvBmh^$oSpJ_}$3(-N^Xe$oSpJ_}$3(-N^Xe$oSpJ_}$3( z-N^Xe$oSpJ_}$3(-N^Xe$oSpJ_}$3(-N^Xe$oSpJ_}$3(-IVdWDdTrj#_y(#-%T06 zn=*bkW&Cc+_}!H8yD8&$Q^xP6jNeTezne0CH)Z^8%J|)s@w+MGcT>jiri|ZB8NZt{ zem7i%wjO=FAkySjo*EIXZ_+8xq?yqU~i}Aab`Ps zP2+cUr@3Ed_KWemy8YZ=)9e@HcXemFzoywQ#_#H;b#G1McXb=PUuO1;@w>Xi-Cxt} z7vpzz^Si&M*)PWL>V0wEn#S+y9(lja>=)yAb^E-(rr9r^-{rPcz5c~L>f}^C(4^aG zS;{j_x}Q~=dnin*Ua{^{cfT?Z{OL|oUdqJ_D7n>@XG(b0yi1*2gsNMtn;Vnz&9PFt z?$~YQ)@fda-l(tR6{C{8%}RHz>n%qJZeHcV)FQVwcIHQ$>Bk&t~>Q0Rm+`Rkgk?aCXMbSg4B1plLpe&(n$hc-{?*X zNZIU80*%i3Bi%R3y`wV~s!N=7mF3MTa9=F%jqbi!-n!9wX{7sNd1Z80OV_*Tu9mKE z(OoV1)kfz}k#2o?OmtUE9unQv(v>K>t0fQE=zJa0)si+z6QR2` zb;XD7)|aP2ck9c0G&-+=bnDAYpu6=I1*5z5b-mT-e&I;Brhc{Pt~6ryOl6$W`dOm8 zFVN4h(f$08u9|*s=&rKs3wj_$OH`|~u(H7GbLnKg+yj050Lodth_#$q&9bDeQ<6D; z+>P?6%0J4(DE(F;xMiMvGcR0{T#Vo~d8$Gx*`{BR68BPQr@2+zmY^5v`_+|{6$Ktz z)N=s5<*oF>X0#?vFr?Jol+Tll{QUS4p)iYrTerGeSzhoY$u^3b48$e0k(|Wiz>VlK zllQRm3PzsU(5>yvh}7b?uXmnnIls~dp2OiCZ#*8?pcQzLe1YGxp2Wa9IU1Dq{-t*s zc4s;#UH^_zY1R_tx zHSvaYnt&tX0onpj2FSL$l?6TZqsJ2w9fe+cSfr*jiBf5Sud{~xx?;y;6v|GXPDFGT zYW09pt)5V-b&n_^rBYhkuP>rQ#qRMSqKgjR6R@3?snrI(gyG0)2*fhTf!K!Ld| zc&48m&oR5Dr0h-djf*5D*vDGJL$Z1qR+qMh_r~=nr-xLSn^1yTrc{eZLfRUcsROO0 z{373)iyhUE7sEvwQ{A*cGXejyZSxMd$Mhi&YGKu=-2z^1XdZqQ+ z;ibHiuG}&f^6Zb>s(t}Ht6Qk0W@+m@Y0AT*+GWMQB^#CUMb1zjC3a^YeyXyY2Y3;! z+RMCv^F=51%sR@k9X#;77)864monlqctThzvqzBNEL=%lJ-S=KbULz$XNGAsj|J;D zMye(ki}m^<9xs-ZpaH90;xghMG?qHi7VsnZsD&34RN>ZC}t>9vNXlrErWRwdU; z)VbcF)Ma^NuzSQr6Jbd06(#9vyqC$lZF%K*QBz(Sjp9Jksg7zmt`>aqEt{c+HKJ@D!GcRe3$@s{y1oV9JHVJ1=#He?T>@@$3gq!p#6sh z?LRDN|6xJ<4-49VSkQi6z(0)Z&raWlBqAtI@ zGH8Eg(EiGx{gpxcD}(m)6uaGi(0&aUn(q(VuOUNI9<*N(p(zjAuc1Rz9<*P>hkiLP zNU-^!{k$~6mIv);`W#yxv|j_1=KF&7Ymm~E2kqBDr6~{EukhBC2klqLYs!Q6=Y#g= zgZAfx_UD84=Y#h1ZU*yx3bXz1*RZI`2klo7Zpwr9D?B&lLHiZ5oARLj3gi9qT+sep z(EeP|{#?+04LF$X1?|^>fhiB#uYZD>@}T`1UNGfB`!(cX%7gZ67{ZhX?av17&j#(! z2JO!V?av17=gk`C`!w|7f4_!*O+IM9hDS_!(0&b^nDU_g8VWY$LHjk>;+JQF_Gg0j zXM*-;g7#;E_A~i~-G0!14e*%n58AImA5$K*Ujsp=JZQiE?Ptn^_G|FSFHZ;UPY3N! z2klP>?bqm$*=?M?w3U z*2Qcu3fj+0WNdlRehsbr_Gm!PI+aGDb&nu6rZTq8Y z+y1E9wm%Bu|ESuwKdQFvkE(6^qiWm!sM@was@kU+OPi? zoARLjLHr-}4$l8U{2%f9M6mS{w zJZQiE`MsgMvS80IVf@h{}f{v~g&FUXtyOWy2X z@@D^%H`iC>P5&Zq_AmLM{r3DqdC-1)exW>QzdgTH7VPQzdgTD9<<+{ zUnmdSZ_h832kp1#7s`XU!(0+SQza3wuJUIUL{6cx) z|LpiO<$?dR{?CptQy%y~JHA|5u;a_*gWta$U#2|x{oC?YHC0ln3p%|Qy#S6jxSRlwBL>|R~GE}GWnqWc6^!gp#64ynew3hc6^!gp#8ds)o;HY zUuONF{dRnr@}T{8e3^3F{=|+iS0;9RnY?X(V#k*$x9v~t_%h|T{fQl4rrfqavE$2> z+uwg;$CoL$zyHLJFH>%R|A`%6u4GzYv%i@IILHU>x8uvy587|Xmnje0Z^xG@587|X zmnje0Z^xG@587|Xmnje0Z^xG_6Fa_4K4`xkU#8spzr>C&Q*QlVV#k*$xBf4&)Ta{zV+ES{FdzQ~V+7>s~GhGyunAR~P zTUl{Ws;y*Uy`D^DV!<{Ql)^tApVM`4O`pz!p2%aq()JD#rpI!U8C?52g~#G}N=?tY z>1n$nb1%8){`|)kgN5bC61}DFp~VgPe_NsaBq5t`Vxm$#_m0xaoS;ohN*V#aTe7&6 zlyapq<}DmhddgK#9WwPObE_2_+UoQyE|Z8Rn$lA{glX2=B}MX^3r0rlyX;~MR9+OFHg)_h&fU`HjL05#H&bnQd6yqJ2ai9OOz>S zUQHE~DLtqd)A)ET%b5rptxfZ@#hRDSt=HP#k7plws+dO?TkEQ7w2F3D+`0x@^#~&g zbMx{Qtt~nfFQPmR&CIy{>0#Qq$vw17qFOxH8EZm9-kL!F zMKYZn^A&1Gbm`BQ)Y6hg%D7#^)U+~-WW)B+ON(ftENkT9Y@VKt8=H7snfZcSb%03N zN~2q~p}&?i^k+eXj+NfJ5cAkJ^L{d!sJ8DE+TOsNf^ME&sVuK|+p1?b(TQT7r;Uqk z9c~#@#}(C^<0`gVXm=_T0``m5K)nS*M~9%krr3)gjoR+qLaYrfVz4pWiO5K#B^Yed zB$EaAG`}X9L}P$UlT0FV5~?Am?Vjj&@7dsaej4VU>ep103{k3{9HV=IhI^o2lT4CT zy_8PDNPbvI)s)Y35BW3qnqH4lUB}Vtr7MqKn2-$UXj+;Ks9m1)Z(ox1XVPS*o1_aj z_3B{1@GgLORdQTSXTnsHNk5v1fVea1=xEfu;7Lb2b5NI(Rmv1wtC{q-q>-#mctm&& zLP}eICbMKAvn2A2aniwG>$A{W*WS$H)-+-@bH%DY&vzqQ5X^Cmz=n>-7PN*AsSO=V z5e;p{{@8=UrWzV}1YD*#1!EdC@vBSta{2=zLDXyWJYY?SYFn>$DQva2ZgJAVI|g`S znUsR+>X^wT6JBbNbQJ38vP#^h6MBQTp|q4NNi>IMXVO+rOWNw=DM?!u?PRAeWA6EW zs}RkNoyevE)M(|&bS=WAF$pY6yg1PV@7kK1*wF1KCK#;dTa@5GTv1ic67p3NJnW4G zP9$23nXh~CMg;i#x9_OoP_|Yr!f7|*Oz9F% zQRAFaN~j*!7u0ff4N2_>TIbRtwmYRGoBHF{pupTfgowzY<1 zyy!w|>{L2b1BZ~`4YS2NwYs@^ty6k=3+X>}DZL566?G=+=XLt+caq5VI-E&eJFmQ1 zmDIJVC)Tw!cCi0RbP|zL+x#?AbB1gEHXLtKC-1=3LM;?;(x^3^)cxQ&o#sd@%BRf;?RNyFf}20VBCWKzf5M6@;svySgqCu3?# zCfuZ`Dz0b3>ZDGS?DA`*M4FCKNl{vCQC8E#GKngU<(Mx|xBy8s@jU|AJnvVaU3$9# z0(g5t9dnX4Jd4WFq+isxb<|Ul3l2nQQtZ#f*d%m7e#otyTDp`aNwFOd%)WH#DiStb zY*(fBMM-gO!hH4|z+!8C+=SO=E_#k3myQWD06&%#aX3wsHnl$`!O|vbG%-i@auWWr zAt|vq!6j)Tc?4^y^Ko9*(IU~pC!wajwwaCBITP>~RH`k?oZ8|t1PTd0l=(#2!A?`> zKw;a}&8-+xbU#fJH9(d!y*!sAN+qbzRg}D4>2)nGVJ$8|=r1HHXw~nZM7qj!z>yM- zu7v9z^ujX!^FZSYxYvZ2n;@v3@J15^@In)W7U``fk`gL)r=ik$2&o02Qxo1qLhEQT z?}R}pr?;<2s#tGSk(2;e;ufhtByuu|+L6RsO+BD|wV81FND03utmBu~&RcerGP!x1 zDxgX%gLnm#j<>05TiYT8{y5>X2d%cgZnY8>xeI!wlyMB*NhId<7Pqp0xYPuE5UnOH z@`4eUVxzKJ3s2#44MiE$TGzk1nRlj0O*nGAa3YP4!fdw%w5Ix|W*mU?EOIO{)5vNu zhk&lh1nDHI(KIuO8*!d8LMcfDm(xlbG&k&8DcaFWN}1-S@~em3GIG#907?;Zr0hRXyvG?OzZHHI0)HFBp4i$X~VV$fX!45ULhI5VV)^!2%ymQg5YddXD zt|(?6_at7*KRuYDyB+@!bGfd4rmOaZuEiyyuD(f~UA)eS4oXR(zOBWb38nGEA$?Uz z;|My1*?(1C?@DoLFD|vqi?l9#Q2jJcUZj__x@)MIHybfrlj~#*WH#d-^I#Utgc&fM zu@CYY^bC4>4oqjfVFqIgb72-^35RteDkV6JM2xK>*q~k>i_jV~AyOuV$SnY^&Zs1U ztuXwE(Ao?%A}}e+@eK?kG8CchW#@nvV^oAuQHBK=rWc$dScr8|dOpkp3eyy(`Q9{T zvN(0vN{Po2mC`Du^_JFKT3%XST25L{8e2)t2DXx#&KScCAmyJ8hstjHcqWN^Z?7dW$H94{=j%QZvWFFoAULq8h*cw2 zjaW5e)reIiHW{&I#G1q(2)0WMf?(ssAqc85GJ~LQiZO0U2{uDyf?!)jCkQr3Jc3}W z489;{!~+H_iU)Lb#{CoEcNia6?2P*jfaBm;P`&{1i*es(Jb7~`p*Yvst4KISE{Xdp zh~s5IaTAwy1ea~n!fo3zmysw+`N7ahl3$Hh!hugSyFIO9KtsErlK%Bh#8{6>pc zNVv=Gl7c;4wZ`pD@v@kgUU3#+gKANGol|KfulvILb1kNg;<@^=3#v*w?=vj0OWJFD zQ9y*NJ+0EDy>=Wj<|SO5opq$tK&P;MMHeyWJsm)&wDs2;*c7+3 zSc{4+T3-jgwMy^WYGZjhqfr{SH4S6B8cx9yrH_#;11h4@JGF!!q(+nUl08cGB}$9@ zbW2J()wghIhM>({nHPBfp!&0PHMdtQ*FH+(+Qw2o=4zUqaBK$+Q

    k?H*n-3C46sz?P-9olb`coxo*Q2(t;c8 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%0D`o0>E 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

    D^9al97PO<}rU_UxLN#9`EFRoZ)Kgl|2 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

    Wr#0N^pK1BwS8!)rj>fuC$g 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 FKL9kOCT0Kt diff --git a/python/LICENSE.txt b/python/LICENSE.txt deleted file mode 100644 index 0e704cb..0000000 --- a/python/LICENSE.txt +++ /dev/null @@ -1,650 +0,0 @@ -A. HISTORY OF THE SOFTWARE -========================== - -Python was created in the early 1990s by Guido van Rossum at Stichting -Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands -as a successor of a language called ABC. Guido remains Python's -principal author, although it includes many contributions from others. - -In 1995, Guido continued his work on Python at the Corporation for -National Research Initiatives (CNRI, see https://www.cnri.reston.va.us) -in Reston, Virginia where he released several versions of the -software. - -In May 2000, Guido and the Python core development team moved to -BeOpen.com to form the BeOpen PythonLabs team. In October of the same -year, the PythonLabs team moved to Digital Creations, which became -Zope Corporation. In 2001, the Python Software Foundation (PSF, see -https://www.python.org/psf/) was formed, a non-profit organization -created specifically to own Python-related Intellectual Property. -Zope Corporation was a sponsoring member of the PSF. - -All Python releases are Open Source (see https://opensource.org for -the Open Source Definition). Historically, most, but not all, Python -releases have also been GPL-compatible; the table below summarizes -the various releases. - - Release Derived Year Owner GPL- - from compatible? (1) - - 0.9.0 thru 1.2 1991-1995 CWI yes - 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes - 1.6 1.5.2 2000 CNRI no - 2.0 1.6 2000 BeOpen.com no - 1.6.1 1.6 2001 CNRI yes (2) - 2.1 2.0+1.6.1 2001 PSF no - 2.0.1 2.0+1.6.1 2001 PSF yes - 2.1.1 2.1+2.0.1 2001 PSF yes - 2.1.2 2.1.1 2002 PSF yes - 2.1.3 2.1.2 2002 PSF yes - 2.2 and above 2.1.1 2001-now PSF yes - -Footnotes: - -(1) GPL-compatible doesn't mean that we're distributing Python under - the GPL. All Python licenses, unlike the GPL, let you distribute - a modified version without making your changes open source. The - GPL-compatible licenses make it possible to combine Python with - other software that is released under the GPL; the others don't. - -(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, - because its license has a choice of law clause. According to - CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 - is "not incompatible" with the GPL. - -Thanks to the many outside volunteers who have worked under Guido's -direction to make these releases possible. - - -B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON -=============================================================== - -Python software and documentation are licensed under the -Python Software Foundation License Version 2. - -Starting with Python 3.8.6, examples, recipes, and other code in -the documentation are dual licensed under the PSF License Version 2 -and the Zero-Clause BSD license. - -Some software incorporated into Python is under different licenses. -The licenses are listed with code falling under that license. - - -PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 --------------------------------------------- - -1. This LICENSE AGREEMENT is between the Python Software Foundation -("PSF"), and the Individual or Organization ("Licensee") accessing and -otherwise using this software ("Python") in source or binary form and -its associated documentation. - -2. Subject to the terms and conditions of this License Agreement, PSF hereby -grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, -analyze, test, perform and/or display publicly, prepare derivative works, -distribute, and otherwise use Python alone or in any derivative version, -provided, however, that PSF's License Agreement and PSF's notice of copyright, -i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Python Software Foundation; -All Rights Reserved" are retained in Python alone or in any derivative version -prepared by Licensee. - -3. In the event Licensee prepares a derivative work that is based on -or incorporates Python or any part thereof, and wants to make -the derivative work available to others as provided herein, then -Licensee hereby agrees to include in any such work a brief summary of -the changes made to Python. - -4. PSF is making Python available to Licensee on an "AS IS" -basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT -INFRINGE ANY THIRD PARTY RIGHTS. - -5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON -FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS -A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, -OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -6. This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -7. Nothing in this License Agreement shall be deemed to create any -relationship of agency, partnership, or joint venture between PSF and -Licensee. This License Agreement does not grant permission to use PSF -trademarks or trade name in a trademark sense to endorse or promote -products or services of Licensee, or any third party. - -8. By copying, installing or otherwise using Python, Licensee -agrees to be bound by the terms and conditions of this License -Agreement. - - -BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 -------------------------------------------- - -BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 - -1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an -office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the -Individual or Organization ("Licensee") accessing and otherwise using -this software in source or binary form and its associated -documentation ("the Software"). - -2. Subject to the terms and conditions of this BeOpen Python License -Agreement, BeOpen hereby grants Licensee a non-exclusive, -royalty-free, world-wide license to reproduce, analyze, test, perform -and/or display publicly, prepare derivative works, distribute, and -otherwise use the Software alone or in any derivative version, -provided, however, that the BeOpen Python License is retained in the -Software, alone or in any derivative version prepared by Licensee. - -3. BeOpen is making the Software available to Licensee on an "AS IS" -basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT -INFRINGE ANY THIRD PARTY RIGHTS. - -4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE -SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS -AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY -DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -5. This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -6. This License Agreement shall be governed by and interpreted in all -respects by the law of the State of California, excluding conflict of -law provisions. Nothing in this License Agreement shall be deemed to -create any relationship of agency, partnership, or joint venture -between BeOpen and Licensee. This License Agreement does not grant -permission to use BeOpen trademarks or trade names in a trademark -sense to endorse or promote products or services of Licensee, or any -third party. As an exception, the "BeOpen Python" logos available at -http://www.pythonlabs.com/logos.html may be used according to the -permissions granted on that web page. - -7. By copying, installing or otherwise using the software, Licensee -agrees to be bound by the terms and conditions of this License -Agreement. - - -CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 ---------------------------------------- - -1. This LICENSE AGREEMENT is between the Corporation for National -Research Initiatives, having an office at 1895 Preston White Drive, -Reston, VA 20191 ("CNRI"), and the Individual or Organization -("Licensee") accessing and otherwise using Python 1.6.1 software in -source or binary form and its associated documentation. - -2. Subject to the terms and conditions of this License Agreement, CNRI -hereby grants Licensee a nonexclusive, royalty-free, world-wide -license to reproduce, analyze, test, perform and/or display publicly, -prepare derivative works, distribute, and otherwise use Python 1.6.1 -alone or in any derivative version, provided, however, that CNRI's -License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) -1995-2001 Corporation for National Research Initiatives; All Rights -Reserved" are retained in Python 1.6.1 alone or in any derivative -version prepared by Licensee. Alternately, in lieu of CNRI's License -Agreement, Licensee may substitute the following text (omitting the -quotes): "Python 1.6.1 is made available subject to the terms and -conditions in CNRI's License Agreement. This Agreement together with -Python 1.6.1 may be located on the internet using the following -unique, persistent identifier (known as a handle): 1895.22/1013. This -Agreement may also be obtained from a proxy server on the internet -using the following URL: http://hdl.handle.net/1895.22/1013". - -3. In the event Licensee prepares a derivative work that is based on -or incorporates Python 1.6.1 or any part thereof, and wants to make -the derivative work available to others as provided herein, then -Licensee hereby agrees to include in any such work a brief summary of -the changes made to Python 1.6.1. - -4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" -basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND -DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT -INFRINGE ANY THIRD PARTY RIGHTS. - -5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON -1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS -A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, -OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -6. This License Agreement will automatically terminate upon a material -breach of its terms and conditions. - -7. This License Agreement shall be governed by the federal -intellectual property law of the United States, including without -limitation the federal copyright law, and, to the extent such -U.S. federal law does not apply, by the law of the Commonwealth of -Virginia, excluding Virginia's conflict of law provisions. -Notwithstanding the foregoing, with regard to derivative works based -on Python 1.6.1 that incorporate non-separable material that was -previously distributed under the GNU General Public License (GPL), the -law of the Commonwealth of Virginia shall govern this License -Agreement only as to issues arising under or with respect to -Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this -License Agreement shall be deemed to create any relationship of -agency, partnership, or joint venture between CNRI and Licensee. This -License Agreement does not grant permission to use CNRI trademarks or -trade name in a trademark sense to endorse or promote products or -services of Licensee, or any third party. - -8. By clicking on the "ACCEPT" button where indicated, or by copying, -installing or otherwise using Python 1.6.1, Licensee agrees to be -bound by the terms and conditions of this License Agreement. - - ACCEPT - - -CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 --------------------------------------------------- - -Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, -The Netherlands. All rights reserved. - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Stichting Mathematisch -Centrum or CWI not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE -FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION ----------------------------------------------------------------------- - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - - -Additional Conditions for this Windows binary build ---------------------------------------------------- - -This program is linked with and uses Microsoft Distributable Code, -copyrighted by Microsoft Corporation. The Microsoft Distributable Code -is embedded in each .exe, .dll and .pyd file as a result of running -the code through a linker. - -If you further distribute programs that include the Microsoft -Distributable Code, you must comply with the restrictions on -distribution specified by Microsoft. In particular, you must require -distributors and external end users to agree to terms that protect the -Microsoft Distributable Code at least as much as Microsoft's own -requirements for the Distributable Code. See Microsoft's documentation -(included in its developer tools and on its website at microsoft.com) -for specific details. - -Redistribution of the Windows binary build of the Python interpreter -complies with this agreement, provided that you do not: - -- alter any copyright, trademark or patent notice in Microsoft's -Distributable Code; - -- use Microsoft's trademarks in your programs' names or in a way that -suggests your programs come from or are endorsed by Microsoft; - -- distribute Microsoft's Distributable Code to run on a platform other -than Microsoft operating systems, run-time technologies or application -platforms; or - -- include Microsoft Distributable Code in malicious, deceptive or -unlawful programs. - -These restrictions apply only to the Microsoft Distributable Code as -defined above, not to Python itself or any programs running on the -Python interpreter. The redistribution of the Python interpreter and -libraries is governed by the Python Software License included with this -file, or by other licenses as marked. - - - --------------------------------------------------------------------------- - -This program, "bzip2", the associated library "libbzip2", and all -documentation, are copyright (C) 1996-2019 Julian R Seward. All -rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - -3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - -4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS -OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Julian Seward, jseward@acm.org -bzip2/libbzip2 version 1.0.8 of 13 July 2019 - --------------------------------------------------------------------------- - - - LICENSE ISSUES - ============== - - The OpenSSL toolkit stays under a double license, i.e. both the conditions of - the OpenSSL License and the original SSLeay license apply to the toolkit. - See below for the actual license texts. - - OpenSSL License - --------------- - -/* ==================================================================== - * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - - Original SSLeay License - ----------------------- - -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - - -libffi - Copyright (c) 1996-2022 Anthony Green, Red Hat, Inc and others. -See source files for details. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -``Software''), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -This software is copyrighted by the Regents of the University of -California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState -Corporation and other parties. The following terms apply to all files -associated with the software unless explicitly disclaimed in -individual files. - -The authors hereby grant permission to use, copy, modify, distribute, -and license this software and its documentation for any purpose, provided -that existing copyright notices are retained in all copies and that this -notice is included verbatim in any distributions. No written agreement, -license, or royalty fee is required for any of the authorized uses. -Modifications to this software may be copyrighted by their authors -and need not follow the licensing terms described here, provided that -the new terms are clearly indicated on the first page of each file where -they apply. - -IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY -FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY -DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE -IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE -NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR -MODIFICATIONS. - -GOVERNMENT USE: If you are acquiring this software on behalf of the -U.S. government, the Government shall have only "Restricted Rights" -in the software and related documentation as defined in the Federal -Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you -are acquiring the software on behalf of the Department of Defense, the -software shall be classified as "Commercial Computer Software" and the -Government shall have only "Restricted Rights" as defined in Clause -252.227-7014 (b) (3) of DFARs. Notwithstanding the foregoing, the -authors grant the U.S. Government and others acting in its behalf -permission to use and distribute the software in accordance with the -terms specified in this license. - -This software is copyrighted by the Regents of the University of -California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState -Corporation, Apple Inc. and other parties. The following terms apply to -all files associated with the software unless explicitly disclaimed in -individual files. - -The authors hereby grant permission to use, copy, modify, distribute, -and license this software and its documentation for any purpose, provided -that existing copyright notices are retained in all copies and that this -notice is included verbatim in any distributions. No written agreement, -license, or royalty fee is required for any of the authorized uses. -Modifications to this software may be copyrighted by their authors -and need not follow the licensing terms described here, provided that -the new terms are clearly indicated on the first page of each file where -they apply. - -IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY -FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY -DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE -IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE -NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR -MODIFICATIONS. - -GOVERNMENT USE: If you are acquiring this software on behalf of the -U.S. government, the Government shall have only "Restricted Rights" -in the software and related documentation as defined in the Federal -Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you -are acquiring the software on behalf of the Department of Defense, the -software shall be classified as "Commercial Computer Software" and the -Government shall have only "Restricted Rights" as defined in Clause -252.227-7013 (b) (3) of DFARs. Notwithstanding the foregoing, the -authors grant the U.S. Government and others acting in its behalf -permission to use and distribute the software in accordance with the -terms specified in this license. - -Copyright (c) 1993-1999 Ioi Kim Lam. -Copyright (c) 2000-2001 Tix Project Group. -Copyright (c) 2004 ActiveState - -This software is copyrighted by the above entities -and other parties. The following terms apply to all files associated -with the software unless explicitly disclaimed in individual files. - -The authors hereby grant permission to use, copy, modify, distribute, -and license this software and its documentation for any purpose, provided -that existing copyright notices are retained in all copies and that this -notice is included verbatim in any distributions. No written agreement, -license, or royalty fee is required for any of the authorized uses. -Modifications to this software may be copyrighted by their authors -and need not follow the licensing terms described here, provided that -the new terms are clearly indicated on the first page of each file where -they apply. - -IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY -FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY -DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE -IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE -NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR -MODIFICATIONS. - -GOVERNMENT USE: If you are acquiring this software on behalf of the -U.S. government, the Government shall have only "Restricted Rights" -in the software and related documentation as defined in the Federal -Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you -are acquiring the software on behalf of the Department of Defense, the -software shall be classified as "Commercial Computer Software" and the -Government shall have only "Restricted Rights" as defined in Clause -252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the -authors grant the U.S. Government and others acting in its behalf -permission to use and distribute the software in accordance with the -terms specified in this license. - ----------------------------------------------------------------------- - -Parts of this software are based on the Tcl/Tk software copyrighted by -the Regents of the University of California, Sun Microsystems, Inc., -and other parties. The original license terms of the Tcl/Tk software -distribution is included in the file docs/license.tcltk. - -Parts of this software are based on the HTML Library software -copyrighted by Sun Microsystems, Inc. The original license terms of -the HTML Library software distribution is included in the file -docs/license.html_lib. - diff --git a/python/Lib/__future__.py b/python/Lib/__future__.py deleted file mode 100644 index c339770..0000000 --- a/python/Lib/__future__.py +++ /dev/null @@ -1,147 +0,0 @@ -"""Record of phased-in incompatible language changes. - -Each line is of the form: - - FeatureName = "_Feature(" OptionalRelease "," MandatoryRelease "," - CompilerFlag ")" - -where, normally, OptionalRelease < MandatoryRelease, and both are 5-tuples -of the same form as sys.version_info: - - (PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int - PY_MINOR_VERSION, # the 1; an int - PY_MICRO_VERSION, # the 0; an int - PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string - PY_RELEASE_SERIAL # the 3; an int - ) - -OptionalRelease records the first release in which - - from __future__ import FeatureName - -was accepted. - -In the case of MandatoryReleases that have not yet occurred, -MandatoryRelease predicts the release in which the feature will become part -of the language. - -Else MandatoryRelease records when the feature became part of the language; -in releases at or after that, modules no longer need - - from __future__ import FeatureName - -to use the feature in question, but may continue to use such imports. - -MandatoryRelease may also be None, meaning that a planned feature got -dropped or that the release version is undetermined. - -Instances of class _Feature have two corresponding methods, -.getOptionalRelease() and .getMandatoryRelease(). - -CompilerFlag is the (bitfield) flag that should be passed in the fourth -argument to the builtin function compile() to enable the feature in -dynamically compiled code. This flag is stored in the .compiler_flag -attribute on _Future instances. These values must match the appropriate -#defines of CO_xxx flags in Include/cpython/compile.h. - -No feature line is ever to be deleted from this file. -""" - -all_feature_names = [ - "nested_scopes", - "generators", - "division", - "absolute_import", - "with_statement", - "print_function", - "unicode_literals", - "barry_as_FLUFL", - "generator_stop", - "annotations", -] - -__all__ = ["all_feature_names"] + all_feature_names - -# The CO_xxx symbols are defined here under the same names defined in -# code.h and used by compile.h, so that an editor search will find them here. -# However, they're not exported in __all__, because they don't really belong to -# this module. -CO_NESTED = 0x0010 # nested_scopes -CO_GENERATOR_ALLOWED = 0 # generators (obsolete, was 0x1000) -CO_FUTURE_DIVISION = 0x20000 # division -CO_FUTURE_ABSOLUTE_IMPORT = 0x40000 # perform absolute imports by default -CO_FUTURE_WITH_STATEMENT = 0x80000 # with statement -CO_FUTURE_PRINT_FUNCTION = 0x100000 # print function -CO_FUTURE_UNICODE_LITERALS = 0x200000 # unicode string literals -CO_FUTURE_BARRY_AS_BDFL = 0x400000 -CO_FUTURE_GENERATOR_STOP = 0x800000 # StopIteration becomes RuntimeError in generators -CO_FUTURE_ANNOTATIONS = 0x1000000 # annotations become strings at runtime - - -class _Feature: - - def __init__(self, optionalRelease, mandatoryRelease, compiler_flag): - self.optional = optionalRelease - self.mandatory = mandatoryRelease - self.compiler_flag = compiler_flag - - def getOptionalRelease(self): - """Return first release in which this feature was recognized. - - This is a 5-tuple, of the same form as sys.version_info. - """ - return self.optional - - def getMandatoryRelease(self): - """Return release in which this feature will become mandatory. - - This is a 5-tuple, of the same form as sys.version_info, or, if - the feature was dropped, or the release date is undetermined, is None. - """ - return self.mandatory - - def __repr__(self): - return "_Feature" + repr((self.optional, - self.mandatory, - self.compiler_flag)) - - -nested_scopes = _Feature((2, 1, 0, "beta", 1), - (2, 2, 0, "alpha", 0), - CO_NESTED) - -generators = _Feature((2, 2, 0, "alpha", 1), - (2, 3, 0, "final", 0), - CO_GENERATOR_ALLOWED) - -division = _Feature((2, 2, 0, "alpha", 2), - (3, 0, 0, "alpha", 0), - CO_FUTURE_DIVISION) - -absolute_import = _Feature((2, 5, 0, "alpha", 1), - (3, 0, 0, "alpha", 0), - CO_FUTURE_ABSOLUTE_IMPORT) - -with_statement = _Feature((2, 5, 0, "alpha", 1), - (2, 6, 0, "alpha", 0), - CO_FUTURE_WITH_STATEMENT) - -print_function = _Feature((2, 6, 0, "alpha", 2), - (3, 0, 0, "alpha", 0), - CO_FUTURE_PRINT_FUNCTION) - -unicode_literals = _Feature((2, 6, 0, "alpha", 2), - (3, 0, 0, "alpha", 0), - CO_FUTURE_UNICODE_LITERALS) - -barry_as_FLUFL = _Feature((3, 1, 0, "alpha", 2), - (4, 0, 0, "alpha", 0), - CO_FUTURE_BARRY_AS_BDFL) - -generator_stop = _Feature((3, 5, 0, "beta", 1), - (3, 7, 0, "alpha", 0), - CO_FUTURE_GENERATOR_STOP) - -annotations = _Feature((3, 7, 0, "beta", 1), - None, - CO_FUTURE_ANNOTATIONS) diff --git a/python/Lib/__hello__.py b/python/Lib/__hello__.py deleted file mode 100644 index 06b4f14..0000000 --- a/python/Lib/__hello__.py +++ /dev/null @@ -1,16 +0,0 @@ -initialized = True - -class TestFrozenUtf8_1: - """\u00b6""" - -class TestFrozenUtf8_2: - """\u03c0""" - -class TestFrozenUtf8_4: - """\U0001f600""" - -def main(): - print("Hello world!") - -if __name__ == '__main__': - main() diff --git a/python/Lib/_aix_support.py b/python/Lib/_aix_support.py deleted file mode 100644 index fa3f30a..0000000 --- a/python/Lib/_aix_support.py +++ /dev/null @@ -1,91 +0,0 @@ -"""Shared AIX support functions.""" - -import sys -import sysconfig - -try: - import subprocess -except ImportError: # pragma: no cover - # _aix_support is used in distutils by setup.py to build C extensions, - # before subprocess dependencies like _posixsubprocess are available. - import _bootsubprocess as subprocess - - -def _aix_tag(vrtl, bd): - # type: (List[int], int) -> str - # Infer the ABI bitwidth from maxsize (assuming 64 bit as the default) - _sz = 32 if sys.maxsize == (2**31-1) else 64 - _bd = bd if bd != 0 else 9988 - # vrtl[version, release, technology_level] - return "aix-{:1x}{:1d}{:02d}-{:04d}-{}".format(vrtl[0], vrtl[1], vrtl[2], _bd, _sz) - - -# extract version, release and technology level from a VRMF string -def _aix_vrtl(vrmf): - # type: (str) -> List[int] - v, r, tl = vrmf.split(".")[:3] - return [int(v[-1]), int(r), int(tl)] - - -def _aix_bos_rte(): - # type: () -> Tuple[str, int] - """ - Return a Tuple[str, int] e.g., ['7.1.4.34', 1806] - The fileset bos.rte represents the current AIX run-time level. It's VRMF and - builddate reflect the current ABI levels of the runtime environment. - If no builddate is found give a value that will satisfy pep425 related queries - """ - # All AIX systems to have lslpp installed in this location - out = subprocess.check_output(["/usr/bin/lslpp", "-Lqc", "bos.rte"]) - out = out.decode("utf-8") - out = out.strip().split(":") # type: ignore - _bd = int(out[-1]) if out[-1] != '' else 9988 - return (str(out[2]), _bd) - - -def aix_platform(): - # type: () -> str - """ - AIX filesets are identified by four decimal values: V.R.M.F. - V (version) and R (release) can be retrieved using ``uname`` - Since 2007, starting with AIX 5.3 TL7, the M value has been - included with the fileset bos.rte and represents the Technology - Level (TL) of AIX. The F (Fix) value also increases, but is not - relevant for comparing releases and binary compatibility. - For binary compatibility the so-called builddate is needed. - Again, the builddate of an AIX release is associated with bos.rte. - AIX ABI compatibility is described as guaranteed at: https://www.ibm.com/\ - support/knowledgecenter/en/ssw_aix_72/install/binary_compatability.html - - For pep425 purposes the AIX platform tag becomes: - "aix-{:1x}{:1d}{:02d}-{:04d}-{}".format(v, r, tl, builddate, bitsize) - e.g., "aix-6107-1415-32" for AIX 6.1 TL7 bd 1415, 32-bit - and, "aix-6107-1415-64" for AIX 6.1 TL7 bd 1415, 64-bit - """ - vrmf, bd = _aix_bos_rte() - return _aix_tag(_aix_vrtl(vrmf), bd) - - -# extract vrtl from the BUILD_GNU_TYPE as an int -def _aix_bgt(): - # type: () -> List[int] - gnu_type = sysconfig.get_config_var("BUILD_GNU_TYPE") - if not gnu_type: - raise ValueError("BUILD_GNU_TYPE is not defined") - return _aix_vrtl(vrmf=gnu_type) - - -def aix_buildtag(): - # type: () -> str - """ - Return the platform_tag of the system Python was built on. - """ - # AIX_BUILDDATE is defined by configure with: - # lslpp -Lcq bos.rte | awk -F: '{ print $NF }' - build_date = sysconfig.get_config_var("AIX_BUILDDATE") - try: - build_date = int(build_date) - except (ValueError, TypeError): - raise ValueError(f"AIX_BUILDDATE is not defined or invalid: " - f"{build_date!r}") - return _aix_tag(_aix_bgt(), build_date) diff --git a/python/Lib/_bootsubprocess.py b/python/Lib/_bootsubprocess.py deleted file mode 100644 index 377d166..0000000 --- a/python/Lib/_bootsubprocess.py +++ /dev/null @@ -1,97 +0,0 @@ -""" -Basic subprocess implementation for POSIX which only uses os functions. Only -implement features required by setup.py to build C extension modules when -subprocess is unavailable. setup.py is not used on Windows. -""" -import os - - -# distutils.spawn used by distutils.command.build_ext -# calls subprocess.Popen().wait() -class Popen: - def __init__(self, cmd, env=None): - self._cmd = cmd - self._env = env - self.returncode = None - - def wait(self): - pid = os.fork() - if pid == 0: - # Child process - try: - if self._env is not None: - os.execve(self._cmd[0], self._cmd, self._env) - else: - os.execv(self._cmd[0], self._cmd) - finally: - os._exit(1) - else: - # Parent process - _, status = os.waitpid(pid, 0) - self.returncode = os.waitstatus_to_exitcode(status) - - return self.returncode - - -def _check_cmd(cmd): - # Use regex [a-zA-Z0-9./-]+: reject empty string, space, etc. - safe_chars = [] - for first, last in (("a", "z"), ("A", "Z"), ("0", "9")): - for ch in range(ord(first), ord(last) + 1): - safe_chars.append(chr(ch)) - safe_chars.append("./-") - safe_chars = ''.join(safe_chars) - - if isinstance(cmd, (tuple, list)): - check_strs = cmd - elif isinstance(cmd, str): - check_strs = [cmd] - else: - return False - - for arg in check_strs: - if not isinstance(arg, str): - return False - if not arg: - # reject empty string - return False - for ch in arg: - if ch not in safe_chars: - return False - - return True - - -# _aix_support used by distutil.util calls subprocess.check_output() -def check_output(cmd, **kwargs): - if kwargs: - raise NotImplementedError(repr(kwargs)) - - if not _check_cmd(cmd): - raise ValueError(f"unsupported command: {cmd!r}") - - tmp_filename = "check_output.tmp" - if not isinstance(cmd, str): - cmd = " ".join(cmd) - cmd = f"{cmd} >{tmp_filename}" - - try: - # system() spawns a shell - status = os.system(cmd) - exitcode = os.waitstatus_to_exitcode(status) - if exitcode: - raise ValueError(f"Command {cmd!r} returned non-zero " - f"exit status {exitcode!r}") - - try: - with open(tmp_filename, "rb") as fp: - stdout = fp.read() - except FileNotFoundError: - stdout = b'' - finally: - try: - os.unlink(tmp_filename) - except OSError: - pass - - return stdout diff --git a/python/Lib/_collections_abc.py b/python/Lib/_collections_abc.py deleted file mode 100644 index 13fe137..0000000 --- a/python/Lib/_collections_abc.py +++ /dev/null @@ -1,1121 +0,0 @@ -# Copyright 2007 Google, Inc. All Rights Reserved. -# Licensed to PSF under a Contributor Agreement. - -"""Abstract Base Classes (ABCs) for collections, according to PEP 3119. - -Unit tests are in test_collections. -""" - -from abc import ABCMeta, abstractmethod -import sys - -GenericAlias = type(list[int]) -EllipsisType = type(...) -def _f(): pass -FunctionType = type(_f) -del _f - -__all__ = ["Awaitable", "Coroutine", - "AsyncIterable", "AsyncIterator", "AsyncGenerator", - "Hashable", "Iterable", "Iterator", "Generator", "Reversible", - "Sized", "Container", "Callable", "Collection", - "Set", "MutableSet", - "Mapping", "MutableMapping", - "MappingView", "KeysView", "ItemsView", "ValuesView", - "Sequence", "MutableSequence", - "ByteString", - ] - -# This module has been renamed from collections.abc to _collections_abc to -# speed up interpreter startup. Some of the types such as MutableMapping are -# required early but collections module imports a lot of other modules. -# See issue #19218 -__name__ = "collections.abc" - -# Private list of types that we want to register with the various ABCs -# so that they will pass tests like: -# it = iter(somebytearray) -# assert isinstance(it, Iterable) -# Note: in other implementations, these types might not be distinct -# and they may have their own implementation specific types that -# are not included on this list. -bytes_iterator = type(iter(b'')) -bytearray_iterator = type(iter(bytearray())) -#callable_iterator = ??? -dict_keyiterator = type(iter({}.keys())) -dict_valueiterator = type(iter({}.values())) -dict_itemiterator = type(iter({}.items())) -list_iterator = type(iter([])) -list_reverseiterator = type(iter(reversed([]))) -range_iterator = type(iter(range(0))) -longrange_iterator = type(iter(range(1 << 1000))) -set_iterator = type(iter(set())) -str_iterator = type(iter("")) -tuple_iterator = type(iter(())) -zip_iterator = type(iter(zip())) -## views ## -dict_keys = type({}.keys()) -dict_values = type({}.values()) -dict_items = type({}.items()) -## misc ## -mappingproxy = type(type.__dict__) -generator = type((lambda: (yield))()) -## coroutine ## -async def _coro(): pass -_coro = _coro() -coroutine = type(_coro) -_coro.close() # Prevent ResourceWarning -del _coro -## asynchronous generator ## -async def _ag(): yield -_ag = _ag() -async_generator = type(_ag) -del _ag - - -### ONE-TRICK PONIES ### - -def _check_methods(C, *methods): - mro = C.__mro__ - for method in methods: - for B in mro: - if method in B.__dict__: - if B.__dict__[method] is None: - return NotImplemented - break - else: - return NotImplemented - return True - -class Hashable(metaclass=ABCMeta): - - __slots__ = () - - @abstractmethod - def __hash__(self): - return 0 - - @classmethod - def __subclasshook__(cls, C): - if cls is Hashable: - return _check_methods(C, "__hash__") - return NotImplemented - - -class Awaitable(metaclass=ABCMeta): - - __slots__ = () - - @abstractmethod - def __await__(self): - yield - - @classmethod - def __subclasshook__(cls, C): - if cls is Awaitable: - return _check_methods(C, "__await__") - return NotImplemented - - __class_getitem__ = classmethod(GenericAlias) - - -class Coroutine(Awaitable): - - __slots__ = () - - @abstractmethod - def send(self, value): - """Send a value into the coroutine. - Return next yielded value or raise StopIteration. - """ - raise StopIteration - - @abstractmethod - def throw(self, typ, val=None, tb=None): - """Raise an exception in the coroutine. - Return next yielded value or raise StopIteration. - """ - if val is None: - if tb is None: - raise typ - val = typ() - if tb is not None: - val = val.with_traceback(tb) - raise val - - def close(self): - """Raise GeneratorExit inside coroutine. - """ - try: - self.throw(GeneratorExit) - except (GeneratorExit, StopIteration): - pass - else: - raise RuntimeError("coroutine ignored GeneratorExit") - - @classmethod - def __subclasshook__(cls, C): - if cls is Coroutine: - return _check_methods(C, '__await__', 'send', 'throw', 'close') - return NotImplemented - - -Coroutine.register(coroutine) - - -class AsyncIterable(metaclass=ABCMeta): - - __slots__ = () - - @abstractmethod - def __aiter__(self): - return AsyncIterator() - - @classmethod - def __subclasshook__(cls, C): - if cls is AsyncIterable: - return _check_methods(C, "__aiter__") - return NotImplemented - - __class_getitem__ = classmethod(GenericAlias) - - -class AsyncIterator(AsyncIterable): - - __slots__ = () - - @abstractmethod - async def __anext__(self): - """Return the next item or raise StopAsyncIteration when exhausted.""" - raise StopAsyncIteration - - def __aiter__(self): - return self - - @classmethod - def __subclasshook__(cls, C): - if cls is AsyncIterator: - return _check_methods(C, "__anext__", "__aiter__") - return NotImplemented - - -class AsyncGenerator(AsyncIterator): - - __slots__ = () - - async def __anext__(self): - """Return the next item from the asynchronous generator. - When exhausted, raise StopAsyncIteration. - """ - return await self.asend(None) - - @abstractmethod - async def asend(self, value): - """Send a value into the asynchronous generator. - Return next yielded value or raise StopAsyncIteration. - """ - raise StopAsyncIteration - - @abstractmethod - async def athrow(self, typ, val=None, tb=None): - """Raise an exception in the asynchronous generator. - Return next yielded value or raise StopAsyncIteration. - """ - if val is None: - if tb is None: - raise typ - val = typ() - if tb is not None: - val = val.with_traceback(tb) - raise val - - async def aclose(self): - """Raise GeneratorExit inside coroutine. - """ - try: - await self.athrow(GeneratorExit) - except (GeneratorExit, StopAsyncIteration): - pass - else: - raise RuntimeError("asynchronous generator ignored GeneratorExit") - - @classmethod - def __subclasshook__(cls, C): - if cls is AsyncGenerator: - return _check_methods(C, '__aiter__', '__anext__', - 'asend', 'athrow', 'aclose') - return NotImplemented - - -AsyncGenerator.register(async_generator) - - -class Iterable(metaclass=ABCMeta): - - __slots__ = () - - @abstractmethod - def __iter__(self): - while False: - yield None - - @classmethod - def __subclasshook__(cls, C): - if cls is Iterable: - return _check_methods(C, "__iter__") - return NotImplemented - - __class_getitem__ = classmethod(GenericAlias) - - -class Iterator(Iterable): - - __slots__ = () - - @abstractmethod - def __next__(self): - 'Return the next item from the iterator. When exhausted, raise StopIteration' - raise StopIteration - - def __iter__(self): - return self - - @classmethod - def __subclasshook__(cls, C): - if cls is Iterator: - return _check_methods(C, '__iter__', '__next__') - return NotImplemented - - -Iterator.register(bytes_iterator) -Iterator.register(bytearray_iterator) -#Iterator.register(callable_iterator) -Iterator.register(dict_keyiterator) -Iterator.register(dict_valueiterator) -Iterator.register(dict_itemiterator) -Iterator.register(list_iterator) -Iterator.register(list_reverseiterator) -Iterator.register(range_iterator) -Iterator.register(longrange_iterator) -Iterator.register(set_iterator) -Iterator.register(str_iterator) -Iterator.register(tuple_iterator) -Iterator.register(zip_iterator) - - -class Reversible(Iterable): - - __slots__ = () - - @abstractmethod - def __reversed__(self): - while False: - yield None - - @classmethod - def __subclasshook__(cls, C): - if cls is Reversible: - return _check_methods(C, "__reversed__", "__iter__") - return NotImplemented - - -class Generator(Iterator): - - __slots__ = () - - def __next__(self): - """Return the next item from the generator. - When exhausted, raise StopIteration. - """ - return self.send(None) - - @abstractmethod - def send(self, value): - """Send a value into the generator. - Return next yielded value or raise StopIteration. - """ - raise StopIteration - - @abstractmethod - def throw(self, typ, val=None, tb=None): - """Raise an exception in the generator. - Return next yielded value or raise StopIteration. - """ - if val is None: - if tb is None: - raise typ - val = typ() - if tb is not None: - val = val.with_traceback(tb) - raise val - - def close(self): - """Raise GeneratorExit inside generator. - """ - try: - self.throw(GeneratorExit) - except (GeneratorExit, StopIteration): - pass - else: - raise RuntimeError("generator ignored GeneratorExit") - - @classmethod - def __subclasshook__(cls, C): - if cls is Generator: - return _check_methods(C, '__iter__', '__next__', - 'send', 'throw', 'close') - return NotImplemented - - -Generator.register(generator) - - -class Sized(metaclass=ABCMeta): - - __slots__ = () - - @abstractmethod - def __len__(self): - return 0 - - @classmethod - def __subclasshook__(cls, C): - if cls is Sized: - return _check_methods(C, "__len__") - return NotImplemented - - -class Container(metaclass=ABCMeta): - - __slots__ = () - - @abstractmethod - def __contains__(self, x): - return False - - @classmethod - def __subclasshook__(cls, C): - if cls is Container: - return _check_methods(C, "__contains__") - return NotImplemented - - __class_getitem__ = classmethod(GenericAlias) - - -class Collection(Sized, Iterable, Container): - - __slots__ = () - - @classmethod - def __subclasshook__(cls, C): - if cls is Collection: - return _check_methods(C, "__len__", "__iter__", "__contains__") - return NotImplemented - - -class _CallableGenericAlias(GenericAlias): - """ Represent `Callable[argtypes, resulttype]`. - - This sets ``__args__`` to a tuple containing the flattened ``argtypes`` - followed by ``resulttype``. - - Example: ``Callable[[int, str], float]`` sets ``__args__`` to - ``(int, str, float)``. - """ - - __slots__ = () - - def __new__(cls, origin, args): - if not (isinstance(args, tuple) and len(args) == 2): - raise TypeError( - "Callable must be used as Callable[[arg, ...], result].") - t_args, t_result = args - if isinstance(t_args, (tuple, list)): - args = (*t_args, t_result) - elif not _is_param_expr(t_args): - raise TypeError(f"Expected a list of types, an ellipsis, " - f"ParamSpec, or Concatenate. Got {t_args}") - return super().__new__(cls, origin, args) - - def __repr__(self): - if len(self.__args__) == 2 and _is_param_expr(self.__args__[0]): - return super().__repr__() - return (f'collections.abc.Callable' - f'[[{", ".join([_type_repr(a) for a in self.__args__[:-1]])}], ' - f'{_type_repr(self.__args__[-1])}]') - - def __reduce__(self): - args = self.__args__ - if not (len(args) == 2 and _is_param_expr(args[0])): - args = list(args[:-1]), args[-1] - return _CallableGenericAlias, (Callable, args) - - def __getitem__(self, item): - # Called during TypeVar substitution, returns the custom subclass - # rather than the default types.GenericAlias object. Most of the - # code is copied from typing's _GenericAlias and the builtin - # types.GenericAlias. - - if not isinstance(item, tuple): - item = (item,) - # A special case in PEP 612 where if X = Callable[P, int], - # then X[int, str] == X[[int, str]]. - if (len(self.__parameters__) == 1 - and _is_param_expr(self.__parameters__[0]) - and item and not _is_param_expr(item[0])): - item = (item,) - - new_args = super().__getitem__(item).__args__ - - # args[0] occurs due to things like Z[[int, str, bool]] from PEP 612 - if not isinstance(new_args[0], (tuple, list)): - t_result = new_args[-1] - t_args = new_args[:-1] - new_args = (t_args, t_result) - return _CallableGenericAlias(Callable, tuple(new_args)) - -def _is_param_expr(obj): - """Checks if obj matches either a list of types, ``...``, ``ParamSpec`` or - ``_ConcatenateGenericAlias`` from typing.py - """ - if obj is Ellipsis: - return True - if isinstance(obj, list): - return True - obj = type(obj) - names = ('ParamSpec', '_ConcatenateGenericAlias') - return obj.__module__ == 'typing' and any(obj.__name__ == name for name in names) - -def _type_repr(obj): - """Return the repr() of an object, special-casing types (internal helper). - - Copied from :mod:`typing` since collections.abc - shouldn't depend on that module. - """ - if isinstance(obj, GenericAlias): - return repr(obj) - if isinstance(obj, type): - if obj.__module__ == 'builtins': - return obj.__qualname__ - return f'{obj.__module__}.{obj.__qualname__}' - if obj is Ellipsis: - return '...' - if isinstance(obj, FunctionType): - return obj.__name__ - return repr(obj) - - -class Callable(metaclass=ABCMeta): - - __slots__ = () - - @abstractmethod - def __call__(self, *args, **kwds): - return False - - @classmethod - def __subclasshook__(cls, C): - if cls is Callable: - return _check_methods(C, "__call__") - return NotImplemented - - __class_getitem__ = classmethod(_CallableGenericAlias) - - -### SETS ### - - -class Set(Collection): - """A set is a finite, iterable container. - - This class provides concrete generic implementations of all - methods except for __contains__, __iter__ and __len__. - - To override the comparisons (presumably for speed, as the - semantics are fixed), redefine __le__ and __ge__, - then the other operations will automatically follow suit. - """ - - __slots__ = () - - def __le__(self, other): - if not isinstance(other, Set): - return NotImplemented - if len(self) > len(other): - return False - for elem in self: - if elem not in other: - return False - return True - - def __lt__(self, other): - if not isinstance(other, Set): - return NotImplemented - return len(self) < len(other) and self.__le__(other) - - def __gt__(self, other): - if not isinstance(other, Set): - return NotImplemented - return len(self) > len(other) and self.__ge__(other) - - def __ge__(self, other): - if not isinstance(other, Set): - return NotImplemented - if len(self) < len(other): - return False - for elem in other: - if elem not in self: - return False - return True - - def __eq__(self, other): - if not isinstance(other, Set): - return NotImplemented - return len(self) == len(other) and self.__le__(other) - - @classmethod - def _from_iterable(cls, it): - '''Construct an instance of the class from any iterable input. - - Must override this method if the class constructor signature - does not accept an iterable for an input. - ''' - return cls(it) - - def __and__(self, other): - if not isinstance(other, Iterable): - return NotImplemented - return self._from_iterable(value for value in other if value in self) - - __rand__ = __and__ - - def isdisjoint(self, other): - 'Return True if two sets have a null intersection.' - for value in other: - if value in self: - return False - return True - - def __or__(self, other): - if not isinstance(other, Iterable): - return NotImplemented - chain = (e for s in (self, other) for e in s) - return self._from_iterable(chain) - - __ror__ = __or__ - - def __sub__(self, other): - if not isinstance(other, Set): - if not isinstance(other, Iterable): - return NotImplemented - other = self._from_iterable(other) - return self._from_iterable(value for value in self - if value not in other) - - def __rsub__(self, other): - if not isinstance(other, Set): - if not isinstance(other, Iterable): - return NotImplemented - other = self._from_iterable(other) - return self._from_iterable(value for value in other - if value not in self) - - def __xor__(self, other): - if not isinstance(other, Set): - if not isinstance(other, Iterable): - return NotImplemented - other = self._from_iterable(other) - return (self - other) | (other - self) - - __rxor__ = __xor__ - - def _hash(self): - """Compute the hash value of a set. - - Note that we don't define __hash__: not all sets are hashable. - But if you define a hashable set type, its __hash__ should - call this function. - - This must be compatible __eq__. - - All sets ought to compare equal if they contain the same - elements, regardless of how they are implemented, and - regardless of the order of the elements; so there's not much - freedom for __eq__ or __hash__. We match the algorithm used - by the built-in frozenset type. - """ - MAX = sys.maxsize - MASK = 2 * MAX + 1 - n = len(self) - h = 1927868237 * (n + 1) - h &= MASK - for x in self: - hx = hash(x) - h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167 - h &= MASK - h ^= (h >> 11) ^ (h >> 25) - h = h * 69069 + 907133923 - h &= MASK - if h > MAX: - h -= MASK + 1 - if h == -1: - h = 590923713 - return h - - -Set.register(frozenset) - - -class MutableSet(Set): - """A mutable set is a finite, iterable container. - - This class provides concrete generic implementations of all - methods except for __contains__, __iter__, __len__, - add(), and discard(). - - To override the comparisons (presumably for speed, as the - semantics are fixed), all you have to do is redefine __le__ and - then the other operations will automatically follow suit. - """ - - __slots__ = () - - @abstractmethod - def add(self, value): - """Add an element.""" - raise NotImplementedError - - @abstractmethod - def discard(self, value): - """Remove an element. Do not raise an exception if absent.""" - raise NotImplementedError - - def remove(self, value): - """Remove an element. If not a member, raise a KeyError.""" - if value not in self: - raise KeyError(value) - self.discard(value) - - def pop(self): - """Return the popped value. Raise KeyError if empty.""" - it = iter(self) - try: - value = next(it) - except StopIteration: - raise KeyError from None - self.discard(value) - return value - - def clear(self): - """This is slow (creates N new iterators!) but effective.""" - try: - while True: - self.pop() - except KeyError: - pass - - def __ior__(self, it): - for value in it: - self.add(value) - return self - - def __iand__(self, it): - for value in (self - it): - self.discard(value) - return self - - def __ixor__(self, it): - if it is self: - self.clear() - else: - if not isinstance(it, Set): - it = self._from_iterable(it) - for value in it: - if value in self: - self.discard(value) - else: - self.add(value) - return self - - def __isub__(self, it): - if it is self: - self.clear() - else: - for value in it: - self.discard(value) - return self - - -MutableSet.register(set) - - -### MAPPINGS ### - -class Mapping(Collection): - """A Mapping is a generic container for associating key/value - pairs. - - This class provides concrete generic implementations of all - methods except for __getitem__, __iter__, and __len__. - """ - - __slots__ = () - - # Tell ABCMeta.__new__ that this class should have TPFLAGS_MAPPING set. - __abc_tpflags__ = 1 << 6 # Py_TPFLAGS_MAPPING - - @abstractmethod - def __getitem__(self, key): - raise KeyError - - def get(self, key, default=None): - 'D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.' - try: - return self[key] - except KeyError: - return default - - def __contains__(self, key): - try: - self[key] - except KeyError: - return False - else: - return True - - def keys(self): - "D.keys() -> a set-like object providing a view on D's keys" - return KeysView(self) - - def items(self): - "D.items() -> a set-like object providing a view on D's items" - return ItemsView(self) - - def values(self): - "D.values() -> an object providing a view on D's values" - return ValuesView(self) - - def __eq__(self, other): - if not isinstance(other, Mapping): - return NotImplemented - return dict(self.items()) == dict(other.items()) - - __reversed__ = None - -Mapping.register(mappingproxy) - - -class MappingView(Sized): - - __slots__ = '_mapping', - - def __init__(self, mapping): - self._mapping = mapping - - def __len__(self): - return len(self._mapping) - - def __repr__(self): - return '{0.__class__.__name__}({0._mapping!r})'.format(self) - - __class_getitem__ = classmethod(GenericAlias) - - -class KeysView(MappingView, Set): - - __slots__ = () - - @classmethod - def _from_iterable(cls, it): - return set(it) - - def __contains__(self, key): - return key in self._mapping - - def __iter__(self): - yield from self._mapping - - -KeysView.register(dict_keys) - - -class ItemsView(MappingView, Set): - - __slots__ = () - - @classmethod - def _from_iterable(cls, it): - return set(it) - - def __contains__(self, item): - key, value = item - try: - v = self._mapping[key] - except KeyError: - return False - else: - return v is value or v == value - - def __iter__(self): - for key in self._mapping: - yield (key, self._mapping[key]) - - -ItemsView.register(dict_items) - - -class ValuesView(MappingView, Collection): - - __slots__ = () - - def __contains__(self, value): - for key in self._mapping: - v = self._mapping[key] - if v is value or v == value: - return True - return False - - def __iter__(self): - for key in self._mapping: - yield self._mapping[key] - - -ValuesView.register(dict_values) - - -class MutableMapping(Mapping): - """A MutableMapping is a generic container for associating - key/value pairs. - - This class provides concrete generic implementations of all - methods except for __getitem__, __setitem__, __delitem__, - __iter__, and __len__. - """ - - __slots__ = () - - @abstractmethod - def __setitem__(self, key, value): - raise KeyError - - @abstractmethod - def __delitem__(self, key): - raise KeyError - - __marker = object() - - def pop(self, key, default=__marker): - '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. - If key is not found, d is returned if given, otherwise KeyError is raised. - ''' - try: - value = self[key] - except KeyError: - if default is self.__marker: - raise - return default - else: - del self[key] - return value - - def popitem(self): - '''D.popitem() -> (k, v), remove and return some (key, value) pair - as a 2-tuple; but raise KeyError if D is empty. - ''' - try: - key = next(iter(self)) - except StopIteration: - raise KeyError from None - value = self[key] - del self[key] - return key, value - - def clear(self): - 'D.clear() -> None. Remove all items from D.' - try: - while True: - self.popitem() - except KeyError: - pass - - def update(self, other=(), /, **kwds): - ''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F. - If E present and has a .keys() method, does: for k in E: D[k] = E[k] - If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v - In either case, this is followed by: for k, v in F.items(): D[k] = v - ''' - if isinstance(other, Mapping): - for key in other: - self[key] = other[key] - elif hasattr(other, "keys"): - for key in other.keys(): - self[key] = other[key] - else: - for key, value in other: - self[key] = value - for key, value in kwds.items(): - self[key] = value - - def setdefault(self, key, default=None): - 'D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D' - try: - return self[key] - except KeyError: - self[key] = default - return default - - -MutableMapping.register(dict) - - -### SEQUENCES ### - -class Sequence(Reversible, Collection): - """All the operations on a read-only sequence. - - Concrete subclasses must override __new__ or __init__, - __getitem__, and __len__. - """ - - __slots__ = () - - # Tell ABCMeta.__new__ that this class should have TPFLAGS_SEQUENCE set. - __abc_tpflags__ = 1 << 5 # Py_TPFLAGS_SEQUENCE - - @abstractmethod - def __getitem__(self, index): - raise IndexError - - def __iter__(self): - i = 0 - try: - while True: - v = self[i] - yield v - i += 1 - except IndexError: - return - - def __contains__(self, value): - for v in self: - if v is value or v == value: - return True - return False - - def __reversed__(self): - for i in reversed(range(len(self))): - yield self[i] - - def index(self, value, start=0, stop=None): - '''S.index(value, [start, [stop]]) -> integer -- return first index of value. - Raises ValueError if the value is not present. - - Supporting start and stop arguments is optional, but - recommended. - ''' - if start is not None and start < 0: - start = max(len(self) + start, 0) - if stop is not None and stop < 0: - stop += len(self) - - i = start - while stop is None or i < stop: - try: - v = self[i] - except IndexError: - break - if v is value or v == value: - return i - i += 1 - raise ValueError - - def count(self, value): - 'S.count(value) -> integer -- return number of occurrences of value' - return sum(1 for v in self if v is value or v == value) - -Sequence.register(tuple) -Sequence.register(str) -Sequence.register(range) -Sequence.register(memoryview) - - -class ByteString(Sequence): - """This unifies bytes and bytearray. - - XXX Should add all their methods. - """ - - __slots__ = () - -ByteString.register(bytes) -ByteString.register(bytearray) - - -class MutableSequence(Sequence): - """All the operations on a read-write sequence. - - Concrete subclasses must provide __new__ or __init__, - __getitem__, __setitem__, __delitem__, __len__, and insert(). - """ - - __slots__ = () - - @abstractmethod - def __setitem__(self, index, value): - raise IndexError - - @abstractmethod - def __delitem__(self, index): - raise IndexError - - @abstractmethod - def insert(self, index, value): - 'S.insert(index, value) -- insert value before index' - raise IndexError - - def append(self, value): - 'S.append(value) -- append value to the end of the sequence' - self.insert(len(self), value) - - def clear(self): - 'S.clear() -> None -- remove all items from S' - try: - while True: - self.pop() - except IndexError: - pass - - def reverse(self): - 'S.reverse() -- reverse *IN PLACE*' - n = len(self) - for i in range(n//2): - self[i], self[n-i-1] = self[n-i-1], self[i] - - def extend(self, values): - 'S.extend(iterable) -- extend sequence by appending elements from the iterable' - if values is self: - values = list(values) - for v in values: - self.append(v) - - def pop(self, index=-1): - '''S.pop([index]) -> item -- remove and return item at index (default last). - Raise IndexError if list is empty or index is out of range. - ''' - v = self[index] - del self[index] - return v - - def remove(self, value): - '''S.remove(value) -- remove first occurrence of value. - Raise ValueError if the value is not present. - ''' - del self[self.index(value)] - - def __iadd__(self, values): - self.extend(values) - return self - - -MutableSequence.register(list) -MutableSequence.register(bytearray) # Multiply inheriting, see ByteString diff --git a/python/Lib/_compat_pickle.py b/python/Lib/_compat_pickle.py deleted file mode 100644 index 9b6115f..0000000 --- a/python/Lib/_compat_pickle.py +++ /dev/null @@ -1,252 +0,0 @@ -# This module is used to map the old Python 2 names to the new names used in -# Python 3 for the pickle module. This needed to make pickle streams -# generated with Python 2 loadable by Python 3. - -# This is a copy of lib2to3.fixes.fix_imports.MAPPING. We cannot import -# lib2to3 and use the mapping defined there, because lib2to3 uses pickle. -# Thus, this could cause the module to be imported recursively. -IMPORT_MAPPING = { - '__builtin__' : 'builtins', - 'copy_reg': 'copyreg', - 'Queue': 'queue', - 'SocketServer': 'socketserver', - 'ConfigParser': 'configparser', - 'repr': 'reprlib', - 'tkFileDialog': 'tkinter.filedialog', - 'tkSimpleDialog': 'tkinter.simpledialog', - 'tkColorChooser': 'tkinter.colorchooser', - 'tkCommonDialog': 'tkinter.commondialog', - 'Dialog': 'tkinter.dialog', - 'Tkdnd': 'tkinter.dnd', - 'tkFont': 'tkinter.font', - 'tkMessageBox': 'tkinter.messagebox', - 'ScrolledText': 'tkinter.scrolledtext', - 'Tkconstants': 'tkinter.constants', - 'Tix': 'tkinter.tix', - 'ttk': 'tkinter.ttk', - 'Tkinter': 'tkinter', - 'markupbase': '_markupbase', - '_winreg': 'winreg', - 'thread': '_thread', - 'dummy_thread': '_dummy_thread', - 'dbhash': 'dbm.bsd', - 'dumbdbm': 'dbm.dumb', - 'dbm': 'dbm.ndbm', - 'gdbm': 'dbm.gnu', - 'xmlrpclib': 'xmlrpc.client', - 'SimpleXMLRPCServer': 'xmlrpc.server', - 'httplib': 'http.client', - 'htmlentitydefs' : 'html.entities', - 'HTMLParser' : 'html.parser', - 'Cookie': 'http.cookies', - 'cookielib': 'http.cookiejar', - 'BaseHTTPServer': 'http.server', - 'test.test_support': 'test.support', - 'commands': 'subprocess', - 'urlparse' : 'urllib.parse', - 'robotparser' : 'urllib.robotparser', - 'urllib2': 'urllib.request', - 'anydbm': 'dbm', - '_abcoll' : 'collections.abc', -} - - -# This contains rename rules that are easy to handle. We ignore the more -# complex stuff (e.g. mapping the names in the urllib and types modules). -# These rules should be run before import names are fixed. -NAME_MAPPING = { - ('__builtin__', 'xrange'): ('builtins', 'range'), - ('__builtin__', 'reduce'): ('functools', 'reduce'), - ('__builtin__', 'intern'): ('sys', 'intern'), - ('__builtin__', 'unichr'): ('builtins', 'chr'), - ('__builtin__', 'unicode'): ('builtins', 'str'), - ('__builtin__', 'long'): ('builtins', 'int'), - ('itertools', 'izip'): ('builtins', 'zip'), - ('itertools', 'imap'): ('builtins', 'map'), - ('itertools', 'ifilter'): ('builtins', 'filter'), - ('itertools', 'ifilterfalse'): ('itertools', 'filterfalse'), - ('itertools', 'izip_longest'): ('itertools', 'zip_longest'), - ('UserDict', 'IterableUserDict'): ('collections', 'UserDict'), - ('UserList', 'UserList'): ('collections', 'UserList'), - ('UserString', 'UserString'): ('collections', 'UserString'), - ('whichdb', 'whichdb'): ('dbm', 'whichdb'), - ('_socket', 'fromfd'): ('socket', 'fromfd'), - ('_multiprocessing', 'Connection'): ('multiprocessing.connection', 'Connection'), - ('multiprocessing.process', 'Process'): ('multiprocessing.context', 'Process'), - ('multiprocessing.forking', 'Popen'): ('multiprocessing.popen_fork', 'Popen'), - ('urllib', 'ContentTooShortError'): ('urllib.error', 'ContentTooShortError'), - ('urllib', 'getproxies'): ('urllib.request', 'getproxies'), - ('urllib', 'pathname2url'): ('urllib.request', 'pathname2url'), - ('urllib', 'quote_plus'): ('urllib.parse', 'quote_plus'), - ('urllib', 'quote'): ('urllib.parse', 'quote'), - ('urllib', 'unquote_plus'): ('urllib.parse', 'unquote_plus'), - ('urllib', 'unquote'): ('urllib.parse', 'unquote'), - ('urllib', 'url2pathname'): ('urllib.request', 'url2pathname'), - ('urllib', 'urlcleanup'): ('urllib.request', 'urlcleanup'), - ('urllib', 'urlencode'): ('urllib.parse', 'urlencode'), - ('urllib', 'urlopen'): ('urllib.request', 'urlopen'), - ('urllib', 'urlretrieve'): ('urllib.request', 'urlretrieve'), - ('urllib2', 'HTTPError'): ('urllib.error', 'HTTPError'), - ('urllib2', 'URLError'): ('urllib.error', 'URLError'), -} - -PYTHON2_EXCEPTIONS = ( - "ArithmeticError", - "AssertionError", - "AttributeError", - "BaseException", - "BufferError", - "BytesWarning", - "DeprecationWarning", - "EOFError", - "EnvironmentError", - "Exception", - "FloatingPointError", - "FutureWarning", - "GeneratorExit", - "IOError", - "ImportError", - "ImportWarning", - "IndentationError", - "IndexError", - "KeyError", - "KeyboardInterrupt", - "LookupError", - "MemoryError", - "NameError", - "NotImplementedError", - "OSError", - "OverflowError", - "PendingDeprecationWarning", - "ReferenceError", - "RuntimeError", - "RuntimeWarning", - # StandardError is gone in Python 3, so we map it to Exception - "StopIteration", - "SyntaxError", - "SyntaxWarning", - "SystemError", - "SystemExit", - "TabError", - "TypeError", - "UnboundLocalError", - "UnicodeDecodeError", - "UnicodeEncodeError", - "UnicodeError", - "UnicodeTranslateError", - "UnicodeWarning", - "UserWarning", - "ValueError", - "Warning", - "ZeroDivisionError", -) - -try: - WindowsError -except NameError: - pass -else: - PYTHON2_EXCEPTIONS += ("WindowsError",) - -for excname in PYTHON2_EXCEPTIONS: - NAME_MAPPING[("exceptions", excname)] = ("builtins", excname) - -MULTIPROCESSING_EXCEPTIONS = ( - 'AuthenticationError', - 'BufferTooShort', - 'ProcessError', - 'TimeoutError', -) - -for excname in MULTIPROCESSING_EXCEPTIONS: - NAME_MAPPING[("multiprocessing", excname)] = ("multiprocessing.context", excname) - -# Same, but for 3.x to 2.x -REVERSE_IMPORT_MAPPING = dict((v, k) for (k, v) in IMPORT_MAPPING.items()) -assert len(REVERSE_IMPORT_MAPPING) == len(IMPORT_MAPPING) -REVERSE_NAME_MAPPING = dict((v, k) for (k, v) in NAME_MAPPING.items()) -assert len(REVERSE_NAME_MAPPING) == len(NAME_MAPPING) - -# Non-mutual mappings. - -IMPORT_MAPPING.update({ - 'cPickle': 'pickle', - '_elementtree': 'xml.etree.ElementTree', - 'FileDialog': 'tkinter.filedialog', - 'SimpleDialog': 'tkinter.simpledialog', - 'DocXMLRPCServer': 'xmlrpc.server', - 'SimpleHTTPServer': 'http.server', - 'CGIHTTPServer': 'http.server', - # For compatibility with broken pickles saved in old Python 3 versions - 'UserDict': 'collections', - 'UserList': 'collections', - 'UserString': 'collections', - 'whichdb': 'dbm', - 'StringIO': 'io', - 'cStringIO': 'io', -}) - -REVERSE_IMPORT_MAPPING.update({ - '_bz2': 'bz2', - '_dbm': 'dbm', - '_functools': 'functools', - '_gdbm': 'gdbm', - '_pickle': 'pickle', -}) - -NAME_MAPPING.update({ - ('__builtin__', 'basestring'): ('builtins', 'str'), - ('exceptions', 'StandardError'): ('builtins', 'Exception'), - ('UserDict', 'UserDict'): ('collections', 'UserDict'), - ('socket', '_socketobject'): ('socket', 'SocketType'), -}) - -REVERSE_NAME_MAPPING.update({ - ('_functools', 'reduce'): ('__builtin__', 'reduce'), - ('tkinter.filedialog', 'FileDialog'): ('FileDialog', 'FileDialog'), - ('tkinter.filedialog', 'LoadFileDialog'): ('FileDialog', 'LoadFileDialog'), - ('tkinter.filedialog', 'SaveFileDialog'): ('FileDialog', 'SaveFileDialog'), - ('tkinter.simpledialog', 'SimpleDialog'): ('SimpleDialog', 'SimpleDialog'), - ('xmlrpc.server', 'ServerHTMLDoc'): ('DocXMLRPCServer', 'ServerHTMLDoc'), - ('xmlrpc.server', 'XMLRPCDocGenerator'): - ('DocXMLRPCServer', 'XMLRPCDocGenerator'), - ('xmlrpc.server', 'DocXMLRPCRequestHandler'): - ('DocXMLRPCServer', 'DocXMLRPCRequestHandler'), - ('xmlrpc.server', 'DocXMLRPCServer'): - ('DocXMLRPCServer', 'DocXMLRPCServer'), - ('xmlrpc.server', 'DocCGIXMLRPCRequestHandler'): - ('DocXMLRPCServer', 'DocCGIXMLRPCRequestHandler'), - ('http.server', 'SimpleHTTPRequestHandler'): - ('SimpleHTTPServer', 'SimpleHTTPRequestHandler'), - ('http.server', 'CGIHTTPRequestHandler'): - ('CGIHTTPServer', 'CGIHTTPRequestHandler'), - ('_socket', 'socket'): ('socket', '_socketobject'), -}) - -PYTHON3_OSERROR_EXCEPTIONS = ( - 'BrokenPipeError', - 'ChildProcessError', - 'ConnectionAbortedError', - 'ConnectionError', - 'ConnectionRefusedError', - 'ConnectionResetError', - 'FileExistsError', - 'FileNotFoundError', - 'InterruptedError', - 'IsADirectoryError', - 'NotADirectoryError', - 'PermissionError', - 'ProcessLookupError', - 'TimeoutError', -) - -for excname in PYTHON3_OSERROR_EXCEPTIONS: - REVERSE_NAME_MAPPING[('builtins', excname)] = ('exceptions', 'OSError') - -PYTHON3_IMPORTERROR_EXCEPTIONS = ( - 'ModuleNotFoundError', -) - -for excname in PYTHON3_IMPORTERROR_EXCEPTIONS: - REVERSE_NAME_MAPPING[('builtins', excname)] = ('exceptions', 'ImportError') -del excname diff --git a/python/Lib/_compression.py b/python/Lib/_compression.py deleted file mode 100644 index 60b6a6e..0000000 --- a/python/Lib/_compression.py +++ /dev/null @@ -1,162 +0,0 @@ -"""Internal classes used by the gzip, lzma and bz2 modules""" - -import io -import sys - -BUFFER_SIZE = io.DEFAULT_BUFFER_SIZE # Compressed data read chunk size - - -class BaseStream(io.BufferedIOBase): - """Mode-checking helper functions.""" - - def _check_not_closed(self): - if self.closed: - raise ValueError("I/O operation on closed file") - - def _check_can_read(self): - if not self.readable(): - raise io.UnsupportedOperation("File not open for reading") - - def _check_can_write(self): - if not self.writable(): - raise io.UnsupportedOperation("File not open for writing") - - def _check_can_seek(self): - if not self.readable(): - raise io.UnsupportedOperation("Seeking is only supported " - "on files open for reading") - if not self.seekable(): - raise io.UnsupportedOperation("The underlying file object " - "does not support seeking") - - -class DecompressReader(io.RawIOBase): - """Adapts the decompressor API to a RawIOBase reader API""" - - def readable(self): - return True - - def __init__(self, fp, decomp_factory, trailing_error=(), **decomp_args): - self._fp = fp - self._eof = False - self._pos = 0 # Current offset in decompressed stream - - # Set to size of decompressed stream once it is known, for SEEK_END - self._size = -1 - - # Save the decompressor factory and arguments. - # If the file contains multiple compressed streams, each - # stream will need a separate decompressor object. A new decompressor - # object is also needed when implementing a backwards seek(). - self._decomp_factory = decomp_factory - self._decomp_args = decomp_args - self._decompressor = self._decomp_factory(**self._decomp_args) - - # Exception class to catch from decompressor signifying invalid - # trailing data to ignore - self._trailing_error = trailing_error - - def close(self): - self._decompressor = None - return super().close() - - def seekable(self): - return self._fp.seekable() - - def readinto(self, b): - with memoryview(b) as view, view.cast("B") as byte_view: - data = self.read(len(byte_view)) - byte_view[:len(data)] = data - return len(data) - - def read(self, size=-1): - if size < 0: - return self.readall() - - if not size or self._eof: - return b"" - data = None # Default if EOF is encountered - # Depending on the input data, our call to the decompressor may not - # return any data. In this case, try again after reading another block. - while True: - if self._decompressor.eof: - rawblock = (self._decompressor.unused_data or - self._fp.read(BUFFER_SIZE)) - if not rawblock: - break - # Continue to next stream. - self._decompressor = self._decomp_factory( - **self._decomp_args) - try: - data = self._decompressor.decompress(rawblock, size) - except self._trailing_error: - # Trailing data isn't a valid compressed stream; ignore it. - break - else: - if self._decompressor.needs_input: - rawblock = self._fp.read(BUFFER_SIZE) - if not rawblock: - raise EOFError("Compressed file ended before the " - "end-of-stream marker was reached") - else: - rawblock = b"" - data = self._decompressor.decompress(rawblock, size) - if data: - break - if not data: - self._eof = True - self._size = self._pos - return b"" - self._pos += len(data) - return data - - def readall(self): - chunks = [] - # sys.maxsize means the max length of output buffer is unlimited, - # so that the whole input buffer can be decompressed within one - # .decompress() call. - while data := self.read(sys.maxsize): - chunks.append(data) - - return b"".join(chunks) - - # Rewind the file to the beginning of the data stream. - def _rewind(self): - self._fp.seek(0) - self._eof = False - self._pos = 0 - self._decompressor = self._decomp_factory(**self._decomp_args) - - def seek(self, offset, whence=io.SEEK_SET): - # Recalculate offset as an absolute file position. - if whence == io.SEEK_SET: - pass - elif whence == io.SEEK_CUR: - offset = self._pos + offset - elif whence == io.SEEK_END: - # Seeking relative to EOF - we need to know the file's size. - if self._size < 0: - while self.read(io.DEFAULT_BUFFER_SIZE): - pass - offset = self._size + offset - else: - raise ValueError("Invalid value for whence: {}".format(whence)) - - # Make it so that offset is the number of bytes to skip forward. - if offset < self._pos: - self._rewind() - else: - offset -= self._pos - - # Read and discard data until we reach the desired position. - while offset > 0: - data = self.read(min(io.DEFAULT_BUFFER_SIZE, offset)) - if not data: - break - offset -= len(data) - - return self._pos - - def tell(self): - """Return the current file position.""" - return self._pos diff --git a/python/Lib/_markupbase.py b/python/Lib/_markupbase.py deleted file mode 100644 index 592d53d..0000000 --- a/python/Lib/_markupbase.py +++ /dev/null @@ -1,396 +0,0 @@ -"""Shared support for scanning document type declarations in HTML and XHTML. - -This module is used as a foundation for the html.parser module. It has no -documented public API and should not be used directly. - -""" - -import re - -_declname_match = re.compile(r'[a-zA-Z][-_.a-zA-Z0-9]*\s*').match -_declstringlit_match = re.compile(r'(\'[^\']*\'|"[^"]*")\s*').match -_commentclose = re.compile(r'--\s*>') -_markedsectionclose = re.compile(r']\s*]\s*>') - -# An analysis of the MS-Word extensions is available at -# http://www.planetpublish.com/xmlarena/xap/Thursday/WordtoXML.pdf - -_msmarkedsectionclose = re.compile(r']\s*>') - -del re - - -class ParserBase: - """Parser base class which provides some common support methods used - by the SGML/HTML and XHTML parsers.""" - - def __init__(self): - if self.__class__ is ParserBase: - raise RuntimeError( - "_markupbase.ParserBase must be subclassed") - - def reset(self): - self.lineno = 1 - self.offset = 0 - - def getpos(self): - """Return current line number and offset.""" - return self.lineno, self.offset - - # Internal -- update line number and offset. This should be - # called for each piece of data exactly once, in order -- in other - # words the concatenation of all the input strings to this - # function should be exactly the entire input. - def updatepos(self, i, j): - if i >= j: - return j - rawdata = self.rawdata - nlines = rawdata.count("\n", i, j) - if nlines: - self.lineno = self.lineno + nlines - pos = rawdata.rindex("\n", i, j) # Should not fail - self.offset = j-(pos+1) - else: - self.offset = self.offset + j-i - return j - - _decl_otherchars = '' - - # Internal -- parse declaration (for use by subclasses). - def parse_declaration(self, i): - # This is some sort of declaration; in "HTML as - # deployed," this should only be the document type - # declaration (""). - # ISO 8879:1986, however, has more complex - # declaration syntax for elements in , including: - # --comment-- - # [marked section] - # name in the following list: ENTITY, DOCTYPE, ELEMENT, - # ATTLIST, NOTATION, SHORTREF, USEMAP, - # LINKTYPE, LINK, IDLINK, USELINK, SYSTEM - rawdata = self.rawdata - j = i + 2 - assert rawdata[i:j] == "": - # the empty comment - return j + 1 - if rawdata[j:j+1] in ("-", ""): - # Start of comment followed by buffer boundary, - # or just a buffer boundary. - return -1 - # A simple, practical version could look like: ((name|stringlit) S*) + '>' - n = len(rawdata) - if rawdata[j:j+2] == '--': #comment - # Locate --.*-- as the body of the comment - return self.parse_comment(i) - elif rawdata[j] == '[': #marked section - # Locate [statusWord [...arbitrary SGML...]] as the body of the marked section - # Where statusWord is one of TEMP, CDATA, IGNORE, INCLUDE, RCDATA - # Note that this is extended by Microsoft Office "Save as Web" function - # to include [if...] and [endif]. - return self.parse_marked_section(i) - else: #all other declaration elements - decltype, j = self._scan_name(j, i) - if j < 0: - return j - if decltype == "doctype": - self._decl_otherchars = '' - while j < n: - c = rawdata[j] - if c == ">": - # end of declaration syntax - data = rawdata[i+2:j] - if decltype == "doctype": - self.handle_decl(data) - else: - # According to the HTML5 specs sections "8.2.4.44 Bogus - # comment state" and "8.2.4.45 Markup declaration open - # state", a comment token should be emitted. - # Calling unknown_decl provides more flexibility though. - self.unknown_decl(data) - return j + 1 - if c in "\"'": - m = _declstringlit_match(rawdata, j) - if not m: - return -1 # incomplete - j = m.end() - elif c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ": - name, j = self._scan_name(j, i) - elif c in self._decl_otherchars: - j = j + 1 - elif c == "[": - # this could be handled in a separate doctype parser - if decltype == "doctype": - j = self._parse_doctype_subset(j + 1, i) - elif decltype in {"attlist", "linktype", "link", "element"}: - # must tolerate []'d groups in a content model in an element declaration - # also in data attribute specifications of attlist declaration - # also link type declaration subsets in linktype declarations - # also link attribute specification lists in link declarations - raise AssertionError("unsupported '[' char in %s declaration" % decltype) - else: - raise AssertionError("unexpected '[' char in declaration") - else: - raise AssertionError("unexpected %r char in declaration" % rawdata[j]) - if j < 0: - return j - return -1 # incomplete - - # Internal -- parse a marked section - # Override this to handle MS-word extension syntax content - def parse_marked_section(self, i, report=1): - rawdata= self.rawdata - assert rawdata[i:i+3] == ' ending - match= _markedsectionclose.search(rawdata, i+3) - elif sectName in {"if", "else", "endif"}: - # look for MS Office ]> ending - match= _msmarkedsectionclose.search(rawdata, i+3) - else: - raise AssertionError( - 'unknown status keyword %r in marked section' % rawdata[i+3:j] - ) - if not match: - return -1 - if report: - j = match.start(0) - self.unknown_decl(rawdata[i+3: j]) - return match.end(0) - - # Internal -- parse comment, return length or -1 if not terminated - def parse_comment(self, i, report=1): - rawdata = self.rawdata - if rawdata[i:i+4] != ' a, b, c - abc_to_rgb(a, b, c) --> r, g, b - -All inputs and outputs are triples of floats in the range [0.0...1.0] -(with the exception of I and Q, which covers a slightly larger range). -Inputs outside the valid range may cause exceptions or invalid outputs. - -Supported color systems: -RGB: Red, Green, Blue components -YIQ: Luminance, Chrominance (used by composite video signals) -HLS: Hue, Luminance, Saturation -HSV: Hue, Saturation, Value -""" - -# References: -# http://en.wikipedia.org/wiki/YIQ -# http://en.wikipedia.org/wiki/HLS_color_space -# http://en.wikipedia.org/wiki/HSV_color_space - -__all__ = ["rgb_to_yiq","yiq_to_rgb","rgb_to_hls","hls_to_rgb", - "rgb_to_hsv","hsv_to_rgb"] - -# Some floating point constants - -ONE_THIRD = 1.0/3.0 -ONE_SIXTH = 1.0/6.0 -TWO_THIRD = 2.0/3.0 - -# YIQ: used by composite video signals (linear combinations of RGB) -# Y: perceived grey level (0.0 == black, 1.0 == white) -# I, Q: color components -# -# There are a great many versions of the constants used in these formulae. -# The ones in this library uses constants from the FCC version of NTSC. - -def rgb_to_yiq(r, g, b): - y = 0.30*r + 0.59*g + 0.11*b - i = 0.74*(r-y) - 0.27*(b-y) - q = 0.48*(r-y) + 0.41*(b-y) - return (y, i, q) - -def yiq_to_rgb(y, i, q): - # r = y + (0.27*q + 0.41*i) / (0.74*0.41 + 0.27*0.48) - # b = y + (0.74*q - 0.48*i) / (0.74*0.41 + 0.27*0.48) - # g = y - (0.30*(r-y) + 0.11*(b-y)) / 0.59 - - r = y + 0.9468822170900693*i + 0.6235565819861433*q - g = y - 0.27478764629897834*i - 0.6356910791873801*q - b = y - 1.1085450346420322*i + 1.7090069284064666*q - - if r < 0.0: - r = 0.0 - if g < 0.0: - g = 0.0 - if b < 0.0: - b = 0.0 - if r > 1.0: - r = 1.0 - if g > 1.0: - g = 1.0 - if b > 1.0: - b = 1.0 - return (r, g, b) - - -# HLS: Hue, Luminance, Saturation -# H: position in the spectrum -# L: color lightness -# S: color saturation - -def rgb_to_hls(r, g, b): - maxc = max(r, g, b) - minc = min(r, g, b) - sumc = (maxc+minc) - rangec = (maxc-minc) - l = sumc/2.0 - if minc == maxc: - return 0.0, l, 0.0 - if l <= 0.5: - s = rangec / sumc - else: - s = rangec / (2.0-sumc) - rc = (maxc-r) / rangec - gc = (maxc-g) / rangec - bc = (maxc-b) / rangec - if r == maxc: - h = bc-gc - elif g == maxc: - h = 2.0+rc-bc - else: - h = 4.0+gc-rc - h = (h/6.0) % 1.0 - return h, l, s - -def hls_to_rgb(h, l, s): - if s == 0.0: - return l, l, l - if l <= 0.5: - m2 = l * (1.0+s) - else: - m2 = l+s-(l*s) - m1 = 2.0*l - m2 - return (_v(m1, m2, h+ONE_THIRD), _v(m1, m2, h), _v(m1, m2, h-ONE_THIRD)) - -def _v(m1, m2, hue): - hue = hue % 1.0 - if hue < ONE_SIXTH: - return m1 + (m2-m1)*hue*6.0 - if hue < 0.5: - return m2 - if hue < TWO_THIRD: - return m1 + (m2-m1)*(TWO_THIRD-hue)*6.0 - return m1 - - -# HSV: Hue, Saturation, Value -# H: position in the spectrum -# S: color saturation ("purity") -# V: color brightness - -def rgb_to_hsv(r, g, b): - maxc = max(r, g, b) - minc = min(r, g, b) - rangec = (maxc-minc) - v = maxc - if minc == maxc: - return 0.0, 0.0, v - s = rangec / maxc - rc = (maxc-r) / rangec - gc = (maxc-g) / rangec - bc = (maxc-b) / rangec - if r == maxc: - h = bc-gc - elif g == maxc: - h = 2.0+rc-bc - else: - h = 4.0+gc-rc - h = (h/6.0) % 1.0 - return h, s, v - -def hsv_to_rgb(h, s, v): - if s == 0.0: - return v, v, v - i = int(h*6.0) # XXX assume int() truncates! - f = (h*6.0) - i - p = v*(1.0 - s) - q = v*(1.0 - s*f) - t = v*(1.0 - s*(1.0-f)) - i = i%6 - if i == 0: - return v, t, p - if i == 1: - return q, v, p - if i == 2: - return p, v, t - if i == 3: - return p, q, v - if i == 4: - return t, p, v - if i == 5: - return v, p, q - # Cannot get here diff --git a/python/Lib/compileall.py b/python/Lib/compileall.py deleted file mode 100644 index abd83a7..0000000 --- a/python/Lib/compileall.py +++ /dev/null @@ -1,463 +0,0 @@ -"""Module/script to byte-compile all .py files to .pyc files. - -When called as a script with arguments, this compiles the directories -given as arguments recursively; the -l option prevents it from -recursing into directories. - -Without arguments, it compiles all modules on sys.path, without -recursing into subdirectories. (Even though it should do so for -packages -- for now, you'll have to deal with packages separately.) - -See module py_compile for details of the actual byte-compilation. -""" -import os -import sys -import importlib.util -import py_compile -import struct -import filecmp - -from functools import partial -from pathlib import Path - -__all__ = ["compile_dir","compile_file","compile_path"] - -def _walk_dir(dir, maxlevels, quiet=0): - if quiet < 2 and isinstance(dir, os.PathLike): - dir = os.fspath(dir) - if not quiet: - print('Listing {!r}...'.format(dir)) - try: - names = os.listdir(dir) - except OSError: - if quiet < 2: - print("Can't list {!r}".format(dir)) - names = [] - names.sort() - for name in names: - if name == '__pycache__': - continue - fullname = os.path.join(dir, name) - if not os.path.isdir(fullname): - yield fullname - elif (maxlevels > 0 and name != os.curdir and name != os.pardir and - os.path.isdir(fullname) and not os.path.islink(fullname)): - yield from _walk_dir(fullname, maxlevels=maxlevels - 1, - quiet=quiet) - -def compile_dir(dir, maxlevels=None, ddir=None, force=False, - rx=None, quiet=0, legacy=False, optimize=-1, workers=1, - invalidation_mode=None, *, stripdir=None, - prependdir=None, limit_sl_dest=None, hardlink_dupes=False): - """Byte-compile all modules in the given directory tree. - - Arguments (only dir is required): - - dir: the directory to byte-compile - maxlevels: maximum recursion level (default `sys.getrecursionlimit()`) - ddir: the directory that will be prepended to the path to the - file as it is compiled into each byte-code file. - force: if True, force compilation, even if timestamps are up-to-date - quiet: full output with False or 0, errors only with 1, - no output with 2 - legacy: if True, produce legacy pyc paths instead of PEP 3147 paths - optimize: int or list of optimization levels or -1 for level of - the interpreter. Multiple levels leads to multiple compiled - files each with one optimization level. - workers: maximum number of parallel workers - invalidation_mode: how the up-to-dateness of the pyc will be checked - stripdir: part of path to left-strip from source file path - prependdir: path to prepend to beginning of original file path, applied - after stripdir - limit_sl_dest: ignore symlinks if they are pointing outside of - the defined path - hardlink_dupes: hardlink duplicated pyc files - """ - ProcessPoolExecutor = None - if ddir is not None and (stripdir is not None or prependdir is not None): - raise ValueError(("Destination dir (ddir) cannot be used " - "in combination with stripdir or prependdir")) - if ddir is not None: - stripdir = dir - prependdir = ddir - ddir = None - if workers < 0: - raise ValueError('workers must be greater or equal to 0') - if workers != 1: - # Check if this is a system where ProcessPoolExecutor can function. - from concurrent.futures.process import _check_system_limits - try: - _check_system_limits() - except NotImplementedError: - workers = 1 - else: - from concurrent.futures import ProcessPoolExecutor - if maxlevels is None: - maxlevels = sys.getrecursionlimit() - files = _walk_dir(dir, quiet=quiet, maxlevels=maxlevels) - success = True - if workers != 1 and ProcessPoolExecutor is not None: - # If workers == 0, let ProcessPoolExecutor choose - workers = workers or None - with ProcessPoolExecutor(max_workers=workers) as executor: - results = executor.map(partial(compile_file, - ddir=ddir, force=force, - rx=rx, quiet=quiet, - legacy=legacy, - optimize=optimize, - invalidation_mode=invalidation_mode, - stripdir=stripdir, - prependdir=prependdir, - limit_sl_dest=limit_sl_dest, - hardlink_dupes=hardlink_dupes), - files) - success = min(results, default=True) - else: - for file in files: - if not compile_file(file, ddir, force, rx, quiet, - legacy, optimize, invalidation_mode, - stripdir=stripdir, prependdir=prependdir, - limit_sl_dest=limit_sl_dest, - hardlink_dupes=hardlink_dupes): - success = False - return success - -def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, - legacy=False, optimize=-1, - invalidation_mode=None, *, stripdir=None, prependdir=None, - limit_sl_dest=None, hardlink_dupes=False): - """Byte-compile one file. - - Arguments (only fullname is required): - - fullname: the file to byte-compile - ddir: if given, the directory name compiled in to the - byte-code file. - force: if True, force compilation, even if timestamps are up-to-date - quiet: full output with False or 0, errors only with 1, - no output with 2 - legacy: if True, produce legacy pyc paths instead of PEP 3147 paths - optimize: int or list of optimization levels or -1 for level of - the interpreter. Multiple levels leads to multiple compiled - files each with one optimization level. - invalidation_mode: how the up-to-dateness of the pyc will be checked - stripdir: part of path to left-strip from source file path - prependdir: path to prepend to beginning of original file path, applied - after stripdir - limit_sl_dest: ignore symlinks if they are pointing outside of - the defined path. - hardlink_dupes: hardlink duplicated pyc files - """ - - if ddir is not None and (stripdir is not None or prependdir is not None): - raise ValueError(("Destination dir (ddir) cannot be used " - "in combination with stripdir or prependdir")) - - success = True - if quiet < 2 and isinstance(fullname, os.PathLike): - fullname = os.fspath(fullname) - name = os.path.basename(fullname) - - dfile = None - - if ddir is not None: - dfile = os.path.join(ddir, name) - - if stripdir is not None: - fullname_parts = fullname.split(os.path.sep) - stripdir_parts = stripdir.split(os.path.sep) - ddir_parts = list(fullname_parts) - - for spart, opart in zip(stripdir_parts, fullname_parts): - if spart == opart: - ddir_parts.remove(spart) - - dfile = os.path.join(*ddir_parts) - - if prependdir is not None: - if dfile is None: - dfile = os.path.join(prependdir, fullname) - else: - dfile = os.path.join(prependdir, dfile) - - if isinstance(optimize, int): - optimize = [optimize] - - # Use set() to remove duplicates. - # Use sorted() to create pyc files in a deterministic order. - optimize = sorted(set(optimize)) - - if hardlink_dupes and len(optimize) < 2: - raise ValueError("Hardlinking of duplicated bytecode makes sense " - "only for more than one optimization level") - - if rx is not None: - mo = rx.search(fullname) - if mo: - return success - - if limit_sl_dest is not None and os.path.islink(fullname): - if Path(limit_sl_dest).resolve() not in Path(fullname).resolve().parents: - return success - - opt_cfiles = {} - - if os.path.isfile(fullname): - for opt_level in optimize: - if legacy: - opt_cfiles[opt_level] = fullname + 'c' - else: - if opt_level >= 0: - opt = opt_level if opt_level >= 1 else '' - cfile = (importlib.util.cache_from_source( - fullname, optimization=opt)) - opt_cfiles[opt_level] = cfile - else: - cfile = importlib.util.cache_from_source(fullname) - opt_cfiles[opt_level] = cfile - - head, tail = name[:-3], name[-3:] - if tail == '.py': - if not force: - try: - mtime = int(os.stat(fullname).st_mtime) - expect = struct.pack('<4sLL', importlib.util.MAGIC_NUMBER, - 0, mtime & 0xFFFF_FFFF) - for cfile in opt_cfiles.values(): - with open(cfile, 'rb') as chandle: - actual = chandle.read(12) - if expect != actual: - break - else: - return success - except OSError: - pass - if not quiet: - print('Compiling {!r}...'.format(fullname)) - try: - for index, opt_level in enumerate(optimize): - cfile = opt_cfiles[opt_level] - ok = py_compile.compile(fullname, cfile, dfile, True, - optimize=opt_level, - invalidation_mode=invalidation_mode) - if index > 0 and hardlink_dupes: - previous_cfile = opt_cfiles[optimize[index - 1]] - if filecmp.cmp(cfile, previous_cfile, shallow=False): - os.unlink(cfile) - os.link(previous_cfile, cfile) - except py_compile.PyCompileError as err: - success = False - if quiet >= 2: - return success - elif quiet: - print('*** Error compiling {!r}...'.format(fullname)) - else: - print('*** ', end='') - # escape non-printable characters in msg - encoding = sys.stdout.encoding or sys.getdefaultencoding() - msg = err.msg.encode(encoding, errors='backslashreplace').decode(encoding) - print(msg) - except (SyntaxError, UnicodeError, OSError) as e: - success = False - if quiet >= 2: - return success - elif quiet: - print('*** Error compiling {!r}...'.format(fullname)) - else: - print('*** ', end='') - print(e.__class__.__name__ + ':', e) - else: - if ok == 0: - success = False - return success - -def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=0, - legacy=False, optimize=-1, - invalidation_mode=None): - """Byte-compile all module on sys.path. - - Arguments (all optional): - - skip_curdir: if true, skip current directory (default True) - maxlevels: max recursion level (default 0) - force: as for compile_dir() (default False) - quiet: as for compile_dir() (default 0) - legacy: as for compile_dir() (default False) - optimize: as for compile_dir() (default -1) - invalidation_mode: as for compiler_dir() - """ - success = True - for dir in sys.path: - if (not dir or dir == os.curdir) and skip_curdir: - if quiet < 2: - print('Skipping current directory') - else: - success = success and compile_dir( - dir, - maxlevels, - None, - force, - quiet=quiet, - legacy=legacy, - optimize=optimize, - invalidation_mode=invalidation_mode, - ) - return success - - -def main(): - """Script main program.""" - import argparse - - parser = argparse.ArgumentParser( - description='Utilities to support installing Python libraries.') - parser.add_argument('-l', action='store_const', const=0, - default=None, dest='maxlevels', - help="don't recurse into subdirectories") - parser.add_argument('-r', type=int, dest='recursion', - help=('control the maximum recursion level. ' - 'if `-l` and `-r` options are specified, ' - 'then `-r` takes precedence.')) - parser.add_argument('-f', action='store_true', dest='force', - help='force rebuild even if timestamps are up to date') - parser.add_argument('-q', action='count', dest='quiet', default=0, - help='output only error messages; -qq will suppress ' - 'the error messages as well.') - parser.add_argument('-b', action='store_true', dest='legacy', - help='use legacy (pre-PEP3147) compiled file locations') - parser.add_argument('-d', metavar='DESTDIR', dest='ddir', default=None, - help=('directory to prepend to file paths for use in ' - 'compile-time tracebacks and in runtime ' - 'tracebacks in cases where the source file is ' - 'unavailable')) - parser.add_argument('-s', metavar='STRIPDIR', dest='stripdir', - default=None, - help=('part of path to left-strip from path ' - 'to source file - for example buildroot. ' - '`-d` and `-s` options cannot be ' - 'specified together.')) - parser.add_argument('-p', metavar='PREPENDDIR', dest='prependdir', - default=None, - help=('path to add as prefix to path ' - 'to source file - for example / to make ' - 'it absolute when some part is removed ' - 'by `-s` option. ' - '`-d` and `-p` options cannot be ' - 'specified together.')) - parser.add_argument('-x', metavar='REGEXP', dest='rx', default=None, - help=('skip files matching the regular expression; ' - 'the regexp is searched for in the full path ' - 'of each file considered for compilation')) - parser.add_argument('-i', metavar='FILE', dest='flist', - help=('add all the files and directories listed in ' - 'FILE to the list considered for compilation; ' - 'if "-", names are read from stdin')) - parser.add_argument('compile_dest', metavar='FILE|DIR', nargs='*', - help=('zero or more file and directory names ' - 'to compile; if no arguments given, defaults ' - 'to the equivalent of -l sys.path')) - parser.add_argument('-j', '--workers', default=1, - type=int, help='Run compileall concurrently') - invalidation_modes = [mode.name.lower().replace('_', '-') - for mode in py_compile.PycInvalidationMode] - parser.add_argument('--invalidation-mode', - choices=sorted(invalidation_modes), - help=('set .pyc invalidation mode; defaults to ' - '"checked-hash" if the SOURCE_DATE_EPOCH ' - 'environment variable is set, and ' - '"timestamp" otherwise.')) - parser.add_argument('-o', action='append', type=int, dest='opt_levels', - help=('Optimization levels to run compilation with. ' - 'Default is -1 which uses the optimization level ' - 'of the Python interpreter itself (see -O).')) - parser.add_argument('-e', metavar='DIR', dest='limit_sl_dest', - help='Ignore symlinks pointing outsite of the DIR') - parser.add_argument('--hardlink-dupes', action='store_true', - dest='hardlink_dupes', - help='Hardlink duplicated pyc files') - - args = parser.parse_args() - compile_dests = args.compile_dest - - if args.rx: - import re - args.rx = re.compile(args.rx) - - if args.limit_sl_dest == "": - args.limit_sl_dest = None - - if args.recursion is not None: - maxlevels = args.recursion - else: - maxlevels = args.maxlevels - - if args.opt_levels is None: - args.opt_levels = [-1] - - if len(args.opt_levels) == 1 and args.hardlink_dupes: - parser.error(("Hardlinking of duplicated bytecode makes sense " - "only for more than one optimization level.")) - - if args.ddir is not None and ( - args.stripdir is not None or args.prependdir is not None - ): - parser.error("-d cannot be used in combination with -s or -p") - - # if flist is provided then load it - if args.flist: - try: - with (sys.stdin if args.flist=='-' else - open(args.flist, encoding="utf-8")) as f: - for line in f: - compile_dests.append(line.strip()) - except OSError: - if args.quiet < 2: - print("Error reading file list {}".format(args.flist)) - return False - - if args.invalidation_mode: - ivl_mode = args.invalidation_mode.replace('-', '_').upper() - invalidation_mode = py_compile.PycInvalidationMode[ivl_mode] - else: - invalidation_mode = None - - success = True - try: - if compile_dests: - for dest in compile_dests: - if os.path.isfile(dest): - if not compile_file(dest, args.ddir, args.force, args.rx, - args.quiet, args.legacy, - invalidation_mode=invalidation_mode, - stripdir=args.stripdir, - prependdir=args.prependdir, - optimize=args.opt_levels, - limit_sl_dest=args.limit_sl_dest, - hardlink_dupes=args.hardlink_dupes): - success = False - else: - if not compile_dir(dest, maxlevels, args.ddir, - args.force, args.rx, args.quiet, - args.legacy, workers=args.workers, - invalidation_mode=invalidation_mode, - stripdir=args.stripdir, - prependdir=args.prependdir, - optimize=args.opt_levels, - limit_sl_dest=args.limit_sl_dest, - hardlink_dupes=args.hardlink_dupes): - success = False - return success - else: - return compile_path(legacy=args.legacy, force=args.force, - quiet=args.quiet, - invalidation_mode=invalidation_mode) - except KeyboardInterrupt: - if args.quiet < 2: - print("\n[interrupted]") - return False - return True - - -if __name__ == '__main__': - exit_status = int(not main()) - sys.exit(exit_status) diff --git a/python/Lib/concurrent/__init__.py b/python/Lib/concurrent/__init__.py deleted file mode 100644 index de1ac25..0000000 --- a/python/Lib/concurrent/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# This directory is a Python package. diff --git a/python/Lib/concurrent/futures/__init__.py b/python/Lib/concurrent/futures/__init__.py deleted file mode 100644 index 1d5cc07..0000000 --- a/python/Lib/concurrent/futures/__init__.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright 2009 Brian Quinlan. All Rights Reserved. -# Licensed to PSF under a Contributor Agreement. - -"""Execute computations asynchronously using threads or processes.""" - -__author__ = 'Brian Quinlan (brian@sweetapp.com)' - -from concurrent.futures._base import (FIRST_COMPLETED, - FIRST_EXCEPTION, - ALL_COMPLETED, - CancelledError, - TimeoutError, - InvalidStateError, - BrokenExecutor, - Future, - Executor, - wait, - as_completed) - -__all__ = ( - 'FIRST_COMPLETED', - 'FIRST_EXCEPTION', - 'ALL_COMPLETED', - 'CancelledError', - 'TimeoutError', - 'BrokenExecutor', - 'Future', - 'Executor', - 'wait', - 'as_completed', - 'ProcessPoolExecutor', - 'ThreadPoolExecutor', -) - - -def __dir__(): - return __all__ + ('__author__', '__doc__') - - -def __getattr__(name): - global ProcessPoolExecutor, ThreadPoolExecutor - - if name == 'ProcessPoolExecutor': - from .process import ProcessPoolExecutor as pe - ProcessPoolExecutor = pe - return pe - - if name == 'ThreadPoolExecutor': - from .thread import ThreadPoolExecutor as te - ThreadPoolExecutor = te - return te - - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/python/Lib/concurrent/futures/_base.py b/python/Lib/concurrent/futures/_base.py deleted file mode 100644 index 578201f..0000000 --- a/python/Lib/concurrent/futures/_base.py +++ /dev/null @@ -1,654 +0,0 @@ -# Copyright 2009 Brian Quinlan. All Rights Reserved. -# Licensed to PSF under a Contributor Agreement. - -__author__ = 'Brian Quinlan (brian@sweetapp.com)' - -import collections -import logging -import threading -import time -import types - -FIRST_COMPLETED = 'FIRST_COMPLETED' -FIRST_EXCEPTION = 'FIRST_EXCEPTION' -ALL_COMPLETED = 'ALL_COMPLETED' -_AS_COMPLETED = '_AS_COMPLETED' - -# Possible future states (for internal use by the futures package). -PENDING = 'PENDING' -RUNNING = 'RUNNING' -# The future was cancelled by the user... -CANCELLED = 'CANCELLED' -# ...and _Waiter.add_cancelled() was called by a worker. -CANCELLED_AND_NOTIFIED = 'CANCELLED_AND_NOTIFIED' -FINISHED = 'FINISHED' - -_FUTURE_STATES = [ - PENDING, - RUNNING, - CANCELLED, - CANCELLED_AND_NOTIFIED, - FINISHED -] - -_STATE_TO_DESCRIPTION_MAP = { - PENDING: "pending", - RUNNING: "running", - CANCELLED: "cancelled", - CANCELLED_AND_NOTIFIED: "cancelled", - FINISHED: "finished" -} - -# Logger for internal use by the futures package. -LOGGER = logging.getLogger("concurrent.futures") - -class Error(Exception): - """Base class for all future-related exceptions.""" - pass - -class CancelledError(Error): - """The Future was cancelled.""" - pass - -TimeoutError = TimeoutError # make local alias for the standard exception - -class InvalidStateError(Error): - """The operation is not allowed in this state.""" - pass - -class _Waiter(object): - """Provides the event that wait() and as_completed() block on.""" - def __init__(self): - self.event = threading.Event() - self.finished_futures = [] - - def add_result(self, future): - self.finished_futures.append(future) - - def add_exception(self, future): - self.finished_futures.append(future) - - def add_cancelled(self, future): - self.finished_futures.append(future) - -class _AsCompletedWaiter(_Waiter): - """Used by as_completed().""" - - def __init__(self): - super(_AsCompletedWaiter, self).__init__() - self.lock = threading.Lock() - - def add_result(self, future): - with self.lock: - super(_AsCompletedWaiter, self).add_result(future) - self.event.set() - - def add_exception(self, future): - with self.lock: - super(_AsCompletedWaiter, self).add_exception(future) - self.event.set() - - def add_cancelled(self, future): - with self.lock: - super(_AsCompletedWaiter, self).add_cancelled(future) - self.event.set() - -class _FirstCompletedWaiter(_Waiter): - """Used by wait(return_when=FIRST_COMPLETED).""" - - def add_result(self, future): - super().add_result(future) - self.event.set() - - def add_exception(self, future): - super().add_exception(future) - self.event.set() - - def add_cancelled(self, future): - super().add_cancelled(future) - self.event.set() - -class _AllCompletedWaiter(_Waiter): - """Used by wait(return_when=FIRST_EXCEPTION and ALL_COMPLETED).""" - - def __init__(self, num_pending_calls, stop_on_exception): - self.num_pending_calls = num_pending_calls - self.stop_on_exception = stop_on_exception - self.lock = threading.Lock() - super().__init__() - - def _decrement_pending_calls(self): - with self.lock: - self.num_pending_calls -= 1 - if not self.num_pending_calls: - self.event.set() - - def add_result(self, future): - super().add_result(future) - self._decrement_pending_calls() - - def add_exception(self, future): - super().add_exception(future) - if self.stop_on_exception: - self.event.set() - else: - self._decrement_pending_calls() - - def add_cancelled(self, future): - super().add_cancelled(future) - self._decrement_pending_calls() - -class _AcquireFutures(object): - """A context manager that does an ordered acquire of Future conditions.""" - - def __init__(self, futures): - self.futures = sorted(futures, key=id) - - def __enter__(self): - for future in self.futures: - future._condition.acquire() - - def __exit__(self, *args): - for future in self.futures: - future._condition.release() - -def _create_and_install_waiters(fs, return_when): - if return_when == _AS_COMPLETED: - waiter = _AsCompletedWaiter() - elif return_when == FIRST_COMPLETED: - waiter = _FirstCompletedWaiter() - else: - pending_count = sum( - f._state not in [CANCELLED_AND_NOTIFIED, FINISHED] for f in fs) - - if return_when == FIRST_EXCEPTION: - waiter = _AllCompletedWaiter(pending_count, stop_on_exception=True) - elif return_when == ALL_COMPLETED: - waiter = _AllCompletedWaiter(pending_count, stop_on_exception=False) - else: - raise ValueError("Invalid return condition: %r" % return_when) - - for f in fs: - f._waiters.append(waiter) - - return waiter - - -def _yield_finished_futures(fs, waiter, ref_collect): - """ - Iterate on the list *fs*, yielding finished futures one by one in - reverse order. - Before yielding a future, *waiter* is removed from its waiters - and the future is removed from each set in the collection of sets - *ref_collect*. - - The aim of this function is to avoid keeping stale references after - the future is yielded and before the iterator resumes. - """ - while fs: - f = fs[-1] - for futures_set in ref_collect: - futures_set.remove(f) - with f._condition: - f._waiters.remove(waiter) - del f - # Careful not to keep a reference to the popped value - yield fs.pop() - - -def as_completed(fs, timeout=None): - """An iterator over the given futures that yields each as it completes. - - Args: - fs: The sequence of Futures (possibly created by different Executors) to - iterate over. - timeout: The maximum number of seconds to wait. If None, then there - is no limit on the wait time. - - Returns: - An iterator that yields the given Futures as they complete (finished or - cancelled). If any given Futures are duplicated, they will be returned - once. - - Raises: - TimeoutError: If the entire result iterator could not be generated - before the given timeout. - """ - if timeout is not None: - end_time = timeout + time.monotonic() - - fs = set(fs) - total_futures = len(fs) - with _AcquireFutures(fs): - finished = set( - f for f in fs - if f._state in [CANCELLED_AND_NOTIFIED, FINISHED]) - pending = fs - finished - waiter = _create_and_install_waiters(fs, _AS_COMPLETED) - finished = list(finished) - try: - yield from _yield_finished_futures(finished, waiter, - ref_collect=(fs,)) - - while pending: - if timeout is None: - wait_timeout = None - else: - wait_timeout = end_time - time.monotonic() - if wait_timeout < 0: - raise TimeoutError( - '%d (of %d) futures unfinished' % ( - len(pending), total_futures)) - - waiter.event.wait(wait_timeout) - - with waiter.lock: - finished = waiter.finished_futures - waiter.finished_futures = [] - waiter.event.clear() - - # reverse to keep finishing order - finished.reverse() - yield from _yield_finished_futures(finished, waiter, - ref_collect=(fs, pending)) - - finally: - # Remove waiter from unfinished futures - for f in fs: - with f._condition: - f._waiters.remove(waiter) - -DoneAndNotDoneFutures = collections.namedtuple( - 'DoneAndNotDoneFutures', 'done not_done') -def wait(fs, timeout=None, return_when=ALL_COMPLETED): - """Wait for the futures in the given sequence to complete. - - Args: - fs: The sequence of Futures (possibly created by different Executors) to - wait upon. - timeout: The maximum number of seconds to wait. If None, then there - is no limit on the wait time. - return_when: Indicates when this function should return. The options - are: - - FIRST_COMPLETED - Return when any future finishes or is - cancelled. - FIRST_EXCEPTION - Return when any future finishes by raising an - exception. If no future raises an exception - then it is equivalent to ALL_COMPLETED. - ALL_COMPLETED - Return when all futures finish or are cancelled. - - Returns: - A named 2-tuple of sets. The first set, named 'done', contains the - futures that completed (is finished or cancelled) before the wait - completed. The second set, named 'not_done', contains uncompleted - futures. Duplicate futures given to *fs* are removed and will be - returned only once. - """ - fs = set(fs) - with _AcquireFutures(fs): - done = {f for f in fs - if f._state in [CANCELLED_AND_NOTIFIED, FINISHED]} - not_done = fs - done - if (return_when == FIRST_COMPLETED) and done: - return DoneAndNotDoneFutures(done, not_done) - elif (return_when == FIRST_EXCEPTION) and done: - if any(f for f in done - if not f.cancelled() and f.exception() is not None): - return DoneAndNotDoneFutures(done, not_done) - - if len(done) == len(fs): - return DoneAndNotDoneFutures(done, not_done) - - waiter = _create_and_install_waiters(fs, return_when) - - waiter.event.wait(timeout) - for f in fs: - with f._condition: - f._waiters.remove(waiter) - - done.update(waiter.finished_futures) - return DoneAndNotDoneFutures(done, fs - done) - - -def _result_or_cancel(fut, timeout=None): - try: - try: - return fut.result(timeout) - finally: - fut.cancel() - finally: - # Break a reference cycle with the exception in self._exception - del fut - - -class Future(object): - """Represents the result of an asynchronous computation.""" - - def __init__(self): - """Initializes the future. Should not be called by clients.""" - self._condition = threading.Condition() - self._state = PENDING - self._result = None - self._exception = None - self._waiters = [] - self._done_callbacks = [] - - def _invoke_callbacks(self): - for callback in self._done_callbacks: - try: - callback(self) - except Exception: - LOGGER.exception('exception calling callback for %r', self) - - def __repr__(self): - with self._condition: - if self._state == FINISHED: - if self._exception: - return '<%s at %#x state=%s raised %s>' % ( - self.__class__.__name__, - id(self), - _STATE_TO_DESCRIPTION_MAP[self._state], - self._exception.__class__.__name__) - else: - return '<%s at %#x state=%s returned %s>' % ( - self.__class__.__name__, - id(self), - _STATE_TO_DESCRIPTION_MAP[self._state], - self._result.__class__.__name__) - return '<%s at %#x state=%s>' % ( - self.__class__.__name__, - id(self), - _STATE_TO_DESCRIPTION_MAP[self._state]) - - def cancel(self): - """Cancel the future if possible. - - Returns True if the future was cancelled, False otherwise. A future - cannot be cancelled if it is running or has already completed. - """ - with self._condition: - if self._state in [RUNNING, FINISHED]: - return False - - if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]: - return True - - self._state = CANCELLED - self._condition.notify_all() - - self._invoke_callbacks() - return True - - def cancelled(self): - """Return True if the future was cancelled.""" - with self._condition: - return self._state in [CANCELLED, CANCELLED_AND_NOTIFIED] - - def running(self): - """Return True if the future is currently executing.""" - with self._condition: - return self._state == RUNNING - - def done(self): - """Return True if the future was cancelled or finished executing.""" - with self._condition: - return self._state in [CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED] - - def __get_result(self): - if self._exception: - try: - raise self._exception - finally: - # Break a reference cycle with the exception in self._exception - self = None - else: - return self._result - - def add_done_callback(self, fn): - """Attaches a callable that will be called when the future finishes. - - Args: - fn: A callable that will be called with this future as its only - argument when the future completes or is cancelled. The callable - will always be called by a thread in the same process in which - it was added. If the future has already completed or been - cancelled then the callable will be called immediately. These - callables are called in the order that they were added. - """ - with self._condition: - if self._state not in [CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED]: - self._done_callbacks.append(fn) - return - try: - fn(self) - except Exception: - LOGGER.exception('exception calling callback for %r', self) - - def result(self, timeout=None): - """Return the result of the call that the future represents. - - Args: - timeout: The number of seconds to wait for the result if the future - isn't done. If None, then there is no limit on the wait time. - - Returns: - The result of the call that the future represents. - - Raises: - CancelledError: If the future was cancelled. - TimeoutError: If the future didn't finish executing before the given - timeout. - Exception: If the call raised then that exception will be raised. - """ - try: - with self._condition: - if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]: - raise CancelledError() - elif self._state == FINISHED: - return self.__get_result() - - self._condition.wait(timeout) - - if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]: - raise CancelledError() - elif self._state == FINISHED: - return self.__get_result() - else: - raise TimeoutError() - finally: - # Break a reference cycle with the exception in self._exception - self = None - - def exception(self, timeout=None): - """Return the exception raised by the call that the future represents. - - Args: - timeout: The number of seconds to wait for the exception if the - future isn't done. If None, then there is no limit on the wait - time. - - Returns: - The exception raised by the call that the future represents or None - if the call completed without raising. - - Raises: - CancelledError: If the future was cancelled. - TimeoutError: If the future didn't finish executing before the given - timeout. - """ - - with self._condition: - if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]: - raise CancelledError() - elif self._state == FINISHED: - return self._exception - - self._condition.wait(timeout) - - if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]: - raise CancelledError() - elif self._state == FINISHED: - return self._exception - else: - raise TimeoutError() - - # The following methods should only be used by Executors and in tests. - def set_running_or_notify_cancel(self): - """Mark the future as running or process any cancel notifications. - - Should only be used by Executor implementations and unit tests. - - If the future has been cancelled (cancel() was called and returned - True) then any threads waiting on the future completing (though calls - to as_completed() or wait()) are notified and False is returned. - - If the future was not cancelled then it is put in the running state - (future calls to running() will return True) and True is returned. - - This method should be called by Executor implementations before - executing the work associated with this future. If this method returns - False then the work should not be executed. - - Returns: - False if the Future was cancelled, True otherwise. - - Raises: - RuntimeError: if this method was already called or if set_result() - or set_exception() was called. - """ - with self._condition: - if self._state == CANCELLED: - self._state = CANCELLED_AND_NOTIFIED - for waiter in self._waiters: - waiter.add_cancelled(self) - # self._condition.notify_all() is not necessary because - # self.cancel() triggers a notification. - return False - elif self._state == PENDING: - self._state = RUNNING - return True - else: - LOGGER.critical('Future %s in unexpected state: %s', - id(self), - self._state) - raise RuntimeError('Future in unexpected state') - - def set_result(self, result): - """Sets the return value of work associated with the future. - - Should only be used by Executor implementations and unit tests. - """ - with self._condition: - if self._state in {CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED}: - raise InvalidStateError('{}: {!r}'.format(self._state, self)) - self._result = result - self._state = FINISHED - for waiter in self._waiters: - waiter.add_result(self) - self._condition.notify_all() - self._invoke_callbacks() - - def set_exception(self, exception): - """Sets the result of the future as being the given exception. - - Should only be used by Executor implementations and unit tests. - """ - with self._condition: - if self._state in {CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED}: - raise InvalidStateError('{}: {!r}'.format(self._state, self)) - self._exception = exception - self._state = FINISHED - for waiter in self._waiters: - waiter.add_exception(self) - self._condition.notify_all() - self._invoke_callbacks() - - __class_getitem__ = classmethod(types.GenericAlias) - -class Executor(object): - """This is an abstract base class for concrete asynchronous executors.""" - - def submit(self, fn, /, *args, **kwargs): - """Submits a callable to be executed with the given arguments. - - Schedules the callable to be executed as fn(*args, **kwargs) and returns - a Future instance representing the execution of the callable. - - Returns: - A Future representing the given call. - """ - raise NotImplementedError() - - def map(self, fn, *iterables, timeout=None, chunksize=1): - """Returns an iterator equivalent to map(fn, iter). - - Args: - fn: A callable that will take as many arguments as there are - passed iterables. - timeout: The maximum number of seconds to wait. If None, then there - is no limit on the wait time. - chunksize: The size of the chunks the iterable will be broken into - before being passed to a child process. This argument is only - used by ProcessPoolExecutor; it is ignored by - ThreadPoolExecutor. - - Returns: - An iterator equivalent to: map(func, *iterables) but the calls may - be evaluated out-of-order. - - Raises: - TimeoutError: If the entire result iterator could not be generated - before the given timeout. - Exception: If fn(*args) raises for any values. - """ - if timeout is not None: - end_time = timeout + time.monotonic() - - fs = [self.submit(fn, *args) for args in zip(*iterables)] - - # Yield must be hidden in closure so that the futures are submitted - # before the first iterator value is required. - def result_iterator(): - try: - # reverse to keep finishing order - fs.reverse() - while fs: - # Careful not to keep a reference to the popped future - if timeout is None: - yield _result_or_cancel(fs.pop()) - else: - yield _result_or_cancel(fs.pop(), end_time - time.monotonic()) - finally: - for future in fs: - future.cancel() - return result_iterator() - - def shutdown(self, wait=True, *, cancel_futures=False): - """Clean-up the resources associated with the Executor. - - It is safe to call this method several times. Otherwise, no other - methods can be called after this one. - - Args: - wait: If True then shutdown will not return until all running - futures have finished executing and the resources used by the - executor have been reclaimed. - cancel_futures: If True then shutdown will cancel all pending - futures. Futures that are completed or running will not be - cancelled. - """ - pass - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.shutdown(wait=True) - return False - - -class BrokenExecutor(RuntimeError): - """ - Raised when a executor has become non-functional after a severe failure. - """ diff --git a/python/Lib/concurrent/futures/process.py b/python/Lib/concurrent/futures/process.py deleted file mode 100644 index f0ee00a..0000000 --- a/python/Lib/concurrent/futures/process.py +++ /dev/null @@ -1,836 +0,0 @@ -# Copyright 2009 Brian Quinlan. All Rights Reserved. -# Licensed to PSF under a Contributor Agreement. - -"""Implements ProcessPoolExecutor. - -The following diagram and text describe the data-flow through the system: - -|======================= In-process =====================|== Out-of-process ==| - -+----------+ +----------+ +--------+ +-----------+ +---------+ -| | => | Work Ids | | | | Call Q | | Process | -| | +----------+ | | +-----------+ | Pool | -| | | ... | | | | ... | +---------+ -| | | 6 | => | | => | 5, call() | => | | -| | | 7 | | | | ... | | | -| Process | | ... | | Local | +-----------+ | Process | -| Pool | +----------+ | Worker | | #1..n | -| Executor | | Thread | | | -| | +----------- + | | +-----------+ | | -| | <=> | Work Items | <=> | | <= | Result Q | <= | | -| | +------------+ | | +-----------+ | | -| | | 6: call() | | | | ... | | | -| | | future | | | | 4, result | | | -| | | ... | | | | 3, except | | | -+----------+ +------------+ +--------+ +-----------+ +---------+ - -Executor.submit() called: -- creates a uniquely numbered _WorkItem and adds it to the "Work Items" dict -- adds the id of the _WorkItem to the "Work Ids" queue - -Local worker thread: -- reads work ids from the "Work Ids" queue and looks up the corresponding - WorkItem from the "Work Items" dict: if the work item has been cancelled then - it is simply removed from the dict, otherwise it is repackaged as a - _CallItem and put in the "Call Q". New _CallItems are put in the "Call Q" - until "Call Q" is full. NOTE: the size of the "Call Q" is kept small because - calls placed in the "Call Q" can no longer be cancelled with Future.cancel(). -- reads _ResultItems from "Result Q", updates the future stored in the - "Work Items" dict and deletes the dict entry - -Process #1..n: -- reads _CallItems from "Call Q", executes the calls, and puts the resulting - _ResultItems in "Result Q" -""" - -__author__ = 'Brian Quinlan (brian@sweetapp.com)' - -import os -from concurrent.futures import _base -import queue -import multiprocessing as mp -import multiprocessing.connection -from multiprocessing.queues import Queue -import threading -import weakref -from functools import partial -import itertools -import sys -from traceback import format_exception - - -_threads_wakeups = weakref.WeakKeyDictionary() -_global_shutdown = False - - -class _ThreadWakeup: - def __init__(self): - self._closed = False - self._reader, self._writer = mp.Pipe(duplex=False) - - def close(self): - if not self._closed: - self._closed = True - self._writer.close() - self._reader.close() - - def wakeup(self): - if not self._closed: - self._writer.send_bytes(b"") - - def clear(self): - if not self._closed: - while self._reader.poll(): - self._reader.recv_bytes() - - -def _python_exit(): - global _global_shutdown - _global_shutdown = True - items = list(_threads_wakeups.items()) - for _, thread_wakeup in items: - # call not protected by ProcessPoolExecutor._shutdown_lock - thread_wakeup.wakeup() - for t, _ in items: - t.join() - -# Register for `_python_exit()` to be called just before joining all -# non-daemon threads. This is used instead of `atexit.register()` for -# compatibility with subinterpreters, which no longer support daemon threads. -# See bpo-39812 for context. -threading._register_atexit(_python_exit) - -# Controls how many more calls than processes will be queued in the call queue. -# A smaller number will mean that processes spend more time idle waiting for -# work while a larger number will make Future.cancel() succeed less frequently -# (Futures in the call queue cannot be cancelled). -EXTRA_QUEUED_CALLS = 1 - - -# On Windows, WaitForMultipleObjects is used to wait for processes to finish. -# It can wait on, at most, 63 objects. There is an overhead of two objects: -# - the result queue reader -# - the thread wakeup reader -_MAX_WINDOWS_WORKERS = 63 - 2 - -# Hack to embed stringification of remote traceback in local traceback - -class _RemoteTraceback(Exception): - def __init__(self, tb): - self.tb = tb - def __str__(self): - return self.tb - -class _ExceptionWithTraceback: - def __init__(self, exc, tb): - tb = ''.join(format_exception(type(exc), exc, tb)) - self.exc = exc - # Traceback object needs to be garbage-collected as its frames - # contain references to all the objects in the exception scope - self.exc.__traceback__ = None - self.tb = '\n"""\n%s"""' % tb - def __reduce__(self): - return _rebuild_exc, (self.exc, self.tb) - -def _rebuild_exc(exc, tb): - exc.__cause__ = _RemoteTraceback(tb) - return exc - -class _WorkItem(object): - def __init__(self, future, fn, args, kwargs): - self.future = future - self.fn = fn - self.args = args - self.kwargs = kwargs - -class _ResultItem(object): - def __init__(self, work_id, exception=None, result=None, exit_pid=None): - self.work_id = work_id - self.exception = exception - self.result = result - self.exit_pid = exit_pid - -class _CallItem(object): - def __init__(self, work_id, fn, args, kwargs): - self.work_id = work_id - self.fn = fn - self.args = args - self.kwargs = kwargs - - -class _SafeQueue(Queue): - """Safe Queue set exception to the future object linked to a job""" - def __init__(self, max_size=0, *, ctx, pending_work_items, shutdown_lock, - thread_wakeup): - self.pending_work_items = pending_work_items - self.shutdown_lock = shutdown_lock - self.thread_wakeup = thread_wakeup - super().__init__(max_size, ctx=ctx) - - def _on_queue_feeder_error(self, e, obj): - if isinstance(obj, _CallItem): - tb = format_exception(type(e), e, e.__traceback__) - e.__cause__ = _RemoteTraceback('\n"""\n{}"""'.format(''.join(tb))) - work_item = self.pending_work_items.pop(obj.work_id, None) - with self.shutdown_lock: - self.thread_wakeup.wakeup() - # work_item can be None if another process terminated. In this - # case, the executor_manager_thread fails all work_items - # with BrokenProcessPool - if work_item is not None: - work_item.future.set_exception(e) - else: - super()._on_queue_feeder_error(e, obj) - - -def _get_chunks(*iterables, chunksize): - """ Iterates over zip()ed iterables in chunks. """ - it = zip(*iterables) - while True: - chunk = tuple(itertools.islice(it, chunksize)) - if not chunk: - return - yield chunk - - -def _process_chunk(fn, chunk): - """ Processes a chunk of an iterable passed to map. - - Runs the function passed to map() on a chunk of the - iterable passed to map. - - This function is run in a separate process. - - """ - return [fn(*args) for args in chunk] - - -def _sendback_result(result_queue, work_id, result=None, exception=None, - exit_pid=None): - """Safely send back the given result or exception""" - try: - result_queue.put(_ResultItem(work_id, result=result, - exception=exception, exit_pid=exit_pid)) - except BaseException as e: - exc = _ExceptionWithTraceback(e, e.__traceback__) - result_queue.put(_ResultItem(work_id, exception=exc, - exit_pid=exit_pid)) - - -def _process_worker(call_queue, result_queue, initializer, initargs, max_tasks=None): - """Evaluates calls from call_queue and places the results in result_queue. - - This worker is run in a separate process. - - Args: - call_queue: A ctx.Queue of _CallItems that will be read and - evaluated by the worker. - result_queue: A ctx.Queue of _ResultItems that will written - to by the worker. - initializer: A callable initializer, or None - initargs: A tuple of args for the initializer - """ - if initializer is not None: - try: - initializer(*initargs) - except BaseException: - _base.LOGGER.critical('Exception in initializer:', exc_info=True) - # The parent will notice that the process stopped and - # mark the pool broken - return - num_tasks = 0 - exit_pid = None - while True: - call_item = call_queue.get(block=True) - if call_item is None: - # Wake up queue management thread - result_queue.put(os.getpid()) - return - - if max_tasks is not None: - num_tasks += 1 - if num_tasks >= max_tasks: - exit_pid = os.getpid() - - try: - r = call_item.fn(*call_item.args, **call_item.kwargs) - except BaseException as e: - exc = _ExceptionWithTraceback(e, e.__traceback__) - _sendback_result(result_queue, call_item.work_id, exception=exc, - exit_pid=exit_pid) - else: - _sendback_result(result_queue, call_item.work_id, result=r, - exit_pid=exit_pid) - del r - - # Liberate the resource as soon as possible, to avoid holding onto - # open files or shared memory that is not needed anymore - del call_item - - if exit_pid is not None: - return - - -class _ExecutorManagerThread(threading.Thread): - """Manages the communication between this process and the worker processes. - - The manager is run in a local thread. - - Args: - executor: A reference to the ProcessPoolExecutor that owns - this thread. A weakref will be own by the manager as well as - references to internal objects used to introspect the state of - the executor. - """ - - def __init__(self, executor): - # Store references to necessary internals of the executor. - - # A _ThreadWakeup to allow waking up the queue_manager_thread from the - # main Thread and avoid deadlocks caused by permanently locked queues. - self.thread_wakeup = executor._executor_manager_thread_wakeup - self.shutdown_lock = executor._shutdown_lock - - # A weakref.ref to the ProcessPoolExecutor that owns this thread. Used - # to determine if the ProcessPoolExecutor has been garbage collected - # and that the manager can exit. - # When the executor gets garbage collected, the weakref callback - # will wake up the queue management thread so that it can terminate - # if there is no pending work item. - def weakref_cb(_, - thread_wakeup=self.thread_wakeup, - shutdown_lock=self.shutdown_lock): - mp.util.debug('Executor collected: triggering callback for' - ' QueueManager wakeup') - with shutdown_lock: - thread_wakeup.wakeup() - - self.executor_reference = weakref.ref(executor, weakref_cb) - - # A list of the ctx.Process instances used as workers. - self.processes = executor._processes - - # A ctx.Queue that will be filled with _CallItems derived from - # _WorkItems for processing by the process workers. - self.call_queue = executor._call_queue - - # A ctx.SimpleQueue of _ResultItems generated by the process workers. - self.result_queue = executor._result_queue - - # A queue.Queue of work ids e.g. Queue([5, 6, ...]). - self.work_ids_queue = executor._work_ids - - # Maximum number of tasks a worker process can execute before - # exiting safely - self.max_tasks_per_child = executor._max_tasks_per_child - - # A dict mapping work ids to _WorkItems e.g. - # {5: <_WorkItem...>, 6: <_WorkItem...>, ...} - self.pending_work_items = executor._pending_work_items - - super().__init__() - - def run(self): - # Main loop for the executor manager thread. - - while True: - self.add_call_item_to_queue() - - result_item, is_broken, cause = self.wait_result_broken_or_wakeup() - - if is_broken: - self.terminate_broken(cause) - return - if result_item is not None: - self.process_result_item(result_item) - - process_exited = result_item.exit_pid is not None - if process_exited: - p = self.processes.pop(result_item.exit_pid) - p.join() - - # Delete reference to result_item to avoid keeping references - # while waiting on new results. - del result_item - - if executor := self.executor_reference(): - if process_exited: - with self.shutdown_lock: - executor._adjust_process_count() - else: - executor._idle_worker_semaphore.release() - del executor - - if self.is_shutting_down(): - self.flag_executor_shutting_down() - - # Since no new work items can be added, it is safe to shutdown - # this thread if there are no pending work items. - if not self.pending_work_items: - self.join_executor_internals() - return - - def add_call_item_to_queue(self): - # Fills call_queue with _WorkItems from pending_work_items. - # This function never blocks. - while True: - if self.call_queue.full(): - return - try: - work_id = self.work_ids_queue.get(block=False) - except queue.Empty: - return - else: - work_item = self.pending_work_items[work_id] - - if work_item.future.set_running_or_notify_cancel(): - self.call_queue.put(_CallItem(work_id, - work_item.fn, - work_item.args, - work_item.kwargs), - block=True) - else: - del self.pending_work_items[work_id] - continue - - def wait_result_broken_or_wakeup(self): - # Wait for a result to be ready in the result_queue while checking - # that all worker processes are still running, or for a wake up - # signal send. The wake up signals come either from new tasks being - # submitted, from the executor being shutdown/gc-ed, or from the - # shutdown of the python interpreter. - result_reader = self.result_queue._reader - assert not self.thread_wakeup._closed - wakeup_reader = self.thread_wakeup._reader - readers = [result_reader, wakeup_reader] - worker_sentinels = [p.sentinel for p in list(self.processes.values())] - ready = mp.connection.wait(readers + worker_sentinels) - - cause = None - is_broken = True - result_item = None - if result_reader in ready: - try: - result_item = result_reader.recv() - is_broken = False - except BaseException as e: - cause = format_exception(type(e), e, e.__traceback__) - - elif wakeup_reader in ready: - is_broken = False - - with self.shutdown_lock: - self.thread_wakeup.clear() - - return result_item, is_broken, cause - - def process_result_item(self, result_item): - # Process the received a result_item. This can be either the PID of a - # worker that exited gracefully or a _ResultItem - - if isinstance(result_item, int): - # Clean shutdown of a worker using its PID - # (avoids marking the executor broken) - assert self.is_shutting_down() - p = self.processes.pop(result_item) - p.join() - if not self.processes: - self.join_executor_internals() - return - else: - # Received a _ResultItem so mark the future as completed. - work_item = self.pending_work_items.pop(result_item.work_id, None) - # work_item can be None if another process terminated (see above) - if work_item is not None: - if result_item.exception: - work_item.future.set_exception(result_item.exception) - else: - work_item.future.set_result(result_item.result) - - def is_shutting_down(self): - # Check whether we should start shutting down the executor. - executor = self.executor_reference() - # No more work items can be added if: - # - The interpreter is shutting down OR - # - The executor that owns this worker has been collected OR - # - The executor that owns this worker has been shutdown. - return (_global_shutdown or executor is None - or executor._shutdown_thread) - - def terminate_broken(self, cause): - # Terminate the executor because it is in a broken state. The cause - # argument can be used to display more information on the error that - # lead the executor into becoming broken. - - # Mark the process pool broken so that submits fail right now. - executor = self.executor_reference() - if executor is not None: - executor._broken = ('A child process terminated ' - 'abruptly, the process pool is not ' - 'usable anymore') - executor._shutdown_thread = True - executor = None - - # All pending tasks are to be marked failed with the following - # BrokenProcessPool error - bpe = BrokenProcessPool("A process in the process pool was " - "terminated abruptly while the future was " - "running or pending.") - if cause is not None: - bpe.__cause__ = _RemoteTraceback( - f"\n'''\n{''.join(cause)}'''") - - # Mark pending tasks as failed. - for work_id, work_item in self.pending_work_items.items(): - work_item.future.set_exception(bpe) - # Delete references to object. See issue16284 - del work_item - self.pending_work_items.clear() - - # Terminate remaining workers forcibly: the queues or their - # locks may be in a dirty state and block forever. - for p in self.processes.values(): - p.terminate() - - # clean up resources - self.join_executor_internals() - - def flag_executor_shutting_down(self): - # Flag the executor as shutting down and cancel remaining tasks if - # requested as early as possible if it is not gc-ed yet. - executor = self.executor_reference() - if executor is not None: - executor._shutdown_thread = True - # Cancel pending work items if requested. - if executor._cancel_pending_futures: - # Cancel all pending futures and update pending_work_items - # to only have futures that are currently running. - new_pending_work_items = {} - for work_id, work_item in self.pending_work_items.items(): - if not work_item.future.cancel(): - new_pending_work_items[work_id] = work_item - self.pending_work_items = new_pending_work_items - # Drain work_ids_queue since we no longer need to - # add items to the call queue. - while True: - try: - self.work_ids_queue.get_nowait() - except queue.Empty: - break - # Make sure we do this only once to not waste time looping - # on running processes over and over. - executor._cancel_pending_futures = False - - def shutdown_workers(self): - n_children_to_stop = self.get_n_children_alive() - n_sentinels_sent = 0 - # Send the right number of sentinels, to make sure all children are - # properly terminated. - while (n_sentinels_sent < n_children_to_stop - and self.get_n_children_alive() > 0): - for i in range(n_children_to_stop - n_sentinels_sent): - try: - self.call_queue.put_nowait(None) - n_sentinels_sent += 1 - except queue.Full: - break - - def join_executor_internals(self): - self.shutdown_workers() - # Release the queue's resources as soon as possible. - self.call_queue.close() - self.call_queue.join_thread() - with self.shutdown_lock: - self.thread_wakeup.close() - # If .join() is not called on the created processes then - # some ctx.Queue methods may deadlock on Mac OS X. - for p in self.processes.values(): - p.join() - - def get_n_children_alive(self): - # This is an upper bound on the number of children alive. - return sum(p.is_alive() for p in self.processes.values()) - - -_system_limits_checked = False -_system_limited = None - - -def _check_system_limits(): - global _system_limits_checked, _system_limited - if _system_limits_checked: - if _system_limited: - raise NotImplementedError(_system_limited) - _system_limits_checked = True - try: - import multiprocessing.synchronize - except ImportError: - _system_limited = ( - "This Python build lacks multiprocessing.synchronize, usually due " - "to named semaphores being unavailable on this platform." - ) - raise NotImplementedError(_system_limited) - try: - nsems_max = os.sysconf("SC_SEM_NSEMS_MAX") - except (AttributeError, ValueError): - # sysconf not available or setting not available - return - if nsems_max == -1: - # indetermined limit, assume that limit is determined - # by available memory only - return - if nsems_max >= 256: - # minimum number of semaphores available - # according to POSIX - return - _system_limited = ("system provides too few semaphores (%d" - " available, 256 necessary)" % nsems_max) - raise NotImplementedError(_system_limited) - - -def _chain_from_iterable_of_lists(iterable): - """ - Specialized implementation of itertools.chain.from_iterable. - Each item in *iterable* should be a list. This function is - careful not to keep references to yielded objects. - """ - for element in iterable: - element.reverse() - while element: - yield element.pop() - - -class BrokenProcessPool(_base.BrokenExecutor): - """ - Raised when a process in a ProcessPoolExecutor terminated abruptly - while a future was in the running state. - """ - - -class ProcessPoolExecutor(_base.Executor): - def __init__(self, max_workers=None, mp_context=None, - initializer=None, initargs=(), *, max_tasks_per_child=None): - """Initializes a new ProcessPoolExecutor instance. - - Args: - max_workers: The maximum number of processes that can be used to - execute the given calls. If None or not given then as many - worker processes will be created as the machine has processors. - mp_context: A multiprocessing context to launch the workers. This - object should provide SimpleQueue, Queue and Process. Useful - to allow specific multiprocessing start methods. - initializer: A callable used to initialize worker processes. - initargs: A tuple of arguments to pass to the initializer. - max_tasks_per_child: The maximum number of tasks a worker process - can complete before it will exit and be replaced with a fresh - worker process. The default of None means worker process will - live as long as the executor. Requires a non-'fork' mp_context - start method. When given, we default to using 'spawn' if no - mp_context is supplied. - """ - _check_system_limits() - - if max_workers is None: - self._max_workers = os.cpu_count() or 1 - if sys.platform == 'win32': - self._max_workers = min(_MAX_WINDOWS_WORKERS, - self._max_workers) - else: - if max_workers <= 0: - raise ValueError("max_workers must be greater than 0") - elif (sys.platform == 'win32' and - max_workers > _MAX_WINDOWS_WORKERS): - raise ValueError( - f"max_workers must be <= {_MAX_WINDOWS_WORKERS}") - - self._max_workers = max_workers - - if mp_context is None: - if max_tasks_per_child is not None: - mp_context = mp.get_context("spawn") - else: - mp_context = mp.get_context() - self._mp_context = mp_context - - # https://github.com/python/cpython/issues/90622 - self._safe_to_dynamically_spawn_children = ( - self._mp_context.get_start_method(allow_none=False) != "fork") - - if initializer is not None and not callable(initializer): - raise TypeError("initializer must be a callable") - self._initializer = initializer - self._initargs = initargs - - if max_tasks_per_child is not None: - if not isinstance(max_tasks_per_child, int): - raise TypeError("max_tasks_per_child must be an integer") - elif max_tasks_per_child <= 0: - raise ValueError("max_tasks_per_child must be >= 1") - if self._mp_context.get_start_method(allow_none=False) == "fork": - # https://github.com/python/cpython/issues/90622 - raise ValueError("max_tasks_per_child is incompatible with" - " the 'fork' multiprocessing start method;" - " supply a different mp_context.") - self._max_tasks_per_child = max_tasks_per_child - - # Management thread - self._executor_manager_thread = None - - # Map of pids to processes - self._processes = {} - - # Shutdown is a two-step process. - self._shutdown_thread = False - self._shutdown_lock = threading.Lock() - self._idle_worker_semaphore = threading.Semaphore(0) - self._broken = False - self._queue_count = 0 - self._pending_work_items = {} - self._cancel_pending_futures = False - - # _ThreadWakeup is a communication channel used to interrupt the wait - # of the main loop of executor_manager_thread from another thread (e.g. - # when calling executor.submit or executor.shutdown). We do not use the - # _result_queue to send wakeup signals to the executor_manager_thread - # as it could result in a deadlock if a worker process dies with the - # _result_queue write lock still acquired. - # - # _shutdown_lock must be locked to access _ThreadWakeup. - self._executor_manager_thread_wakeup = _ThreadWakeup() - - # Create communication channels for the executor - # Make the call queue slightly larger than the number of processes to - # prevent the worker processes from idling. But don't make it too big - # because futures in the call queue cannot be cancelled. - queue_size = self._max_workers + EXTRA_QUEUED_CALLS - self._call_queue = _SafeQueue( - max_size=queue_size, ctx=self._mp_context, - pending_work_items=self._pending_work_items, - shutdown_lock=self._shutdown_lock, - thread_wakeup=self._executor_manager_thread_wakeup) - # Killed worker processes can produce spurious "broken pipe" - # tracebacks in the queue's own worker thread. But we detect killed - # processes anyway, so silence the tracebacks. - self._call_queue._ignore_epipe = True - self._result_queue = mp_context.SimpleQueue() - self._work_ids = queue.Queue() - - def _start_executor_manager_thread(self): - if self._executor_manager_thread is None: - # Start the processes so that their sentinels are known. - if not self._safe_to_dynamically_spawn_children: # ie, using fork. - self._launch_processes() - self._executor_manager_thread = _ExecutorManagerThread(self) - self._executor_manager_thread.start() - _threads_wakeups[self._executor_manager_thread] = \ - self._executor_manager_thread_wakeup - - def _adjust_process_count(self): - # if there's an idle process, we don't need to spawn a new one. - if self._idle_worker_semaphore.acquire(blocking=False): - return - - process_count = len(self._processes) - if process_count < self._max_workers: - # Assertion disabled as this codepath is also used to replace a - # worker that unexpectedly dies, even when using the 'fork' start - # method. That means there is still a potential deadlock bug. If a - # 'fork' mp_context worker dies, we'll be forking a new one when - # we know a thread is running (self._executor_manager_thread). - #assert self._safe_to_dynamically_spawn_children or not self._executor_manager_thread, 'https://github.com/python/cpython/issues/90622' - self._spawn_process() - - def _launch_processes(self): - # https://github.com/python/cpython/issues/90622 - assert not self._executor_manager_thread, ( - 'Processes cannot be fork()ed after the thread has started, ' - 'deadlock in the child processes could result.') - for _ in range(len(self._processes), self._max_workers): - self._spawn_process() - - def _spawn_process(self): - p = self._mp_context.Process( - target=_process_worker, - args=(self._call_queue, - self._result_queue, - self._initializer, - self._initargs, - self._max_tasks_per_child)) - p.start() - self._processes[p.pid] = p - - def submit(self, fn, /, *args, **kwargs): - with self._shutdown_lock: - if self._broken: - raise BrokenProcessPool(self._broken) - if self._shutdown_thread: - raise RuntimeError('cannot schedule new futures after shutdown') - if _global_shutdown: - raise RuntimeError('cannot schedule new futures after ' - 'interpreter shutdown') - - f = _base.Future() - w = _WorkItem(f, fn, args, kwargs) - - self._pending_work_items[self._queue_count] = w - self._work_ids.put(self._queue_count) - self._queue_count += 1 - # Wake up queue management thread - self._executor_manager_thread_wakeup.wakeup() - - if self._safe_to_dynamically_spawn_children: - self._adjust_process_count() - self._start_executor_manager_thread() - return f - submit.__doc__ = _base.Executor.submit.__doc__ - - def map(self, fn, *iterables, timeout=None, chunksize=1): - """Returns an iterator equivalent to map(fn, iter). - - Args: - fn: A callable that will take as many arguments as there are - passed iterables. - timeout: The maximum number of seconds to wait. If None, then there - is no limit on the wait time. - chunksize: If greater than one, the iterables will be chopped into - chunks of size chunksize and submitted to the process pool. - If set to one, the items in the list will be sent one at a time. - - Returns: - An iterator equivalent to: map(func, *iterables) but the calls may - be evaluated out-of-order. - - Raises: - TimeoutError: If the entire result iterator could not be generated - before the given timeout. - Exception: If fn(*args) raises for any values. - """ - if chunksize < 1: - raise ValueError("chunksize must be >= 1.") - - results = super().map(partial(_process_chunk, fn), - _get_chunks(*iterables, chunksize=chunksize), - timeout=timeout) - return _chain_from_iterable_of_lists(results) - - def shutdown(self, wait=True, *, cancel_futures=False): - with self._shutdown_lock: - self._cancel_pending_futures = cancel_futures - self._shutdown_thread = True - if self._executor_manager_thread_wakeup is not None: - # Wake up queue management thread - self._executor_manager_thread_wakeup.wakeup() - - if self._executor_manager_thread is not None and wait: - self._executor_manager_thread.join() - # To reduce the risk of opening too many files, remove references to - # objects that use file descriptors. - self._executor_manager_thread = None - self._call_queue = None - if self._result_queue is not None and wait: - self._result_queue.close() - self._result_queue = None - self._processes = None - self._executor_manager_thread_wakeup = None - - shutdown.__doc__ = _base.Executor.shutdown.__doc__ diff --git a/python/Lib/concurrent/futures/thread.py b/python/Lib/concurrent/futures/thread.py deleted file mode 100644 index fdda936..0000000 --- a/python/Lib/concurrent/futures/thread.py +++ /dev/null @@ -1,236 +0,0 @@ -# Copyright 2009 Brian Quinlan. All Rights Reserved. -# Licensed to PSF under a Contributor Agreement. - -"""Implements ThreadPoolExecutor.""" - -__author__ = 'Brian Quinlan (brian@sweetapp.com)' - -from concurrent.futures import _base -import itertools -import queue -import threading -import types -import weakref -import os - - -_threads_queues = weakref.WeakKeyDictionary() -_shutdown = False -# Lock that ensures that new workers are not created while the interpreter is -# shutting down. Must be held while mutating _threads_queues and _shutdown. -_global_shutdown_lock = threading.Lock() - -def _python_exit(): - global _shutdown - with _global_shutdown_lock: - _shutdown = True - items = list(_threads_queues.items()) - for t, q in items: - q.put(None) - for t, q in items: - t.join() - -# Register for `_python_exit()` to be called just before joining all -# non-daemon threads. This is used instead of `atexit.register()` for -# compatibility with subinterpreters, which no longer support daemon threads. -# See bpo-39812 for context. -threading._register_atexit(_python_exit) - -# At fork, reinitialize the `_global_shutdown_lock` lock in the child process -if hasattr(os, 'register_at_fork'): - os.register_at_fork(before=_global_shutdown_lock.acquire, - after_in_child=_global_shutdown_lock._at_fork_reinit, - after_in_parent=_global_shutdown_lock.release) - - -class _WorkItem(object): - def __init__(self, future, fn, args, kwargs): - self.future = future - self.fn = fn - self.args = args - self.kwargs = kwargs - - def run(self): - if not self.future.set_running_or_notify_cancel(): - return - - try: - result = self.fn(*self.args, **self.kwargs) - except BaseException as exc: - self.future.set_exception(exc) - # Break a reference cycle with the exception 'exc' - self = None - else: - self.future.set_result(result) - - __class_getitem__ = classmethod(types.GenericAlias) - - -def _worker(executor_reference, work_queue, initializer, initargs): - if initializer is not None: - try: - initializer(*initargs) - except BaseException: - _base.LOGGER.critical('Exception in initializer:', exc_info=True) - executor = executor_reference() - if executor is not None: - executor._initializer_failed() - return - try: - while True: - work_item = work_queue.get(block=True) - if work_item is not None: - work_item.run() - # Delete references to object. See issue16284 - del work_item - - # attempt to increment idle count - executor = executor_reference() - if executor is not None: - executor._idle_semaphore.release() - del executor - continue - - executor = executor_reference() - # Exit if: - # - The interpreter is shutting down OR - # - The executor that owns the worker has been collected OR - # - The executor that owns the worker has been shutdown. - if _shutdown or executor is None or executor._shutdown: - # Flag the executor as shutting down as early as possible if it - # is not gc-ed yet. - if executor is not None: - executor._shutdown = True - # Notice other workers - work_queue.put(None) - return - del executor - except BaseException: - _base.LOGGER.critical('Exception in worker', exc_info=True) - - -class BrokenThreadPool(_base.BrokenExecutor): - """ - Raised when a worker thread in a ThreadPoolExecutor failed initializing. - """ - - -class ThreadPoolExecutor(_base.Executor): - - # Used to assign unique thread names when thread_name_prefix is not supplied. - _counter = itertools.count().__next__ - - def __init__(self, max_workers=None, thread_name_prefix='', - initializer=None, initargs=()): - """Initializes a new ThreadPoolExecutor instance. - - Args: - max_workers: The maximum number of threads that can be used to - execute the given calls. - thread_name_prefix: An optional name prefix to give our threads. - initializer: A callable used to initialize worker threads. - initargs: A tuple of arguments to pass to the initializer. - """ - if max_workers is None: - # ThreadPoolExecutor is often used to: - # * CPU bound task which releases GIL - # * I/O bound task (which releases GIL, of course) - # - # We use cpu_count + 4 for both types of tasks. - # But we limit it to 32 to avoid consuming surprisingly large resource - # on many core machine. - max_workers = min(32, (os.cpu_count() or 1) + 4) - if max_workers <= 0: - raise ValueError("max_workers must be greater than 0") - - if initializer is not None and not callable(initializer): - raise TypeError("initializer must be a callable") - - self._max_workers = max_workers - self._work_queue = queue.SimpleQueue() - self._idle_semaphore = threading.Semaphore(0) - self._threads = set() - self._broken = False - self._shutdown = False - self._shutdown_lock = threading.Lock() - self._thread_name_prefix = (thread_name_prefix or - ("ThreadPoolExecutor-%d" % self._counter())) - self._initializer = initializer - self._initargs = initargs - - def submit(self, fn, /, *args, **kwargs): - with self._shutdown_lock, _global_shutdown_lock: - if self._broken: - raise BrokenThreadPool(self._broken) - - if self._shutdown: - raise RuntimeError('cannot schedule new futures after shutdown') - if _shutdown: - raise RuntimeError('cannot schedule new futures after ' - 'interpreter shutdown') - - f = _base.Future() - w = _WorkItem(f, fn, args, kwargs) - - self._work_queue.put(w) - self._adjust_thread_count() - return f - submit.__doc__ = _base.Executor.submit.__doc__ - - def _adjust_thread_count(self): - # if idle threads are available, don't spin new threads - if self._idle_semaphore.acquire(timeout=0): - return - - # When the executor gets lost, the weakref callback will wake up - # the worker threads. - def weakref_cb(_, q=self._work_queue): - q.put(None) - - num_threads = len(self._threads) - if num_threads < self._max_workers: - thread_name = '%s_%d' % (self._thread_name_prefix or self, - num_threads) - t = threading.Thread(name=thread_name, target=_worker, - args=(weakref.ref(self, weakref_cb), - self._work_queue, - self._initializer, - self._initargs)) - t.start() - self._threads.add(t) - _threads_queues[t] = self._work_queue - - def _initializer_failed(self): - with self._shutdown_lock: - self._broken = ('A thread initializer failed, the thread pool ' - 'is not usable anymore') - # Drain work queue and mark pending futures failed - while True: - try: - work_item = self._work_queue.get_nowait() - except queue.Empty: - break - if work_item is not None: - work_item.future.set_exception(BrokenThreadPool(self._broken)) - - def shutdown(self, wait=True, *, cancel_futures=False): - with self._shutdown_lock: - self._shutdown = True - if cancel_futures: - # Drain all work items from the queue, and then cancel their - # associated futures. - while True: - try: - work_item = self._work_queue.get_nowait() - except queue.Empty: - break - if work_item is not None: - work_item.future.cancel() - - # Send a wake-up to prevent threads calling - # _work_queue.get(block=True) from permanently blocking. - self._work_queue.put(None) - if wait: - for t in self._threads: - t.join() - shutdown.__doc__ = _base.Executor.shutdown.__doc__ diff --git a/python/Lib/configparser.py b/python/Lib/configparser.py deleted file mode 100644 index 5e72ad1..0000000 --- a/python/Lib/configparser.py +++ /dev/null @@ -1,1381 +0,0 @@ -"""Configuration file parser. - -A configuration file consists of sections, lead by a "[section]" header, -and followed by "name: value" entries, with continuations and such in -the style of RFC 822. - -Intrinsic defaults can be specified by passing them into the -ConfigParser constructor as a dictionary. - -class: - -ConfigParser -- responsible for parsing a list of - configuration files, and managing the parsed database. - - methods: - - __init__(defaults=None, dict_type=_default_dict, allow_no_value=False, - delimiters=('=', ':'), comment_prefixes=('#', ';'), - inline_comment_prefixes=None, strict=True, - empty_lines_in_values=True, default_section='DEFAULT', - interpolation=, converters=): - Create the parser. When `defaults' is given, it is initialized into the - dictionary or intrinsic defaults. The keys must be strings, the values - must be appropriate for %()s string interpolation. - - When `dict_type' is given, it will be used to create the dictionary - objects for the list of sections, for the options within a section, and - for the default values. - - When `delimiters' is given, it will be used as the set of substrings - that divide keys from values. - - When `comment_prefixes' is given, it will be used as the set of - substrings that prefix comments in empty lines. Comments can be - indented. - - When `inline_comment_prefixes' is given, it will be used as the set of - substrings that prefix comments in non-empty lines. - - When `strict` is True, the parser won't allow for any section or option - duplicates while reading from a single source (file, string or - dictionary). Default is True. - - When `empty_lines_in_values' is False (default: True), each empty line - marks the end of an option. Otherwise, internal empty lines of - a multiline option are kept as part of the value. - - When `allow_no_value' is True (default: False), options without - values are accepted; the value presented for these is None. - - When `default_section' is given, the name of the special section is - named accordingly. By default it is called ``"DEFAULT"`` but this can - be customized to point to any other valid section name. Its current - value can be retrieved using the ``parser_instance.default_section`` - attribute and may be modified at runtime. - - When `interpolation` is given, it should be an Interpolation subclass - instance. It will be used as the handler for option value - pre-processing when using getters. RawConfigParser objects don't do - any sort of interpolation, whereas ConfigParser uses an instance of - BasicInterpolation. The library also provides a ``zc.buildbot`` - inspired ExtendedInterpolation implementation. - - When `converters` is given, it should be a dictionary where each key - represents the name of a type converter and each value is a callable - implementing the conversion from string to the desired datatype. Every - converter gets its corresponding get*() method on the parser object and - section proxies. - - sections() - Return all the configuration section names, sans DEFAULT. - - has_section(section) - Return whether the given section exists. - - has_option(section, option) - Return whether the given option exists in the given section. - - options(section) - Return list of configuration options for the named section. - - read(filenames, encoding=None) - Read and parse the iterable of named configuration files, given by - name. A single filename is also allowed. Non-existing files - are ignored. Return list of successfully read files. - - read_file(f, filename=None) - Read and parse one configuration file, given as a file object. - The filename defaults to f.name; it is only used in error - messages (if f has no `name' attribute, the string `' is used). - - read_string(string) - Read configuration from a given string. - - read_dict(dictionary) - Read configuration from a dictionary. Keys are section names, - values are dictionaries with keys and values that should be present - in the section. If the used dictionary type preserves order, sections - and their keys will be added in order. Values are automatically - converted to strings. - - get(section, option, raw=False, vars=None, fallback=_UNSET) - Return a string value for the named option. All % interpolations are - expanded in the return values, based on the defaults passed into the - constructor and the DEFAULT section. Additional substitutions may be - provided using the `vars' argument, which must be a dictionary whose - contents override any pre-existing defaults. If `option' is a key in - `vars', the value from `vars' is used. - - getint(section, options, raw=False, vars=None, fallback=_UNSET) - Like get(), but convert value to an integer. - - getfloat(section, options, raw=False, vars=None, fallback=_UNSET) - Like get(), but convert value to a float. - - getboolean(section, options, raw=False, vars=None, fallback=_UNSET) - Like get(), but convert value to a boolean (currently case - insensitively defined as 0, false, no, off for False, and 1, true, - yes, on for True). Returns False or True. - - items(section=_UNSET, raw=False, vars=None) - If section is given, return a list of tuples with (name, value) for - each option in the section. Otherwise, return a list of tuples with - (section_name, section_proxy) for each section, including DEFAULTSECT. - - remove_section(section) - Remove the given file section and all its options. - - remove_option(section, option) - Remove the given option from the given section. - - set(section, option, value) - Set the given option. - - write(fp, space_around_delimiters=True) - Write the configuration state in .ini format. If - `space_around_delimiters' is True (the default), delimiters - between keys and values are surrounded by spaces. -""" - -from collections.abc import MutableMapping -from collections import ChainMap as _ChainMap -import functools -import io -import itertools -import os -import re -import sys -import warnings - -__all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError", - "NoOptionError", "InterpolationError", "InterpolationDepthError", - "InterpolationMissingOptionError", "InterpolationSyntaxError", - "ParsingError", "MissingSectionHeaderError", - "ConfigParser", "SafeConfigParser", "RawConfigParser", - "Interpolation", "BasicInterpolation", "ExtendedInterpolation", - "LegacyInterpolation", "SectionProxy", "ConverterMapping", - "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] - -_default_dict = dict -DEFAULTSECT = "DEFAULT" - -MAX_INTERPOLATION_DEPTH = 10 - - - -# exception classes -class Error(Exception): - """Base class for ConfigParser exceptions.""" - - def __init__(self, msg=''): - self.message = msg - Exception.__init__(self, msg) - - def __repr__(self): - return self.message - - __str__ = __repr__ - - -class NoSectionError(Error): - """Raised when no section matches a requested option.""" - - def __init__(self, section): - Error.__init__(self, 'No section: %r' % (section,)) - self.section = section - self.args = (section, ) - - -class DuplicateSectionError(Error): - """Raised when a section is repeated in an input source. - - Possible repetitions that raise this exception are: multiple creation - using the API or in strict parsers when a section is found more than once - in a single input file, string or dictionary. - """ - - def __init__(self, section, source=None, lineno=None): - msg = [repr(section), " already exists"] - if source is not None: - message = ["While reading from ", repr(source)] - if lineno is not None: - message.append(" [line {0:2d}]".format(lineno)) - message.append(": section ") - message.extend(msg) - msg = message - else: - msg.insert(0, "Section ") - Error.__init__(self, "".join(msg)) - self.section = section - self.source = source - self.lineno = lineno - self.args = (section, source, lineno) - - -class DuplicateOptionError(Error): - """Raised by strict parsers when an option is repeated in an input source. - - Current implementation raises this exception only when an option is found - more than once in a single file, string or dictionary. - """ - - def __init__(self, section, option, source=None, lineno=None): - msg = [repr(option), " in section ", repr(section), - " already exists"] - if source is not None: - message = ["While reading from ", repr(source)] - if lineno is not None: - message.append(" [line {0:2d}]".format(lineno)) - message.append(": option ") - message.extend(msg) - msg = message - else: - msg.insert(0, "Option ") - Error.__init__(self, "".join(msg)) - self.section = section - self.option = option - self.source = source - self.lineno = lineno - self.args = (section, option, source, lineno) - - -class NoOptionError(Error): - """A requested option was not found.""" - - def __init__(self, option, section): - Error.__init__(self, "No option %r in section: %r" % - (option, section)) - self.option = option - self.section = section - self.args = (option, section) - - -class InterpolationError(Error): - """Base class for interpolation-related exceptions.""" - - def __init__(self, option, section, msg): - Error.__init__(self, msg) - self.option = option - self.section = section - self.args = (option, section, msg) - - -class InterpolationMissingOptionError(InterpolationError): - """A string substitution required a setting which was not available.""" - - def __init__(self, option, section, rawval, reference): - msg = ("Bad value substitution: option {!r} in section {!r} contains " - "an interpolation key {!r} which is not a valid option name. " - "Raw value: {!r}".format(option, section, reference, rawval)) - InterpolationError.__init__(self, option, section, msg) - self.reference = reference - self.args = (option, section, rawval, reference) - - -class InterpolationSyntaxError(InterpolationError): - """Raised when the source text contains invalid syntax. - - Current implementation raises this exception when the source text into - which substitutions are made does not conform to the required syntax. - """ - - -class InterpolationDepthError(InterpolationError): - """Raised when substitutions are nested too deeply.""" - - def __init__(self, option, section, rawval): - msg = ("Recursion limit exceeded in value substitution: option {!r} " - "in section {!r} contains an interpolation key which " - "cannot be substituted in {} steps. Raw value: {!r}" - "".format(option, section, MAX_INTERPOLATION_DEPTH, - rawval)) - InterpolationError.__init__(self, option, section, msg) - self.args = (option, section, rawval) - - -class ParsingError(Error): - """Raised when a configuration file does not follow legal syntax.""" - - def __init__(self, source=None, filename=None): - # Exactly one of `source'/`filename' arguments has to be given. - # `filename' kept for compatibility. - if filename and source: - raise ValueError("Cannot specify both `filename' and `source'. " - "Use `source'.") - elif not filename and not source: - raise ValueError("Required argument `source' not given.") - elif filename: - source = filename - Error.__init__(self, 'Source contains parsing errors: %r' % source) - self.source = source - self.errors = [] - self.args = (source, ) - - @property - def filename(self): - """Deprecated, use `source'.""" - warnings.warn( - "The 'filename' attribute will be removed in Python 3.12. " - "Use 'source' instead.", - DeprecationWarning, stacklevel=2 - ) - return self.source - - @filename.setter - def filename(self, value): - """Deprecated, user `source'.""" - warnings.warn( - "The 'filename' attribute will be removed in Python 3.12. " - "Use 'source' instead.", - DeprecationWarning, stacklevel=2 - ) - self.source = value - - def append(self, lineno, line): - self.errors.append((lineno, line)) - self.message += '\n\t[line %2d]: %s' % (lineno, line) - - -class MissingSectionHeaderError(ParsingError): - """Raised when a key-value pair is found before any section header.""" - - def __init__(self, filename, lineno, line): - Error.__init__( - self, - 'File contains no section headers.\nfile: %r, line: %d\n%r' % - (filename, lineno, line)) - self.source = filename - self.lineno = lineno - self.line = line - self.args = (filename, lineno, line) - - -# Used in parser getters to indicate the default behaviour when a specific -# option is not found it to raise an exception. Created to enable `None' as -# a valid fallback value. -_UNSET = object() - - -class Interpolation: - """Dummy interpolation that passes the value through with no changes.""" - - def before_get(self, parser, section, option, value, defaults): - return value - - def before_set(self, parser, section, option, value): - return value - - def before_read(self, parser, section, option, value): - return value - - def before_write(self, parser, section, option, value): - return value - - -class BasicInterpolation(Interpolation): - """Interpolation as implemented in the classic ConfigParser. - - The option values can contain format strings which refer to other values in - the same section, or values in the special default section. - - For example: - - something: %(dir)s/whatever - - would resolve the "%(dir)s" to the value of dir. All reference - expansions are done late, on demand. If a user needs to use a bare % in - a configuration file, she can escape it by writing %%. Other % usage - is considered a user error and raises `InterpolationSyntaxError'.""" - - _KEYCRE = re.compile(r"%\(([^)]+)\)s") - - def before_get(self, parser, section, option, value, defaults): - L = [] - self._interpolate_some(parser, option, L, value, section, defaults, 1) - return ''.join(L) - - def before_set(self, parser, section, option, value): - tmp_value = value.replace('%%', '') # escaped percent signs - tmp_value = self._KEYCRE.sub('', tmp_value) # valid syntax - if '%' in tmp_value: - raise ValueError("invalid interpolation syntax in %r at " - "position %d" % (value, tmp_value.find('%'))) - return value - - def _interpolate_some(self, parser, option, accum, rest, section, map, - depth): - rawval = parser.get(section, option, raw=True, fallback=rest) - if depth > MAX_INTERPOLATION_DEPTH: - raise InterpolationDepthError(option, section, rawval) - while rest: - p = rest.find("%") - if p < 0: - accum.append(rest) - return - if p > 0: - accum.append(rest[:p]) - rest = rest[p:] - # p is no longer used - c = rest[1:2] - if c == "%": - accum.append("%") - rest = rest[2:] - elif c == "(": - m = self._KEYCRE.match(rest) - if m is None: - raise InterpolationSyntaxError(option, section, - "bad interpolation variable reference %r" % rest) - var = parser.optionxform(m.group(1)) - rest = rest[m.end():] - try: - v = map[var] - except KeyError: - raise InterpolationMissingOptionError( - option, section, rawval, var) from None - if "%" in v: - self._interpolate_some(parser, option, accum, v, - section, map, depth + 1) - else: - accum.append(v) - else: - raise InterpolationSyntaxError( - option, section, - "'%%' must be followed by '%%' or '(', " - "found: %r" % (rest,)) - - -class ExtendedInterpolation(Interpolation): - """Advanced variant of interpolation, supports the syntax used by - `zc.buildout'. Enables interpolation between sections.""" - - _KEYCRE = re.compile(r"\$\{([^}]+)\}") - - def before_get(self, parser, section, option, value, defaults): - L = [] - self._interpolate_some(parser, option, L, value, section, defaults, 1) - return ''.join(L) - - def before_set(self, parser, section, option, value): - tmp_value = value.replace('$$', '') # escaped dollar signs - tmp_value = self._KEYCRE.sub('', tmp_value) # valid syntax - if '$' in tmp_value: - raise ValueError("invalid interpolation syntax in %r at " - "position %d" % (value, tmp_value.find('$'))) - return value - - def _interpolate_some(self, parser, option, accum, rest, section, map, - depth): - rawval = parser.get(section, option, raw=True, fallback=rest) - if depth > MAX_INTERPOLATION_DEPTH: - raise InterpolationDepthError(option, section, rawval) - while rest: - p = rest.find("$") - if p < 0: - accum.append(rest) - return - if p > 0: - accum.append(rest[:p]) - rest = rest[p:] - # p is no longer used - c = rest[1:2] - if c == "$": - accum.append("$") - rest = rest[2:] - elif c == "{": - m = self._KEYCRE.match(rest) - if m is None: - raise InterpolationSyntaxError(option, section, - "bad interpolation variable reference %r" % rest) - path = m.group(1).split(':') - rest = rest[m.end():] - sect = section - opt = option - try: - if len(path) == 1: - opt = parser.optionxform(path[0]) - v = map[opt] - elif len(path) == 2: - sect = path[0] - opt = parser.optionxform(path[1]) - v = parser.get(sect, opt, raw=True) - else: - raise InterpolationSyntaxError( - option, section, - "More than one ':' found: %r" % (rest,)) - except (KeyError, NoSectionError, NoOptionError): - raise InterpolationMissingOptionError( - option, section, rawval, ":".join(path)) from None - if "$" in v: - self._interpolate_some(parser, opt, accum, v, sect, - dict(parser.items(sect, raw=True)), - depth + 1) - else: - accum.append(v) - else: - raise InterpolationSyntaxError( - option, section, - "'$' must be followed by '$' or '{', " - "found: %r" % (rest,)) - - -class LegacyInterpolation(Interpolation): - """Deprecated interpolation used in old versions of ConfigParser. - Use BasicInterpolation or ExtendedInterpolation instead.""" - - _KEYCRE = re.compile(r"%\(([^)]*)\)s|.") - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - warnings.warn( - "LegacyInterpolation has been deprecated since Python 3.2 " - "and will be removed from the configparser module in Python 3.13. " - "Use BasicInterpolation or ExtendedInterpolation instead.", - DeprecationWarning, stacklevel=2 - ) - - def before_get(self, parser, section, option, value, vars): - rawval = value - depth = MAX_INTERPOLATION_DEPTH - while depth: # Loop through this until it's done - depth -= 1 - if value and "%(" in value: - replace = functools.partial(self._interpolation_replace, - parser=parser) - value = self._KEYCRE.sub(replace, value) - try: - value = value % vars - except KeyError as e: - raise InterpolationMissingOptionError( - option, section, rawval, e.args[0]) from None - else: - break - if value and "%(" in value: - raise InterpolationDepthError(option, section, rawval) - return value - - def before_set(self, parser, section, option, value): - return value - - @staticmethod - def _interpolation_replace(match, parser): - s = match.group(1) - if s is None: - return match.group() - else: - return "%%(%s)s" % parser.optionxform(s) - - -class RawConfigParser(MutableMapping): - """ConfigParser that does not do interpolation.""" - - # Regular expressions for parsing section headers and options - _SECT_TMPL = r""" - \[ # [ - (?P

    .+) # very permissive! - \] # ] - """ - _OPT_TMPL = r""" - (?P ..." % action) - dir = convert_path(words[1]) - patterns = [convert_path(w) for w in words[2:]] - elif action in ('graft', 'prune'): - if len(words) != 2: - raise DistutilsTemplateError( - "'%s' expects a single " % action) - dir_pattern = convert_path(words[1]) - else: - raise DistutilsTemplateError("unknown action '%s'" % action) - - return (action, patterns, dir, dir_pattern) - - def process_template_line(self, line): - # Parse the line: split it up, make sure the right number of words - # is there, and return the relevant words. 'action' is always - # defined: it's the first word of the line. Which of the other - # three are defined depends on the action; it'll be either - # patterns, (dir and patterns), or (dir_pattern). - (action, patterns, dir, dir_pattern) = self._parse_template_line(line) - - # OK, now we know that the action is valid and we have the - # right number of words on the line for that action -- so we - # can proceed with minimal error-checking. - if action == 'include': - self.debug_print("include " + ' '.join(patterns)) - for pattern in patterns: - if not self.include_pattern(pattern, anchor=1): - log.warn("warning: no files found matching '%s'", - pattern) - - elif action == 'exclude': - self.debug_print("exclude " + ' '.join(patterns)) - for pattern in patterns: - if not self.exclude_pattern(pattern, anchor=1): - log.warn(("warning: no previously-included files " - "found matching '%s'"), pattern) - - elif action == 'global-include': - self.debug_print("global-include " + ' '.join(patterns)) - for pattern in patterns: - if not self.include_pattern(pattern, anchor=0): - log.warn(("warning: no files found matching '%s' " - "anywhere in distribution"), pattern) - - elif action == 'global-exclude': - self.debug_print("global-exclude " + ' '.join(patterns)) - for pattern in patterns: - if not self.exclude_pattern(pattern, anchor=0): - log.warn(("warning: no previously-included files matching " - "'%s' found anywhere in distribution"), - pattern) - - elif action == 'recursive-include': - self.debug_print("recursive-include %s %s" % - (dir, ' '.join(patterns))) - for pattern in patterns: - if not self.include_pattern(pattern, prefix=dir): - log.warn(("warning: no files found matching '%s' " - "under directory '%s'"), - pattern, dir) - - elif action == 'recursive-exclude': - self.debug_print("recursive-exclude %s %s" % - (dir, ' '.join(patterns))) - for pattern in patterns: - if not self.exclude_pattern(pattern, prefix=dir): - log.warn(("warning: no previously-included files matching " - "'%s' found under directory '%s'"), - pattern, dir) - - elif action == 'graft': - self.debug_print("graft " + dir_pattern) - if not self.include_pattern(None, prefix=dir_pattern): - log.warn("warning: no directories found matching '%s'", - dir_pattern) - - elif action == 'prune': - self.debug_print("prune " + dir_pattern) - if not self.exclude_pattern(None, prefix=dir_pattern): - log.warn(("no previously-included directories found " - "matching '%s'"), dir_pattern) - else: - raise DistutilsInternalError( - "this cannot happen: invalid action '%s'" % action) - - - # -- Filtering/selection methods ----------------------------------- - - def include_pattern(self, pattern, anchor=1, prefix=None, is_regex=0): - """Select strings (presumably filenames) from 'self.files' that - match 'pattern', a Unix-style wildcard (glob) pattern. Patterns - are not quite the same as implemented by the 'fnmatch' module: '*' - and '?' match non-special characters, where "special" is platform- - dependent: slash on Unix; colon, slash, and backslash on - DOS/Windows; and colon on Mac OS. - - If 'anchor' is true (the default), then the pattern match is more - stringent: "*.py" will match "foo.py" but not "foo/bar.py". If - 'anchor' is false, both of these will match. - - If 'prefix' is supplied, then only filenames starting with 'prefix' - (itself a pattern) and ending with 'pattern', with anything in between - them, will match. 'anchor' is ignored in this case. - - If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and - 'pattern' is assumed to be either a string containing a regex or a - regex object -- no translation is done, the regex is just compiled - and used as-is. - - Selected strings will be added to self.files. - - Return True if files are found, False otherwise. - """ - # XXX docstring lying about what the special chars are? - files_found = False - pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) - self.debug_print("include_pattern: applying regex r'%s'" % - pattern_re.pattern) - - # delayed loading of allfiles list - if self.allfiles is None: - self.findall() - - for name in self.allfiles: - if pattern_re.search(name): - self.debug_print(" adding " + name) - self.files.append(name) - files_found = True - return files_found - - - def exclude_pattern (self, pattern, - anchor=1, prefix=None, is_regex=0): - """Remove strings (presumably filenames) from 'files' that match - 'pattern'. Other parameters are the same as for - 'include_pattern()', above. - The list 'self.files' is modified in place. - Return True if files are found, False otherwise. - """ - files_found = False - pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) - self.debug_print("exclude_pattern: applying regex r'%s'" % - pattern_re.pattern) - for i in range(len(self.files)-1, -1, -1): - if pattern_re.search(self.files[i]): - self.debug_print(" removing " + self.files[i]) - del self.files[i] - files_found = True - return files_found - - -# ---------------------------------------------------------------------- -# Utility functions - -def _find_all_simple(path): - """ - Find all files under 'path' - """ - results = ( - os.path.join(base, file) - for base, dirs, files in os.walk(path, followlinks=True) - for file in files - ) - return filter(os.path.isfile, results) - - -def findall(dir=os.curdir): - """ - Find all files under 'dir' and return the list of full filenames. - Unless dir is '.', return full filenames with dir prepended. - """ - files = _find_all_simple(dir) - if dir == os.curdir: - make_rel = functools.partial(os.path.relpath, start=dir) - files = map(make_rel, files) - return list(files) - - -def glob_to_re(pattern): - """Translate a shell-like glob pattern to a regular expression; return - a string containing the regex. Differs from 'fnmatch.translate()' in - that '*' does not match "special characters" (which are - platform-specific). - """ - pattern_re = fnmatch.translate(pattern) - - # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which - # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, - # and by extension they shouldn't match such "special characters" under - # any OS. So change all non-escaped dots in the RE to match any - # character except the special characters (currently: just os.sep). - sep = os.sep - if os.sep == '\\': - # we're using a regex to manipulate a regex, so we need - # to escape the backslash twice - sep = r'\\\\' - escaped = r'\1[^%s]' % sep - pattern_re = re.sub(r'((?= self.threshold: - if args: - msg = msg % args - if level in (WARN, ERROR, FATAL): - stream = sys.stderr - else: - stream = sys.stdout - try: - stream.write('%s\n' % msg) - except UnicodeEncodeError: - # emulate backslashreplace error handler - encoding = stream.encoding - msg = msg.encode(encoding, "backslashreplace").decode(encoding) - stream.write('%s\n' % msg) - stream.flush() - - def log(self, level, msg, *args): - self._log(level, msg, args) - - def debug(self, msg, *args): - self._log(DEBUG, msg, args) - - def info(self, msg, *args): - self._log(INFO, msg, args) - - def warn(self, msg, *args): - self._log(WARN, msg, args) - - def error(self, msg, *args): - self._log(ERROR, msg, args) - - def fatal(self, msg, *args): - self._log(FATAL, msg, args) - -_global_log = Log() -log = _global_log.log -debug = _global_log.debug -info = _global_log.info -warn = _global_log.warn -error = _global_log.error -fatal = _global_log.fatal - -def set_threshold(level): - # return the old threshold for use from tests - old = _global_log.threshold - _global_log.threshold = level - return old - -def set_verbosity(v): - if v <= 0: - set_threshold(WARN) - elif v == 1: - set_threshold(INFO) - elif v >= 2: - set_threshold(DEBUG) diff --git a/python/Lib/distutils/msvc9compiler.py b/python/Lib/distutils/msvc9compiler.py deleted file mode 100644 index b43bb1b..0000000 --- a/python/Lib/distutils/msvc9compiler.py +++ /dev/null @@ -1,788 +0,0 @@ -"""distutils.msvc9compiler - -Contains MSVCCompiler, an implementation of the abstract CCompiler class -for the Microsoft Visual Studio 2008. - -The module is compatible with VS 2005 and VS 2008. You can find legacy support -for older versions of VS in distutils.msvccompiler. -""" - -# Written by Perry Stoll -# hacked by Robin Becker and Thomas Heller to do a better job of -# finding DevStudio (through the registry) -# ported to VS2005 and VS 2008 by Christian Heimes - -import os -import subprocess -import sys -import re - -from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError -from distutils.ccompiler import CCompiler, gen_lib_options -from distutils import log -from distutils.util import get_platform - -import winreg - -RegOpenKeyEx = winreg.OpenKeyEx -RegEnumKey = winreg.EnumKey -RegEnumValue = winreg.EnumValue -RegError = winreg.error - -HKEYS = (winreg.HKEY_USERS, - winreg.HKEY_CURRENT_USER, - winreg.HKEY_LOCAL_MACHINE, - winreg.HKEY_CLASSES_ROOT) - -NATIVE_WIN64 = (sys.platform == 'win32' and sys.maxsize > 2**32) -if NATIVE_WIN64: - # Visual C++ is a 32-bit application, so we need to look in - # the corresponding registry branch, if we're running a - # 64-bit Python on Win64 - VS_BASE = r"Software\Wow6432Node\Microsoft\VisualStudio\%0.1f" - WINSDK_BASE = r"Software\Wow6432Node\Microsoft\Microsoft SDKs\Windows" - NET_BASE = r"Software\Wow6432Node\Microsoft\.NETFramework" -else: - VS_BASE = r"Software\Microsoft\VisualStudio\%0.1f" - WINSDK_BASE = r"Software\Microsoft\Microsoft SDKs\Windows" - NET_BASE = r"Software\Microsoft\.NETFramework" - -# A map keyed by get_platform() return values to values accepted by -# 'vcvarsall.bat'. Note a cross-compile may combine these (eg, 'x86_amd64' is -# the param to cross-compile on x86 targeting amd64.) -PLAT_TO_VCVARS = { - 'win32' : 'x86', - 'win-amd64' : 'amd64', -} - -class Reg: - """Helper class to read values from the registry - """ - - def get_value(cls, path, key): - for base in HKEYS: - d = cls.read_values(base, path) - if d and key in d: - return d[key] - raise KeyError(key) - get_value = classmethod(get_value) - - def read_keys(cls, base, key): - """Return list of registry keys.""" - try: - handle = RegOpenKeyEx(base, key) - except RegError: - return None - L = [] - i = 0 - while True: - try: - k = RegEnumKey(handle, i) - except RegError: - break - L.append(k) - i += 1 - return L - read_keys = classmethod(read_keys) - - def read_values(cls, base, key): - """Return dict of registry keys and values. - - All names are converted to lowercase. - """ - try: - handle = RegOpenKeyEx(base, key) - except RegError: - return None - d = {} - i = 0 - while True: - try: - name, value, type = RegEnumValue(handle, i) - except RegError: - break - name = name.lower() - d[cls.convert_mbcs(name)] = cls.convert_mbcs(value) - i += 1 - return d - read_values = classmethod(read_values) - - def convert_mbcs(s): - dec = getattr(s, "decode", None) - if dec is not None: - try: - s = dec("mbcs") - except UnicodeError: - pass - return s - convert_mbcs = staticmethod(convert_mbcs) - -class MacroExpander: - - def __init__(self, version): - self.macros = {} - self.vsbase = VS_BASE % version - self.load_macros(version) - - def set_macro(self, macro, path, key): - self.macros["$(%s)" % macro] = Reg.get_value(path, key) - - def load_macros(self, version): - self.set_macro("VCInstallDir", self.vsbase + r"\Setup\VC", "productdir") - self.set_macro("VSInstallDir", self.vsbase + r"\Setup\VS", "productdir") - self.set_macro("FrameworkDir", NET_BASE, "installroot") - try: - if version >= 8.0: - self.set_macro("FrameworkSDKDir", NET_BASE, - "sdkinstallrootv2.0") - else: - raise KeyError("sdkinstallrootv2.0") - except KeyError: - raise DistutilsPlatformError( - """Python was built with Visual Studio 2008; -extensions must be built with a compiler than can generate compatible binaries. -Visual Studio 2008 was not found on this system. If you have Cygwin installed, -you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") - - if version >= 9.0: - self.set_macro("FrameworkVersion", self.vsbase, "clr version") - self.set_macro("WindowsSdkDir", WINSDK_BASE, "currentinstallfolder") - else: - p = r"Software\Microsoft\NET Framework Setup\Product" - for base in HKEYS: - try: - h = RegOpenKeyEx(base, p) - except RegError: - continue - key = RegEnumKey(h, 0) - d = Reg.get_value(base, r"%s\%s" % (p, key)) - self.macros["$(FrameworkVersion)"] = d["version"] - - def sub(self, s): - for k, v in self.macros.items(): - s = s.replace(k, v) - return s - -def get_build_version(): - """Return the version of MSVC that was used to build Python. - - For Python 2.3 and up, the version number is included in - sys.version. For earlier versions, assume the compiler is MSVC 6. - """ - prefix = "MSC v." - i = sys.version.find(prefix) - if i == -1: - return 6 - i = i + len(prefix) - s, rest = sys.version[i:].split(" ", 1) - majorVersion = int(s[:-2]) - 6 - if majorVersion >= 13: - # v13 was skipped and should be v14 - majorVersion += 1 - minorVersion = int(s[2:3]) / 10.0 - # I don't think paths are affected by minor version in version 6 - if majorVersion == 6: - minorVersion = 0 - if majorVersion >= 6: - return majorVersion + minorVersion - # else we don't know what version of the compiler this is - return None - -def normalize_and_reduce_paths(paths): - """Return a list of normalized paths with duplicates removed. - - The current order of paths is maintained. - """ - # Paths are normalized so things like: /a and /a/ aren't both preserved. - reduced_paths = [] - for p in paths: - np = os.path.normpath(p) - # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set. - if np not in reduced_paths: - reduced_paths.append(np) - return reduced_paths - -def removeDuplicates(variable): - """Remove duplicate values of an environment variable. - """ - oldList = variable.split(os.pathsep) - newList = [] - for i in oldList: - if i not in newList: - newList.append(i) - newVariable = os.pathsep.join(newList) - return newVariable - -def find_vcvarsall(version): - """Find the vcvarsall.bat file - - At first it tries to find the productdir of VS 2008 in the registry. If - that fails it falls back to the VS90COMNTOOLS env var. - """ - vsbase = VS_BASE % version - try: - productdir = Reg.get_value(r"%s\Setup\VC" % vsbase, - "productdir") - except KeyError: - log.debug("Unable to find productdir in registry") - productdir = None - - if not productdir or not os.path.isdir(productdir): - toolskey = "VS%0.f0COMNTOOLS" % version - toolsdir = os.environ.get(toolskey, None) - - if toolsdir and os.path.isdir(toolsdir): - productdir = os.path.join(toolsdir, os.pardir, os.pardir, "VC") - productdir = os.path.abspath(productdir) - if not os.path.isdir(productdir): - log.debug("%s is not a valid directory" % productdir) - return None - else: - log.debug("Env var %s is not set or invalid" % toolskey) - if not productdir: - log.debug("No productdir found") - return None - vcvarsall = os.path.join(productdir, "vcvarsall.bat") - if os.path.isfile(vcvarsall): - return vcvarsall - log.debug("Unable to find vcvarsall.bat") - return None - -def query_vcvarsall(version, arch="x86"): - """Launch vcvarsall.bat and read the settings from its environment - """ - vcvarsall = find_vcvarsall(version) - interesting = {"include", "lib", "libpath", "path"} - result = {} - - if vcvarsall is None: - raise DistutilsPlatformError("Unable to find vcvarsall.bat") - log.debug("Calling 'vcvarsall.bat %s' (version=%s)", arch, version) - popen = subprocess.Popen('"%s" %s & set' % (vcvarsall, arch), - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - try: - stdout, stderr = popen.communicate() - if popen.wait() != 0: - raise DistutilsPlatformError(stderr.decode("mbcs")) - - stdout = stdout.decode("mbcs") - for line in stdout.split("\n"): - line = Reg.convert_mbcs(line) - if '=' not in line: - continue - line = line.strip() - key, value = line.split('=', 1) - key = key.lower() - if key in interesting: - if value.endswith(os.pathsep): - value = value[:-1] - result[key] = removeDuplicates(value) - - finally: - popen.stdout.close() - popen.stderr.close() - - if len(result) != len(interesting): - raise ValueError(str(list(result.keys()))) - - return result - -# More globals -VERSION = get_build_version() -if VERSION < 8.0: - raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION) -# MACROS = MacroExpander(VERSION) - -class MSVCCompiler(CCompiler) : - """Concrete class that implements an interface to Microsoft Visual C++, - as defined by the CCompiler abstract class.""" - - compiler_type = 'msvc' - - # Just set this so CCompiler's constructor doesn't barf. We currently - # don't use the 'set_executables()' bureaucracy provided by CCompiler, - # as it really isn't necessary for this sort of single-compiler class. - # Would be nice to have a consistent interface with UnixCCompiler, - # though, so it's worth thinking about. - executables = {} - - # Private class data (need to distinguish C from C++ source for compiler) - _c_extensions = ['.c'] - _cpp_extensions = ['.cc', '.cpp', '.cxx'] - _rc_extensions = ['.rc'] - _mc_extensions = ['.mc'] - - # Needed for the filename generation methods provided by the - # base class, CCompiler. - src_extensions = (_c_extensions + _cpp_extensions + - _rc_extensions + _mc_extensions) - res_extension = '.res' - obj_extension = '.obj' - static_lib_extension = '.lib' - shared_lib_extension = '.dll' - static_lib_format = shared_lib_format = '%s%s' - exe_extension = '.exe' - - def __init__(self, verbose=0, dry_run=0, force=0): - CCompiler.__init__ (self, verbose, dry_run, force) - self.__version = VERSION - self.__root = r"Software\Microsoft\VisualStudio" - # self.__macros = MACROS - self.__paths = [] - # target platform (.plat_name is consistent with 'bdist') - self.plat_name = None - self.__arch = None # deprecated name - self.initialized = False - - def initialize(self, plat_name=None): - # multi-init means we would need to check platform same each time... - assert not self.initialized, "don't init multiple times" - if plat_name is None: - plat_name = get_platform() - # sanity check for platforms to prevent obscure errors later. - ok_plats = 'win32', 'win-amd64' - if plat_name not in ok_plats: - raise DistutilsPlatformError("--plat-name must be one of %s" % - (ok_plats,)) - - if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"): - # Assume that the SDK set up everything alright; don't try to be - # smarter - self.cc = "cl.exe" - self.linker = "link.exe" - self.lib = "lib.exe" - self.rc = "rc.exe" - self.mc = "mc.exe" - else: - # On x86, 'vcvars32.bat amd64' creates an env that doesn't work; - # to cross compile, you use 'x86_amd64'. - # On AMD64, 'vcvars32.bat amd64' is a native build env; to cross - # compile use 'x86' (ie, it runs the x86 compiler directly) - if plat_name == get_platform() or plat_name == 'win32': - # native build or cross-compile to win32 - plat_spec = PLAT_TO_VCVARS[plat_name] - else: - # cross compile from win32 -> some 64bit - plat_spec = PLAT_TO_VCVARS[get_platform()] + '_' + \ - PLAT_TO_VCVARS[plat_name] - - vc_env = query_vcvarsall(VERSION, plat_spec) - - self.__paths = vc_env['path'].split(os.pathsep) - os.environ['lib'] = vc_env['lib'] - os.environ['include'] = vc_env['include'] - - if len(self.__paths) == 0: - raise DistutilsPlatformError("Python was built with %s, " - "and extensions need to be built with the same " - "version of the compiler, but it isn't installed." - % self.__product) - - self.cc = self.find_exe("cl.exe") - self.linker = self.find_exe("link.exe") - self.lib = self.find_exe("lib.exe") - self.rc = self.find_exe("rc.exe") # resource compiler - self.mc = self.find_exe("mc.exe") # message compiler - #self.set_path_env_var('lib') - #self.set_path_env_var('include') - - # extend the MSVC path with the current path - try: - for p in os.environ['path'].split(';'): - self.__paths.append(p) - except KeyError: - pass - self.__paths = normalize_and_reduce_paths(self.__paths) - os.environ['path'] = ";".join(self.__paths) - - self.preprocess_options = None - if self.__arch == "x86": - self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', - '/DNDEBUG'] - self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', - '/Z7', '/D_DEBUG'] - else: - # Win64 - self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' , - '/DNDEBUG'] - self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-', - '/Z7', '/D_DEBUG'] - - self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] - if self.__version >= 7: - self.ldflags_shared_debug = [ - '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG' - ] - self.ldflags_static = [ '/nologo'] - - self.initialized = True - - # -- Worker methods ------------------------------------------------ - - def object_filenames(self, - source_filenames, - strip_dir=0, - output_dir=''): - # Copied from ccompiler.py, extended to return .res as 'object'-file - # for .rc input file - if output_dir is None: output_dir = '' - obj_names = [] - for src_name in source_filenames: - (base, ext) = os.path.splitext (src_name) - base = os.path.splitdrive(base)[1] # Chop off the drive - base = base[os.path.isabs(base):] # If abs, chop off leading / - if ext not in self.src_extensions: - # Better to raise an exception instead of silently continuing - # and later complain about sources and targets having - # different lengths - raise CompileError ("Don't know how to compile %s" % src_name) - if strip_dir: - base = os.path.basename (base) - if ext in self._rc_extensions: - obj_names.append (os.path.join (output_dir, - base + self.res_extension)) - elif ext in self._mc_extensions: - obj_names.append (os.path.join (output_dir, - base + self.res_extension)) - else: - obj_names.append (os.path.join (output_dir, - base + self.obj_extension)) - return obj_names - - - def compile(self, sources, - output_dir=None, macros=None, include_dirs=None, debug=0, - extra_preargs=None, extra_postargs=None, depends=None): - - if not self.initialized: - self.initialize() - compile_info = self._setup_compile(output_dir, macros, include_dirs, - sources, depends, extra_postargs) - macros, objects, extra_postargs, pp_opts, build = compile_info - - compile_opts = extra_preargs or [] - compile_opts.append ('/c') - if debug: - compile_opts.extend(self.compile_options_debug) - else: - compile_opts.extend(self.compile_options) - - for obj in objects: - try: - src, ext = build[obj] - except KeyError: - continue - if debug: - # pass the full pathname to MSVC in debug mode, - # this allows the debugger to find the source file - # without asking the user to browse for it - src = os.path.abspath(src) - - if ext in self._c_extensions: - input_opt = "/Tc" + src - elif ext in self._cpp_extensions: - input_opt = "/Tp" + src - elif ext in self._rc_extensions: - # compile .RC to .RES file - input_opt = src - output_opt = "/fo" + obj - try: - self.spawn([self.rc] + pp_opts + - [output_opt] + [input_opt]) - except DistutilsExecError as msg: - raise CompileError(msg) - continue - elif ext in self._mc_extensions: - # Compile .MC to .RC file to .RES file. - # * '-h dir' specifies the directory for the - # generated include file - # * '-r dir' specifies the target directory of the - # generated RC file and the binary message resource - # it includes - # - # For now (since there are no options to change this), - # we use the source-directory for the include file and - # the build directory for the RC file and message - # resources. This works at least for win32all. - h_dir = os.path.dirname(src) - rc_dir = os.path.dirname(obj) - try: - # first compile .MC to .RC and .H file - self.spawn([self.mc] + - ['-h', h_dir, '-r', rc_dir] + [src]) - base, _ = os.path.splitext (os.path.basename (src)) - rc_file = os.path.join (rc_dir, base + '.rc') - # then compile .RC to .RES file - self.spawn([self.rc] + - ["/fo" + obj] + [rc_file]) - - except DistutilsExecError as msg: - raise CompileError(msg) - continue - else: - # how to handle this file? - raise CompileError("Don't know how to compile %s to %s" - % (src, obj)) - - output_opt = "/Fo" + obj - try: - self.spawn([self.cc] + compile_opts + pp_opts + - [input_opt, output_opt] + - extra_postargs) - except DistutilsExecError as msg: - raise CompileError(msg) - - return objects - - - def create_static_lib(self, - objects, - output_libname, - output_dir=None, - debug=0, - target_lang=None): - - if not self.initialized: - self.initialize() - (objects, output_dir) = self._fix_object_args(objects, output_dir) - output_filename = self.library_filename(output_libname, - output_dir=output_dir) - - if self._need_link(objects, output_filename): - lib_args = objects + ['/OUT:' + output_filename] - if debug: - pass # XXX what goes here? - try: - self.spawn([self.lib] + lib_args) - except DistutilsExecError as msg: - raise LibError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - - def link(self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - - if not self.initialized: - self.initialize() - (objects, output_dir) = self._fix_object_args(objects, output_dir) - fixed_args = self._fix_lib_args(libraries, library_dirs, - runtime_library_dirs) - (libraries, library_dirs, runtime_library_dirs) = fixed_args - - if runtime_library_dirs: - self.warn ("I don't know what to do with 'runtime_library_dirs': " - + str (runtime_library_dirs)) - - lib_opts = gen_lib_options(self, - library_dirs, runtime_library_dirs, - libraries) - if output_dir is not None: - output_filename = os.path.join(output_dir, output_filename) - - if self._need_link(objects, output_filename): - if target_desc == CCompiler.EXECUTABLE: - if debug: - ldflags = self.ldflags_shared_debug[1:] - else: - ldflags = self.ldflags_shared[1:] - else: - if debug: - ldflags = self.ldflags_shared_debug - else: - ldflags = self.ldflags_shared - - export_opts = [] - for sym in (export_symbols or []): - export_opts.append("/EXPORT:" + sym) - - ld_args = (ldflags + lib_opts + export_opts + - objects + ['/OUT:' + output_filename]) - - # The MSVC linker generates .lib and .exp files, which cannot be - # suppressed by any linker switches. The .lib files may even be - # needed! Make sure they are generated in the temporary build - # directory. Since they have different names for debug and release - # builds, they can go into the same directory. - build_temp = os.path.dirname(objects[0]) - if export_symbols is not None: - (dll_name, dll_ext) = os.path.splitext( - os.path.basename(output_filename)) - implib_file = os.path.join( - build_temp, - self.library_filename(dll_name)) - ld_args.append ('/IMPLIB:' + implib_file) - - self.manifest_setup_ldargs(output_filename, build_temp, ld_args) - - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - - self.mkpath(os.path.dirname(output_filename)) - try: - self.spawn([self.linker] + ld_args) - except DistutilsExecError as msg: - raise LinkError(msg) - - # embed the manifest - # XXX - this is somewhat fragile - if mt.exe fails, distutils - # will still consider the DLL up-to-date, but it will not have a - # manifest. Maybe we should link to a temp file? OTOH, that - # implies a build environment error that shouldn't go undetected. - mfinfo = self.manifest_get_embed_info(target_desc, ld_args) - if mfinfo is not None: - mffilename, mfid = mfinfo - out_arg = '-outputresource:%s;%s' % (output_filename, mfid) - try: - self.spawn(['mt.exe', '-nologo', '-manifest', - mffilename, out_arg]) - except DistutilsExecError as msg: - raise LinkError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - def manifest_setup_ldargs(self, output_filename, build_temp, ld_args): - # If we need a manifest at all, an embedded manifest is recommended. - # See MSDN article titled - # "How to: Embed a Manifest Inside a C/C++ Application" - # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx) - # Ask the linker to generate the manifest in the temp dir, so - # we can check it, and possibly embed it, later. - temp_manifest = os.path.join( - build_temp, - os.path.basename(output_filename) + ".manifest") - ld_args.append('/MANIFESTFILE:' + temp_manifest) - - def manifest_get_embed_info(self, target_desc, ld_args): - # If a manifest should be embedded, return a tuple of - # (manifest_filename, resource_id). Returns None if no manifest - # should be embedded. See http://bugs.python.org/issue7833 for why - # we want to avoid any manifest for extension modules if we can. - for arg in ld_args: - if arg.startswith("/MANIFESTFILE:"): - temp_manifest = arg.split(":", 1)[1] - break - else: - # no /MANIFESTFILE so nothing to do. - return None - if target_desc == CCompiler.EXECUTABLE: - # by default, executables always get the manifest with the - # CRT referenced. - mfid = 1 - else: - # Extension modules try and avoid any manifest if possible. - mfid = 2 - temp_manifest = self._remove_visual_c_ref(temp_manifest) - if temp_manifest is None: - return None - return temp_manifest, mfid - - def _remove_visual_c_ref(self, manifest_file): - try: - # Remove references to the Visual C runtime, so they will - # fall through to the Visual C dependency of Python.exe. - # This way, when installed for a restricted user (e.g. - # runtimes are not in WinSxS folder, but in Python's own - # folder), the runtimes do not need to be in every folder - # with .pyd's. - # Returns either the filename of the modified manifest or - # None if no manifest should be embedded. - manifest_f = open(manifest_file) - try: - manifest_buf = manifest_f.read() - finally: - manifest_f.close() - pattern = re.compile( - r"""|)""", - re.DOTALL) - manifest_buf = re.sub(pattern, "", manifest_buf) - pattern = r"\s*" - manifest_buf = re.sub(pattern, "", manifest_buf) - # Now see if any other assemblies are referenced - if not, we - # don't want a manifest embedded. - pattern = re.compile( - r"""|)""", re.DOTALL) - if re.search(pattern, manifest_buf) is None: - return None - - manifest_f = open(manifest_file, 'w') - try: - manifest_f.write(manifest_buf) - return manifest_file - finally: - manifest_f.close() - except OSError: - pass - - # -- Miscellaneous methods ----------------------------------------- - # These are all used by the 'gen_lib_options() function, in - # ccompiler.py. - - def library_dir_option(self, dir): - return "/LIBPATH:" + dir - - def runtime_library_dir_option(self, dir): - raise DistutilsPlatformError( - "don't know how to set runtime library search path for MSVC++") - - def library_option(self, lib): - return self.library_filename(lib) - - - def find_library_file(self, dirs, lib, debug=0): - # Prefer a debugging library if found (and requested), but deal - # with it if we don't have one. - if debug: - try_names = [lib + "_d", lib] - else: - try_names = [lib] - for dir in dirs: - for name in try_names: - libfile = os.path.join(dir, self.library_filename (name)) - if os.path.exists(libfile): - return libfile - else: - # Oops, didn't find it in *any* of 'dirs' - return None - - # Helper methods for using the MSVC registry settings - - def find_exe(self, exe): - """Return path to an MSVC executable program. - - Tries to find the program in several places: first, one of the - MSVC program search paths from the registry; next, the directories - in the PATH environment variable. If any of those work, return an - absolute path that is known to exist. If none of them work, just - return the original program name, 'exe'. - """ - for p in self.__paths: - fn = os.path.join(os.path.abspath(p), exe) - if os.path.isfile(fn): - return fn - - # didn't find it; try existing path - for p in os.environ['Path'].split(';'): - fn = os.path.join(os.path.abspath(p),exe) - if os.path.isfile(fn): - return fn - - return exe diff --git a/python/Lib/distutils/msvccompiler.py b/python/Lib/distutils/msvccompiler.py deleted file mode 100644 index de2900c..0000000 --- a/python/Lib/distutils/msvccompiler.py +++ /dev/null @@ -1,642 +0,0 @@ -"""distutils.msvccompiler - -Contains MSVCCompiler, an implementation of the abstract CCompiler class -for the Microsoft Visual Studio. -""" - -# Written by Perry Stoll -# hacked by Robin Becker and Thomas Heller to do a better job of -# finding DevStudio (through the registry) - -import sys, os -from distutils.errors import \ - DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError -from distutils.ccompiler import \ - CCompiler, gen_lib_options -from distutils import log - -_can_read_reg = False -try: - import winreg - - _can_read_reg = True - hkey_mod = winreg - - RegOpenKeyEx = winreg.OpenKeyEx - RegEnumKey = winreg.EnumKey - RegEnumValue = winreg.EnumValue - RegError = winreg.error - -except ImportError: - try: - import win32api - import win32con - _can_read_reg = True - hkey_mod = win32con - - RegOpenKeyEx = win32api.RegOpenKeyEx - RegEnumKey = win32api.RegEnumKey - RegEnumValue = win32api.RegEnumValue - RegError = win32api.error - except ImportError: - log.info("Warning: Can't read registry to find the " - "necessary compiler setting\n" - "Make sure that Python modules winreg, " - "win32api or win32con are installed.") - -if _can_read_reg: - HKEYS = (hkey_mod.HKEY_USERS, - hkey_mod.HKEY_CURRENT_USER, - hkey_mod.HKEY_LOCAL_MACHINE, - hkey_mod.HKEY_CLASSES_ROOT) - -def read_keys(base, key): - """Return list of registry keys.""" - try: - handle = RegOpenKeyEx(base, key) - except RegError: - return None - L = [] - i = 0 - while True: - try: - k = RegEnumKey(handle, i) - except RegError: - break - L.append(k) - i += 1 - return L - -def read_values(base, key): - """Return dict of registry keys and values. - - All names are converted to lowercase. - """ - try: - handle = RegOpenKeyEx(base, key) - except RegError: - return None - d = {} - i = 0 - while True: - try: - name, value, type = RegEnumValue(handle, i) - except RegError: - break - name = name.lower() - d[convert_mbcs(name)] = convert_mbcs(value) - i += 1 - return d - -def convert_mbcs(s): - dec = getattr(s, "decode", None) - if dec is not None: - try: - s = dec("mbcs") - except UnicodeError: - pass - return s - -class MacroExpander: - def __init__(self, version): - self.macros = {} - self.load_macros(version) - - def set_macro(self, macro, path, key): - for base in HKEYS: - d = read_values(base, path) - if d: - self.macros["$(%s)" % macro] = d[key] - break - - def load_macros(self, version): - vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version - self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir") - self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir") - net = r"Software\Microsoft\.NETFramework" - self.set_macro("FrameworkDir", net, "installroot") - try: - if version > 7.0: - self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1") - else: - self.set_macro("FrameworkSDKDir", net, "sdkinstallroot") - except KeyError as exc: # - raise DistutilsPlatformError( - """Python was built with Visual Studio 2003; -extensions must be built with a compiler than can generate compatible binaries. -Visual Studio 2003 was not found on this system. If you have Cygwin installed, -you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") - - p = r"Software\Microsoft\NET Framework Setup\Product" - for base in HKEYS: - try: - h = RegOpenKeyEx(base, p) - except RegError: - continue - key = RegEnumKey(h, 0) - d = read_values(base, r"%s\%s" % (p, key)) - self.macros["$(FrameworkVersion)"] = d["version"] - - def sub(self, s): - for k, v in self.macros.items(): - s = s.replace(k, v) - return s - -def get_build_version(): - """Return the version of MSVC that was used to build Python. - - For Python 2.3 and up, the version number is included in - sys.version. For earlier versions, assume the compiler is MSVC 6. - """ - prefix = "MSC v." - i = sys.version.find(prefix) - if i == -1: - return 6 - i = i + len(prefix) - s, rest = sys.version[i:].split(" ", 1) - majorVersion = int(s[:-2]) - 6 - if majorVersion >= 13: - # v13 was skipped and should be v14 - majorVersion += 1 - minorVersion = int(s[2:3]) / 10.0 - # I don't think paths are affected by minor version in version 6 - if majorVersion == 6: - minorVersion = 0 - if majorVersion >= 6: - return majorVersion + minorVersion - # else we don't know what version of the compiler this is - return None - -def get_build_architecture(): - """Return the processor architecture. - - Possible results are "Intel" or "AMD64". - """ - - prefix = " bit (" - i = sys.version.find(prefix) - if i == -1: - return "Intel" - j = sys.version.find(")", i) - return sys.version[i+len(prefix):j] - -def normalize_and_reduce_paths(paths): - """Return a list of normalized paths with duplicates removed. - - The current order of paths is maintained. - """ - # Paths are normalized so things like: /a and /a/ aren't both preserved. - reduced_paths = [] - for p in paths: - np = os.path.normpath(p) - # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set. - if np not in reduced_paths: - reduced_paths.append(np) - return reduced_paths - - -class MSVCCompiler(CCompiler) : - """Concrete class that implements an interface to Microsoft Visual C++, - as defined by the CCompiler abstract class.""" - - compiler_type = 'msvc' - - # Just set this so CCompiler's constructor doesn't barf. We currently - # don't use the 'set_executables()' bureaucracy provided by CCompiler, - # as it really isn't necessary for this sort of single-compiler class. - # Would be nice to have a consistent interface with UnixCCompiler, - # though, so it's worth thinking about. - executables = {} - - # Private class data (need to distinguish C from C++ source for compiler) - _c_extensions = ['.c'] - _cpp_extensions = ['.cc', '.cpp', '.cxx'] - _rc_extensions = ['.rc'] - _mc_extensions = ['.mc'] - - # Needed for the filename generation methods provided by the - # base class, CCompiler. - src_extensions = (_c_extensions + _cpp_extensions + - _rc_extensions + _mc_extensions) - res_extension = '.res' - obj_extension = '.obj' - static_lib_extension = '.lib' - shared_lib_extension = '.dll' - static_lib_format = shared_lib_format = '%s%s' - exe_extension = '.exe' - - def __init__(self, verbose=0, dry_run=0, force=0): - CCompiler.__init__ (self, verbose, dry_run, force) - self.__version = get_build_version() - self.__arch = get_build_architecture() - if self.__arch == "Intel": - # x86 - if self.__version >= 7: - self.__root = r"Software\Microsoft\VisualStudio" - self.__macros = MacroExpander(self.__version) - else: - self.__root = r"Software\Microsoft\Devstudio" - self.__product = "Visual Studio version %s" % self.__version - else: - # Win64. Assume this was built with the platform SDK - self.__product = "Microsoft SDK compiler %s" % (self.__version + 6) - - self.initialized = False - - def initialize(self): - self.__paths = [] - if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"): - # Assume that the SDK set up everything alright; don't try to be - # smarter - self.cc = "cl.exe" - self.linker = "link.exe" - self.lib = "lib.exe" - self.rc = "rc.exe" - self.mc = "mc.exe" - else: - self.__paths = self.get_msvc_paths("path") - - if len(self.__paths) == 0: - raise DistutilsPlatformError("Python was built with %s, " - "and extensions need to be built with the same " - "version of the compiler, but it isn't installed." - % self.__product) - - self.cc = self.find_exe("cl.exe") - self.linker = self.find_exe("link.exe") - self.lib = self.find_exe("lib.exe") - self.rc = self.find_exe("rc.exe") # resource compiler - self.mc = self.find_exe("mc.exe") # message compiler - self.set_path_env_var('lib') - self.set_path_env_var('include') - - # extend the MSVC path with the current path - try: - for p in os.environ['path'].split(';'): - self.__paths.append(p) - except KeyError: - pass - self.__paths = normalize_and_reduce_paths(self.__paths) - os.environ['path'] = ";".join(self.__paths) - - self.preprocess_options = None - if self.__arch == "Intel": - self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' , - '/DNDEBUG'] - self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX', - '/Z7', '/D_DEBUG'] - else: - # Win64 - self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' , - '/DNDEBUG'] - self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-', - '/Z7', '/D_DEBUG'] - - self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] - if self.__version >= 7: - self.ldflags_shared_debug = [ - '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG' - ] - else: - self.ldflags_shared_debug = [ - '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG' - ] - self.ldflags_static = [ '/nologo'] - - self.initialized = True - - # -- Worker methods ------------------------------------------------ - - def object_filenames(self, - source_filenames, - strip_dir=0, - output_dir=''): - # Copied from ccompiler.py, extended to return .res as 'object'-file - # for .rc input file - if output_dir is None: output_dir = '' - obj_names = [] - for src_name in source_filenames: - (base, ext) = os.path.splitext (src_name) - base = os.path.splitdrive(base)[1] # Chop off the drive - base = base[os.path.isabs(base):] # If abs, chop off leading / - if ext not in self.src_extensions: - # Better to raise an exception instead of silently continuing - # and later complain about sources and targets having - # different lengths - raise CompileError ("Don't know how to compile %s" % src_name) - if strip_dir: - base = os.path.basename (base) - if ext in self._rc_extensions: - obj_names.append (os.path.join (output_dir, - base + self.res_extension)) - elif ext in self._mc_extensions: - obj_names.append (os.path.join (output_dir, - base + self.res_extension)) - else: - obj_names.append (os.path.join (output_dir, - base + self.obj_extension)) - return obj_names - - - def compile(self, sources, - output_dir=None, macros=None, include_dirs=None, debug=0, - extra_preargs=None, extra_postargs=None, depends=None): - - if not self.initialized: - self.initialize() - compile_info = self._setup_compile(output_dir, macros, include_dirs, - sources, depends, extra_postargs) - macros, objects, extra_postargs, pp_opts, build = compile_info - - compile_opts = extra_preargs or [] - compile_opts.append ('/c') - if debug: - compile_opts.extend(self.compile_options_debug) - else: - compile_opts.extend(self.compile_options) - - for obj in objects: - try: - src, ext = build[obj] - except KeyError: - continue - if debug: - # pass the full pathname to MSVC in debug mode, - # this allows the debugger to find the source file - # without asking the user to browse for it - src = os.path.abspath(src) - - if ext in self._c_extensions: - input_opt = "/Tc" + src - elif ext in self._cpp_extensions: - input_opt = "/Tp" + src - elif ext in self._rc_extensions: - # compile .RC to .RES file - input_opt = src - output_opt = "/fo" + obj - try: - self.spawn([self.rc] + pp_opts + - [output_opt] + [input_opt]) - except DistutilsExecError as msg: - raise CompileError(msg) - continue - elif ext in self._mc_extensions: - # Compile .MC to .RC file to .RES file. - # * '-h dir' specifies the directory for the - # generated include file - # * '-r dir' specifies the target directory of the - # generated RC file and the binary message resource - # it includes - # - # For now (since there are no options to change this), - # we use the source-directory for the include file and - # the build directory for the RC file and message - # resources. This works at least for win32all. - h_dir = os.path.dirname(src) - rc_dir = os.path.dirname(obj) - try: - # first compile .MC to .RC and .H file - self.spawn([self.mc] + - ['-h', h_dir, '-r', rc_dir] + [src]) - base, _ = os.path.splitext (os.path.basename (src)) - rc_file = os.path.join (rc_dir, base + '.rc') - # then compile .RC to .RES file - self.spawn([self.rc] + - ["/fo" + obj] + [rc_file]) - - except DistutilsExecError as msg: - raise CompileError(msg) - continue - else: - # how to handle this file? - raise CompileError("Don't know how to compile %s to %s" - % (src, obj)) - - output_opt = "/Fo" + obj - try: - self.spawn([self.cc] + compile_opts + pp_opts + - [input_opt, output_opt] + - extra_postargs) - except DistutilsExecError as msg: - raise CompileError(msg) - - return objects - - - def create_static_lib(self, - objects, - output_libname, - output_dir=None, - debug=0, - target_lang=None): - - if not self.initialized: - self.initialize() - (objects, output_dir) = self._fix_object_args(objects, output_dir) - output_filename = self.library_filename(output_libname, - output_dir=output_dir) - - if self._need_link(objects, output_filename): - lib_args = objects + ['/OUT:' + output_filename] - if debug: - pass # XXX what goes here? - try: - self.spawn([self.lib] + lib_args) - except DistutilsExecError as msg: - raise LibError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - - def link(self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - - if not self.initialized: - self.initialize() - (objects, output_dir) = self._fix_object_args(objects, output_dir) - fixed_args = self._fix_lib_args(libraries, library_dirs, - runtime_library_dirs) - (libraries, library_dirs, runtime_library_dirs) = fixed_args - - if runtime_library_dirs: - self.warn ("I don't know what to do with 'runtime_library_dirs': " - + str (runtime_library_dirs)) - - lib_opts = gen_lib_options(self, - library_dirs, runtime_library_dirs, - libraries) - if output_dir is not None: - output_filename = os.path.join(output_dir, output_filename) - - if self._need_link(objects, output_filename): - if target_desc == CCompiler.EXECUTABLE: - if debug: - ldflags = self.ldflags_shared_debug[1:] - else: - ldflags = self.ldflags_shared[1:] - else: - if debug: - ldflags = self.ldflags_shared_debug - else: - ldflags = self.ldflags_shared - - export_opts = [] - for sym in (export_symbols or []): - export_opts.append("/EXPORT:" + sym) - - ld_args = (ldflags + lib_opts + export_opts + - objects + ['/OUT:' + output_filename]) - - # The MSVC linker generates .lib and .exp files, which cannot be - # suppressed by any linker switches. The .lib files may even be - # needed! Make sure they are generated in the temporary build - # directory. Since they have different names for debug and release - # builds, they can go into the same directory. - if export_symbols is not None: - (dll_name, dll_ext) = os.path.splitext( - os.path.basename(output_filename)) - implib_file = os.path.join( - os.path.dirname(objects[0]), - self.library_filename(dll_name)) - ld_args.append ('/IMPLIB:' + implib_file) - - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - - self.mkpath(os.path.dirname(output_filename)) - try: - self.spawn([self.linker] + ld_args) - except DistutilsExecError as msg: - raise LinkError(msg) - - else: - log.debug("skipping %s (up-to-date)", output_filename) - - - # -- Miscellaneous methods ----------------------------------------- - # These are all used by the 'gen_lib_options() function, in - # ccompiler.py. - - def library_dir_option(self, dir): - return "/LIBPATH:" + dir - - def runtime_library_dir_option(self, dir): - raise DistutilsPlatformError( - "don't know how to set runtime library search path for MSVC++") - - def library_option(self, lib): - return self.library_filename(lib) - - - def find_library_file(self, dirs, lib, debug=0): - # Prefer a debugging library if found (and requested), but deal - # with it if we don't have one. - if debug: - try_names = [lib + "_d", lib] - else: - try_names = [lib] - for dir in dirs: - for name in try_names: - libfile = os.path.join(dir, self.library_filename (name)) - if os.path.exists(libfile): - return libfile - else: - # Oops, didn't find it in *any* of 'dirs' - return None - - # Helper methods for using the MSVC registry settings - - def find_exe(self, exe): - """Return path to an MSVC executable program. - - Tries to find the program in several places: first, one of the - MSVC program search paths from the registry; next, the directories - in the PATH environment variable. If any of those work, return an - absolute path that is known to exist. If none of them work, just - return the original program name, 'exe'. - """ - for p in self.__paths: - fn = os.path.join(os.path.abspath(p), exe) - if os.path.isfile(fn): - return fn - - # didn't find it; try existing path - for p in os.environ['Path'].split(';'): - fn = os.path.join(os.path.abspath(p),exe) - if os.path.isfile(fn): - return fn - - return exe - - def get_msvc_paths(self, path, platform='x86'): - """Get a list of devstudio directories (include, lib or path). - - Return a list of strings. The list will be empty if unable to - access the registry or appropriate registry keys not found. - """ - if not _can_read_reg: - return [] - - path = path + " dirs" - if self.__version >= 7: - key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories" - % (self.__root, self.__version)) - else: - key = (r"%s\6.0\Build System\Components\Platforms" - r"\Win32 (%s)\Directories" % (self.__root, platform)) - - for base in HKEYS: - d = read_values(base, key) - if d: - if self.__version >= 7: - return self.__macros.sub(d[path]).split(";") - else: - return d[path].split(";") - # MSVC 6 seems to create the registry entries we need only when - # the GUI is run. - if self.__version == 6: - for base in HKEYS: - if read_values(base, r"%s\6.0" % self.__root) is not None: - self.warn("It seems you have Visual Studio 6 installed, " - "but the expected registry settings are not present.\n" - "You must at least run the Visual Studio GUI once " - "so that these entries are created.") - break - return [] - - def set_path_env_var(self, name): - """Set environment variable 'name' to an MSVC path type value. - - This is equivalent to a SET command prior to execution of spawned - commands. - """ - - if name == "lib": - p = self.get_msvc_paths("library") - else: - p = self.get_msvc_paths(name) - if p: - os.environ[name] = ';'.join(p) - - -if get_build_version() >= 8.0: - log.debug("Importing new compiler from distutils.msvc9compiler") - OldMSVCCompiler = MSVCCompiler - from distutils.msvc9compiler import MSVCCompiler - # get_build_architecture not really relevant now we support cross-compile - from distutils.msvc9compiler import MacroExpander diff --git a/python/Lib/distutils/spawn.py b/python/Lib/distutils/spawn.py deleted file mode 100644 index 1cd6057..0000000 --- a/python/Lib/distutils/spawn.py +++ /dev/null @@ -1,129 +0,0 @@ -"""distutils.spawn - -Provides the 'spawn()' function, a front-end to various platform- -specific functions for launching another program in a sub-process. -Also provides the 'find_executable()' to search the path for a given -executable name. -""" - -import sys -import os -import subprocess - -from distutils.errors import DistutilsPlatformError, DistutilsExecError -from distutils.debug import DEBUG -from distutils import log - - -if sys.platform == 'darwin': - _cfg_target = None - _cfg_target_split = None - - -def spawn(cmd, search_path=1, verbose=0, dry_run=0): - """Run another program, specified as a command list 'cmd', in a new process. - - 'cmd' is just the argument list for the new process, ie. - cmd[0] is the program to run and cmd[1:] are the rest of its arguments. - There is no way to run a program with a name different from that of its - executable. - - If 'search_path' is true (the default), the system's executable - search path will be used to find the program; otherwise, cmd[0] - must be the exact path to the executable. If 'dry_run' is true, - the command will not actually be run. - - Raise DistutilsExecError if running the program fails in any way; just - return on success. - """ - # cmd is documented as a list, but just in case some code passes a tuple - # in, protect our %-formatting code against horrible death - cmd = list(cmd) - - log.info(' '.join(cmd)) - if dry_run: - return - - if search_path: - executable = find_executable(cmd[0]) - if executable is not None: - cmd[0] = executable - - env = None - if sys.platform == 'darwin': - global _cfg_target, _cfg_target_split - if _cfg_target is None: - from distutils import sysconfig - _cfg_target = sysconfig.get_config_var( - 'MACOSX_DEPLOYMENT_TARGET') or '' - if _cfg_target: - _cfg_target_split = [int(x) for x in _cfg_target.split('.')] - if _cfg_target: - # Ensure that the deployment target of the build process is not - # less than 10.3 if the interpreter was built for 10.3 or later. - # This ensures extension modules are built with correct - # compatibility values, specifically LDSHARED which can use - # '-undefined dynamic_lookup' which only works on >= 10.3. - cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) - cur_target_split = [int(x) for x in cur_target.split('.')] - if _cfg_target_split[:2] >= [10, 3] and cur_target_split[:2] < [10, 3]: - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' - 'now "%s" but "%s" during configure;' - 'must use 10.3 or later' - % (cur_target, _cfg_target)) - raise DistutilsPlatformError(my_msg) - env = dict(os.environ, - MACOSX_DEPLOYMENT_TARGET=cur_target) - - try: - proc = subprocess.Popen(cmd, env=env) - proc.wait() - exitcode = proc.returncode - except OSError as exc: - if not DEBUG: - cmd = cmd[0] - raise DistutilsExecError( - "command %r failed: %s" % (cmd, exc.args[-1])) from exc - - if exitcode: - if not DEBUG: - cmd = cmd[0] - raise DistutilsExecError( - "command %r failed with exit code %s" % (cmd, exitcode)) - - -def find_executable(executable, path=None): - """Tries to find 'executable' in the directories listed in 'path'. - - A string listing directories separated by 'os.pathsep'; defaults to - os.environ['PATH']. Returns the complete filename or None if not found. - """ - _, ext = os.path.splitext(executable) - if (sys.platform == 'win32') and (ext != '.exe'): - executable = executable + '.exe' - - if os.path.isfile(executable): - return executable - - if path is None: - path = os.environ.get('PATH', None) - if path is None: - try: - path = os.confstr("CS_PATH") - except (AttributeError, ValueError): - # os.confstr() or CS_PATH is not available - path = os.defpath - # bpo-35755: Don't use os.defpath if the PATH environment variable is - # set to an empty string - - # PATH='' doesn't match, whereas PATH=':' looks in the current directory - if not path: - return None - - paths = path.split(os.pathsep) - for p in paths: - f = os.path.join(p, executable) - if os.path.isfile(f): - # the file exists, we have a shot at spawn working - return f - return None diff --git a/python/Lib/distutils/sysconfig.py b/python/Lib/distutils/sysconfig.py deleted file mode 100644 index 3efdfe3..0000000 --- a/python/Lib/distutils/sysconfig.py +++ /dev/null @@ -1,346 +0,0 @@ -"""Provide access to Python's configuration information. The specific -configuration variables available depend heavily on the platform and -configuration. The values may be retrieved using -get_config_var(name), and the list of variables is available via -get_config_vars().keys(). Additional convenience functions are also -available. - -Written by: Fred L. Drake, Jr. -Email: -""" - -import _imp -import os -import re -import sys -import warnings - -from functools import partial - -from .errors import DistutilsPlatformError - -from sysconfig import ( - _PREFIX as PREFIX, - _BASE_PREFIX as BASE_PREFIX, - _EXEC_PREFIX as EXEC_PREFIX, - _BASE_EXEC_PREFIX as BASE_EXEC_PREFIX, - _PROJECT_BASE as project_base, - _PYTHON_BUILD as python_build, - _init_posix as sysconfig_init_posix, - parse_config_h as sysconfig_parse_config_h, - - _init_non_posix, - - _variable_rx, - _findvar1_rx, - _findvar2_rx, - - expand_makefile_vars, - is_python_build, - get_config_h_filename, - get_config_var, - get_config_vars, - get_makefile_filename, - get_python_version, -) - -# This is better than -# from sysconfig import _CONFIG_VARS as _config_vars -# because it makes sure that the global dictionary is initialized -# which might not be true in the time of import. -_config_vars = get_config_vars() - -warnings.warn( - 'The distutils.sysconfig module is deprecated, use sysconfig instead', - DeprecationWarning, - stacklevel=2 -) - - -# Following functions are the same as in sysconfig but with different API -def parse_config_h(fp, g=None): - return sysconfig_parse_config_h(fp, vars=g) - - -_python_build = partial(is_python_build, check_home=True) -_init_posix = partial(sysconfig_init_posix, _config_vars) -_init_nt = partial(_init_non_posix, _config_vars) - - -# Similar function is also implemented in sysconfig as _parse_makefile -# but without the parsing capabilities of distutils.text_file.TextFile. -def parse_makefile(fn, g=None): - """Parse a Makefile-style file. - A dictionary containing name/value pairs is returned. If an - optional dictionary is passed in as the second argument, it is - used instead of a new dictionary. - """ - from distutils.text_file import TextFile - fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1, errors="surrogateescape") - - if g is None: - g = {} - done = {} - notdone = {} - - while True: - line = fp.readline() - if line is None: # eof - break - m = re.match(_variable_rx, line) - if m: - n, v = m.group(1, 2) - v = v.strip() - # `$$' is a literal `$' in make - tmpv = v.replace('$$', '') - - if "$" in tmpv: - notdone[n] = v - else: - try: - v = int(v) - except ValueError: - # insert literal `$' - done[n] = v.replace('$$', '$') - else: - done[n] = v - - # Variables with a 'PY_' prefix in the makefile. These need to - # be made available without that prefix through sysconfig. - # Special care is needed to ensure that variable expansion works, even - # if the expansion uses the name without a prefix. - renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') - - # do variable interpolation here - while notdone: - for name in list(notdone): - value = notdone[name] - m = re.search(_findvar1_rx, value) or re.search(_findvar2_rx, value) - if m: - n = m.group(1) - found = True - if n in done: - item = str(done[n]) - elif n in notdone: - # get it on a subsequent round - found = False - elif n in os.environ: - # do it like make: fall back to environment - item = os.environ[n] - - elif n in renamed_variables: - if name.startswith('PY_') and name[3:] in renamed_variables: - item = "" - - elif 'PY_' + n in notdone: - found = False - - else: - item = str(done['PY_' + n]) - else: - done[n] = item = "" - if found: - after = value[m.end():] - value = value[:m.start()] + item + after - if "$" in after: - notdone[name] = value - else: - try: value = int(value) - except ValueError: - done[name] = value.strip() - else: - done[name] = value - del notdone[name] - - if name.startswith('PY_') \ - and name[3:] in renamed_variables: - - name = name[3:] - if name not in done: - done[name] = value - else: - # bogus variable reference; just drop it since we can't deal - del notdone[name] - - fp.close() - - # strip spurious spaces - for k, v in done.items(): - if isinstance(v, str): - done[k] = v.strip() - - # save the results in the global dictionary - g.update(done) - return g - - -# Following functions are deprecated together with this module and they -# have no direct replacement - -# Calculate the build qualifier flags if they are defined. Adding the flags -# to the include and lib directories only makes sense for an installation, not -# an in-source build. -build_flags = '' -try: - if not python_build: - build_flags = sys.abiflags -except AttributeError: - # It's not a configure-based build, so the sys module doesn't have - # this attribute, which is fine. - pass - - -def customize_compiler(compiler): - """Do any platform-specific customization of a CCompiler instance. - - Mainly needed on Unix, so we can plug in the information that - varies across Unices and is stored in Python's Makefile. - """ - if compiler.compiler_type == "unix": - if sys.platform == "darwin": - # Perform first-time customization of compiler-related - # config vars on OS X now that we know we need a compiler. - # This is primarily to support Pythons from binary - # installers. The kind and paths to build tools on - # the user system may vary significantly from the system - # that Python itself was built on. Also the user OS - # version and build tools may not support the same set - # of CPU architectures for universal builds. - if not _config_vars.get('CUSTOMIZED_OSX_COMPILER'): - import _osx_support - _osx_support.customize_compiler(_config_vars) - _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True' - - (cc, cxx, cflags, ccshared, ldshared, shlib_suffix, ar, ar_flags) = \ - get_config_vars('CC', 'CXX', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS') - - if 'CC' in os.environ: - newcc = os.environ['CC'] - if (sys.platform == 'darwin' - and 'LDSHARED' not in os.environ - and ldshared.startswith(cc)): - # On OS X, if CC is overridden, use that as the default - # command for LDSHARED as well - ldshared = newcc + ldshared[len(cc):] - cc = newcc - if 'CXX' in os.environ: - cxx = os.environ['CXX'] - if 'LDSHARED' in os.environ: - ldshared = os.environ['LDSHARED'] - if 'CPP' in os.environ: - cpp = os.environ['CPP'] - else: - cpp = cc + " -E" # not always - if 'LDFLAGS' in os.environ: - ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - if 'CFLAGS' in os.environ: - cflags = cflags + ' ' + os.environ['CFLAGS'] - ldshared = ldshared + ' ' + os.environ['CFLAGS'] - if 'CPPFLAGS' in os.environ: - cpp = cpp + ' ' + os.environ['CPPFLAGS'] - cflags = cflags + ' ' + os.environ['CPPFLAGS'] - ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] - if 'AR' in os.environ: - ar = os.environ['AR'] - if 'ARFLAGS' in os.environ: - archiver = ar + ' ' + os.environ['ARFLAGS'] - else: - archiver = ar + ' ' + ar_flags - - cc_cmd = cc + ' ' + cflags - compiler.set_executables( - preprocessor=cpp, - compiler=cc_cmd, - compiler_so=cc_cmd + ' ' + ccshared, - compiler_cxx=cxx, - linker_so=ldshared, - linker_exe=cc, - archiver=archiver) - - compiler.shared_lib_extension = shlib_suffix - - -def get_python_inc(plat_specific=0, prefix=None): - """Return the directory containing installed Python header files. - - If 'plat_specific' is false (the default), this is the path to the - non-platform-specific header files, i.e. Python.h and so on; - otherwise, this is the path to platform-specific header files - (namely pyconfig.h). - - If 'prefix' is supplied, use it instead of sys.base_prefix or - sys.base_exec_prefix -- i.e., ignore 'plat_specific'. - """ - if prefix is None: - prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX - if os.name == "posix": - if python_build: - # Assume the executable is in the build directory. The - # pyconfig.h file should be in the same directory. Since - # the build directory may not be the source directory, we - # must use "srcdir" from the makefile to find the "Include" - # directory. - if plat_specific: - return project_base - else: - incdir = os.path.join(get_config_var('srcdir'), 'Include') - return os.path.normpath(incdir) - python_dir = 'python' + get_python_version() + build_flags - return os.path.join(prefix, "include", python_dir) - elif os.name == "nt": - if python_build: - # Include both the include and PC dir to ensure we can find - # pyconfig.h - return (os.path.join(prefix, "include") + os.path.pathsep + - os.path.join(prefix, "PC")) - return os.path.join(prefix, "include") - else: - raise DistutilsPlatformError( - "I don't know where Python installs its C header files " - "on platform '%s'" % os.name) - - -def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): - """Return the directory containing the Python library (standard or - site additions). - - If 'plat_specific' is true, return the directory containing - platform-specific modules, i.e. any module from a non-pure-Python - module distribution; otherwise, return the platform-shared library - directory. If 'standard_lib' is true, return the directory - containing standard Python library modules; otherwise, return the - directory for site-specific modules. - - If 'prefix' is supplied, use it instead of sys.base_prefix or - sys.base_exec_prefix -- i.e., ignore 'plat_specific'. - """ - if prefix is None: - if standard_lib: - prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX - else: - prefix = plat_specific and EXEC_PREFIX or PREFIX - - if os.name == "posix": - if plat_specific or standard_lib: - # Platform-specific modules (any module from a non-pure-Python - # module distribution) or standard Python library modules. - libdir = sys.platlibdir - else: - # Pure Python - libdir = "lib" - libpython = os.path.join(prefix, libdir, - "python" + get_python_version()) - if standard_lib: - return libpython - else: - return os.path.join(libpython, "site-packages") - elif os.name == "nt": - if standard_lib: - return os.path.join(prefix, "Lib") - else: - return os.path.join(prefix, "Lib", "site-packages") - else: - raise DistutilsPlatformError( - "I don't know where Python installs its library " - "on platform '%s'" % os.name) diff --git a/python/Lib/distutils/tests/Setup.sample b/python/Lib/distutils/tests/Setup.sample deleted file mode 100644 index 6cd3bfe..0000000 --- a/python/Lib/distutils/tests/Setup.sample +++ /dev/null @@ -1,67 +0,0 @@ -# Setup file from the pygame project - -#--StartConfig -SDL = -I/usr/include/SDL -D_REENTRANT -lSDL -FONT = -lSDL_ttf -IMAGE = -lSDL_image -MIXER = -lSDL_mixer -SMPEG = -lsmpeg -PNG = -lpng -JPEG = -ljpeg -SCRAP = -lX11 -PORTMIDI = -lportmidi -PORTTIME = -lporttime -#--EndConfig - -#DEBUG = -C-W -C-Wall -DEBUG = - -#the following modules are optional. you will want to compile -#everything you can, but you can ignore ones you don't have -#dependencies for, just comment them out - -imageext src/imageext.c $(SDL) $(IMAGE) $(PNG) $(JPEG) $(DEBUG) -font src/font.c $(SDL) $(FONT) $(DEBUG) -mixer src/mixer.c $(SDL) $(MIXER) $(DEBUG) -mixer_music src/music.c $(SDL) $(MIXER) $(DEBUG) -_numericsurfarray src/_numericsurfarray.c $(SDL) $(DEBUG) -_numericsndarray src/_numericsndarray.c $(SDL) $(MIXER) $(DEBUG) -movie src/movie.c $(SDL) $(SMPEG) $(DEBUG) -scrap src/scrap.c $(SDL) $(SCRAP) $(DEBUG) -_camera src/_camera.c src/camera_v4l2.c src/camera_v4l.c $(SDL) $(DEBUG) -pypm src/pypm.c $(SDL) $(PORTMIDI) $(PORTTIME) $(DEBUG) - -GFX = src/SDL_gfx/SDL_gfxPrimitives.c -#GFX = src/SDL_gfx/SDL_gfxBlitFunc.c src/SDL_gfx/SDL_gfxPrimitives.c -gfxdraw src/gfxdraw.c $(SDL) $(GFX) $(DEBUG) - - - -#these modules are required for pygame to run. they only require -#SDL as a dependency. these should not be altered - -base src/base.c $(SDL) $(DEBUG) -cdrom src/cdrom.c $(SDL) $(DEBUG) -color src/color.c $(SDL) $(DEBUG) -constants src/constants.c $(SDL) $(DEBUG) -display src/display.c $(SDL) $(DEBUG) -event src/event.c $(SDL) $(DEBUG) -fastevent src/fastevent.c src/fastevents.c $(SDL) $(DEBUG) -key src/key.c $(SDL) $(DEBUG) -mouse src/mouse.c $(SDL) $(DEBUG) -rect src/rect.c $(SDL) $(DEBUG) -rwobject src/rwobject.c $(SDL) $(DEBUG) -surface src/surface.c src/alphablit.c src/surface_fill.c $(SDL) $(DEBUG) -surflock src/surflock.c $(SDL) $(DEBUG) -time src/time.c $(SDL) $(DEBUG) -joystick src/joystick.c $(SDL) $(DEBUG) -draw src/draw.c $(SDL) $(DEBUG) -image src/image.c $(SDL) $(DEBUG) -overlay src/overlay.c $(SDL) $(DEBUG) -transform src/transform.c src/rotozoom.c src/scale2x.c src/scale_mmx.c $(SDL) $(DEBUG) -mask src/mask.c src/bitmask.c $(SDL) $(DEBUG) -bufferproxy src/bufferproxy.c $(SDL) $(DEBUG) -pixelarray src/pixelarray.c $(SDL) $(DEBUG) -_arraysurfarray src/_arraysurfarray.c $(SDL) $(DEBUG) - - diff --git a/python/Lib/distutils/tests/__init__.py b/python/Lib/distutils/tests/__init__.py deleted file mode 100644 index 2aada40..0000000 --- a/python/Lib/distutils/tests/__init__.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Test suite for distutils. - -This test suite consists of a collection of test modules in the -distutils.tests package. Each test module has a name starting with -'test' and contains a function test_suite(). The function is expected -to return an initialized unittest.TestSuite instance. - -Tests for the command classes in the distutils.command package are -included in distutils.tests as well, instead of using a separate -distutils.command.tests package, since command identification is done -by import rather than matching pre-defined names. - -""" - -import os -import sys -import unittest -from test.support import run_unittest -from test.support.warnings_helper import save_restore_warnings_filters - - -here = os.path.dirname(__file__) or os.curdir - - -def test_suite(): - suite = unittest.TestSuite() - for fn in os.listdir(here): - if fn.startswith("test") and fn.endswith(".py"): - modname = "distutils.tests." + fn[:-3] - # bpo-40055: Save/restore warnings filters to leave them unchanged. - # Importing tests imports docutils which imports pkg_resources - # which adds a warnings filter. - with save_restore_warnings_filters(): - __import__(modname) - module = sys.modules[modname] - suite.addTest(module.test_suite()) - return suite - - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/includetest.rst b/python/Lib/distutils/tests/includetest.rst deleted file mode 100644 index f606fc7..0000000 --- a/python/Lib/distutils/tests/includetest.rst +++ /dev/null @@ -1 +0,0 @@ -This should be included. diff --git a/python/Lib/distutils/tests/support.py b/python/Lib/distutils/tests/support.py deleted file mode 100644 index d8d27ee..0000000 --- a/python/Lib/distutils/tests/support.py +++ /dev/null @@ -1,209 +0,0 @@ -"""Support code for distutils test cases.""" -import os -import sys -import shutil -import tempfile -import unittest -import sysconfig -from copy import deepcopy -from test.support import os_helper - -from distutils import log -from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL -from distutils.core import Distribution - - -class LoggingSilencer(object): - - def setUp(self): - super().setUp() - self.threshold = log.set_threshold(log.FATAL) - # catching warnings - # when log will be replaced by logging - # we won't need such monkey-patch anymore - self._old_log = log.Log._log - log.Log._log = self._log - self.logs = [] - - def tearDown(self): - log.set_threshold(self.threshold) - log.Log._log = self._old_log - super().tearDown() - - def _log(self, level, msg, args): - if level not in (DEBUG, INFO, WARN, ERROR, FATAL): - raise ValueError('%s wrong log level' % str(level)) - if not isinstance(msg, str): - raise TypeError("msg should be str, not '%.200s'" - % (type(msg).__name__)) - self.logs.append((level, msg, args)) - - def get_logs(self, *levels): - return [msg % args for level, msg, args - in self.logs if level in levels] - - def clear_logs(self): - self.logs = [] - - -class TempdirManager(object): - """Mix-in class that handles temporary directories for test cases. - - This is intended to be used with unittest.TestCase. - """ - - def setUp(self): - super().setUp() - self.old_cwd = os.getcwd() - self.tempdirs = [] - - def tearDown(self): - # Restore working dir, for Solaris and derivatives, where rmdir() - # on the current directory fails. - os.chdir(self.old_cwd) - super().tearDown() - while self.tempdirs: - tmpdir = self.tempdirs.pop() - os_helper.rmtree(tmpdir) - - def mkdtemp(self): - """Create a temporary directory that will be cleaned up. - - Returns the path of the directory. - """ - d = tempfile.mkdtemp() - self.tempdirs.append(d) - return d - - def write_file(self, path, content='xxx'): - """Writes a file in the given path. - - - path can be a string or a sequence. - """ - if isinstance(path, (list, tuple)): - path = os.path.join(*path) - f = open(path, 'w') - try: - f.write(content) - finally: - f.close() - - def create_dist(self, pkg_name='foo', **kw): - """Will generate a test environment. - - This function creates: - - a Distribution instance using keywords - - a temporary directory with a package structure - - It returns the package directory and the distribution - instance. - """ - tmp_dir = self.mkdtemp() - pkg_dir = os.path.join(tmp_dir, pkg_name) - os.mkdir(pkg_dir) - dist = Distribution(attrs=kw) - - return pkg_dir, dist - - -class DummyCommand: - """Class to store options for retrieval via set_undefined_options().""" - - def __init__(self, **kwargs): - for kw, val in kwargs.items(): - setattr(self, kw, val) - - def ensure_finalized(self): - pass - - -class EnvironGuard(object): - - def setUp(self): - super(EnvironGuard, self).setUp() - self.old_environ = deepcopy(os.environ) - - def tearDown(self): - for key, value in self.old_environ.items(): - if os.environ.get(key) != value: - os.environ[key] = value - - for key in tuple(os.environ.keys()): - if key not in self.old_environ: - del os.environ[key] - - super(EnvironGuard, self).tearDown() - - -def copy_xxmodule_c(directory): - """Helper for tests that need the xxmodule.c source file. - - Example use: - - def test_compile(self): - copy_xxmodule_c(self.tmpdir) - self.assertIn('xxmodule.c', os.listdir(self.tmpdir)) - - If the source file can be found, it will be copied to *directory*. If not, - the test will be skipped. Errors during copy are not caught. - """ - filename = _get_xxmodule_path() - if filename is None: - raise unittest.SkipTest('cannot find xxmodule.c (test must run in ' - 'the python build dir)') - shutil.copy(filename, directory) - - -def _get_xxmodule_path(): - srcdir = sysconfig.get_config_var('srcdir') - candidates = [ - # use installed copy if available - os.path.join(os.path.dirname(__file__), 'xxmodule.c'), - # otherwise try using copy from build directory - os.path.join(srcdir, 'Modules', 'xxmodule.c'), - # srcdir mysteriously can be $srcdir/Lib/distutils/tests when - # this file is run from its parent directory, so walk up the - # tree to find the real srcdir - os.path.join(srcdir, '..', '..', '..', 'Modules', 'xxmodule.c'), - ] - for path in candidates: - if os.path.exists(path): - return path - - -def fixup_build_ext(cmd): - """Function needed to make build_ext tests pass. - - When Python was built with --enable-shared on Unix, -L. is not enough to - find libpython.so, because regrtest runs in a tempdir, not in the - source directory where the .so lives. - - When Python was built with in debug mode on Windows, build_ext commands - need their debug attribute set, and it is not done automatically for - some reason. - - This function handles both of these things. Example use: - - cmd = build_ext(dist) - support.fixup_build_ext(cmd) - cmd.ensure_finalized() - - Unlike most other Unix platforms, Mac OS X embeds absolute paths - to shared libraries into executables, so the fixup is not needed there. - """ - if os.name == 'nt': - cmd.debug = sys.executable.endswith('_d.exe') - elif sysconfig.get_config_var('Py_ENABLE_SHARED'): - # To further add to the shared builds fun on Unix, we can't just add - # library_dirs to the Extension() instance because that doesn't get - # plumbed through to the final compiler command. - runshared = sysconfig.get_config_var('RUNSHARED') - if runshared is None: - cmd.library_dirs = ['.'] - else: - if sys.platform == 'darwin': - cmd.library_dirs = [] - else: - name, equals, value = runshared.partition('=') - cmd.library_dirs = [d for d in value.split(os.pathsep) if d] diff --git a/python/Lib/distutils/tests/test_archive_util.py b/python/Lib/distutils/tests/test_archive_util.py deleted file mode 100644 index 0ea8edd..0000000 --- a/python/Lib/distutils/tests/test_archive_util.py +++ /dev/null @@ -1,396 +0,0 @@ -# -*- coding: utf-8 -*- -"""Tests for distutils.archive_util.""" -import unittest -import os -import sys -import tarfile -from os.path import splitdrive -import warnings - -from distutils import archive_util -from distutils.archive_util import (check_archive_formats, make_tarball, - make_zipfile, make_archive, - ARCHIVE_FORMATS) -from distutils.spawn import find_executable, spawn -from distutils.tests import support -from test.support import run_unittest, patch -from test.support.os_helper import change_cwd -from test.support.warnings_helper import check_warnings - -try: - import grp - import pwd - UID_GID_SUPPORT = True -except ImportError: - UID_GID_SUPPORT = False - -try: - import zipfile - ZIP_SUPPORT = True -except ImportError: - ZIP_SUPPORT = find_executable('zip') - -try: - import zlib - ZLIB_SUPPORT = True -except ImportError: - ZLIB_SUPPORT = False - -try: - import bz2 -except ImportError: - bz2 = None - -try: - import lzma -except ImportError: - lzma = None - -def can_fs_encode(filename): - """ - Return True if the filename can be saved in the file system. - """ - if os.path.supports_unicode_filenames: - return True - try: - filename.encode(sys.getfilesystemencoding()) - except UnicodeEncodeError: - return False - return True - - -class ArchiveUtilTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_make_tarball(self, name='archive'): - # creating something to tar - tmpdir = self._create_files() - self._make_tarball(tmpdir, name, '.tar.gz') - # trying an uncompressed one - self._make_tarball(tmpdir, name, '.tar', compress=None) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_make_tarball_gzip(self): - tmpdir = self._create_files() - self._make_tarball(tmpdir, 'archive', '.tar.gz', compress='gzip') - - @unittest.skipUnless(bz2, 'Need bz2 support to run') - def test_make_tarball_bzip2(self): - tmpdir = self._create_files() - self._make_tarball(tmpdir, 'archive', '.tar.bz2', compress='bzip2') - - @unittest.skipUnless(lzma, 'Need lzma support to run') - def test_make_tarball_xz(self): - tmpdir = self._create_files() - self._make_tarball(tmpdir, 'archive', '.tar.xz', compress='xz') - - @unittest.skipUnless(can_fs_encode('årchiv'), - 'File system cannot handle this filename') - def test_make_tarball_latin1(self): - """ - Mirror test_make_tarball, except filename contains latin characters. - """ - self.test_make_tarball('årchiv') # note this isn't a real word - - @unittest.skipUnless(can_fs_encode('のアーカイブ'), - 'File system cannot handle this filename') - def test_make_tarball_extended(self): - """ - Mirror test_make_tarball, except filename contains extended - characters outside the latin charset. - """ - self.test_make_tarball('のアーカイブ') # japanese for archive - - def _make_tarball(self, tmpdir, target_name, suffix, **kwargs): - tmpdir2 = self.mkdtemp() - unittest.skipUnless(splitdrive(tmpdir)[0] == splitdrive(tmpdir2)[0], - "source and target should be on same drive") - - base_name = os.path.join(tmpdir2, target_name) - - # working with relative paths to avoid tar warnings - with change_cwd(tmpdir): - make_tarball(splitdrive(base_name)[1], 'dist', **kwargs) - - # check if the compressed tarball was created - tarball = base_name + suffix - self.assertTrue(os.path.exists(tarball)) - self.assertEqual(self._tarinfo(tarball), self._created_files) - - def _tarinfo(self, path): - tar = tarfile.open(path) - try: - names = tar.getnames() - names.sort() - return names - finally: - tar.close() - - _zip_created_files = ['dist/', 'dist/file1', 'dist/file2', - 'dist/sub/', 'dist/sub/file3', 'dist/sub2/'] - _created_files = [p.rstrip('/') for p in _zip_created_files] - - def _create_files(self): - # creating something to tar - tmpdir = self.mkdtemp() - dist = os.path.join(tmpdir, 'dist') - os.mkdir(dist) - self.write_file([dist, 'file1'], 'xxx') - self.write_file([dist, 'file2'], 'xxx') - os.mkdir(os.path.join(dist, 'sub')) - self.write_file([dist, 'sub', 'file3'], 'xxx') - os.mkdir(os.path.join(dist, 'sub2')) - return tmpdir - - @unittest.skipUnless(find_executable('tar') and find_executable('gzip') - and ZLIB_SUPPORT, - 'Need the tar, gzip and zlib command to run') - def test_tarfile_vs_tar(self): - tmpdir = self._create_files() - tmpdir2 = self.mkdtemp() - base_name = os.path.join(tmpdir2, 'archive') - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - make_tarball(base_name, 'dist') - finally: - os.chdir(old_dir) - - # check if the compressed tarball was created - tarball = base_name + '.tar.gz' - self.assertTrue(os.path.exists(tarball)) - - # now create another tarball using `tar` - tarball2 = os.path.join(tmpdir, 'archive2.tar.gz') - tar_cmd = ['tar', '-cf', 'archive2.tar', 'dist'] - gzip_cmd = ['gzip', '-f', '-9', 'archive2.tar'] - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - spawn(tar_cmd) - spawn(gzip_cmd) - finally: - os.chdir(old_dir) - - self.assertTrue(os.path.exists(tarball2)) - # let's compare both tarballs - self.assertEqual(self._tarinfo(tarball), self._created_files) - self.assertEqual(self._tarinfo(tarball2), self._created_files) - - # trying an uncompressed one - base_name = os.path.join(tmpdir2, 'archive') - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - make_tarball(base_name, 'dist', compress=None) - finally: - os.chdir(old_dir) - tarball = base_name + '.tar' - self.assertTrue(os.path.exists(tarball)) - - # now for a dry_run - base_name = os.path.join(tmpdir2, 'archive') - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - make_tarball(base_name, 'dist', compress=None, dry_run=True) - finally: - os.chdir(old_dir) - tarball = base_name + '.tar' - self.assertTrue(os.path.exists(tarball)) - - @unittest.skipUnless(find_executable('compress'), - 'The compress program is required') - def test_compress_deprecated(self): - tmpdir = self._create_files() - base_name = os.path.join(self.mkdtemp(), 'archive') - - # using compress and testing the PendingDeprecationWarning - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - with check_warnings() as w: - warnings.simplefilter("always") - make_tarball(base_name, 'dist', compress='compress') - finally: - os.chdir(old_dir) - tarball = base_name + '.tar.Z' - self.assertTrue(os.path.exists(tarball)) - self.assertEqual(len(w.warnings), 1) - - # same test with dry_run - os.remove(tarball) - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - with check_warnings() as w: - warnings.simplefilter("always") - make_tarball(base_name, 'dist', compress='compress', - dry_run=True) - finally: - os.chdir(old_dir) - self.assertFalse(os.path.exists(tarball)) - self.assertEqual(len(w.warnings), 1) - - @unittest.skipUnless(ZIP_SUPPORT and ZLIB_SUPPORT, - 'Need zip and zlib support to run') - def test_make_zipfile(self): - # creating something to tar - tmpdir = self._create_files() - base_name = os.path.join(self.mkdtemp(), 'archive') - with change_cwd(tmpdir): - make_zipfile(base_name, 'dist') - - # check if the compressed tarball was created - tarball = base_name + '.zip' - self.assertTrue(os.path.exists(tarball)) - with zipfile.ZipFile(tarball) as zf: - self.assertEqual(sorted(zf.namelist()), self._zip_created_files) - - @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') - def test_make_zipfile_no_zlib(self): - patch(self, archive_util.zipfile, 'zlib', None) # force zlib ImportError - - called = [] - zipfile_class = zipfile.ZipFile - def fake_zipfile(*a, **kw): - if kw.get('compression', None) == zipfile.ZIP_STORED: - called.append((a, kw)) - return zipfile_class(*a, **kw) - - patch(self, archive_util.zipfile, 'ZipFile', fake_zipfile) - - # create something to tar and compress - tmpdir = self._create_files() - base_name = os.path.join(self.mkdtemp(), 'archive') - with change_cwd(tmpdir): - make_zipfile(base_name, 'dist') - - tarball = base_name + '.zip' - self.assertEqual(called, - [((tarball, "w"), {'compression': zipfile.ZIP_STORED})]) - self.assertTrue(os.path.exists(tarball)) - with zipfile.ZipFile(tarball) as zf: - self.assertEqual(sorted(zf.namelist()), self._zip_created_files) - - def test_check_archive_formats(self): - self.assertEqual(check_archive_formats(['gztar', 'xxx', 'zip']), - 'xxx') - self.assertIsNone(check_archive_formats(['gztar', 'bztar', 'xztar', - 'ztar', 'tar', 'zip'])) - - def test_make_archive(self): - tmpdir = self.mkdtemp() - base_name = os.path.join(tmpdir, 'archive') - self.assertRaises(ValueError, make_archive, base_name, 'xxx') - - def test_make_archive_cwd(self): - current_dir = os.getcwd() - def _breaks(*args, **kw): - raise RuntimeError() - ARCHIVE_FORMATS['xxx'] = (_breaks, [], 'xxx file') - try: - try: - make_archive('xxx', 'xxx', root_dir=self.mkdtemp()) - except: - pass - self.assertEqual(os.getcwd(), current_dir) - finally: - del ARCHIVE_FORMATS['xxx'] - - def test_make_archive_tar(self): - base_dir = self._create_files() - base_name = os.path.join(self.mkdtemp() , 'archive') - res = make_archive(base_name, 'tar', base_dir, 'dist') - self.assertTrue(os.path.exists(res)) - self.assertEqual(os.path.basename(res), 'archive.tar') - self.assertEqual(self._tarinfo(res), self._created_files) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_make_archive_gztar(self): - base_dir = self._create_files() - base_name = os.path.join(self.mkdtemp() , 'archive') - res = make_archive(base_name, 'gztar', base_dir, 'dist') - self.assertTrue(os.path.exists(res)) - self.assertEqual(os.path.basename(res), 'archive.tar.gz') - self.assertEqual(self._tarinfo(res), self._created_files) - - @unittest.skipUnless(bz2, 'Need bz2 support to run') - def test_make_archive_bztar(self): - base_dir = self._create_files() - base_name = os.path.join(self.mkdtemp() , 'archive') - res = make_archive(base_name, 'bztar', base_dir, 'dist') - self.assertTrue(os.path.exists(res)) - self.assertEqual(os.path.basename(res), 'archive.tar.bz2') - self.assertEqual(self._tarinfo(res), self._created_files) - - @unittest.skipUnless(lzma, 'Need xz support to run') - def test_make_archive_xztar(self): - base_dir = self._create_files() - base_name = os.path.join(self.mkdtemp() , 'archive') - res = make_archive(base_name, 'xztar', base_dir, 'dist') - self.assertTrue(os.path.exists(res)) - self.assertEqual(os.path.basename(res), 'archive.tar.xz') - self.assertEqual(self._tarinfo(res), self._created_files) - - def test_make_archive_owner_group(self): - # testing make_archive with owner and group, with various combinations - # this works even if there's not gid/uid support - if UID_GID_SUPPORT: - group = grp.getgrgid(0)[0] - owner = pwd.getpwuid(0)[0] - else: - group = owner = 'root' - - base_dir = self._create_files() - root_dir = self.mkdtemp() - base_name = os.path.join(self.mkdtemp() , 'archive') - res = make_archive(base_name, 'zip', root_dir, base_dir, owner=owner, - group=group) - self.assertTrue(os.path.exists(res)) - - res = make_archive(base_name, 'zip', root_dir, base_dir) - self.assertTrue(os.path.exists(res)) - - res = make_archive(base_name, 'tar', root_dir, base_dir, - owner=owner, group=group) - self.assertTrue(os.path.exists(res)) - - res = make_archive(base_name, 'tar', root_dir, base_dir, - owner='kjhkjhkjg', group='oihohoh') - self.assertTrue(os.path.exists(res)) - - @unittest.skipUnless(ZLIB_SUPPORT, "Requires zlib") - @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") - def test_tarfile_root_owner(self): - tmpdir = self._create_files() - base_name = os.path.join(self.mkdtemp(), 'archive') - old_dir = os.getcwd() - os.chdir(tmpdir) - group = grp.getgrgid(0)[0] - owner = pwd.getpwuid(0)[0] - try: - archive_name = make_tarball(base_name, 'dist', compress=None, - owner=owner, group=group) - finally: - os.chdir(old_dir) - - # check if the compressed tarball was created - self.assertTrue(os.path.exists(archive_name)) - - # now checks the rights - archive = tarfile.open(archive_name) - try: - for member in archive.getmembers(): - self.assertEqual(member.uid, 0) - self.assertEqual(member.gid, 0) - finally: - archive.close() - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(ArchiveUtilTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_bdist.py b/python/Lib/distutils/tests/test_bdist.py deleted file mode 100644 index 896e258..0000000 --- a/python/Lib/distutils/tests/test_bdist.py +++ /dev/null @@ -1,52 +0,0 @@ -"""Tests for distutils.command.bdist.""" -import os -import unittest -from test.support import run_unittest - -import warnings -with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - from distutils.command.bdist import bdist - from distutils.tests import support - - -class BuildTestCase(support.TempdirManager, - unittest.TestCase): - - def test_formats(self): - # let's create a command and make sure - # we can set the format - dist = self.create_dist()[1] - cmd = bdist(dist) - cmd.formats = ['tar'] - cmd.ensure_finalized() - self.assertEqual(cmd.formats, ['tar']) - - # what formats does bdist offer? - formats = ['bztar', 'gztar', 'rpm', 'tar', 'xztar', 'zip', 'ztar'] - found = sorted(cmd.format_command) - self.assertEqual(found, formats) - - def test_skip_build(self): - # bug #10946: bdist --skip-build should trickle down to subcommands - dist = self.create_dist()[1] - cmd = bdist(dist) - cmd.skip_build = 1 - cmd.ensure_finalized() - dist.command_obj['bdist'] = cmd - - for name in ['bdist_dumb']: # bdist_rpm does not support --skip-build - subcmd = cmd.get_finalized_command(name) - if getattr(subcmd, '_unsupported', False): - # command is not supported on this build - continue - self.assertTrue(subcmd.skip_build, - '%s should take --skip-build from bdist' % name) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildTestCase) - - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_bdist_dumb.py b/python/Lib/distutils/tests/test_bdist_dumb.py deleted file mode 100644 index 8e5be6a..0000000 --- a/python/Lib/distutils/tests/test_bdist_dumb.py +++ /dev/null @@ -1,97 +0,0 @@ -"""Tests for distutils.command.bdist_dumb.""" - -import os -import sys -import zipfile -import unittest -from test.support import run_unittest - -from distutils.core import Distribution -from distutils.command.bdist_dumb import bdist_dumb -from distutils.tests import support - -SETUP_PY = """\ -from distutils.core import setup -import foo - -setup(name='foo', version='0.1', py_modules=['foo'], - url='xxx', author='xxx', author_email='xxx') - -""" - -try: - import zlib - ZLIB_SUPPORT = True -except ImportError: - ZLIB_SUPPORT = False - - -class BuildDumbTestCase(support.TempdirManager, - support.LoggingSilencer, - support.EnvironGuard, - unittest.TestCase): - - def setUp(self): - super(BuildDumbTestCase, self).setUp() - self.old_location = os.getcwd() - self.old_sys_argv = sys.argv, sys.argv[:] - - def tearDown(self): - os.chdir(self.old_location) - sys.argv = self.old_sys_argv[0] - sys.argv[:] = self.old_sys_argv[1] - super(BuildDumbTestCase, self).tearDown() - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_simple_built(self): - - # let's create a simple package - tmp_dir = self.mkdtemp() - pkg_dir = os.path.join(tmp_dir, 'foo') - os.mkdir(pkg_dir) - self.write_file((pkg_dir, 'setup.py'), SETUP_PY) - self.write_file((pkg_dir, 'foo.py'), '#') - self.write_file((pkg_dir, 'MANIFEST.in'), 'include foo.py') - self.write_file((pkg_dir, 'README'), '') - - dist = Distribution({'name': 'foo', 'version': '0.1', - 'py_modules': ['foo'], - 'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx'}) - dist.script_name = 'setup.py' - os.chdir(pkg_dir) - - sys.argv = ['setup.py'] - cmd = bdist_dumb(dist) - - # so the output is the same no matter - # what is the platform - cmd.format = 'zip' - - cmd.ensure_finalized() - cmd.run() - - # see what we have - dist_created = os.listdir(os.path.join(pkg_dir, 'dist')) - base = "%s.%s.zip" % (dist.get_fullname(), cmd.plat_name) - - self.assertEqual(dist_created, [base]) - - # now let's check what we have in the zip file - fp = zipfile.ZipFile(os.path.join('dist', base)) - try: - contents = fp.namelist() - finally: - fp.close() - - contents = sorted(filter(None, map(os.path.basename, contents))) - wanted = ['foo-0.1-py%s.%s.egg-info' % sys.version_info[:2], 'foo.py'] - if not sys.dont_write_bytecode: - wanted.append('foo.%s.pyc' % sys.implementation.cache_tag) - self.assertEqual(contents, sorted(wanted)) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildDumbTestCase) - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_bdist_rpm.py b/python/Lib/distutils/tests/test_bdist_rpm.py deleted file mode 100644 index ce3b2c0..0000000 --- a/python/Lib/distutils/tests/test_bdist_rpm.py +++ /dev/null @@ -1,141 +0,0 @@ -"""Tests for distutils.command.bdist_rpm.""" - -import unittest -import sys -import os -from test.support import run_unittest, requires_zlib - -from distutils.core import Distribution -from distutils.command.bdist_rpm import bdist_rpm -from distutils.tests import support -from distutils.spawn import find_executable - -SETUP_PY = """\ -from distutils.core import setup -import foo - -setup(name='foo', version='0.1', py_modules=['foo'], - url='xxx', author='xxx', author_email='xxx') - -""" - -class BuildRpmTestCase(support.TempdirManager, - support.EnvironGuard, - support.LoggingSilencer, - unittest.TestCase): - - def setUp(self): - try: - sys.executable.encode("UTF-8") - except UnicodeEncodeError: - raise unittest.SkipTest("sys.executable is not encodable to UTF-8") - - super(BuildRpmTestCase, self).setUp() - self.old_location = os.getcwd() - self.old_sys_argv = sys.argv, sys.argv[:] - - def tearDown(self): - os.chdir(self.old_location) - sys.argv = self.old_sys_argv[0] - sys.argv[:] = self.old_sys_argv[1] - super(BuildRpmTestCase, self).tearDown() - - # XXX I am unable yet to make this test work without - # spurious sdtout/stderr output under Mac OS X - @unittest.skipUnless(sys.platform.startswith('linux'), - 'spurious sdtout/stderr output under Mac OS X') - @requires_zlib() - @unittest.skipIf(find_executable('rpm') is None, - 'the rpm command is not found') - @unittest.skipIf(find_executable('rpmbuild') is None, - 'the rpmbuild command is not found') - # import foo fails with safe path - @unittest.skipIf(sys.flags.safe_path, - 'PYTHONSAFEPATH changes default sys.path') - def test_quiet(self): - # let's create a package - tmp_dir = self.mkdtemp() - os.environ['HOME'] = tmp_dir # to confine dir '.rpmdb' creation - pkg_dir = os.path.join(tmp_dir, 'foo') - os.mkdir(pkg_dir) - self.write_file((pkg_dir, 'setup.py'), SETUP_PY) - self.write_file((pkg_dir, 'foo.py'), '#') - self.write_file((pkg_dir, 'MANIFEST.in'), 'include foo.py') - self.write_file((pkg_dir, 'README'), '') - - dist = Distribution({'name': 'foo', 'version': '0.1', - 'py_modules': ['foo'], - 'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx'}) - dist.script_name = 'setup.py' - os.chdir(pkg_dir) - - sys.argv = ['setup.py'] - cmd = bdist_rpm(dist) - cmd.fix_python = True - - # running in quiet mode - cmd.quiet = 1 - cmd.ensure_finalized() - cmd.run() - - dist_created = os.listdir(os.path.join(pkg_dir, 'dist')) - self.assertIn('foo-0.1-1.noarch.rpm', dist_created) - - # bug #2945: upload ignores bdist_rpm files - self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.src.rpm'), dist.dist_files) - self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.noarch.rpm'), dist.dist_files) - - # XXX I am unable yet to make this test work without - # spurious sdtout/stderr output under Mac OS X - @unittest.skipUnless(sys.platform.startswith('linux'), - 'spurious sdtout/stderr output under Mac OS X') - @requires_zlib() - # http://bugs.python.org/issue1533164 - @unittest.skipIf(find_executable('rpm') is None, - 'the rpm command is not found') - @unittest.skipIf(find_executable('rpmbuild') is None, - 'the rpmbuild command is not found') - # import foo fails with safe path - @unittest.skipIf(sys.flags.safe_path, - 'PYTHONSAFEPATH changes default sys.path') - def test_no_optimize_flag(self): - # let's create a package that breaks bdist_rpm - tmp_dir = self.mkdtemp() - os.environ['HOME'] = tmp_dir # to confine dir '.rpmdb' creation - pkg_dir = os.path.join(tmp_dir, 'foo') - os.mkdir(pkg_dir) - self.write_file((pkg_dir, 'setup.py'), SETUP_PY) - self.write_file((pkg_dir, 'foo.py'), '#') - self.write_file((pkg_dir, 'MANIFEST.in'), 'include foo.py') - self.write_file((pkg_dir, 'README'), '') - - dist = Distribution({'name': 'foo', 'version': '0.1', - 'py_modules': ['foo'], - 'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx'}) - dist.script_name = 'setup.py' - os.chdir(pkg_dir) - - sys.argv = ['setup.py'] - cmd = bdist_rpm(dist) - cmd.fix_python = True - - cmd.quiet = 1 - cmd.ensure_finalized() - cmd.run() - - dist_created = os.listdir(os.path.join(pkg_dir, 'dist')) - self.assertIn('foo-0.1-1.noarch.rpm', dist_created) - - # bug #2945: upload ignores bdist_rpm files - self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.src.rpm'), dist.dist_files) - self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.noarch.rpm'), dist.dist_files) - - os.remove(os.path.join(pkg_dir, 'dist', 'foo-0.1-1.noarch.rpm')) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildRpmTestCase) - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_build.py b/python/Lib/distutils/tests/test_build.py deleted file mode 100644 index 9cd2d5a..0000000 --- a/python/Lib/distutils/tests/test_build.py +++ /dev/null @@ -1,57 +0,0 @@ -"""Tests for distutils.command.build.""" -import unittest -import os -import sys -from test.support import run_unittest - -from distutils.command.build import build -from distutils.tests import support -from sysconfig import get_platform - -class BuildTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - @unittest.skipUnless(sys.executable, "test requires sys.executable") - def test_finalize_options(self): - pkg_dir, dist = self.create_dist() - cmd = build(dist) - cmd.finalize_options() - - # if not specified, plat_name gets the current platform - self.assertEqual(cmd.plat_name, get_platform()) - - # build_purelib is build + lib - wanted = os.path.join(cmd.build_base, 'lib') - self.assertEqual(cmd.build_purelib, wanted) - - # build_platlib is 'build/lib.platform-x.x[-pydebug]' - # examples: - # build/lib.macosx-10.3-i386-2.7 - plat_spec = '.%s-%d.%d' % (cmd.plat_name, *sys.version_info[:2]) - if hasattr(sys, 'gettotalrefcount'): - self.assertTrue(cmd.build_platlib.endswith('-pydebug')) - plat_spec += '-pydebug' - wanted = os.path.join(cmd.build_base, 'lib' + plat_spec) - self.assertEqual(cmd.build_platlib, wanted) - - # by default, build_lib = build_purelib - self.assertEqual(cmd.build_lib, cmd.build_purelib) - - # build_temp is build/temp. - wanted = os.path.join(cmd.build_base, 'temp' + plat_spec) - self.assertEqual(cmd.build_temp, wanted) - - # build_scripts is build/scripts-x.x - wanted = os.path.join(cmd.build_base, - 'scripts-%d.%d' % sys.version_info[:2]) - self.assertEqual(cmd.build_scripts, wanted) - - # executable is os.path.normpath(sys.executable) - self.assertEqual(cmd.executable, os.path.normpath(sys.executable)) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_build_clib.py b/python/Lib/distutils/tests/test_build_clib.py deleted file mode 100644 index c800b4f..0000000 --- a/python/Lib/distutils/tests/test_build_clib.py +++ /dev/null @@ -1,147 +0,0 @@ -"""Tests for distutils.command.build_clib.""" -import unittest -import os -import sys -import sysconfig - -from test.support import ( - run_unittest, missing_compiler_executable, requires_subprocess -) - -from distutils.command.build_clib import build_clib -from distutils.errors import DistutilsSetupError -from distutils.tests import support - -class BuildCLibTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - def setUp(self): - super().setUp() - self._backup_CONFIG_VARS = dict(sysconfig._CONFIG_VARS) - - def tearDown(self): - super().tearDown() - sysconfig._CONFIG_VARS.clear() - sysconfig._CONFIG_VARS.update(self._backup_CONFIG_VARS) - - def test_check_library_dist(self): - pkg_dir, dist = self.create_dist() - cmd = build_clib(dist) - - # 'libraries' option must be a list - self.assertRaises(DistutilsSetupError, cmd.check_library_list, 'foo') - - # each element of 'libraries' must a 2-tuple - self.assertRaises(DistutilsSetupError, cmd.check_library_list, - ['foo1', 'foo2']) - - # first element of each tuple in 'libraries' - # must be a string (the library name) - self.assertRaises(DistutilsSetupError, cmd.check_library_list, - [(1, 'foo1'), ('name', 'foo2')]) - - # library name may not contain directory separators - self.assertRaises(DistutilsSetupError, cmd.check_library_list, - [('name', 'foo1'), - ('another/name', 'foo2')]) - - # second element of each tuple must be a dictionary (build info) - self.assertRaises(DistutilsSetupError, cmd.check_library_list, - [('name', {}), - ('another', 'foo2')]) - - # those work - libs = [('name', {}), ('name', {'ok': 'good'})] - cmd.check_library_list(libs) - - def test_get_source_files(self): - pkg_dir, dist = self.create_dist() - cmd = build_clib(dist) - - # "in 'libraries' option 'sources' must be present and must be - # a list of source filenames - cmd.libraries = [('name', {})] - self.assertRaises(DistutilsSetupError, cmd.get_source_files) - - cmd.libraries = [('name', {'sources': 1})] - self.assertRaises(DistutilsSetupError, cmd.get_source_files) - - cmd.libraries = [('name', {'sources': ['a', 'b']})] - self.assertEqual(cmd.get_source_files(), ['a', 'b']) - - cmd.libraries = [('name', {'sources': ('a', 'b')})] - self.assertEqual(cmd.get_source_files(), ['a', 'b']) - - cmd.libraries = [('name', {'sources': ('a', 'b')}), - ('name2', {'sources': ['c', 'd']})] - self.assertEqual(cmd.get_source_files(), ['a', 'b', 'c', 'd']) - - def test_build_libraries(self): - - pkg_dir, dist = self.create_dist() - cmd = build_clib(dist) - class FakeCompiler: - def compile(*args, **kw): - pass - create_static_lib = compile - - cmd.compiler = FakeCompiler() - - # build_libraries is also doing a bit of typo checking - lib = [('name', {'sources': 'notvalid'})] - self.assertRaises(DistutilsSetupError, cmd.build_libraries, lib) - - lib = [('name', {'sources': list()})] - cmd.build_libraries(lib) - - lib = [('name', {'sources': tuple()})] - cmd.build_libraries(lib) - - def test_finalize_options(self): - pkg_dir, dist = self.create_dist() - cmd = build_clib(dist) - - cmd.include_dirs = 'one-dir' - cmd.finalize_options() - self.assertEqual(cmd.include_dirs, ['one-dir']) - - cmd.include_dirs = None - cmd.finalize_options() - self.assertEqual(cmd.include_dirs, []) - - cmd.distribution.libraries = 'WONTWORK' - self.assertRaises(DistutilsSetupError, cmd.finalize_options) - - @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") - @requires_subprocess() - def test_run(self): - pkg_dir, dist = self.create_dist() - cmd = build_clib(dist) - - foo_c = os.path.join(pkg_dir, 'foo.c') - self.write_file(foo_c, 'int main(void) { return 1;}\n') - cmd.libraries = [('foo', {'sources': [foo_c]})] - - build_temp = os.path.join(pkg_dir, 'build') - os.mkdir(build_temp) - cmd.build_temp = build_temp - cmd.build_clib = build_temp - - # Before we run the command, we want to make sure - # all commands are present on the system. - ccmd = missing_compiler_executable() - if ccmd is not None: - self.skipTest('The %r command is not found' % ccmd) - - # this should work - cmd.run() - - # let's check the result - self.assertIn('libfoo.a', os.listdir(build_temp)) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildCLibTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_build_ext.py b/python/Lib/distutils/tests/test_build_ext.py deleted file mode 100644 index 043323e..0000000 --- a/python/Lib/distutils/tests/test_build_ext.py +++ /dev/null @@ -1,555 +0,0 @@ -import sys -import os -from io import StringIO -import textwrap - -from distutils.core import Distribution -from distutils.command.build_ext import build_ext -from distutils import sysconfig -from distutils.tests.support import (TempdirManager, LoggingSilencer, - copy_xxmodule_c, fixup_build_ext) -from distutils.extension import Extension -from distutils.errors import ( - CompileError, DistutilsPlatformError, DistutilsSetupError, - UnknownFileError) - -import unittest -from test import support -from test.support import os_helper -from test.support.script_helper import assert_python_ok -from test.support import threading_helper - -# http://bugs.python.org/issue4373 -# Don't load the xx module more than once. -ALREADY_TESTED = False - - -class BuildExtTestCase(TempdirManager, - LoggingSilencer, - unittest.TestCase): - def setUp(self): - # Create a simple test environment - super(BuildExtTestCase, self).setUp() - self.tmp_dir = self.mkdtemp() - import site - self.old_user_base = site.USER_BASE - site.USER_BASE = self.mkdtemp() - from distutils.command import build_ext - build_ext.USER_BASE = site.USER_BASE - self.old_config_vars = dict(sysconfig._config_vars) - - # bpo-30132: On Windows, a .pdb file may be created in the current - # working directory. Create a temporary working directory to cleanup - # everything at the end of the test. - self.enterContext(os_helper.change_cwd(self.tmp_dir)) - - def tearDown(self): - import site - site.USER_BASE = self.old_user_base - from distutils.command import build_ext - build_ext.USER_BASE = self.old_user_base - sysconfig._config_vars.clear() - sysconfig._config_vars.update(self.old_config_vars) - super(BuildExtTestCase, self).tearDown() - - def build_ext(self, *args, **kwargs): - return build_ext(*args, **kwargs) - - @support.requires_subprocess() - def test_build_ext(self): - cmd = support.missing_compiler_executable() - if cmd is not None: - self.skipTest('The %r command is not found' % cmd) - global ALREADY_TESTED - copy_xxmodule_c(self.tmp_dir) - xx_c = os.path.join(self.tmp_dir, 'xxmodule.c') - xx_ext = Extension('xx', [xx_c]) - dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]}) - dist.package_dir = self.tmp_dir - cmd = self.build_ext(dist) - fixup_build_ext(cmd) - cmd.build_lib = self.tmp_dir - cmd.build_temp = self.tmp_dir - - old_stdout = sys.stdout - if not support.verbose: - # silence compiler output - sys.stdout = StringIO() - try: - cmd.ensure_finalized() - cmd.run() - finally: - sys.stdout = old_stdout - - if ALREADY_TESTED: - self.skipTest('Already tested in %s' % ALREADY_TESTED) - else: - ALREADY_TESTED = type(self).__name__ - - code = textwrap.dedent(f""" - tmp_dir = {self.tmp_dir!r} - - import sys - import unittest - from test import support - - sys.path.insert(0, tmp_dir) - import xx - - class Tests(unittest.TestCase): - def test_xx(self): - for attr in ('error', 'foo', 'new', 'roj'): - self.assertTrue(hasattr(xx, attr)) - - self.assertEqual(xx.foo(2, 5), 7) - self.assertEqual(xx.foo(13,15), 28) - self.assertEqual(xx.new().demo(), None) - if support.HAVE_DOCSTRINGS: - doc = 'This is a template module just for instruction.' - self.assertEqual(xx.__doc__, doc) - self.assertIsInstance(xx.Null(), xx.Null) - self.assertIsInstance(xx.Str(), xx.Str) - - - unittest.main() - """) - assert_python_ok('-c', code) - - def test_solaris_enable_shared(self): - dist = Distribution({'name': 'xx'}) - cmd = self.build_ext(dist) - old = sys.platform - - sys.platform = 'sunos' # fooling finalize_options - from distutils.sysconfig import _config_vars - old_var = _config_vars.get('Py_ENABLE_SHARED') - _config_vars['Py_ENABLE_SHARED'] = 1 - try: - cmd.ensure_finalized() - finally: - sys.platform = old - if old_var is None: - del _config_vars['Py_ENABLE_SHARED'] - else: - _config_vars['Py_ENABLE_SHARED'] = old_var - - # make sure we get some library dirs under solaris - self.assertGreater(len(cmd.library_dirs), 0) - - def test_user_site(self): - import site - dist = Distribution({'name': 'xx'}) - cmd = self.build_ext(dist) - - # making sure the user option is there - options = [name for name, short, lable in - cmd.user_options] - self.assertIn('user', options) - - # setting a value - cmd.user = 1 - - # setting user based lib and include - lib = os.path.join(site.USER_BASE, 'lib') - incl = os.path.join(site.USER_BASE, 'include') - os.mkdir(lib) - os.mkdir(incl) - - # let's run finalize - cmd.ensure_finalized() - - # see if include_dirs and library_dirs - # were set - self.assertIn(lib, cmd.library_dirs) - self.assertIn(lib, cmd.rpath) - self.assertIn(incl, cmd.include_dirs) - - @threading_helper.requires_working_threading() - def test_optional_extension(self): - - # this extension will fail, but let's ignore this failure - # with the optional argument. - modules = [Extension('foo', ['xxx'], optional=False)] - dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = self.build_ext(dist) - cmd.ensure_finalized() - self.assertRaises((UnknownFileError, CompileError), - cmd.run) # should raise an error - - modules = [Extension('foo', ['xxx'], optional=True)] - dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = self.build_ext(dist) - cmd.ensure_finalized() - cmd.run() # should pass - - def test_finalize_options(self): - # Make sure Python's include directories (for Python.h, pyconfig.h, - # etc.) are in the include search path. - modules = [Extension('foo', ['xxx'], optional=False)] - dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = self.build_ext(dist) - cmd.finalize_options() - - py_include = sysconfig.get_python_inc() - for p in py_include.split(os.path.pathsep): - self.assertIn(p, cmd.include_dirs) - - plat_py_include = sysconfig.get_python_inc(plat_specific=1) - for p in plat_py_include.split(os.path.pathsep): - self.assertIn(p, cmd.include_dirs) - - # make sure cmd.libraries is turned into a list - # if it's a string - cmd = self.build_ext(dist) - cmd.libraries = 'my_lib, other_lib lastlib' - cmd.finalize_options() - self.assertEqual(cmd.libraries, ['my_lib', 'other_lib', 'lastlib']) - - # make sure cmd.library_dirs is turned into a list - # if it's a string - cmd = self.build_ext(dist) - cmd.library_dirs = 'my_lib_dir%sother_lib_dir' % os.pathsep - cmd.finalize_options() - self.assertIn('my_lib_dir', cmd.library_dirs) - self.assertIn('other_lib_dir', cmd.library_dirs) - - # make sure rpath is turned into a list - # if it's a string - cmd = self.build_ext(dist) - cmd.rpath = 'one%stwo' % os.pathsep - cmd.finalize_options() - self.assertEqual(cmd.rpath, ['one', 'two']) - - # make sure cmd.link_objects is turned into a list - # if it's a string - cmd = build_ext(dist) - cmd.link_objects = 'one two,three' - cmd.finalize_options() - self.assertEqual(cmd.link_objects, ['one', 'two', 'three']) - - # XXX more tests to perform for win32 - - # make sure define is turned into 2-tuples - # strings if they are ','-separated strings - cmd = self.build_ext(dist) - cmd.define = 'one,two' - cmd.finalize_options() - self.assertEqual(cmd.define, [('one', '1'), ('two', '1')]) - - # make sure undef is turned into a list of - # strings if they are ','-separated strings - cmd = self.build_ext(dist) - cmd.undef = 'one,two' - cmd.finalize_options() - self.assertEqual(cmd.undef, ['one', 'two']) - - # make sure swig_opts is turned into a list - cmd = self.build_ext(dist) - cmd.swig_opts = None - cmd.finalize_options() - self.assertEqual(cmd.swig_opts, []) - - cmd = self.build_ext(dist) - cmd.swig_opts = '1 2' - cmd.finalize_options() - self.assertEqual(cmd.swig_opts, ['1', '2']) - - def test_check_extensions_list(self): - dist = Distribution() - cmd = self.build_ext(dist) - cmd.finalize_options() - - #'extensions' option must be a list of Extension instances - self.assertRaises(DistutilsSetupError, - cmd.check_extensions_list, 'foo') - - # each element of 'ext_modules' option must be an - # Extension instance or 2-tuple - exts = [('bar', 'foo', 'bar'), 'foo'] - self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) - - # first element of each tuple in 'ext_modules' - # must be the extension name (a string) and match - # a python dotted-separated name - exts = [('foo-bar', '')] - self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) - - # second element of each tuple in 'ext_modules' - # must be a dictionary (build info) - exts = [('foo.bar', '')] - self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) - - # ok this one should pass - exts = [('foo.bar', {'sources': [''], 'libraries': 'foo', - 'some': 'bar'})] - cmd.check_extensions_list(exts) - ext = exts[0] - self.assertIsInstance(ext, Extension) - - # check_extensions_list adds in ext the values passed - # when they are in ('include_dirs', 'library_dirs', 'libraries' - # 'extra_objects', 'extra_compile_args', 'extra_link_args') - self.assertEqual(ext.libraries, 'foo') - self.assertFalse(hasattr(ext, 'some')) - - # 'macros' element of build info dict must be 1- or 2-tuple - exts = [('foo.bar', {'sources': [''], 'libraries': 'foo', - 'some': 'bar', 'macros': [('1', '2', '3'), 'foo']})] - self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) - - exts[0][1]['macros'] = [('1', '2'), ('3',)] - cmd.check_extensions_list(exts) - self.assertEqual(exts[0].undef_macros, ['3']) - self.assertEqual(exts[0].define_macros, [('1', '2')]) - - def test_get_source_files(self): - modules = [Extension('foo', ['xxx'], optional=False)] - dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = self.build_ext(dist) - cmd.ensure_finalized() - self.assertEqual(cmd.get_source_files(), ['xxx']) - - def test_unicode_module_names(self): - modules = [ - Extension('foo', ['aaa'], optional=False), - Extension('föö', ['uuu'], optional=False), - ] - dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = self.build_ext(dist) - cmd.ensure_finalized() - self.assertRegex(cmd.get_ext_filename(modules[0].name), r'foo(_d)?\..*') - self.assertRegex(cmd.get_ext_filename(modules[1].name), r'föö(_d)?\..*') - self.assertEqual(cmd.get_export_symbols(modules[0]), ['PyInit_foo']) - self.assertEqual(cmd.get_export_symbols(modules[1]), ['PyInitU_f_gkaa']) - - def test_compiler_option(self): - # cmd.compiler is an option and - # should not be overridden by a compiler instance - # when the command is run - dist = Distribution() - cmd = self.build_ext(dist) - cmd.compiler = 'unix' - cmd.ensure_finalized() - cmd.run() - self.assertEqual(cmd.compiler, 'unix') - - @support.requires_subprocess() - def test_get_outputs(self): - cmd = support.missing_compiler_executable() - if cmd is not None: - self.skipTest('The %r command is not found' % cmd) - tmp_dir = self.mkdtemp() - c_file = os.path.join(tmp_dir, 'foo.c') - self.write_file(c_file, 'void PyInit_foo(void) {}\n') - ext = Extension('foo', [c_file], optional=False) - dist = Distribution({'name': 'xx', - 'ext_modules': [ext]}) - cmd = self.build_ext(dist) - fixup_build_ext(cmd) - cmd.ensure_finalized() - self.assertEqual(len(cmd.get_outputs()), 1) - - cmd.build_lib = os.path.join(self.tmp_dir, 'build') - cmd.build_temp = os.path.join(self.tmp_dir, 'tempt') - - # issue #5977 : distutils build_ext.get_outputs - # returns wrong result with --inplace - other_tmp_dir = os.path.realpath(self.mkdtemp()) - old_wd = os.getcwd() - os.chdir(other_tmp_dir) - try: - cmd.inplace = 1 - cmd.run() - so_file = cmd.get_outputs()[0] - finally: - os.chdir(old_wd) - self.assertTrue(os.path.exists(so_file)) - ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') - self.assertTrue(so_file.endswith(ext_suffix)) - so_dir = os.path.dirname(so_file) - self.assertEqual(so_dir, other_tmp_dir) - - cmd.inplace = 0 - cmd.compiler = None - cmd.run() - so_file = cmd.get_outputs()[0] - self.assertTrue(os.path.exists(so_file)) - self.assertTrue(so_file.endswith(ext_suffix)) - so_dir = os.path.dirname(so_file) - self.assertEqual(so_dir, cmd.build_lib) - - # inplace = 0, cmd.package = 'bar' - build_py = cmd.get_finalized_command('build_py') - build_py.package_dir = {'': 'bar'} - path = cmd.get_ext_fullpath('foo') - # checking that the last directory is the build_dir - path = os.path.split(path)[0] - self.assertEqual(path, cmd.build_lib) - - # inplace = 1, cmd.package = 'bar' - cmd.inplace = 1 - other_tmp_dir = os.path.realpath(self.mkdtemp()) - old_wd = os.getcwd() - os.chdir(other_tmp_dir) - try: - path = cmd.get_ext_fullpath('foo') - finally: - os.chdir(old_wd) - # checking that the last directory is bar - path = os.path.split(path)[0] - lastdir = os.path.split(path)[-1] - self.assertEqual(lastdir, 'bar') - - def test_ext_fullpath(self): - ext = sysconfig.get_config_var('EXT_SUFFIX') - # building lxml.etree inplace - #etree_c = os.path.join(self.tmp_dir, 'lxml.etree.c') - #etree_ext = Extension('lxml.etree', [etree_c]) - #dist = Distribution({'name': 'lxml', 'ext_modules': [etree_ext]}) - dist = Distribution() - cmd = self.build_ext(dist) - cmd.inplace = 1 - cmd.distribution.package_dir = {'': 'src'} - cmd.distribution.packages = ['lxml', 'lxml.html'] - curdir = os.getcwd() - wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) - path = cmd.get_ext_fullpath('lxml.etree') - self.assertEqual(wanted, path) - - # building lxml.etree not inplace - cmd.inplace = 0 - cmd.build_lib = os.path.join(curdir, 'tmpdir') - wanted = os.path.join(curdir, 'tmpdir', 'lxml', 'etree' + ext) - path = cmd.get_ext_fullpath('lxml.etree') - self.assertEqual(wanted, path) - - # building twisted.runner.portmap not inplace - build_py = cmd.get_finalized_command('build_py') - build_py.package_dir = {} - cmd.distribution.packages = ['twisted', 'twisted.runner.portmap'] - path = cmd.get_ext_fullpath('twisted.runner.portmap') - wanted = os.path.join(curdir, 'tmpdir', 'twisted', 'runner', - 'portmap' + ext) - self.assertEqual(wanted, path) - - # building twisted.runner.portmap inplace - cmd.inplace = 1 - path = cmd.get_ext_fullpath('twisted.runner.portmap') - wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + ext) - self.assertEqual(wanted, path) - - - @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') - def test_deployment_target_default(self): - # Issue 9516: Test that, in the absence of the environment variable, - # an extension module is compiled with the same deployment target as - # the interpreter. - self._try_compile_deployment_target('==', None) - - @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') - def test_deployment_target_too_low(self): - # Issue 9516: Test that an extension module is not allowed to be - # compiled with a deployment target less than that of the interpreter. - self.assertRaises(DistutilsPlatformError, - self._try_compile_deployment_target, '>', '10.1') - - @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') - def test_deployment_target_higher_ok(self): - # Issue 9516: Test that an extension module can be compiled with a - # deployment target higher than that of the interpreter: the ext - # module may depend on some newer OS feature. - deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') - if deptarget: - # increment the minor version number (i.e. 10.6 -> 10.7) - deptarget = [int(x) for x in deptarget.split('.')] - deptarget[-1] += 1 - deptarget = '.'.join(str(i) for i in deptarget) - self._try_compile_deployment_target('<', deptarget) - - def _try_compile_deployment_target(self, operator, target): - orig_environ = os.environ - os.environ = orig_environ.copy() - self.addCleanup(setattr, os, 'environ', orig_environ) - - if target is None: - if os.environ.get('MACOSX_DEPLOYMENT_TARGET'): - del os.environ['MACOSX_DEPLOYMENT_TARGET'] - else: - os.environ['MACOSX_DEPLOYMENT_TARGET'] = target - - deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c') - - with open(deptarget_c, 'w') as fp: - fp.write(textwrap.dedent('''\ - #include - - int dummy; - - #if TARGET %s MAC_OS_X_VERSION_MIN_REQUIRED - #else - #error "Unexpected target" - #endif - - ''' % operator)) - - # get the deployment target that the interpreter was built with - target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') - target = tuple(map(int, target.split('.')[0:2])) - # format the target value as defined in the Apple - # Availability Macros. We can't use the macro names since - # at least one value we test with will not exist yet. - if target[:2] < (10, 10): - # for 10.1 through 10.9.x -> "10n0" - target = '%02d%01d0' % target - else: - # for 10.10 and beyond -> "10nn00" - if len(target) >= 2: - target = '%02d%02d00' % target - else: - # 11 and later can have no minor version (11 instead of 11.0) - target = '%02d0000' % target - deptarget_ext = Extension( - 'deptarget', - [deptarget_c], - extra_compile_args=['-DTARGET=%s'%(target,)], - ) - dist = Distribution({ - 'name': 'deptarget', - 'ext_modules': [deptarget_ext] - }) - dist.package_dir = self.tmp_dir - cmd = self.build_ext(dist) - cmd.build_lib = self.tmp_dir - cmd.build_temp = self.tmp_dir - - try: - old_stdout = sys.stdout - if not support.verbose: - # silence compiler output - sys.stdout = StringIO() - try: - cmd.ensure_finalized() - cmd.run() - finally: - sys.stdout = old_stdout - - except CompileError: - self.fail("Wrong deployment target during compilation") - - -class ParallelBuildExtTestCase(BuildExtTestCase): - - def build_ext(self, *args, **kwargs): - build_ext = super().build_ext(*args, **kwargs) - build_ext.parallel = True - return build_ext - - -def test_suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(BuildExtTestCase)) - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(ParallelBuildExtTestCase)) - return suite - -if __name__ == '__main__': - support.run_unittest(__name__) diff --git a/python/Lib/distutils/tests/test_build_py.py b/python/Lib/distutils/tests/test_build_py.py deleted file mode 100644 index ba037b6..0000000 --- a/python/Lib/distutils/tests/test_build_py.py +++ /dev/null @@ -1,181 +0,0 @@ -"""Tests for distutils.command.build_py.""" - -import os -import sys -import unittest - -from distutils.command.build_py import build_py -from distutils.core import Distribution -from distutils.errors import DistutilsFileError - -from distutils.tests import support -from test.support import run_unittest, requires_subprocess - - -class BuildPyTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - def test_package_data(self): - sources = self.mkdtemp() - f = open(os.path.join(sources, "__init__.py"), "w") - try: - f.write("# Pretend this is a package.") - finally: - f.close() - f = open(os.path.join(sources, "README.txt"), "w") - try: - f.write("Info about this package") - finally: - f.close() - - destination = self.mkdtemp() - - dist = Distribution({"packages": ["pkg"], - "package_dir": {"pkg": sources}}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(sources, "setup.py") - dist.command_obj["build"] = support.DummyCommand( - force=0, - build_lib=destination) - dist.packages = ["pkg"] - dist.package_data = {"pkg": ["README.txt"]} - dist.package_dir = {"pkg": sources} - - cmd = build_py(dist) - cmd.compile = 1 - cmd.ensure_finalized() - self.assertEqual(cmd.package_data, dist.package_data) - - cmd.run() - - # This makes sure the list of outputs includes byte-compiled - # files for Python modules but not for package data files - # (there shouldn't *be* byte-code files for those!). - self.assertEqual(len(cmd.get_outputs()), 3) - pkgdest = os.path.join(destination, "pkg") - files = os.listdir(pkgdest) - pycache_dir = os.path.join(pkgdest, "__pycache__") - self.assertIn("__init__.py", files) - self.assertIn("README.txt", files) - if sys.dont_write_bytecode: - self.assertFalse(os.path.exists(pycache_dir)) - else: - pyc_files = os.listdir(pycache_dir) - self.assertIn("__init__.%s.pyc" % sys.implementation.cache_tag, - pyc_files) - - def test_empty_package_dir(self): - # See bugs #1668596/#1720897 - sources = self.mkdtemp() - open(os.path.join(sources, "__init__.py"), "w").close() - - testdir = os.path.join(sources, "doc") - os.mkdir(testdir) - open(os.path.join(testdir, "testfile"), "w").close() - - os.chdir(sources) - dist = Distribution({"packages": ["pkg"], - "package_dir": {"pkg": ""}, - "package_data": {"pkg": ["doc/*"]}}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(sources, "setup.py") - dist.script_args = ["build"] - dist.parse_command_line() - - try: - dist.run_commands() - except DistutilsFileError: - self.fail("failed package_data test when package_dir is ''") - - @unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled') - @requires_subprocess() - def test_byte_compile(self): - project_dir, dist = self.create_dist(py_modules=['boiledeggs']) - os.chdir(project_dir) - self.write_file('boiledeggs.py', 'import antigravity') - cmd = build_py(dist) - cmd.compile = 1 - cmd.build_lib = 'here' - cmd.finalize_options() - cmd.run() - - found = os.listdir(cmd.build_lib) - self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py']) - found = os.listdir(os.path.join(cmd.build_lib, '__pycache__')) - self.assertEqual(found, - ['boiledeggs.%s.pyc' % sys.implementation.cache_tag]) - - @unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled') - @requires_subprocess() - def test_byte_compile_optimized(self): - project_dir, dist = self.create_dist(py_modules=['boiledeggs']) - os.chdir(project_dir) - self.write_file('boiledeggs.py', 'import antigravity') - cmd = build_py(dist) - cmd.compile = 0 - cmd.optimize = 1 - cmd.build_lib = 'here' - cmd.finalize_options() - cmd.run() - - found = os.listdir(cmd.build_lib) - self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py']) - found = os.listdir(os.path.join(cmd.build_lib, '__pycache__')) - expect = 'boiledeggs.{}.opt-1.pyc'.format(sys.implementation.cache_tag) - self.assertEqual(sorted(found), [expect]) - - def test_dir_in_package_data(self): - """ - A directory in package_data should not be added to the filelist. - """ - # See bug 19286 - sources = self.mkdtemp() - pkg_dir = os.path.join(sources, "pkg") - - os.mkdir(pkg_dir) - open(os.path.join(pkg_dir, "__init__.py"), "w").close() - - docdir = os.path.join(pkg_dir, "doc") - os.mkdir(docdir) - open(os.path.join(docdir, "testfile"), "w").close() - - # create the directory that could be incorrectly detected as a file - os.mkdir(os.path.join(docdir, 'otherdir')) - - os.chdir(sources) - dist = Distribution({"packages": ["pkg"], - "package_data": {"pkg": ["doc/*"]}}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(sources, "setup.py") - dist.script_args = ["build"] - dist.parse_command_line() - - try: - dist.run_commands() - except DistutilsFileError: - self.fail("failed package_data when data dir includes a dir") - - def test_dont_write_bytecode(self): - # makes sure byte_compile is not used - dist = self.create_dist()[1] - cmd = build_py(dist) - cmd.compile = 1 - cmd.optimize = 1 - - old_dont_write_bytecode = sys.dont_write_bytecode - sys.dont_write_bytecode = True - try: - cmd.byte_compile([]) - finally: - sys.dont_write_bytecode = old_dont_write_bytecode - - self.assertIn('byte-compiling is disabled', - self.logs[0][1] % self.logs[0][2]) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildPyTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_build_scripts.py b/python/Lib/distutils/tests/test_build_scripts.py deleted file mode 100644 index d5dde0e..0000000 --- a/python/Lib/distutils/tests/test_build_scripts.py +++ /dev/null @@ -1,112 +0,0 @@ -"""Tests for distutils.command.build_scripts.""" - -import os -import unittest - -from distutils.command.build_scripts import build_scripts -from distutils.core import Distribution -from distutils import sysconfig - -from distutils.tests import support -from test.support import run_unittest - - -class BuildScriptsTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - def test_default_settings(self): - cmd = self.get_build_scripts_cmd("/foo/bar", []) - self.assertFalse(cmd.force) - self.assertIsNone(cmd.build_dir) - - cmd.finalize_options() - - self.assertTrue(cmd.force) - self.assertEqual(cmd.build_dir, "/foo/bar") - - def test_build(self): - source = self.mkdtemp() - target = self.mkdtemp() - expected = self.write_sample_scripts(source) - - cmd = self.get_build_scripts_cmd(target, - [os.path.join(source, fn) - for fn in expected]) - cmd.finalize_options() - cmd.run() - - built = os.listdir(target) - for name in expected: - self.assertIn(name, built) - - def get_build_scripts_cmd(self, target, scripts): - import sys - dist = Distribution() - dist.scripts = scripts - dist.command_obj["build"] = support.DummyCommand( - build_scripts=target, - force=1, - executable=sys.executable - ) - return build_scripts(dist) - - def write_sample_scripts(self, dir): - expected = [] - expected.append("script1.py") - self.write_script(dir, "script1.py", - ("#! /usr/bin/env python2.3\n" - "# bogus script w/ Python sh-bang\n" - "pass\n")) - expected.append("script2.py") - self.write_script(dir, "script2.py", - ("#!/usr/bin/python\n" - "# bogus script w/ Python sh-bang\n" - "pass\n")) - expected.append("shell.sh") - self.write_script(dir, "shell.sh", - ("#!/bin/sh\n" - "# bogus shell script w/ sh-bang\n" - "exit 0\n")) - return expected - - def write_script(self, dir, name, text): - f = open(os.path.join(dir, name), "w") - try: - f.write(text) - finally: - f.close() - - def test_version_int(self): - source = self.mkdtemp() - target = self.mkdtemp() - expected = self.write_sample_scripts(source) - - - cmd = self.get_build_scripts_cmd(target, - [os.path.join(source, fn) - for fn in expected]) - cmd.finalize_options() - - # http://bugs.python.org/issue4524 - # - # On linux-g++-32 with command line `./configure --enable-ipv6 - # --with-suffix=3`, python is compiled okay but the build scripts - # failed when writing the name of the executable - old = sysconfig.get_config_vars().get('VERSION') - sysconfig._config_vars['VERSION'] = 4 - try: - cmd.run() - finally: - if old is not None: - sysconfig._config_vars['VERSION'] = old - - built = os.listdir(target) - for name in expected: - self.assertIn(name, built) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildScriptsTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_check.py b/python/Lib/distutils/tests/test_check.py deleted file mode 100644 index dcd197b..0000000 --- a/python/Lib/distutils/tests/test_check.py +++ /dev/null @@ -1,163 +0,0 @@ -"""Tests for distutils.command.check.""" -import os -import textwrap -import unittest -from test.support import run_unittest - -from distutils.command.check import check, HAS_DOCUTILS -from distutils.tests import support -from distutils.errors import DistutilsSetupError - -try: - import pygments -except ImportError: - pygments = None - - -HERE = os.path.dirname(__file__) - - -class CheckTestCase(support.LoggingSilencer, - support.TempdirManager, - unittest.TestCase): - - def _run(self, metadata=None, cwd=None, **options): - if metadata is None: - metadata = {} - if cwd is not None: - old_dir = os.getcwd() - os.chdir(cwd) - pkg_info, dist = self.create_dist(**metadata) - cmd = check(dist) - cmd.initialize_options() - for name, value in options.items(): - setattr(cmd, name, value) - cmd.ensure_finalized() - cmd.run() - if cwd is not None: - os.chdir(old_dir) - return cmd - - def test_check_metadata(self): - # let's run the command with no metadata at all - # by default, check is checking the metadata - # should have some warnings - cmd = self._run() - self.assertEqual(cmd._warnings, 2) - - # now let's add the required fields - # and run it again, to make sure we don't get - # any warning anymore - metadata = {'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx', - 'name': 'xxx', 'version': 'xxx'} - cmd = self._run(metadata) - self.assertEqual(cmd._warnings, 0) - - # now with the strict mode, we should - # get an error if there are missing metadata - self.assertRaises(DistutilsSetupError, self._run, {}, **{'strict': 1}) - - # and of course, no error when all metadata are present - cmd = self._run(metadata, strict=1) - self.assertEqual(cmd._warnings, 0) - - # now a test with non-ASCII characters - metadata = {'url': 'xxx', 'author': '\u00c9ric', - 'author_email': 'xxx', 'name': 'xxx', - 'version': 'xxx', - 'description': 'Something about esszet \u00df', - 'long_description': 'More things about esszet \u00df'} - cmd = self._run(metadata) - self.assertEqual(cmd._warnings, 0) - - @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") - def test_check_document(self): - pkg_info, dist = self.create_dist() - cmd = check(dist) - - # let's see if it detects broken rest - broken_rest = 'title\n===\n\ntest' - msgs = cmd._check_rst_data(broken_rest) - self.assertEqual(len(msgs), 1) - - # and non-broken rest - rest = 'title\n=====\n\ntest' - msgs = cmd._check_rst_data(rest) - self.assertEqual(len(msgs), 0) - - @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") - def test_check_restructuredtext(self): - # let's see if it detects broken rest in long_description - broken_rest = 'title\n===\n\ntest' - pkg_info, dist = self.create_dist(long_description=broken_rest) - cmd = check(dist) - cmd.check_restructuredtext() - self.assertEqual(cmd._warnings, 1) - - # let's see if we have an error with strict=1 - metadata = {'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx', - 'name': 'xxx', 'version': 'xxx', - 'long_description': broken_rest} - self.assertRaises(DistutilsSetupError, self._run, metadata, - **{'strict': 1, 'restructuredtext': 1}) - - # and non-broken rest, including a non-ASCII character to test #12114 - metadata['long_description'] = 'title\n=====\n\ntest \u00df' - cmd = self._run(metadata, strict=1, restructuredtext=1) - self.assertEqual(cmd._warnings, 0) - - # check that includes work to test #31292 - metadata['long_description'] = 'title\n=====\n\n.. include:: includetest.rst' - cmd = self._run(metadata, cwd=HERE, strict=1, restructuredtext=1) - self.assertEqual(cmd._warnings, 0) - - @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") - def test_check_restructuredtext_with_syntax_highlight(self): - # Don't fail if there is a `code` or `code-block` directive - - example_rst_docs = [] - example_rst_docs.append(textwrap.dedent("""\ - Here's some code: - - .. code:: python - - def foo(): - pass - """)) - example_rst_docs.append(textwrap.dedent("""\ - Here's some code: - - .. code-block:: python - - def foo(): - pass - """)) - - for rest_with_code in example_rst_docs: - pkg_info, dist = self.create_dist(long_description=rest_with_code) - cmd = check(dist) - cmd.check_restructuredtext() - msgs = cmd._check_rst_data(rest_with_code) - if pygments is not None: - self.assertEqual(len(msgs), 0) - else: - self.assertEqual(len(msgs), 1) - self.assertEqual( - str(msgs[0][1]), - 'Cannot analyze code. Pygments package not found.' - ) - - def test_check_all(self): - - metadata = {'url': 'xxx', 'author': 'xxx'} - self.assertRaises(DistutilsSetupError, self._run, - {}, **{'strict': 1, - 'restructuredtext': 1}) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(CheckTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_clean.py b/python/Lib/distutils/tests/test_clean.py deleted file mode 100644 index 8860435..0000000 --- a/python/Lib/distutils/tests/test_clean.py +++ /dev/null @@ -1,49 +0,0 @@ -"""Tests for distutils.command.clean.""" -import os -import unittest - -from distutils.command.clean import clean -from distutils.tests import support -from test.support import run_unittest - -class cleanTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - def test_simple_run(self): - pkg_dir, dist = self.create_dist() - cmd = clean(dist) - - # let's add some elements clean should remove - dirs = [(d, os.path.join(pkg_dir, d)) - for d in ('build_temp', 'build_lib', 'bdist_base', - 'build_scripts', 'build_base')] - - for name, path in dirs: - os.mkdir(path) - setattr(cmd, name, path) - if name == 'build_base': - continue - for f in ('one', 'two', 'three'): - self.write_file(os.path.join(path, f)) - - # let's run the command - cmd.all = 1 - cmd.ensure_finalized() - cmd.run() - - # make sure the files where removed - for name, path in dirs: - self.assertFalse(os.path.exists(path), - '%s was not removed' % path) - - # let's run the command again (should spit warnings but succeed) - cmd.all = 1 - cmd.ensure_finalized() - cmd.run() - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(cleanTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_cmd.py b/python/Lib/distutils/tests/test_cmd.py deleted file mode 100644 index b466651..0000000 --- a/python/Lib/distutils/tests/test_cmd.py +++ /dev/null @@ -1,126 +0,0 @@ -"""Tests for distutils.cmd.""" -import unittest -import os -from test.support import captured_stdout, run_unittest - -from distutils.cmd import Command -from distutils.dist import Distribution -from distutils.errors import DistutilsOptionError -from distutils import debug - -class MyCmd(Command): - def initialize_options(self): - pass - -class CommandTestCase(unittest.TestCase): - - def setUp(self): - dist = Distribution() - self.cmd = MyCmd(dist) - - def test_ensure_string_list(self): - - cmd = self.cmd - cmd.not_string_list = ['one', 2, 'three'] - cmd.yes_string_list = ['one', 'two', 'three'] - cmd.not_string_list2 = object() - cmd.yes_string_list2 = 'ok' - cmd.ensure_string_list('yes_string_list') - cmd.ensure_string_list('yes_string_list2') - - self.assertRaises(DistutilsOptionError, - cmd.ensure_string_list, 'not_string_list') - - self.assertRaises(DistutilsOptionError, - cmd.ensure_string_list, 'not_string_list2') - - cmd.option1 = 'ok,dok' - cmd.ensure_string_list('option1') - self.assertEqual(cmd.option1, ['ok', 'dok']) - - cmd.option2 = ['xxx', 'www'] - cmd.ensure_string_list('option2') - - cmd.option3 = ['ok', 2] - self.assertRaises(DistutilsOptionError, cmd.ensure_string_list, - 'option3') - - - def test_make_file(self): - - cmd = self.cmd - - # making sure it raises when infiles is not a string or a list/tuple - self.assertRaises(TypeError, cmd.make_file, - infiles=1, outfile='', func='func', args=()) - - # making sure execute gets called properly - def _execute(func, args, exec_msg, level): - self.assertEqual(exec_msg, 'generating out from in') - cmd.force = True - cmd.execute = _execute - cmd.make_file(infiles='in', outfile='out', func='func', args=()) - - def test_dump_options(self): - - msgs = [] - def _announce(msg, level): - msgs.append(msg) - cmd = self.cmd - cmd.announce = _announce - cmd.option1 = 1 - cmd.option2 = 1 - cmd.user_options = [('option1', '', ''), ('option2', '', '')] - cmd.dump_options() - - wanted = ["command options for 'MyCmd':", ' option1 = 1', - ' option2 = 1'] - self.assertEqual(msgs, wanted) - - def test_ensure_string(self): - cmd = self.cmd - cmd.option1 = 'ok' - cmd.ensure_string('option1') - - cmd.option2 = None - cmd.ensure_string('option2', 'xxx') - self.assertTrue(hasattr(cmd, 'option2')) - - cmd.option3 = 1 - self.assertRaises(DistutilsOptionError, cmd.ensure_string, 'option3') - - def test_ensure_filename(self): - cmd = self.cmd - cmd.option1 = __file__ - cmd.ensure_filename('option1') - cmd.option2 = 'xxx' - self.assertRaises(DistutilsOptionError, cmd.ensure_filename, 'option2') - - def test_ensure_dirname(self): - cmd = self.cmd - cmd.option1 = os.path.dirname(__file__) or os.curdir - cmd.ensure_dirname('option1') - cmd.option2 = 'xxx' - self.assertRaises(DistutilsOptionError, cmd.ensure_dirname, 'option2') - - def test_debug_print(self): - cmd = self.cmd - with captured_stdout() as stdout: - cmd.debug_print('xxx') - stdout.seek(0) - self.assertEqual(stdout.read(), '') - - debug.DEBUG = True - try: - with captured_stdout() as stdout: - cmd.debug_print('xxx') - stdout.seek(0) - self.assertEqual(stdout.read(), 'xxx\n') - finally: - debug.DEBUG = False - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(CommandTestCase) - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_config.py b/python/Lib/distutils/tests/test_config.py deleted file mode 100644 index d8f0a8f..0000000 --- a/python/Lib/distutils/tests/test_config.py +++ /dev/null @@ -1,141 +0,0 @@ -"""Tests for distutils.pypirc.pypirc.""" -import os -import unittest - -from distutils.core import PyPIRCCommand -from distutils.core import Distribution -from distutils.log import set_threshold -from distutils.log import WARN - -from distutils.tests import support -from test.support import run_unittest - -PYPIRC = """\ -[distutils] - -index-servers = - server1 - server2 - server3 - -[server1] -username:me -password:secret - -[server2] -username:meagain -password: secret -realm:acme -repository:http://another.pypi/ - -[server3] -username:cbiggles -password:yh^%#rest-of-my-password -""" - -PYPIRC_OLD = """\ -[server-login] -username:tarek -password:secret -""" - -WANTED = """\ -[distutils] -index-servers = - pypi - -[pypi] -username:tarek -password:xxx -""" - - -class BasePyPIRCCommandTestCase(support.TempdirManager, - support.LoggingSilencer, - support.EnvironGuard, - unittest.TestCase): - - def setUp(self): - """Patches the environment.""" - super(BasePyPIRCCommandTestCase, self).setUp() - self.tmp_dir = self.mkdtemp() - os.environ['HOME'] = self.tmp_dir - os.environ['USERPROFILE'] = self.tmp_dir - self.rc = os.path.join(self.tmp_dir, '.pypirc') - self.dist = Distribution() - - class command(PyPIRCCommand): - def __init__(self, dist): - PyPIRCCommand.__init__(self, dist) - def initialize_options(self): - pass - finalize_options = initialize_options - - self._cmd = command - self.old_threshold = set_threshold(WARN) - - def tearDown(self): - """Removes the patch.""" - set_threshold(self.old_threshold) - super(BasePyPIRCCommandTestCase, self).tearDown() - - -class PyPIRCCommandTestCase(BasePyPIRCCommandTestCase): - - def test_server_registration(self): - # This test makes sure PyPIRCCommand knows how to: - # 1. handle several sections in .pypirc - # 2. handle the old format - - # new format - self.write_file(self.rc, PYPIRC) - cmd = self._cmd(self.dist) - config = cmd._read_pypirc() - - config = list(sorted(config.items())) - waited = [('password', 'secret'), ('realm', 'pypi'), - ('repository', 'https://upload.pypi.org/legacy/'), - ('server', 'server1'), ('username', 'me')] - self.assertEqual(config, waited) - - # old format - self.write_file(self.rc, PYPIRC_OLD) - config = cmd._read_pypirc() - config = list(sorted(config.items())) - waited = [('password', 'secret'), ('realm', 'pypi'), - ('repository', 'https://upload.pypi.org/legacy/'), - ('server', 'server-login'), ('username', 'tarek')] - self.assertEqual(config, waited) - - def test_server_empty_registration(self): - cmd = self._cmd(self.dist) - rc = cmd._get_rc_file() - self.assertFalse(os.path.exists(rc)) - cmd._store_pypirc('tarek', 'xxx') - self.assertTrue(os.path.exists(rc)) - f = open(rc) - try: - content = f.read() - self.assertEqual(content, WANTED) - finally: - f.close() - - def test_config_interpolation(self): - # using the % character in .pypirc should not raise an error (#20120) - self.write_file(self.rc, PYPIRC) - cmd = self._cmd(self.dist) - cmd.repository = 'server3' - config = cmd._read_pypirc() - - config = list(sorted(config.items())) - waited = [('password', 'yh^%#rest-of-my-password'), ('realm', 'pypi'), - ('repository', 'https://upload.pypi.org/legacy/'), - ('server', 'server3'), ('username', 'cbiggles')] - self.assertEqual(config, waited) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(PyPIRCCommandTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_config_cmd.py b/python/Lib/distutils/tests/test_config_cmd.py deleted file mode 100644 index 5bae678..0000000 --- a/python/Lib/distutils/tests/test_config_cmd.py +++ /dev/null @@ -1,103 +0,0 @@ -"""Tests for distutils.command.config.""" -import unittest -import os -import sys -import sysconfig -from test.support import ( - run_unittest, missing_compiler_executable, requires_subprocess -) - -from distutils.command.config import dump_file, config -from distutils.tests import support -from distutils import log - -class ConfigTestCase(support.LoggingSilencer, - support.TempdirManager, - unittest.TestCase): - - def _info(self, msg, *args): - for line in msg.splitlines(): - self._logs.append(line) - - def setUp(self): - super(ConfigTestCase, self).setUp() - self._logs = [] - self.old_log = log.info - log.info = self._info - self.old_config_vars = dict(sysconfig._CONFIG_VARS) - - def tearDown(self): - log.info = self.old_log - sysconfig._CONFIG_VARS.clear() - sysconfig._CONFIG_VARS.update(self.old_config_vars) - super(ConfigTestCase, self).tearDown() - - def test_dump_file(self): - this_file = os.path.splitext(__file__)[0] + '.py' - f = open(this_file) - try: - numlines = len(f.readlines()) - finally: - f.close() - - dump_file(this_file, 'I am the header') - self.assertEqual(len(self._logs), numlines+1) - - @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") - @requires_subprocess() - def test_search_cpp(self): - cmd = missing_compiler_executable(['preprocessor']) - if cmd is not None: - self.skipTest('The %r command is not found' % cmd) - pkg_dir, dist = self.create_dist() - cmd = config(dist) - cmd._check_compiler() - compiler = cmd.compiler - if sys.platform[:3] == "aix" and "xlc" in compiler.preprocessor[0].lower(): - self.skipTest('xlc: The -E option overrides the -P, -o, and -qsyntaxonly options') - - # simple pattern searches - match = cmd.search_cpp(pattern='xxx', body='/* xxx */') - self.assertEqual(match, 0) - - match = cmd.search_cpp(pattern='_configtest', body='/* xxx */') - self.assertEqual(match, 1) - - def test_finalize_options(self): - # finalize_options does a bit of transformation - # on options - pkg_dir, dist = self.create_dist() - cmd = config(dist) - cmd.include_dirs = 'one%stwo' % os.pathsep - cmd.libraries = 'one' - cmd.library_dirs = 'three%sfour' % os.pathsep - cmd.ensure_finalized() - - self.assertEqual(cmd.include_dirs, ['one', 'two']) - self.assertEqual(cmd.libraries, ['one']) - self.assertEqual(cmd.library_dirs, ['three', 'four']) - - def test_clean(self): - # _clean removes files - tmp_dir = self.mkdtemp() - f1 = os.path.join(tmp_dir, 'one') - f2 = os.path.join(tmp_dir, 'two') - - self.write_file(f1, 'xxx') - self.write_file(f2, 'xxx') - - for f in (f1, f2): - self.assertTrue(os.path.exists(f)) - - pkg_dir, dist = self.create_dist() - cmd = config(dist) - cmd._clean(f1, f2) - - for f in (f1, f2): - self.assertFalse(os.path.exists(f)) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(ConfigTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_core.py b/python/Lib/distutils/tests/test_core.py deleted file mode 100644 index 3c542b3..0000000 --- a/python/Lib/distutils/tests/test_core.py +++ /dev/null @@ -1,140 +0,0 @@ -"""Tests for distutils.core.""" - -import io -import distutils.core -import os -import shutil -import sys -from test.support import captured_stdout, run_unittest -from test.support import os_helper -import unittest -from distutils.tests import support -from distutils import log - -# setup script that uses __file__ -setup_using___file__ = """\ - -__file__ - -from distutils.core import setup -setup() -""" - -setup_prints_cwd = """\ - -import os -print(os.getcwd()) - -from distutils.core import setup -setup() -""" - -setup_does_nothing = """\ -from distutils.core import setup -setup() -""" - - -setup_defines_subclass = """\ -from distutils.core import setup -from distutils.command.install import install as _install - -class install(_install): - sub_commands = _install.sub_commands + ['cmd'] - -setup(cmdclass={'install': install}) -""" - -class CoreTestCase(support.EnvironGuard, unittest.TestCase): - - def setUp(self): - super(CoreTestCase, self).setUp() - self.old_stdout = sys.stdout - self.cleanup_testfn() - self.old_argv = sys.argv, sys.argv[:] - self.addCleanup(log.set_threshold, log._global_log.threshold) - - def tearDown(self): - sys.stdout = self.old_stdout - self.cleanup_testfn() - sys.argv = self.old_argv[0] - sys.argv[:] = self.old_argv[1] - super(CoreTestCase, self).tearDown() - - def cleanup_testfn(self): - path = os_helper.TESTFN - if os.path.isfile(path): - os.remove(path) - elif os.path.isdir(path): - shutil.rmtree(path) - - def write_setup(self, text, path=os_helper.TESTFN): - f = open(path, "w") - try: - f.write(text) - finally: - f.close() - return path - - def test_run_setup_provides_file(self): - # Make sure the script can use __file__; if that's missing, the test - # setup.py script will raise NameError. - distutils.core.run_setup( - self.write_setup(setup_using___file__)) - - def test_run_setup_preserves_sys_argv(self): - # Make sure run_setup does not clobber sys.argv - argv_copy = sys.argv.copy() - distutils.core.run_setup( - self.write_setup(setup_does_nothing)) - self.assertEqual(sys.argv, argv_copy) - - def test_run_setup_defines_subclass(self): - # Make sure the script can use __file__; if that's missing, the test - # setup.py script will raise NameError. - dist = distutils.core.run_setup( - self.write_setup(setup_defines_subclass)) - install = dist.get_command_obj('install') - self.assertIn('cmd', install.sub_commands) - - def test_run_setup_uses_current_dir(self): - # This tests that the setup script is run with the current directory - # as its own current directory; this was temporarily broken by a - # previous patch when TESTFN did not use the current directory. - sys.stdout = io.StringIO() - cwd = os.getcwd() - - # Create a directory and write the setup.py file there: - os.mkdir(os_helper.TESTFN) - setup_py = os.path.join(os_helper.TESTFN, "setup.py") - distutils.core.run_setup( - self.write_setup(setup_prints_cwd, path=setup_py)) - - output = sys.stdout.getvalue() - if output.endswith("\n"): - output = output[:-1] - self.assertEqual(cwd, output) - - def test_debug_mode(self): - # this covers the code called when DEBUG is set - sys.argv = ['setup.py', '--name'] - with captured_stdout() as stdout: - distutils.core.setup(name='bar') - stdout.seek(0) - self.assertEqual(stdout.read(), 'bar\n') - - distutils.core.DEBUG = True - try: - with captured_stdout() as stdout: - distutils.core.setup(name='bar') - finally: - distutils.core.DEBUG = False - stdout.seek(0) - wanted = "options (after parsing config files):\n" - self.assertEqual(stdout.readlines()[0], wanted) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(CoreTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_cygwinccompiler.py b/python/Lib/distutils/tests/test_cygwinccompiler.py deleted file mode 100644 index 7df3f5d..0000000 --- a/python/Lib/distutils/tests/test_cygwinccompiler.py +++ /dev/null @@ -1,154 +0,0 @@ -"""Tests for distutils.cygwinccompiler.""" -import unittest -import sys -import os -from io import BytesIO -from test.support import run_unittest - -from distutils import cygwinccompiler -from distutils.cygwinccompiler import (check_config_h, - CONFIG_H_OK, CONFIG_H_NOTOK, - CONFIG_H_UNCERTAIN, get_versions, - get_msvcr) -from distutils.tests import support - -class FakePopen(object): - test_class = None - - def __init__(self, cmd, shell, stdout): - self.cmd = cmd.split()[0] - exes = self.test_class._exes - if self.cmd in exes: - # issue #6438 in Python 3.x, Popen returns bytes - self.stdout = BytesIO(exes[self.cmd]) - else: - self.stdout = os.popen(cmd, 'r') - - -class CygwinCCompilerTestCase(support.TempdirManager, - unittest.TestCase): - - def setUp(self): - super(CygwinCCompilerTestCase, self).setUp() - self.version = sys.version - self.python_h = os.path.join(self.mkdtemp(), 'python.h') - from distutils import sysconfig - self.old_get_config_h_filename = sysconfig.get_config_h_filename - sysconfig.get_config_h_filename = self._get_config_h_filename - self.old_find_executable = cygwinccompiler.find_executable - cygwinccompiler.find_executable = self._find_executable - self._exes = {} - self.old_popen = cygwinccompiler.Popen - FakePopen.test_class = self - cygwinccompiler.Popen = FakePopen - - def tearDown(self): - sys.version = self.version - from distutils import sysconfig - sysconfig.get_config_h_filename = self.old_get_config_h_filename - cygwinccompiler.find_executable = self.old_find_executable - cygwinccompiler.Popen = self.old_popen - super(CygwinCCompilerTestCase, self).tearDown() - - def _get_config_h_filename(self): - return self.python_h - - def _find_executable(self, name): - if name in self._exes: - return name - return None - - def test_check_config_h(self): - - # check_config_h looks for "GCC" in sys.version first - # returns CONFIG_H_OK if found - sys.version = ('2.6.1 (r261:67515, Dec 6 2008, 16:42:21) \n[GCC ' - '4.0.1 (Apple Computer, Inc. build 5370)]') - - self.assertEqual(check_config_h()[0], CONFIG_H_OK) - - # then it tries to see if it can find "__GNUC__" in pyconfig.h - sys.version = 'something without the *CC word' - - # if the file doesn't exist it returns CONFIG_H_UNCERTAIN - self.assertEqual(check_config_h()[0], CONFIG_H_UNCERTAIN) - - # if it exists but does not contain __GNUC__, it returns CONFIG_H_NOTOK - self.write_file(self.python_h, 'xxx') - self.assertEqual(check_config_h()[0], CONFIG_H_NOTOK) - - # and CONFIG_H_OK if __GNUC__ is found - self.write_file(self.python_h, 'xxx __GNUC__ xxx') - self.assertEqual(check_config_h()[0], CONFIG_H_OK) - - def test_get_versions(self): - - # get_versions calls distutils.spawn.find_executable on - # 'gcc', 'ld' and 'dllwrap' - self.assertEqual(get_versions(), (None, None, None)) - - # Let's fake we have 'gcc' and it returns '3.4.5' - self._exes['gcc'] = b'gcc (GCC) 3.4.5 (mingw special)\nFSF' - res = get_versions() - self.assertEqual(str(res[0]), '3.4.5') - - # and let's see what happens when the version - # doesn't match the regular expression - # (\d+\.\d+(\.\d+)*) - self._exes['gcc'] = b'very strange output' - res = get_versions() - self.assertEqual(res[0], None) - - # same thing for ld - self._exes['ld'] = b'GNU ld version 2.17.50 20060824' - res = get_versions() - self.assertEqual(str(res[1]), '2.17.50') - self._exes['ld'] = b'@(#)PROGRAM:ld PROJECT:ld64-77' - res = get_versions() - self.assertEqual(res[1], None) - - # and dllwrap - self._exes['dllwrap'] = b'GNU dllwrap 2.17.50 20060824\nFSF' - res = get_versions() - self.assertEqual(str(res[2]), '2.17.50') - self._exes['dllwrap'] = b'Cheese Wrap' - res = get_versions() - self.assertEqual(res[2], None) - - def test_get_msvcr(self): - - # none - sys.version = ('2.6.1 (r261:67515, Dec 6 2008, 16:42:21) ' - '\n[GCC 4.0.1 (Apple Computer, Inc. build 5370)]') - self.assertEqual(get_msvcr(), None) - - # MSVC 7.0 - sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) ' - '[MSC v.1300 32 bits (Intel)]') - self.assertEqual(get_msvcr(), ['msvcr70']) - - # MSVC 7.1 - sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) ' - '[MSC v.1310 32 bits (Intel)]') - self.assertEqual(get_msvcr(), ['msvcr71']) - - # VS2005 / MSVC 8.0 - sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) ' - '[MSC v.1400 32 bits (Intel)]') - self.assertEqual(get_msvcr(), ['msvcr80']) - - # VS2008 / MSVC 9.0 - sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) ' - '[MSC v.1500 32 bits (Intel)]') - self.assertEqual(get_msvcr(), ['msvcr90']) - - # unknown - sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) ' - '[MSC v.1999 32 bits (Intel)]') - self.assertRaises(ValueError, get_msvcr) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(CygwinCCompilerTestCase) - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_dep_util.py b/python/Lib/distutils/tests/test_dep_util.py deleted file mode 100644 index 38c7b0e..0000000 --- a/python/Lib/distutils/tests/test_dep_util.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Tests for distutils.dep_util.""" -import unittest -import os - -from distutils.dep_util import newer, newer_pairwise, newer_group -from distutils.errors import DistutilsFileError -from distutils.tests import support -from test.support import run_unittest - -class DepUtilTestCase(support.TempdirManager, unittest.TestCase): - - def test_newer(self): - - tmpdir = self.mkdtemp() - new_file = os.path.join(tmpdir, 'new') - old_file = os.path.abspath(__file__) - - # Raise DistutilsFileError if 'new_file' does not exist. - self.assertRaises(DistutilsFileError, newer, new_file, old_file) - - # Return true if 'new_file' exists and is more recently modified than - # 'old_file', or if 'new_file' exists and 'old_file' doesn't. - self.write_file(new_file) - self.assertTrue(newer(new_file, 'I_dont_exist')) - self.assertTrue(newer(new_file, old_file)) - - # Return false if both exist and 'old_file' is the same age or younger - # than 'new_file'. - self.assertFalse(newer(old_file, new_file)) - - def test_newer_pairwise(self): - tmpdir = self.mkdtemp() - sources = os.path.join(tmpdir, 'sources') - targets = os.path.join(tmpdir, 'targets') - os.mkdir(sources) - os.mkdir(targets) - one = os.path.join(sources, 'one') - two = os.path.join(sources, 'two') - three = os.path.abspath(__file__) # I am the old file - four = os.path.join(targets, 'four') - self.write_file(one) - self.write_file(two) - self.write_file(four) - - self.assertEqual(newer_pairwise([one, two], [three, four]), - ([one],[three])) - - def test_newer_group(self): - tmpdir = self.mkdtemp() - sources = os.path.join(tmpdir, 'sources') - os.mkdir(sources) - one = os.path.join(sources, 'one') - two = os.path.join(sources, 'two') - three = os.path.join(sources, 'three') - old_file = os.path.abspath(__file__) - - # return true if 'old_file' is out-of-date with respect to any file - # listed in 'sources'. - self.write_file(one) - self.write_file(two) - self.write_file(three) - self.assertTrue(newer_group([one, two, three], old_file)) - self.assertFalse(newer_group([one, two, old_file], three)) - - # missing handling - os.remove(one) - self.assertRaises(OSError, newer_group, [one, two, old_file], three) - - self.assertFalse(newer_group([one, two, old_file], three, - missing='ignore')) - - self.assertTrue(newer_group([one, two, old_file], three, - missing='newer')) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(DepUtilTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_dir_util.py b/python/Lib/distutils/tests/test_dir_util.py deleted file mode 100644 index 05b2744..0000000 --- a/python/Lib/distutils/tests/test_dir_util.py +++ /dev/null @@ -1,143 +0,0 @@ -"""Tests for distutils.dir_util.""" -import unittest -import os -import stat -import sys -from unittest.mock import patch - -from distutils import dir_util, errors -from distutils.dir_util import (mkpath, remove_tree, create_tree, copy_tree, - ensure_relative) - -from distutils import log -from distutils.tests import support -from test.support import run_unittest, is_emscripten, is_wasi - - -class DirUtilTestCase(support.TempdirManager, unittest.TestCase): - - def _log(self, msg, *args): - if len(args) > 0: - self._logs.append(msg % args) - else: - self._logs.append(msg) - - def setUp(self): - super(DirUtilTestCase, self).setUp() - self._logs = [] - tmp_dir = self.mkdtemp() - self.root_target = os.path.join(tmp_dir, 'deep') - self.target = os.path.join(self.root_target, 'here') - self.target2 = os.path.join(tmp_dir, 'deep2') - self.old_log = log.info - log.info = self._log - - def tearDown(self): - log.info = self.old_log - super(DirUtilTestCase, self).tearDown() - - def test_mkpath_remove_tree_verbosity(self): - - mkpath(self.target, verbose=0) - wanted = [] - self.assertEqual(self._logs, wanted) - remove_tree(self.root_target, verbose=0) - - mkpath(self.target, verbose=1) - wanted = ['creating %s' % self.root_target, - 'creating %s' % self.target] - self.assertEqual(self._logs, wanted) - self._logs = [] - - remove_tree(self.root_target, verbose=1) - wanted = ["removing '%s' (and everything under it)" % self.root_target] - self.assertEqual(self._logs, wanted) - - @unittest.skipIf(sys.platform.startswith('win'), - "This test is only appropriate for POSIX-like systems.") - @unittest.skipIf( - is_emscripten or is_wasi, - "Emscripten's/WASI's umask is a stub." - ) - def test_mkpath_with_custom_mode(self): - # Get and set the current umask value for testing mode bits. - umask = os.umask(0o002) - os.umask(umask) - mkpath(self.target, 0o700) - self.assertEqual( - stat.S_IMODE(os.stat(self.target).st_mode), 0o700 & ~umask) - mkpath(self.target2, 0o555) - self.assertEqual( - stat.S_IMODE(os.stat(self.target2).st_mode), 0o555 & ~umask) - - def test_create_tree_verbosity(self): - - create_tree(self.root_target, ['one', 'two', 'three'], verbose=0) - self.assertEqual(self._logs, []) - remove_tree(self.root_target, verbose=0) - - wanted = ['creating %s' % self.root_target] - create_tree(self.root_target, ['one', 'two', 'three'], verbose=1) - self.assertEqual(self._logs, wanted) - - remove_tree(self.root_target, verbose=0) - - def test_copy_tree_verbosity(self): - - mkpath(self.target, verbose=0) - - copy_tree(self.target, self.target2, verbose=0) - self.assertEqual(self._logs, []) - - remove_tree(self.root_target, verbose=0) - - mkpath(self.target, verbose=0) - a_file = os.path.join(self.target, 'ok.txt') - with open(a_file, 'w') as f: - f.write('some content') - - wanted = ['copying %s -> %s' % (a_file, self.target2)] - copy_tree(self.target, self.target2, verbose=1) - self.assertEqual(self._logs, wanted) - - remove_tree(self.root_target, verbose=0) - remove_tree(self.target2, verbose=0) - - def test_copy_tree_skips_nfs_temp_files(self): - mkpath(self.target, verbose=0) - - a_file = os.path.join(self.target, 'ok.txt') - nfs_file = os.path.join(self.target, '.nfs123abc') - for f in a_file, nfs_file: - with open(f, 'w') as fh: - fh.write('some content') - - copy_tree(self.target, self.target2) - self.assertEqual(os.listdir(self.target2), ['ok.txt']) - - remove_tree(self.root_target, verbose=0) - remove_tree(self.target2, verbose=0) - - def test_ensure_relative(self): - if os.sep == '/': - self.assertEqual(ensure_relative('/home/foo'), 'home/foo') - self.assertEqual(ensure_relative('some/path'), 'some/path') - else: # \\ - self.assertEqual(ensure_relative('c:\\home\\foo'), 'c:home\\foo') - self.assertEqual(ensure_relative('home\\foo'), 'home\\foo') - - def test_copy_tree_exception_in_listdir(self): - """ - An exception in listdir should raise a DistutilsFileError - """ - with patch("os.listdir", side_effect=OSError()), \ - self.assertRaises(errors.DistutilsFileError): - src = self.tempdirs[-1] - dir_util.copy_tree(src, None) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(DirUtilTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_dist.py b/python/Lib/distutils/tests/test_dist.py deleted file mode 100644 index 2007d28..0000000 --- a/python/Lib/distutils/tests/test_dist.py +++ /dev/null @@ -1,529 +0,0 @@ -"""Tests for distutils.dist.""" -import os -import io -import sys -import unittest -import warnings -import textwrap - -from unittest import mock - -from distutils.dist import Distribution, fix_help_options -from distutils.cmd import Command - -from test.support import ( - captured_stdout, captured_stderr, run_unittest -) -from test.support.os_helper import TESTFN -from distutils.tests import support -from distutils import log - - -class test_dist(Command): - """Sample distutils extension command.""" - - user_options = [ - ("sample-option=", "S", "help text"), - ] - - def initialize_options(self): - self.sample_option = None - - -class TestDistribution(Distribution): - """Distribution subclasses that avoids the default search for - configuration files. - - The ._config_files attribute must be set before - .parse_config_files() is called. - """ - - def find_config_files(self): - return self._config_files - - -class DistributionTestCase(support.LoggingSilencer, - support.TempdirManager, - support.EnvironGuard, - unittest.TestCase): - - def setUp(self): - super(DistributionTestCase, self).setUp() - self.argv = sys.argv, sys.argv[:] - del sys.argv[1:] - - def tearDown(self): - sys.argv = self.argv[0] - sys.argv[:] = self.argv[1] - super(DistributionTestCase, self).tearDown() - - def create_distribution(self, configfiles=()): - d = TestDistribution() - d._config_files = configfiles - d.parse_config_files() - d.parse_command_line() - return d - - def test_command_packages_unspecified(self): - sys.argv.append("build") - d = self.create_distribution() - self.assertEqual(d.get_command_packages(), ["distutils.command"]) - - def test_command_packages_cmdline(self): - from distutils.tests.test_dist import test_dist - sys.argv.extend(["--command-packages", - "foo.bar,distutils.tests", - "test_dist", - "-Ssometext", - ]) - d = self.create_distribution() - # let's actually try to load our test command: - self.assertEqual(d.get_command_packages(), - ["distutils.command", "foo.bar", "distutils.tests"]) - cmd = d.get_command_obj("test_dist") - self.assertIsInstance(cmd, test_dist) - self.assertEqual(cmd.sample_option, "sometext") - - def test_venv_install_options(self): - sys.argv.append("install") - self.addCleanup(os.unlink, TESTFN) - - fakepath = '/somedir' - - with open(TESTFN, "w") as f: - print(("[install]\n" - "install-base = {0}\n" - "install-platbase = {0}\n" - "install-lib = {0}\n" - "install-platlib = {0}\n" - "install-purelib = {0}\n" - "install-headers = {0}\n" - "install-scripts = {0}\n" - "install-data = {0}\n" - "prefix = {0}\n" - "exec-prefix = {0}\n" - "home = {0}\n" - "user = {0}\n" - "root = {0}").format(fakepath), file=f) - - # Base case: Not in a Virtual Environment - with mock.patch.multiple(sys, prefix='/a', base_prefix='/a') as values: - d = self.create_distribution([TESTFN]) - - option_tuple = (TESTFN, fakepath) - - result_dict = { - 'install_base': option_tuple, - 'install_platbase': option_tuple, - 'install_lib': option_tuple, - 'install_platlib': option_tuple, - 'install_purelib': option_tuple, - 'install_headers': option_tuple, - 'install_scripts': option_tuple, - 'install_data': option_tuple, - 'prefix': option_tuple, - 'exec_prefix': option_tuple, - 'home': option_tuple, - 'user': option_tuple, - 'root': option_tuple, - } - - self.assertEqual( - sorted(d.command_options.get('install').keys()), - sorted(result_dict.keys())) - - for (key, value) in d.command_options.get('install').items(): - self.assertEqual(value, result_dict[key]) - - # Test case: In a Virtual Environment - with mock.patch.multiple(sys, prefix='/a', base_prefix='/b') as values: - d = self.create_distribution([TESTFN]) - - for key in result_dict.keys(): - self.assertNotIn(key, d.command_options.get('install', {})) - - def test_command_packages_configfile(self): - sys.argv.append("build") - self.addCleanup(os.unlink, TESTFN) - f = open(TESTFN, "w") - try: - print("[global]", file=f) - print("command_packages = foo.bar, splat", file=f) - finally: - f.close() - - d = self.create_distribution([TESTFN]) - self.assertEqual(d.get_command_packages(), - ["distutils.command", "foo.bar", "splat"]) - - # ensure command line overrides config: - sys.argv[1:] = ["--command-packages", "spork", "build"] - d = self.create_distribution([TESTFN]) - self.assertEqual(d.get_command_packages(), - ["distutils.command", "spork"]) - - # Setting --command-packages to '' should cause the default to - # be used even if a config file specified something else: - sys.argv[1:] = ["--command-packages", "", "build"] - d = self.create_distribution([TESTFN]) - self.assertEqual(d.get_command_packages(), ["distutils.command"]) - - def test_empty_options(self): - # an empty options dictionary should not stay in the - # list of attributes - - # catching warnings - warns = [] - - def _warn(msg): - warns.append(msg) - - self.addCleanup(setattr, warnings, 'warn', warnings.warn) - warnings.warn = _warn - dist = Distribution(attrs={'author': 'xxx', 'name': 'xxx', - 'version': 'xxx', 'url': 'xxxx', - 'options': {}}) - - self.assertEqual(len(warns), 0) - self.assertNotIn('options', dir(dist)) - - def test_finalize_options(self): - attrs = {'keywords': 'one,two', - 'platforms': 'one,two'} - - dist = Distribution(attrs=attrs) - dist.finalize_options() - - # finalize_option splits platforms and keywords - self.assertEqual(dist.metadata.platforms, ['one', 'two']) - self.assertEqual(dist.metadata.keywords, ['one', 'two']) - - attrs = {'keywords': 'foo bar', - 'platforms': 'foo bar'} - dist = Distribution(attrs=attrs) - dist.finalize_options() - self.assertEqual(dist.metadata.platforms, ['foo bar']) - self.assertEqual(dist.metadata.keywords, ['foo bar']) - - def test_get_command_packages(self): - dist = Distribution() - self.assertEqual(dist.command_packages, None) - cmds = dist.get_command_packages() - self.assertEqual(cmds, ['distutils.command']) - self.assertEqual(dist.command_packages, - ['distutils.command']) - - dist.command_packages = 'one,two' - cmds = dist.get_command_packages() - self.assertEqual(cmds, ['distutils.command', 'one', 'two']) - - def test_announce(self): - # make sure the level is known - dist = Distribution() - args = ('ok',) - kwargs = {'level': 'ok2'} - self.assertRaises(ValueError, dist.announce, args, kwargs) - - - def test_find_config_files_disable(self): - # Ticket #1180: Allow user to disable their home config file. - temp_home = self.mkdtemp() - if os.name == 'posix': - user_filename = os.path.join(temp_home, ".pydistutils.cfg") - else: - user_filename = os.path.join(temp_home, "pydistutils.cfg") - - with open(user_filename, 'w') as f: - f.write('[distutils]\n') - - def _expander(path): - return temp_home - - old_expander = os.path.expanduser - os.path.expanduser = _expander - try: - d = Distribution() - all_files = d.find_config_files() - - d = Distribution(attrs={'script_args': ['--no-user-cfg']}) - files = d.find_config_files() - finally: - os.path.expanduser = old_expander - - # make sure --no-user-cfg disables the user cfg file - self.assertEqual(len(all_files)-1, len(files)) - -class MetadataTestCase(support.TempdirManager, support.EnvironGuard, - unittest.TestCase): - - def setUp(self): - super(MetadataTestCase, self).setUp() - self.argv = sys.argv, sys.argv[:] - - def tearDown(self): - sys.argv = self.argv[0] - sys.argv[:] = self.argv[1] - super(MetadataTestCase, self).tearDown() - - def format_metadata(self, dist): - sio = io.StringIO() - dist.metadata.write_pkg_file(sio) - return sio.getvalue() - - def test_simple_metadata(self): - attrs = {"name": "package", - "version": "1.0"} - dist = Distribution(attrs) - meta = self.format_metadata(dist) - self.assertIn("Metadata-Version: 1.0", meta) - self.assertNotIn("provides:", meta.lower()) - self.assertNotIn("requires:", meta.lower()) - self.assertNotIn("obsoletes:", meta.lower()) - - def test_provides(self): - attrs = {"name": "package", - "version": "1.0", - "provides": ["package", "package.sub"]} - dist = Distribution(attrs) - self.assertEqual(dist.metadata.get_provides(), - ["package", "package.sub"]) - self.assertEqual(dist.get_provides(), - ["package", "package.sub"]) - meta = self.format_metadata(dist) - self.assertIn("Metadata-Version: 1.1", meta) - self.assertNotIn("requires:", meta.lower()) - self.assertNotIn("obsoletes:", meta.lower()) - - def test_provides_illegal(self): - self.assertRaises(ValueError, Distribution, - {"name": "package", - "version": "1.0", - "provides": ["my.pkg (splat)"]}) - - def test_requires(self): - attrs = {"name": "package", - "version": "1.0", - "requires": ["other", "another (==1.0)"]} - dist = Distribution(attrs) - self.assertEqual(dist.metadata.get_requires(), - ["other", "another (==1.0)"]) - self.assertEqual(dist.get_requires(), - ["other", "another (==1.0)"]) - meta = self.format_metadata(dist) - self.assertIn("Metadata-Version: 1.1", meta) - self.assertNotIn("provides:", meta.lower()) - self.assertIn("Requires: other", meta) - self.assertIn("Requires: another (==1.0)", meta) - self.assertNotIn("obsoletes:", meta.lower()) - - def test_requires_illegal(self): - self.assertRaises(ValueError, Distribution, - {"name": "package", - "version": "1.0", - "requires": ["my.pkg (splat)"]}) - - def test_requires_to_list(self): - attrs = {"name": "package", - "requires": iter(["other"])} - dist = Distribution(attrs) - self.assertIsInstance(dist.metadata.requires, list) - - - def test_obsoletes(self): - attrs = {"name": "package", - "version": "1.0", - "obsoletes": ["other", "another (<1.0)"]} - dist = Distribution(attrs) - self.assertEqual(dist.metadata.get_obsoletes(), - ["other", "another (<1.0)"]) - self.assertEqual(dist.get_obsoletes(), - ["other", "another (<1.0)"]) - meta = self.format_metadata(dist) - self.assertIn("Metadata-Version: 1.1", meta) - self.assertNotIn("provides:", meta.lower()) - self.assertNotIn("requires:", meta.lower()) - self.assertIn("Obsoletes: other", meta) - self.assertIn("Obsoletes: another (<1.0)", meta) - - def test_obsoletes_illegal(self): - self.assertRaises(ValueError, Distribution, - {"name": "package", - "version": "1.0", - "obsoletes": ["my.pkg (splat)"]}) - - def test_obsoletes_to_list(self): - attrs = {"name": "package", - "obsoletes": iter(["other"])} - dist = Distribution(attrs) - self.assertIsInstance(dist.metadata.obsoletes, list) - - def test_classifier(self): - attrs = {'name': 'Boa', 'version': '3.0', - 'classifiers': ['Programming Language :: Python :: 3']} - dist = Distribution(attrs) - self.assertEqual(dist.get_classifiers(), - ['Programming Language :: Python :: 3']) - meta = self.format_metadata(dist) - self.assertIn('Metadata-Version: 1.1', meta) - - def test_classifier_invalid_type(self): - attrs = {'name': 'Boa', 'version': '3.0', - 'classifiers': ('Programming Language :: Python :: 3',)} - with captured_stderr() as error: - d = Distribution(attrs) - # should have warning about passing a non-list - self.assertIn('should be a list', error.getvalue()) - # should be converted to a list - self.assertIsInstance(d.metadata.classifiers, list) - self.assertEqual(d.metadata.classifiers, - list(attrs['classifiers'])) - - def test_keywords(self): - attrs = {'name': 'Monty', 'version': '1.0', - 'keywords': ['spam', 'eggs', 'life of brian']} - dist = Distribution(attrs) - self.assertEqual(dist.get_keywords(), - ['spam', 'eggs', 'life of brian']) - - def test_keywords_invalid_type(self): - attrs = {'name': 'Monty', 'version': '1.0', - 'keywords': ('spam', 'eggs', 'life of brian')} - with captured_stderr() as error: - d = Distribution(attrs) - # should have warning about passing a non-list - self.assertIn('should be a list', error.getvalue()) - # should be converted to a list - self.assertIsInstance(d.metadata.keywords, list) - self.assertEqual(d.metadata.keywords, list(attrs['keywords'])) - - def test_platforms(self): - attrs = {'name': 'Monty', 'version': '1.0', - 'platforms': ['GNU/Linux', 'Some Evil Platform']} - dist = Distribution(attrs) - self.assertEqual(dist.get_platforms(), - ['GNU/Linux', 'Some Evil Platform']) - - def test_platforms_invalid_types(self): - attrs = {'name': 'Monty', 'version': '1.0', - 'platforms': ('GNU/Linux', 'Some Evil Platform')} - with captured_stderr() as error: - d = Distribution(attrs) - # should have warning about passing a non-list - self.assertIn('should be a list', error.getvalue()) - # should be converted to a list - self.assertIsInstance(d.metadata.platforms, list) - self.assertEqual(d.metadata.platforms, list(attrs['platforms'])) - - def test_download_url(self): - attrs = {'name': 'Boa', 'version': '3.0', - 'download_url': 'http://example.org/boa'} - dist = Distribution(attrs) - meta = self.format_metadata(dist) - self.assertIn('Metadata-Version: 1.1', meta) - - def test_long_description(self): - long_desc = textwrap.dedent("""\ - example:: - We start here - and continue here - and end here.""") - attrs = {"name": "package", - "version": "1.0", - "long_description": long_desc} - - dist = Distribution(attrs) - meta = self.format_metadata(dist) - meta = meta.replace('\n' + 8 * ' ', '\n') - self.assertIn(long_desc, meta) - - def test_custom_pydistutils(self): - # fixes #2166 - # make sure pydistutils.cfg is found - if os.name == 'posix': - user_filename = ".pydistutils.cfg" - else: - user_filename = "pydistutils.cfg" - - temp_dir = self.mkdtemp() - user_filename = os.path.join(temp_dir, user_filename) - f = open(user_filename, 'w') - try: - f.write('.') - finally: - f.close() - - try: - dist = Distribution() - - # linux-style - if sys.platform in ('linux', 'darwin'): - os.environ['HOME'] = temp_dir - files = dist.find_config_files() - self.assertIn(user_filename, files) - - # win32-style - if sys.platform == 'win32': - # home drive should be found - os.environ['USERPROFILE'] = temp_dir - files = dist.find_config_files() - self.assertIn(user_filename, files, - '%r not found in %r' % (user_filename, files)) - finally: - os.remove(user_filename) - - def test_fix_help_options(self): - help_tuples = [('a', 'b', 'c', 'd'), (1, 2, 3, 4)] - fancy_options = fix_help_options(help_tuples) - self.assertEqual(fancy_options[0], ('a', 'b', 'c')) - self.assertEqual(fancy_options[1], (1, 2, 3)) - - def test_show_help(self): - # smoke test, just makes sure some help is displayed - self.addCleanup(log.set_threshold, log._global_log.threshold) - dist = Distribution() - sys.argv = [] - dist.help = 1 - dist.script_name = 'setup.py' - with captured_stdout() as s: - dist.parse_command_line() - - output = [line for line in s.getvalue().split('\n') - if line.strip() != ''] - self.assertTrue(output) - - - def test_read_metadata(self): - attrs = {"name": "package", - "version": "1.0", - "long_description": "desc", - "description": "xxx", - "download_url": "http://example.com", - "keywords": ['one', 'two'], - "requires": ['foo']} - - dist = Distribution(attrs) - metadata = dist.metadata - - # write it then reloads it - PKG_INFO = io.StringIO() - metadata.write_pkg_file(PKG_INFO) - PKG_INFO.seek(0) - metadata.read_pkg_file(PKG_INFO) - - self.assertEqual(metadata.name, "package") - self.assertEqual(metadata.version, "1.0") - self.assertEqual(metadata.description, "xxx") - self.assertEqual(metadata.download_url, 'http://example.com') - self.assertEqual(metadata.keywords, ['one', 'two']) - self.assertEqual(metadata.platforms, ['UNKNOWN']) - self.assertEqual(metadata.obsoletes, None) - self.assertEqual(metadata.requires, ['foo']) - -def test_suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(DistributionTestCase)) - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(MetadataTestCase)) - return suite - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_extension.py b/python/Lib/distutils/tests/test_extension.py deleted file mode 100644 index 3fb7cce..0000000 --- a/python/Lib/distutils/tests/test_extension.py +++ /dev/null @@ -1,70 +0,0 @@ -"""Tests for distutils.extension.""" -import unittest -import os -import warnings - -from test.support import run_unittest -from test.support.warnings_helper import check_warnings -from distutils.extension import read_setup_file, Extension - -class ExtensionTestCase(unittest.TestCase): - - def test_read_setup_file(self): - # trying to read a Setup file - # (sample extracted from the PyGame project) - setup = os.path.join(os.path.dirname(__file__), 'Setup.sample') - - exts = read_setup_file(setup) - names = [ext.name for ext in exts] - names.sort() - - # here are the extensions read_setup_file should have created - # out of the file - wanted = ['_arraysurfarray', '_camera', '_numericsndarray', - '_numericsurfarray', 'base', 'bufferproxy', 'cdrom', - 'color', 'constants', 'display', 'draw', 'event', - 'fastevent', 'font', 'gfxdraw', 'image', 'imageext', - 'joystick', 'key', 'mask', 'mixer', 'mixer_music', - 'mouse', 'movie', 'overlay', 'pixelarray', 'pypm', - 'rect', 'rwobject', 'scrap', 'surface', 'surflock', - 'time', 'transform'] - - self.assertEqual(names, wanted) - - def test_extension_init(self): - # the first argument, which is the name, must be a string - self.assertRaises(AssertionError, Extension, 1, []) - ext = Extension('name', []) - self.assertEqual(ext.name, 'name') - - # the second argument, which is the list of files, must - # be a list of strings - self.assertRaises(AssertionError, Extension, 'name', 'file') - self.assertRaises(AssertionError, Extension, 'name', ['file', 1]) - ext = Extension('name', ['file1', 'file2']) - self.assertEqual(ext.sources, ['file1', 'file2']) - - # others arguments have defaults - for attr in ('include_dirs', 'define_macros', 'undef_macros', - 'library_dirs', 'libraries', 'runtime_library_dirs', - 'extra_objects', 'extra_compile_args', 'extra_link_args', - 'export_symbols', 'swig_opts', 'depends'): - self.assertEqual(getattr(ext, attr), []) - - self.assertEqual(ext.language, None) - self.assertEqual(ext.optional, None) - - # if there are unknown keyword options, warn about them - with check_warnings() as w: - warnings.simplefilter('always') - ext = Extension('name', ['file1', 'file2'], chic=True) - - self.assertEqual(len(w.warnings), 1) - self.assertEqual(str(w.warnings[0].message), - "Unknown Extension options: 'chic'") - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(ExtensionTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_file_util.py b/python/Lib/distutils/tests/test_file_util.py deleted file mode 100644 index 04b708e..0000000 --- a/python/Lib/distutils/tests/test_file_util.py +++ /dev/null @@ -1,126 +0,0 @@ -"""Tests for distutils.file_util.""" -import unittest -import os -import errno -from unittest.mock import patch - -from distutils.file_util import move_file, copy_file -from distutils import log -from distutils.tests import support -from distutils.errors import DistutilsFileError -from test.support import run_unittest -from test.support.os_helper import unlink - - -class FileUtilTestCase(support.TempdirManager, unittest.TestCase): - - def _log(self, msg, *args): - if len(args) > 0: - self._logs.append(msg % args) - else: - self._logs.append(msg) - - def setUp(self): - super(FileUtilTestCase, self).setUp() - self._logs = [] - self.old_log = log.info - log.info = self._log - tmp_dir = self.mkdtemp() - self.source = os.path.join(tmp_dir, 'f1') - self.target = os.path.join(tmp_dir, 'f2') - self.target_dir = os.path.join(tmp_dir, 'd1') - - def tearDown(self): - log.info = self.old_log - super(FileUtilTestCase, self).tearDown() - - def test_move_file_verbosity(self): - f = open(self.source, 'w') - try: - f.write('some content') - finally: - f.close() - - move_file(self.source, self.target, verbose=0) - wanted = [] - self.assertEqual(self._logs, wanted) - - # back to original state - move_file(self.target, self.source, verbose=0) - - move_file(self.source, self.target, verbose=1) - wanted = ['moving %s -> %s' % (self.source, self.target)] - self.assertEqual(self._logs, wanted) - - # back to original state - move_file(self.target, self.source, verbose=0) - - self._logs = [] - # now the target is a dir - os.mkdir(self.target_dir) - move_file(self.source, self.target_dir, verbose=1) - wanted = ['moving %s -> %s' % (self.source, self.target_dir)] - self.assertEqual(self._logs, wanted) - - def test_move_file_exception_unpacking_rename(self): - # see issue 22182 - with patch("os.rename", side_effect=OSError("wrong", 1)), \ - self.assertRaises(DistutilsFileError): - with open(self.source, 'w') as fobj: - fobj.write('spam eggs') - move_file(self.source, self.target, verbose=0) - - def test_move_file_exception_unpacking_unlink(self): - # see issue 22182 - with patch("os.rename", side_effect=OSError(errno.EXDEV, "wrong")), \ - patch("os.unlink", side_effect=OSError("wrong", 1)), \ - self.assertRaises(DistutilsFileError): - with open(self.source, 'w') as fobj: - fobj.write('spam eggs') - move_file(self.source, self.target, verbose=0) - - @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') - def test_copy_file_hard_link(self): - with open(self.source, 'w') as f: - f.write('some content') - # Check first that copy_file() will not fall back on copying the file - # instead of creating the hard link. - try: - os.link(self.source, self.target) - except OSError as e: - self.skipTest('os.link: %s' % e) - else: - unlink(self.target) - st = os.stat(self.source) - copy_file(self.source, self.target, link='hard') - st2 = os.stat(self.source) - st3 = os.stat(self.target) - self.assertTrue(os.path.samestat(st, st2), (st, st2)) - self.assertTrue(os.path.samestat(st2, st3), (st2, st3)) - with open(self.source, 'r') as f: - self.assertEqual(f.read(), 'some content') - - @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') - def test_copy_file_hard_link_failure(self): - # If hard linking fails, copy_file() falls back on copying file - # (some special filesystems don't support hard linking even under - # Unix, see issue #8876). - with open(self.source, 'w') as f: - f.write('some content') - st = os.stat(self.source) - with patch("os.link", side_effect=OSError(0, "linking unsupported")): - copy_file(self.source, self.target, link='hard') - st2 = os.stat(self.source) - st3 = os.stat(self.target) - self.assertTrue(os.path.samestat(st, st2), (st, st2)) - self.assertFalse(os.path.samestat(st2, st3), (st2, st3)) - for fn in (self.source, self.target): - with open(fn, 'r') as f: - self.assertEqual(f.read(), 'some content') - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(FileUtilTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_filelist.py b/python/Lib/distutils/tests/test_filelist.py deleted file mode 100644 index 0241a04..0000000 --- a/python/Lib/distutils/tests/test_filelist.py +++ /dev/null @@ -1,340 +0,0 @@ -"""Tests for distutils.filelist.""" -import os -import re -import unittest -from distutils import debug -from distutils.log import WARN -from distutils.errors import DistutilsTemplateError -from distutils.filelist import glob_to_re, translate_pattern, FileList -from distutils import filelist - -from test.support import os_helper -from test.support import captured_stdout, run_unittest -from distutils.tests import support - -MANIFEST_IN = """\ -include ok -include xo -exclude xo -include foo.tmp -include buildout.cfg -global-include *.x -global-include *.txt -global-exclude *.tmp -recursive-include f *.oo -recursive-exclude global *.x -graft dir -prune dir3 -""" - - -def make_local_path(s): - """Converts '/' in a string to os.sep""" - return s.replace('/', os.sep) - - -class FileListTestCase(support.LoggingSilencer, - unittest.TestCase): - - def assertNoWarnings(self): - self.assertEqual(self.get_logs(WARN), []) - self.clear_logs() - - def assertWarnings(self): - self.assertGreater(len(self.get_logs(WARN)), 0) - self.clear_logs() - - def test_glob_to_re(self): - sep = os.sep - if os.sep == '\\': - sep = re.escape(os.sep) - - for glob, regex in ( - # simple cases - ('foo*', r'(?s:foo[^%(sep)s]*)\Z'), - ('foo?', r'(?s:foo[^%(sep)s])\Z'), - ('foo??', r'(?s:foo[^%(sep)s][^%(sep)s])\Z'), - # special cases - (r'foo\\*', r'(?s:foo\\\\[^%(sep)s]*)\Z'), - (r'foo\\\*', r'(?s:foo\\\\\\[^%(sep)s]*)\Z'), - ('foo????', r'(?s:foo[^%(sep)s][^%(sep)s][^%(sep)s][^%(sep)s])\Z'), - (r'foo\\??', r'(?s:foo\\\\[^%(sep)s][^%(sep)s])\Z')): - regex = regex % {'sep': sep} - self.assertEqual(glob_to_re(glob), regex) - - def test_process_template_line(self): - # testing all MANIFEST.in template patterns - file_list = FileList() - l = make_local_path - - # simulated file list - file_list.allfiles = ['foo.tmp', 'ok', 'xo', 'four.txt', - 'buildout.cfg', - # filelist does not filter out VCS directories, - # it's sdist that does - l('.hg/last-message.txt'), - l('global/one.txt'), - l('global/two.txt'), - l('global/files.x'), - l('global/here.tmp'), - l('f/o/f.oo'), - l('dir/graft-one'), - l('dir/dir2/graft2'), - l('dir3/ok'), - l('dir3/sub/ok.txt'), - ] - - for line in MANIFEST_IN.split('\n'): - if line.strip() == '': - continue - file_list.process_template_line(line) - - wanted = ['ok', - 'buildout.cfg', - 'four.txt', - l('.hg/last-message.txt'), - l('global/one.txt'), - l('global/two.txt'), - l('f/o/f.oo'), - l('dir/graft-one'), - l('dir/dir2/graft2'), - ] - - self.assertEqual(file_list.files, wanted) - - def test_debug_print(self): - file_list = FileList() - with captured_stdout() as stdout: - file_list.debug_print('xxx') - self.assertEqual(stdout.getvalue(), '') - - debug.DEBUG = True - try: - with captured_stdout() as stdout: - file_list.debug_print('xxx') - self.assertEqual(stdout.getvalue(), 'xxx\n') - finally: - debug.DEBUG = False - - def test_set_allfiles(self): - file_list = FileList() - files = ['a', 'b', 'c'] - file_list.set_allfiles(files) - self.assertEqual(file_list.allfiles, files) - - def test_remove_duplicates(self): - file_list = FileList() - file_list.files = ['a', 'b', 'a', 'g', 'c', 'g'] - # files must be sorted beforehand (sdist does it) - file_list.sort() - file_list.remove_duplicates() - self.assertEqual(file_list.files, ['a', 'b', 'c', 'g']) - - def test_translate_pattern(self): - # not regex - self.assertTrue(hasattr( - translate_pattern('a', anchor=True, is_regex=False), - 'search')) - - # is a regex - regex = re.compile('a') - self.assertEqual( - translate_pattern(regex, anchor=True, is_regex=True), - regex) - - # plain string flagged as regex - self.assertTrue(hasattr( - translate_pattern('a', anchor=True, is_regex=True), - 'search')) - - # glob support - self.assertTrue(translate_pattern( - '*.py', anchor=True, is_regex=False).search('filelist.py')) - - def test_exclude_pattern(self): - # return False if no match - file_list = FileList() - self.assertFalse(file_list.exclude_pattern('*.py')) - - # return True if files match - file_list = FileList() - file_list.files = ['a.py', 'b.py'] - self.assertTrue(file_list.exclude_pattern('*.py')) - - # test excludes - file_list = FileList() - file_list.files = ['a.py', 'a.txt'] - file_list.exclude_pattern('*.py') - self.assertEqual(file_list.files, ['a.txt']) - - def test_include_pattern(self): - # return False if no match - file_list = FileList() - file_list.set_allfiles([]) - self.assertFalse(file_list.include_pattern('*.py')) - - # return True if files match - file_list = FileList() - file_list.set_allfiles(['a.py', 'b.txt']) - self.assertTrue(file_list.include_pattern('*.py')) - - # test * matches all files - file_list = FileList() - self.assertIsNone(file_list.allfiles) - file_list.set_allfiles(['a.py', 'b.txt']) - file_list.include_pattern('*') - self.assertEqual(file_list.allfiles, ['a.py', 'b.txt']) - - def test_process_template(self): - l = make_local_path - # invalid lines - file_list = FileList() - for action in ('include', 'exclude', 'global-include', - 'global-exclude', 'recursive-include', - 'recursive-exclude', 'graft', 'prune', 'blarg'): - self.assertRaises(DistutilsTemplateError, - file_list.process_template_line, action) - - # include - file_list = FileList() - file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')]) - - file_list.process_template_line('include *.py') - self.assertEqual(file_list.files, ['a.py']) - self.assertNoWarnings() - - file_list.process_template_line('include *.rb') - self.assertEqual(file_list.files, ['a.py']) - self.assertWarnings() - - # exclude - file_list = FileList() - file_list.files = ['a.py', 'b.txt', l('d/c.py')] - - file_list.process_template_line('exclude *.py') - self.assertEqual(file_list.files, ['b.txt', l('d/c.py')]) - self.assertNoWarnings() - - file_list.process_template_line('exclude *.rb') - self.assertEqual(file_list.files, ['b.txt', l('d/c.py')]) - self.assertWarnings() - - # global-include - file_list = FileList() - file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')]) - - file_list.process_template_line('global-include *.py') - self.assertEqual(file_list.files, ['a.py', l('d/c.py')]) - self.assertNoWarnings() - - file_list.process_template_line('global-include *.rb') - self.assertEqual(file_list.files, ['a.py', l('d/c.py')]) - self.assertWarnings() - - # global-exclude - file_list = FileList() - file_list.files = ['a.py', 'b.txt', l('d/c.py')] - - file_list.process_template_line('global-exclude *.py') - self.assertEqual(file_list.files, ['b.txt']) - self.assertNoWarnings() - - file_list.process_template_line('global-exclude *.rb') - self.assertEqual(file_list.files, ['b.txt']) - self.assertWarnings() - - # recursive-include - file_list = FileList() - file_list.set_allfiles(['a.py', l('d/b.py'), l('d/c.txt'), - l('d/d/e.py')]) - - file_list.process_template_line('recursive-include d *.py') - self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) - self.assertNoWarnings() - - file_list.process_template_line('recursive-include e *.py') - self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) - self.assertWarnings() - - # recursive-exclude - file_list = FileList() - file_list.files = ['a.py', l('d/b.py'), l('d/c.txt'), l('d/d/e.py')] - - file_list.process_template_line('recursive-exclude d *.py') - self.assertEqual(file_list.files, ['a.py', l('d/c.txt')]) - self.assertNoWarnings() - - file_list.process_template_line('recursive-exclude e *.py') - self.assertEqual(file_list.files, ['a.py', l('d/c.txt')]) - self.assertWarnings() - - # graft - file_list = FileList() - file_list.set_allfiles(['a.py', l('d/b.py'), l('d/d/e.py'), - l('f/f.py')]) - - file_list.process_template_line('graft d') - self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) - self.assertNoWarnings() - - file_list.process_template_line('graft e') - self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) - self.assertWarnings() - - # prune - file_list = FileList() - file_list.files = ['a.py', l('d/b.py'), l('d/d/e.py'), l('f/f.py')] - - file_list.process_template_line('prune d') - self.assertEqual(file_list.files, ['a.py', l('f/f.py')]) - self.assertNoWarnings() - - file_list.process_template_line('prune e') - self.assertEqual(file_list.files, ['a.py', l('f/f.py')]) - self.assertWarnings() - - -class FindAllTestCase(unittest.TestCase): - @os_helper.skip_unless_symlink - def test_missing_symlink(self): - with os_helper.temp_cwd(): - os.symlink('foo', 'bar') - self.assertEqual(filelist.findall(), []) - - def test_basic_discovery(self): - """ - When findall is called with no parameters or with - '.' as the parameter, the dot should be omitted from - the results. - """ - with os_helper.temp_cwd(): - os.mkdir('foo') - file1 = os.path.join('foo', 'file1.txt') - os_helper.create_empty_file(file1) - os.mkdir('bar') - file2 = os.path.join('bar', 'file2.txt') - os_helper.create_empty_file(file2) - expected = [file2, file1] - self.assertEqual(sorted(filelist.findall()), expected) - - def test_non_local_discovery(self): - """ - When findall is called with another path, the full - path name should be returned. - """ - with os_helper.temp_dir() as temp_dir: - file1 = os.path.join(temp_dir, 'file1.txt') - os_helper.create_empty_file(file1) - expected = [file1] - self.assertEqual(filelist.findall(temp_dir), expected) - - -def test_suite(): - return unittest.TestSuite([ - unittest.TestLoader().loadTestsFromTestCase(FileListTestCase), - unittest.TestLoader().loadTestsFromTestCase(FindAllTestCase), - ]) - - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_install.py b/python/Lib/distutils/tests/test_install.py deleted file mode 100644 index b68849a..0000000 --- a/python/Lib/distutils/tests/test_install.py +++ /dev/null @@ -1,261 +0,0 @@ -"""Tests for distutils.command.install.""" - -import os -import sys -import unittest -import site - -from test.support import captured_stdout, run_unittest, requires_subprocess - -from distutils import sysconfig -from distutils.command.install import install, HAS_USER_SITE -from distutils.command import install as install_module -from distutils.command.build_ext import build_ext -from distutils.command.install import INSTALL_SCHEMES -from distutils.core import Distribution -from distutils.errors import DistutilsOptionError -from distutils.extension import Extension - -from distutils.tests import support -from test import support as test_support - - -def _make_ext_name(modname): - return modname + sysconfig.get_config_var('EXT_SUFFIX') - - -class InstallTestCase(support.TempdirManager, - support.EnvironGuard, - support.LoggingSilencer, - unittest.TestCase): - - def setUp(self): - super().setUp() - self._backup_config_vars = dict(sysconfig._config_vars) - - def tearDown(self): - super().tearDown() - sysconfig._config_vars.clear() - sysconfig._config_vars.update(self._backup_config_vars) - - def test_home_installation_scheme(self): - # This ensure two things: - # - that --home generates the desired set of directory names - # - test --home is supported on all platforms - builddir = self.mkdtemp() - destination = os.path.join(builddir, "installation") - - dist = Distribution({"name": "foopkg"}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(builddir, "setup.py") - dist.command_obj["build"] = support.DummyCommand( - build_base=builddir, - build_lib=os.path.join(builddir, "lib"), - ) - - cmd = install(dist) - cmd.home = destination - cmd.ensure_finalized() - - self.assertEqual(cmd.install_base, destination) - self.assertEqual(cmd.install_platbase, destination) - - def check_path(got, expected): - got = os.path.normpath(got) - expected = os.path.normpath(expected) - self.assertEqual(got, expected) - - libdir = os.path.join(destination, "lib", "python") - check_path(cmd.install_lib, libdir) - platlibdir = os.path.join(destination, sys.platlibdir, "python") - check_path(cmd.install_platlib, platlibdir) - check_path(cmd.install_purelib, libdir) - check_path(cmd.install_headers, - os.path.join(destination, "include", "python", "foopkg")) - check_path(cmd.install_scripts, os.path.join(destination, "bin")) - check_path(cmd.install_data, destination) - - @unittest.skipUnless(HAS_USER_SITE, 'need user site') - def test_user_site(self): - # test install with --user - # preparing the environment for the test - self.old_user_base = site.USER_BASE - self.old_user_site = site.USER_SITE - self.tmpdir = self.mkdtemp() - self.user_base = os.path.join(self.tmpdir, 'B') - self.user_site = os.path.join(self.tmpdir, 'S') - site.USER_BASE = self.user_base - site.USER_SITE = self.user_site - install_module.USER_BASE = self.user_base - install_module.USER_SITE = self.user_site - - def _expanduser(path): - return self.tmpdir - self.old_expand = os.path.expanduser - os.path.expanduser = _expanduser - - def cleanup(): - site.USER_BASE = self.old_user_base - site.USER_SITE = self.old_user_site - install_module.USER_BASE = self.old_user_base - install_module.USER_SITE = self.old_user_site - os.path.expanduser = self.old_expand - - self.addCleanup(cleanup) - - if HAS_USER_SITE: - for key in ('nt_user', 'unix_user'): - self.assertIn(key, INSTALL_SCHEMES) - - dist = Distribution({'name': 'xx'}) - cmd = install(dist) - - # making sure the user option is there - options = [name for name, short, lable in - cmd.user_options] - self.assertIn('user', options) - - # setting a value - cmd.user = 1 - - # user base and site shouldn't be created yet - self.assertFalse(os.path.exists(self.user_base)) - self.assertFalse(os.path.exists(self.user_site)) - - # let's run finalize - cmd.ensure_finalized() - - # now they should - self.assertTrue(os.path.exists(self.user_base)) - self.assertTrue(os.path.exists(self.user_site)) - - self.assertIn('userbase', cmd.config_vars) - self.assertIn('usersite', cmd.config_vars) - - def test_handle_extra_path(self): - dist = Distribution({'name': 'xx', 'extra_path': 'path,dirs'}) - cmd = install(dist) - - # two elements - cmd.handle_extra_path() - self.assertEqual(cmd.extra_path, ['path', 'dirs']) - self.assertEqual(cmd.extra_dirs, 'dirs') - self.assertEqual(cmd.path_file, 'path') - - # one element - cmd.extra_path = ['path'] - cmd.handle_extra_path() - self.assertEqual(cmd.extra_path, ['path']) - self.assertEqual(cmd.extra_dirs, 'path') - self.assertEqual(cmd.path_file, 'path') - - # none - dist.extra_path = cmd.extra_path = None - cmd.handle_extra_path() - self.assertEqual(cmd.extra_path, None) - self.assertEqual(cmd.extra_dirs, '') - self.assertEqual(cmd.path_file, None) - - # three elements (no way !) - cmd.extra_path = 'path,dirs,again' - self.assertRaises(DistutilsOptionError, cmd.handle_extra_path) - - def test_finalize_options(self): - dist = Distribution({'name': 'xx'}) - cmd = install(dist) - - # must supply either prefix/exec-prefix/home or - # install-base/install-platbase -- not both - cmd.prefix = 'prefix' - cmd.install_base = 'base' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - - # must supply either home or prefix/exec-prefix -- not both - cmd.install_base = None - cmd.home = 'home' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - - # can't combine user with prefix/exec_prefix/home or - # install_(plat)base - cmd.prefix = None - cmd.user = 'user' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - - def test_record(self): - install_dir = self.mkdtemp() - project_dir, dist = self.create_dist(py_modules=['hello'], - scripts=['sayhi']) - os.chdir(project_dir) - self.write_file('hello.py', "def main(): print('o hai')") - self.write_file('sayhi', 'from hello import main; main()') - - cmd = install(dist) - dist.command_obj['install'] = cmd - cmd.root = install_dir - cmd.record = os.path.join(project_dir, 'filelist') - cmd.ensure_finalized() - cmd.run() - - f = open(cmd.record) - try: - content = f.read() - finally: - f.close() - - found = [os.path.basename(line) for line in content.splitlines()] - expected = ['hello.py', 'hello.%s.pyc' % sys.implementation.cache_tag, - 'sayhi', - 'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]] - self.assertEqual(found, expected) - - @requires_subprocess() - def test_record_extensions(self): - cmd = test_support.missing_compiler_executable() - if cmd is not None: - self.skipTest('The %r command is not found' % cmd) - install_dir = self.mkdtemp() - project_dir, dist = self.create_dist(ext_modules=[ - Extension('xx', ['xxmodule.c'])]) - os.chdir(project_dir) - support.copy_xxmodule_c(project_dir) - - buildextcmd = build_ext(dist) - support.fixup_build_ext(buildextcmd) - buildextcmd.ensure_finalized() - - cmd = install(dist) - dist.command_obj['install'] = cmd - dist.command_obj['build_ext'] = buildextcmd - cmd.root = install_dir - cmd.record = os.path.join(project_dir, 'filelist') - cmd.ensure_finalized() - cmd.run() - - f = open(cmd.record) - try: - content = f.read() - finally: - f.close() - - found = [os.path.basename(line) for line in content.splitlines()] - expected = [_make_ext_name('xx'), - 'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]] - self.assertEqual(found, expected) - - def test_debug_mode(self): - # this covers the code called when DEBUG is set - old_logs_len = len(self.logs) - install_module.DEBUG = True - try: - with captured_stdout(): - self.test_record() - finally: - install_module.DEBUG = False - self.assertGreater(len(self.logs), old_logs_len) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(InstallTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_install_data.py b/python/Lib/distutils/tests/test_install_data.py deleted file mode 100644 index 9cdc53f..0000000 --- a/python/Lib/distutils/tests/test_install_data.py +++ /dev/null @@ -1,75 +0,0 @@ -"""Tests for distutils.command.install_data.""" -import os -import unittest - -from distutils.command.install_data import install_data -from distutils.tests import support -from test.support import run_unittest - -class InstallDataTestCase(support.TempdirManager, - support.LoggingSilencer, - support.EnvironGuard, - unittest.TestCase): - - def test_simple_run(self): - pkg_dir, dist = self.create_dist() - cmd = install_data(dist) - cmd.install_dir = inst = os.path.join(pkg_dir, 'inst') - - # data_files can contain - # - simple files - # - a tuple with a path, and a list of file - one = os.path.join(pkg_dir, 'one') - self.write_file(one, 'xxx') - inst2 = os.path.join(pkg_dir, 'inst2') - two = os.path.join(pkg_dir, 'two') - self.write_file(two, 'xxx') - - cmd.data_files = [one, (inst2, [two])] - self.assertEqual(cmd.get_inputs(), [one, (inst2, [two])]) - - # let's run the command - cmd.ensure_finalized() - cmd.run() - - # let's check the result - self.assertEqual(len(cmd.get_outputs()), 2) - rtwo = os.path.split(two)[-1] - self.assertTrue(os.path.exists(os.path.join(inst2, rtwo))) - rone = os.path.split(one)[-1] - self.assertTrue(os.path.exists(os.path.join(inst, rone))) - cmd.outfiles = [] - - # let's try with warn_dir one - cmd.warn_dir = 1 - cmd.ensure_finalized() - cmd.run() - - # let's check the result - self.assertEqual(len(cmd.get_outputs()), 2) - self.assertTrue(os.path.exists(os.path.join(inst2, rtwo))) - self.assertTrue(os.path.exists(os.path.join(inst, rone))) - cmd.outfiles = [] - - # now using root and empty dir - cmd.root = os.path.join(pkg_dir, 'root') - inst3 = os.path.join(cmd.install_dir, 'inst3') - inst4 = os.path.join(pkg_dir, 'inst4') - three = os.path.join(cmd.install_dir, 'three') - self.write_file(three, 'xx') - cmd.data_files = [one, (inst2, [two]), - ('inst3', [three]), - (inst4, [])] - cmd.ensure_finalized() - cmd.run() - - # let's check the result - self.assertEqual(len(cmd.get_outputs()), 4) - self.assertTrue(os.path.exists(os.path.join(inst2, rtwo))) - self.assertTrue(os.path.exists(os.path.join(inst, rone))) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(InstallDataTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_install_headers.py b/python/Lib/distutils/tests/test_install_headers.py deleted file mode 100644 index 12fdb3c..0000000 --- a/python/Lib/distutils/tests/test_install_headers.py +++ /dev/null @@ -1,39 +0,0 @@ -"""Tests for distutils.command.install_headers.""" -import os -import unittest - -from distutils.command.install_headers import install_headers -from distutils.tests import support -from test.support import run_unittest - -class InstallHeadersTestCase(support.TempdirManager, - support.LoggingSilencer, - support.EnvironGuard, - unittest.TestCase): - - def test_simple_run(self): - # we have two headers - header_list = self.mkdtemp() - header1 = os.path.join(header_list, 'header1') - header2 = os.path.join(header_list, 'header2') - self.write_file(header1) - self.write_file(header2) - headers = [header1, header2] - - pkg_dir, dist = self.create_dist(headers=headers) - cmd = install_headers(dist) - self.assertEqual(cmd.get_inputs(), headers) - - # let's run the command - cmd.install_dir = os.path.join(pkg_dir, 'inst') - cmd.ensure_finalized() - cmd.run() - - # let's check the results - self.assertEqual(len(cmd.get_outputs()), 2) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(InstallHeadersTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_install_lib.py b/python/Lib/distutils/tests/test_install_lib.py deleted file mode 100644 index 74b2370..0000000 --- a/python/Lib/distutils/tests/test_install_lib.py +++ /dev/null @@ -1,117 +0,0 @@ -"""Tests for distutils.command.install_data.""" -import sys -import os -import importlib.util -import unittest - -from distutils.command.install_lib import install_lib -from distutils.extension import Extension -from distutils.tests import support -from distutils.errors import DistutilsOptionError -from test.support import run_unittest, requires_subprocess - - -class InstallLibTestCase(support.TempdirManager, - support.LoggingSilencer, - support.EnvironGuard, - unittest.TestCase): - - def test_finalize_options(self): - dist = self.create_dist()[1] - cmd = install_lib(dist) - - cmd.finalize_options() - self.assertEqual(cmd.compile, 1) - self.assertEqual(cmd.optimize, 0) - - # optimize must be 0, 1, or 2 - cmd.optimize = 'foo' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - cmd.optimize = '4' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - - cmd.optimize = '2' - cmd.finalize_options() - self.assertEqual(cmd.optimize, 2) - - @unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled') - @requires_subprocess() - def test_byte_compile(self): - project_dir, dist = self.create_dist() - os.chdir(project_dir) - cmd = install_lib(dist) - cmd.compile = cmd.optimize = 1 - - f = os.path.join(project_dir, 'foo.py') - self.write_file(f, '# python file') - cmd.byte_compile([f]) - pyc_file = importlib.util.cache_from_source('foo.py', optimization='') - pyc_opt_file = importlib.util.cache_from_source('foo.py', - optimization=cmd.optimize) - self.assertTrue(os.path.exists(pyc_file)) - self.assertTrue(os.path.exists(pyc_opt_file)) - - def test_get_outputs(self): - project_dir, dist = self.create_dist() - os.chdir(project_dir) - os.mkdir('spam') - cmd = install_lib(dist) - - # setting up a dist environment - cmd.compile = cmd.optimize = 1 - cmd.install_dir = self.mkdtemp() - f = os.path.join(project_dir, 'spam', '__init__.py') - self.write_file(f, '# python package') - cmd.distribution.ext_modules = [Extension('foo', ['xxx'])] - cmd.distribution.packages = ['spam'] - cmd.distribution.script_name = 'setup.py' - - # get_outputs should return 4 elements: spam/__init__.py and .pyc, - # foo.import-tag-abiflags.so / foo.pyd - outputs = cmd.get_outputs() - self.assertEqual(len(outputs), 4, outputs) - - def test_get_inputs(self): - project_dir, dist = self.create_dist() - os.chdir(project_dir) - os.mkdir('spam') - cmd = install_lib(dist) - - # setting up a dist environment - cmd.compile = cmd.optimize = 1 - cmd.install_dir = self.mkdtemp() - f = os.path.join(project_dir, 'spam', '__init__.py') - self.write_file(f, '# python package') - cmd.distribution.ext_modules = [Extension('foo', ['xxx'])] - cmd.distribution.packages = ['spam'] - cmd.distribution.script_name = 'setup.py' - - # get_inputs should return 2 elements: spam/__init__.py and - # foo.import-tag-abiflags.so / foo.pyd - inputs = cmd.get_inputs() - self.assertEqual(len(inputs), 2, inputs) - - @requires_subprocess() - def test_dont_write_bytecode(self): - # makes sure byte_compile is not used - dist = self.create_dist()[1] - cmd = install_lib(dist) - cmd.compile = 1 - cmd.optimize = 1 - - old_dont_write_bytecode = sys.dont_write_bytecode - sys.dont_write_bytecode = True - try: - cmd.byte_compile([]) - finally: - sys.dont_write_bytecode = old_dont_write_bytecode - - self.assertIn('byte-compiling is disabled', - self.logs[0][1] % self.logs[0][2]) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(InstallLibTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_install_scripts.py b/python/Lib/distutils/tests/test_install_scripts.py deleted file mode 100644 index 8651114..0000000 --- a/python/Lib/distutils/tests/test_install_scripts.py +++ /dev/null @@ -1,82 +0,0 @@ -"""Tests for distutils.command.install_scripts.""" - -import os -import unittest - -from distutils.command.install_scripts import install_scripts -from distutils.core import Distribution - -from distutils.tests import support -from test.support import run_unittest - - -class InstallScriptsTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - def test_default_settings(self): - dist = Distribution() - dist.command_obj["build"] = support.DummyCommand( - build_scripts="/foo/bar") - dist.command_obj["install"] = support.DummyCommand( - install_scripts="/splat/funk", - force=1, - skip_build=1, - ) - cmd = install_scripts(dist) - self.assertFalse(cmd.force) - self.assertFalse(cmd.skip_build) - self.assertIsNone(cmd.build_dir) - self.assertIsNone(cmd.install_dir) - - cmd.finalize_options() - - self.assertTrue(cmd.force) - self.assertTrue(cmd.skip_build) - self.assertEqual(cmd.build_dir, "/foo/bar") - self.assertEqual(cmd.install_dir, "/splat/funk") - - def test_installation(self): - source = self.mkdtemp() - expected = [] - - def write_script(name, text): - expected.append(name) - f = open(os.path.join(source, name), "w") - try: - f.write(text) - finally: - f.close() - - write_script("script1.py", ("#! /usr/bin/env python2.3\n" - "# bogus script w/ Python sh-bang\n" - "pass\n")) - write_script("script2.py", ("#!/usr/bin/python\n" - "# bogus script w/ Python sh-bang\n" - "pass\n")) - write_script("shell.sh", ("#!/bin/sh\n" - "# bogus shell script w/ sh-bang\n" - "exit 0\n")) - - target = self.mkdtemp() - dist = Distribution() - dist.command_obj["build"] = support.DummyCommand(build_scripts=source) - dist.command_obj["install"] = support.DummyCommand( - install_scripts=target, - force=1, - skip_build=1, - ) - cmd = install_scripts(dist) - cmd.finalize_options() - cmd.run() - - installed = os.listdir(target) - for name in expected: - self.assertIn(name, installed) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(InstallScriptsTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_log.py b/python/Lib/distutils/tests/test_log.py deleted file mode 100644 index 91cdd8a..0000000 --- a/python/Lib/distutils/tests/test_log.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Tests for distutils.log""" - -import io -import sys -import unittest -from test.support import swap_attr, run_unittest - -from distutils import log - -class TestLog(unittest.TestCase): - def test_non_ascii(self): - # Issues #8663, #34421: test that non-encodable text is escaped with - # backslashreplace error handler and encodable non-ASCII text is - # output as is. - for errors in ('strict', 'backslashreplace', 'surrogateescape', - 'replace', 'ignore'): - with self.subTest(errors=errors): - stdout = io.TextIOWrapper(io.BytesIO(), - encoding='cp437', errors=errors) - stderr = io.TextIOWrapper(io.BytesIO(), - encoding='cp437', errors=errors) - old_threshold = log.set_threshold(log.DEBUG) - try: - with swap_attr(sys, 'stdout', stdout), \ - swap_attr(sys, 'stderr', stderr): - log.debug('Dεbug\tMėssãge') - log.fatal('Fαtal\tÈrrōr') - finally: - log.set_threshold(old_threshold) - - stdout.seek(0) - self.assertEqual(stdout.read().rstrip(), - 'Dεbug\tM?ss?ge' if errors == 'replace' else - 'Dεbug\tMssge' if errors == 'ignore' else - 'Dεbug\tM\\u0117ss\\xe3ge') - stderr.seek(0) - self.assertEqual(stderr.read().rstrip(), - 'Fαtal\t?rr?r' if errors == 'replace' else - 'Fαtal\trrr' if errors == 'ignore' else - 'Fαtal\t\\xc8rr\\u014dr') - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(TestLog) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_msvc9compiler.py b/python/Lib/distutils/tests/test_msvc9compiler.py deleted file mode 100644 index 48c000a..0000000 --- a/python/Lib/distutils/tests/test_msvc9compiler.py +++ /dev/null @@ -1,184 +0,0 @@ -"""Tests for distutils.msvc9compiler.""" -import sys -import unittest -import os - -from distutils.errors import DistutilsPlatformError -from distutils.tests import support -from test.support import run_unittest - -# A manifest with the only assembly reference being the msvcrt assembly, so -# should have the assembly completely stripped. Note that although the -# assembly has a reference the assembly is removed - that is -# currently a "feature", not a bug :) -_MANIFEST_WITH_ONLY_MSVC_REFERENCE = """\ - - - - - - - - - - - - - - - - - -""" - -# A manifest with references to assemblies other than msvcrt. When processed, -# this assembly should be returned with just the msvcrt part removed. -_MANIFEST_WITH_MULTIPLE_REFERENCES = """\ - - - - - - - - - - - - - - - - - - - - - - -""" - -_CLEANED_MANIFEST = """\ - - - - - - - - - - - - - - - - - - -""" - -if sys.platform=="win32": - from distutils.msvccompiler import get_build_version - if get_build_version()>=8.0: - SKIP_MESSAGE = None - else: - SKIP_MESSAGE = "These tests are only for MSVC8.0 or above" -else: - SKIP_MESSAGE = "These tests are only for win32" - -@unittest.skipUnless(SKIP_MESSAGE is None, SKIP_MESSAGE) -class msvc9compilerTestCase(support.TempdirManager, - unittest.TestCase): - - def test_no_compiler(self): - # makes sure query_vcvarsall raises - # a DistutilsPlatformError if the compiler - # is not found - from distutils.msvc9compiler import query_vcvarsall - def _find_vcvarsall(version): - return None - - from distutils import msvc9compiler - old_find_vcvarsall = msvc9compiler.find_vcvarsall - msvc9compiler.find_vcvarsall = _find_vcvarsall - try: - self.assertRaises(DistutilsPlatformError, query_vcvarsall, - 'wont find this version') - finally: - msvc9compiler.find_vcvarsall = old_find_vcvarsall - - def test_reg_class(self): - from distutils.msvc9compiler import Reg - self.assertRaises(KeyError, Reg.get_value, 'xxx', 'xxx') - - # looking for values that should exist on all - # windows registry versions. - path = r'Control Panel\Desktop' - v = Reg.get_value(path, 'dragfullwindows') - self.assertIn(v, ('0', '1', '2')) - - import winreg - HKCU = winreg.HKEY_CURRENT_USER - keys = Reg.read_keys(HKCU, 'xxxx') - self.assertEqual(keys, None) - - keys = Reg.read_keys(HKCU, r'Control Panel') - self.assertIn('Desktop', keys) - - def test_remove_visual_c_ref(self): - from distutils.msvc9compiler import MSVCCompiler - tempdir = self.mkdtemp() - manifest = os.path.join(tempdir, 'manifest') - f = open(manifest, 'w') - try: - f.write(_MANIFEST_WITH_MULTIPLE_REFERENCES) - finally: - f.close() - - compiler = MSVCCompiler() - compiler._remove_visual_c_ref(manifest) - - # see what we got - f = open(manifest) - try: - # removing trailing spaces - content = '\n'.join([line.rstrip() for line in f.readlines()]) - finally: - f.close() - - # makes sure the manifest was properly cleaned - self.assertEqual(content, _CLEANED_MANIFEST) - - def test_remove_entire_manifest(self): - from distutils.msvc9compiler import MSVCCompiler - tempdir = self.mkdtemp() - manifest = os.path.join(tempdir, 'manifest') - f = open(manifest, 'w') - try: - f.write(_MANIFEST_WITH_ONLY_MSVC_REFERENCE) - finally: - f.close() - - compiler = MSVCCompiler() - got = compiler._remove_visual_c_ref(manifest) - self.assertIsNone(got) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(msvc9compilerTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_msvccompiler.py b/python/Lib/distutils/tests/test_msvccompiler.py deleted file mode 100644 index 7d9d2c1..0000000 --- a/python/Lib/distutils/tests/test_msvccompiler.py +++ /dev/null @@ -1,81 +0,0 @@ -"""Tests for distutils._msvccompiler.""" -import sys -import unittest -import os - -from distutils.errors import DistutilsPlatformError -from distutils.tests import support -from test.support import run_unittest - - -SKIP_MESSAGE = (None if sys.platform == "win32" else - "These tests are only for win32") - -@unittest.skipUnless(SKIP_MESSAGE is None, SKIP_MESSAGE) -class msvccompilerTestCase(support.TempdirManager, - unittest.TestCase): - - def test_no_compiler(self): - import distutils._msvccompiler as _msvccompiler - # makes sure query_vcvarsall raises - # a DistutilsPlatformError if the compiler - # is not found - def _find_vcvarsall(plat_spec): - return None, None - - old_find_vcvarsall = _msvccompiler._find_vcvarsall - _msvccompiler._find_vcvarsall = _find_vcvarsall - try: - self.assertRaises(DistutilsPlatformError, - _msvccompiler._get_vc_env, - 'wont find this version') - finally: - _msvccompiler._find_vcvarsall = old_find_vcvarsall - - def test_get_vc_env_unicode(self): - import distutils._msvccompiler as _msvccompiler - - test_var = 'ṰḖṤṪ┅ṼẨṜ' - test_value = '₃⁴₅' - - # Ensure we don't early exit from _get_vc_env - old_distutils_use_sdk = os.environ.pop('DISTUTILS_USE_SDK', None) - os.environ[test_var] = test_value - try: - env = _msvccompiler._get_vc_env('x86') - self.assertIn(test_var.lower(), env) - self.assertEqual(test_value, env[test_var.lower()]) - finally: - os.environ.pop(test_var) - if old_distutils_use_sdk: - os.environ['DISTUTILS_USE_SDK'] = old_distutils_use_sdk - - def test_get_vc2017(self): - import distutils._msvccompiler as _msvccompiler - - # This function cannot be mocked, so pass it if we find VS 2017 - # and mark it skipped if we do not. - version, path = _msvccompiler._find_vc2017() - if version: - self.assertGreaterEqual(version, 15) - self.assertTrue(os.path.isdir(path)) - else: - raise unittest.SkipTest("VS 2017 is not installed") - - def test_get_vc2015(self): - import distutils._msvccompiler as _msvccompiler - - # This function cannot be mocked, so pass it if we find VS 2015 - # and mark it skipped if we do not. - version, path = _msvccompiler._find_vc2015() - if version: - self.assertGreaterEqual(version, 14) - self.assertTrue(os.path.isdir(path)) - else: - raise unittest.SkipTest("VS 2015 is not installed") - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(msvccompilerTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_register.py b/python/Lib/distutils/tests/test_register.py deleted file mode 100644 index 10ba231..0000000 --- a/python/Lib/distutils/tests/test_register.py +++ /dev/null @@ -1,324 +0,0 @@ -"""Tests for distutils.command.register.""" -import os -import unittest -import getpass -import urllib -import warnings - -from test.support import run_unittest -from test.support.warnings_helper import check_warnings - -from distutils.command import register as register_module -from distutils.command.register import register -from distutils.errors import DistutilsSetupError -from distutils.log import INFO - -from distutils.tests.test_config import BasePyPIRCCommandTestCase - -try: - import docutils -except ImportError: - docutils = None - -PYPIRC_NOPASSWORD = """\ -[distutils] - -index-servers = - server1 - -[server1] -username:me -""" - -WANTED_PYPIRC = """\ -[distutils] -index-servers = - pypi - -[pypi] -username:tarek -password:password -""" - -class Inputs(object): - """Fakes user inputs.""" - def __init__(self, *answers): - self.answers = answers - self.index = 0 - - def __call__(self, prompt=''): - try: - return self.answers[self.index] - finally: - self.index += 1 - -class FakeOpener(object): - """Fakes a PyPI server""" - def __init__(self): - self.reqs = [] - - def __call__(self, *args): - return self - - def open(self, req, data=None, timeout=None): - self.reqs.append(req) - return self - - def read(self): - return b'xxx' - - def getheader(self, name, default=None): - return { - 'content-type': 'text/plain; charset=utf-8', - }.get(name.lower(), default) - - -class RegisterTestCase(BasePyPIRCCommandTestCase): - - def setUp(self): - super(RegisterTestCase, self).setUp() - # patching the password prompt - self._old_getpass = getpass.getpass - def _getpass(prompt): - return 'password' - getpass.getpass = _getpass - urllib.request._opener = None - self.old_opener = urllib.request.build_opener - self.conn = urllib.request.build_opener = FakeOpener() - - def tearDown(self): - getpass.getpass = self._old_getpass - urllib.request._opener = None - urllib.request.build_opener = self.old_opener - super(RegisterTestCase, self).tearDown() - - def _get_cmd(self, metadata=None): - if metadata is None: - metadata = {'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx', - 'name': 'xxx', 'version': 'xxx'} - pkg_info, dist = self.create_dist(**metadata) - return register(dist) - - def test_create_pypirc(self): - # this test makes sure a .pypirc file - # is created when requested. - - # let's create a register instance - cmd = self._get_cmd() - - # we shouldn't have a .pypirc file yet - self.assertFalse(os.path.exists(self.rc)) - - # patching input and getpass.getpass - # so register gets happy - # - # Here's what we are faking : - # use your existing login (choice 1.) - # Username : 'tarek' - # Password : 'password' - # Save your login (y/N)? : 'y' - inputs = Inputs('1', 'tarek', 'y') - register_module.input = inputs.__call__ - # let's run the command - try: - cmd.run() - finally: - del register_module.input - - # we should have a brand new .pypirc file - self.assertTrue(os.path.exists(self.rc)) - - # with the content similar to WANTED_PYPIRC - f = open(self.rc) - try: - content = f.read() - self.assertEqual(content, WANTED_PYPIRC) - finally: - f.close() - - # now let's make sure the .pypirc file generated - # really works : we shouldn't be asked anything - # if we run the command again - def _no_way(prompt=''): - raise AssertionError(prompt) - register_module.input = _no_way - - cmd.show_response = 1 - cmd.run() - - # let's see what the server received : we should - # have 2 similar requests - self.assertEqual(len(self.conn.reqs), 2) - req1 = dict(self.conn.reqs[0].headers) - req2 = dict(self.conn.reqs[1].headers) - - self.assertEqual(req1['Content-length'], '1374') - self.assertEqual(req2['Content-length'], '1374') - self.assertIn(b'xxx', self.conn.reqs[1].data) - - def test_password_not_in_file(self): - - self.write_file(self.rc, PYPIRC_NOPASSWORD) - cmd = self._get_cmd() - cmd._set_config() - cmd.finalize_options() - cmd.send_metadata() - - # dist.password should be set - # therefore used afterwards by other commands - self.assertEqual(cmd.distribution.password, 'password') - - def test_registering(self): - # this test runs choice 2 - cmd = self._get_cmd() - inputs = Inputs('2', 'tarek', 'tarek@ziade.org') - register_module.input = inputs.__call__ - try: - # let's run the command - cmd.run() - finally: - del register_module.input - - # we should have send a request - self.assertEqual(len(self.conn.reqs), 1) - req = self.conn.reqs[0] - headers = dict(req.headers) - self.assertEqual(headers['Content-length'], '608') - self.assertIn(b'tarek', req.data) - - def test_password_reset(self): - # this test runs choice 3 - cmd = self._get_cmd() - inputs = Inputs('3', 'tarek@ziade.org') - register_module.input = inputs.__call__ - try: - # let's run the command - cmd.run() - finally: - del register_module.input - - # we should have send a request - self.assertEqual(len(self.conn.reqs), 1) - req = self.conn.reqs[0] - headers = dict(req.headers) - self.assertEqual(headers['Content-length'], '290') - self.assertIn(b'tarek', req.data) - - @unittest.skipUnless(docutils is not None, 'needs docutils') - def test_strict(self): - # testing the script option - # when on, the register command stops if - # the metadata is incomplete or if - # long_description is not reSt compliant - - # empty metadata - cmd = self._get_cmd({}) - cmd.ensure_finalized() - cmd.strict = 1 - self.assertRaises(DistutilsSetupError, cmd.run) - - # metadata are OK but long_description is broken - metadata = {'url': 'xxx', 'author': 'xxx', - 'author_email': 'éxéxé', - 'name': 'xxx', 'version': 'xxx', - 'long_description': 'title\n==\n\ntext'} - - cmd = self._get_cmd(metadata) - cmd.ensure_finalized() - cmd.strict = 1 - self.assertRaises(DistutilsSetupError, cmd.run) - - # now something that works - metadata['long_description'] = 'title\n=====\n\ntext' - cmd = self._get_cmd(metadata) - cmd.ensure_finalized() - cmd.strict = 1 - inputs = Inputs('1', 'tarek', 'y') - register_module.input = inputs.__call__ - # let's run the command - try: - cmd.run() - finally: - del register_module.input - - # strict is not by default - cmd = self._get_cmd() - cmd.ensure_finalized() - inputs = Inputs('1', 'tarek', 'y') - register_module.input = inputs.__call__ - # let's run the command - try: - cmd.run() - finally: - del register_module.input - - # and finally a Unicode test (bug #12114) - metadata = {'url': 'xxx', 'author': '\u00c9ric', - 'author_email': 'xxx', 'name': 'xxx', - 'version': 'xxx', - 'description': 'Something about esszet \u00df', - 'long_description': 'More things about esszet \u00df'} - - cmd = self._get_cmd(metadata) - cmd.ensure_finalized() - cmd.strict = 1 - inputs = Inputs('1', 'tarek', 'y') - register_module.input = inputs.__call__ - # let's run the command - try: - cmd.run() - finally: - del register_module.input - - @unittest.skipUnless(docutils is not None, 'needs docutils') - def test_register_invalid_long_description(self): - description = ':funkie:`str`' # mimic Sphinx-specific markup - metadata = {'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx', - 'name': 'xxx', 'version': 'xxx', - 'long_description': description} - cmd = self._get_cmd(metadata) - cmd.ensure_finalized() - cmd.strict = True - inputs = Inputs('2', 'tarek', 'tarek@ziade.org') - register_module.input = inputs - self.addCleanup(delattr, register_module, 'input') - - self.assertRaises(DistutilsSetupError, cmd.run) - - def test_check_metadata_deprecated(self): - # makes sure make_metadata is deprecated - cmd = self._get_cmd() - with check_warnings() as w: - warnings.simplefilter("always") - cmd.check_metadata() - self.assertEqual(len(w.warnings), 1) - - def test_list_classifiers(self): - cmd = self._get_cmd() - cmd.list_classifiers = 1 - cmd.run() - results = self.get_logs(INFO) - self.assertEqual(results, ['running check', 'xxx']) - - def test_show_response(self): - # test that the --show-response option return a well formatted response - cmd = self._get_cmd() - inputs = Inputs('1', 'tarek', 'y') - register_module.input = inputs.__call__ - cmd.show_response = 1 - try: - cmd.run() - finally: - del register_module.input - - results = self.get_logs(INFO) - self.assertEqual(results[3], 75 * '-' + '\nxxx\n' + 75 * '-') - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(RegisterTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_sdist.py b/python/Lib/distutils/tests/test_sdist.py deleted file mode 100644 index 7247fb3..0000000 --- a/python/Lib/distutils/tests/test_sdist.py +++ /dev/null @@ -1,493 +0,0 @@ -"""Tests for distutils.command.sdist.""" -import os -import tarfile -import unittest -import warnings -import zipfile -from os.path import join -from textwrap import dedent -from test.support import captured_stdout, run_unittest -from test.support.warnings_helper import check_warnings - -try: - import zlib - ZLIB_SUPPORT = True -except ImportError: - ZLIB_SUPPORT = False - -try: - import grp - import pwd - UID_GID_SUPPORT = True -except ImportError: - UID_GID_SUPPORT = False - -from distutils.command.sdist import sdist, show_formats -from distutils.core import Distribution -from distutils.tests.test_config import BasePyPIRCCommandTestCase -from distutils.errors import DistutilsOptionError -from distutils.spawn import find_executable -from distutils.log import WARN -from distutils.filelist import FileList -from distutils.archive_util import ARCHIVE_FORMATS - -SETUP_PY = """ -from distutils.core import setup -import somecode - -setup(name='fake') -""" - -MANIFEST = """\ -# file GENERATED by distutils, do NOT edit -README -buildout.cfg -inroot.txt -setup.py -data%(sep)sdata.dt -scripts%(sep)sscript.py -some%(sep)sfile.txt -some%(sep)sother_file.txt -somecode%(sep)s__init__.py -somecode%(sep)sdoc.dat -somecode%(sep)sdoc.txt -""" - -class SDistTestCase(BasePyPIRCCommandTestCase): - - def setUp(self): - # PyPIRCCommandTestCase creates a temp dir already - # and put it in self.tmp_dir - super(SDistTestCase, self).setUp() - # setting up an environment - self.old_path = os.getcwd() - os.mkdir(join(self.tmp_dir, 'somecode')) - os.mkdir(join(self.tmp_dir, 'dist')) - # a package, and a README - self.write_file((self.tmp_dir, 'README'), 'xxx') - self.write_file((self.tmp_dir, 'somecode', '__init__.py'), '#') - self.write_file((self.tmp_dir, 'setup.py'), SETUP_PY) - os.chdir(self.tmp_dir) - - def tearDown(self): - # back to normal - os.chdir(self.old_path) - super(SDistTestCase, self).tearDown() - - def get_cmd(self, metadata=None): - """Returns a cmd""" - if metadata is None: - metadata = {'name': 'fake', 'version': '1.0', - 'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx'} - dist = Distribution(metadata) - dist.script_name = 'setup.py' - dist.packages = ['somecode'] - dist.include_package_data = True - cmd = sdist(dist) - cmd.dist_dir = 'dist' - return dist, cmd - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_prune_file_list(self): - # this test creates a project with some VCS dirs and an NFS rename - # file, then launches sdist to check they get pruned on all systems - - # creating VCS directories with some files in them - os.mkdir(join(self.tmp_dir, 'somecode', '.svn')) - self.write_file((self.tmp_dir, 'somecode', '.svn', 'ok.py'), 'xxx') - - os.mkdir(join(self.tmp_dir, 'somecode', '.hg')) - self.write_file((self.tmp_dir, 'somecode', '.hg', - 'ok'), 'xxx') - - os.mkdir(join(self.tmp_dir, 'somecode', '.git')) - self.write_file((self.tmp_dir, 'somecode', '.git', - 'ok'), 'xxx') - - self.write_file((self.tmp_dir, 'somecode', '.nfs0001'), 'xxx') - - # now building a sdist - dist, cmd = self.get_cmd() - - # zip is available universally - # (tar might not be installed under win32) - cmd.formats = ['zip'] - - cmd.ensure_finalized() - cmd.run() - - # now let's check what we have - dist_folder = join(self.tmp_dir, 'dist') - files = os.listdir(dist_folder) - self.assertEqual(files, ['fake-1.0.zip']) - - zip_file = zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip')) - try: - content = zip_file.namelist() - finally: - zip_file.close() - - # making sure everything has been pruned correctly - expected = ['', 'PKG-INFO', 'README', 'setup.py', - 'somecode/', 'somecode/__init__.py'] - self.assertEqual(sorted(content), ['fake-1.0/' + x for x in expected]) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - @unittest.skipIf(find_executable('tar') is None, - "The tar command is not found") - @unittest.skipIf(find_executable('gzip') is None, - "The gzip command is not found") - def test_make_distribution(self): - # now building a sdist - dist, cmd = self.get_cmd() - - # creating a gztar then a tar - cmd.formats = ['gztar', 'tar'] - cmd.ensure_finalized() - cmd.run() - - # making sure we have two files - dist_folder = join(self.tmp_dir, 'dist') - result = os.listdir(dist_folder) - result.sort() - self.assertEqual(result, ['fake-1.0.tar', 'fake-1.0.tar.gz']) - - os.remove(join(dist_folder, 'fake-1.0.tar')) - os.remove(join(dist_folder, 'fake-1.0.tar.gz')) - - # now trying a tar then a gztar - cmd.formats = ['tar', 'gztar'] - - cmd.ensure_finalized() - cmd.run() - - result = os.listdir(dist_folder) - result.sort() - self.assertEqual(result, ['fake-1.0.tar', 'fake-1.0.tar.gz']) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_add_defaults(self): - - # http://bugs.python.org/issue2279 - - # add_default should also include - # data_files and package_data - dist, cmd = self.get_cmd() - - # filling data_files by pointing files - # in package_data - dist.package_data = {'': ['*.cfg', '*.dat'], - 'somecode': ['*.txt']} - self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#') - self.write_file((self.tmp_dir, 'somecode', 'doc.dat'), '#') - - # adding some data in data_files - data_dir = join(self.tmp_dir, 'data') - os.mkdir(data_dir) - self.write_file((data_dir, 'data.dt'), '#') - some_dir = join(self.tmp_dir, 'some') - os.mkdir(some_dir) - # make sure VCS directories are pruned (#14004) - hg_dir = join(self.tmp_dir, '.hg') - os.mkdir(hg_dir) - self.write_file((hg_dir, 'last-message.txt'), '#') - # a buggy regex used to prevent this from working on windows (#6884) - self.write_file((self.tmp_dir, 'buildout.cfg'), '#') - self.write_file((self.tmp_dir, 'inroot.txt'), '#') - self.write_file((some_dir, 'file.txt'), '#') - self.write_file((some_dir, 'other_file.txt'), '#') - - dist.data_files = [('data', ['data/data.dt', - 'buildout.cfg', - 'inroot.txt', - 'notexisting']), - 'some/file.txt', - 'some/other_file.txt'] - - # adding a script - script_dir = join(self.tmp_dir, 'scripts') - os.mkdir(script_dir) - self.write_file((script_dir, 'script.py'), '#') - dist.scripts = [join('scripts', 'script.py')] - - cmd.formats = ['zip'] - cmd.use_defaults = True - - cmd.ensure_finalized() - cmd.run() - - # now let's check what we have - dist_folder = join(self.tmp_dir, 'dist') - files = os.listdir(dist_folder) - self.assertEqual(files, ['fake-1.0.zip']) - - zip_file = zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip')) - try: - content = zip_file.namelist() - finally: - zip_file.close() - - # making sure everything was added - expected = ['', 'PKG-INFO', 'README', 'buildout.cfg', - 'data/', 'data/data.dt', 'inroot.txt', - 'scripts/', 'scripts/script.py', 'setup.py', - 'some/', 'some/file.txt', 'some/other_file.txt', - 'somecode/', 'somecode/__init__.py', 'somecode/doc.dat', - 'somecode/doc.txt'] - self.assertEqual(sorted(content), ['fake-1.0/' + x for x in expected]) - - # checking the MANIFEST - f = open(join(self.tmp_dir, 'MANIFEST')) - try: - manifest = f.read() - finally: - f.close() - self.assertEqual(manifest, MANIFEST % {'sep': os.sep}) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_metadata_check_option(self): - # testing the `medata-check` option - dist, cmd = self.get_cmd(metadata={}) - - # this should raise some warnings ! - # with the `check` subcommand - cmd.ensure_finalized() - cmd.run() - warnings = [msg for msg in self.get_logs(WARN) if - msg.startswith('warning: check:')] - self.assertEqual(len(warnings), 2) - - # trying with a complete set of metadata - self.clear_logs() - dist, cmd = self.get_cmd() - cmd.ensure_finalized() - cmd.metadata_check = 0 - cmd.run() - warnings = [msg for msg in self.get_logs(WARN) if - msg.startswith('warning: check:')] - self.assertEqual(len(warnings), 0) - - def test_check_metadata_deprecated(self): - # makes sure make_metadata is deprecated - dist, cmd = self.get_cmd() - with check_warnings() as w: - warnings.simplefilter("always") - cmd.check_metadata() - self.assertEqual(len(w.warnings), 1) - - def test_show_formats(self): - with captured_stdout() as stdout: - show_formats() - - # the output should be a header line + one line per format - num_formats = len(ARCHIVE_FORMATS.keys()) - output = [line for line in stdout.getvalue().split('\n') - if line.strip().startswith('--formats=')] - self.assertEqual(len(output), num_formats) - - def test_finalize_options(self): - dist, cmd = self.get_cmd() - cmd.finalize_options() - - # default options set by finalize - self.assertEqual(cmd.manifest, 'MANIFEST') - self.assertEqual(cmd.template, 'MANIFEST.in') - self.assertEqual(cmd.dist_dir, 'dist') - - # formats has to be a string splitable on (' ', ',') or - # a stringlist - cmd.formats = 1 - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - cmd.formats = ['zip'] - cmd.finalize_options() - - # formats has to be known - cmd.formats = 'supazipa' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - - # the following tests make sure there is a nice error message instead - # of a traceback when parsing an invalid manifest template - - def _check_template(self, content): - dist, cmd = self.get_cmd() - os.chdir(self.tmp_dir) - self.write_file('MANIFEST.in', content) - cmd.ensure_finalized() - cmd.filelist = FileList() - cmd.read_template() - warnings = self.get_logs(WARN) - self.assertEqual(len(warnings), 1) - - def test_invalid_template_unknown_command(self): - self._check_template('taunt knights *') - - def test_invalid_template_wrong_arguments(self): - # this manifest command takes one argument - self._check_template('prune') - - @unittest.skipIf(os.name != 'nt', 'test relevant for Windows only') - def test_invalid_template_wrong_path(self): - # on Windows, trailing slashes are not allowed - # this used to crash instead of raising a warning: #8286 - self._check_template('include examples/') - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_get_file_list(self): - # make sure MANIFEST is recalculated - dist, cmd = self.get_cmd() - - # filling data_files by pointing files in package_data - dist.package_data = {'somecode': ['*.txt']} - self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#') - cmd.formats = ['gztar'] - cmd.ensure_finalized() - cmd.run() - - f = open(cmd.manifest) - try: - manifest = [line.strip() for line in f.read().split('\n') - if line.strip() != ''] - finally: - f.close() - - self.assertEqual(len(manifest), 5) - - # adding a file - self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#') - - # make sure build_py is reinitialized, like a fresh run - build_py = dist.get_command_obj('build_py') - build_py.finalized = False - build_py.ensure_finalized() - - cmd.run() - - f = open(cmd.manifest) - try: - manifest2 = [line.strip() for line in f.read().split('\n') - if line.strip() != ''] - finally: - f.close() - - # do we have the new file in MANIFEST ? - self.assertEqual(len(manifest2), 6) - self.assertIn('doc2.txt', manifest2[-1]) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_manifest_marker(self): - # check that autogenerated MANIFESTs have a marker - dist, cmd = self.get_cmd() - cmd.ensure_finalized() - cmd.run() - - f = open(cmd.manifest) - try: - manifest = [line.strip() for line in f.read().split('\n') - if line.strip() != ''] - finally: - f.close() - - self.assertEqual(manifest[0], - '# file GENERATED by distutils, do NOT edit') - - @unittest.skipUnless(ZLIB_SUPPORT, "Need zlib support to run") - def test_manifest_comments(self): - # make sure comments don't cause exceptions or wrong includes - contents = dedent("""\ - # bad.py - #bad.py - good.py - """) - dist, cmd = self.get_cmd() - cmd.ensure_finalized() - self.write_file((self.tmp_dir, cmd.manifest), contents) - self.write_file((self.tmp_dir, 'good.py'), '# pick me!') - self.write_file((self.tmp_dir, 'bad.py'), "# don't pick me!") - self.write_file((self.tmp_dir, '#bad.py'), "# don't pick me!") - cmd.run() - self.assertEqual(cmd.filelist.files, ['good.py']) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_manual_manifest(self): - # check that a MANIFEST without a marker is left alone - dist, cmd = self.get_cmd() - cmd.formats = ['gztar'] - cmd.ensure_finalized() - self.write_file((self.tmp_dir, cmd.manifest), 'README.manual') - self.write_file((self.tmp_dir, 'README.manual'), - 'This project maintains its MANIFEST file itself.') - cmd.run() - self.assertEqual(cmd.filelist.files, ['README.manual']) - - f = open(cmd.manifest) - try: - manifest = [line.strip() for line in f.read().split('\n') - if line.strip() != ''] - finally: - f.close() - - self.assertEqual(manifest, ['README.manual']) - - archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz') - archive = tarfile.open(archive_name) - try: - filenames = [tarinfo.name for tarinfo in archive] - finally: - archive.close() - self.assertEqual(sorted(filenames), ['fake-1.0', 'fake-1.0/PKG-INFO', - 'fake-1.0/README.manual']) - - @unittest.skipUnless(ZLIB_SUPPORT, "requires zlib") - @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") - @unittest.skipIf(find_executable('tar') is None, - "The tar command is not found") - @unittest.skipIf(find_executable('gzip') is None, - "The gzip command is not found") - def test_make_distribution_owner_group(self): - # now building a sdist - dist, cmd = self.get_cmd() - - # creating a gztar and specifying the owner+group - cmd.formats = ['gztar'] - cmd.owner = pwd.getpwuid(0)[0] - cmd.group = grp.getgrgid(0)[0] - cmd.ensure_finalized() - cmd.run() - - # making sure we have the good rights - archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz') - archive = tarfile.open(archive_name) - try: - for member in archive.getmembers(): - self.assertEqual(member.uid, 0) - self.assertEqual(member.gid, 0) - finally: - archive.close() - - # building a sdist again - dist, cmd = self.get_cmd() - - # creating a gztar - cmd.formats = ['gztar'] - cmd.ensure_finalized() - cmd.run() - - # making sure we have the good rights - archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz') - archive = tarfile.open(archive_name) - - # note that we are not testing the group ownership here - # because, depending on the platforms and the container - # rights (see #7408) - try: - for member in archive.getmembers(): - self.assertEqual(member.uid, os.getuid()) - finally: - archive.close() - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(SDistTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_spawn.py b/python/Lib/distutils/tests/test_spawn.py deleted file mode 100644 index 73dddf6..0000000 --- a/python/Lib/distutils/tests/test_spawn.py +++ /dev/null @@ -1,139 +0,0 @@ -"""Tests for distutils.spawn.""" -import os -import stat -import sys -import unittest.mock -from test.support import run_unittest, unix_shell, requires_subprocess -from test.support import os_helper - -from distutils.spawn import find_executable -from distutils.spawn import spawn -from distutils.errors import DistutilsExecError -from distutils.tests import support - - -@requires_subprocess() -class SpawnTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - @unittest.skipUnless(os.name in ('nt', 'posix'), - 'Runs only under posix or nt') - def test_spawn(self): - tmpdir = self.mkdtemp() - - # creating something executable - # through the shell that returns 1 - if sys.platform != 'win32': - exe = os.path.join(tmpdir, 'foo.sh') - self.write_file(exe, '#!%s\nexit 1' % unix_shell) - else: - exe = os.path.join(tmpdir, 'foo.bat') - self.write_file(exe, 'exit 1') - - os.chmod(exe, 0o777) - self.assertRaises(DistutilsExecError, spawn, [exe]) - - # now something that works - if sys.platform != 'win32': - exe = os.path.join(tmpdir, 'foo.sh') - self.write_file(exe, '#!%s\nexit 0' % unix_shell) - else: - exe = os.path.join(tmpdir, 'foo.bat') - self.write_file(exe, 'exit 0') - - os.chmod(exe, 0o777) - spawn([exe]) # should work without any error - - def test_find_executable(self): - with os_helper.temp_dir() as tmp_dir: - # use TESTFN to get a pseudo-unique filename - program_noeext = os_helper.TESTFN - # Give the temporary program an ".exe" suffix for all. - # It's needed on Windows and not harmful on other platforms. - program = program_noeext + ".exe" - - filename = os.path.join(tmp_dir, program) - with open(filename, "wb"): - pass - os.chmod(filename, stat.S_IXUSR) - - # test path parameter - rv = find_executable(program, path=tmp_dir) - self.assertEqual(rv, filename) - - if sys.platform == 'win32': - # test without ".exe" extension - rv = find_executable(program_noeext, path=tmp_dir) - self.assertEqual(rv, filename) - - # test find in the current directory - with os_helper.change_cwd(tmp_dir): - rv = find_executable(program) - self.assertEqual(rv, program) - - # test non-existent program - dont_exist_program = "dontexist_" + program - rv = find_executable(dont_exist_program , path=tmp_dir) - self.assertIsNone(rv) - - # PATH='': no match, except in the current directory - with os_helper.EnvironmentVarGuard() as env: - env['PATH'] = '' - with unittest.mock.patch('distutils.spawn.os.confstr', - return_value=tmp_dir, create=True), \ - unittest.mock.patch('distutils.spawn.os.defpath', - tmp_dir): - rv = find_executable(program) - self.assertIsNone(rv) - - # look in current directory - with os_helper.change_cwd(tmp_dir): - rv = find_executable(program) - self.assertEqual(rv, program) - - # PATH=':': explicitly looks in the current directory - with os_helper.EnvironmentVarGuard() as env: - env['PATH'] = os.pathsep - with unittest.mock.patch('distutils.spawn.os.confstr', - return_value='', create=True), \ - unittest.mock.patch('distutils.spawn.os.defpath', ''): - rv = find_executable(program) - self.assertIsNone(rv) - - # look in current directory - with os_helper.change_cwd(tmp_dir): - rv = find_executable(program) - self.assertEqual(rv, program) - - # missing PATH: test os.confstr("CS_PATH") and os.defpath - with os_helper.EnvironmentVarGuard() as env: - env.pop('PATH', None) - - # without confstr - with unittest.mock.patch('distutils.spawn.os.confstr', - side_effect=ValueError, - create=True), \ - unittest.mock.patch('distutils.spawn.os.defpath', - tmp_dir): - rv = find_executable(program) - self.assertEqual(rv, filename) - - # with confstr - with unittest.mock.patch('distutils.spawn.os.confstr', - return_value=tmp_dir, create=True), \ - unittest.mock.patch('distutils.spawn.os.defpath', ''): - rv = find_executable(program) - self.assertEqual(rv, filename) - - def test_spawn_missing_exe(self): - with self.assertRaises(DistutilsExecError) as ctx: - spawn(['does-not-exist']) - self.assertIn("command 'does-not-exist' failed", str(ctx.exception)) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(SpawnTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_sysconfig.py b/python/Lib/distutils/tests/test_sysconfig.py deleted file mode 100644 index 4dfd228..0000000 --- a/python/Lib/distutils/tests/test_sysconfig.py +++ /dev/null @@ -1,264 +0,0 @@ -"""Tests for distutils.sysconfig.""" -import contextlib -import os -import shutil -import subprocess -import sys -import textwrap -import unittest - -from distutils import sysconfig -from distutils.ccompiler import get_default_compiler -from distutils.tests import support -from test.support import run_unittest, swap_item, requires_subprocess, is_wasi -from test.support.os_helper import TESTFN -from test.support.warnings_helper import check_warnings - - -class SysconfigTestCase(support.EnvironGuard, unittest.TestCase): - def setUp(self): - super(SysconfigTestCase, self).setUp() - self.makefile = None - - def tearDown(self): - if self.makefile is not None: - os.unlink(self.makefile) - self.cleanup_testfn() - super(SysconfigTestCase, self).tearDown() - - def cleanup_testfn(self): - if os.path.isfile(TESTFN): - os.remove(TESTFN) - elif os.path.isdir(TESTFN): - shutil.rmtree(TESTFN) - - @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") - def test_get_config_h_filename(self): - config_h = sysconfig.get_config_h_filename() - self.assertTrue(os.path.isfile(config_h), config_h) - - def test_get_python_lib(self): - # XXX doesn't work on Linux when Python was never installed before - #self.assertTrue(os.path.isdir(lib_dir), lib_dir) - # test for pythonxx.lib? - self.assertNotEqual(sysconfig.get_python_lib(), - sysconfig.get_python_lib(prefix=TESTFN)) - - def test_get_config_vars(self): - cvars = sysconfig.get_config_vars() - self.assertIsInstance(cvars, dict) - self.assertTrue(cvars) - - @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") - def test_srcdir(self): - # See Issues #15322, #15364. - srcdir = sysconfig.get_config_var('srcdir') - - self.assertTrue(os.path.isabs(srcdir), srcdir) - self.assertTrue(os.path.isdir(srcdir), srcdir) - - if sysconfig.python_build: - # The python executable has not been installed so srcdir - # should be a full source checkout. - Python_h = os.path.join(srcdir, 'Include', 'Python.h') - self.assertTrue(os.path.exists(Python_h), Python_h) - # /PC/pyconfig.h always exists even if unused on POSIX. - pyconfig_h = os.path.join(srcdir, 'PC', 'pyconfig.h') - self.assertTrue(os.path.exists(pyconfig_h), pyconfig_h) - pyconfig_h_in = os.path.join(srcdir, 'pyconfig.h.in') - self.assertTrue(os.path.exists(pyconfig_h_in), pyconfig_h_in) - elif os.name == 'posix': - self.assertEqual( - os.path.dirname(sysconfig.get_makefile_filename()), - srcdir) - - def test_srcdir_independent_of_cwd(self): - # srcdir should be independent of the current working directory - # See Issues #15322, #15364. - srcdir = sysconfig.get_config_var('srcdir') - cwd = os.getcwd() - try: - os.chdir('..') - srcdir2 = sysconfig.get_config_var('srcdir') - finally: - os.chdir(cwd) - self.assertEqual(srcdir, srcdir2) - - def customize_compiler(self): - # make sure AR gets caught - class compiler: - compiler_type = 'unix' - - def set_executables(self, **kw): - self.exes = kw - - sysconfig_vars = { - 'AR': 'sc_ar', - 'CC': 'sc_cc', - 'CXX': 'sc_cxx', - 'ARFLAGS': '--sc-arflags', - 'CFLAGS': '--sc-cflags', - 'CCSHARED': '--sc-ccshared', - 'LDSHARED': 'sc_ldshared', - 'SHLIB_SUFFIX': 'sc_shutil_suffix', - - # On macOS, disable _osx_support.customize_compiler() - 'CUSTOMIZED_OSX_COMPILER': 'True', - } - - comp = compiler() - with contextlib.ExitStack() as cm: - for key, value in sysconfig_vars.items(): - cm.enter_context(swap_item(sysconfig._config_vars, key, value)) - sysconfig.customize_compiler(comp) - - return comp - - @unittest.skipUnless(get_default_compiler() == 'unix', - 'not testing if default compiler is not unix') - def test_customize_compiler(self): - # Make sure that sysconfig._config_vars is initialized - sysconfig.get_config_vars() - - os.environ['AR'] = 'env_ar' - os.environ['CC'] = 'env_cc' - os.environ['CPP'] = 'env_cpp' - os.environ['CXX'] = 'env_cxx --env-cxx-flags' - os.environ['LDSHARED'] = 'env_ldshared' - os.environ['LDFLAGS'] = '--env-ldflags' - os.environ['ARFLAGS'] = '--env-arflags' - os.environ['CFLAGS'] = '--env-cflags' - os.environ['CPPFLAGS'] = '--env-cppflags' - - comp = self.customize_compiler() - self.assertEqual(comp.exes['archiver'], - 'env_ar --env-arflags') - self.assertEqual(comp.exes['preprocessor'], - 'env_cpp --env-cppflags') - self.assertEqual(comp.exes['compiler'], - 'env_cc --sc-cflags --env-cflags --env-cppflags') - self.assertEqual(comp.exes['compiler_so'], - ('env_cc --sc-cflags ' - '--env-cflags ''--env-cppflags --sc-ccshared')) - self.assertEqual(comp.exes['compiler_cxx'], - 'env_cxx --env-cxx-flags') - self.assertEqual(comp.exes['linker_exe'], - 'env_cc') - self.assertEqual(comp.exes['linker_so'], - ('env_ldshared --env-ldflags --env-cflags' - ' --env-cppflags')) - self.assertEqual(comp.shared_lib_extension, 'sc_shutil_suffix') - - del os.environ['AR'] - del os.environ['CC'] - del os.environ['CPP'] - del os.environ['CXX'] - del os.environ['LDSHARED'] - del os.environ['LDFLAGS'] - del os.environ['ARFLAGS'] - del os.environ['CFLAGS'] - del os.environ['CPPFLAGS'] - - comp = self.customize_compiler() - self.assertEqual(comp.exes['archiver'], - 'sc_ar --sc-arflags') - self.assertEqual(comp.exes['preprocessor'], - 'sc_cc -E') - self.assertEqual(comp.exes['compiler'], - 'sc_cc --sc-cflags') - self.assertEqual(comp.exes['compiler_so'], - 'sc_cc --sc-cflags --sc-ccshared') - self.assertEqual(comp.exes['compiler_cxx'], - 'sc_cxx') - self.assertEqual(comp.exes['linker_exe'], - 'sc_cc') - self.assertEqual(comp.exes['linker_so'], - 'sc_ldshared') - self.assertEqual(comp.shared_lib_extension, 'sc_shutil_suffix') - - def test_parse_makefile_base(self): - self.makefile = TESTFN - fd = open(self.makefile, 'w') - try: - fd.write(r"CONFIG_ARGS= '--arg1=optarg1' 'ENV=LIB'" '\n') - fd.write('VAR=$OTHER\nOTHER=foo') - finally: - fd.close() - d = sysconfig.parse_makefile(self.makefile) - self.assertEqual(d, {'CONFIG_ARGS': "'--arg1=optarg1' 'ENV=LIB'", - 'OTHER': 'foo'}) - - def test_parse_makefile_literal_dollar(self): - self.makefile = TESTFN - fd = open(self.makefile, 'w') - try: - fd.write(r"CONFIG_ARGS= '--arg1=optarg1' 'ENV=\$$LIB'" '\n') - fd.write('VAR=$OTHER\nOTHER=foo') - finally: - fd.close() - d = sysconfig.parse_makefile(self.makefile) - self.assertEqual(d, {'CONFIG_ARGS': r"'--arg1=optarg1' 'ENV=\$LIB'", - 'OTHER': 'foo'}) - - - def test_sysconfig_module(self): - import sysconfig as global_sysconfig - self.assertEqual(global_sysconfig.get_config_var('CFLAGS'), - sysconfig.get_config_var('CFLAGS')) - self.assertEqual(global_sysconfig.get_config_var('LDFLAGS'), - sysconfig.get_config_var('LDFLAGS')) - - @unittest.skipIf(sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'), - 'compiler flags customized') - def test_sysconfig_compiler_vars(self): - # On OS X, binary installers support extension module building on - # various levels of the operating system with differing Xcode - # configurations. This requires customization of some of the - # compiler configuration directives to suit the environment on - # the installed machine. Some of these customizations may require - # running external programs and, so, are deferred until needed by - # the first extension module build. With Python 3.3, only - # the Distutils version of sysconfig is used for extension module - # builds, which happens earlier in the Distutils tests. This may - # cause the following tests to fail since no tests have caused - # the global version of sysconfig to call the customization yet. - # The solution for now is to simply skip this test in this case. - # The longer-term solution is to only have one version of sysconfig. - - import sysconfig as global_sysconfig - if sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'): - self.skipTest('compiler flags customized') - self.assertEqual(global_sysconfig.get_config_var('LDSHARED'), - sysconfig.get_config_var('LDSHARED')) - self.assertEqual(global_sysconfig.get_config_var('CC'), - sysconfig.get_config_var('CC')) - - @requires_subprocess() - def test_customize_compiler_before_get_config_vars(self): - # Issue #21923: test that a Distribution compiler - # instance can be called without an explicit call to - # get_config_vars(). - with open(TESTFN, 'w') as f: - f.writelines(textwrap.dedent('''\ - from distutils.core import Distribution - config = Distribution().get_command_obj('config') - # try_compile may pass or it may fail if no compiler - # is found but it should not raise an exception. - rc = config.try_compile('int x;') - ''')) - p = subprocess.Popen([str(sys.executable), TESTFN], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - universal_newlines=True) - outs, errs = p.communicate() - self.assertEqual(0, p.returncode, "Subprocess failed: " + outs) - - -def test_suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(SysconfigTestCase)) - return suite - - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_text_file.py b/python/Lib/distutils/tests/test_text_file.py deleted file mode 100644 index 57f1ed1..0000000 --- a/python/Lib/distutils/tests/test_text_file.py +++ /dev/null @@ -1,107 +0,0 @@ -"""Tests for distutils.text_file.""" -import os -import unittest -from distutils.text_file import TextFile -from distutils.tests import support -from test.support import run_unittest - -TEST_DATA = """# test file - -line 3 \\ -# intervening comment - continues on next line -""" - -class TextFileTestCase(support.TempdirManager, unittest.TestCase): - - def test_class(self): - # old tests moved from text_file.__main__ - # so they are really called by the buildbots - - # result 1: no fancy options - result1 = ['# test file\n', '\n', 'line 3 \\\n', - '# intervening comment\n', - ' continues on next line\n'] - - # result 2: just strip comments - result2 = ["\n", - "line 3 \\\n", - " continues on next line\n"] - - # result 3: just strip blank lines - result3 = ["# test file\n", - "line 3 \\\n", - "# intervening comment\n", - " continues on next line\n"] - - # result 4: default, strip comments, blank lines, - # and trailing whitespace - result4 = ["line 3 \\", - " continues on next line"] - - # result 5: strip comments and blanks, plus join lines (but don't - # "collapse" joined lines - result5 = ["line 3 continues on next line"] - - # result 6: strip comments and blanks, plus join lines (and - # "collapse" joined lines - result6 = ["line 3 continues on next line"] - - def test_input(count, description, file, expected_result): - result = file.readlines() - self.assertEqual(result, expected_result) - - tmpdir = self.mkdtemp() - filename = os.path.join(tmpdir, "test.txt") - out_file = open(filename, "w") - try: - out_file.write(TEST_DATA) - finally: - out_file.close() - - in_file = TextFile(filename, strip_comments=0, skip_blanks=0, - lstrip_ws=0, rstrip_ws=0) - try: - test_input(1, "no processing", in_file, result1) - finally: - in_file.close() - - in_file = TextFile(filename, strip_comments=1, skip_blanks=0, - lstrip_ws=0, rstrip_ws=0) - try: - test_input(2, "strip comments", in_file, result2) - finally: - in_file.close() - - in_file = TextFile(filename, strip_comments=0, skip_blanks=1, - lstrip_ws=0, rstrip_ws=0) - try: - test_input(3, "strip blanks", in_file, result3) - finally: - in_file.close() - - in_file = TextFile(filename) - try: - test_input(4, "default processing", in_file, result4) - finally: - in_file.close() - - in_file = TextFile(filename, strip_comments=1, skip_blanks=1, - join_lines=1, rstrip_ws=1) - try: - test_input(5, "join lines without collapsing", in_file, result5) - finally: - in_file.close() - - in_file = TextFile(filename, strip_comments=1, skip_blanks=1, - join_lines=1, rstrip_ws=1, collapse_join=1) - try: - test_input(6, "join lines with collapsing", in_file, result6) - finally: - in_file.close() - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(TextFileTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_unixccompiler.py b/python/Lib/distutils/tests/test_unixccompiler.py deleted file mode 100644 index 26a6974..0000000 --- a/python/Lib/distutils/tests/test_unixccompiler.py +++ /dev/null @@ -1,145 +0,0 @@ -"""Tests for distutils.unixccompiler.""" -import sys -import unittest -from test.support import run_unittest -from test.support.os_helper import EnvironmentVarGuard - -from distutils import sysconfig -from distutils.unixccompiler import UnixCCompiler - -class UnixCCompilerTestCase(unittest.TestCase): - - def setUp(self): - self._backup_platform = sys.platform - self._backup_get_config_var = sysconfig.get_config_var - self._backup_config_vars = dict(sysconfig._config_vars) - class CompilerWrapper(UnixCCompiler): - def rpath_foo(self): - return self.runtime_library_dir_option('/foo') - self.cc = CompilerWrapper() - - def tearDown(self): - sys.platform = self._backup_platform - sysconfig.get_config_var = self._backup_get_config_var - sysconfig._config_vars.clear() - sysconfig._config_vars.update(self._backup_config_vars) - - @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") - def test_runtime_libdir_option(self): - # Issue#5900 - # - # Ensure RUNPATH is added to extension modules with RPATH if - # GNU ld is used - - # darwin - sys.platform = 'darwin' - self.assertEqual(self.cc.rpath_foo(), '-L/foo') - - # hp-ux - sys.platform = 'hp-ux' - old_gcv = sysconfig.get_config_var - def gcv(v): - return 'xxx' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), ['+s', '-L/foo']) - - def gcv(v): - return 'gcc' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), ['-Wl,+s', '-L/foo']) - - def gcv(v): - return 'g++' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), ['-Wl,+s', '-L/foo']) - - sysconfig.get_config_var = old_gcv - - # GCC GNULD - sys.platform = 'bar' - def gcv(v): - if v == 'CC': - return 'gcc' - elif v == 'GNULD': - return 'yes' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), '-Wl,--enable-new-dtags,-R/foo') - - # GCC non-GNULD - sys.platform = 'bar' - def gcv(v): - if v == 'CC': - return 'gcc' - elif v == 'GNULD': - return 'no' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), '-Wl,-R/foo') - - # GCC GNULD with fully qualified configuration prefix - # see #7617 - sys.platform = 'bar' - def gcv(v): - if v == 'CC': - return 'x86_64-pc-linux-gnu-gcc-4.4.2' - elif v == 'GNULD': - return 'yes' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), '-Wl,--enable-new-dtags,-R/foo') - - # non-GCC GNULD - sys.platform = 'bar' - def gcv(v): - if v == 'CC': - return 'cc' - elif v == 'GNULD': - return 'yes' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), '-R/foo') - - # non-GCC non-GNULD - sys.platform = 'bar' - def gcv(v): - if v == 'CC': - return 'cc' - elif v == 'GNULD': - return 'no' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), '-R/foo') - - @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for OS X') - def test_osx_cc_overrides_ldshared(self): - # Issue #18080: - # ensure that setting CC env variable also changes default linker - def gcv(v): - if v == 'LDSHARED': - return 'gcc-4.2 -bundle -undefined dynamic_lookup ' - return 'gcc-4.2' - sysconfig.get_config_var = gcv - with EnvironmentVarGuard() as env: - env['CC'] = 'my_cc' - del env['LDSHARED'] - sysconfig.customize_compiler(self.cc) - self.assertEqual(self.cc.linker_so[0], 'my_cc') - - @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for OS X') - def test_osx_explicit_ldshared(self): - # Issue #18080: - # ensure that setting CC env variable does not change - # explicit LDSHARED setting for linker - def gcv(v): - if v == 'LDSHARED': - return 'gcc-4.2 -bundle -undefined dynamic_lookup ' - return 'gcc-4.2' - sysconfig.get_config_var = gcv - with EnvironmentVarGuard() as env: - env['CC'] = 'my_cc' - env['LDSHARED'] = 'my_ld -bundle -dynamic' - sysconfig.customize_compiler(self.cc) - self.assertEqual(self.cc.linker_so[0], 'my_ld') - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(UnixCCompilerTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_upload.py b/python/Lib/distutils/tests/test_upload.py deleted file mode 100644 index b799c46..0000000 --- a/python/Lib/distutils/tests/test_upload.py +++ /dev/null @@ -1,223 +0,0 @@ -"""Tests for distutils.command.upload.""" -import os -import unittest -import unittest.mock as mock -from urllib.error import HTTPError - -from test.support import run_unittest - -from distutils.command import upload as upload_mod -from distutils.command.upload import upload -from distutils.core import Distribution -from distutils.errors import DistutilsError -from distutils.log import ERROR, INFO - -from distutils.tests.test_config import PYPIRC, BasePyPIRCCommandTestCase - -PYPIRC_LONG_PASSWORD = """\ -[distutils] - -index-servers = - server1 - server2 - -[server1] -username:me -password:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -[server2] -username:meagain -password: secret -realm:acme -repository:http://another.pypi/ -""" - - -PYPIRC_NOPASSWORD = """\ -[distutils] - -index-servers = - server1 - -[server1] -username:me -""" - -class FakeOpen(object): - - def __init__(self, url, msg=None, code=None): - self.url = url - if not isinstance(url, str): - self.req = url - else: - self.req = None - self.msg = msg or 'OK' - self.code = code or 200 - - def getheader(self, name, default=None): - return { - 'content-type': 'text/plain; charset=utf-8', - }.get(name.lower(), default) - - def read(self): - return b'xyzzy' - - def getcode(self): - return self.code - - -class uploadTestCase(BasePyPIRCCommandTestCase): - - def setUp(self): - super(uploadTestCase, self).setUp() - self.old_open = upload_mod.urlopen - upload_mod.urlopen = self._urlopen - self.last_open = None - self.next_msg = None - self.next_code = None - - def tearDown(self): - upload_mod.urlopen = self.old_open - super(uploadTestCase, self).tearDown() - - def _urlopen(self, url): - self.last_open = FakeOpen(url, msg=self.next_msg, code=self.next_code) - return self.last_open - - def test_finalize_options(self): - - # new format - self.write_file(self.rc, PYPIRC) - dist = Distribution() - cmd = upload(dist) - cmd.finalize_options() - for attr, waited in (('username', 'me'), ('password', 'secret'), - ('realm', 'pypi'), - ('repository', 'https://upload.pypi.org/legacy/')): - self.assertEqual(getattr(cmd, attr), waited) - - def test_saved_password(self): - # file with no password - self.write_file(self.rc, PYPIRC_NOPASSWORD) - - # make sure it passes - dist = Distribution() - cmd = upload(dist) - cmd.finalize_options() - self.assertEqual(cmd.password, None) - - # make sure we get it as well, if another command - # initialized it at the dist level - dist.password = 'xxx' - cmd = upload(dist) - cmd.finalize_options() - self.assertEqual(cmd.password, 'xxx') - - def test_upload(self): - tmp = self.mkdtemp() - path = os.path.join(tmp, 'xxx') - self.write_file(path) - command, pyversion, filename = 'xxx', '2.6', path - dist_files = [(command, pyversion, filename)] - self.write_file(self.rc, PYPIRC_LONG_PASSWORD) - - # lets run it - pkg_dir, dist = self.create_dist(dist_files=dist_files) - cmd = upload(dist) - cmd.show_response = 1 - cmd.ensure_finalized() - cmd.run() - - # what did we send ? - headers = dict(self.last_open.req.headers) - self.assertGreaterEqual(int(headers['Content-length']), 2162) - content_type = headers['Content-type'] - self.assertTrue(content_type.startswith('multipart/form-data')) - self.assertEqual(self.last_open.req.get_method(), 'POST') - expected_url = 'https://upload.pypi.org/legacy/' - self.assertEqual(self.last_open.req.get_full_url(), expected_url) - data = self.last_open.req.data - self.assertIn(b'xxx',data) - self.assertIn(b'protocol_version', data) - self.assertIn(b'sha256_digest', data) - self.assertIn( - b'cd2eb0837c9b4c962c22d2ff8b5441b7b45805887f051d39bf133b583baf' - b'6860', - data - ) - if b'md5_digest' in data: - self.assertIn(b'f561aaf6ef0bf14d4208bb46a4ccb3ad', data) - if b'blake2_256_digest' in data: - self.assertIn( - b'b6f289a27d4fe90da63c503bfe0a9b761a8f76bb86148565065f040be' - b'6d1c3044cf7ded78ef800509bccb4b648e507d88dc6383d67642aadcc' - b'ce443f1534330a', - data - ) - - # The PyPI response body was echoed - results = self.get_logs(INFO) - self.assertEqual(results[-1], 75 * '-' + '\nxyzzy\n' + 75 * '-') - - # bpo-32304: archives whose last byte was b'\r' were corrupted due to - # normalization intended for Mac OS 9. - def test_upload_correct_cr(self): - # content that ends with \r should not be modified. - tmp = self.mkdtemp() - path = os.path.join(tmp, 'xxx') - self.write_file(path, content='yy\r') - command, pyversion, filename = 'xxx', '2.6', path - dist_files = [(command, pyversion, filename)] - self.write_file(self.rc, PYPIRC_LONG_PASSWORD) - - # other fields that ended with \r used to be modified, now are - # preserved. - pkg_dir, dist = self.create_dist( - dist_files=dist_files, - description='long description\r' - ) - cmd = upload(dist) - cmd.show_response = 1 - cmd.ensure_finalized() - cmd.run() - - headers = dict(self.last_open.req.headers) - self.assertGreaterEqual(int(headers['Content-length']), 2172) - self.assertIn(b'long description\r', self.last_open.req.data) - - def test_upload_fails(self): - self.next_msg = "Not Found" - self.next_code = 404 - self.assertRaises(DistutilsError, self.test_upload) - - def test_wrong_exception_order(self): - tmp = self.mkdtemp() - path = os.path.join(tmp, 'xxx') - self.write_file(path) - dist_files = [('xxx', '2.6', path)] # command, pyversion, filename - self.write_file(self.rc, PYPIRC_LONG_PASSWORD) - - pkg_dir, dist = self.create_dist(dist_files=dist_files) - tests = [ - (OSError('oserror'), 'oserror', OSError), - (HTTPError('url', 400, 'httperror', {}, None), - 'Upload failed (400): httperror', DistutilsError), - ] - for exception, expected, raised_exception in tests: - with self.subTest(exception=type(exception).__name__): - with mock.patch('distutils.command.upload.urlopen', - new=mock.Mock(side_effect=exception)): - with self.assertRaises(raised_exception): - cmd = upload(dist) - cmd.ensure_finalized() - cmd.run() - results = self.get_logs(ERROR) - self.assertIn(expected, results[-1]) - self.clear_logs() - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(uploadTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_util.py b/python/Lib/distutils/tests/test_util.py deleted file mode 100644 index 23840a1..0000000 --- a/python/Lib/distutils/tests/test_util.py +++ /dev/null @@ -1,313 +0,0 @@ -"""Tests for distutils.util.""" -import os -import sys -import unittest -from copy import copy -from test.support import run_unittest -from unittest import mock - -from distutils.errors import DistutilsPlatformError, DistutilsByteCompileError -from distutils.util import (get_platform, convert_path, change_root, - check_environ, split_quoted, strtobool, - rfc822_escape, byte_compile, - grok_environment_error) -from distutils import util # used to patch _environ_checked -from distutils.sysconfig import get_config_vars -from distutils import sysconfig -from distutils.tests import support -import _osx_support - -class UtilTestCase(support.EnvironGuard, unittest.TestCase): - - def setUp(self): - super(UtilTestCase, self).setUp() - # saving the environment - self.name = os.name - self.platform = sys.platform - self.version = sys.version - self.sep = os.sep - self.join = os.path.join - self.isabs = os.path.isabs - self.splitdrive = os.path.splitdrive - self._config_vars = copy(sysconfig._config_vars) - - # patching os.uname - if hasattr(os, 'uname'): - self.uname = os.uname - self._uname = os.uname() - else: - self.uname = None - self._uname = None - - os.uname = self._get_uname - - def tearDown(self): - # getting back the environment - os.name = self.name - sys.platform = self.platform - sys.version = self.version - os.sep = self.sep - os.path.join = self.join - os.path.isabs = self.isabs - os.path.splitdrive = self.splitdrive - if self.uname is not None: - os.uname = self.uname - else: - del os.uname - sysconfig._config_vars.clear() - sysconfig._config_vars.update(self._config_vars) - super(UtilTestCase, self).tearDown() - - def _set_uname(self, uname): - self._uname = uname - - def _get_uname(self): - return self._uname - - def test_get_platform(self): - - # windows XP, 32bits - os.name = 'nt' - sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' - '[MSC v.1310 32 bit (Intel)]') - sys.platform = 'win32' - self.assertEqual(get_platform(), 'win32') - - # windows XP, amd64 - os.name = 'nt' - sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' - '[MSC v.1310 32 bit (Amd64)]') - sys.platform = 'win32' - self.assertEqual(get_platform(), 'win-amd64') - - # macbook - os.name = 'posix' - sys.version = ('2.5 (r25:51918, Sep 19 2006, 08:49:13) ' - '\n[GCC 4.0.1 (Apple Computer, Inc. build 5341)]') - sys.platform = 'darwin' - self._set_uname(('Darwin', 'macziade', '8.11.1', - ('Darwin Kernel Version 8.11.1: ' - 'Wed Oct 10 18:23:28 PDT 2007; ' - 'root:xnu-792.25.20~1/RELEASE_I386'), 'i386')) - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3' - - get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' - '-fwrapv -O3 -Wall -Wstrict-prototypes') - - cursize = sys.maxsize - sys.maxsize = (2 ** 31)-1 - try: - self.assertEqual(get_platform(), 'macosx-10.3-i386') - finally: - sys.maxsize = cursize - - # macbook with fat binaries (fat, universal or fat64) - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.4' - get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3') - - self.assertEqual(get_platform(), 'macosx-10.4-fat') - - _osx_support._remove_original_values(get_config_vars()) - os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.1' - self.assertEqual(get_platform(), 'macosx-10.4-fat') - - - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3') - - self.assertEqual(get_platform(), 'macosx-10.4-intel') - - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc -arch i386 -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3') - self.assertEqual(get_platform(), 'macosx-10.4-fat3') - - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['CFLAGS'] = ('-arch ppc64 -arch x86_64 -arch ppc -arch i386 -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3') - self.assertEqual(get_platform(), 'macosx-10.4-universal') - - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc64 -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3') - - self.assertEqual(get_platform(), 'macosx-10.4-fat64') - - for arch in ('ppc', 'i386', 'x86_64', 'ppc64'): - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['CFLAGS'] = ('-arch %s -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3'%(arch,)) - - self.assertEqual(get_platform(), 'macosx-10.4-%s'%(arch,)) - - - # linux debian sarge - os.name = 'posix' - sys.version = ('2.3.5 (#1, Jul 4 2007, 17:28:59) ' - '\n[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)]') - sys.platform = 'linux2' - self._set_uname(('Linux', 'aglae', '2.6.21.1dedibox-r7', - '#1 Mon Apr 30 17:25:38 CEST 2007', 'i686')) - - self.assertEqual(get_platform(), 'linux-i686') - - # XXX more platforms to tests here - - def test_convert_path(self): - # linux/mac - os.sep = '/' - def _join(path): - return '/'.join(path) - os.path.join = _join - - self.assertEqual(convert_path('/home/to/my/stuff'), - '/home/to/my/stuff') - - # win - os.sep = '\\' - def _join(*path): - return '\\'.join(path) - os.path.join = _join - - self.assertRaises(ValueError, convert_path, '/home/to/my/stuff') - self.assertRaises(ValueError, convert_path, 'home/to/my/stuff/') - - self.assertEqual(convert_path('home/to/my/stuff'), - 'home\\to\\my\\stuff') - self.assertEqual(convert_path('.'), - os.curdir) - - def test_change_root(self): - # linux/mac - os.name = 'posix' - def _isabs(path): - return path[0] == '/' - os.path.isabs = _isabs - def _join(*path): - return '/'.join(path) - os.path.join = _join - - self.assertEqual(change_root('/root', '/old/its/here'), - '/root/old/its/here') - self.assertEqual(change_root('/root', 'its/here'), - '/root/its/here') - - # windows - os.name = 'nt' - def _isabs(path): - return path.startswith('c:\\') - os.path.isabs = _isabs - def _splitdrive(path): - if path.startswith('c:'): - return ('', path.replace('c:', '')) - return ('', path) - os.path.splitdrive = _splitdrive - def _join(*path): - return '\\'.join(path) - os.path.join = _join - - self.assertEqual(change_root('c:\\root', 'c:\\old\\its\\here'), - 'c:\\root\\old\\its\\here') - self.assertEqual(change_root('c:\\root', 'its\\here'), - 'c:\\root\\its\\here') - - # BugsBunny os (it's a great os) - os.name = 'BugsBunny' - self.assertRaises(DistutilsPlatformError, - change_root, 'c:\\root', 'its\\here') - - # XXX platforms to be covered: mac - - def test_check_environ(self): - util._environ_checked = 0 - os.environ.pop('HOME', None) - - check_environ() - - self.assertEqual(os.environ['PLAT'], get_platform()) - self.assertEqual(util._environ_checked, 1) - - @unittest.skipUnless(os.name == 'posix', 'specific to posix') - def test_check_environ_getpwuid(self): - util._environ_checked = 0 - os.environ.pop('HOME', None) - - try: - import pwd - except ImportError: - raise unittest.SkipTest("Test requires pwd module.") - - # only set pw_dir field, other fields are not used - result = pwd.struct_passwd((None, None, None, None, None, - '/home/distutils', None)) - with mock.patch.object(pwd, 'getpwuid', return_value=result): - check_environ() - self.assertEqual(os.environ['HOME'], '/home/distutils') - - util._environ_checked = 0 - os.environ.pop('HOME', None) - - # bpo-10496: Catch pwd.getpwuid() error - with mock.patch.object(pwd, 'getpwuid', side_effect=KeyError): - check_environ() - self.assertNotIn('HOME', os.environ) - - def test_split_quoted(self): - self.assertEqual(split_quoted('""one"" "two" \'three\' \\four'), - ['one', 'two', 'three', 'four']) - - def test_strtobool(self): - yes = ('y', 'Y', 'yes', 'True', 't', 'true', 'True', 'On', 'on', '1') - no = ('n', 'no', 'f', 'false', 'off', '0', 'Off', 'No', 'N') - - for y in yes: - self.assertTrue(strtobool(y)) - - for n in no: - self.assertFalse(strtobool(n)) - - def test_rfc822_escape(self): - header = 'I am a\npoor\nlonesome\nheader\n' - res = rfc822_escape(header) - wanted = ('I am a%(8s)spoor%(8s)slonesome%(8s)s' - 'header%(8s)s') % {'8s': '\n'+8*' '} - self.assertEqual(res, wanted) - - def test_dont_write_bytecode(self): - # makes sure byte_compile raise a DistutilsError - # if sys.dont_write_bytecode is True - old_dont_write_bytecode = sys.dont_write_bytecode - sys.dont_write_bytecode = True - try: - self.assertRaises(DistutilsByteCompileError, byte_compile, []) - finally: - sys.dont_write_bytecode = old_dont_write_bytecode - - def test_grok_environment_error(self): - # test obsolete function to ensure backward compat (#4931) - exc = IOError("Unable to find batch file") - msg = grok_environment_error(exc) - self.assertEqual(msg, "error: Unable to find batch file") - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(UtilTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_version.py b/python/Lib/distutils/tests/test_version.py deleted file mode 100644 index 152df6c..0000000 --- a/python/Lib/distutils/tests/test_version.py +++ /dev/null @@ -1,87 +0,0 @@ -"""Tests for distutils.version.""" -import unittest -from distutils.version import LooseVersion -from distutils.version import StrictVersion -from test.support import run_unittest - -class VersionTestCase(unittest.TestCase): - - def test_prerelease(self): - version = StrictVersion('1.2.3a1') - self.assertEqual(version.version, (1, 2, 3)) - self.assertEqual(version.prerelease, ('a', 1)) - self.assertEqual(str(version), '1.2.3a1') - - version = StrictVersion('1.2.0') - self.assertEqual(str(version), '1.2') - - def test_cmp_strict(self): - versions = (('1.5.1', '1.5.2b2', -1), - ('161', '3.10a', ValueError), - ('8.02', '8.02', 0), - ('3.4j', '1996.07.12', ValueError), - ('3.2.pl0', '3.1.1.6', ValueError), - ('2g6', '11g', ValueError), - ('0.9', '2.2', -1), - ('1.2.1', '1.2', 1), - ('1.1', '1.2.2', -1), - ('1.2', '1.1', 1), - ('1.2.1', '1.2.2', -1), - ('1.2.2', '1.2', 1), - ('1.2', '1.2.2', -1), - ('0.4.0', '0.4', 0), - ('1.13++', '5.5.kw', ValueError)) - - for v1, v2, wanted in versions: - try: - res = StrictVersion(v1)._cmp(StrictVersion(v2)) - except ValueError: - if wanted is ValueError: - continue - else: - raise AssertionError(("cmp(%s, %s) " - "shouldn't raise ValueError") - % (v1, v2)) - self.assertEqual(res, wanted, - 'cmp(%s, %s) should be %s, got %s' % - (v1, v2, wanted, res)) - res = StrictVersion(v1)._cmp(v2) - self.assertEqual(res, wanted, - 'cmp(%s, %s) should be %s, got %s' % - (v1, v2, wanted, res)) - res = StrictVersion(v1)._cmp(object()) - self.assertIs(res, NotImplemented, - 'cmp(%s, %s) should be NotImplemented, got %s' % - (v1, v2, res)) - - - def test_cmp(self): - versions = (('1.5.1', '1.5.2b2', -1), - ('161', '3.10a', 1), - ('8.02', '8.02', 0), - ('3.4j', '1996.07.12', -1), - ('3.2.pl0', '3.1.1.6', 1), - ('2g6', '11g', -1), - ('0.960923', '2.2beta29', -1), - ('1.13++', '5.5.kw', -1)) - - - for v1, v2, wanted in versions: - res = LooseVersion(v1)._cmp(LooseVersion(v2)) - self.assertEqual(res, wanted, - 'cmp(%s, %s) should be %s, got %s' % - (v1, v2, wanted, res)) - res = LooseVersion(v1)._cmp(v2) - self.assertEqual(res, wanted, - 'cmp(%s, %s) should be %s, got %s' % - (v1, v2, wanted, res)) - res = LooseVersion(v1)._cmp(object()) - self.assertIs(res, NotImplemented, - 'cmp(%s, %s) should be NotImplemented, got %s' % - (v1, v2, res)) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(VersionTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/python/Lib/distutils/tests/test_versionpredicate.py b/python/Lib/distutils/tests/test_versionpredicate.py deleted file mode 100644 index dac0859..0000000 --- a/python/Lib/distutils/tests/test_versionpredicate.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Tests harness for distutils.versionpredicate. - -""" - -import distutils.versionpredicate -import doctest -from test.support import run_unittest - -def test_suite(): - return doctest.DocTestSuite(distutils.versionpredicate) - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/python/Lib/distutils/text_file.py b/python/Lib/distutils/text_file.py deleted file mode 100644 index 818155c..0000000 --- a/python/Lib/distutils/text_file.py +++ /dev/null @@ -1,286 +0,0 @@ -"""text_file - -provides the TextFile class, which gives an interface to text files -that (optionally) takes care of stripping comments, ignoring blank -lines, and joining lines with backslashes.""" - -import sys, io - - -class TextFile: - """Provides a file-like object that takes care of all the things you - commonly want to do when processing a text file that has some - line-by-line syntax: strip comments (as long as "#" is your - comment character), skip blank lines, join adjacent lines by - escaping the newline (ie. backslash at end of line), strip - leading and/or trailing whitespace. All of these are optional - and independently controllable. - - Provides a 'warn()' method so you can generate warning messages that - report physical line number, even if the logical line in question - spans multiple physical lines. Also provides 'unreadline()' for - implementing line-at-a-time lookahead. - - Constructor is called as: - - TextFile (filename=None, file=None, **options) - - It bombs (RuntimeError) if both 'filename' and 'file' are None; - 'filename' should be a string, and 'file' a file object (or - something that provides 'readline()' and 'close()' methods). It is - recommended that you supply at least 'filename', so that TextFile - can include it in warning messages. If 'file' is not supplied, - TextFile creates its own using 'io.open()'. - - The options are all boolean, and affect the value returned by - 'readline()': - strip_comments [default: true] - strip from "#" to end-of-line, as well as any whitespace - leading up to the "#" -- unless it is escaped by a backslash - lstrip_ws [default: false] - strip leading whitespace from each line before returning it - rstrip_ws [default: true] - strip trailing whitespace (including line terminator!) from - each line before returning it - skip_blanks [default: true} - skip lines that are empty *after* stripping comments and - whitespace. (If both lstrip_ws and rstrip_ws are false, - then some lines may consist of solely whitespace: these will - *not* be skipped, even if 'skip_blanks' is true.) - join_lines [default: false] - if a backslash is the last non-newline character on a line - after stripping comments and whitespace, join the following line - to it to form one "logical line"; if N consecutive lines end - with a backslash, then N+1 physical lines will be joined to - form one logical line. - collapse_join [default: false] - strip leading whitespace from lines that are joined to their - predecessor; only matters if (join_lines and not lstrip_ws) - errors [default: 'strict'] - error handler used to decode the file content - - Note that since 'rstrip_ws' can strip the trailing newline, the - semantics of 'readline()' must differ from those of the builtin file - object's 'readline()' method! In particular, 'readline()' returns - None for end-of-file: an empty string might just be a blank line (or - an all-whitespace line), if 'rstrip_ws' is true but 'skip_blanks' is - not.""" - - default_options = { 'strip_comments': 1, - 'skip_blanks': 1, - 'lstrip_ws': 0, - 'rstrip_ws': 1, - 'join_lines': 0, - 'collapse_join': 0, - 'errors': 'strict', - } - - def __init__(self, filename=None, file=None, **options): - """Construct a new TextFile object. At least one of 'filename' - (a string) and 'file' (a file-like object) must be supplied. - They keyword argument options are described above and affect - the values returned by 'readline()'.""" - if filename is None and file is None: - raise RuntimeError("you must supply either or both of 'filename' and 'file'") - - # set values for all options -- either from client option hash - # or fallback to default_options - for opt in self.default_options.keys(): - if opt in options: - setattr(self, opt, options[opt]) - else: - setattr(self, opt, self.default_options[opt]) - - # sanity check client option hash - for opt in options.keys(): - if opt not in self.default_options: - raise KeyError("invalid TextFile option '%s'" % opt) - - if file is None: - self.open(filename) - else: - self.filename = filename - self.file = file - self.current_line = 0 # assuming that file is at BOF! - - # 'linebuf' is a stack of lines that will be emptied before we - # actually read from the file; it's only populated by an - # 'unreadline()' operation - self.linebuf = [] - - def open(self, filename): - """Open a new file named 'filename'. This overrides both the - 'filename' and 'file' arguments to the constructor.""" - self.filename = filename - self.file = io.open(self.filename, 'r', errors=self.errors) - self.current_line = 0 - - def close(self): - """Close the current file and forget everything we know about it - (filename, current line number).""" - file = self.file - self.file = None - self.filename = None - self.current_line = None - file.close() - - def gen_error(self, msg, line=None): - outmsg = [] - if line is None: - line = self.current_line - outmsg.append(self.filename + ", ") - if isinstance(line, (list, tuple)): - outmsg.append("lines %d-%d: " % tuple(line)) - else: - outmsg.append("line %d: " % line) - outmsg.append(str(msg)) - return "".join(outmsg) - - def error(self, msg, line=None): - raise ValueError("error: " + self.gen_error(msg, line)) - - def warn(self, msg, line=None): - """Print (to stderr) a warning message tied to the current logical - line in the current file. If the current logical line in the - file spans multiple physical lines, the warning refers to the - whole range, eg. "lines 3-5". If 'line' supplied, it overrides - the current line number; it may be a list or tuple to indicate a - range of physical lines, or an integer for a single physical - line.""" - sys.stderr.write("warning: " + self.gen_error(msg, line) + "\n") - - def readline(self): - """Read and return a single logical line from the current file (or - from an internal buffer if lines have previously been "unread" - with 'unreadline()'). If the 'join_lines' option is true, this - may involve reading multiple physical lines concatenated into a - single string. Updates the current line number, so calling - 'warn()' after 'readline()' emits a warning about the physical - line(s) just read. Returns None on end-of-file, since the empty - string can occur if 'rstrip_ws' is true but 'strip_blanks' is - not.""" - # If any "unread" lines waiting in 'linebuf', return the top - # one. (We don't actually buffer read-ahead data -- lines only - # get put in 'linebuf' if the client explicitly does an - # 'unreadline()'. - if self.linebuf: - line = self.linebuf[-1] - del self.linebuf[-1] - return line - - buildup_line = '' - - while True: - # read the line, make it None if EOF - line = self.file.readline() - if line == '': - line = None - - if self.strip_comments and line: - - # Look for the first "#" in the line. If none, never - # mind. If we find one and it's the first character, or - # is not preceded by "\", then it starts a comment -- - # strip the comment, strip whitespace before it, and - # carry on. Otherwise, it's just an escaped "#", so - # unescape it (and any other escaped "#"'s that might be - # lurking in there) and otherwise leave the line alone. - - pos = line.find("#") - if pos == -1: # no "#" -- no comments - pass - - # It's definitely a comment -- either "#" is the first - # character, or it's elsewhere and unescaped. - elif pos == 0 or line[pos-1] != "\\": - # Have to preserve the trailing newline, because it's - # the job of a later step (rstrip_ws) to remove it -- - # and if rstrip_ws is false, we'd better preserve it! - # (NB. this means that if the final line is all comment - # and has no trailing newline, we will think that it's - # EOF; I think that's OK.) - eol = (line[-1] == '\n') and '\n' or '' - line = line[0:pos] + eol - - # If all that's left is whitespace, then skip line - # *now*, before we try to join it to 'buildup_line' -- - # that way constructs like - # hello \\ - # # comment that should be ignored - # there - # result in "hello there". - if line.strip() == "": - continue - else: # it's an escaped "#" - line = line.replace("\\#", "#") - - # did previous line end with a backslash? then accumulate - if self.join_lines and buildup_line: - # oops: end of file - if line is None: - self.warn("continuation line immediately precedes " - "end-of-file") - return buildup_line - - if self.collapse_join: - line = line.lstrip() - line = buildup_line + line - - # careful: pay attention to line number when incrementing it - if isinstance(self.current_line, list): - self.current_line[1] = self.current_line[1] + 1 - else: - self.current_line = [self.current_line, - self.current_line + 1] - # just an ordinary line, read it as usual - else: - if line is None: # eof - return None - - # still have to be careful about incrementing the line number! - if isinstance(self.current_line, list): - self.current_line = self.current_line[1] + 1 - else: - self.current_line = self.current_line + 1 - - # strip whitespace however the client wants (leading and - # trailing, or one or the other, or neither) - if self.lstrip_ws and self.rstrip_ws: - line = line.strip() - elif self.lstrip_ws: - line = line.lstrip() - elif self.rstrip_ws: - line = line.rstrip() - - # blank line (whether we rstrip'ed or not)? skip to next line - # if appropriate - if (line == '' or line == '\n') and self.skip_blanks: - continue - - if self.join_lines: - if line[-1] == '\\': - buildup_line = line[:-1] - continue - - if line[-2:] == '\\\n': - buildup_line = line[0:-2] + '\n' - continue - - # well, I guess there's some actual content there: return it - return line - - def readlines(self): - """Read and return the list of all logical lines remaining in the - current file.""" - lines = [] - while True: - line = self.readline() - if line is None: - return lines - lines.append(line) - - def unreadline(self, line): - """Push 'line' (a string) onto an internal buffer that will be - checked by future 'readline()' calls. Handy for implementing - a parser with line-at-a-time lookahead.""" - self.linebuf.append(line) diff --git a/python/Lib/distutils/unixccompiler.py b/python/Lib/distutils/unixccompiler.py deleted file mode 100644 index 68bc1a1..0000000 --- a/python/Lib/distutils/unixccompiler.py +++ /dev/null @@ -1,329 +0,0 @@ -"""distutils.unixccompiler - -Contains the UnixCCompiler class, a subclass of CCompiler that handles -the "typical" Unix-style command-line C compiler: - * macros defined with -Dname[=value] - * macros undefined with -Uname - * include search directories specified with -Idir - * libraries specified with -lllib - * library search directories specified with -Ldir - * compile handled by 'cc' (or similar) executable with -c option: - compiles .c to .o - * link static library handled by 'ar' command (possibly with 'ranlib') - * link shared library handled by 'cc -shared' -""" - -import os, sys, re - -from distutils import sysconfig -from distutils.dep_util import newer -from distutils.ccompiler import \ - CCompiler, gen_preprocess_options, gen_lib_options -from distutils.errors import \ - DistutilsExecError, CompileError, LibError, LinkError -from distutils import log - -if sys.platform == 'darwin': - import _osx_support - -# XXX Things not currently handled: -# * optimization/debug/warning flags; we just use whatever's in Python's -# Makefile and live with it. Is this adequate? If not, we might -# have to have a bunch of subclasses GNUCCompiler, SGICCompiler, -# SunCCompiler, and I suspect down that road lies madness. -# * even if we don't know a warning flag from an optimization flag, -# we need some way for outsiders to feed preprocessor/compiler/linker -# flags in to us -- eg. a sysadmin might want to mandate certain flags -# via a site config file, or a user might want to set something for -# compiling this module distribution only via the setup.py command -# line, whatever. As long as these options come from something on the -# current system, they can be as system-dependent as they like, and we -# should just happily stuff them into the preprocessor/compiler/linker -# options and carry on. - - -class UnixCCompiler(CCompiler): - - compiler_type = 'unix' - - # These are used by CCompiler in two places: the constructor sets - # instance attributes 'preprocessor', 'compiler', etc. from them, and - # 'set_executable()' allows any of these to be set. The defaults here - # are pretty generic; they will probably have to be set by an outsider - # (eg. using information discovered by the sysconfig about building - # Python extensions). - executables = {'preprocessor' : None, - 'compiler' : ["cc"], - 'compiler_so' : ["cc"], - 'compiler_cxx' : ["cc"], - 'linker_so' : ["cc", "-shared"], - 'linker_exe' : ["cc"], - 'archiver' : ["ar", "-cr"], - 'ranlib' : None, - } - - if sys.platform[:6] == "darwin": - executables['ranlib'] = ["ranlib"] - - # Needed for the filename generation methods provided by the base - # class, CCompiler. NB. whoever instantiates/uses a particular - # UnixCCompiler instance should set 'shared_lib_ext' -- we set a - # reasonable common default here, but it's not necessarily used on all - # Unices! - - src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"] - obj_extension = ".o" - static_lib_extension = ".a" - shared_lib_extension = ".so" - dylib_lib_extension = ".dylib" - xcode_stub_lib_extension = ".tbd" - static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s" - xcode_stub_lib_format = dylib_lib_format - if sys.platform == "cygwin": - exe_extension = ".exe" - - def preprocess(self, source, output_file=None, macros=None, - include_dirs=None, extra_preargs=None, extra_postargs=None): - fixed_args = self._fix_compile_args(None, macros, include_dirs) - ignore, macros, include_dirs = fixed_args - pp_opts = gen_preprocess_options(macros, include_dirs) - pp_args = self.preprocessor + pp_opts - if output_file: - pp_args.extend(['-o', output_file]) - if extra_preargs: - pp_args[:0] = extra_preargs - if extra_postargs: - pp_args.extend(extra_postargs) - pp_args.append(source) - - # We need to preprocess: either we're being forced to, or we're - # generating output to stdout, or there's a target output file and - # the source file is newer than the target (or the target doesn't - # exist). - if self.force or output_file is None or newer(source, output_file): - if output_file: - self.mkpath(os.path.dirname(output_file)) - try: - self.spawn(pp_args) - except DistutilsExecError as msg: - raise CompileError(msg) - - def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): - compiler_so = self.compiler_so - if sys.platform == 'darwin': - compiler_so = _osx_support.compiler_fixup(compiler_so, - cc_args + extra_postargs) - try: - self.spawn(compiler_so + cc_args + [src, '-o', obj] + - extra_postargs) - except DistutilsExecError as msg: - raise CompileError(msg) - - def create_static_lib(self, objects, output_libname, - output_dir=None, debug=0, target_lang=None): - objects, output_dir = self._fix_object_args(objects, output_dir) - - output_filename = \ - self.library_filename(output_libname, output_dir=output_dir) - - if self._need_link(objects, output_filename): - self.mkpath(os.path.dirname(output_filename)) - self.spawn(self.archiver + - [output_filename] + - objects + self.objects) - - # Not many Unices required ranlib anymore -- SunOS 4.x is, I - # think the only major Unix that does. Maybe we need some - # platform intelligence here to skip ranlib if it's not - # needed -- or maybe Python's configure script took care of - # it for us, hence the check for leading colon. - if self.ranlib: - try: - self.spawn(self.ranlib + [output_filename]) - except DistutilsExecError as msg: - raise LibError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - def link(self, target_desc, objects, - output_filename, output_dir=None, libraries=None, - library_dirs=None, runtime_library_dirs=None, - export_symbols=None, debug=0, extra_preargs=None, - extra_postargs=None, build_temp=None, target_lang=None): - objects, output_dir = self._fix_object_args(objects, output_dir) - fixed_args = self._fix_lib_args(libraries, library_dirs, - runtime_library_dirs) - libraries, library_dirs, runtime_library_dirs = fixed_args - - lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, - libraries) - if not isinstance(output_dir, (str, type(None))): - raise TypeError("'output_dir' must be a string or None") - if output_dir is not None: - output_filename = os.path.join(output_dir, output_filename) - - if self._need_link(objects, output_filename): - ld_args = (objects + self.objects + - lib_opts + ['-o', output_filename]) - if debug: - ld_args[:0] = ['-g'] - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - self.mkpath(os.path.dirname(output_filename)) - try: - if target_desc == CCompiler.EXECUTABLE: - linker = self.linker_exe[:] - else: - linker = self.linker_so[:] - if target_lang == "c++" and self.compiler_cxx: - # skip over environment variable settings if /usr/bin/env - # is used to set up the linker's environment. - # This is needed on OSX. Note: this assumes that the - # normal and C++ compiler have the same environment - # settings. - i = 0 - if os.path.basename(linker[0]) == "env": - i = 1 - while '=' in linker[i]: - i += 1 - - if os.path.basename(linker[i]) == 'ld_so_aix': - # AIX platforms prefix the compiler with the ld_so_aix - # script, so we need to adjust our linker index - offset = 1 - else: - offset = 0 - - linker[i+offset] = self.compiler_cxx[i] - - if sys.platform == 'darwin': - linker = _osx_support.compiler_fixup(linker, ld_args) - - self.spawn(linker + ld_args) - except DistutilsExecError as msg: - raise LinkError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - # -- Miscellaneous methods ----------------------------------------- - # These are all used by the 'gen_lib_options() function, in - # ccompiler.py. - - def library_dir_option(self, dir): - return "-L" + dir - - def _is_gcc(self, compiler_name): - # clang uses same syntax for rpath as gcc - return any(name in compiler_name for name in ("gcc", "g++", "clang")) - - def runtime_library_dir_option(self, dir): - # XXX Hackish, at the very least. See Python bug #445902: - # http://sourceforge.net/tracker/index.php - # ?func=detail&aid=445902&group_id=5470&atid=105470 - # Linkers on different platforms need different options to - # specify that directories need to be added to the list of - # directories searched for dependencies when a dynamic library - # is sought. GCC on GNU systems (Linux, FreeBSD, ...) has to - # be told to pass the -R option through to the linker, whereas - # other compilers and gcc on other systems just know this. - # Other compilers may need something slightly different. At - # this time, there's no way to determine this information from - # the configuration data stored in the Python installation, so - # we use this hack. - compiler = os.path.basename(sysconfig.get_config_var("CC")) - if sys.platform[:6] == "darwin": - # MacOSX's linker doesn't understand the -R flag at all - return "-L" + dir - elif sys.platform[:7] == "freebsd": - return "-Wl,-rpath=" + dir - elif sys.platform[:5] == "hp-ux": - if self._is_gcc(compiler): - return ["-Wl,+s", "-L" + dir] - return ["+s", "-L" + dir] - else: - if self._is_gcc(compiler): - # gcc on non-GNU systems does not need -Wl, but can - # use it anyway. Since distutils has always passed in - # -Wl whenever gcc was used in the past it is probably - # safest to keep doing so. - if sysconfig.get_config_var("GNULD") == "yes": - # GNU ld needs an extra option to get a RUNPATH - # instead of just an RPATH. - return "-Wl,--enable-new-dtags,-R" + dir - else: - return "-Wl,-R" + dir - else: - # No idea how --enable-new-dtags would be passed on to - # ld if this system was using GNU ld. Don't know if a - # system like this even exists. - return "-R" + dir - - def library_option(self, lib): - return "-l" + lib - - def find_library_file(self, dirs, lib, debug=0): - shared_f = self.library_filename(lib, lib_type='shared') - dylib_f = self.library_filename(lib, lib_type='dylib') - xcode_stub_f = self.library_filename(lib, lib_type='xcode_stub') - static_f = self.library_filename(lib, lib_type='static') - - if sys.platform == 'darwin': - # On OSX users can specify an alternate SDK using - # '-isysroot', calculate the SDK root if it is specified - # (and use it further on) - # - # Note that, as of Xcode 7, Apple SDKs may contain textual stub - # libraries with .tbd extensions rather than the normal .dylib - # shared libraries installed in /. The Apple compiler tool - # chain handles this transparently but it can cause problems - # for programs that are being built with an SDK and searching - # for specific libraries. Callers of find_library_file need to - # keep in mind that the base filename of the returned SDK library - # file might have a different extension from that of the library - # file installed on the running system, for example: - # /Applications/Xcode.app/Contents/Developer/Platforms/ - # MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/ - # usr/lib/libedit.tbd - # vs - # /usr/lib/libedit.dylib - cflags = sysconfig.get_config_var('CFLAGS') - m = re.search(r'-isysroot\s*(\S+)', cflags) - if m is None: - sysroot = _osx_support._default_sysroot(sysconfig.get_config_var('CC')) - else: - sysroot = m.group(1) - - - - for dir in dirs: - shared = os.path.join(dir, shared_f) - dylib = os.path.join(dir, dylib_f) - static = os.path.join(dir, static_f) - xcode_stub = os.path.join(dir, xcode_stub_f) - - if sys.platform == 'darwin' and ( - dir.startswith('/System/') or ( - dir.startswith('/usr/') and not dir.startswith('/usr/local/'))): - - shared = os.path.join(sysroot, dir[1:], shared_f) - dylib = os.path.join(sysroot, dir[1:], dylib_f) - static = os.path.join(sysroot, dir[1:], static_f) - xcode_stub = os.path.join(sysroot, dir[1:], xcode_stub_f) - - # We're second-guessing the linker here, with not much hard - # data to go on: GCC seems to prefer the shared library, so I'm - # assuming that *all* Unix C compilers do. And of course I'm - # ignoring even GCC's "-static" option. So sue me. - if os.path.exists(dylib): - return dylib - elif os.path.exists(xcode_stub): - return xcode_stub - elif os.path.exists(shared): - return shared - elif os.path.exists(static): - return static - - # Oops, didn't find it in *any* of 'dirs' - return None diff --git a/python/Lib/distutils/util.py b/python/Lib/distutils/util.py deleted file mode 100644 index cfa5834..0000000 --- a/python/Lib/distutils/util.py +++ /dev/null @@ -1,562 +0,0 @@ -"""distutils.util - -Miscellaneous utility functions -- anything that doesn't fit into -one of the other *util.py modules. -""" - -import os -import re -import importlib.util -import string -import sys -import distutils -from distutils.errors import DistutilsPlatformError -from distutils.dep_util import newer -from distutils.spawn import spawn -from distutils import log -from distutils.errors import DistutilsByteCompileError - -def get_host_platform(): - """Return a string that identifies the current platform. This is used mainly to - distinguish platform-specific build directories and platform-specific built - distributions. Typically includes the OS name and version and the - architecture (as supplied by 'os.uname()'), although the exact information - included depends on the OS; eg. on Linux, the kernel version isn't - particularly important. - - Examples of returned values: - linux-i586 - linux-alpha (?) - solaris-2.6-sun4u - - Windows will return one of: - win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) - win32 (all others - specifically, sys.platform is returned) - - For other non-POSIX platforms, currently just returns 'sys.platform'. - - """ - if os.name == 'nt': - if 'amd64' in sys.version.lower(): - return 'win-amd64' - if '(arm)' in sys.version.lower(): - return 'win-arm32' - if '(arm64)' in sys.version.lower(): - return 'win-arm64' - return sys.platform - - # Set for cross builds explicitly - if "_PYTHON_HOST_PLATFORM" in os.environ: - return os.environ["_PYTHON_HOST_PLATFORM"] - - if os.name != "posix" or not hasattr(os, 'uname'): - # XXX what about the architecture? NT is Intel or Alpha, - # Mac OS is M68k or PPC, etc. - return sys.platform - - # Try to distinguish various flavours of Unix - - (osname, host, release, version, machine) = os.uname() - - # Convert the OS name to lowercase, remove '/' characters, and translate - # spaces (for "Power Macintosh") - osname = osname.lower().replace('/', '') - machine = machine.replace(' ', '_') - machine = machine.replace('/', '-') - - if osname[:5] == "linux": - # At least on Linux/Intel, 'machine' is the processor -- - # i386, etc. - # XXX what about Alpha, SPARC, etc? - return "%s-%s" % (osname, machine) - elif osname[:5] == "sunos": - if release[0] >= "5": # SunOS 5 == Solaris 2 - osname = "solaris" - release = "%d.%s" % (int(release[0]) - 3, release[2:]) - # We can't use "platform.architecture()[0]" because a - # bootstrap problem. We use a dict to get an error - # if some suspicious happens. - bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} - machine += ".%s" % bitness[sys.maxsize] - # fall through to standard osname-release-machine representation - elif osname[:3] == "aix": - from _aix_support import aix_platform - return aix_platform() - elif osname[:6] == "cygwin": - osname = "cygwin" - rel_re = re.compile (r'[\d.]+', re.ASCII) - m = rel_re.match(release) - if m: - release = m.group() - elif osname[:6] == "darwin": - import _osx_support, distutils.sysconfig - osname, release, machine = _osx_support.get_platform_osx( - distutils.sysconfig.get_config_vars(), - osname, release, machine) - - return "%s-%s-%s" % (osname, release, machine) - -def get_platform(): - if os.name == 'nt': - TARGET_TO_PLAT = { - 'x86' : 'win32', - 'x64' : 'win-amd64', - 'arm' : 'win-arm32', - } - return TARGET_TO_PLAT.get(os.environ.get('VSCMD_ARG_TGT_ARCH')) or get_host_platform() - else: - return get_host_platform() - -def convert_path (pathname): - """Return 'pathname' as a name that will work on the native filesystem, - i.e. split it on '/' and put it back together again using the current - directory separator. Needed because filenames in the setup script are - always supplied in Unix style, and have to be converted to the local - convention before we can actually use them in the filesystem. Raises - ValueError on non-Unix-ish systems if 'pathname' either starts or - ends with a slash. - """ - if os.sep == '/': - return pathname - if not pathname: - return pathname - if pathname[0] == '/': - raise ValueError("path '%s' cannot be absolute" % pathname) - if pathname[-1] == '/': - raise ValueError("path '%s' cannot end with '/'" % pathname) - - paths = pathname.split('/') - while '.' in paths: - paths.remove('.') - if not paths: - return os.curdir - return os.path.join(*paths) - -# convert_path () - - -def change_root (new_root, pathname): - """Return 'pathname' with 'new_root' prepended. If 'pathname' is - relative, this is equivalent to "os.path.join(new_root,pathname)". - Otherwise, it requires making 'pathname' relative and then joining the - two, which is tricky on DOS/Windows and Mac OS. - """ - if os.name == 'posix': - if not os.path.isabs(pathname): - return os.path.join(new_root, pathname) - else: - return os.path.join(new_root, pathname[1:]) - - elif os.name == 'nt': - (drive, path) = os.path.splitdrive(pathname) - if path[0] == '\\': - path = path[1:] - return os.path.join(new_root, path) - - else: - raise DistutilsPlatformError("nothing known about platform '%s'" % os.name) - - -_environ_checked = 0 -def check_environ (): - """Ensure that 'os.environ' has all the environment variables we - guarantee that users can use in config files, command-line options, - etc. Currently this includes: - HOME - user's home directory (Unix only) - PLAT - description of the current platform, including hardware - and OS (see 'get_platform()') - """ - global _environ_checked - if _environ_checked: - return - - if os.name == 'posix' and 'HOME' not in os.environ: - try: - import pwd - os.environ['HOME'] = pwd.getpwuid(os.getuid())[5] - except (ImportError, KeyError): - # bpo-10496: if the current user identifier doesn't exist in the - # password database, do nothing - pass - - if 'PLAT' not in os.environ: - os.environ['PLAT'] = get_platform() - - _environ_checked = 1 - - -def subst_vars (s, local_vars): - """Perform shell/Perl-style variable substitution on 'string'. Every - occurrence of '$' followed by a name is considered a variable, and - variable is substituted by the value found in the 'local_vars' - dictionary, or in 'os.environ' if it's not in 'local_vars'. - 'os.environ' is first checked/augmented to guarantee that it contains - certain values: see 'check_environ()'. Raise ValueError for any - variables not found in either 'local_vars' or 'os.environ'. - """ - check_environ() - def _subst (match, local_vars=local_vars): - var_name = match.group(1) - if var_name in local_vars: - return str(local_vars[var_name]) - else: - return os.environ[var_name] - - try: - return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s) - except KeyError as var: - raise ValueError("invalid variable '$%s'" % var) - -# subst_vars () - - -def grok_environment_error (exc, prefix="error: "): - # Function kept for backward compatibility. - # Used to try clever things with EnvironmentErrors, - # but nowadays str(exception) produces good messages. - return prefix + str(exc) - - -# Needed by 'split_quoted()' -_wordchars_re = _squote_re = _dquote_re = None -def _init_regex(): - global _wordchars_re, _squote_re, _dquote_re - _wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace) - _squote_re = re.compile(r"'(?:[^'\\]|\\.)*'") - _dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"') - -def split_quoted (s): - """Split a string up according to Unix shell-like rules for quotes and - backslashes. In short: words are delimited by spaces, as long as those - spaces are not escaped by a backslash, or inside a quoted string. - Single and double quotes are equivalent, and the quote characters can - be backslash-escaped. The backslash is stripped from any two-character - escape sequence, leaving only the escaped character. The quote - characters are stripped from any quoted string. Returns a list of - words. - """ - - # This is a nice algorithm for splitting up a single string, since it - # doesn't require character-by-character examination. It was a little - # bit of a brain-bender to get it working right, though... - if _wordchars_re is None: _init_regex() - - s = s.strip() - words = [] - pos = 0 - - while s: - m = _wordchars_re.match(s, pos) - end = m.end() - if end == len(s): - words.append(s[:end]) - break - - if s[end] in string.whitespace: # unescaped, unquoted whitespace: now - words.append(s[:end]) # we definitely have a word delimiter - s = s[end:].lstrip() - pos = 0 - - elif s[end] == '\\': # preserve whatever is being escaped; - # will become part of the current word - s = s[:end] + s[end+1:] - pos = end+1 - - else: - if s[end] == "'": # slurp singly-quoted string - m = _squote_re.match(s, end) - elif s[end] == '"': # slurp doubly-quoted string - m = _dquote_re.match(s, end) - else: - raise RuntimeError("this can't happen (bad char '%c')" % s[end]) - - if m is None: - raise ValueError("bad string (mismatched %s quotes?)" % s[end]) - - (beg, end) = m.span() - s = s[:beg] + s[beg+1:end-1] + s[end:] - pos = m.end() - 2 - - if pos >= len(s): - words.append(s) - break - - return words - -# split_quoted () - - -def execute (func, args, msg=None, verbose=0, dry_run=0): - """Perform some action that affects the outside world (eg. by - writing to the filesystem). Such actions are special because they - are disabled by the 'dry_run' flag. This method takes care of all - that bureaucracy for you; all you have to do is supply the - function to call and an argument tuple for it (to embody the - "external action" being performed), and an optional message to - print. - """ - if msg is None: - msg = "%s%r" % (func.__name__, args) - if msg[-2:] == ',)': # correct for singleton tuple - msg = msg[0:-2] + ')' - - log.info(msg) - if not dry_run: - func(*args) - - -def strtobool (val): - """Convert a string representation of truth to true (1) or false (0). - - True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values - are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if - 'val' is anything else. - """ - val = val.lower() - if val in ('y', 'yes', 't', 'true', 'on', '1'): - return 1 - elif val in ('n', 'no', 'f', 'false', 'off', '0'): - return 0 - else: - raise ValueError("invalid truth value %r" % (val,)) - - -def byte_compile (py_files, - optimize=0, force=0, - prefix=None, base_dir=None, - verbose=1, dry_run=0, - direct=None): - """Byte-compile a collection of Python source files to .pyc - files in a __pycache__ subdirectory. 'py_files' is a list - of files to compile; any files that don't end in ".py" are silently - skipped. 'optimize' must be one of the following: - 0 - don't optimize - 1 - normal optimization (like "python -O") - 2 - extra optimization (like "python -OO") - If 'force' is true, all files are recompiled regardless of - timestamps. - - The source filename encoded in each bytecode file defaults to the - filenames listed in 'py_files'; you can modify these with 'prefix' and - 'basedir'. 'prefix' is a string that will be stripped off of each - source filename, and 'base_dir' is a directory name that will be - prepended (after 'prefix' is stripped). You can supply either or both - (or neither) of 'prefix' and 'base_dir', as you wish. - - If 'dry_run' is true, doesn't actually do anything that would - affect the filesystem. - - Byte-compilation is either done directly in this interpreter process - with the standard py_compile module, or indirectly by writing a - temporary script and executing it. Normally, you should let - 'byte_compile()' figure out to use direct compilation or not (see - the source for details). The 'direct' flag is used by the script - generated in indirect mode; unless you know what you're doing, leave - it set to None. - """ - - # Late import to fix a bootstrap issue: _posixsubprocess is built by - # setup.py, but setup.py uses distutils. - import subprocess - - # nothing is done if sys.dont_write_bytecode is True - if sys.dont_write_bytecode: - raise DistutilsByteCompileError('byte-compiling is disabled.') - - # First, if the caller didn't force us into direct or indirect mode, - # figure out which mode we should be in. We take a conservative - # approach: choose direct mode *only* if the current interpreter is - # in debug mode and optimize is 0. If we're not in debug mode (-O - # or -OO), we don't know which level of optimization this - # interpreter is running with, so we can't do direct - # byte-compilation and be certain that it's the right thing. Thus, - # always compile indirectly if the current interpreter is in either - # optimize mode, or if either optimization level was requested by - # the caller. - if direct is None: - direct = (__debug__ and optimize == 0) - - # "Indirect" byte-compilation: write a temporary script and then - # run it with the appropriate flags. - if not direct: - try: - from tempfile import mkstemp - (script_fd, script_name) = mkstemp(".py") - except ImportError: - from tempfile import mktemp - (script_fd, script_name) = None, mktemp(".py") - log.info("writing byte-compilation script '%s'", script_name) - if not dry_run: - if script_fd is not None: - script = os.fdopen(script_fd, "w") - else: - script = open(script_name, "w") - - with script: - script.write("""\ -from distutils.util import byte_compile -files = [ -""") - - # XXX would be nice to write absolute filenames, just for - # safety's sake (script should be more robust in the face of - # chdir'ing before running it). But this requires abspath'ing - # 'prefix' as well, and that breaks the hack in build_lib's - # 'byte_compile()' method that carefully tacks on a trailing - # slash (os.sep really) to make sure the prefix here is "just - # right". This whole prefix business is rather delicate -- the - # problem is that it's really a directory, but I'm treating it - # as a dumb string, so trailing slashes and so forth matter. - - #py_files = map(os.path.abspath, py_files) - #if prefix: - # prefix = os.path.abspath(prefix) - - script.write(",\n".join(map(repr, py_files)) + "]\n") - script.write(""" -byte_compile(files, optimize=%r, force=%r, - prefix=%r, base_dir=%r, - verbose=%r, dry_run=0, - direct=1) -""" % (optimize, force, prefix, base_dir, verbose)) - - msg = distutils._DEPRECATION_MESSAGE - cmd = [sys.executable] - cmd.extend(subprocess._optim_args_from_interpreter_flags()) - cmd.append(f'-Wignore:{msg}:DeprecationWarning') - cmd.append(script_name) - spawn(cmd, dry_run=dry_run) - execute(os.remove, (script_name,), "removing %s" % script_name, - dry_run=dry_run) - - # "Direct" byte-compilation: use the py_compile module to compile - # right here, right now. Note that the script generated in indirect - # mode simply calls 'byte_compile()' in direct mode, a weird sort of - # cross-process recursion. Hey, it works! - else: - from py_compile import compile - - for file in py_files: - if file[-3:] != ".py": - # This lets us be lazy and not filter filenames in - # the "install_lib" command. - continue - - # Terminology from the py_compile module: - # cfile - byte-compiled file - # dfile - purported source filename (same as 'file' by default) - if optimize >= 0: - opt = '' if optimize == 0 else optimize - cfile = importlib.util.cache_from_source( - file, optimization=opt) - else: - cfile = importlib.util.cache_from_source(file) - dfile = file - if prefix: - if file[:len(prefix)] != prefix: - raise ValueError("invalid prefix: filename %r doesn't start with %r" - % (file, prefix)) - dfile = dfile[len(prefix):] - if base_dir: - dfile = os.path.join(base_dir, dfile) - - cfile_base = os.path.basename(cfile) - if direct: - if force or newer(file, cfile): - log.info("byte-compiling %s to %s", file, cfile_base) - if not dry_run: - compile(file, cfile, dfile) - else: - log.debug("skipping byte-compilation of %s to %s", - file, cfile_base) - -# byte_compile () - -def rfc822_escape (header): - """Return a version of the string escaped for inclusion in an - RFC-822 header, by ensuring there are 8 spaces space after each newline. - """ - lines = header.split('\n') - sep = '\n' + 8 * ' ' - return sep.join(lines) - -# 2to3 support - -def run_2to3(files, fixer_names=None, options=None, explicit=None): - """Invoke 2to3 on a list of Python files. - The files should all come from the build area, as the - modification is done in-place. To reduce the build time, - only files modified since the last invocation of this - function should be passed in the files argument.""" - - if not files: - return - - # Make this class local, to delay import of 2to3 - from lib2to3.refactor import RefactoringTool, get_fixers_from_package - class DistutilsRefactoringTool(RefactoringTool): - def log_error(self, msg, *args, **kw): - log.error(msg, *args) - - def log_message(self, msg, *args): - log.info(msg, *args) - - def log_debug(self, msg, *args): - log.debug(msg, *args) - - if fixer_names is None: - fixer_names = get_fixers_from_package('lib2to3.fixes') - r = DistutilsRefactoringTool(fixer_names, options=options) - r.refactor(files, write=True) - -def copydir_run_2to3(src, dest, template=None, fixer_names=None, - options=None, explicit=None): - """Recursively copy a directory, only copying new and changed files, - running run_2to3 over all newly copied Python modules afterward. - - If you give a template string, it's parsed like a MANIFEST.in. - """ - from distutils.dir_util import mkpath - from distutils.file_util import copy_file - from distutils.filelist import FileList - filelist = FileList() - curdir = os.getcwd() - os.chdir(src) - try: - filelist.findall() - finally: - os.chdir(curdir) - filelist.files[:] = filelist.allfiles - if template: - for line in template.splitlines(): - line = line.strip() - if not line: continue - filelist.process_template_line(line) - copied = [] - for filename in filelist.files: - outname = os.path.join(dest, filename) - mkpath(os.path.dirname(outname)) - res = copy_file(os.path.join(src, filename), outname, update=1) - if res[1]: copied.append(outname) - run_2to3([fn for fn in copied if fn.lower().endswith('.py')], - fixer_names=fixer_names, options=options, explicit=explicit) - return copied - -class Mixin2to3: - '''Mixin class for commands that run 2to3. - To configure 2to3, setup scripts may either change - the class variables, or inherit from individual commands - to override how 2to3 is invoked.''' - - # provide list of fixers to run; - # defaults to all from lib2to3.fixers - fixer_names = None - - # options dictionary - options = None - - # list of fixers to invoke even though they are marked as explicit - explicit = None - - def run_2to3(self, files): - return run_2to3(files, self.fixer_names, self.options, self.explicit) diff --git a/python/Lib/distutils/version.py b/python/Lib/distutils/version.py deleted file mode 100644 index 3e70625..0000000 --- a/python/Lib/distutils/version.py +++ /dev/null @@ -1,347 +0,0 @@ -# -# distutils/version.py -# -# Implements multiple version numbering conventions for the -# Python Module Distribution Utilities. -# -# $Id$ -# - -"""Provides classes to represent module version numbers (one class for -each style of version numbering). There are currently two such classes -implemented: StrictVersion and LooseVersion. - -Every version number class implements the following interface: - * the 'parse' method takes a string and parses it to some internal - representation; if the string is an invalid version number, - 'parse' raises a ValueError exception - * the class constructor takes an optional string argument which, - if supplied, is passed to 'parse' - * __str__ reconstructs the string that was passed to 'parse' (or - an equivalent string -- ie. one that will generate an equivalent - version number instance) - * __repr__ generates Python code to recreate the version number instance - * _cmp compares the current instance with either another instance - of the same class or a string (which will be parsed to an instance - of the same class, thus must follow the same rules) -""" - -import re - -class Version: - """Abstract base class for version numbering classes. Just provides - constructor (__init__) and reproducer (__repr__), because those - seem to be the same for all version numbering classes; and route - rich comparisons to _cmp. - """ - - def __init__ (self, vstring=None): - if vstring: - self.parse(vstring) - - def __repr__ (self): - return "%s ('%s')" % (self.__class__.__name__, str(self)) - - def __eq__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c == 0 - - def __lt__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c < 0 - - def __le__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c <= 0 - - def __gt__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c > 0 - - def __ge__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c >= 0 - - -# Interface for version-number classes -- must be implemented -# by the following classes (the concrete ones -- Version should -# be treated as an abstract class). -# __init__ (string) - create and take same action as 'parse' -# (string parameter is optional) -# parse (string) - convert a string representation to whatever -# internal representation is appropriate for -# this style of version numbering -# __str__ (self) - convert back to a string; should be very similar -# (if not identical to) the string supplied to parse -# __repr__ (self) - generate Python code to recreate -# the instance -# _cmp (self, other) - compare two version numbers ('other' may -# be an unparsed version string, or another -# instance of your version class) - - -class StrictVersion (Version): - - """Version numbering for anal retentives and software idealists. - Implements the standard interface for version number classes as - described above. A version number consists of two or three - dot-separated numeric components, with an optional "pre-release" tag - on the end. The pre-release tag consists of the letter 'a' or 'b' - followed by a number. If the numeric components of two version - numbers are equal, then one with a pre-release tag will always - be deemed earlier (lesser) than one without. - - The following are valid version numbers (shown in the order that - would be obtained by sorting according to the supplied cmp function): - - 0.4 0.4.0 (these two are equivalent) - 0.4.1 - 0.5a1 - 0.5b3 - 0.5 - 0.9.6 - 1.0 - 1.0.4a3 - 1.0.4b1 - 1.0.4 - - The following are examples of invalid version numbers: - - 1 - 2.7.2.2 - 1.3.a4 - 1.3pl1 - 1.3c4 - - The rationale for this version numbering system will be explained - in the distutils documentation. - """ - - version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$', - re.VERBOSE | re.ASCII) - - - def parse (self, vstring): - match = self.version_re.match(vstring) - if not match: - raise ValueError("invalid version number '%s'" % vstring) - - (major, minor, patch, prerelease, prerelease_num) = \ - match.group(1, 2, 4, 5, 6) - - if patch: - self.version = tuple(map(int, [major, minor, patch])) - else: - self.version = tuple(map(int, [major, minor])) + (0,) - - if prerelease: - self.prerelease = (prerelease[0], int(prerelease_num)) - else: - self.prerelease = None - - - def __str__ (self): - - if self.version[2] == 0: - vstring = '.'.join(map(str, self.version[0:2])) - else: - vstring = '.'.join(map(str, self.version)) - - if self.prerelease: - vstring = vstring + self.prerelease[0] + str(self.prerelease[1]) - - return vstring - - - def _cmp (self, other): - if isinstance(other, str): - other = StrictVersion(other) - elif not isinstance(other, StrictVersion): - return NotImplemented - - if self.version != other.version: - # numeric versions don't match - # prerelease stuff doesn't matter - if self.version < other.version: - return -1 - else: - return 1 - - # have to compare prerelease - # case 1: neither has prerelease; they're equal - # case 2: self has prerelease, other doesn't; other is greater - # case 3: self doesn't have prerelease, other does: self is greater - # case 4: both have prerelease: must compare them! - - if (not self.prerelease and not other.prerelease): - return 0 - elif (self.prerelease and not other.prerelease): - return -1 - elif (not self.prerelease and other.prerelease): - return 1 - elif (self.prerelease and other.prerelease): - if self.prerelease == other.prerelease: - return 0 - elif self.prerelease < other.prerelease: - return -1 - else: - return 1 - else: - assert False, "never get here" - -# end class StrictVersion - - -# The rules according to Greg Stein: -# 1) a version number has 1 or more numbers separated by a period or by -# sequences of letters. If only periods, then these are compared -# left-to-right to determine an ordering. -# 2) sequences of letters are part of the tuple for comparison and are -# compared lexicographically -# 3) recognize the numeric components may have leading zeroes -# -# The LooseVersion class below implements these rules: a version number -# string is split up into a tuple of integer and string components, and -# comparison is a simple tuple comparison. This means that version -# numbers behave in a predictable and obvious way, but a way that might -# not necessarily be how people *want* version numbers to behave. There -# wouldn't be a problem if people could stick to purely numeric version -# numbers: just split on period and compare the numbers as tuples. -# However, people insist on putting letters into their version numbers; -# the most common purpose seems to be: -# - indicating a "pre-release" version -# ('alpha', 'beta', 'a', 'b', 'pre', 'p') -# - indicating a post-release patch ('p', 'pl', 'patch') -# but of course this can't cover all version number schemes, and there's -# no way to know what a programmer means without asking him. -# -# The problem is what to do with letters (and other non-numeric -# characters) in a version number. The current implementation does the -# obvious and predictable thing: keep them as strings and compare -# lexically within a tuple comparison. This has the desired effect if -# an appended letter sequence implies something "post-release": -# eg. "0.99" < "0.99pl14" < "1.0", and "5.001" < "5.001m" < "5.002". -# -# However, if letters in a version number imply a pre-release version, -# the "obvious" thing isn't correct. Eg. you would expect that -# "1.5.1" < "1.5.2a2" < "1.5.2", but under the tuple/lexical comparison -# implemented here, this just isn't so. -# -# Two possible solutions come to mind. The first is to tie the -# comparison algorithm to a particular set of semantic rules, as has -# been done in the StrictVersion class above. This works great as long -# as everyone can go along with bondage and discipline. Hopefully a -# (large) subset of Python module programmers will agree that the -# particular flavour of bondage and discipline provided by StrictVersion -# provides enough benefit to be worth using, and will submit their -# version numbering scheme to its domination. The free-thinking -# anarchists in the lot will never give in, though, and something needs -# to be done to accommodate them. -# -# Perhaps a "moderately strict" version class could be implemented that -# lets almost anything slide (syntactically), and makes some heuristic -# assumptions about non-digits in version number strings. This could -# sink into special-case-hell, though; if I was as talented and -# idiosyncratic as Larry Wall, I'd go ahead and implement a class that -# somehow knows that "1.2.1" < "1.2.2a2" < "1.2.2" < "1.2.2pl3", and is -# just as happy dealing with things like "2g6" and "1.13++". I don't -# think I'm smart enough to do it right though. -# -# In any case, I've coded the test suite for this module (see -# ../test/test_version.py) specifically to fail on things like comparing -# "1.2a2" and "1.2". That's not because the *code* is doing anything -# wrong, it's because the simple, obvious design doesn't match my -# complicated, hairy expectations for real-world version numbers. It -# would be a snap to fix the test suite to say, "Yep, LooseVersion does -# the Right Thing" (ie. the code matches the conception). But I'd rather -# have a conception that matches common notions about version numbers. - -class LooseVersion (Version): - - """Version numbering for anarchists and software realists. - Implements the standard interface for version number classes as - described above. A version number consists of a series of numbers, - separated by either periods or strings of letters. When comparing - version numbers, the numeric components will be compared - numerically, and the alphabetic components lexically. The following - are all valid version numbers, in no particular order: - - 1.5.1 - 1.5.2b2 - 161 - 3.10a - 8.02 - 3.4j - 1996.07.12 - 3.2.pl0 - 3.1.1.6 - 2g6 - 11g - 0.960923 - 2.2beta29 - 1.13++ - 5.5.kw - 2.0b1pl0 - - In fact, there is no such thing as an invalid version number under - this scheme; the rules for comparison are simple and predictable, - but may not always give the results you want (for some definition - of "want"). - """ - - component_re = re.compile(r'(\d+ | [a-z]+ | \.)', re.VERBOSE) - - def __init__ (self, vstring=None): - if vstring: - self.parse(vstring) - - - def parse (self, vstring): - # I've given up on thinking I can reconstruct the version string - # from the parsed tuple -- so I just store the string here for - # use by __str__ - self.vstring = vstring - components = [x for x in self.component_re.split(vstring) - if x and x != '.'] - for i, obj in enumerate(components): - try: - components[i] = int(obj) - except ValueError: - pass - - self.version = components - - - def __str__ (self): - return self.vstring - - - def __repr__ (self): - return "LooseVersion ('%s')" % str(self) - - - def _cmp (self, other): - if isinstance(other, str): - other = LooseVersion(other) - elif not isinstance(other, LooseVersion): - return NotImplemented - - if self.version == other.version: - return 0 - if self.version < other.version: - return -1 - if self.version > other.version: - return 1 - - -# end class LooseVersion diff --git a/python/Lib/distutils/versionpredicate.py b/python/Lib/distutils/versionpredicate.py deleted file mode 100644 index db1759c..0000000 --- a/python/Lib/distutils/versionpredicate.py +++ /dev/null @@ -1,166 +0,0 @@ -"""Module for parsing and testing package version predicate strings. -""" -import re -import distutils.version -import operator - - -re_validPackage = re.compile(r"(?i)^\s*([a-z_]\w*(?:\.[a-z_]\w*)*)(.*)", - re.ASCII) -# (package) (rest) - -re_paren = re.compile(r"^\s*\((.*)\)\s*$") # (list) inside of parentheses -re_splitComparison = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$") -# (comp) (version) - - -def splitUp(pred): - """Parse a single version comparison. - - Return (comparison string, StrictVersion) - """ - res = re_splitComparison.match(pred) - if not res: - raise ValueError("bad package restriction syntax: %r" % pred) - comp, verStr = res.groups() - return (comp, distutils.version.StrictVersion(verStr)) - -compmap = {"<": operator.lt, "<=": operator.le, "==": operator.eq, - ">": operator.gt, ">=": operator.ge, "!=": operator.ne} - -class VersionPredicate: - """Parse and test package version predicates. - - >>> v = VersionPredicate('pyepat.abc (>1.0, <3333.3a1, !=1555.1b3)') - - The `name` attribute provides the full dotted name that is given:: - - >>> v.name - 'pyepat.abc' - - The str() of a `VersionPredicate` provides a normalized - human-readable version of the expression:: - - >>> print(v) - pyepat.abc (> 1.0, < 3333.3a1, != 1555.1b3) - - The `satisfied_by()` method can be used to determine with a given - version number is included in the set described by the version - restrictions:: - - >>> v.satisfied_by('1.1') - True - >>> v.satisfied_by('1.4') - True - >>> v.satisfied_by('1.0') - False - >>> v.satisfied_by('4444.4') - False - >>> v.satisfied_by('1555.1b3') - False - - `VersionPredicate` is flexible in accepting extra whitespace:: - - >>> v = VersionPredicate(' pat( == 0.1 ) ') - >>> v.name - 'pat' - >>> v.satisfied_by('0.1') - True - >>> v.satisfied_by('0.2') - False - - If any version numbers passed in do not conform to the - restrictions of `StrictVersion`, a `ValueError` is raised:: - - >>> v = VersionPredicate('p1.p2.p3.p4(>=1.0, <=1.3a1, !=1.2zb3)') - Traceback (most recent call last): - ... - ValueError: invalid version number '1.2zb3' - - It the module or package name given does not conform to what's - allowed as a legal module or package name, `ValueError` is - raised:: - - >>> v = VersionPredicate('foo-bar') - Traceback (most recent call last): - ... - ValueError: expected parenthesized list: '-bar' - - >>> v = VersionPredicate('foo bar (12.21)') - Traceback (most recent call last): - ... - ValueError: expected parenthesized list: 'bar (12.21)' - - """ - - def __init__(self, versionPredicateStr): - """Parse a version predicate string. - """ - # Fields: - # name: package name - # pred: list of (comparison string, StrictVersion) - - versionPredicateStr = versionPredicateStr.strip() - if not versionPredicateStr: - raise ValueError("empty package restriction") - match = re_validPackage.match(versionPredicateStr) - if not match: - raise ValueError("bad package name in %r" % versionPredicateStr) - self.name, paren = match.groups() - paren = paren.strip() - if paren: - match = re_paren.match(paren) - if not match: - raise ValueError("expected parenthesized list: %r" % paren) - str = match.groups()[0] - self.pred = [splitUp(aPred) for aPred in str.split(",")] - if not self.pred: - raise ValueError("empty parenthesized list in %r" - % versionPredicateStr) - else: - self.pred = [] - - def __str__(self): - if self.pred: - seq = [cond + " " + str(ver) for cond, ver in self.pred] - return self.name + " (" + ", ".join(seq) + ")" - else: - return self.name - - def satisfied_by(self, version): - """True if version is compatible with all the predicates in self. - The parameter version must be acceptable to the StrictVersion - constructor. It may be either a string or StrictVersion. - """ - for cond, ver in self.pred: - if not compmap[cond](version, ver): - return False - return True - - -_provision_rx = None - -def split_provision(value): - """Return the name and optional version number of a provision. - - The version number, if given, will be returned as a `StrictVersion` - instance, otherwise it will be `None`. - - >>> split_provision('mypkg') - ('mypkg', None) - >>> split_provision(' mypkg( 1.2 ) ') - ('mypkg', StrictVersion ('1.2')) - """ - global _provision_rx - if _provision_rx is None: - _provision_rx = re.compile( - r"([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)(?:\s*\(\s*([^)\s]+)\s*\))?$", - re.ASCII) - value = value.strip() - m = _provision_rx.match(value) - if not m: - raise ValueError("illegal provides specification: %r" % value) - ver = m.group(2) or None - if ver: - ver = distutils.version.StrictVersion(ver) - return m.group(1), ver diff --git a/python/Lib/doctest.py b/python/Lib/doctest.py deleted file mode 100644 index 8829e79..0000000 --- a/python/Lib/doctest.py +++ /dev/null @@ -1,2810 +0,0 @@ -# Module doctest. -# Released to the public domain 16-Jan-2001, by Tim Peters (tim@python.org). -# Major enhancements and refactoring by: -# Jim Fulton -# Edward Loper - -# Provided as-is; use at your own risk; no warranty; no promises; enjoy! - -r"""Module doctest -- a framework for running examples in docstrings. - -In simplest use, end each module M to be tested with: - -def _test(): - import doctest - doctest.testmod() - -if __name__ == "__main__": - _test() - -Then running the module as a script will cause the examples in the -docstrings to get executed and verified: - -python M.py - -This won't display anything unless an example fails, in which case the -failing example(s) and the cause(s) of the failure(s) are printed to stdout -(why not stderr? because stderr is a lame hack <0.2 wink>), and the final -line of output is "Test failed.". - -Run it with the -v switch instead: - -python M.py -v - -and a detailed report of all examples tried is printed to stdout, along -with assorted summaries at the end. - -You can force verbose mode by passing "verbose=True" to testmod, or prohibit -it by passing "verbose=False". In either of those cases, sys.argv is not -examined by testmod. - -There are a variety of other ways to run doctests, including integration -with the unittest framework, and support for running non-Python text -files containing doctests. There are also many ways to override parts -of doctest's default behaviors. See the Library Reference Manual for -details. -""" - -__docformat__ = 'reStructuredText en' - -__all__ = [ - # 0, Option Flags - 'register_optionflag', - 'DONT_ACCEPT_TRUE_FOR_1', - 'DONT_ACCEPT_BLANKLINE', - 'NORMALIZE_WHITESPACE', - 'ELLIPSIS', - 'SKIP', - 'IGNORE_EXCEPTION_DETAIL', - 'COMPARISON_FLAGS', - 'REPORT_UDIFF', - 'REPORT_CDIFF', - 'REPORT_NDIFF', - 'REPORT_ONLY_FIRST_FAILURE', - 'REPORTING_FLAGS', - 'FAIL_FAST', - # 1. Utility Functions - # 2. Example & DocTest - 'Example', - 'DocTest', - # 3. Doctest Parser - 'DocTestParser', - # 4. Doctest Finder - 'DocTestFinder', - # 5. Doctest Runner - 'DocTestRunner', - 'OutputChecker', - 'DocTestFailure', - 'UnexpectedException', - 'DebugRunner', - # 6. Test Functions - 'testmod', - 'testfile', - 'run_docstring_examples', - # 7. Unittest Support - 'DocTestSuite', - 'DocFileSuite', - 'set_unittest_reportflags', - # 8. Debugging Support - 'script_from_examples', - 'testsource', - 'debug_src', - 'debug', -] - -import __future__ -import difflib -import inspect -import linecache -import os -import pdb -import re -import sys -import traceback -import unittest -from io import StringIO, IncrementalNewlineDecoder -from collections import namedtuple - -TestResults = namedtuple('TestResults', 'failed attempted') - -# There are 4 basic classes: -# - Example: a pair, plus an intra-docstring line number. -# - DocTest: a collection of examples, parsed from a docstring, plus -# info about where the docstring came from (name, filename, lineno). -# - DocTestFinder: extracts DocTests from a given object's docstring and -# its contained objects' docstrings. -# - DocTestRunner: runs DocTest cases, and accumulates statistics. -# -# So the basic picture is: -# -# list of: -# +------+ +---------+ +-------+ -# |object| --DocTestFinder-> | DocTest | --DocTestRunner-> |results| -# +------+ +---------+ +-------+ -# | Example | -# | ... | -# | Example | -# +---------+ - -# Option constants. - -OPTIONFLAGS_BY_NAME = {} -def register_optionflag(name): - # Create a new flag unless `name` is already known. - return OPTIONFLAGS_BY_NAME.setdefault(name, 1 << len(OPTIONFLAGS_BY_NAME)) - -DONT_ACCEPT_TRUE_FOR_1 = register_optionflag('DONT_ACCEPT_TRUE_FOR_1') -DONT_ACCEPT_BLANKLINE = register_optionflag('DONT_ACCEPT_BLANKLINE') -NORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE') -ELLIPSIS = register_optionflag('ELLIPSIS') -SKIP = register_optionflag('SKIP') -IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL') - -COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 | - DONT_ACCEPT_BLANKLINE | - NORMALIZE_WHITESPACE | - ELLIPSIS | - SKIP | - IGNORE_EXCEPTION_DETAIL) - -REPORT_UDIFF = register_optionflag('REPORT_UDIFF') -REPORT_CDIFF = register_optionflag('REPORT_CDIFF') -REPORT_NDIFF = register_optionflag('REPORT_NDIFF') -REPORT_ONLY_FIRST_FAILURE = register_optionflag('REPORT_ONLY_FIRST_FAILURE') -FAIL_FAST = register_optionflag('FAIL_FAST') - -REPORTING_FLAGS = (REPORT_UDIFF | - REPORT_CDIFF | - REPORT_NDIFF | - REPORT_ONLY_FIRST_FAILURE | - FAIL_FAST) - -# Special string markers for use in `want` strings: -BLANKLINE_MARKER = '' -ELLIPSIS_MARKER = '...' - -###################################################################### -## Table of Contents -###################################################################### -# 1. Utility Functions -# 2. Example & DocTest -- store test cases -# 3. DocTest Parser -- extracts examples from strings -# 4. DocTest Finder -- extracts test cases from objects -# 5. DocTest Runner -- runs test cases -# 6. Test Functions -- convenient wrappers for testing -# 7. Unittest Support -# 8. Debugging Support -# 9. Example Usage - -###################################################################### -## 1. Utility Functions -###################################################################### - -def _extract_future_flags(globs): - """ - Return the compiler-flags associated with the future features that - have been imported into the given namespace (globs). - """ - flags = 0 - for fname in __future__.all_feature_names: - feature = globs.get(fname, None) - if feature is getattr(__future__, fname): - flags |= feature.compiler_flag - return flags - -def _normalize_module(module, depth=2): - """ - Return the module specified by `module`. In particular: - - If `module` is a module, then return module. - - If `module` is a string, then import and return the - module with that name. - - If `module` is None, then return the calling module. - The calling module is assumed to be the module of - the stack frame at the given depth in the call stack. - """ - if inspect.ismodule(module): - return module - elif isinstance(module, str): - return __import__(module, globals(), locals(), ["*"]) - elif module is None: - return sys.modules[sys._getframe(depth).f_globals['__name__']] - else: - raise TypeError("Expected a module, string, or None") - -def _newline_convert(data): - # The IO module provides a handy decoder for universal newline conversion - return IncrementalNewlineDecoder(None, True).decode(data, True) - -def _load_testfile(filename, package, module_relative, encoding): - if module_relative: - package = _normalize_module(package, 3) - filename = _module_relative_path(package, filename) - if (loader := getattr(package, '__loader__', None)) is None: - try: - loader = package.__spec__.loader - except AttributeError: - pass - if hasattr(loader, 'get_data'): - file_contents = loader.get_data(filename) - file_contents = file_contents.decode(encoding) - # get_data() opens files as 'rb', so one must do the equivalent - # conversion as universal newlines would do. - return _newline_convert(file_contents), filename - with open(filename, encoding=encoding) as f: - return f.read(), filename - -def _indent(s, indent=4): - """ - Add the given number of space characters to the beginning of - every non-blank line in `s`, and return the result. - """ - # This regexp matches the start of non-blank lines: - return re.sub('(?m)^(?!$)', indent*' ', s) - -def _exception_traceback(exc_info): - """ - Return a string containing a traceback message for the given - exc_info tuple (as returned by sys.exc_info()). - """ - # Get a traceback message. - excout = StringIO() - exc_type, exc_val, exc_tb = exc_info - traceback.print_exception(exc_type, exc_val, exc_tb, file=excout) - return excout.getvalue() - -# Override some StringIO methods. -class _SpoofOut(StringIO): - def getvalue(self): - result = StringIO.getvalue(self) - # If anything at all was written, make sure there's a trailing - # newline. There's no way for the expected output to indicate - # that a trailing newline is missing. - if result and not result.endswith("\n"): - result += "\n" - return result - - def truncate(self, size=None): - self.seek(size) - StringIO.truncate(self) - -# Worst-case linear-time ellipsis matching. -def _ellipsis_match(want, got): - """ - Essentially the only subtle case: - >>> _ellipsis_match('aa...aa', 'aaa') - False - """ - if ELLIPSIS_MARKER not in want: - return want == got - - # Find "the real" strings. - ws = want.split(ELLIPSIS_MARKER) - assert len(ws) >= 2 - - # Deal with exact matches possibly needed at one or both ends. - startpos, endpos = 0, len(got) - w = ws[0] - if w: # starts with exact match - if got.startswith(w): - startpos = len(w) - del ws[0] - else: - return False - w = ws[-1] - if w: # ends with exact match - if got.endswith(w): - endpos -= len(w) - del ws[-1] - else: - return False - - if startpos > endpos: - # Exact end matches required more characters than we have, as in - # _ellipsis_match('aa...aa', 'aaa') - return False - - # For the rest, we only need to find the leftmost non-overlapping - # match for each piece. If there's no overall match that way alone, - # there's no overall match period. - for w in ws: - # w may be '' at times, if there are consecutive ellipses, or - # due to an ellipsis at the start or end of `want`. That's OK. - # Search for an empty string succeeds, and doesn't change startpos. - startpos = got.find(w, startpos, endpos) - if startpos < 0: - return False - startpos += len(w) - - return True - -def _comment_line(line): - "Return a commented form of the given line" - line = line.rstrip() - if line: - return '# '+line - else: - return '#' - -def _strip_exception_details(msg): - # Support for IGNORE_EXCEPTION_DETAIL. - # Get rid of everything except the exception name; in particular, drop - # the possibly dotted module path (if any) and the exception message (if - # any). We assume that a colon is never part of a dotted name, or of an - # exception name. - # E.g., given - # "foo.bar.MyError: la di da" - # return "MyError" - # Or for "abc.def" or "abc.def:\n" return "def". - - start, end = 0, len(msg) - # The exception name must appear on the first line. - i = msg.find("\n") - if i >= 0: - end = i - # retain up to the first colon (if any) - i = msg.find(':', 0, end) - if i >= 0: - end = i - # retain just the exception name - i = msg.rfind('.', 0, end) - if i >= 0: - start = i+1 - return msg[start: end] - -class _OutputRedirectingPdb(pdb.Pdb): - """ - A specialized version of the python debugger that redirects stdout - to a given stream when interacting with the user. Stdout is *not* - redirected when traced code is executed. - """ - def __init__(self, out): - self.__out = out - self.__debugger_used = False - # do not play signal games in the pdb - pdb.Pdb.__init__(self, stdout=out, nosigint=True) - # still use input() to get user input - self.use_rawinput = 1 - - def set_trace(self, frame=None): - self.__debugger_used = True - if frame is None: - frame = sys._getframe().f_back - pdb.Pdb.set_trace(self, frame) - - def set_continue(self): - # Calling set_continue unconditionally would break unit test - # coverage reporting, as Bdb.set_continue calls sys.settrace(None). - if self.__debugger_used: - pdb.Pdb.set_continue(self) - - def trace_dispatch(self, *args): - # Redirect stdout to the given stream. - save_stdout = sys.stdout - sys.stdout = self.__out - # Call Pdb's trace dispatch method. - try: - return pdb.Pdb.trace_dispatch(self, *args) - finally: - sys.stdout = save_stdout - -# [XX] Normalize with respect to os.path.pardir? -def _module_relative_path(module, test_path): - if not inspect.ismodule(module): - raise TypeError('Expected a module: %r' % module) - if test_path.startswith('/'): - raise ValueError('Module-relative files may not have absolute paths') - - # Normalize the path. On Windows, replace "/" with "\". - test_path = os.path.join(*(test_path.split('/'))) - - # Find the base directory for the path. - if hasattr(module, '__file__'): - # A normal module/package - basedir = os.path.split(module.__file__)[0] - elif module.__name__ == '__main__': - # An interactive session. - if len(sys.argv)>0 and sys.argv[0] != '': - basedir = os.path.split(sys.argv[0])[0] - else: - basedir = os.curdir - else: - if hasattr(module, '__path__'): - for directory in module.__path__: - fullpath = os.path.join(directory, test_path) - if os.path.exists(fullpath): - return fullpath - - # A module w/o __file__ (this includes builtins) - raise ValueError("Can't resolve paths relative to the module " - "%r (it has no __file__)" - % module.__name__) - - # Combine the base directory and the test path. - return os.path.join(basedir, test_path) - -###################################################################### -## 2. Example & DocTest -###################################################################### -## - An "example" is a pair, where "source" is a -## fragment of source code, and "want" is the expected output for -## "source." The Example class also includes information about -## where the example was extracted from. -## -## - A "doctest" is a collection of examples, typically extracted from -## a string (such as an object's docstring). The DocTest class also -## includes information about where the string was extracted from. - -class Example: - """ - A single doctest example, consisting of source code and expected - output. `Example` defines the following attributes: - - - source: A single Python statement, always ending with a newline. - The constructor adds a newline if needed. - - - want: The expected output from running the source code (either - from stdout, or a traceback in case of exception). `want` ends - with a newline unless it's empty, in which case it's an empty - string. The constructor adds a newline if needed. - - - exc_msg: The exception message generated by the example, if - the example is expected to generate an exception; or `None` if - it is not expected to generate an exception. This exception - message is compared against the return value of - `traceback.format_exception_only()`. `exc_msg` ends with a - newline unless it's `None`. The constructor adds a newline - if needed. - - - lineno: The line number within the DocTest string containing - this Example where the Example begins. This line number is - zero-based, with respect to the beginning of the DocTest. - - - indent: The example's indentation in the DocTest string. - I.e., the number of space characters that precede the - example's first prompt. - - - options: A dictionary mapping from option flags to True or - False, which is used to override default options for this - example. Any option flags not contained in this dictionary - are left at their default value (as specified by the - DocTestRunner's optionflags). By default, no options are set. - """ - def __init__(self, source, want, exc_msg=None, lineno=0, indent=0, - options=None): - # Normalize inputs. - if not source.endswith('\n'): - source += '\n' - if want and not want.endswith('\n'): - want += '\n' - if exc_msg is not None and not exc_msg.endswith('\n'): - exc_msg += '\n' - # Store properties. - self.source = source - self.want = want - self.lineno = lineno - self.indent = indent - if options is None: options = {} - self.options = options - self.exc_msg = exc_msg - - def __eq__(self, other): - if type(self) is not type(other): - return NotImplemented - - return self.source == other.source and \ - self.want == other.want and \ - self.lineno == other.lineno and \ - self.indent == other.indent and \ - self.options == other.options and \ - self.exc_msg == other.exc_msg - - def __hash__(self): - return hash((self.source, self.want, self.lineno, self.indent, - self.exc_msg)) - -class DocTest: - """ - A collection of doctest examples that should be run in a single - namespace. Each `DocTest` defines the following attributes: - - - examples: the list of examples. - - - globs: The namespace (aka globals) that the examples should - be run in. - - - name: A name identifying the DocTest (typically, the name of - the object whose docstring this DocTest was extracted from). - - - filename: The name of the file that this DocTest was extracted - from, or `None` if the filename is unknown. - - - lineno: The line number within filename where this DocTest - begins, or `None` if the line number is unavailable. This - line number is zero-based, with respect to the beginning of - the file. - - - docstring: The string that the examples were extracted from, - or `None` if the string is unavailable. - """ - def __init__(self, examples, globs, name, filename, lineno, docstring): - """ - Create a new DocTest containing the given examples. The - DocTest's globals are initialized with a copy of `globs`. - """ - assert not isinstance(examples, str), \ - "DocTest no longer accepts str; use DocTestParser instead" - self.examples = examples - self.docstring = docstring - self.globs = globs.copy() - self.name = name - self.filename = filename - self.lineno = lineno - - def __repr__(self): - if len(self.examples) == 0: - examples = 'no examples' - elif len(self.examples) == 1: - examples = '1 example' - else: - examples = '%d examples' % len(self.examples) - return ('<%s %s from %s:%s (%s)>' % - (self.__class__.__name__, - self.name, self.filename, self.lineno, examples)) - - def __eq__(self, other): - if type(self) is not type(other): - return NotImplemented - - return self.examples == other.examples and \ - self.docstring == other.docstring and \ - self.globs == other.globs and \ - self.name == other.name and \ - self.filename == other.filename and \ - self.lineno == other.lineno - - def __hash__(self): - return hash((self.docstring, self.name, self.filename, self.lineno)) - - # This lets us sort tests by name: - def __lt__(self, other): - if not isinstance(other, DocTest): - return NotImplemented - return ((self.name, self.filename, self.lineno, id(self)) - < - (other.name, other.filename, other.lineno, id(other))) - -###################################################################### -## 3. DocTestParser -###################################################################### - -class DocTestParser: - """ - A class used to parse strings containing doctest examples. - """ - # This regular expression is used to find doctest examples in a - # string. It defines three groups: `source` is the source code - # (including leading indentation and prompts); `indent` is the - # indentation of the first (PS1) line of the source code; and - # `want` is the expected output (including leading indentation). - _EXAMPLE_RE = re.compile(r''' - # Source consists of a PS1 line followed by zero or more PS2 lines. - (?P - (?:^(?P [ ]*) >>> .*) # PS1 line - (?:\n [ ]* \.\.\. .*)*) # PS2 lines - \n? - # Want consists of any non-blank lines that do not start with PS1. - (?P (?:(?![ ]*$) # Not a blank line - (?![ ]*>>>) # Not a line starting with PS1 - .+$\n? # But any other line - )*) - ''', re.MULTILINE | re.VERBOSE) - - # A regular expression for handling `want` strings that contain - # expected exceptions. It divides `want` into three pieces: - # - the traceback header line (`hdr`) - # - the traceback stack (`stack`) - # - the exception message (`msg`), as generated by - # traceback.format_exception_only() - # `msg` may have multiple lines. We assume/require that the - # exception message is the first non-indented line starting with a word - # character following the traceback header line. - _EXCEPTION_RE = re.compile(r""" - # Grab the traceback header. Different versions of Python have - # said different things on the first traceback line. - ^(?P Traceback\ \( - (?: most\ recent\ call\ last - | innermost\ last - ) \) : - ) - \s* $ # toss trailing whitespace on the header. - (?P .*?) # don't blink: absorb stuff until... - ^ (?P \w+ .*) # a line *starts* with alphanum. - """, re.VERBOSE | re.MULTILINE | re.DOTALL) - - # A callable returning a true value iff its argument is a blank line - # or contains a single comment. - _IS_BLANK_OR_COMMENT = re.compile(r'^[ ]*(#.*)?$').match - - def parse(self, string, name=''): - """ - Divide the given string into examples and intervening text, - and return them as a list of alternating Examples and strings. - Line numbers for the Examples are 0-based. The optional - argument `name` is a name identifying this string, and is only - used for error messages. - """ - string = string.expandtabs() - # If all lines begin with the same indentation, then strip it. - min_indent = self._min_indent(string) - if min_indent > 0: - string = '\n'.join([l[min_indent:] for l in string.split('\n')]) - - output = [] - charno, lineno = 0, 0 - # Find all doctest examples in the string: - for m in self._EXAMPLE_RE.finditer(string): - # Add the pre-example text to `output`. - output.append(string[charno:m.start()]) - # Update lineno (lines before this example) - lineno += string.count('\n', charno, m.start()) - # Extract info from the regexp match. - (source, options, want, exc_msg) = \ - self._parse_example(m, name, lineno) - # Create an Example, and add it to the list. - if not self._IS_BLANK_OR_COMMENT(source): - output.append( Example(source, want, exc_msg, - lineno=lineno, - indent=min_indent+len(m.group('indent')), - options=options) ) - # Update lineno (lines inside this example) - lineno += string.count('\n', m.start(), m.end()) - # Update charno. - charno = m.end() - # Add any remaining post-example text to `output`. - output.append(string[charno:]) - return output - - def get_doctest(self, string, globs, name, filename, lineno): - """ - Extract all doctest examples from the given string, and - collect them into a `DocTest` object. - - `globs`, `name`, `filename`, and `lineno` are attributes for - the new `DocTest` object. See the documentation for `DocTest` - for more information. - """ - return DocTest(self.get_examples(string, name), globs, - name, filename, lineno, string) - - def get_examples(self, string, name=''): - """ - Extract all doctest examples from the given string, and return - them as a list of `Example` objects. Line numbers are - 0-based, because it's most common in doctests that nothing - interesting appears on the same line as opening triple-quote, - and so the first interesting line is called \"line 1\" then. - - The optional argument `name` is a name identifying this - string, and is only used for error messages. - """ - return [x for x in self.parse(string, name) - if isinstance(x, Example)] - - def _parse_example(self, m, name, lineno): - """ - Given a regular expression match from `_EXAMPLE_RE` (`m`), - return a pair `(source, want)`, where `source` is the matched - example's source code (with prompts and indentation stripped); - and `want` is the example's expected output (with indentation - stripped). - - `name` is the string's name, and `lineno` is the line number - where the example starts; both are used for error messages. - """ - # Get the example's indentation level. - indent = len(m.group('indent')) - - # Divide source into lines; check that they're properly - # indented; and then strip their indentation & prompts. - source_lines = m.group('source').split('\n') - self._check_prompt_blank(source_lines, indent, name, lineno) - self._check_prefix(source_lines[1:], ' '*indent + '.', name, lineno) - source = '\n'.join([sl[indent+4:] for sl in source_lines]) - - # Divide want into lines; check that it's properly indented; and - # then strip the indentation. Spaces before the last newline should - # be preserved, so plain rstrip() isn't good enough. - want = m.group('want') - want_lines = want.split('\n') - if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]): - del want_lines[-1] # forget final newline & spaces after it - self._check_prefix(want_lines, ' '*indent, name, - lineno + len(source_lines)) - want = '\n'.join([wl[indent:] for wl in want_lines]) - - # If `want` contains a traceback message, then extract it. - m = self._EXCEPTION_RE.match(want) - if m: - exc_msg = m.group('msg') - else: - exc_msg = None - - # Extract options from the source. - options = self._find_options(source, name, lineno) - - return source, options, want, exc_msg - - # This regular expression looks for option directives in the - # source code of an example. Option directives are comments - # starting with "doctest:". Warning: this may give false - # positives for string-literals that contain the string - # "#doctest:". Eliminating these false positives would require - # actually parsing the string; but we limit them by ignoring any - # line containing "#doctest:" that is *followed* by a quote mark. - _OPTION_DIRECTIVE_RE = re.compile(r'#\s*doctest:\s*([^\n\'"]*)$', - re.MULTILINE) - - def _find_options(self, source, name, lineno): - """ - Return a dictionary containing option overrides extracted from - option directives in the given source string. - - `name` is the string's name, and `lineno` is the line number - where the example starts; both are used for error messages. - """ - options = {} - # (note: with the current regexp, this will match at most once:) - for m in self._OPTION_DIRECTIVE_RE.finditer(source): - option_strings = m.group(1).replace(',', ' ').split() - for option in option_strings: - if (option[0] not in '+-' or - option[1:] not in OPTIONFLAGS_BY_NAME): - raise ValueError('line %r of the doctest for %s ' - 'has an invalid option: %r' % - (lineno+1, name, option)) - flag = OPTIONFLAGS_BY_NAME[option[1:]] - options[flag] = (option[0] == '+') - if options and self._IS_BLANK_OR_COMMENT(source): - raise ValueError('line %r of the doctest for %s has an option ' - 'directive on a line with no example: %r' % - (lineno, name, source)) - return options - - # This regular expression finds the indentation of every non-blank - # line in a string. - _INDENT_RE = re.compile(r'^([ ]*)(?=\S)', re.MULTILINE) - - def _min_indent(self, s): - "Return the minimum indentation of any non-blank line in `s`" - indents = [len(indent) for indent in self._INDENT_RE.findall(s)] - if len(indents) > 0: - return min(indents) - else: - return 0 - - def _check_prompt_blank(self, lines, indent, name, lineno): - """ - Given the lines of a source string (including prompts and - leading indentation), check to make sure that every prompt is - followed by a space character. If any line is not followed by - a space character, then raise ValueError. - """ - for i, line in enumerate(lines): - if len(line) >= indent+4 and line[indent+3] != ' ': - raise ValueError('line %r of the docstring for %s ' - 'lacks blank after %s: %r' % - (lineno+i+1, name, - line[indent:indent+3], line)) - - def _check_prefix(self, lines, prefix, name, lineno): - """ - Check that every line in the given list starts with the given - prefix; if any line does not, then raise a ValueError. - """ - for i, line in enumerate(lines): - if line and not line.startswith(prefix): - raise ValueError('line %r of the docstring for %s has ' - 'inconsistent leading whitespace: %r' % - (lineno+i+1, name, line)) - - -###################################################################### -## 4. DocTest Finder -###################################################################### - -class DocTestFinder: - """ - A class used to extract the DocTests that are relevant to a given - object, from its docstring and the docstrings of its contained - objects. Doctests can currently be extracted from the following - object types: modules, functions, classes, methods, staticmethods, - classmethods, and properties. - """ - - def __init__(self, verbose=False, parser=DocTestParser(), - recurse=True, exclude_empty=True): - """ - Create a new doctest finder. - - The optional argument `parser` specifies a class or - function that should be used to create new DocTest objects (or - objects that implement the same interface as DocTest). The - signature for this factory function should match the signature - of the DocTest constructor. - - If the optional argument `recurse` is false, then `find` will - only examine the given object, and not any contained objects. - - If the optional argument `exclude_empty` is false, then `find` - will include tests for objects with empty docstrings. - """ - self._parser = parser - self._verbose = verbose - self._recurse = recurse - self._exclude_empty = exclude_empty - - def find(self, obj, name=None, module=None, globs=None, extraglobs=None): - """ - Return a list of the DocTests that are defined by the given - object's docstring, or by any of its contained objects' - docstrings. - - The optional parameter `module` is the module that contains - the given object. If the module is not specified or is None, then - the test finder will attempt to automatically determine the - correct module. The object's module is used: - - - As a default namespace, if `globs` is not specified. - - To prevent the DocTestFinder from extracting DocTests - from objects that are imported from other modules. - - To find the name of the file containing the object. - - To help find the line number of the object within its - file. - - Contained objects whose module does not match `module` are ignored. - - If `module` is False, no attempt to find the module will be made. - This is obscure, of use mostly in tests: if `module` is False, or - is None but cannot be found automatically, then all objects are - considered to belong to the (non-existent) module, so all contained - objects will (recursively) be searched for doctests. - - The globals for each DocTest is formed by combining `globs` - and `extraglobs` (bindings in `extraglobs` override bindings - in `globs`). A new copy of the globals dictionary is created - for each DocTest. If `globs` is not specified, then it - defaults to the module's `__dict__`, if specified, or {} - otherwise. If `extraglobs` is not specified, then it defaults - to {}. - - """ - # If name was not specified, then extract it from the object. - if name is None: - name = getattr(obj, '__name__', None) - if name is None: - raise ValueError("DocTestFinder.find: name must be given " - "when obj.__name__ doesn't exist: %r" % - (type(obj),)) - - # Find the module that contains the given object (if obj is - # a module, then module=obj.). Note: this may fail, in which - # case module will be None. - if module is False: - module = None - elif module is None: - module = inspect.getmodule(obj) - - # Read the module's source code. This is used by - # DocTestFinder._find_lineno to find the line number for a - # given object's docstring. - try: - file = inspect.getsourcefile(obj) - except TypeError: - source_lines = None - else: - if not file: - # Check to see if it's one of our special internal "files" - # (see __patched_linecache_getlines). - file = inspect.getfile(obj) - if not file[0]+file[-2:] == '<]>': file = None - if file is None: - source_lines = None - else: - if module is not None: - # Supply the module globals in case the module was - # originally loaded via a PEP 302 loader and - # file is not a valid filesystem path - source_lines = linecache.getlines(file, module.__dict__) - else: - # No access to a loader, so assume it's a normal - # filesystem path - source_lines = linecache.getlines(file) - if not source_lines: - source_lines = None - - # Initialize globals, and merge in extraglobs. - if globs is None: - if module is None: - globs = {} - else: - globs = module.__dict__.copy() - else: - globs = globs.copy() - if extraglobs is not None: - globs.update(extraglobs) - if '__name__' not in globs: - globs['__name__'] = '__main__' # provide a default module name - - # Recursively explore `obj`, extracting DocTests. - tests = [] - self._find(tests, obj, name, module, source_lines, globs, {}) - # Sort the tests by alpha order of names, for consistency in - # verbose-mode output. This was a feature of doctest in Pythons - # <= 2.3 that got lost by accident in 2.4. It was repaired in - # 2.4.4 and 2.5. - tests.sort() - return tests - - def _from_module(self, module, object): - """ - Return true if the given object is defined in the given - module. - """ - if module is None: - return True - elif inspect.getmodule(object) is not None: - return module is inspect.getmodule(object) - elif inspect.isfunction(object): - return module.__dict__ is object.__globals__ - elif inspect.ismethoddescriptor(object): - if hasattr(object, '__objclass__'): - obj_mod = object.__objclass__.__module__ - elif hasattr(object, '__module__'): - obj_mod = object.__module__ - else: - return True # [XX] no easy way to tell otherwise - return module.__name__ == obj_mod - elif inspect.isclass(object): - return module.__name__ == object.__module__ - elif hasattr(object, '__module__'): - return module.__name__ == object.__module__ - elif isinstance(object, property): - return True # [XX] no way not be sure. - else: - raise ValueError("object must be a class or function") - - def _is_routine(self, obj): - """ - Safely unwrap objects and determine if they are functions. - """ - maybe_routine = obj - try: - maybe_routine = inspect.unwrap(maybe_routine) - except ValueError: - pass - return inspect.isroutine(maybe_routine) - - def _find(self, tests, obj, name, module, source_lines, globs, seen): - """ - Find tests for the given object and any contained objects, and - add them to `tests`. - """ - if self._verbose: - print('Finding tests in %s' % name) - - # If we've already processed this object, then ignore it. - if id(obj) in seen: - return - seen[id(obj)] = 1 - - # Find a test for this object, and add it to the list of tests. - test = self._get_test(obj, name, module, globs, source_lines) - if test is not None: - tests.append(test) - - # Look for tests in a module's contained objects. - if inspect.ismodule(obj) and self._recurse: - for valname, val in obj.__dict__.items(): - valname = '%s.%s' % (name, valname) - - # Recurse to functions & classes. - if ((self._is_routine(val) or inspect.isclass(val)) and - self._from_module(module, val)): - self._find(tests, val, valname, module, source_lines, - globs, seen) - - # Look for tests in a module's __test__ dictionary. - if inspect.ismodule(obj) and self._recurse: - for valname, val in getattr(obj, '__test__', {}).items(): - if not isinstance(valname, str): - raise ValueError("DocTestFinder.find: __test__ keys " - "must be strings: %r" % - (type(valname),)) - if not (inspect.isroutine(val) or inspect.isclass(val) or - inspect.ismodule(val) or isinstance(val, str)): - raise ValueError("DocTestFinder.find: __test__ values " - "must be strings, functions, methods, " - "classes, or modules: %r" % - (type(val),)) - valname = '%s.__test__.%s' % (name, valname) - self._find(tests, val, valname, module, source_lines, - globs, seen) - - # Look for tests in a class's contained objects. - if inspect.isclass(obj) and self._recurse: - for valname, val in obj.__dict__.items(): - # Special handling for staticmethod/classmethod. - if isinstance(val, (staticmethod, classmethod)): - val = val.__func__ - - # Recurse to methods, properties, and nested classes. - if ((inspect.isroutine(val) or inspect.isclass(val) or - isinstance(val, property)) and - self._from_module(module, val)): - valname = '%s.%s' % (name, valname) - self._find(tests, val, valname, module, source_lines, - globs, seen) - - def _get_test(self, obj, name, module, globs, source_lines): - """ - Return a DocTest for the given object, if it defines a docstring; - otherwise, return None. - """ - # Extract the object's docstring. If it doesn't have one, - # then return None (no test for this object). - if isinstance(obj, str): - docstring = obj - else: - try: - if obj.__doc__ is None: - docstring = '' - else: - docstring = obj.__doc__ - if not isinstance(docstring, str): - docstring = str(docstring) - except (TypeError, AttributeError): - docstring = '' - - # Find the docstring's location in the file. - lineno = self._find_lineno(obj, source_lines) - - # Don't bother if the docstring is empty. - if self._exclude_empty and not docstring: - return None - - # Return a DocTest for this object. - if module is None: - filename = None - else: - # __file__ can be None for namespace packages. - filename = getattr(module, '__file__', None) or module.__name__ - if filename[-4:] == ".pyc": - filename = filename[:-1] - return self._parser.get_doctest(docstring, globs, name, - filename, lineno) - - def _find_lineno(self, obj, source_lines): - """ - Return a line number of the given object's docstring. - - Returns `None` if the given object does not have a docstring. - """ - lineno = None - docstring = getattr(obj, '__doc__', None) - - # Find the line number for modules. - if inspect.ismodule(obj) and docstring is not None: - lineno = 0 - - # Find the line number for classes. - # Note: this could be fooled if a class is defined multiple - # times in a single file. - if inspect.isclass(obj) and docstring is not None: - if source_lines is None: - return None - pat = re.compile(r'^\s*class\s*%s\b' % - getattr(obj, '__name__', '-')) - for i, line in enumerate(source_lines): - if pat.match(line): - lineno = i - break - - # Find the line number for functions & methods. - if inspect.ismethod(obj): obj = obj.__func__ - if inspect.isfunction(obj) and getattr(obj, '__doc__', None): - # We don't use `docstring` var here, because `obj` can be changed. - obj = obj.__code__ - if inspect.istraceback(obj): obj = obj.tb_frame - if inspect.isframe(obj): obj = obj.f_code - if inspect.iscode(obj): - lineno = obj.co_firstlineno - 1 - - # Find the line number where the docstring starts. Assume - # that it's the first line that begins with a quote mark. - # Note: this could be fooled by a multiline function - # signature, where a continuation line begins with a quote - # mark. - if lineno is not None: - if source_lines is None: - return lineno+1 - pat = re.compile(r'(^|.*:)\s*\w*("|\')') - for lineno in range(lineno, len(source_lines)): - if pat.match(source_lines[lineno]): - return lineno - - # We couldn't find the line number. - return None - -###################################################################### -## 5. DocTest Runner -###################################################################### - -class DocTestRunner: - """ - A class used to run DocTest test cases, and accumulate statistics. - The `run` method is used to process a single DocTest case. It - returns a tuple `(f, t)`, where `t` is the number of test cases - tried, and `f` is the number of test cases that failed. - - >>> tests = DocTestFinder().find(_TestClass) - >>> runner = DocTestRunner(verbose=False) - >>> tests.sort(key = lambda test: test.name) - >>> for test in tests: - ... print(test.name, '->', runner.run(test)) - _TestClass -> TestResults(failed=0, attempted=2) - _TestClass.__init__ -> TestResults(failed=0, attempted=2) - _TestClass.get -> TestResults(failed=0, attempted=2) - _TestClass.square -> TestResults(failed=0, attempted=1) - - The `summarize` method prints a summary of all the test cases that - have been run by the runner, and returns an aggregated `(f, t)` - tuple: - - >>> runner.summarize(verbose=1) - 4 items passed all tests: - 2 tests in _TestClass - 2 tests in _TestClass.__init__ - 2 tests in _TestClass.get - 1 tests in _TestClass.square - 7 tests in 4 items. - 7 passed and 0 failed. - Test passed. - TestResults(failed=0, attempted=7) - - The aggregated number of tried examples and failed examples is - also available via the `tries` and `failures` attributes: - - >>> runner.tries - 7 - >>> runner.failures - 0 - - The comparison between expected outputs and actual outputs is done - by an `OutputChecker`. This comparison may be customized with a - number of option flags; see the documentation for `testmod` for - more information. If the option flags are insufficient, then the - comparison may also be customized by passing a subclass of - `OutputChecker` to the constructor. - - The test runner's display output can be controlled in two ways. - First, an output function (`out) can be passed to - `TestRunner.run`; this function will be called with strings that - should be displayed. It defaults to `sys.stdout.write`. If - capturing the output is not sufficient, then the display output - can be also customized by subclassing DocTestRunner, and - overriding the methods `report_start`, `report_success`, - `report_unexpected_exception`, and `report_failure`. - """ - # This divider string is used to separate failure messages, and to - # separate sections of the summary. - DIVIDER = "*" * 70 - - def __init__(self, checker=None, verbose=None, optionflags=0): - """ - Create a new test runner. - - Optional keyword arg `checker` is the `OutputChecker` that - should be used to compare the expected outputs and actual - outputs of doctest examples. - - Optional keyword arg 'verbose' prints lots of stuff if true, - only failures if false; by default, it's true iff '-v' is in - sys.argv. - - Optional argument `optionflags` can be used to control how the - test runner compares expected output to actual output, and how - it displays failures. See the documentation for `testmod` for - more information. - """ - self._checker = checker or OutputChecker() - if verbose is None: - verbose = '-v' in sys.argv - self._verbose = verbose - self.optionflags = optionflags - self.original_optionflags = optionflags - - # Keep track of the examples we've run. - self.tries = 0 - self.failures = 0 - self._name2ft = {} - - # Create a fake output target for capturing doctest output. - self._fakeout = _SpoofOut() - - #///////////////////////////////////////////////////////////////// - # Reporting methods - #///////////////////////////////////////////////////////////////// - - def report_start(self, out, test, example): - """ - Report that the test runner is about to process the given - example. (Only displays a message if verbose=True) - """ - if self._verbose: - if example.want: - out('Trying:\n' + _indent(example.source) + - 'Expecting:\n' + _indent(example.want)) - else: - out('Trying:\n' + _indent(example.source) + - 'Expecting nothing\n') - - def report_success(self, out, test, example, got): - """ - Report that the given example ran successfully. (Only - displays a message if verbose=True) - """ - if self._verbose: - out("ok\n") - - def report_failure(self, out, test, example, got): - """ - Report that the given example failed. - """ - out(self._failure_header(test, example) + - self._checker.output_difference(example, got, self.optionflags)) - - def report_unexpected_exception(self, out, test, example, exc_info): - """ - Report that the given example raised an unexpected exception. - """ - out(self._failure_header(test, example) + - 'Exception raised:\n' + _indent(_exception_traceback(exc_info))) - - def _failure_header(self, test, example): - out = [self.DIVIDER] - if test.filename: - if test.lineno is not None and example.lineno is not None: - lineno = test.lineno + example.lineno + 1 - else: - lineno = '?' - out.append('File "%s", line %s, in %s' % - (test.filename, lineno, test.name)) - else: - out.append('Line %s, in %s' % (example.lineno+1, test.name)) - out.append('Failed example:') - source = example.source - out.append(_indent(source)) - return '\n'.join(out) - - #///////////////////////////////////////////////////////////////// - # DocTest Running - #///////////////////////////////////////////////////////////////// - - def __run(self, test, compileflags, out): - """ - Run the examples in `test`. Write the outcome of each example - with one of the `DocTestRunner.report_*` methods, using the - writer function `out`. `compileflags` is the set of compiler - flags that should be used to execute examples. Return a tuple - `(f, t)`, where `t` is the number of examples tried, and `f` - is the number of examples that failed. The examples are run - in the namespace `test.globs`. - """ - # Keep track of the number of failures and tries. - failures = tries = 0 - - # Save the option flags (since option directives can be used - # to modify them). - original_optionflags = self.optionflags - - SUCCESS, FAILURE, BOOM = range(3) # `outcome` state - - check = self._checker.check_output - - # Process each example. - for examplenum, example in enumerate(test.examples): - - # If REPORT_ONLY_FIRST_FAILURE is set, then suppress - # reporting after the first failure. - quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and - failures > 0) - - # Merge in the example's options. - self.optionflags = original_optionflags - if example.options: - for (optionflag, val) in example.options.items(): - if val: - self.optionflags |= optionflag - else: - self.optionflags &= ~optionflag - - # If 'SKIP' is set, then skip this example. - if self.optionflags & SKIP: - continue - - # Record that we started this example. - tries += 1 - if not quiet: - self.report_start(out, test, example) - - # Use a special filename for compile(), so we can retrieve - # the source code during interactive debugging (see - # __patched_linecache_getlines). - filename = '' % (test.name, examplenum) - - # Run the example in the given context (globs), and record - # any exception that gets raised. (But don't intercept - # keyboard interrupts.) - try: - # Don't blink! This is where the user's code gets run. - exec(compile(example.source, filename, "single", - compileflags, True), test.globs) - self.debugger.set_continue() # ==== Example Finished ==== - exception = None - except KeyboardInterrupt: - raise - except: - exception = sys.exc_info() - self.debugger.set_continue() # ==== Example Finished ==== - - got = self._fakeout.getvalue() # the actual output - self._fakeout.truncate(0) - outcome = FAILURE # guilty until proved innocent or insane - - # If the example executed without raising any exceptions, - # verify its output. - if exception is None: - if check(example.want, got, self.optionflags): - outcome = SUCCESS - - # The example raised an exception: check if it was expected. - else: - exc_msg = traceback.format_exception_only(*exception[:2])[-1] - if not quiet: - got += _exception_traceback(exception) - - # If `example.exc_msg` is None, then we weren't expecting - # an exception. - if example.exc_msg is None: - outcome = BOOM - - # We expected an exception: see whether it matches. - elif check(example.exc_msg, exc_msg, self.optionflags): - outcome = SUCCESS - - # Another chance if they didn't care about the detail. - elif self.optionflags & IGNORE_EXCEPTION_DETAIL: - if check(_strip_exception_details(example.exc_msg), - _strip_exception_details(exc_msg), - self.optionflags): - outcome = SUCCESS - - # Report the outcome. - if outcome is SUCCESS: - if not quiet: - self.report_success(out, test, example, got) - elif outcome is FAILURE: - if not quiet: - self.report_failure(out, test, example, got) - failures += 1 - elif outcome is BOOM: - if not quiet: - self.report_unexpected_exception(out, test, example, - exception) - failures += 1 - else: - assert False, ("unknown outcome", outcome) - - if failures and self.optionflags & FAIL_FAST: - break - - # Restore the option flags (in case they were modified) - self.optionflags = original_optionflags - - # Record and return the number of failures and tries. - self.__record_outcome(test, failures, tries) - return TestResults(failures, tries) - - def __record_outcome(self, test, f, t): - """ - Record the fact that the given DocTest (`test`) generated `f` - failures out of `t` tried examples. - """ - f2, t2 = self._name2ft.get(test.name, (0,0)) - self._name2ft[test.name] = (f+f2, t+t2) - self.failures += f - self.tries += t - - __LINECACHE_FILENAME_RE = re.compile(r'.+)' - r'\[(?P\d+)\]>$') - def __patched_linecache_getlines(self, filename, module_globals=None): - m = self.__LINECACHE_FILENAME_RE.match(filename) - if m and m.group('name') == self.test.name: - example = self.test.examples[int(m.group('examplenum'))] - return example.source.splitlines(keepends=True) - else: - return self.save_linecache_getlines(filename, module_globals) - - def run(self, test, compileflags=None, out=None, clear_globs=True): - """ - Run the examples in `test`, and display the results using the - writer function `out`. - - The examples are run in the namespace `test.globs`. If - `clear_globs` is true (the default), then this namespace will - be cleared after the test runs, to help with garbage - collection. If you would like to examine the namespace after - the test completes, then use `clear_globs=False`. - - `compileflags` gives the set of flags that should be used by - the Python compiler when running the examples. If not - specified, then it will default to the set of future-import - flags that apply to `globs`. - - The output of each example is checked using - `DocTestRunner.check_output`, and the results are formatted by - the `DocTestRunner.report_*` methods. - """ - self.test = test - - if compileflags is None: - compileflags = _extract_future_flags(test.globs) - - save_stdout = sys.stdout - if out is None: - encoding = save_stdout.encoding - if encoding is None or encoding.lower() == 'utf-8': - out = save_stdout.write - else: - # Use backslashreplace error handling on write - def out(s): - s = str(s.encode(encoding, 'backslashreplace'), encoding) - save_stdout.write(s) - sys.stdout = self._fakeout - - # Patch pdb.set_trace to restore sys.stdout during interactive - # debugging (so it's not still redirected to self._fakeout). - # Note that the interactive output will go to *our* - # save_stdout, even if that's not the real sys.stdout; this - # allows us to write test cases for the set_trace behavior. - save_trace = sys.gettrace() - save_set_trace = pdb.set_trace - self.debugger = _OutputRedirectingPdb(save_stdout) - self.debugger.reset() - pdb.set_trace = self.debugger.set_trace - - # Patch linecache.getlines, so we can see the example's source - # when we're inside the debugger. - self.save_linecache_getlines = linecache.getlines - linecache.getlines = self.__patched_linecache_getlines - - # Make sure sys.displayhook just prints the value to stdout - save_displayhook = sys.displayhook - sys.displayhook = sys.__displayhook__ - - try: - return self.__run(test, compileflags, out) - finally: - sys.stdout = save_stdout - pdb.set_trace = save_set_trace - sys.settrace(save_trace) - linecache.getlines = self.save_linecache_getlines - sys.displayhook = save_displayhook - if clear_globs: - test.globs.clear() - import builtins - builtins._ = None - - #///////////////////////////////////////////////////////////////// - # Summarization - #///////////////////////////////////////////////////////////////// - def summarize(self, verbose=None): - """ - Print a summary of all the test cases that have been run by - this DocTestRunner, and return a tuple `(f, t)`, where `f` is - the total number of failed examples, and `t` is the total - number of tried examples. - - The optional `verbose` argument controls how detailed the - summary is. If the verbosity is not specified, then the - DocTestRunner's verbosity is used. - """ - if verbose is None: - verbose = self._verbose - notests = [] - passed = [] - failed = [] - totalt = totalf = 0 - for x in self._name2ft.items(): - name, (f, t) = x - assert f <= t - totalt += t - totalf += f - if t == 0: - notests.append(name) - elif f == 0: - passed.append( (name, t) ) - else: - failed.append(x) - if verbose: - if notests: - print(len(notests), "items had no tests:") - notests.sort() - for thing in notests: - print(" ", thing) - if passed: - print(len(passed), "items passed all tests:") - passed.sort() - for thing, count in passed: - print(" %3d tests in %s" % (count, thing)) - if failed: - print(self.DIVIDER) - print(len(failed), "items had failures:") - failed.sort() - for thing, (f, t) in failed: - print(" %3d of %3d in %s" % (f, t, thing)) - if verbose: - print(totalt, "tests in", len(self._name2ft), "items.") - print(totalt - totalf, "passed and", totalf, "failed.") - if totalf: - print("***Test Failed***", totalf, "failures.") - elif verbose: - print("Test passed.") - return TestResults(totalf, totalt) - - #///////////////////////////////////////////////////////////////// - # Backward compatibility cruft to maintain doctest.master. - #///////////////////////////////////////////////////////////////// - def merge(self, other): - d = self._name2ft - for name, (f, t) in other._name2ft.items(): - if name in d: - # Don't print here by default, since doing - # so breaks some of the buildbots - #print("*** DocTestRunner.merge: '" + name + "' in both" \ - # " testers; summing outcomes.") - f2, t2 = d[name] - f = f + f2 - t = t + t2 - d[name] = f, t - -class OutputChecker: - """ - A class used to check the whether the actual output from a doctest - example matches the expected output. `OutputChecker` defines two - methods: `check_output`, which compares a given pair of outputs, - and returns true if they match; and `output_difference`, which - returns a string describing the differences between two outputs. - """ - def _toAscii(self, s): - """ - Convert string to hex-escaped ASCII string. - """ - return str(s.encode('ASCII', 'backslashreplace'), "ASCII") - - def check_output(self, want, got, optionflags): - """ - Return True iff the actual output from an example (`got`) - matches the expected output (`want`). These strings are - always considered to match if they are identical; but - depending on what option flags the test runner is using, - several non-exact match types are also possible. See the - documentation for `TestRunner` for more information about - option flags. - """ - - # If `want` contains hex-escaped character such as "\u1234", - # then `want` is a string of six characters(e.g. [\,u,1,2,3,4]). - # On the other hand, `got` could be another sequence of - # characters such as [\u1234], so `want` and `got` should - # be folded to hex-escaped ASCII string to compare. - got = self._toAscii(got) - want = self._toAscii(want) - - # Handle the common case first, for efficiency: - # if they're string-identical, always return true. - if got == want: - return True - - # The values True and False replaced 1 and 0 as the return - # value for boolean comparisons in Python 2.3. - if not (optionflags & DONT_ACCEPT_TRUE_FOR_1): - if (got,want) == ("True\n", "1\n"): - return True - if (got,want) == ("False\n", "0\n"): - return True - - # can be used as a special sequence to signify a - # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used. - if not (optionflags & DONT_ACCEPT_BLANKLINE): - # Replace in want with a blank line. - want = re.sub(r'(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER), - '', want) - # If a line in got contains only spaces, then remove the - # spaces. - got = re.sub(r'(?m)^[^\S\n]+$', '', got) - if got == want: - return True - - # This flag causes doctest to ignore any differences in the - # contents of whitespace strings. Note that this can be used - # in conjunction with the ELLIPSIS flag. - if optionflags & NORMALIZE_WHITESPACE: - got = ' '.join(got.split()) - want = ' '.join(want.split()) - if got == want: - return True - - # The ELLIPSIS flag says to let the sequence "..." in `want` - # match any substring in `got`. - if optionflags & ELLIPSIS: - if _ellipsis_match(want, got): - return True - - # We didn't find any match; return false. - return False - - # Should we do a fancy diff? - def _do_a_fancy_diff(self, want, got, optionflags): - # Not unless they asked for a fancy diff. - if not optionflags & (REPORT_UDIFF | - REPORT_CDIFF | - REPORT_NDIFF): - return False - - # If expected output uses ellipsis, a meaningful fancy diff is - # too hard ... or maybe not. In two real-life failures Tim saw, - # a diff was a major help anyway, so this is commented out. - # [todo] _ellipsis_match() knows which pieces do and don't match, - # and could be the basis for a kick-ass diff in this case. - ##if optionflags & ELLIPSIS and ELLIPSIS_MARKER in want: - ## return False - - # ndiff does intraline difference marking, so can be useful even - # for 1-line differences. - if optionflags & REPORT_NDIFF: - return True - - # The other diff types need at least a few lines to be helpful. - return want.count('\n') > 2 and got.count('\n') > 2 - - def output_difference(self, example, got, optionflags): - """ - Return a string describing the differences between the - expected output for a given example (`example`) and the actual - output (`got`). `optionflags` is the set of option flags used - to compare `want` and `got`. - """ - want = example.want - # If s are being used, then replace blank lines - # with in the actual output string. - if not (optionflags & DONT_ACCEPT_BLANKLINE): - got = re.sub('(?m)^[ ]*(?=\n)', BLANKLINE_MARKER, got) - - # Check if we should use diff. - if self._do_a_fancy_diff(want, got, optionflags): - # Split want & got into lines. - want_lines = want.splitlines(keepends=True) - got_lines = got.splitlines(keepends=True) - # Use difflib to find their differences. - if optionflags & REPORT_UDIFF: - diff = difflib.unified_diff(want_lines, got_lines, n=2) - diff = list(diff)[2:] # strip the diff header - kind = 'unified diff with -expected +actual' - elif optionflags & REPORT_CDIFF: - diff = difflib.context_diff(want_lines, got_lines, n=2) - diff = list(diff)[2:] # strip the diff header - kind = 'context diff with expected followed by actual' - elif optionflags & REPORT_NDIFF: - engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK) - diff = list(engine.compare(want_lines, got_lines)) - kind = 'ndiff with -expected +actual' - else: - assert 0, 'Bad diff option' - return 'Differences (%s):\n' % kind + _indent(''.join(diff)) - - # If we're not using diff, then simply list the expected - # output followed by the actual output. - if want and got: - return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got)) - elif want: - return 'Expected:\n%sGot nothing\n' % _indent(want) - elif got: - return 'Expected nothing\nGot:\n%s' % _indent(got) - else: - return 'Expected nothing\nGot nothing\n' - -class DocTestFailure(Exception): - """A DocTest example has failed in debugging mode. - - The exception instance has variables: - - - test: the DocTest object being run - - - example: the Example object that failed - - - got: the actual output - """ - def __init__(self, test, example, got): - self.test = test - self.example = example - self.got = got - - def __str__(self): - return str(self.test) - -class UnexpectedException(Exception): - """A DocTest example has encountered an unexpected exception - - The exception instance has variables: - - - test: the DocTest object being run - - - example: the Example object that failed - - - exc_info: the exception info - """ - def __init__(self, test, example, exc_info): - self.test = test - self.example = example - self.exc_info = exc_info - - def __str__(self): - return str(self.test) - -class DebugRunner(DocTestRunner): - r"""Run doc tests but raise an exception as soon as there is a failure. - - If an unexpected exception occurs, an UnexpectedException is raised. - It contains the test, the example, and the original exception: - - >>> runner = DebugRunner(verbose=False) - >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42', - ... {}, 'foo', 'foo.py', 0) - >>> try: - ... runner.run(test) - ... except UnexpectedException as f: - ... failure = f - - >>> failure.test is test - True - - >>> failure.example.want - '42\n' - - >>> exc_info = failure.exc_info - >>> raise exc_info[1] # Already has the traceback - Traceback (most recent call last): - ... - KeyError - - We wrap the original exception to give the calling application - access to the test and example information. - - If the output doesn't match, then a DocTestFailure is raised: - - >>> test = DocTestParser().get_doctest(''' - ... >>> x = 1 - ... >>> x - ... 2 - ... ''', {}, 'foo', 'foo.py', 0) - - >>> try: - ... runner.run(test) - ... except DocTestFailure as f: - ... failure = f - - DocTestFailure objects provide access to the test: - - >>> failure.test is test - True - - As well as to the example: - - >>> failure.example.want - '2\n' - - and the actual output: - - >>> failure.got - '1\n' - - If a failure or error occurs, the globals are left intact: - - >>> del test.globs['__builtins__'] - >>> test.globs - {'x': 1} - - >>> test = DocTestParser().get_doctest(''' - ... >>> x = 2 - ... >>> raise KeyError - ... ''', {}, 'foo', 'foo.py', 0) - - >>> runner.run(test) - Traceback (most recent call last): - ... - doctest.UnexpectedException: - - >>> del test.globs['__builtins__'] - >>> test.globs - {'x': 2} - - But the globals are cleared if there is no error: - - >>> test = DocTestParser().get_doctest(''' - ... >>> x = 2 - ... ''', {}, 'foo', 'foo.py', 0) - - >>> runner.run(test) - TestResults(failed=0, attempted=1) - - >>> test.globs - {} - - """ - - def run(self, test, compileflags=None, out=None, clear_globs=True): - r = DocTestRunner.run(self, test, compileflags, out, False) - if clear_globs: - test.globs.clear() - return r - - def report_unexpected_exception(self, out, test, example, exc_info): - raise UnexpectedException(test, example, exc_info) - - def report_failure(self, out, test, example, got): - raise DocTestFailure(test, example, got) - -###################################################################### -## 6. Test Functions -###################################################################### -# These should be backwards compatible. - -# For backward compatibility, a global instance of a DocTestRunner -# class, updated by testmod. -master = None - -def testmod(m=None, name=None, globs=None, verbose=None, - report=True, optionflags=0, extraglobs=None, - raise_on_error=False, exclude_empty=False): - """m=None, name=None, globs=None, verbose=None, report=True, - optionflags=0, extraglobs=None, raise_on_error=False, - exclude_empty=False - - Test examples in docstrings in functions and classes reachable - from module m (or the current module if m is not supplied), starting - with m.__doc__. - - Also test examples reachable from dict m.__test__ if it exists and is - not None. m.__test__ maps names to functions, classes and strings; - function and class docstrings are tested even if the name is private; - strings are tested directly, as if they were docstrings. - - Return (#failures, #tests). - - See help(doctest) for an overview. - - Optional keyword arg "name" gives the name of the module; by default - use m.__name__. - - Optional keyword arg "globs" gives a dict to be used as the globals - when executing examples; by default, use m.__dict__. A copy of this - dict is actually used for each docstring, so that each docstring's - examples start with a clean slate. - - Optional keyword arg "extraglobs" gives a dictionary that should be - merged into the globals that are used to execute examples. By - default, no extra globals are used. This is new in 2.4. - - Optional keyword arg "verbose" prints lots of stuff if true, prints - only failures if false; by default, it's true iff "-v" is in sys.argv. - - Optional keyword arg "report" prints a summary at the end when true, - else prints nothing at the end. In verbose mode, the summary is - detailed, else very brief (in fact, empty if all tests passed). - - Optional keyword arg "optionflags" or's together module constants, - and defaults to 0. This is new in 2.3. Possible values (see the - docs for details): - - DONT_ACCEPT_TRUE_FOR_1 - DONT_ACCEPT_BLANKLINE - NORMALIZE_WHITESPACE - ELLIPSIS - SKIP - IGNORE_EXCEPTION_DETAIL - REPORT_UDIFF - REPORT_CDIFF - REPORT_NDIFF - REPORT_ONLY_FIRST_FAILURE - - Optional keyword arg "raise_on_error" raises an exception on the - first unexpected exception or failure. This allows failures to be - post-mortem debugged. - - Advanced tomfoolery: testmod runs methods of a local instance of - class doctest.Tester, then merges the results into (or creates) - global Tester instance doctest.master. Methods of doctest.master - can be called directly too, if you want to do something unusual. - Passing report=0 to testmod is especially useful then, to delay - displaying a summary. Invoke doctest.master.summarize(verbose) - when you're done fiddling. - """ - global master - - # If no module was given, then use __main__. - if m is None: - # DWA - m will still be None if this wasn't invoked from the command - # line, in which case the following TypeError is about as good an error - # as we should expect - m = sys.modules.get('__main__') - - # Check that we were actually given a module. - if not inspect.ismodule(m): - raise TypeError("testmod: module required; %r" % (m,)) - - # If no name was given, then use the module's name. - if name is None: - name = m.__name__ - - # Find, parse, and run all tests in the given module. - finder = DocTestFinder(exclude_empty=exclude_empty) - - if raise_on_error: - runner = DebugRunner(verbose=verbose, optionflags=optionflags) - else: - runner = DocTestRunner(verbose=verbose, optionflags=optionflags) - - for test in finder.find(m, name, globs=globs, extraglobs=extraglobs): - runner.run(test) - - if report: - runner.summarize() - - if master is None: - master = runner - else: - master.merge(runner) - - return TestResults(runner.failures, runner.tries) - -def testfile(filename, module_relative=True, name=None, package=None, - globs=None, verbose=None, report=True, optionflags=0, - extraglobs=None, raise_on_error=False, parser=DocTestParser(), - encoding=None): - """ - Test examples in the given file. Return (#failures, #tests). - - Optional keyword arg "module_relative" specifies how filenames - should be interpreted: - - - If "module_relative" is True (the default), then "filename" - specifies a module-relative path. By default, this path is - relative to the calling module's directory; but if the - "package" argument is specified, then it is relative to that - package. To ensure os-independence, "filename" should use - "/" characters to separate path segments, and should not - be an absolute path (i.e., it may not begin with "/"). - - - If "module_relative" is False, then "filename" specifies an - os-specific path. The path may be absolute or relative (to - the current working directory). - - Optional keyword arg "name" gives the name of the test; by default - use the file's basename. - - Optional keyword argument "package" is a Python package or the - name of a Python package whose directory should be used as the - base directory for a module relative filename. If no package is - specified, then the calling module's directory is used as the base - directory for module relative filenames. It is an error to - specify "package" if "module_relative" is False. - - Optional keyword arg "globs" gives a dict to be used as the globals - when executing examples; by default, use {}. A copy of this dict - is actually used for each docstring, so that each docstring's - examples start with a clean slate. - - Optional keyword arg "extraglobs" gives a dictionary that should be - merged into the globals that are used to execute examples. By - default, no extra globals are used. - - Optional keyword arg "verbose" prints lots of stuff if true, prints - only failures if false; by default, it's true iff "-v" is in sys.argv. - - Optional keyword arg "report" prints a summary at the end when true, - else prints nothing at the end. In verbose mode, the summary is - detailed, else very brief (in fact, empty if all tests passed). - - Optional keyword arg "optionflags" or's together module constants, - and defaults to 0. Possible values (see the docs for details): - - DONT_ACCEPT_TRUE_FOR_1 - DONT_ACCEPT_BLANKLINE - NORMALIZE_WHITESPACE - ELLIPSIS - SKIP - IGNORE_EXCEPTION_DETAIL - REPORT_UDIFF - REPORT_CDIFF - REPORT_NDIFF - REPORT_ONLY_FIRST_FAILURE - - Optional keyword arg "raise_on_error" raises an exception on the - first unexpected exception or failure. This allows failures to be - post-mortem debugged. - - Optional keyword arg "parser" specifies a DocTestParser (or - subclass) that should be used to extract tests from the files. - - Optional keyword arg "encoding" specifies an encoding that should - be used to convert the file to unicode. - - Advanced tomfoolery: testmod runs methods of a local instance of - class doctest.Tester, then merges the results into (or creates) - global Tester instance doctest.master. Methods of doctest.master - can be called directly too, if you want to do something unusual. - Passing report=0 to testmod is especially useful then, to delay - displaying a summary. Invoke doctest.master.summarize(verbose) - when you're done fiddling. - """ - global master - - if package and not module_relative: - raise ValueError("Package may only be specified for module-" - "relative paths.") - - # Relativize the path - text, filename = _load_testfile(filename, package, module_relative, - encoding or "utf-8") - - # If no name was given, then use the file's name. - if name is None: - name = os.path.basename(filename) - - # Assemble the globals. - if globs is None: - globs = {} - else: - globs = globs.copy() - if extraglobs is not None: - globs.update(extraglobs) - if '__name__' not in globs: - globs['__name__'] = '__main__' - - if raise_on_error: - runner = DebugRunner(verbose=verbose, optionflags=optionflags) - else: - runner = DocTestRunner(verbose=verbose, optionflags=optionflags) - - # Read the file, convert it to a test, and run it. - test = parser.get_doctest(text, globs, name, filename, 0) - runner.run(test) - - if report: - runner.summarize() - - if master is None: - master = runner - else: - master.merge(runner) - - return TestResults(runner.failures, runner.tries) - -def run_docstring_examples(f, globs, verbose=False, name="NoName", - compileflags=None, optionflags=0): - """ - Test examples in the given object's docstring (`f`), using `globs` - as globals. Optional argument `name` is used in failure messages. - If the optional argument `verbose` is true, then generate output - even if there are no failures. - - `compileflags` gives the set of flags that should be used by the - Python compiler when running the examples. If not specified, then - it will default to the set of future-import flags that apply to - `globs`. - - Optional keyword arg `optionflags` specifies options for the - testing and output. See the documentation for `testmod` for more - information. - """ - # Find, parse, and run all tests in the given module. - finder = DocTestFinder(verbose=verbose, recurse=False) - runner = DocTestRunner(verbose=verbose, optionflags=optionflags) - for test in finder.find(f, name, globs=globs): - runner.run(test, compileflags=compileflags) - -###################################################################### -## 7. Unittest Support -###################################################################### - -_unittest_reportflags = 0 - -def set_unittest_reportflags(flags): - """Sets the unittest option flags. - - The old flag is returned so that a runner could restore the old - value if it wished to: - - >>> import doctest - >>> old = doctest._unittest_reportflags - >>> doctest.set_unittest_reportflags(REPORT_NDIFF | - ... REPORT_ONLY_FIRST_FAILURE) == old - True - - >>> doctest._unittest_reportflags == (REPORT_NDIFF | - ... REPORT_ONLY_FIRST_FAILURE) - True - - Only reporting flags can be set: - - >>> doctest.set_unittest_reportflags(ELLIPSIS) - Traceback (most recent call last): - ... - ValueError: ('Only reporting flags allowed', 8) - - >>> doctest.set_unittest_reportflags(old) == (REPORT_NDIFF | - ... REPORT_ONLY_FIRST_FAILURE) - True - """ - global _unittest_reportflags - - if (flags & REPORTING_FLAGS) != flags: - raise ValueError("Only reporting flags allowed", flags) - old = _unittest_reportflags - _unittest_reportflags = flags - return old - - -class DocTestCase(unittest.TestCase): - - def __init__(self, test, optionflags=0, setUp=None, tearDown=None, - checker=None): - - unittest.TestCase.__init__(self) - self._dt_optionflags = optionflags - self._dt_checker = checker - self._dt_globs = test.globs.copy() - self._dt_test = test - self._dt_setUp = setUp - self._dt_tearDown = tearDown - - def setUp(self): - test = self._dt_test - - if self._dt_setUp is not None: - self._dt_setUp(test) - - def tearDown(self): - test = self._dt_test - - if self._dt_tearDown is not None: - self._dt_tearDown(test) - - # restore the original globs - test.globs.clear() - test.globs.update(self._dt_globs) - - def runTest(self): - test = self._dt_test - old = sys.stdout - new = StringIO() - optionflags = self._dt_optionflags - - if not (optionflags & REPORTING_FLAGS): - # The option flags don't include any reporting flags, - # so add the default reporting flags - optionflags |= _unittest_reportflags - - runner = DocTestRunner(optionflags=optionflags, - checker=self._dt_checker, verbose=False) - - try: - runner.DIVIDER = "-"*70 - failures, tries = runner.run( - test, out=new.write, clear_globs=False) - finally: - sys.stdout = old - - if failures: - raise self.failureException(self.format_failure(new.getvalue())) - - def format_failure(self, err): - test = self._dt_test - if test.lineno is None: - lineno = 'unknown line number' - else: - lineno = '%s' % test.lineno - lname = '.'.join(test.name.split('.')[-1:]) - return ('Failed doctest test for %s\n' - ' File "%s", line %s, in %s\n\n%s' - % (test.name, test.filename, lineno, lname, err) - ) - - def debug(self): - r"""Run the test case without results and without catching exceptions - - The unit test framework includes a debug method on test cases - and test suites to support post-mortem debugging. The test code - is run in such a way that errors are not caught. This way a - caller can catch the errors and initiate post-mortem debugging. - - The DocTestCase provides a debug method that raises - UnexpectedException errors if there is an unexpected - exception: - - >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42', - ... {}, 'foo', 'foo.py', 0) - >>> case = DocTestCase(test) - >>> try: - ... case.debug() - ... except UnexpectedException as f: - ... failure = f - - The UnexpectedException contains the test, the example, and - the original exception: - - >>> failure.test is test - True - - >>> failure.example.want - '42\n' - - >>> exc_info = failure.exc_info - >>> raise exc_info[1] # Already has the traceback - Traceback (most recent call last): - ... - KeyError - - If the output doesn't match, then a DocTestFailure is raised: - - >>> test = DocTestParser().get_doctest(''' - ... >>> x = 1 - ... >>> x - ... 2 - ... ''', {}, 'foo', 'foo.py', 0) - >>> case = DocTestCase(test) - - >>> try: - ... case.debug() - ... except DocTestFailure as f: - ... failure = f - - DocTestFailure objects provide access to the test: - - >>> failure.test is test - True - - As well as to the example: - - >>> failure.example.want - '2\n' - - and the actual output: - - >>> failure.got - '1\n' - - """ - - self.setUp() - runner = DebugRunner(optionflags=self._dt_optionflags, - checker=self._dt_checker, verbose=False) - runner.run(self._dt_test, clear_globs=False) - self.tearDown() - - def id(self): - return self._dt_test.name - - def __eq__(self, other): - if type(self) is not type(other): - return NotImplemented - - return self._dt_test == other._dt_test and \ - self._dt_optionflags == other._dt_optionflags and \ - self._dt_setUp == other._dt_setUp and \ - self._dt_tearDown == other._dt_tearDown and \ - self._dt_checker == other._dt_checker - - def __hash__(self): - return hash((self._dt_optionflags, self._dt_setUp, self._dt_tearDown, - self._dt_checker)) - - def __repr__(self): - name = self._dt_test.name.split('.') - return "%s (%s)" % (name[-1], '.'.join(name[:-1])) - - __str__ = object.__str__ - - def shortDescription(self): - return "Doctest: " + self._dt_test.name - -class SkipDocTestCase(DocTestCase): - def __init__(self, module): - self.module = module - DocTestCase.__init__(self, None) - - def setUp(self): - self.skipTest("DocTestSuite will not work with -O2 and above") - - def test_skip(self): - pass - - def shortDescription(self): - return "Skipping tests from %s" % self.module.__name__ - - __str__ = shortDescription - - -class _DocTestSuite(unittest.TestSuite): - - def _removeTestAtIndex(self, index): - pass - - -def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, - **options): - """ - Convert doctest tests for a module to a unittest test suite. - - This converts each documentation string in a module that - contains doctest tests to a unittest test case. If any of the - tests in a doc string fail, then the test case fails. An exception - is raised showing the name of the file containing the test and a - (sometimes approximate) line number. - - The `module` argument provides the module to be tested. The argument - can be either a module or a module name. - - If no argument is given, the calling module is used. - - A number of options may be provided as keyword arguments: - - setUp - A set-up function. This is called before running the - tests in each file. The setUp function will be passed a DocTest - object. The setUp function can access the test globals as the - globs attribute of the test passed. - - tearDown - A tear-down function. This is called after running the - tests in each file. The tearDown function will be passed a DocTest - object. The tearDown function can access the test globals as the - globs attribute of the test passed. - - globs - A dictionary containing initial global variables for the tests. - - optionflags - A set of doctest option flags expressed as an integer. - """ - - if test_finder is None: - test_finder = DocTestFinder() - - module = _normalize_module(module) - tests = test_finder.find(module, globs=globs, extraglobs=extraglobs) - - if not tests and sys.flags.optimize >=2: - # Skip doctests when running with -O2 - suite = _DocTestSuite() - suite.addTest(SkipDocTestCase(module)) - return suite - - tests.sort() - suite = _DocTestSuite() - - for test in tests: - if len(test.examples) == 0: - continue - if not test.filename: - filename = module.__file__ - if filename[-4:] == ".pyc": - filename = filename[:-1] - test.filename = filename - suite.addTest(DocTestCase(test, **options)) - - return suite - -class DocFileCase(DocTestCase): - - def id(self): - return '_'.join(self._dt_test.name.split('.')) - - def __repr__(self): - return self._dt_test.filename - - def format_failure(self, err): - return ('Failed doctest test for %s\n File "%s", line 0\n\n%s' - % (self._dt_test.name, self._dt_test.filename, err) - ) - -def DocFileTest(path, module_relative=True, package=None, - globs=None, parser=DocTestParser(), - encoding=None, **options): - if globs is None: - globs = {} - else: - globs = globs.copy() - - if package and not module_relative: - raise ValueError("Package may only be specified for module-" - "relative paths.") - - # Relativize the path. - doc, path = _load_testfile(path, package, module_relative, - encoding or "utf-8") - - if "__file__" not in globs: - globs["__file__"] = path - - # Find the file and read it. - name = os.path.basename(path) - - # Convert it to a test, and wrap it in a DocFileCase. - test = parser.get_doctest(doc, globs, name, path, 0) - return DocFileCase(test, **options) - -def DocFileSuite(*paths, **kw): - """A unittest suite for one or more doctest files. - - The path to each doctest file is given as a string; the - interpretation of that string depends on the keyword argument - "module_relative". - - A number of options may be provided as keyword arguments: - - module_relative - If "module_relative" is True, then the given file paths are - interpreted as os-independent module-relative paths. By - default, these paths are relative to the calling module's - directory; but if the "package" argument is specified, then - they are relative to that package. To ensure os-independence, - "filename" should use "/" characters to separate path - segments, and may not be an absolute path (i.e., it may not - begin with "/"). - - If "module_relative" is False, then the given file paths are - interpreted as os-specific paths. These paths may be absolute - or relative (to the current working directory). - - package - A Python package or the name of a Python package whose directory - should be used as the base directory for module relative paths. - If "package" is not specified, then the calling module's - directory is used as the base directory for module relative - filenames. It is an error to specify "package" if - "module_relative" is False. - - setUp - A set-up function. This is called before running the - tests in each file. The setUp function will be passed a DocTest - object. The setUp function can access the test globals as the - globs attribute of the test passed. - - tearDown - A tear-down function. This is called after running the - tests in each file. The tearDown function will be passed a DocTest - object. The tearDown function can access the test globals as the - globs attribute of the test passed. - - globs - A dictionary containing initial global variables for the tests. - - optionflags - A set of doctest option flags expressed as an integer. - - parser - A DocTestParser (or subclass) that should be used to extract - tests from the files. - - encoding - An encoding that will be used to convert the files to unicode. - """ - suite = _DocTestSuite() - - # We do this here so that _normalize_module is called at the right - # level. If it were called in DocFileTest, then this function - # would be the caller and we might guess the package incorrectly. - if kw.get('module_relative', True): - kw['package'] = _normalize_module(kw.get('package')) - - for path in paths: - suite.addTest(DocFileTest(path, **kw)) - - return suite - -###################################################################### -## 8. Debugging Support -###################################################################### - -def script_from_examples(s): - r"""Extract script from text with examples. - - Converts text with examples to a Python script. Example input is - converted to regular code. Example output and all other words - are converted to comments: - - >>> text = ''' - ... Here are examples of simple math. - ... - ... Python has super accurate integer addition - ... - ... >>> 2 + 2 - ... 5 - ... - ... And very friendly error messages: - ... - ... >>> 1/0 - ... To Infinity - ... And - ... Beyond - ... - ... You can use logic if you want: - ... - ... >>> if 0: - ... ... blah - ... ... blah - ... ... - ... - ... Ho hum - ... ''' - - >>> print(script_from_examples(text)) - # Here are examples of simple math. - # - # Python has super accurate integer addition - # - 2 + 2 - # Expected: - ## 5 - # - # And very friendly error messages: - # - 1/0 - # Expected: - ## To Infinity - ## And - ## Beyond - # - # You can use logic if you want: - # - if 0: - blah - blah - # - # Ho hum - - """ - output = [] - for piece in DocTestParser().parse(s): - if isinstance(piece, Example): - # Add the example's source code (strip trailing NL) - output.append(piece.source[:-1]) - # Add the expected output: - want = piece.want - if want: - output.append('# Expected:') - output += ['## '+l for l in want.split('\n')[:-1]] - else: - # Add non-example text. - output += [_comment_line(l) - for l in piece.split('\n')[:-1]] - - # Trim junk on both ends. - while output and output[-1] == '#': - output.pop() - while output and output[0] == '#': - output.pop(0) - # Combine the output, and return it. - # Add a courtesy newline to prevent exec from choking (see bug #1172785) - return '\n'.join(output) + '\n' - -def testsource(module, name): - """Extract the test sources from a doctest docstring as a script. - - Provide the module (or dotted name of the module) containing the - test to be debugged and the name (within the module) of the object - with the doc string with tests to be debugged. - """ - module = _normalize_module(module) - tests = DocTestFinder().find(module) - test = [t for t in tests if t.name == name] - if not test: - raise ValueError(name, "not found in tests") - test = test[0] - testsrc = script_from_examples(test.docstring) - return testsrc - -def debug_src(src, pm=False, globs=None): - """Debug a single doctest docstring, in argument `src`'""" - testsrc = script_from_examples(src) - debug_script(testsrc, pm, globs) - -def debug_script(src, pm=False, globs=None): - "Debug a test script. `src` is the script, as a string." - import pdb - - if globs: - globs = globs.copy() - else: - globs = {} - - if pm: - try: - exec(src, globs, globs) - except: - print(sys.exc_info()[1]) - p = pdb.Pdb(nosigint=True) - p.reset() - p.interaction(None, sys.exc_info()[2]) - else: - pdb.Pdb(nosigint=True).run("exec(%r)" % src, globs, globs) - -def debug(module, name, pm=False): - """Debug a single doctest docstring. - - Provide the module (or dotted name of the module) containing the - test to be debugged and the name (within the module) of the object - with the docstring with tests to be debugged. - """ - module = _normalize_module(module) - testsrc = testsource(module, name) - debug_script(testsrc, pm, module.__dict__) - -###################################################################### -## 9. Example Usage -###################################################################### -class _TestClass: - """ - A pointless class, for sanity-checking of docstring testing. - - Methods: - square() - get() - - >>> _TestClass(13).get() + _TestClass(-12).get() - 1 - >>> hex(_TestClass(13).square().get()) - '0xa9' - """ - - def __init__(self, val): - """val -> _TestClass object with associated value val. - - >>> t = _TestClass(123) - >>> print(t.get()) - 123 - """ - - self.val = val - - def square(self): - """square() -> square TestClass's associated value - - >>> _TestClass(13).square().get() - 169 - """ - - self.val = self.val ** 2 - return self - - def get(self): - """get() -> return TestClass's associated value. - - >>> x = _TestClass(-42) - >>> print(x.get()) - -42 - """ - - return self.val - -__test__ = {"_TestClass": _TestClass, - "string": r""" - Example of a string object, searched as-is. - >>> x = 1; y = 2 - >>> x + y, x * y - (3, 2) - """, - - "bool-int equivalence": r""" - In 2.2, boolean expressions displayed - 0 or 1. By default, we still accept - them. This can be disabled by passing - DONT_ACCEPT_TRUE_FOR_1 to the new - optionflags argument. - >>> 4 == 4 - 1 - >>> 4 == 4 - True - >>> 4 > 4 - 0 - >>> 4 > 4 - False - """, - - "blank lines": r""" - Blank lines can be marked with : - >>> print('foo\n\nbar\n') - foo - - bar - - """, - - "ellipsis": r""" - If the ellipsis flag is used, then '...' can be used to - elide substrings in the desired output: - >>> print(list(range(1000))) #doctest: +ELLIPSIS - [0, 1, 2, ..., 999] - """, - - "whitespace normalization": r""" - If the whitespace normalization flag is used, then - differences in whitespace are ignored. - >>> print(list(range(30))) #doctest: +NORMALIZE_WHITESPACE - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29] - """, - } - - -def _test(): - import argparse - - parser = argparse.ArgumentParser(description="doctest runner") - parser.add_argument('-v', '--verbose', action='store_true', default=False, - help='print very verbose output for all tests') - parser.add_argument('-o', '--option', action='append', - choices=OPTIONFLAGS_BY_NAME.keys(), default=[], - help=('specify a doctest option flag to apply' - ' to the test run; may be specified more' - ' than once to apply multiple options')) - parser.add_argument('-f', '--fail-fast', action='store_true', - help=('stop running tests after first failure (this' - ' is a shorthand for -o FAIL_FAST, and is' - ' in addition to any other -o options)')) - parser.add_argument('file', nargs='+', - help='file containing the tests to run') - args = parser.parse_args() - testfiles = args.file - # Verbose used to be handled by the "inspect argv" magic in DocTestRunner, - # but since we are using argparse we are passing it manually now. - verbose = args.verbose - options = 0 - for option in args.option: - options |= OPTIONFLAGS_BY_NAME[option] - if args.fail_fast: - options |= FAIL_FAST - for filename in testfiles: - if filename.endswith(".py"): - # It is a module -- insert its dir into sys.path and try to - # import it. If it is part of a package, that possibly - # won't work because of package imports. - dirname, filename = os.path.split(filename) - sys.path.insert(0, dirname) - m = __import__(filename[:-3]) - del sys.path[0] - failures, _ = testmod(m, verbose=verbose, optionflags=options) - else: - failures, _ = testfile(filename, module_relative=False, - verbose=verbose, optionflags=options) - if failures: - return 1 - return 0 - - -if __name__ == "__main__": - sys.exit(_test()) diff --git a/python/Lib/encodings/__init__.py b/python/Lib/encodings/__init__.py deleted file mode 100644 index 079f51c..0000000 --- a/python/Lib/encodings/__init__.py +++ /dev/null @@ -1,174 +0,0 @@ -""" Standard "encodings" Package - - Standard Python encoding modules are stored in this package - directory. - - Codec modules must have names corresponding to normalized encoding - names as defined in the normalize_encoding() function below, e.g. - 'utf-8' must be implemented by the module 'utf_8.py'. - - Each codec module must export the following interface: - - * getregentry() -> codecs.CodecInfo object - The getregentry() API must return a CodecInfo object with encoder, decoder, - incrementalencoder, incrementaldecoder, streamwriter and streamreader - attributes which adhere to the Python Codec Interface Standard. - - In addition, a module may optionally also define the following - APIs which are then used by the package's codec search function: - - * getaliases() -> sequence of encoding name strings to use as aliases - - Alias names returned by getaliases() must be normalized encoding - names as defined by normalize_encoding(). - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -"""#" - -import codecs -import sys -from . import aliases - -_cache = {} -_unknown = '--unknown--' -_import_tail = ['*'] -_aliases = aliases.aliases - -class CodecRegistryError(LookupError, SystemError): - pass - -def normalize_encoding(encoding): - - """ Normalize an encoding name. - - Normalization works as follows: all non-alphanumeric - characters except the dot used for Python package names are - collapsed and replaced with a single underscore, e.g. ' -;#' - becomes '_'. Leading and trailing underscores are removed. - - Note that encoding names should be ASCII only. - - """ - if isinstance(encoding, bytes): - encoding = str(encoding, "ascii") - - chars = [] - punct = False - for c in encoding: - if c.isalnum() or c == '.': - if punct and chars: - chars.append('_') - if c.isascii(): - chars.append(c) - punct = False - else: - punct = True - return ''.join(chars) - -def search_function(encoding): - - # Cache lookup - entry = _cache.get(encoding, _unknown) - if entry is not _unknown: - return entry - - # Import the module: - # - # First try to find an alias for the normalized encoding - # name and lookup the module using the aliased name, then try to - # lookup the module using the standard import scheme, i.e. first - # try in the encodings package, then at top-level. - # - norm_encoding = normalize_encoding(encoding) - aliased_encoding = _aliases.get(norm_encoding) or \ - _aliases.get(norm_encoding.replace('.', '_')) - if aliased_encoding is not None: - modnames = [aliased_encoding, - norm_encoding] - else: - modnames = [norm_encoding] - for modname in modnames: - if not modname or '.' in modname: - continue - try: - # Import is absolute to prevent the possibly malicious import of a - # module with side-effects that is not in the 'encodings' package. - mod = __import__('encodings.' + modname, fromlist=_import_tail, - level=0) - except ImportError: - # ImportError may occur because 'encodings.(modname)' does not exist, - # or because it imports a name that does not exist (see mbcs and oem) - pass - else: - break - else: - mod = None - - try: - getregentry = mod.getregentry - except AttributeError: - # Not a codec module - mod = None - - if mod is None: - # Cache misses - _cache[encoding] = None - return None - - # Now ask the module for the registry entry - entry = getregentry() - if not isinstance(entry, codecs.CodecInfo): - if not 4 <= len(entry) <= 7: - raise CodecRegistryError('module "%s" (%s) failed to register' - % (mod.__name__, mod.__file__)) - if not callable(entry[0]) or not callable(entry[1]) or \ - (entry[2] is not None and not callable(entry[2])) or \ - (entry[3] is not None and not callable(entry[3])) or \ - (len(entry) > 4 and entry[4] is not None and not callable(entry[4])) or \ - (len(entry) > 5 and entry[5] is not None and not callable(entry[5])): - raise CodecRegistryError('incompatible codecs in module "%s" (%s)' - % (mod.__name__, mod.__file__)) - if len(entry)<7 or entry[6] is None: - entry += (None,)*(6-len(entry)) + (mod.__name__.split(".", 1)[1],) - entry = codecs.CodecInfo(*entry) - - # Cache the codec registry entry - _cache[encoding] = entry - - # Register its aliases (without overwriting previously registered - # aliases) - try: - codecaliases = mod.getaliases() - except AttributeError: - pass - else: - for alias in codecaliases: - if alias not in _aliases: - _aliases[alias] = modname - - # Return the registry entry - return entry - -# Register the search_function in the Python codec registry -codecs.register(search_function) - -if sys.platform == 'win32': - # bpo-671666, bpo-46668: If Python does not implement a codec for current - # Windows ANSI code page, use the "mbcs" codec instead: - # WideCharToMultiByte() and MultiByteToWideChar() functions with CP_ACP. - # Python does not support custom code pages. - def _alias_mbcs(encoding): - try: - import _winapi - ansi_code_page = "cp%s" % _winapi.GetACP() - if encoding == ansi_code_page: - import encodings.mbcs - return encodings.mbcs.getregentry() - except ImportError: - # Imports may fail while we are shutting down - pass - - codecs.register(_alias_mbcs) diff --git a/python/Lib/encodings/aliases.py b/python/Lib/encodings/aliases.py deleted file mode 100644 index 9d8d20f..0000000 --- a/python/Lib/encodings/aliases.py +++ /dev/null @@ -1,551 +0,0 @@ -""" Encoding Aliases Support - - This module is used by the encodings package search function to - map encodings names to module names. - - Note that the search function normalizes the encoding names before - doing the lookup, so the mapping will have to map normalized - encoding names to module names. - - Contents: - - The following aliases dictionary contains mappings of all IANA - character set names for which the Python core library provides - codecs. In addition to these, a few Python specific codec - aliases have also been added. - -""" -aliases = { - - # Please keep this list sorted alphabetically by value ! - - # ascii codec - '646' : 'ascii', - 'ansi_x3.4_1968' : 'ascii', - 'ansi_x3_4_1968' : 'ascii', # some email headers use this non-standard name - 'ansi_x3.4_1986' : 'ascii', - 'cp367' : 'ascii', - 'csascii' : 'ascii', - 'ibm367' : 'ascii', - 'iso646_us' : 'ascii', - 'iso_646.irv_1991' : 'ascii', - 'iso_ir_6' : 'ascii', - 'us' : 'ascii', - 'us_ascii' : 'ascii', - - # base64_codec codec - 'base64' : 'base64_codec', - 'base_64' : 'base64_codec', - - # big5 codec - 'big5_tw' : 'big5', - 'csbig5' : 'big5', - - # big5hkscs codec - 'big5_hkscs' : 'big5hkscs', - 'hkscs' : 'big5hkscs', - - # bz2_codec codec - 'bz2' : 'bz2_codec', - - # cp037 codec - '037' : 'cp037', - 'csibm037' : 'cp037', - 'ebcdic_cp_ca' : 'cp037', - 'ebcdic_cp_nl' : 'cp037', - 'ebcdic_cp_us' : 'cp037', - 'ebcdic_cp_wt' : 'cp037', - 'ibm037' : 'cp037', - 'ibm039' : 'cp037', - - # cp1026 codec - '1026' : 'cp1026', - 'csibm1026' : 'cp1026', - 'ibm1026' : 'cp1026', - - # cp1125 codec - '1125' : 'cp1125', - 'ibm1125' : 'cp1125', - 'cp866u' : 'cp1125', - 'ruscii' : 'cp1125', - - # cp1140 codec - '1140' : 'cp1140', - 'ibm1140' : 'cp1140', - - # cp1250 codec - '1250' : 'cp1250', - 'windows_1250' : 'cp1250', - - # cp1251 codec - '1251' : 'cp1251', - 'windows_1251' : 'cp1251', - - # cp1252 codec - '1252' : 'cp1252', - 'windows_1252' : 'cp1252', - - # cp1253 codec - '1253' : 'cp1253', - 'windows_1253' : 'cp1253', - - # cp1254 codec - '1254' : 'cp1254', - 'windows_1254' : 'cp1254', - - # cp1255 codec - '1255' : 'cp1255', - 'windows_1255' : 'cp1255', - - # cp1256 codec - '1256' : 'cp1256', - 'windows_1256' : 'cp1256', - - # cp1257 codec - '1257' : 'cp1257', - 'windows_1257' : 'cp1257', - - # cp1258 codec - '1258' : 'cp1258', - 'windows_1258' : 'cp1258', - - # cp273 codec - '273' : 'cp273', - 'ibm273' : 'cp273', - 'csibm273' : 'cp273', - - # cp424 codec - '424' : 'cp424', - 'csibm424' : 'cp424', - 'ebcdic_cp_he' : 'cp424', - 'ibm424' : 'cp424', - - # cp437 codec - '437' : 'cp437', - 'cspc8codepage437' : 'cp437', - 'ibm437' : 'cp437', - - # cp500 codec - '500' : 'cp500', - 'csibm500' : 'cp500', - 'ebcdic_cp_be' : 'cp500', - 'ebcdic_cp_ch' : 'cp500', - 'ibm500' : 'cp500', - - # cp775 codec - '775' : 'cp775', - 'cspc775baltic' : 'cp775', - 'ibm775' : 'cp775', - - # cp850 codec - '850' : 'cp850', - 'cspc850multilingual' : 'cp850', - 'ibm850' : 'cp850', - - # cp852 codec - '852' : 'cp852', - 'cspcp852' : 'cp852', - 'ibm852' : 'cp852', - - # cp855 codec - '855' : 'cp855', - 'csibm855' : 'cp855', - 'ibm855' : 'cp855', - - # cp857 codec - '857' : 'cp857', - 'csibm857' : 'cp857', - 'ibm857' : 'cp857', - - # cp858 codec - '858' : 'cp858', - 'csibm858' : 'cp858', - 'ibm858' : 'cp858', - - # cp860 codec - '860' : 'cp860', - 'csibm860' : 'cp860', - 'ibm860' : 'cp860', - - # cp861 codec - '861' : 'cp861', - 'cp_is' : 'cp861', - 'csibm861' : 'cp861', - 'ibm861' : 'cp861', - - # cp862 codec - '862' : 'cp862', - 'cspc862latinhebrew' : 'cp862', - 'ibm862' : 'cp862', - - # cp863 codec - '863' : 'cp863', - 'csibm863' : 'cp863', - 'ibm863' : 'cp863', - - # cp864 codec - '864' : 'cp864', - 'csibm864' : 'cp864', - 'ibm864' : 'cp864', - - # cp865 codec - '865' : 'cp865', - 'csibm865' : 'cp865', - 'ibm865' : 'cp865', - - # cp866 codec - '866' : 'cp866', - 'csibm866' : 'cp866', - 'ibm866' : 'cp866', - - # cp869 codec - '869' : 'cp869', - 'cp_gr' : 'cp869', - 'csibm869' : 'cp869', - 'ibm869' : 'cp869', - - # cp932 codec - '932' : 'cp932', - 'ms932' : 'cp932', - 'mskanji' : 'cp932', - 'ms_kanji' : 'cp932', - - # cp949 codec - '949' : 'cp949', - 'ms949' : 'cp949', - 'uhc' : 'cp949', - - # cp950 codec - '950' : 'cp950', - 'ms950' : 'cp950', - - # euc_jis_2004 codec - 'jisx0213' : 'euc_jis_2004', - 'eucjis2004' : 'euc_jis_2004', - 'euc_jis2004' : 'euc_jis_2004', - - # euc_jisx0213 codec - 'eucjisx0213' : 'euc_jisx0213', - - # euc_jp codec - 'eucjp' : 'euc_jp', - 'ujis' : 'euc_jp', - 'u_jis' : 'euc_jp', - - # euc_kr codec - 'euckr' : 'euc_kr', - 'korean' : 'euc_kr', - 'ksc5601' : 'euc_kr', - 'ks_c_5601' : 'euc_kr', - 'ks_c_5601_1987' : 'euc_kr', - 'ksx1001' : 'euc_kr', - 'ks_x_1001' : 'euc_kr', - - # gb18030 codec - 'gb18030_2000' : 'gb18030', - - # gb2312 codec - 'chinese' : 'gb2312', - 'csiso58gb231280' : 'gb2312', - 'euc_cn' : 'gb2312', - 'euccn' : 'gb2312', - 'eucgb2312_cn' : 'gb2312', - 'gb2312_1980' : 'gb2312', - 'gb2312_80' : 'gb2312', - 'iso_ir_58' : 'gb2312', - - # gbk codec - '936' : 'gbk', - 'cp936' : 'gbk', - 'ms936' : 'gbk', - - # hex_codec codec - 'hex' : 'hex_codec', - - # hp_roman8 codec - 'roman8' : 'hp_roman8', - 'r8' : 'hp_roman8', - 'csHPRoman8' : 'hp_roman8', - 'cp1051' : 'hp_roman8', - 'ibm1051' : 'hp_roman8', - - # hz codec - 'hzgb' : 'hz', - 'hz_gb' : 'hz', - 'hz_gb_2312' : 'hz', - - # iso2022_jp codec - 'csiso2022jp' : 'iso2022_jp', - 'iso2022jp' : 'iso2022_jp', - 'iso_2022_jp' : 'iso2022_jp', - - # iso2022_jp_1 codec - 'iso2022jp_1' : 'iso2022_jp_1', - 'iso_2022_jp_1' : 'iso2022_jp_1', - - # iso2022_jp_2 codec - 'iso2022jp_2' : 'iso2022_jp_2', - 'iso_2022_jp_2' : 'iso2022_jp_2', - - # iso2022_jp_2004 codec - 'iso_2022_jp_2004' : 'iso2022_jp_2004', - 'iso2022jp_2004' : 'iso2022_jp_2004', - - # iso2022_jp_3 codec - 'iso2022jp_3' : 'iso2022_jp_3', - 'iso_2022_jp_3' : 'iso2022_jp_3', - - # iso2022_jp_ext codec - 'iso2022jp_ext' : 'iso2022_jp_ext', - 'iso_2022_jp_ext' : 'iso2022_jp_ext', - - # iso2022_kr codec - 'csiso2022kr' : 'iso2022_kr', - 'iso2022kr' : 'iso2022_kr', - 'iso_2022_kr' : 'iso2022_kr', - - # iso8859_10 codec - 'csisolatin6' : 'iso8859_10', - 'iso_8859_10' : 'iso8859_10', - 'iso_8859_10_1992' : 'iso8859_10', - 'iso_ir_157' : 'iso8859_10', - 'l6' : 'iso8859_10', - 'latin6' : 'iso8859_10', - - # iso8859_11 codec - 'thai' : 'iso8859_11', - 'iso_8859_11' : 'iso8859_11', - 'iso_8859_11_2001' : 'iso8859_11', - - # iso8859_13 codec - 'iso_8859_13' : 'iso8859_13', - 'l7' : 'iso8859_13', - 'latin7' : 'iso8859_13', - - # iso8859_14 codec - 'iso_8859_14' : 'iso8859_14', - 'iso_8859_14_1998' : 'iso8859_14', - 'iso_celtic' : 'iso8859_14', - 'iso_ir_199' : 'iso8859_14', - 'l8' : 'iso8859_14', - 'latin8' : 'iso8859_14', - - # iso8859_15 codec - 'iso_8859_15' : 'iso8859_15', - 'l9' : 'iso8859_15', - 'latin9' : 'iso8859_15', - - # iso8859_16 codec - 'iso_8859_16' : 'iso8859_16', - 'iso_8859_16_2001' : 'iso8859_16', - 'iso_ir_226' : 'iso8859_16', - 'l10' : 'iso8859_16', - 'latin10' : 'iso8859_16', - - # iso8859_2 codec - 'csisolatin2' : 'iso8859_2', - 'iso_8859_2' : 'iso8859_2', - 'iso_8859_2_1987' : 'iso8859_2', - 'iso_ir_101' : 'iso8859_2', - 'l2' : 'iso8859_2', - 'latin2' : 'iso8859_2', - - # iso8859_3 codec - 'csisolatin3' : 'iso8859_3', - 'iso_8859_3' : 'iso8859_3', - 'iso_8859_3_1988' : 'iso8859_3', - 'iso_ir_109' : 'iso8859_3', - 'l3' : 'iso8859_3', - 'latin3' : 'iso8859_3', - - # iso8859_4 codec - 'csisolatin4' : 'iso8859_4', - 'iso_8859_4' : 'iso8859_4', - 'iso_8859_4_1988' : 'iso8859_4', - 'iso_ir_110' : 'iso8859_4', - 'l4' : 'iso8859_4', - 'latin4' : 'iso8859_4', - - # iso8859_5 codec - 'csisolatincyrillic' : 'iso8859_5', - 'cyrillic' : 'iso8859_5', - 'iso_8859_5' : 'iso8859_5', - 'iso_8859_5_1988' : 'iso8859_5', - 'iso_ir_144' : 'iso8859_5', - - # iso8859_6 codec - 'arabic' : 'iso8859_6', - 'asmo_708' : 'iso8859_6', - 'csisolatinarabic' : 'iso8859_6', - 'ecma_114' : 'iso8859_6', - 'iso_8859_6' : 'iso8859_6', - 'iso_8859_6_1987' : 'iso8859_6', - 'iso_ir_127' : 'iso8859_6', - - # iso8859_7 codec - 'csisolatingreek' : 'iso8859_7', - 'ecma_118' : 'iso8859_7', - 'elot_928' : 'iso8859_7', - 'greek' : 'iso8859_7', - 'greek8' : 'iso8859_7', - 'iso_8859_7' : 'iso8859_7', - 'iso_8859_7_1987' : 'iso8859_7', - 'iso_ir_126' : 'iso8859_7', - - # iso8859_8 codec - 'csisolatinhebrew' : 'iso8859_8', - 'hebrew' : 'iso8859_8', - 'iso_8859_8' : 'iso8859_8', - 'iso_8859_8_1988' : 'iso8859_8', - 'iso_ir_138' : 'iso8859_8', - - # iso8859_9 codec - 'csisolatin5' : 'iso8859_9', - 'iso_8859_9' : 'iso8859_9', - 'iso_8859_9_1989' : 'iso8859_9', - 'iso_ir_148' : 'iso8859_9', - 'l5' : 'iso8859_9', - 'latin5' : 'iso8859_9', - - # johab codec - 'cp1361' : 'johab', - 'ms1361' : 'johab', - - # koi8_r codec - 'cskoi8r' : 'koi8_r', - - # kz1048 codec - 'kz_1048' : 'kz1048', - 'rk1048' : 'kz1048', - 'strk1048_2002' : 'kz1048', - - # latin_1 codec - # - # Note that the latin_1 codec is implemented internally in C and a - # lot faster than the charmap codec iso8859_1 which uses the same - # encoding. This is why we discourage the use of the iso8859_1 - # codec and alias it to latin_1 instead. - # - '8859' : 'latin_1', - 'cp819' : 'latin_1', - 'csisolatin1' : 'latin_1', - 'ibm819' : 'latin_1', - 'iso8859' : 'latin_1', - 'iso8859_1' : 'latin_1', - 'iso_8859_1' : 'latin_1', - 'iso_8859_1_1987' : 'latin_1', - 'iso_ir_100' : 'latin_1', - 'l1' : 'latin_1', - 'latin' : 'latin_1', - 'latin1' : 'latin_1', - - # mac_cyrillic codec - 'maccyrillic' : 'mac_cyrillic', - - # mac_greek codec - 'macgreek' : 'mac_greek', - - # mac_iceland codec - 'maciceland' : 'mac_iceland', - - # mac_latin2 codec - 'maccentraleurope' : 'mac_latin2', - 'mac_centeuro' : 'mac_latin2', - 'maclatin2' : 'mac_latin2', - - # mac_roman codec - 'macintosh' : 'mac_roman', - 'macroman' : 'mac_roman', - - # mac_turkish codec - 'macturkish' : 'mac_turkish', - - # mbcs codec - 'ansi' : 'mbcs', - 'dbcs' : 'mbcs', - - # ptcp154 codec - 'csptcp154' : 'ptcp154', - 'pt154' : 'ptcp154', - 'cp154' : 'ptcp154', - 'cyrillic_asian' : 'ptcp154', - - # quopri_codec codec - 'quopri' : 'quopri_codec', - 'quoted_printable' : 'quopri_codec', - 'quotedprintable' : 'quopri_codec', - - # rot_13 codec - 'rot13' : 'rot_13', - - # shift_jis codec - 'csshiftjis' : 'shift_jis', - 'shiftjis' : 'shift_jis', - 'sjis' : 'shift_jis', - 's_jis' : 'shift_jis', - - # shift_jis_2004 codec - 'shiftjis2004' : 'shift_jis_2004', - 'sjis_2004' : 'shift_jis_2004', - 's_jis_2004' : 'shift_jis_2004', - - # shift_jisx0213 codec - 'shiftjisx0213' : 'shift_jisx0213', - 'sjisx0213' : 'shift_jisx0213', - 's_jisx0213' : 'shift_jisx0213', - - # tis_620 codec - 'tis620' : 'tis_620', - 'tis_620_0' : 'tis_620', - 'tis_620_2529_0' : 'tis_620', - 'tis_620_2529_1' : 'tis_620', - 'iso_ir_166' : 'tis_620', - - # utf_16 codec - 'u16' : 'utf_16', - 'utf16' : 'utf_16', - - # utf_16_be codec - 'unicodebigunmarked' : 'utf_16_be', - 'utf_16be' : 'utf_16_be', - - # utf_16_le codec - 'unicodelittleunmarked' : 'utf_16_le', - 'utf_16le' : 'utf_16_le', - - # utf_32 codec - 'u32' : 'utf_32', - 'utf32' : 'utf_32', - - # utf_32_be codec - 'utf_32be' : 'utf_32_be', - - # utf_32_le codec - 'utf_32le' : 'utf_32_le', - - # utf_7 codec - 'u7' : 'utf_7', - 'utf7' : 'utf_7', - 'unicode_1_1_utf_7' : 'utf_7', - - # utf_8 codec - 'u8' : 'utf_8', - 'utf' : 'utf_8', - 'utf8' : 'utf_8', - 'utf8_ucs2' : 'utf_8', - 'utf8_ucs4' : 'utf_8', - 'cp65001' : 'utf_8', - - # uu_codec codec - 'uu' : 'uu_codec', - - # zlib_codec codec - 'zip' : 'zlib_codec', - 'zlib' : 'zlib_codec', - - # temporary mac CJK aliases, will be replaced by proper codecs in 3.1 - 'x_mac_japanese' : 'shift_jis', - 'x_mac_korean' : 'euc_kr', - 'x_mac_simp_chinese' : 'gb2312', - 'x_mac_trad_chinese' : 'big5', -} diff --git a/python/Lib/encodings/ascii.py b/python/Lib/encodings/ascii.py deleted file mode 100644 index df0d66d..0000000 --- a/python/Lib/encodings/ascii.py +++ /dev/null @@ -1,50 +0,0 @@ -""" Python 'ascii' Codec - - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -""" -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - # Note: Binding these as C functions will result in the class not - # converting them to methods. This is intended. - encode = codecs.ascii_encode - decode = codecs.ascii_decode - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.ascii_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.ascii_decode(input, self.errors)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -class StreamConverter(StreamWriter,StreamReader): - - encode = codecs.ascii_decode - decode = codecs.ascii_encode - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='ascii', - encode=Codec.encode, - decode=Codec.decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) diff --git a/python/Lib/encodings/base64_codec.py b/python/Lib/encodings/base64_codec.py deleted file mode 100644 index 70cdb8a..0000000 --- a/python/Lib/encodings/base64_codec.py +++ /dev/null @@ -1,55 +0,0 @@ -"""Python 'base64_codec' Codec - base64 content transfer encoding. - -This codec de/encodes from bytes to bytes. - -Written by Marc-Andre Lemburg (mal@lemburg.com). -""" - -import codecs -import base64 - -### Codec APIs - -def base64_encode(input, errors='strict'): - assert errors == 'strict' - return (base64.encodebytes(input), len(input)) - -def base64_decode(input, errors='strict'): - assert errors == 'strict' - return (base64.decodebytes(input), len(input)) - -class Codec(codecs.Codec): - def encode(self, input, errors='strict'): - return base64_encode(input, errors) - def decode(self, input, errors='strict'): - return base64_decode(input, errors) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - assert self.errors == 'strict' - return base64.encodebytes(input) - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - assert self.errors == 'strict' - return base64.decodebytes(input) - -class StreamWriter(Codec, codecs.StreamWriter): - charbuffertype = bytes - -class StreamReader(Codec, codecs.StreamReader): - charbuffertype = bytes - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='base64', - encode=base64_encode, - decode=base64_decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - _is_text_encoding=False, - ) diff --git a/python/Lib/encodings/big5.py b/python/Lib/encodings/big5.py deleted file mode 100644 index 1be2c29..0000000 --- a/python/Lib/encodings/big5.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# big5.py: Python Unicode Codec for BIG5 -# -# Written by Hye-Shik Chang -# - -import _codecs_tw, codecs -import _multibytecodec as mbc - -codec = _codecs_tw.getcodec('big5') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='big5', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/big5hkscs.py b/python/Lib/encodings/big5hkscs.py deleted file mode 100644 index ddfcaa6..0000000 --- a/python/Lib/encodings/big5hkscs.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# big5hkscs.py: Python Unicode Codec for BIG5HKSCS -# -# Written by Hye-Shik Chang -# - -import _codecs_hk, codecs -import _multibytecodec as mbc - -codec = _codecs_hk.getcodec('big5hkscs') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='big5hkscs', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/bz2_codec.py b/python/Lib/encodings/bz2_codec.py deleted file mode 100644 index 573d82a..0000000 --- a/python/Lib/encodings/bz2_codec.py +++ /dev/null @@ -1,78 +0,0 @@ -"""Python 'bz2_codec' Codec - bz2 compression encoding. - -This codec de/encodes from bytes to bytes and is therefore usable with -bytes.transform() and bytes.untransform(). - -Adapted by Raymond Hettinger from zlib_codec.py which was written -by Marc-Andre Lemburg (mal@lemburg.com). -""" - -import codecs -import bz2 # this codec needs the optional bz2 module ! - -### Codec APIs - -def bz2_encode(input, errors='strict'): - assert errors == 'strict' - return (bz2.compress(input), len(input)) - -def bz2_decode(input, errors='strict'): - assert errors == 'strict' - return (bz2.decompress(input), len(input)) - -class Codec(codecs.Codec): - def encode(self, input, errors='strict'): - return bz2_encode(input, errors) - def decode(self, input, errors='strict'): - return bz2_decode(input, errors) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def __init__(self, errors='strict'): - assert errors == 'strict' - self.errors = errors - self.compressobj = bz2.BZ2Compressor() - - def encode(self, input, final=False): - if final: - c = self.compressobj.compress(input) - return c + self.compressobj.flush() - else: - return self.compressobj.compress(input) - - def reset(self): - self.compressobj = bz2.BZ2Compressor() - -class IncrementalDecoder(codecs.IncrementalDecoder): - def __init__(self, errors='strict'): - assert errors == 'strict' - self.errors = errors - self.decompressobj = bz2.BZ2Decompressor() - - def decode(self, input, final=False): - try: - return self.decompressobj.decompress(input) - except EOFError: - return '' - - def reset(self): - self.decompressobj = bz2.BZ2Decompressor() - -class StreamWriter(Codec, codecs.StreamWriter): - charbuffertype = bytes - -class StreamReader(Codec, codecs.StreamReader): - charbuffertype = bytes - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name="bz2", - encode=bz2_encode, - decode=bz2_decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - _is_text_encoding=False, - ) diff --git a/python/Lib/encodings/charmap.py b/python/Lib/encodings/charmap.py deleted file mode 100644 index 9697493..0000000 --- a/python/Lib/encodings/charmap.py +++ /dev/null @@ -1,69 +0,0 @@ -""" Generic Python Character Mapping Codec. - - Use this codec directly rather than through the automatic - conversion mechanisms supplied by unicode() and .encode(). - - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - # Note: Binding these as C functions will result in the class not - # converting them to methods. This is intended. - encode = codecs.charmap_encode - decode = codecs.charmap_decode - -class IncrementalEncoder(codecs.IncrementalEncoder): - def __init__(self, errors='strict', mapping=None): - codecs.IncrementalEncoder.__init__(self, errors) - self.mapping = mapping - - def encode(self, input, final=False): - return codecs.charmap_encode(input, self.errors, self.mapping)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def __init__(self, errors='strict', mapping=None): - codecs.IncrementalDecoder.__init__(self, errors) - self.mapping = mapping - - def decode(self, input, final=False): - return codecs.charmap_decode(input, self.errors, self.mapping)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - - def __init__(self,stream,errors='strict',mapping=None): - codecs.StreamWriter.__init__(self,stream,errors) - self.mapping = mapping - - def encode(self,input,errors='strict'): - return Codec.encode(input,errors,self.mapping) - -class StreamReader(Codec,codecs.StreamReader): - - def __init__(self,stream,errors='strict',mapping=None): - codecs.StreamReader.__init__(self,stream,errors) - self.mapping = mapping - - def decode(self,input,errors='strict'): - return Codec.decode(input,errors,self.mapping) - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='charmap', - encode=Codec.encode, - decode=Codec.decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) diff --git a/python/Lib/encodings/cp037.py b/python/Lib/encodings/cp037.py deleted file mode 100644 index 97c21ec..0000000 --- a/python/Lib/encodings/cp037.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp037 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp037', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x9c' # 0x04 -> CONTROL - '\t' # 0x05 -> HORIZONTAL TABULATION - '\x86' # 0x06 -> CONTROL - '\x7f' # 0x07 -> DELETE - '\x97' # 0x08 -> CONTROL - '\x8d' # 0x09 -> CONTROL - '\x8e' # 0x0A -> CONTROL - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x9d' # 0x14 -> CONTROL - '\x85' # 0x15 -> CONTROL - '\x08' # 0x16 -> BACKSPACE - '\x87' # 0x17 -> CONTROL - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x92' # 0x1A -> CONTROL - '\x8f' # 0x1B -> CONTROL - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - '\x80' # 0x20 -> CONTROL - '\x81' # 0x21 -> CONTROL - '\x82' # 0x22 -> CONTROL - '\x83' # 0x23 -> CONTROL - '\x84' # 0x24 -> CONTROL - '\n' # 0x25 -> LINE FEED - '\x17' # 0x26 -> END OF TRANSMISSION BLOCK - '\x1b' # 0x27 -> ESCAPE - '\x88' # 0x28 -> CONTROL - '\x89' # 0x29 -> CONTROL - '\x8a' # 0x2A -> CONTROL - '\x8b' # 0x2B -> CONTROL - '\x8c' # 0x2C -> CONTROL - '\x05' # 0x2D -> ENQUIRY - '\x06' # 0x2E -> ACKNOWLEDGE - '\x07' # 0x2F -> BELL - '\x90' # 0x30 -> CONTROL - '\x91' # 0x31 -> CONTROL - '\x16' # 0x32 -> SYNCHRONOUS IDLE - '\x93' # 0x33 -> CONTROL - '\x94' # 0x34 -> CONTROL - '\x95' # 0x35 -> CONTROL - '\x96' # 0x36 -> CONTROL - '\x04' # 0x37 -> END OF TRANSMISSION - '\x98' # 0x38 -> CONTROL - '\x99' # 0x39 -> CONTROL - '\x9a' # 0x3A -> CONTROL - '\x9b' # 0x3B -> CONTROL - '\x14' # 0x3C -> DEVICE CONTROL FOUR - '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE - '\x9e' # 0x3E -> CONTROL - '\x1a' # 0x3F -> SUBSTITUTE - ' ' # 0x40 -> SPACE - '\xa0' # 0x41 -> NO-BREAK SPACE - '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE - '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE - '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA - '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE - '\xa2' # 0x4A -> CENT SIGN - '.' # 0x4B -> FULL STOP - '<' # 0x4C -> LESS-THAN SIGN - '(' # 0x4D -> LEFT PARENTHESIS - '+' # 0x4E -> PLUS SIGN - '|' # 0x4F -> VERTICAL LINE - '&' # 0x50 -> AMPERSAND - '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE - '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE - '\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) - '!' # 0x5A -> EXCLAMATION MARK - '$' # 0x5B -> DOLLAR SIGN - '*' # 0x5C -> ASTERISK - ')' # 0x5D -> RIGHT PARENTHESIS - ';' # 0x5E -> SEMICOLON - '\xac' # 0x5F -> NOT SIGN - '-' # 0x60 -> HYPHEN-MINUS - '/' # 0x61 -> SOLIDUS - '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE - '\xa6' # 0x6A -> BROKEN BAR - ',' # 0x6B -> COMMA - '%' # 0x6C -> PERCENT SIGN - '_' # 0x6D -> LOW LINE - '>' # 0x6E -> GREATER-THAN SIGN - '?' # 0x6F -> QUESTION MARK - '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE - '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE - '`' # 0x79 -> GRAVE ACCENT - ':' # 0x7A -> COLON - '#' # 0x7B -> NUMBER SIGN - '@' # 0x7C -> COMMERCIAL AT - "'" # 0x7D -> APOSTROPHE - '=' # 0x7E -> EQUALS SIGN - '"' # 0x7F -> QUOTATION MARK - '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE - 'a' # 0x81 -> LATIN SMALL LETTER A - 'b' # 0x82 -> LATIN SMALL LETTER B - 'c' # 0x83 -> LATIN SMALL LETTER C - 'd' # 0x84 -> LATIN SMALL LETTER D - 'e' # 0x85 -> LATIN SMALL LETTER E - 'f' # 0x86 -> LATIN SMALL LETTER F - 'g' # 0x87 -> LATIN SMALL LETTER G - 'h' # 0x88 -> LATIN SMALL LETTER H - 'i' # 0x89 -> LATIN SMALL LETTER I - '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xf0' # 0x8C -> LATIN SMALL LETTER ETH (ICELANDIC) - '\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE - '\xfe' # 0x8E -> LATIN SMALL LETTER THORN (ICELANDIC) - '\xb1' # 0x8F -> PLUS-MINUS SIGN - '\xb0' # 0x90 -> DEGREE SIGN - 'j' # 0x91 -> LATIN SMALL LETTER J - 'k' # 0x92 -> LATIN SMALL LETTER K - 'l' # 0x93 -> LATIN SMALL LETTER L - 'm' # 0x94 -> LATIN SMALL LETTER M - 'n' # 0x95 -> LATIN SMALL LETTER N - 'o' # 0x96 -> LATIN SMALL LETTER O - 'p' # 0x97 -> LATIN SMALL LETTER P - 'q' # 0x98 -> LATIN SMALL LETTER Q - 'r' # 0x99 -> LATIN SMALL LETTER R - '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR - '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR - '\xe6' # 0x9C -> LATIN SMALL LIGATURE AE - '\xb8' # 0x9D -> CEDILLA - '\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE - '\xa4' # 0x9F -> CURRENCY SIGN - '\xb5' # 0xA0 -> MICRO SIGN - '~' # 0xA1 -> TILDE - 's' # 0xA2 -> LATIN SMALL LETTER S - 't' # 0xA3 -> LATIN SMALL LETTER T - 'u' # 0xA4 -> LATIN SMALL LETTER U - 'v' # 0xA5 -> LATIN SMALL LETTER V - 'w' # 0xA6 -> LATIN SMALL LETTER W - 'x' # 0xA7 -> LATIN SMALL LETTER X - 'y' # 0xA8 -> LATIN SMALL LETTER Y - 'z' # 0xA9 -> LATIN SMALL LETTER Z - '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK - '\xbf' # 0xAB -> INVERTED QUESTION MARK - '\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC) - '\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC) - '\xae' # 0xAF -> REGISTERED SIGN - '^' # 0xB0 -> CIRCUMFLEX ACCENT - '\xa3' # 0xB1 -> POUND SIGN - '\xa5' # 0xB2 -> YEN SIGN - '\xb7' # 0xB3 -> MIDDLE DOT - '\xa9' # 0xB4 -> COPYRIGHT SIGN - '\xa7' # 0xB5 -> SECTION SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF - '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS - '[' # 0xBA -> LEFT SQUARE BRACKET - ']' # 0xBB -> RIGHT SQUARE BRACKET - '\xaf' # 0xBC -> MACRON - '\xa8' # 0xBD -> DIAERESIS - '\xb4' # 0xBE -> ACUTE ACCENT - '\xd7' # 0xBF -> MULTIPLICATION SIGN - '{' # 0xC0 -> LEFT CURLY BRACKET - 'A' # 0xC1 -> LATIN CAPITAL LETTER A - 'B' # 0xC2 -> LATIN CAPITAL LETTER B - 'C' # 0xC3 -> LATIN CAPITAL LETTER C - 'D' # 0xC4 -> LATIN CAPITAL LETTER D - 'E' # 0xC5 -> LATIN CAPITAL LETTER E - 'F' # 0xC6 -> LATIN CAPITAL LETTER F - 'G' # 0xC7 -> LATIN CAPITAL LETTER G - 'H' # 0xC8 -> LATIN CAPITAL LETTER H - 'I' # 0xC9 -> LATIN CAPITAL LETTER I - '\xad' # 0xCA -> SOFT HYPHEN - '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0xCC -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE - '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE - '}' # 0xD0 -> RIGHT CURLY BRACKET - 'J' # 0xD1 -> LATIN CAPITAL LETTER J - 'K' # 0xD2 -> LATIN CAPITAL LETTER K - 'L' # 0xD3 -> LATIN CAPITAL LETTER L - 'M' # 0xD4 -> LATIN CAPITAL LETTER M - 'N' # 0xD5 -> LATIN CAPITAL LETTER N - 'O' # 0xD6 -> LATIN CAPITAL LETTER O - 'P' # 0xD7 -> LATIN CAPITAL LETTER P - 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q - 'R' # 0xD9 -> LATIN CAPITAL LETTER R - '\xb9' # 0xDA -> SUPERSCRIPT ONE - '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xDC -> LATIN SMALL LETTER U WITH DIAERESIS - '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE - '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS - '\\' # 0xE0 -> REVERSE SOLIDUS - '\xf7' # 0xE1 -> DIVISION SIGN - 'S' # 0xE2 -> LATIN CAPITAL LETTER S - 'T' # 0xE3 -> LATIN CAPITAL LETTER T - 'U' # 0xE4 -> LATIN CAPITAL LETTER U - 'V' # 0xE5 -> LATIN CAPITAL LETTER V - 'W' # 0xE6 -> LATIN CAPITAL LETTER W - 'X' # 0xE7 -> LATIN CAPITAL LETTER X - 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y - 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z - '\xb2' # 0xEA -> SUPERSCRIPT TWO - '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd6' # 0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE - '0' # 0xF0 -> DIGIT ZERO - '1' # 0xF1 -> DIGIT ONE - '2' # 0xF2 -> DIGIT TWO - '3' # 0xF3 -> DIGIT THREE - '4' # 0xF4 -> DIGIT FOUR - '5' # 0xF5 -> DIGIT FIVE - '6' # 0xF6 -> DIGIT SIX - '7' # 0xF7 -> DIGIT SEVEN - '8' # 0xF8 -> DIGIT EIGHT - '9' # 0xF9 -> DIGIT NINE - '\xb3' # 0xFA -> SUPERSCRIPT THREE - '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE - '\x9f' # 0xFF -> CONTROL -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1006.py b/python/Lib/encodings/cp1006.py deleted file mode 100644 index a081734..0000000 --- a/python/Lib/encodings/cp1006.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1006 generated from 'MAPPINGS/VENDORS/MISC/CP1006.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1006', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u06f0' # 0xA1 -> EXTENDED ARABIC-INDIC DIGIT ZERO - '\u06f1' # 0xA2 -> EXTENDED ARABIC-INDIC DIGIT ONE - '\u06f2' # 0xA3 -> EXTENDED ARABIC-INDIC DIGIT TWO - '\u06f3' # 0xA4 -> EXTENDED ARABIC-INDIC DIGIT THREE - '\u06f4' # 0xA5 -> EXTENDED ARABIC-INDIC DIGIT FOUR - '\u06f5' # 0xA6 -> EXTENDED ARABIC-INDIC DIGIT FIVE - '\u06f6' # 0xA7 -> EXTENDED ARABIC-INDIC DIGIT SIX - '\u06f7' # 0xA8 -> EXTENDED ARABIC-INDIC DIGIT SEVEN - '\u06f8' # 0xA9 -> EXTENDED ARABIC-INDIC DIGIT EIGHT - '\u06f9' # 0xAA -> EXTENDED ARABIC-INDIC DIGIT NINE - '\u060c' # 0xAB -> ARABIC COMMA - '\u061b' # 0xAC -> ARABIC SEMICOLON - '\xad' # 0xAD -> SOFT HYPHEN - '\u061f' # 0xAE -> ARABIC QUESTION MARK - '\ufe81' # 0xAF -> ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM - '\ufe8d' # 0xB0 -> ARABIC LETTER ALEF ISOLATED FORM - '\ufe8e' # 0xB1 -> ARABIC LETTER ALEF FINAL FORM - '\ufe8e' # 0xB2 -> ARABIC LETTER ALEF FINAL FORM - '\ufe8f' # 0xB3 -> ARABIC LETTER BEH ISOLATED FORM - '\ufe91' # 0xB4 -> ARABIC LETTER BEH INITIAL FORM - '\ufb56' # 0xB5 -> ARABIC LETTER PEH ISOLATED FORM - '\ufb58' # 0xB6 -> ARABIC LETTER PEH INITIAL FORM - '\ufe93' # 0xB7 -> ARABIC LETTER TEH MARBUTA ISOLATED FORM - '\ufe95' # 0xB8 -> ARABIC LETTER TEH ISOLATED FORM - '\ufe97' # 0xB9 -> ARABIC LETTER TEH INITIAL FORM - '\ufb66' # 0xBA -> ARABIC LETTER TTEH ISOLATED FORM - '\ufb68' # 0xBB -> ARABIC LETTER TTEH INITIAL FORM - '\ufe99' # 0xBC -> ARABIC LETTER THEH ISOLATED FORM - '\ufe9b' # 0xBD -> ARABIC LETTER THEH INITIAL FORM - '\ufe9d' # 0xBE -> ARABIC LETTER JEEM ISOLATED FORM - '\ufe9f' # 0xBF -> ARABIC LETTER JEEM INITIAL FORM - '\ufb7a' # 0xC0 -> ARABIC LETTER TCHEH ISOLATED FORM - '\ufb7c' # 0xC1 -> ARABIC LETTER TCHEH INITIAL FORM - '\ufea1' # 0xC2 -> ARABIC LETTER HAH ISOLATED FORM - '\ufea3' # 0xC3 -> ARABIC LETTER HAH INITIAL FORM - '\ufea5' # 0xC4 -> ARABIC LETTER KHAH ISOLATED FORM - '\ufea7' # 0xC5 -> ARABIC LETTER KHAH INITIAL FORM - '\ufea9' # 0xC6 -> ARABIC LETTER DAL ISOLATED FORM - '\ufb84' # 0xC7 -> ARABIC LETTER DAHAL ISOLATED FORMN - '\ufeab' # 0xC8 -> ARABIC LETTER THAL ISOLATED FORM - '\ufead' # 0xC9 -> ARABIC LETTER REH ISOLATED FORM - '\ufb8c' # 0xCA -> ARABIC LETTER RREH ISOLATED FORM - '\ufeaf' # 0xCB -> ARABIC LETTER ZAIN ISOLATED FORM - '\ufb8a' # 0xCC -> ARABIC LETTER JEH ISOLATED FORM - '\ufeb1' # 0xCD -> ARABIC LETTER SEEN ISOLATED FORM - '\ufeb3' # 0xCE -> ARABIC LETTER SEEN INITIAL FORM - '\ufeb5' # 0xCF -> ARABIC LETTER SHEEN ISOLATED FORM - '\ufeb7' # 0xD0 -> ARABIC LETTER SHEEN INITIAL FORM - '\ufeb9' # 0xD1 -> ARABIC LETTER SAD ISOLATED FORM - '\ufebb' # 0xD2 -> ARABIC LETTER SAD INITIAL FORM - '\ufebd' # 0xD3 -> ARABIC LETTER DAD ISOLATED FORM - '\ufebf' # 0xD4 -> ARABIC LETTER DAD INITIAL FORM - '\ufec1' # 0xD5 -> ARABIC LETTER TAH ISOLATED FORM - '\ufec5' # 0xD6 -> ARABIC LETTER ZAH ISOLATED FORM - '\ufec9' # 0xD7 -> ARABIC LETTER AIN ISOLATED FORM - '\ufeca' # 0xD8 -> ARABIC LETTER AIN FINAL FORM - '\ufecb' # 0xD9 -> ARABIC LETTER AIN INITIAL FORM - '\ufecc' # 0xDA -> ARABIC LETTER AIN MEDIAL FORM - '\ufecd' # 0xDB -> ARABIC LETTER GHAIN ISOLATED FORM - '\ufece' # 0xDC -> ARABIC LETTER GHAIN FINAL FORM - '\ufecf' # 0xDD -> ARABIC LETTER GHAIN INITIAL FORM - '\ufed0' # 0xDE -> ARABIC LETTER GHAIN MEDIAL FORM - '\ufed1' # 0xDF -> ARABIC LETTER FEH ISOLATED FORM - '\ufed3' # 0xE0 -> ARABIC LETTER FEH INITIAL FORM - '\ufed5' # 0xE1 -> ARABIC LETTER QAF ISOLATED FORM - '\ufed7' # 0xE2 -> ARABIC LETTER QAF INITIAL FORM - '\ufed9' # 0xE3 -> ARABIC LETTER KAF ISOLATED FORM - '\ufedb' # 0xE4 -> ARABIC LETTER KAF INITIAL FORM - '\ufb92' # 0xE5 -> ARABIC LETTER GAF ISOLATED FORM - '\ufb94' # 0xE6 -> ARABIC LETTER GAF INITIAL FORM - '\ufedd' # 0xE7 -> ARABIC LETTER LAM ISOLATED FORM - '\ufedf' # 0xE8 -> ARABIC LETTER LAM INITIAL FORM - '\ufee0' # 0xE9 -> ARABIC LETTER LAM MEDIAL FORM - '\ufee1' # 0xEA -> ARABIC LETTER MEEM ISOLATED FORM - '\ufee3' # 0xEB -> ARABIC LETTER MEEM INITIAL FORM - '\ufb9e' # 0xEC -> ARABIC LETTER NOON GHUNNA ISOLATED FORM - '\ufee5' # 0xED -> ARABIC LETTER NOON ISOLATED FORM - '\ufee7' # 0xEE -> ARABIC LETTER NOON INITIAL FORM - '\ufe85' # 0xEF -> ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM - '\ufeed' # 0xF0 -> ARABIC LETTER WAW ISOLATED FORM - '\ufba6' # 0xF1 -> ARABIC LETTER HEH GOAL ISOLATED FORM - '\ufba8' # 0xF2 -> ARABIC LETTER HEH GOAL INITIAL FORM - '\ufba9' # 0xF3 -> ARABIC LETTER HEH GOAL MEDIAL FORM - '\ufbaa' # 0xF4 -> ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM - '\ufe80' # 0xF5 -> ARABIC LETTER HAMZA ISOLATED FORM - '\ufe89' # 0xF6 -> ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM - '\ufe8a' # 0xF7 -> ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM - '\ufe8b' # 0xF8 -> ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM - '\ufef1' # 0xF9 -> ARABIC LETTER YEH ISOLATED FORM - '\ufef2' # 0xFA -> ARABIC LETTER YEH FINAL FORM - '\ufef3' # 0xFB -> ARABIC LETTER YEH INITIAL FORM - '\ufbb0' # 0xFC -> ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM - '\ufbae' # 0xFD -> ARABIC LETTER YEH BARREE ISOLATED FORM - '\ufe7c' # 0xFE -> ARABIC SHADDA ISOLATED FORM - '\ufe7d' # 0xFF -> ARABIC SHADDA MEDIAL FORM -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1026.py b/python/Lib/encodings/cp1026.py deleted file mode 100644 index 7c4e3aa..0000000 --- a/python/Lib/encodings/cp1026.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1026 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP1026.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1026', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x9c' # 0x04 -> CONTROL - '\t' # 0x05 -> HORIZONTAL TABULATION - '\x86' # 0x06 -> CONTROL - '\x7f' # 0x07 -> DELETE - '\x97' # 0x08 -> CONTROL - '\x8d' # 0x09 -> CONTROL - '\x8e' # 0x0A -> CONTROL - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x9d' # 0x14 -> CONTROL - '\x85' # 0x15 -> CONTROL - '\x08' # 0x16 -> BACKSPACE - '\x87' # 0x17 -> CONTROL - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x92' # 0x1A -> CONTROL - '\x8f' # 0x1B -> CONTROL - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - '\x80' # 0x20 -> CONTROL - '\x81' # 0x21 -> CONTROL - '\x82' # 0x22 -> CONTROL - '\x83' # 0x23 -> CONTROL - '\x84' # 0x24 -> CONTROL - '\n' # 0x25 -> LINE FEED - '\x17' # 0x26 -> END OF TRANSMISSION BLOCK - '\x1b' # 0x27 -> ESCAPE - '\x88' # 0x28 -> CONTROL - '\x89' # 0x29 -> CONTROL - '\x8a' # 0x2A -> CONTROL - '\x8b' # 0x2B -> CONTROL - '\x8c' # 0x2C -> CONTROL - '\x05' # 0x2D -> ENQUIRY - '\x06' # 0x2E -> ACKNOWLEDGE - '\x07' # 0x2F -> BELL - '\x90' # 0x30 -> CONTROL - '\x91' # 0x31 -> CONTROL - '\x16' # 0x32 -> SYNCHRONOUS IDLE - '\x93' # 0x33 -> CONTROL - '\x94' # 0x34 -> CONTROL - '\x95' # 0x35 -> CONTROL - '\x96' # 0x36 -> CONTROL - '\x04' # 0x37 -> END OF TRANSMISSION - '\x98' # 0x38 -> CONTROL - '\x99' # 0x39 -> CONTROL - '\x9a' # 0x3A -> CONTROL - '\x9b' # 0x3B -> CONTROL - '\x14' # 0x3C -> DEVICE CONTROL FOUR - '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE - '\x9e' # 0x3E -> CONTROL - '\x1a' # 0x3F -> SUBSTITUTE - ' ' # 0x40 -> SPACE - '\xa0' # 0x41 -> NO-BREAK SPACE - '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE - '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE - '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE - '{' # 0x48 -> LEFT CURLY BRACKET - '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE - '\xc7' # 0x4A -> LATIN CAPITAL LETTER C WITH CEDILLA - '.' # 0x4B -> FULL STOP - '<' # 0x4C -> LESS-THAN SIGN - '(' # 0x4D -> LEFT PARENTHESIS - '+' # 0x4E -> PLUS SIGN - '!' # 0x4F -> EXCLAMATION MARK - '&' # 0x50 -> AMPERSAND - '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE - '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE - '\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) - '\u011e' # 0x5A -> LATIN CAPITAL LETTER G WITH BREVE - '\u0130' # 0x5B -> LATIN CAPITAL LETTER I WITH DOT ABOVE - '*' # 0x5C -> ASTERISK - ')' # 0x5D -> RIGHT PARENTHESIS - ';' # 0x5E -> SEMICOLON - '^' # 0x5F -> CIRCUMFLEX ACCENT - '-' # 0x60 -> HYPHEN-MINUS - '/' # 0x61 -> SOLIDUS - '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '[' # 0x68 -> LEFT SQUARE BRACKET - '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE - '\u015f' # 0x6A -> LATIN SMALL LETTER S WITH CEDILLA - ',' # 0x6B -> COMMA - '%' # 0x6C -> PERCENT SIGN - '_' # 0x6D -> LOW LINE - '>' # 0x6E -> GREATER-THAN SIGN - '?' # 0x6F -> QUESTION MARK - '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE - '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE - '\u0131' # 0x79 -> LATIN SMALL LETTER DOTLESS I - ':' # 0x7A -> COLON - '\xd6' # 0x7B -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\u015e' # 0x7C -> LATIN CAPITAL LETTER S WITH CEDILLA - "'" # 0x7D -> APOSTROPHE - '=' # 0x7E -> EQUALS SIGN - '\xdc' # 0x7F -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE - 'a' # 0x81 -> LATIN SMALL LETTER A - 'b' # 0x82 -> LATIN SMALL LETTER B - 'c' # 0x83 -> LATIN SMALL LETTER C - 'd' # 0x84 -> LATIN SMALL LETTER D - 'e' # 0x85 -> LATIN SMALL LETTER E - 'f' # 0x86 -> LATIN SMALL LETTER F - 'g' # 0x87 -> LATIN SMALL LETTER G - 'h' # 0x88 -> LATIN SMALL LETTER H - 'i' # 0x89 -> LATIN SMALL LETTER I - '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '}' # 0x8C -> RIGHT CURLY BRACKET - '`' # 0x8D -> GRAVE ACCENT - '\xa6' # 0x8E -> BROKEN BAR - '\xb1' # 0x8F -> PLUS-MINUS SIGN - '\xb0' # 0x90 -> DEGREE SIGN - 'j' # 0x91 -> LATIN SMALL LETTER J - 'k' # 0x92 -> LATIN SMALL LETTER K - 'l' # 0x93 -> LATIN SMALL LETTER L - 'm' # 0x94 -> LATIN SMALL LETTER M - 'n' # 0x95 -> LATIN SMALL LETTER N - 'o' # 0x96 -> LATIN SMALL LETTER O - 'p' # 0x97 -> LATIN SMALL LETTER P - 'q' # 0x98 -> LATIN SMALL LETTER Q - 'r' # 0x99 -> LATIN SMALL LETTER R - '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR - '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR - '\xe6' # 0x9C -> LATIN SMALL LIGATURE AE - '\xb8' # 0x9D -> CEDILLA - '\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE - '\xa4' # 0x9F -> CURRENCY SIGN - '\xb5' # 0xA0 -> MICRO SIGN - '\xf6' # 0xA1 -> LATIN SMALL LETTER O WITH DIAERESIS - 's' # 0xA2 -> LATIN SMALL LETTER S - 't' # 0xA3 -> LATIN SMALL LETTER T - 'u' # 0xA4 -> LATIN SMALL LETTER U - 'v' # 0xA5 -> LATIN SMALL LETTER V - 'w' # 0xA6 -> LATIN SMALL LETTER W - 'x' # 0xA7 -> LATIN SMALL LETTER X - 'y' # 0xA8 -> LATIN SMALL LETTER Y - 'z' # 0xA9 -> LATIN SMALL LETTER Z - '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK - '\xbf' # 0xAB -> INVERTED QUESTION MARK - ']' # 0xAC -> RIGHT SQUARE BRACKET - '$' # 0xAD -> DOLLAR SIGN - '@' # 0xAE -> COMMERCIAL AT - '\xae' # 0xAF -> REGISTERED SIGN - '\xa2' # 0xB0 -> CENT SIGN - '\xa3' # 0xB1 -> POUND SIGN - '\xa5' # 0xB2 -> YEN SIGN - '\xb7' # 0xB3 -> MIDDLE DOT - '\xa9' # 0xB4 -> COPYRIGHT SIGN - '\xa7' # 0xB5 -> SECTION SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF - '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS - '\xac' # 0xBA -> NOT SIGN - '|' # 0xBB -> VERTICAL LINE - '\xaf' # 0xBC -> MACRON - '\xa8' # 0xBD -> DIAERESIS - '\xb4' # 0xBE -> ACUTE ACCENT - '\xd7' # 0xBF -> MULTIPLICATION SIGN - '\xe7' # 0xC0 -> LATIN SMALL LETTER C WITH CEDILLA - 'A' # 0xC1 -> LATIN CAPITAL LETTER A - 'B' # 0xC2 -> LATIN CAPITAL LETTER B - 'C' # 0xC3 -> LATIN CAPITAL LETTER C - 'D' # 0xC4 -> LATIN CAPITAL LETTER D - 'E' # 0xC5 -> LATIN CAPITAL LETTER E - 'F' # 0xC6 -> LATIN CAPITAL LETTER F - 'G' # 0xC7 -> LATIN CAPITAL LETTER G - 'H' # 0xC8 -> LATIN CAPITAL LETTER H - 'I' # 0xC9 -> LATIN CAPITAL LETTER I - '\xad' # 0xCA -> SOFT HYPHEN - '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '~' # 0xCC -> TILDE - '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE - '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE - '\u011f' # 0xD0 -> LATIN SMALL LETTER G WITH BREVE - 'J' # 0xD1 -> LATIN CAPITAL LETTER J - 'K' # 0xD2 -> LATIN CAPITAL LETTER K - 'L' # 0xD3 -> LATIN CAPITAL LETTER L - 'M' # 0xD4 -> LATIN CAPITAL LETTER M - 'N' # 0xD5 -> LATIN CAPITAL LETTER N - 'O' # 0xD6 -> LATIN CAPITAL LETTER O - 'P' # 0xD7 -> LATIN CAPITAL LETTER P - 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q - 'R' # 0xD9 -> LATIN CAPITAL LETTER R - '\xb9' # 0xDA -> SUPERSCRIPT ONE - '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\\' # 0xDC -> REVERSE SOLIDUS - '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE - '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS - '\xfc' # 0xE0 -> LATIN SMALL LETTER U WITH DIAERESIS - '\xf7' # 0xE1 -> DIVISION SIGN - 'S' # 0xE2 -> LATIN CAPITAL LETTER S - 'T' # 0xE3 -> LATIN CAPITAL LETTER T - 'U' # 0xE4 -> LATIN CAPITAL LETTER U - 'V' # 0xE5 -> LATIN CAPITAL LETTER V - 'W' # 0xE6 -> LATIN CAPITAL LETTER W - 'X' # 0xE7 -> LATIN CAPITAL LETTER X - 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y - 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z - '\xb2' # 0xEA -> SUPERSCRIPT TWO - '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '#' # 0xEC -> NUMBER SIGN - '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE - '0' # 0xF0 -> DIGIT ZERO - '1' # 0xF1 -> DIGIT ONE - '2' # 0xF2 -> DIGIT TWO - '3' # 0xF3 -> DIGIT THREE - '4' # 0xF4 -> DIGIT FOUR - '5' # 0xF5 -> DIGIT FIVE - '6' # 0xF6 -> DIGIT SIX - '7' # 0xF7 -> DIGIT SEVEN - '8' # 0xF8 -> DIGIT EIGHT - '9' # 0xF9 -> DIGIT NINE - '\xb3' # 0xFA -> SUPERSCRIPT THREE - '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '"' # 0xFC -> QUOTATION MARK - '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE - '\x9f' # 0xFF -> CONTROL -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1125.py b/python/Lib/encodings/cp1125.py deleted file mode 100644 index 637dcc7..0000000 --- a/python/Lib/encodings/cp1125.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec for CP1125 - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1125', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x0410, # CYRILLIC CAPITAL LETTER A - 0x0081: 0x0411, # CYRILLIC CAPITAL LETTER BE - 0x0082: 0x0412, # CYRILLIC CAPITAL LETTER VE - 0x0083: 0x0413, # CYRILLIC CAPITAL LETTER GHE - 0x0084: 0x0414, # CYRILLIC CAPITAL LETTER DE - 0x0085: 0x0415, # CYRILLIC CAPITAL LETTER IE - 0x0086: 0x0416, # CYRILLIC CAPITAL LETTER ZHE - 0x0087: 0x0417, # CYRILLIC CAPITAL LETTER ZE - 0x0088: 0x0418, # CYRILLIC CAPITAL LETTER I - 0x0089: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I - 0x008a: 0x041a, # CYRILLIC CAPITAL LETTER KA - 0x008b: 0x041b, # CYRILLIC CAPITAL LETTER EL - 0x008c: 0x041c, # CYRILLIC CAPITAL LETTER EM - 0x008d: 0x041d, # CYRILLIC CAPITAL LETTER EN - 0x008e: 0x041e, # CYRILLIC CAPITAL LETTER O - 0x008f: 0x041f, # CYRILLIC CAPITAL LETTER PE - 0x0090: 0x0420, # CYRILLIC CAPITAL LETTER ER - 0x0091: 0x0421, # CYRILLIC CAPITAL LETTER ES - 0x0092: 0x0422, # CYRILLIC CAPITAL LETTER TE - 0x0093: 0x0423, # CYRILLIC CAPITAL LETTER U - 0x0094: 0x0424, # CYRILLIC CAPITAL LETTER EF - 0x0095: 0x0425, # CYRILLIC CAPITAL LETTER HA - 0x0096: 0x0426, # CYRILLIC CAPITAL LETTER TSE - 0x0097: 0x0427, # CYRILLIC CAPITAL LETTER CHE - 0x0098: 0x0428, # CYRILLIC CAPITAL LETTER SHA - 0x0099: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA - 0x009a: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN - 0x009b: 0x042b, # CYRILLIC CAPITAL LETTER YERU - 0x009c: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN - 0x009d: 0x042d, # CYRILLIC CAPITAL LETTER E - 0x009e: 0x042e, # CYRILLIC CAPITAL LETTER YU - 0x009f: 0x042f, # CYRILLIC CAPITAL LETTER YA - 0x00a0: 0x0430, # CYRILLIC SMALL LETTER A - 0x00a1: 0x0431, # CYRILLIC SMALL LETTER BE - 0x00a2: 0x0432, # CYRILLIC SMALL LETTER VE - 0x00a3: 0x0433, # CYRILLIC SMALL LETTER GHE - 0x00a4: 0x0434, # CYRILLIC SMALL LETTER DE - 0x00a5: 0x0435, # CYRILLIC SMALL LETTER IE - 0x00a6: 0x0436, # CYRILLIC SMALL LETTER ZHE - 0x00a7: 0x0437, # CYRILLIC SMALL LETTER ZE - 0x00a8: 0x0438, # CYRILLIC SMALL LETTER I - 0x00a9: 0x0439, # CYRILLIC SMALL LETTER SHORT I - 0x00aa: 0x043a, # CYRILLIC SMALL LETTER KA - 0x00ab: 0x043b, # CYRILLIC SMALL LETTER EL - 0x00ac: 0x043c, # CYRILLIC SMALL LETTER EM - 0x00ad: 0x043d, # CYRILLIC SMALL LETTER EN - 0x00ae: 0x043e, # CYRILLIC SMALL LETTER O - 0x00af: 0x043f, # CYRILLIC SMALL LETTER PE - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x258c, # LEFT HALF BLOCK - 0x00de: 0x2590, # RIGHT HALF BLOCK - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x0440, # CYRILLIC SMALL LETTER ER - 0x00e1: 0x0441, # CYRILLIC SMALL LETTER ES - 0x00e2: 0x0442, # CYRILLIC SMALL LETTER TE - 0x00e3: 0x0443, # CYRILLIC SMALL LETTER U - 0x00e4: 0x0444, # CYRILLIC SMALL LETTER EF - 0x00e5: 0x0445, # CYRILLIC SMALL LETTER HA - 0x00e6: 0x0446, # CYRILLIC SMALL LETTER TSE - 0x00e7: 0x0447, # CYRILLIC SMALL LETTER CHE - 0x00e8: 0x0448, # CYRILLIC SMALL LETTER SHA - 0x00e9: 0x0449, # CYRILLIC SMALL LETTER SHCHA - 0x00ea: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN - 0x00eb: 0x044b, # CYRILLIC SMALL LETTER YERU - 0x00ec: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN - 0x00ed: 0x044d, # CYRILLIC SMALL LETTER E - 0x00ee: 0x044e, # CYRILLIC SMALL LETTER YU - 0x00ef: 0x044f, # CYRILLIC SMALL LETTER YA - 0x00f0: 0x0401, # CYRILLIC CAPITAL LETTER IO - 0x00f1: 0x0451, # CYRILLIC SMALL LETTER IO - 0x00f2: 0x0490, # CYRILLIC CAPITAL LETTER GHE WITH UPTURN - 0x00f3: 0x0491, # CYRILLIC SMALL LETTER GHE WITH UPTURN - 0x00f4: 0x0404, # CYRILLIC CAPITAL LETTER UKRAINIAN IE - 0x00f5: 0x0454, # CYRILLIC SMALL LETTER UKRAINIAN IE - 0x00f6: 0x0406, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - 0x00f7: 0x0456, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - 0x00f8: 0x0407, # CYRILLIC CAPITAL LETTER YI - 0x00f9: 0x0457, # CYRILLIC SMALL LETTER YI - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x221a, # SQUARE ROOT - 0x00fc: 0x2116, # NUMERO SIGN - 0x00fd: 0x00a4, # CURRENCY SIGN - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\u0410' # 0x0080 -> CYRILLIC CAPITAL LETTER A - '\u0411' # 0x0081 -> CYRILLIC CAPITAL LETTER BE - '\u0412' # 0x0082 -> CYRILLIC CAPITAL LETTER VE - '\u0413' # 0x0083 -> CYRILLIC CAPITAL LETTER GHE - '\u0414' # 0x0084 -> CYRILLIC CAPITAL LETTER DE - '\u0415' # 0x0085 -> CYRILLIC CAPITAL LETTER IE - '\u0416' # 0x0086 -> CYRILLIC CAPITAL LETTER ZHE - '\u0417' # 0x0087 -> CYRILLIC CAPITAL LETTER ZE - '\u0418' # 0x0088 -> CYRILLIC CAPITAL LETTER I - '\u0419' # 0x0089 -> CYRILLIC CAPITAL LETTER SHORT I - '\u041a' # 0x008a -> CYRILLIC CAPITAL LETTER KA - '\u041b' # 0x008b -> CYRILLIC CAPITAL LETTER EL - '\u041c' # 0x008c -> CYRILLIC CAPITAL LETTER EM - '\u041d' # 0x008d -> CYRILLIC CAPITAL LETTER EN - '\u041e' # 0x008e -> CYRILLIC CAPITAL LETTER O - '\u041f' # 0x008f -> CYRILLIC CAPITAL LETTER PE - '\u0420' # 0x0090 -> CYRILLIC CAPITAL LETTER ER - '\u0421' # 0x0091 -> CYRILLIC CAPITAL LETTER ES - '\u0422' # 0x0092 -> CYRILLIC CAPITAL LETTER TE - '\u0423' # 0x0093 -> CYRILLIC CAPITAL LETTER U - '\u0424' # 0x0094 -> CYRILLIC CAPITAL LETTER EF - '\u0425' # 0x0095 -> CYRILLIC CAPITAL LETTER HA - '\u0426' # 0x0096 -> CYRILLIC CAPITAL LETTER TSE - '\u0427' # 0x0097 -> CYRILLIC CAPITAL LETTER CHE - '\u0428' # 0x0098 -> CYRILLIC CAPITAL LETTER SHA - '\u0429' # 0x0099 -> CYRILLIC CAPITAL LETTER SHCHA - '\u042a' # 0x009a -> CYRILLIC CAPITAL LETTER HARD SIGN - '\u042b' # 0x009b -> CYRILLIC CAPITAL LETTER YERU - '\u042c' # 0x009c -> CYRILLIC CAPITAL LETTER SOFT SIGN - '\u042d' # 0x009d -> CYRILLIC CAPITAL LETTER E - '\u042e' # 0x009e -> CYRILLIC CAPITAL LETTER YU - '\u042f' # 0x009f -> CYRILLIC CAPITAL LETTER YA - '\u0430' # 0x00a0 -> CYRILLIC SMALL LETTER A - '\u0431' # 0x00a1 -> CYRILLIC SMALL LETTER BE - '\u0432' # 0x00a2 -> CYRILLIC SMALL LETTER VE - '\u0433' # 0x00a3 -> CYRILLIC SMALL LETTER GHE - '\u0434' # 0x00a4 -> CYRILLIC SMALL LETTER DE - '\u0435' # 0x00a5 -> CYRILLIC SMALL LETTER IE - '\u0436' # 0x00a6 -> CYRILLIC SMALL LETTER ZHE - '\u0437' # 0x00a7 -> CYRILLIC SMALL LETTER ZE - '\u0438' # 0x00a8 -> CYRILLIC SMALL LETTER I - '\u0439' # 0x00a9 -> CYRILLIC SMALL LETTER SHORT I - '\u043a' # 0x00aa -> CYRILLIC SMALL LETTER KA - '\u043b' # 0x00ab -> CYRILLIC SMALL LETTER EL - '\u043c' # 0x00ac -> CYRILLIC SMALL LETTER EM - '\u043d' # 0x00ad -> CYRILLIC SMALL LETTER EN - '\u043e' # 0x00ae -> CYRILLIC SMALL LETTER O - '\u043f' # 0x00af -> CYRILLIC SMALL LETTER PE - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u258c' # 0x00dd -> LEFT HALF BLOCK - '\u2590' # 0x00de -> RIGHT HALF BLOCK - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\u0440' # 0x00e0 -> CYRILLIC SMALL LETTER ER - '\u0441' # 0x00e1 -> CYRILLIC SMALL LETTER ES - '\u0442' # 0x00e2 -> CYRILLIC SMALL LETTER TE - '\u0443' # 0x00e3 -> CYRILLIC SMALL LETTER U - '\u0444' # 0x00e4 -> CYRILLIC SMALL LETTER EF - '\u0445' # 0x00e5 -> CYRILLIC SMALL LETTER HA - '\u0446' # 0x00e6 -> CYRILLIC SMALL LETTER TSE - '\u0447' # 0x00e7 -> CYRILLIC SMALL LETTER CHE - '\u0448' # 0x00e8 -> CYRILLIC SMALL LETTER SHA - '\u0449' # 0x00e9 -> CYRILLIC SMALL LETTER SHCHA - '\u044a' # 0x00ea -> CYRILLIC SMALL LETTER HARD SIGN - '\u044b' # 0x00eb -> CYRILLIC SMALL LETTER YERU - '\u044c' # 0x00ec -> CYRILLIC SMALL LETTER SOFT SIGN - '\u044d' # 0x00ed -> CYRILLIC SMALL LETTER E - '\u044e' # 0x00ee -> CYRILLIC SMALL LETTER YU - '\u044f' # 0x00ef -> CYRILLIC SMALL LETTER YA - '\u0401' # 0x00f0 -> CYRILLIC CAPITAL LETTER IO - '\u0451' # 0x00f1 -> CYRILLIC SMALL LETTER IO - '\u0490' # 0x00f2 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN - '\u0491' # 0x00f3 -> CYRILLIC SMALL LETTER GHE WITH UPTURN - '\u0404' # 0x00f4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE - '\u0454' # 0x00f5 -> CYRILLIC SMALL LETTER UKRAINIAN IE - '\u0406' # 0x00f6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0456' # 0x00f7 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0407' # 0x00f8 -> CYRILLIC CAPITAL LETTER YI - '\u0457' # 0x00f9 -> CYRILLIC SMALL LETTER YI - '\xb7' # 0x00fa -> MIDDLE DOT - '\u221a' # 0x00fb -> SQUARE ROOT - '\u2116' # 0x00fc -> NUMERO SIGN - '\xa4' # 0x00fd -> CURRENCY SIGN - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a4: 0x00fd, # CURRENCY SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x0401: 0x00f0, # CYRILLIC CAPITAL LETTER IO - 0x0404: 0x00f4, # CYRILLIC CAPITAL LETTER UKRAINIAN IE - 0x0406: 0x00f6, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - 0x0407: 0x00f8, # CYRILLIC CAPITAL LETTER YI - 0x0410: 0x0080, # CYRILLIC CAPITAL LETTER A - 0x0411: 0x0081, # CYRILLIC CAPITAL LETTER BE - 0x0412: 0x0082, # CYRILLIC CAPITAL LETTER VE - 0x0413: 0x0083, # CYRILLIC CAPITAL LETTER GHE - 0x0414: 0x0084, # CYRILLIC CAPITAL LETTER DE - 0x0415: 0x0085, # CYRILLIC CAPITAL LETTER IE - 0x0416: 0x0086, # CYRILLIC CAPITAL LETTER ZHE - 0x0417: 0x0087, # CYRILLIC CAPITAL LETTER ZE - 0x0418: 0x0088, # CYRILLIC CAPITAL LETTER I - 0x0419: 0x0089, # CYRILLIC CAPITAL LETTER SHORT I - 0x041a: 0x008a, # CYRILLIC CAPITAL LETTER KA - 0x041b: 0x008b, # CYRILLIC CAPITAL LETTER EL - 0x041c: 0x008c, # CYRILLIC CAPITAL LETTER EM - 0x041d: 0x008d, # CYRILLIC CAPITAL LETTER EN - 0x041e: 0x008e, # CYRILLIC CAPITAL LETTER O - 0x041f: 0x008f, # CYRILLIC CAPITAL LETTER PE - 0x0420: 0x0090, # CYRILLIC CAPITAL LETTER ER - 0x0421: 0x0091, # CYRILLIC CAPITAL LETTER ES - 0x0422: 0x0092, # CYRILLIC CAPITAL LETTER TE - 0x0423: 0x0093, # CYRILLIC CAPITAL LETTER U - 0x0424: 0x0094, # CYRILLIC CAPITAL LETTER EF - 0x0425: 0x0095, # CYRILLIC CAPITAL LETTER HA - 0x0426: 0x0096, # CYRILLIC CAPITAL LETTER TSE - 0x0427: 0x0097, # CYRILLIC CAPITAL LETTER CHE - 0x0428: 0x0098, # CYRILLIC CAPITAL LETTER SHA - 0x0429: 0x0099, # CYRILLIC CAPITAL LETTER SHCHA - 0x042a: 0x009a, # CYRILLIC CAPITAL LETTER HARD SIGN - 0x042b: 0x009b, # CYRILLIC CAPITAL LETTER YERU - 0x042c: 0x009c, # CYRILLIC CAPITAL LETTER SOFT SIGN - 0x042d: 0x009d, # CYRILLIC CAPITAL LETTER E - 0x042e: 0x009e, # CYRILLIC CAPITAL LETTER YU - 0x042f: 0x009f, # CYRILLIC CAPITAL LETTER YA - 0x0430: 0x00a0, # CYRILLIC SMALL LETTER A - 0x0431: 0x00a1, # CYRILLIC SMALL LETTER BE - 0x0432: 0x00a2, # CYRILLIC SMALL LETTER VE - 0x0433: 0x00a3, # CYRILLIC SMALL LETTER GHE - 0x0434: 0x00a4, # CYRILLIC SMALL LETTER DE - 0x0435: 0x00a5, # CYRILLIC SMALL LETTER IE - 0x0436: 0x00a6, # CYRILLIC SMALL LETTER ZHE - 0x0437: 0x00a7, # CYRILLIC SMALL LETTER ZE - 0x0438: 0x00a8, # CYRILLIC SMALL LETTER I - 0x0439: 0x00a9, # CYRILLIC SMALL LETTER SHORT I - 0x043a: 0x00aa, # CYRILLIC SMALL LETTER KA - 0x043b: 0x00ab, # CYRILLIC SMALL LETTER EL - 0x043c: 0x00ac, # CYRILLIC SMALL LETTER EM - 0x043d: 0x00ad, # CYRILLIC SMALL LETTER EN - 0x043e: 0x00ae, # CYRILLIC SMALL LETTER O - 0x043f: 0x00af, # CYRILLIC SMALL LETTER PE - 0x0440: 0x00e0, # CYRILLIC SMALL LETTER ER - 0x0441: 0x00e1, # CYRILLIC SMALL LETTER ES - 0x0442: 0x00e2, # CYRILLIC SMALL LETTER TE - 0x0443: 0x00e3, # CYRILLIC SMALL LETTER U - 0x0444: 0x00e4, # CYRILLIC SMALL LETTER EF - 0x0445: 0x00e5, # CYRILLIC SMALL LETTER HA - 0x0446: 0x00e6, # CYRILLIC SMALL LETTER TSE - 0x0447: 0x00e7, # CYRILLIC SMALL LETTER CHE - 0x0448: 0x00e8, # CYRILLIC SMALL LETTER SHA - 0x0449: 0x00e9, # CYRILLIC SMALL LETTER SHCHA - 0x044a: 0x00ea, # CYRILLIC SMALL LETTER HARD SIGN - 0x044b: 0x00eb, # CYRILLIC SMALL LETTER YERU - 0x044c: 0x00ec, # CYRILLIC SMALL LETTER SOFT SIGN - 0x044d: 0x00ed, # CYRILLIC SMALL LETTER E - 0x044e: 0x00ee, # CYRILLIC SMALL LETTER YU - 0x044f: 0x00ef, # CYRILLIC SMALL LETTER YA - 0x0451: 0x00f1, # CYRILLIC SMALL LETTER IO - 0x0454: 0x00f5, # CYRILLIC SMALL LETTER UKRAINIAN IE - 0x0456: 0x00f7, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - 0x0457: 0x00f9, # CYRILLIC SMALL LETTER YI - 0x0490: 0x00f2, # CYRILLIC CAPITAL LETTER GHE WITH UPTURN - 0x0491: 0x00f3, # CYRILLIC SMALL LETTER GHE WITH UPTURN - 0x2116: 0x00fc, # NUMERO SIGN - 0x221a: 0x00fb, # SQUARE ROOT - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x258c: 0x00dd, # LEFT HALF BLOCK - 0x2590: 0x00de, # RIGHT HALF BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp1140.py b/python/Lib/encodings/cp1140.py deleted file mode 100644 index 1dd64fd..0000000 --- a/python/Lib/encodings/cp1140.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1140 generated from 'python-mappings/CP1140.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1140', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x9c' # 0x04 -> CONTROL - '\t' # 0x05 -> HORIZONTAL TABULATION - '\x86' # 0x06 -> CONTROL - '\x7f' # 0x07 -> DELETE - '\x97' # 0x08 -> CONTROL - '\x8d' # 0x09 -> CONTROL - '\x8e' # 0x0A -> CONTROL - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x9d' # 0x14 -> CONTROL - '\x85' # 0x15 -> CONTROL - '\x08' # 0x16 -> BACKSPACE - '\x87' # 0x17 -> CONTROL - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x92' # 0x1A -> CONTROL - '\x8f' # 0x1B -> CONTROL - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - '\x80' # 0x20 -> CONTROL - '\x81' # 0x21 -> CONTROL - '\x82' # 0x22 -> CONTROL - '\x83' # 0x23 -> CONTROL - '\x84' # 0x24 -> CONTROL - '\n' # 0x25 -> LINE FEED - '\x17' # 0x26 -> END OF TRANSMISSION BLOCK - '\x1b' # 0x27 -> ESCAPE - '\x88' # 0x28 -> CONTROL - '\x89' # 0x29 -> CONTROL - '\x8a' # 0x2A -> CONTROL - '\x8b' # 0x2B -> CONTROL - '\x8c' # 0x2C -> CONTROL - '\x05' # 0x2D -> ENQUIRY - '\x06' # 0x2E -> ACKNOWLEDGE - '\x07' # 0x2F -> BELL - '\x90' # 0x30 -> CONTROL - '\x91' # 0x31 -> CONTROL - '\x16' # 0x32 -> SYNCHRONOUS IDLE - '\x93' # 0x33 -> CONTROL - '\x94' # 0x34 -> CONTROL - '\x95' # 0x35 -> CONTROL - '\x96' # 0x36 -> CONTROL - '\x04' # 0x37 -> END OF TRANSMISSION - '\x98' # 0x38 -> CONTROL - '\x99' # 0x39 -> CONTROL - '\x9a' # 0x3A -> CONTROL - '\x9b' # 0x3B -> CONTROL - '\x14' # 0x3C -> DEVICE CONTROL FOUR - '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE - '\x9e' # 0x3E -> CONTROL - '\x1a' # 0x3F -> SUBSTITUTE - ' ' # 0x40 -> SPACE - '\xa0' # 0x41 -> NO-BREAK SPACE - '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE - '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE - '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA - '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE - '\xa2' # 0x4A -> CENT SIGN - '.' # 0x4B -> FULL STOP - '<' # 0x4C -> LESS-THAN SIGN - '(' # 0x4D -> LEFT PARENTHESIS - '+' # 0x4E -> PLUS SIGN - '|' # 0x4F -> VERTICAL LINE - '&' # 0x50 -> AMPERSAND - '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE - '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE - '\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) - '!' # 0x5A -> EXCLAMATION MARK - '$' # 0x5B -> DOLLAR SIGN - '*' # 0x5C -> ASTERISK - ')' # 0x5D -> RIGHT PARENTHESIS - ';' # 0x5E -> SEMICOLON - '\xac' # 0x5F -> NOT SIGN - '-' # 0x60 -> HYPHEN-MINUS - '/' # 0x61 -> SOLIDUS - '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE - '\xa6' # 0x6A -> BROKEN BAR - ',' # 0x6B -> COMMA - '%' # 0x6C -> PERCENT SIGN - '_' # 0x6D -> LOW LINE - '>' # 0x6E -> GREATER-THAN SIGN - '?' # 0x6F -> QUESTION MARK - '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE - '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE - '`' # 0x79 -> GRAVE ACCENT - ':' # 0x7A -> COLON - '#' # 0x7B -> NUMBER SIGN - '@' # 0x7C -> COMMERCIAL AT - "'" # 0x7D -> APOSTROPHE - '=' # 0x7E -> EQUALS SIGN - '"' # 0x7F -> QUOTATION MARK - '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE - 'a' # 0x81 -> LATIN SMALL LETTER A - 'b' # 0x82 -> LATIN SMALL LETTER B - 'c' # 0x83 -> LATIN SMALL LETTER C - 'd' # 0x84 -> LATIN SMALL LETTER D - 'e' # 0x85 -> LATIN SMALL LETTER E - 'f' # 0x86 -> LATIN SMALL LETTER F - 'g' # 0x87 -> LATIN SMALL LETTER G - 'h' # 0x88 -> LATIN SMALL LETTER H - 'i' # 0x89 -> LATIN SMALL LETTER I - '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xf0' # 0x8C -> LATIN SMALL LETTER ETH (ICELANDIC) - '\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE - '\xfe' # 0x8E -> LATIN SMALL LETTER THORN (ICELANDIC) - '\xb1' # 0x8F -> PLUS-MINUS SIGN - '\xb0' # 0x90 -> DEGREE SIGN - 'j' # 0x91 -> LATIN SMALL LETTER J - 'k' # 0x92 -> LATIN SMALL LETTER K - 'l' # 0x93 -> LATIN SMALL LETTER L - 'm' # 0x94 -> LATIN SMALL LETTER M - 'n' # 0x95 -> LATIN SMALL LETTER N - 'o' # 0x96 -> LATIN SMALL LETTER O - 'p' # 0x97 -> LATIN SMALL LETTER P - 'q' # 0x98 -> LATIN SMALL LETTER Q - 'r' # 0x99 -> LATIN SMALL LETTER R - '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR - '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR - '\xe6' # 0x9C -> LATIN SMALL LIGATURE AE - '\xb8' # 0x9D -> CEDILLA - '\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE - '\u20ac' # 0x9F -> EURO SIGN - '\xb5' # 0xA0 -> MICRO SIGN - '~' # 0xA1 -> TILDE - 's' # 0xA2 -> LATIN SMALL LETTER S - 't' # 0xA3 -> LATIN SMALL LETTER T - 'u' # 0xA4 -> LATIN SMALL LETTER U - 'v' # 0xA5 -> LATIN SMALL LETTER V - 'w' # 0xA6 -> LATIN SMALL LETTER W - 'x' # 0xA7 -> LATIN SMALL LETTER X - 'y' # 0xA8 -> LATIN SMALL LETTER Y - 'z' # 0xA9 -> LATIN SMALL LETTER Z - '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK - '\xbf' # 0xAB -> INVERTED QUESTION MARK - '\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC) - '\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC) - '\xae' # 0xAF -> REGISTERED SIGN - '^' # 0xB0 -> CIRCUMFLEX ACCENT - '\xa3' # 0xB1 -> POUND SIGN - '\xa5' # 0xB2 -> YEN SIGN - '\xb7' # 0xB3 -> MIDDLE DOT - '\xa9' # 0xB4 -> COPYRIGHT SIGN - '\xa7' # 0xB5 -> SECTION SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF - '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS - '[' # 0xBA -> LEFT SQUARE BRACKET - ']' # 0xBB -> RIGHT SQUARE BRACKET - '\xaf' # 0xBC -> MACRON - '\xa8' # 0xBD -> DIAERESIS - '\xb4' # 0xBE -> ACUTE ACCENT - '\xd7' # 0xBF -> MULTIPLICATION SIGN - '{' # 0xC0 -> LEFT CURLY BRACKET - 'A' # 0xC1 -> LATIN CAPITAL LETTER A - 'B' # 0xC2 -> LATIN CAPITAL LETTER B - 'C' # 0xC3 -> LATIN CAPITAL LETTER C - 'D' # 0xC4 -> LATIN CAPITAL LETTER D - 'E' # 0xC5 -> LATIN CAPITAL LETTER E - 'F' # 0xC6 -> LATIN CAPITAL LETTER F - 'G' # 0xC7 -> LATIN CAPITAL LETTER G - 'H' # 0xC8 -> LATIN CAPITAL LETTER H - 'I' # 0xC9 -> LATIN CAPITAL LETTER I - '\xad' # 0xCA -> SOFT HYPHEN - '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0xCC -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE - '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE - '}' # 0xD0 -> RIGHT CURLY BRACKET - 'J' # 0xD1 -> LATIN CAPITAL LETTER J - 'K' # 0xD2 -> LATIN CAPITAL LETTER K - 'L' # 0xD3 -> LATIN CAPITAL LETTER L - 'M' # 0xD4 -> LATIN CAPITAL LETTER M - 'N' # 0xD5 -> LATIN CAPITAL LETTER N - 'O' # 0xD6 -> LATIN CAPITAL LETTER O - 'P' # 0xD7 -> LATIN CAPITAL LETTER P - 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q - 'R' # 0xD9 -> LATIN CAPITAL LETTER R - '\xb9' # 0xDA -> SUPERSCRIPT ONE - '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xDC -> LATIN SMALL LETTER U WITH DIAERESIS - '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE - '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS - '\\' # 0xE0 -> REVERSE SOLIDUS - '\xf7' # 0xE1 -> DIVISION SIGN - 'S' # 0xE2 -> LATIN CAPITAL LETTER S - 'T' # 0xE3 -> LATIN CAPITAL LETTER T - 'U' # 0xE4 -> LATIN CAPITAL LETTER U - 'V' # 0xE5 -> LATIN CAPITAL LETTER V - 'W' # 0xE6 -> LATIN CAPITAL LETTER W - 'X' # 0xE7 -> LATIN CAPITAL LETTER X - 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y - 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z - '\xb2' # 0xEA -> SUPERSCRIPT TWO - '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd6' # 0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE - '0' # 0xF0 -> DIGIT ZERO - '1' # 0xF1 -> DIGIT ONE - '2' # 0xF2 -> DIGIT TWO - '3' # 0xF3 -> DIGIT THREE - '4' # 0xF4 -> DIGIT FOUR - '5' # 0xF5 -> DIGIT FIVE - '6' # 0xF6 -> DIGIT SIX - '7' # 0xF7 -> DIGIT SEVEN - '8' # 0xF8 -> DIGIT EIGHT - '9' # 0xF9 -> DIGIT NINE - '\xb3' # 0xFA -> SUPERSCRIPT THREE - '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE - '\x9f' # 0xFF -> CONTROL -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1250.py b/python/Lib/encodings/cp1250.py deleted file mode 100644 index 548d865..0000000 --- a/python/Lib/encodings/cp1250.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1250 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1250', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u20ac' # 0x80 -> EURO SIGN - '\ufffe' # 0x81 -> UNDEFINED - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\ufffe' # 0x83 -> UNDEFINED - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\ufffe' # 0x88 -> UNDEFINED - '\u2030' # 0x89 -> PER MILLE SIGN - '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u015a' # 0x8C -> LATIN CAPITAL LETTER S WITH ACUTE - '\u0164' # 0x8D -> LATIN CAPITAL LETTER T WITH CARON - '\u017d' # 0x8E -> LATIN CAPITAL LETTER Z WITH CARON - '\u0179' # 0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE - '\ufffe' # 0x90 -> UNDEFINED - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\ufffe' # 0x98 -> UNDEFINED - '\u2122' # 0x99 -> TRADE MARK SIGN - '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON - '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\u015b' # 0x9C -> LATIN SMALL LETTER S WITH ACUTE - '\u0165' # 0x9D -> LATIN SMALL LETTER T WITH CARON - '\u017e' # 0x9E -> LATIN SMALL LETTER Z WITH CARON - '\u017a' # 0x9F -> LATIN SMALL LETTER Z WITH ACUTE - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u02c7' # 0xA1 -> CARON - '\u02d8' # 0xA2 -> BREVE - '\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE - '\xa4' # 0xA4 -> CURRENCY SIGN - '\u0104' # 0xA5 -> LATIN CAPITAL LETTER A WITH OGONEK - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\u02db' # 0xB2 -> OGONEK - '\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xb8' # 0xB8 -> CEDILLA - '\u0105' # 0xB9 -> LATIN SMALL LETTER A WITH OGONEK - '\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u013d' # 0xBC -> LATIN CAPITAL LETTER L WITH CARON - '\u02dd' # 0xBD -> DOUBLE ACUTE ACCENT - '\u013e' # 0xBE -> LATIN SMALL LETTER L WITH CARON - '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE - '\u0154' # 0xC0 -> LATIN CAPITAL LETTER R WITH ACUTE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\u0139' # 0xC5 -> LATIN CAPITAL LETTER L WITH ACUTE - '\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\u011a' # 0xCC -> LATIN CAPITAL LETTER E WITH CARON - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\u010e' # 0xCF -> LATIN CAPITAL LETTER D WITH CARON - '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE - '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE - '\u0147' # 0xD2 -> LATIN CAPITAL LETTER N WITH CARON - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\u0158' # 0xD8 -> LATIN CAPITAL LETTER R WITH CARON - '\u016e' # 0xD9 -> LATIN CAPITAL LETTER U WITH RING ABOVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\u0170' # 0xDB -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\u0162' # 0xDE -> LATIN CAPITAL LETTER T WITH CEDILLA - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\u0155' # 0xE0 -> LATIN SMALL LETTER R WITH ACUTE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\u013a' # 0xE5 -> LATIN SMALL LETTER L WITH ACUTE - '\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\u011b' # 0xEC -> LATIN SMALL LETTER E WITH CARON - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\u010f' # 0xEF -> LATIN SMALL LETTER D WITH CARON - '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE - '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE - '\u0148' # 0xF2 -> LATIN SMALL LETTER N WITH CARON - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\u0159' # 0xF8 -> LATIN SMALL LETTER R WITH CARON - '\u016f' # 0xF9 -> LATIN SMALL LETTER U WITH RING ABOVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\u0171' # 0xFB -> LATIN SMALL LETTER U WITH DOUBLE ACUTE - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE - '\u0163' # 0xFE -> LATIN SMALL LETTER T WITH CEDILLA - '\u02d9' # 0xFF -> DOT ABOVE -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1251.py b/python/Lib/encodings/cp1251.py deleted file mode 100644 index 39c0fde..0000000 --- a/python/Lib/encodings/cp1251.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1251 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1251', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u0402' # 0x80 -> CYRILLIC CAPITAL LETTER DJE - '\u0403' # 0x81 -> CYRILLIC CAPITAL LETTER GJE - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\u0453' # 0x83 -> CYRILLIC SMALL LETTER GJE - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\u20ac' # 0x88 -> EURO SIGN - '\u2030' # 0x89 -> PER MILLE SIGN - '\u0409' # 0x8A -> CYRILLIC CAPITAL LETTER LJE - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u040a' # 0x8C -> CYRILLIC CAPITAL LETTER NJE - '\u040c' # 0x8D -> CYRILLIC CAPITAL LETTER KJE - '\u040b' # 0x8E -> CYRILLIC CAPITAL LETTER TSHE - '\u040f' # 0x8F -> CYRILLIC CAPITAL LETTER DZHE - '\u0452' # 0x90 -> CYRILLIC SMALL LETTER DJE - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\ufffe' # 0x98 -> UNDEFINED - '\u2122' # 0x99 -> TRADE MARK SIGN - '\u0459' # 0x9A -> CYRILLIC SMALL LETTER LJE - '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\u045a' # 0x9C -> CYRILLIC SMALL LETTER NJE - '\u045c' # 0x9D -> CYRILLIC SMALL LETTER KJE - '\u045b' # 0x9E -> CYRILLIC SMALL LETTER TSHE - '\u045f' # 0x9F -> CYRILLIC SMALL LETTER DZHE - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u040e' # 0xA1 -> CYRILLIC CAPITAL LETTER SHORT U - '\u045e' # 0xA2 -> CYRILLIC SMALL LETTER SHORT U - '\u0408' # 0xA3 -> CYRILLIC CAPITAL LETTER JE - '\xa4' # 0xA4 -> CURRENCY SIGN - '\u0490' # 0xA5 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\u0401' # 0xA8 -> CYRILLIC CAPITAL LETTER IO - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u0404' # 0xAA -> CYRILLIC CAPITAL LETTER UKRAINIAN IE - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\u0407' # 0xAF -> CYRILLIC CAPITAL LETTER YI - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\u0406' # 0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0456' # 0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0491' # 0xB4 -> CYRILLIC SMALL LETTER GHE WITH UPTURN - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\u0451' # 0xB8 -> CYRILLIC SMALL LETTER IO - '\u2116' # 0xB9 -> NUMERO SIGN - '\u0454' # 0xBA -> CYRILLIC SMALL LETTER UKRAINIAN IE - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u0458' # 0xBC -> CYRILLIC SMALL LETTER JE - '\u0405' # 0xBD -> CYRILLIC CAPITAL LETTER DZE - '\u0455' # 0xBE -> CYRILLIC SMALL LETTER DZE - '\u0457' # 0xBF -> CYRILLIC SMALL LETTER YI - '\u0410' # 0xC0 -> CYRILLIC CAPITAL LETTER A - '\u0411' # 0xC1 -> CYRILLIC CAPITAL LETTER BE - '\u0412' # 0xC2 -> CYRILLIC CAPITAL LETTER VE - '\u0413' # 0xC3 -> CYRILLIC CAPITAL LETTER GHE - '\u0414' # 0xC4 -> CYRILLIC CAPITAL LETTER DE - '\u0415' # 0xC5 -> CYRILLIC CAPITAL LETTER IE - '\u0416' # 0xC6 -> CYRILLIC CAPITAL LETTER ZHE - '\u0417' # 0xC7 -> CYRILLIC CAPITAL LETTER ZE - '\u0418' # 0xC8 -> CYRILLIC CAPITAL LETTER I - '\u0419' # 0xC9 -> CYRILLIC CAPITAL LETTER SHORT I - '\u041a' # 0xCA -> CYRILLIC CAPITAL LETTER KA - '\u041b' # 0xCB -> CYRILLIC CAPITAL LETTER EL - '\u041c' # 0xCC -> CYRILLIC CAPITAL LETTER EM - '\u041d' # 0xCD -> CYRILLIC CAPITAL LETTER EN - '\u041e' # 0xCE -> CYRILLIC CAPITAL LETTER O - '\u041f' # 0xCF -> CYRILLIC CAPITAL LETTER PE - '\u0420' # 0xD0 -> CYRILLIC CAPITAL LETTER ER - '\u0421' # 0xD1 -> CYRILLIC CAPITAL LETTER ES - '\u0422' # 0xD2 -> CYRILLIC CAPITAL LETTER TE - '\u0423' # 0xD3 -> CYRILLIC CAPITAL LETTER U - '\u0424' # 0xD4 -> CYRILLIC CAPITAL LETTER EF - '\u0425' # 0xD5 -> CYRILLIC CAPITAL LETTER HA - '\u0426' # 0xD6 -> CYRILLIC CAPITAL LETTER TSE - '\u0427' # 0xD7 -> CYRILLIC CAPITAL LETTER CHE - '\u0428' # 0xD8 -> CYRILLIC CAPITAL LETTER SHA - '\u0429' # 0xD9 -> CYRILLIC CAPITAL LETTER SHCHA - '\u042a' # 0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN - '\u042b' # 0xDB -> CYRILLIC CAPITAL LETTER YERU - '\u042c' # 0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN - '\u042d' # 0xDD -> CYRILLIC CAPITAL LETTER E - '\u042e' # 0xDE -> CYRILLIC CAPITAL LETTER YU - '\u042f' # 0xDF -> CYRILLIC CAPITAL LETTER YA - '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A - '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE - '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE - '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE - '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE - '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE - '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE - '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE - '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I - '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I - '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA - '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL - '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM - '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN - '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O - '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE - '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER - '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES - '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE - '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U - '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF - '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA - '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE - '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE - '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA - '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA - '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN - '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU - '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN - '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E - '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU - '\u044f' # 0xFF -> CYRILLIC SMALL LETTER YA -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1252.py b/python/Lib/encodings/cp1252.py deleted file mode 100644 index 660cd46..0000000 --- a/python/Lib/encodings/cp1252.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1252 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1252', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u20ac' # 0x80 -> EURO SIGN - '\ufffe' # 0x81 -> UNDEFINED - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\u2030' # 0x89 -> PER MILLE SIGN - '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE - '\ufffe' # 0x8D -> UNDEFINED - '\u017d' # 0x8E -> LATIN CAPITAL LETTER Z WITH CARON - '\ufffe' # 0x8F -> UNDEFINED - '\ufffe' # 0x90 -> UNDEFINED - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\u02dc' # 0x98 -> SMALL TILDE - '\u2122' # 0x99 -> TRADE MARK SIGN - '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON - '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE - '\ufffe' # 0x9D -> UNDEFINED - '\u017e' # 0x9E -> LATIN SMALL LETTER Z WITH CARON - '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\xa5' # 0xA5 -> YEN SIGN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xaf' # 0xAF -> MACRON - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xb8' # 0xB8 -> CEDILLA - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS - '\xbf' # 0xBF -> INVERTED QUESTION MARK - '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH - '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE - '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe6' # 0xE6 -> LATIN SMALL LETTER AE - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH - '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE - '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE - '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE - '\xfe' # 0xFE -> LATIN SMALL LETTER THORN - '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1253.py b/python/Lib/encodings/cp1253.py deleted file mode 100644 index 5bee639..0000000 --- a/python/Lib/encodings/cp1253.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1253 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1253.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1253', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u20ac' # 0x80 -> EURO SIGN - '\ufffe' # 0x81 -> UNDEFINED - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\ufffe' # 0x88 -> UNDEFINED - '\u2030' # 0x89 -> PER MILLE SIGN - '\ufffe' # 0x8A -> UNDEFINED - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\ufffe' # 0x8C -> UNDEFINED - '\ufffe' # 0x8D -> UNDEFINED - '\ufffe' # 0x8E -> UNDEFINED - '\ufffe' # 0x8F -> UNDEFINED - '\ufffe' # 0x90 -> UNDEFINED - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\ufffe' # 0x98 -> UNDEFINED - '\u2122' # 0x99 -> TRADE MARK SIGN - '\ufffe' # 0x9A -> UNDEFINED - '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\ufffe' # 0x9C -> UNDEFINED - '\ufffe' # 0x9D -> UNDEFINED - '\ufffe' # 0x9E -> UNDEFINED - '\ufffe' # 0x9F -> UNDEFINED - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u0385' # 0xA1 -> GREEK DIALYTIKA TONOS - '\u0386' # 0xA2 -> GREEK CAPITAL LETTER ALPHA WITH TONOS - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\xa5' # 0xA5 -> YEN SIGN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\ufffe' # 0xAA -> UNDEFINED - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\u2015' # 0xAF -> HORIZONTAL BAR - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\u0384' # 0xB4 -> GREEK TONOS - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\u0388' # 0xB8 -> GREEK CAPITAL LETTER EPSILON WITH TONOS - '\u0389' # 0xB9 -> GREEK CAPITAL LETTER ETA WITH TONOS - '\u038a' # 0xBA -> GREEK CAPITAL LETTER IOTA WITH TONOS - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u038c' # 0xBC -> GREEK CAPITAL LETTER OMICRON WITH TONOS - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\u038e' # 0xBE -> GREEK CAPITAL LETTER UPSILON WITH TONOS - '\u038f' # 0xBF -> GREEK CAPITAL LETTER OMEGA WITH TONOS - '\u0390' # 0xC0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - '\u0391' # 0xC1 -> GREEK CAPITAL LETTER ALPHA - '\u0392' # 0xC2 -> GREEK CAPITAL LETTER BETA - '\u0393' # 0xC3 -> GREEK CAPITAL LETTER GAMMA - '\u0394' # 0xC4 -> GREEK CAPITAL LETTER DELTA - '\u0395' # 0xC5 -> GREEK CAPITAL LETTER EPSILON - '\u0396' # 0xC6 -> GREEK CAPITAL LETTER ZETA - '\u0397' # 0xC7 -> GREEK CAPITAL LETTER ETA - '\u0398' # 0xC8 -> GREEK CAPITAL LETTER THETA - '\u0399' # 0xC9 -> GREEK CAPITAL LETTER IOTA - '\u039a' # 0xCA -> GREEK CAPITAL LETTER KAPPA - '\u039b' # 0xCB -> GREEK CAPITAL LETTER LAMDA - '\u039c' # 0xCC -> GREEK CAPITAL LETTER MU - '\u039d' # 0xCD -> GREEK CAPITAL LETTER NU - '\u039e' # 0xCE -> GREEK CAPITAL LETTER XI - '\u039f' # 0xCF -> GREEK CAPITAL LETTER OMICRON - '\u03a0' # 0xD0 -> GREEK CAPITAL LETTER PI - '\u03a1' # 0xD1 -> GREEK CAPITAL LETTER RHO - '\ufffe' # 0xD2 -> UNDEFINED - '\u03a3' # 0xD3 -> GREEK CAPITAL LETTER SIGMA - '\u03a4' # 0xD4 -> GREEK CAPITAL LETTER TAU - '\u03a5' # 0xD5 -> GREEK CAPITAL LETTER UPSILON - '\u03a6' # 0xD6 -> GREEK CAPITAL LETTER PHI - '\u03a7' # 0xD7 -> GREEK CAPITAL LETTER CHI - '\u03a8' # 0xD8 -> GREEK CAPITAL LETTER PSI - '\u03a9' # 0xD9 -> GREEK CAPITAL LETTER OMEGA - '\u03aa' # 0xDA -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - '\u03ab' # 0xDB -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - '\u03ac' # 0xDC -> GREEK SMALL LETTER ALPHA WITH TONOS - '\u03ad' # 0xDD -> GREEK SMALL LETTER EPSILON WITH TONOS - '\u03ae' # 0xDE -> GREEK SMALL LETTER ETA WITH TONOS - '\u03af' # 0xDF -> GREEK SMALL LETTER IOTA WITH TONOS - '\u03b0' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - '\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA - '\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA - '\u03b3' # 0xE3 -> GREEK SMALL LETTER GAMMA - '\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA - '\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON - '\u03b6' # 0xE6 -> GREEK SMALL LETTER ZETA - '\u03b7' # 0xE7 -> GREEK SMALL LETTER ETA - '\u03b8' # 0xE8 -> GREEK SMALL LETTER THETA - '\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA - '\u03ba' # 0xEA -> GREEK SMALL LETTER KAPPA - '\u03bb' # 0xEB -> GREEK SMALL LETTER LAMDA - '\u03bc' # 0xEC -> GREEK SMALL LETTER MU - '\u03bd' # 0xED -> GREEK SMALL LETTER NU - '\u03be' # 0xEE -> GREEK SMALL LETTER XI - '\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON - '\u03c0' # 0xF0 -> GREEK SMALL LETTER PI - '\u03c1' # 0xF1 -> GREEK SMALL LETTER RHO - '\u03c2' # 0xF2 -> GREEK SMALL LETTER FINAL SIGMA - '\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA - '\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU - '\u03c5' # 0xF5 -> GREEK SMALL LETTER UPSILON - '\u03c6' # 0xF6 -> GREEK SMALL LETTER PHI - '\u03c7' # 0xF7 -> GREEK SMALL LETTER CHI - '\u03c8' # 0xF8 -> GREEK SMALL LETTER PSI - '\u03c9' # 0xF9 -> GREEK SMALL LETTER OMEGA - '\u03ca' # 0xFA -> GREEK SMALL LETTER IOTA WITH DIALYTIKA - '\u03cb' # 0xFB -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA - '\u03cc' # 0xFC -> GREEK SMALL LETTER OMICRON WITH TONOS - '\u03cd' # 0xFD -> GREEK SMALL LETTER UPSILON WITH TONOS - '\u03ce' # 0xFE -> GREEK SMALL LETTER OMEGA WITH TONOS - '\ufffe' # 0xFF -> UNDEFINED -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1254.py b/python/Lib/encodings/cp1254.py deleted file mode 100644 index 8257240..0000000 --- a/python/Lib/encodings/cp1254.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1254 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1254.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1254', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u20ac' # 0x80 -> EURO SIGN - '\ufffe' # 0x81 -> UNDEFINED - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\u2030' # 0x89 -> PER MILLE SIGN - '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE - '\ufffe' # 0x8D -> UNDEFINED - '\ufffe' # 0x8E -> UNDEFINED - '\ufffe' # 0x8F -> UNDEFINED - '\ufffe' # 0x90 -> UNDEFINED - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\u02dc' # 0x98 -> SMALL TILDE - '\u2122' # 0x99 -> TRADE MARK SIGN - '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON - '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE - '\ufffe' # 0x9D -> UNDEFINED - '\ufffe' # 0x9E -> UNDEFINED - '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\xa5' # 0xA5 -> YEN SIGN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xaf' # 0xAF -> MACRON - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xb8' # 0xB8 -> CEDILLA - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS - '\xbf' # 0xBF -> INVERTED QUESTION MARK - '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\u011e' # 0xD0 -> LATIN CAPITAL LETTER G WITH BREVE - '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE - '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\u0130' # 0xDD -> LATIN CAPITAL LETTER I WITH DOT ABOVE - '\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe6' # 0xE6 -> LATIN SMALL LETTER AE - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\u011f' # 0xF0 -> LATIN SMALL LETTER G WITH BREVE - '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE - '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE - '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\u0131' # 0xFD -> LATIN SMALL LETTER DOTLESS I - '\u015f' # 0xFE -> LATIN SMALL LETTER S WITH CEDILLA - '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1255.py b/python/Lib/encodings/cp1255.py deleted file mode 100644 index 6d6877f..0000000 --- a/python/Lib/encodings/cp1255.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1255 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1255.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1255', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u20ac' # 0x80 -> EURO SIGN - '\ufffe' # 0x81 -> UNDEFINED - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\u2030' # 0x89 -> PER MILLE SIGN - '\ufffe' # 0x8A -> UNDEFINED - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\ufffe' # 0x8C -> UNDEFINED - '\ufffe' # 0x8D -> UNDEFINED - '\ufffe' # 0x8E -> UNDEFINED - '\ufffe' # 0x8F -> UNDEFINED - '\ufffe' # 0x90 -> UNDEFINED - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\u02dc' # 0x98 -> SMALL TILDE - '\u2122' # 0x99 -> TRADE MARK SIGN - '\ufffe' # 0x9A -> UNDEFINED - '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\ufffe' # 0x9C -> UNDEFINED - '\ufffe' # 0x9D -> UNDEFINED - '\ufffe' # 0x9E -> UNDEFINED - '\ufffe' # 0x9F -> UNDEFINED - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\u20aa' # 0xA4 -> NEW SHEQEL SIGN - '\xa5' # 0xA5 -> YEN SIGN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\xd7' # 0xAA -> MULTIPLICATION SIGN - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xaf' # 0xAF -> MACRON - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xb8' # 0xB8 -> CEDILLA - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\xf7' # 0xBA -> DIVISION SIGN - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS - '\xbf' # 0xBF -> INVERTED QUESTION MARK - '\u05b0' # 0xC0 -> HEBREW POINT SHEVA - '\u05b1' # 0xC1 -> HEBREW POINT HATAF SEGOL - '\u05b2' # 0xC2 -> HEBREW POINT HATAF PATAH - '\u05b3' # 0xC3 -> HEBREW POINT HATAF QAMATS - '\u05b4' # 0xC4 -> HEBREW POINT HIRIQ - '\u05b5' # 0xC5 -> HEBREW POINT TSERE - '\u05b6' # 0xC6 -> HEBREW POINT SEGOL - '\u05b7' # 0xC7 -> HEBREW POINT PATAH - '\u05b8' # 0xC8 -> HEBREW POINT QAMATS - '\u05b9' # 0xC9 -> HEBREW POINT HOLAM - '\ufffe' # 0xCA -> UNDEFINED - '\u05bb' # 0xCB -> HEBREW POINT QUBUTS - '\u05bc' # 0xCC -> HEBREW POINT DAGESH OR MAPIQ - '\u05bd' # 0xCD -> HEBREW POINT METEG - '\u05be' # 0xCE -> HEBREW PUNCTUATION MAQAF - '\u05bf' # 0xCF -> HEBREW POINT RAFE - '\u05c0' # 0xD0 -> HEBREW PUNCTUATION PASEQ - '\u05c1' # 0xD1 -> HEBREW POINT SHIN DOT - '\u05c2' # 0xD2 -> HEBREW POINT SIN DOT - '\u05c3' # 0xD3 -> HEBREW PUNCTUATION SOF PASUQ - '\u05f0' # 0xD4 -> HEBREW LIGATURE YIDDISH DOUBLE VAV - '\u05f1' # 0xD5 -> HEBREW LIGATURE YIDDISH VAV YOD - '\u05f2' # 0xD6 -> HEBREW LIGATURE YIDDISH DOUBLE YOD - '\u05f3' # 0xD7 -> HEBREW PUNCTUATION GERESH - '\u05f4' # 0xD8 -> HEBREW PUNCTUATION GERSHAYIM - '\ufffe' # 0xD9 -> UNDEFINED - '\ufffe' # 0xDA -> UNDEFINED - '\ufffe' # 0xDB -> UNDEFINED - '\ufffe' # 0xDC -> UNDEFINED - '\ufffe' # 0xDD -> UNDEFINED - '\ufffe' # 0xDE -> UNDEFINED - '\ufffe' # 0xDF -> UNDEFINED - '\u05d0' # 0xE0 -> HEBREW LETTER ALEF - '\u05d1' # 0xE1 -> HEBREW LETTER BET - '\u05d2' # 0xE2 -> HEBREW LETTER GIMEL - '\u05d3' # 0xE3 -> HEBREW LETTER DALET - '\u05d4' # 0xE4 -> HEBREW LETTER HE - '\u05d5' # 0xE5 -> HEBREW LETTER VAV - '\u05d6' # 0xE6 -> HEBREW LETTER ZAYIN - '\u05d7' # 0xE7 -> HEBREW LETTER HET - '\u05d8' # 0xE8 -> HEBREW LETTER TET - '\u05d9' # 0xE9 -> HEBREW LETTER YOD - '\u05da' # 0xEA -> HEBREW LETTER FINAL KAF - '\u05db' # 0xEB -> HEBREW LETTER KAF - '\u05dc' # 0xEC -> HEBREW LETTER LAMED - '\u05dd' # 0xED -> HEBREW LETTER FINAL MEM - '\u05de' # 0xEE -> HEBREW LETTER MEM - '\u05df' # 0xEF -> HEBREW LETTER FINAL NUN - '\u05e0' # 0xF0 -> HEBREW LETTER NUN - '\u05e1' # 0xF1 -> HEBREW LETTER SAMEKH - '\u05e2' # 0xF2 -> HEBREW LETTER AYIN - '\u05e3' # 0xF3 -> HEBREW LETTER FINAL PE - '\u05e4' # 0xF4 -> HEBREW LETTER PE - '\u05e5' # 0xF5 -> HEBREW LETTER FINAL TSADI - '\u05e6' # 0xF6 -> HEBREW LETTER TSADI - '\u05e7' # 0xF7 -> HEBREW LETTER QOF - '\u05e8' # 0xF8 -> HEBREW LETTER RESH - '\u05e9' # 0xF9 -> HEBREW LETTER SHIN - '\u05ea' # 0xFA -> HEBREW LETTER TAV - '\ufffe' # 0xFB -> UNDEFINED - '\ufffe' # 0xFC -> UNDEFINED - '\u200e' # 0xFD -> LEFT-TO-RIGHT MARK - '\u200f' # 0xFE -> RIGHT-TO-LEFT MARK - '\ufffe' # 0xFF -> UNDEFINED -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1256.py b/python/Lib/encodings/cp1256.py deleted file mode 100644 index ee33516..0000000 --- a/python/Lib/encodings/cp1256.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1256 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1256', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u20ac' # 0x80 -> EURO SIGN - '\u067e' # 0x81 -> ARABIC LETTER PEH - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\u2030' # 0x89 -> PER MILLE SIGN - '\u0679' # 0x8A -> ARABIC LETTER TTEH - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE - '\u0686' # 0x8D -> ARABIC LETTER TCHEH - '\u0698' # 0x8E -> ARABIC LETTER JEH - '\u0688' # 0x8F -> ARABIC LETTER DDAL - '\u06af' # 0x90 -> ARABIC LETTER GAF - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\u06a9' # 0x98 -> ARABIC LETTER KEHEH - '\u2122' # 0x99 -> TRADE MARK SIGN - '\u0691' # 0x9A -> ARABIC LETTER RREH - '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE - '\u200c' # 0x9D -> ZERO WIDTH NON-JOINER - '\u200d' # 0x9E -> ZERO WIDTH JOINER - '\u06ba' # 0x9F -> ARABIC LETTER NOON GHUNNA - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u060c' # 0xA1 -> ARABIC COMMA - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\xa5' # 0xA5 -> YEN SIGN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u06be' # 0xAA -> ARABIC LETTER HEH DOACHASHMEE - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xaf' # 0xAF -> MACRON - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xb8' # 0xB8 -> CEDILLA - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\u061b' # 0xBA -> ARABIC SEMICOLON - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS - '\u061f' # 0xBF -> ARABIC QUESTION MARK - '\u06c1' # 0xC0 -> ARABIC LETTER HEH GOAL - '\u0621' # 0xC1 -> ARABIC LETTER HAMZA - '\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE - '\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE - '\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE - '\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW - '\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE - '\u0627' # 0xC7 -> ARABIC LETTER ALEF - '\u0628' # 0xC8 -> ARABIC LETTER BEH - '\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA - '\u062a' # 0xCA -> ARABIC LETTER TEH - '\u062b' # 0xCB -> ARABIC LETTER THEH - '\u062c' # 0xCC -> ARABIC LETTER JEEM - '\u062d' # 0xCD -> ARABIC LETTER HAH - '\u062e' # 0xCE -> ARABIC LETTER KHAH - '\u062f' # 0xCF -> ARABIC LETTER DAL - '\u0630' # 0xD0 -> ARABIC LETTER THAL - '\u0631' # 0xD1 -> ARABIC LETTER REH - '\u0632' # 0xD2 -> ARABIC LETTER ZAIN - '\u0633' # 0xD3 -> ARABIC LETTER SEEN - '\u0634' # 0xD4 -> ARABIC LETTER SHEEN - '\u0635' # 0xD5 -> ARABIC LETTER SAD - '\u0636' # 0xD6 -> ARABIC LETTER DAD - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\u0637' # 0xD8 -> ARABIC LETTER TAH - '\u0638' # 0xD9 -> ARABIC LETTER ZAH - '\u0639' # 0xDA -> ARABIC LETTER AIN - '\u063a' # 0xDB -> ARABIC LETTER GHAIN - '\u0640' # 0xDC -> ARABIC TATWEEL - '\u0641' # 0xDD -> ARABIC LETTER FEH - '\u0642' # 0xDE -> ARABIC LETTER QAF - '\u0643' # 0xDF -> ARABIC LETTER KAF - '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE - '\u0644' # 0xE1 -> ARABIC LETTER LAM - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\u0645' # 0xE3 -> ARABIC LETTER MEEM - '\u0646' # 0xE4 -> ARABIC LETTER NOON - '\u0647' # 0xE5 -> ARABIC LETTER HEH - '\u0648' # 0xE6 -> ARABIC LETTER WAW - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\u0649' # 0xEC -> ARABIC LETTER ALEF MAKSURA - '\u064a' # 0xED -> ARABIC LETTER YEH - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\u064b' # 0xF0 -> ARABIC FATHATAN - '\u064c' # 0xF1 -> ARABIC DAMMATAN - '\u064d' # 0xF2 -> ARABIC KASRATAN - '\u064e' # 0xF3 -> ARABIC FATHA - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\u064f' # 0xF5 -> ARABIC DAMMA - '\u0650' # 0xF6 -> ARABIC KASRA - '\xf7' # 0xF7 -> DIVISION SIGN - '\u0651' # 0xF8 -> ARABIC SHADDA - '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE - '\u0652' # 0xFA -> ARABIC SUKUN - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\u200e' # 0xFD -> LEFT-TO-RIGHT MARK - '\u200f' # 0xFE -> RIGHT-TO-LEFT MARK - '\u06d2' # 0xFF -> ARABIC LETTER YEH BARREE -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1257.py b/python/Lib/encodings/cp1257.py deleted file mode 100644 index c0f0468..0000000 --- a/python/Lib/encodings/cp1257.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1257 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1257.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1257', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u20ac' # 0x80 -> EURO SIGN - '\ufffe' # 0x81 -> UNDEFINED - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\ufffe' # 0x83 -> UNDEFINED - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\ufffe' # 0x88 -> UNDEFINED - '\u2030' # 0x89 -> PER MILLE SIGN - '\ufffe' # 0x8A -> UNDEFINED - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\ufffe' # 0x8C -> UNDEFINED - '\xa8' # 0x8D -> DIAERESIS - '\u02c7' # 0x8E -> CARON - '\xb8' # 0x8F -> CEDILLA - '\ufffe' # 0x90 -> UNDEFINED - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\ufffe' # 0x98 -> UNDEFINED - '\u2122' # 0x99 -> TRADE MARK SIGN - '\ufffe' # 0x9A -> UNDEFINED - '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\ufffe' # 0x9C -> UNDEFINED - '\xaf' # 0x9D -> MACRON - '\u02db' # 0x9E -> OGONEK - '\ufffe' # 0x9F -> UNDEFINED - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\ufffe' # 0xA1 -> UNDEFINED - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\ufffe' # 0xA5 -> UNDEFINED - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xd8' # 0xA8 -> LATIN CAPITAL LETTER O WITH STROKE - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u0156' # 0xAA -> LATIN CAPITAL LETTER R WITH CEDILLA - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xc6' # 0xAF -> LATIN CAPITAL LETTER AE - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xf8' # 0xB8 -> LATIN SMALL LETTER O WITH STROKE - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\u0157' # 0xBA -> LATIN SMALL LETTER R WITH CEDILLA - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS - '\xe6' # 0xBF -> LATIN SMALL LETTER AE - '\u0104' # 0xC0 -> LATIN CAPITAL LETTER A WITH OGONEK - '\u012e' # 0xC1 -> LATIN CAPITAL LETTER I WITH OGONEK - '\u0100' # 0xC2 -> LATIN CAPITAL LETTER A WITH MACRON - '\u0106' # 0xC3 -> LATIN CAPITAL LETTER C WITH ACUTE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\u0118' # 0xC6 -> LATIN CAPITAL LETTER E WITH OGONEK - '\u0112' # 0xC7 -> LATIN CAPITAL LETTER E WITH MACRON - '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\u0179' # 0xCA -> LATIN CAPITAL LETTER Z WITH ACUTE - '\u0116' # 0xCB -> LATIN CAPITAL LETTER E WITH DOT ABOVE - '\u0122' # 0xCC -> LATIN CAPITAL LETTER G WITH CEDILLA - '\u0136' # 0xCD -> LATIN CAPITAL LETTER K WITH CEDILLA - '\u012a' # 0xCE -> LATIN CAPITAL LETTER I WITH MACRON - '\u013b' # 0xCF -> LATIN CAPITAL LETTER L WITH CEDILLA - '\u0160' # 0xD0 -> LATIN CAPITAL LETTER S WITH CARON - '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE - '\u0145' # 0xD2 -> LATIN CAPITAL LETTER N WITH CEDILLA - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\u014c' # 0xD4 -> LATIN CAPITAL LETTER O WITH MACRON - '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\u0172' # 0xD8 -> LATIN CAPITAL LETTER U WITH OGONEK - '\u0141' # 0xD9 -> LATIN CAPITAL LETTER L WITH STROKE - '\u015a' # 0xDA -> LATIN CAPITAL LETTER S WITH ACUTE - '\u016a' # 0xDB -> LATIN CAPITAL LETTER U WITH MACRON - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\u017b' # 0xDD -> LATIN CAPITAL LETTER Z WITH DOT ABOVE - '\u017d' # 0xDE -> LATIN CAPITAL LETTER Z WITH CARON - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\u0105' # 0xE0 -> LATIN SMALL LETTER A WITH OGONEK - '\u012f' # 0xE1 -> LATIN SMALL LETTER I WITH OGONEK - '\u0101' # 0xE2 -> LATIN SMALL LETTER A WITH MACRON - '\u0107' # 0xE3 -> LATIN SMALL LETTER C WITH ACUTE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\u0119' # 0xE6 -> LATIN SMALL LETTER E WITH OGONEK - '\u0113' # 0xE7 -> LATIN SMALL LETTER E WITH MACRON - '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\u017a' # 0xEA -> LATIN SMALL LETTER Z WITH ACUTE - '\u0117' # 0xEB -> LATIN SMALL LETTER E WITH DOT ABOVE - '\u0123' # 0xEC -> LATIN SMALL LETTER G WITH CEDILLA - '\u0137' # 0xED -> LATIN SMALL LETTER K WITH CEDILLA - '\u012b' # 0xEE -> LATIN SMALL LETTER I WITH MACRON - '\u013c' # 0xEF -> LATIN SMALL LETTER L WITH CEDILLA - '\u0161' # 0xF0 -> LATIN SMALL LETTER S WITH CARON - '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE - '\u0146' # 0xF2 -> LATIN SMALL LETTER N WITH CEDILLA - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\u014d' # 0xF4 -> LATIN SMALL LETTER O WITH MACRON - '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\u0173' # 0xF8 -> LATIN SMALL LETTER U WITH OGONEK - '\u0142' # 0xF9 -> LATIN SMALL LETTER L WITH STROKE - '\u015b' # 0xFA -> LATIN SMALL LETTER S WITH ACUTE - '\u016b' # 0xFB -> LATIN SMALL LETTER U WITH MACRON - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE - '\u017e' # 0xFE -> LATIN SMALL LETTER Z WITH CARON - '\u02d9' # 0xFF -> DOT ABOVE -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp1258.py b/python/Lib/encodings/cp1258.py deleted file mode 100644 index 3991d42..0000000 --- a/python/Lib/encodings/cp1258.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp1258 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1258.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp1258', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u20ac' # 0x80 -> EURO SIGN - '\ufffe' # 0x81 -> UNDEFINED - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\u2030' # 0x89 -> PER MILLE SIGN - '\ufffe' # 0x8A -> UNDEFINED - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE - '\ufffe' # 0x8D -> UNDEFINED - '\ufffe' # 0x8E -> UNDEFINED - '\ufffe' # 0x8F -> UNDEFINED - '\ufffe' # 0x90 -> UNDEFINED - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\u02dc' # 0x98 -> SMALL TILDE - '\u2122' # 0x99 -> TRADE MARK SIGN - '\ufffe' # 0x9A -> UNDEFINED - '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE - '\ufffe' # 0x9D -> UNDEFINED - '\ufffe' # 0x9E -> UNDEFINED - '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\xa5' # 0xA5 -> YEN SIGN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xaf' # 0xAF -> MACRON - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xb8' # 0xB8 -> CEDILLA - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS - '\xbf' # 0xBF -> INVERTED QUESTION MARK - '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\u0300' # 0xCC -> COMBINING GRAVE ACCENT - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE - '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE - '\u0309' # 0xD2 -> COMBINING HOOK ABOVE - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\u01a0' # 0xD5 -> LATIN CAPITAL LETTER O WITH HORN - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE - '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\u01af' # 0xDD -> LATIN CAPITAL LETTER U WITH HORN - '\u0303' # 0xDE -> COMBINING TILDE - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe6' # 0xE6 -> LATIN SMALL LETTER AE - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\u0301' # 0xEC -> COMBINING ACUTE ACCENT - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE - '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE - '\u0323' # 0xF2 -> COMBINING DOT BELOW - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\u01a1' # 0xF5 -> LATIN SMALL LETTER O WITH HORN - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE - '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\u01b0' # 0xFD -> LATIN SMALL LETTER U WITH HORN - '\u20ab' # 0xFE -> DONG SIGN - '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp273.py b/python/Lib/encodings/cp273.py deleted file mode 100644 index 3c21953..0000000 --- a/python/Lib/encodings/cp273.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp273 generated from 'python-mappings/CP273.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp273', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL (NUL) - '\x01' # 0x01 -> START OF HEADING (SOH) - '\x02' # 0x02 -> START OF TEXT (STX) - '\x03' # 0x03 -> END OF TEXT (ETX) - '\x9c' # 0x04 -> STRING TERMINATOR (ST) - '\t' # 0x05 -> CHARACTER TABULATION (HT) - '\x86' # 0x06 -> START OF SELECTED AREA (SSA) - '\x7f' # 0x07 -> DELETE (DEL) - '\x97' # 0x08 -> END OF GUARDED AREA (EPA) - '\x8d' # 0x09 -> REVERSE LINE FEED (RI) - '\x8e' # 0x0A -> SINGLE-SHIFT TWO (SS2) - '\x0b' # 0x0B -> LINE TABULATION (VT) - '\x0c' # 0x0C -> FORM FEED (FF) - '\r' # 0x0D -> CARRIAGE RETURN (CR) - '\x0e' # 0x0E -> SHIFT OUT (SO) - '\x0f' # 0x0F -> SHIFT IN (SI) - '\x10' # 0x10 -> DATALINK ESCAPE (DLE) - '\x11' # 0x11 -> DEVICE CONTROL ONE (DC1) - '\x12' # 0x12 -> DEVICE CONTROL TWO (DC2) - '\x13' # 0x13 -> DEVICE CONTROL THREE (DC3) - '\x9d' # 0x14 -> OPERATING SYSTEM COMMAND (OSC) - '\x85' # 0x15 -> NEXT LINE (NEL) - '\x08' # 0x16 -> BACKSPACE (BS) - '\x87' # 0x17 -> END OF SELECTED AREA (ESA) - '\x18' # 0x18 -> CANCEL (CAN) - '\x19' # 0x19 -> END OF MEDIUM (EM) - '\x92' # 0x1A -> PRIVATE USE TWO (PU2) - '\x8f' # 0x1B -> SINGLE-SHIFT THREE (SS3) - '\x1c' # 0x1C -> FILE SEPARATOR (IS4) - '\x1d' # 0x1D -> GROUP SEPARATOR (IS3) - '\x1e' # 0x1E -> RECORD SEPARATOR (IS2) - '\x1f' # 0x1F -> UNIT SEPARATOR (IS1) - '\x80' # 0x20 -> PADDING CHARACTER (PAD) - '\x81' # 0x21 -> HIGH OCTET PRESET (HOP) - '\x82' # 0x22 -> BREAK PERMITTED HERE (BPH) - '\x83' # 0x23 -> NO BREAK HERE (NBH) - '\x84' # 0x24 -> INDEX (IND) - '\n' # 0x25 -> LINE FEED (LF) - '\x17' # 0x26 -> END OF TRANSMISSION BLOCK (ETB) - '\x1b' # 0x27 -> ESCAPE (ESC) - '\x88' # 0x28 -> CHARACTER TABULATION SET (HTS) - '\x89' # 0x29 -> CHARACTER TABULATION WITH JUSTIFICATION (HTJ) - '\x8a' # 0x2A -> LINE TABULATION SET (VTS) - '\x8b' # 0x2B -> PARTIAL LINE FORWARD (PLD) - '\x8c' # 0x2C -> PARTIAL LINE BACKWARD (PLU) - '\x05' # 0x2D -> ENQUIRY (ENQ) - '\x06' # 0x2E -> ACKNOWLEDGE (ACK) - '\x07' # 0x2F -> BELL (BEL) - '\x90' # 0x30 -> DEVICE CONTROL STRING (DCS) - '\x91' # 0x31 -> PRIVATE USE ONE (PU1) - '\x16' # 0x32 -> SYNCHRONOUS IDLE (SYN) - '\x93' # 0x33 -> SET TRANSMIT STATE (STS) - '\x94' # 0x34 -> CANCEL CHARACTER (CCH) - '\x95' # 0x35 -> MESSAGE WAITING (MW) - '\x96' # 0x36 -> START OF GUARDED AREA (SPA) - '\x04' # 0x37 -> END OF TRANSMISSION (EOT) - '\x98' # 0x38 -> START OF STRING (SOS) - '\x99' # 0x39 -> SINGLE GRAPHIC CHARACTER INTRODUCER (SGCI) - '\x9a' # 0x3A -> SINGLE CHARACTER INTRODUCER (SCI) - '\x9b' # 0x3B -> CONTROL SEQUENCE INTRODUCER (CSI) - '\x14' # 0x3C -> DEVICE CONTROL FOUR (DC4) - '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE (NAK) - '\x9e' # 0x3E -> PRIVACY MESSAGE (PM) - '\x1a' # 0x3F -> SUBSTITUTE (SUB) - ' ' # 0x40 -> SPACE - '\xa0' # 0x41 -> NO-BREAK SPACE - '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '{' # 0x43 -> LEFT CURLY BRACKET - '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE - '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE - '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA - '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE - '\xc4' # 0x4A -> LATIN CAPITAL LETTER A WITH DIAERESIS - '.' # 0x4B -> FULL STOP - '<' # 0x4C -> LESS-THAN SIGN - '(' # 0x4D -> LEFT PARENTHESIS - '+' # 0x4E -> PLUS SIGN - '!' # 0x4F -> EXCLAMATION MARK - '&' # 0x50 -> AMPERSAND - '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE - '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE - '~' # 0x59 -> TILDE - '\xdc' # 0x5A -> LATIN CAPITAL LETTER U WITH DIAERESIS - '$' # 0x5B -> DOLLAR SIGN - '*' # 0x5C -> ASTERISK - ')' # 0x5D -> RIGHT PARENTHESIS - ';' # 0x5E -> SEMICOLON - '^' # 0x5F -> CIRCUMFLEX ACCENT - '-' # 0x60 -> HYPHEN-MINUS - '/' # 0x61 -> SOLIDUS - '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '[' # 0x63 -> LEFT SQUARE BRACKET - '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE - '\xf6' # 0x6A -> LATIN SMALL LETTER O WITH DIAERESIS - ',' # 0x6B -> COMMA - '%' # 0x6C -> PERCENT SIGN - '_' # 0x6D -> LOW LINE - '>' # 0x6E -> GREATER-THAN SIGN - '?' # 0x6F -> QUESTION MARK - '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE - '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE - '`' # 0x79 -> GRAVE ACCENT - ':' # 0x7A -> COLON - '#' # 0x7B -> NUMBER SIGN - '\xa7' # 0x7C -> SECTION SIGN - "'" # 0x7D -> APOSTROPHE - '=' # 0x7E -> EQUALS SIGN - '"' # 0x7F -> QUOTATION MARK - '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE - 'a' # 0x81 -> LATIN SMALL LETTER A - 'b' # 0x82 -> LATIN SMALL LETTER B - 'c' # 0x83 -> LATIN SMALL LETTER C - 'd' # 0x84 -> LATIN SMALL LETTER D - 'e' # 0x85 -> LATIN SMALL LETTER E - 'f' # 0x86 -> LATIN SMALL LETTER F - 'g' # 0x87 -> LATIN SMALL LETTER G - 'h' # 0x88 -> LATIN SMALL LETTER H - 'i' # 0x89 -> LATIN SMALL LETTER I - '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xf0' # 0x8C -> LATIN SMALL LETTER ETH (Icelandic) - '\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE - '\xfe' # 0x8E -> LATIN SMALL LETTER THORN (Icelandic) - '\xb1' # 0x8F -> PLUS-MINUS SIGN - '\xb0' # 0x90 -> DEGREE SIGN - 'j' # 0x91 -> LATIN SMALL LETTER J - 'k' # 0x92 -> LATIN SMALL LETTER K - 'l' # 0x93 -> LATIN SMALL LETTER L - 'm' # 0x94 -> LATIN SMALL LETTER M - 'n' # 0x95 -> LATIN SMALL LETTER N - 'o' # 0x96 -> LATIN SMALL LETTER O - 'p' # 0x97 -> LATIN SMALL LETTER P - 'q' # 0x98 -> LATIN SMALL LETTER Q - 'r' # 0x99 -> LATIN SMALL LETTER R - '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR - '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR - '\xe6' # 0x9C -> LATIN SMALL LETTER AE - '\xb8' # 0x9D -> CEDILLA - '\xc6' # 0x9E -> LATIN CAPITAL LETTER AE - '\xa4' # 0x9F -> CURRENCY SIGN - '\xb5' # 0xA0 -> MICRO SIGN - '\xdf' # 0xA1 -> LATIN SMALL LETTER SHARP S (German) - 's' # 0xA2 -> LATIN SMALL LETTER S - 't' # 0xA3 -> LATIN SMALL LETTER T - 'u' # 0xA4 -> LATIN SMALL LETTER U - 'v' # 0xA5 -> LATIN SMALL LETTER V - 'w' # 0xA6 -> LATIN SMALL LETTER W - 'x' # 0xA7 -> LATIN SMALL LETTER X - 'y' # 0xA8 -> LATIN SMALL LETTER Y - 'z' # 0xA9 -> LATIN SMALL LETTER Z - '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK - '\xbf' # 0xAB -> INVERTED QUESTION MARK - '\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (Icelandic) - '\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (Icelandic) - '\xae' # 0xAF -> REGISTERED SIGN - '\xa2' # 0xB0 -> CENT SIGN - '\xa3' # 0xB1 -> POUND SIGN - '\xa5' # 0xB2 -> YEN SIGN - '\xb7' # 0xB3 -> MIDDLE DOT - '\xa9' # 0xB4 -> COPYRIGHT SIGN - '@' # 0xB5 -> COMMERCIAL AT - '\xb6' # 0xB6 -> PILCROW SIGN - '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF - '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS - '\xac' # 0xBA -> NOT SIGN - '|' # 0xBB -> VERTICAL LINE - '\u203e' # 0xBC -> OVERLINE - '\xa8' # 0xBD -> DIAERESIS - '\xb4' # 0xBE -> ACUTE ACCENT - '\xd7' # 0xBF -> MULTIPLICATION SIGN - '\xe4' # 0xC0 -> LATIN SMALL LETTER A WITH DIAERESIS - 'A' # 0xC1 -> LATIN CAPITAL LETTER A - 'B' # 0xC2 -> LATIN CAPITAL LETTER B - 'C' # 0xC3 -> LATIN CAPITAL LETTER C - 'D' # 0xC4 -> LATIN CAPITAL LETTER D - 'E' # 0xC5 -> LATIN CAPITAL LETTER E - 'F' # 0xC6 -> LATIN CAPITAL LETTER F - 'G' # 0xC7 -> LATIN CAPITAL LETTER G - 'H' # 0xC8 -> LATIN CAPITAL LETTER H - 'I' # 0xC9 -> LATIN CAPITAL LETTER I - '\xad' # 0xCA -> SOFT HYPHEN - '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xa6' # 0xCC -> BROKEN BAR - '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE - '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE - '\xfc' # 0xD0 -> LATIN SMALL LETTER U WITH DIAERESIS - 'J' # 0xD1 -> LATIN CAPITAL LETTER J - 'K' # 0xD2 -> LATIN CAPITAL LETTER K - 'L' # 0xD3 -> LATIN CAPITAL LETTER L - 'M' # 0xD4 -> LATIN CAPITAL LETTER M - 'N' # 0xD5 -> LATIN CAPITAL LETTER N - 'O' # 0xD6 -> LATIN CAPITAL LETTER O - 'P' # 0xD7 -> LATIN CAPITAL LETTER P - 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q - 'R' # 0xD9 -> LATIN CAPITAL LETTER R - '\xb9' # 0xDA -> SUPERSCRIPT ONE - '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '}' # 0xDC -> RIGHT CURLY BRACKET - '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE - '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS - '\xd6' # 0xE0 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xf7' # 0xE1 -> DIVISION SIGN - 'S' # 0xE2 -> LATIN CAPITAL LETTER S - 'T' # 0xE3 -> LATIN CAPITAL LETTER T - 'U' # 0xE4 -> LATIN CAPITAL LETTER U - 'V' # 0xE5 -> LATIN CAPITAL LETTER V - 'W' # 0xE6 -> LATIN CAPITAL LETTER W - 'X' # 0xE7 -> LATIN CAPITAL LETTER X - 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y - 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z - '\xb2' # 0xEA -> SUPERSCRIPT TWO - '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\\' # 0xEC -> REVERSE SOLIDUS - '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE - '0' # 0xF0 -> DIGIT ZERO - '1' # 0xF1 -> DIGIT ONE - '2' # 0xF2 -> DIGIT TWO - '3' # 0xF3 -> DIGIT THREE - '4' # 0xF4 -> DIGIT FOUR - '5' # 0xF5 -> DIGIT FIVE - '6' # 0xF6 -> DIGIT SIX - '7' # 0xF7 -> DIGIT SEVEN - '8' # 0xF8 -> DIGIT EIGHT - '9' # 0xF9 -> DIGIT NINE - '\xb3' # 0xFA -> SUPERSCRIPT THREE - '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - ']' # 0xFC -> RIGHT SQUARE BRACKET - '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE - '\x9f' # 0xFF -> APPLICATION PROGRAM COMMAND (APC) -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp424.py b/python/Lib/encodings/cp424.py deleted file mode 100644 index 17c557e..0000000 --- a/python/Lib/encodings/cp424.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp424 generated from 'MAPPINGS/VENDORS/MISC/CP424.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp424', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x9c' # 0x04 -> SELECT - '\t' # 0x05 -> HORIZONTAL TABULATION - '\x86' # 0x06 -> REQUIRED NEW LINE - '\x7f' # 0x07 -> DELETE - '\x97' # 0x08 -> GRAPHIC ESCAPE - '\x8d' # 0x09 -> SUPERSCRIPT - '\x8e' # 0x0A -> REPEAT - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x9d' # 0x14 -> RESTORE/ENABLE PRESENTATION - '\x85' # 0x15 -> NEW LINE - '\x08' # 0x16 -> BACKSPACE - '\x87' # 0x17 -> PROGRAM OPERATOR COMMUNICATION - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x92' # 0x1A -> UNIT BACK SPACE - '\x8f' # 0x1B -> CUSTOMER USE ONE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - '\x80' # 0x20 -> DIGIT SELECT - '\x81' # 0x21 -> START OF SIGNIFICANCE - '\x82' # 0x22 -> FIELD SEPARATOR - '\x83' # 0x23 -> WORD UNDERSCORE - '\x84' # 0x24 -> BYPASS OR INHIBIT PRESENTATION - '\n' # 0x25 -> LINE FEED - '\x17' # 0x26 -> END OF TRANSMISSION BLOCK - '\x1b' # 0x27 -> ESCAPE - '\x88' # 0x28 -> SET ATTRIBUTE - '\x89' # 0x29 -> START FIELD EXTENDED - '\x8a' # 0x2A -> SET MODE OR SWITCH - '\x8b' # 0x2B -> CONTROL SEQUENCE PREFIX - '\x8c' # 0x2C -> MODIFY FIELD ATTRIBUTE - '\x05' # 0x2D -> ENQUIRY - '\x06' # 0x2E -> ACKNOWLEDGE - '\x07' # 0x2F -> BELL - '\x90' # 0x30 -> - '\x91' # 0x31 -> - '\x16' # 0x32 -> SYNCHRONOUS IDLE - '\x93' # 0x33 -> INDEX RETURN - '\x94' # 0x34 -> PRESENTATION POSITION - '\x95' # 0x35 -> TRANSPARENT - '\x96' # 0x36 -> NUMERIC BACKSPACE - '\x04' # 0x37 -> END OF TRANSMISSION - '\x98' # 0x38 -> SUBSCRIPT - '\x99' # 0x39 -> INDENT TABULATION - '\x9a' # 0x3A -> REVERSE FORM FEED - '\x9b' # 0x3B -> CUSTOMER USE THREE - '\x14' # 0x3C -> DEVICE CONTROL FOUR - '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE - '\x9e' # 0x3E -> - '\x1a' # 0x3F -> SUBSTITUTE - ' ' # 0x40 -> SPACE - '\u05d0' # 0x41 -> HEBREW LETTER ALEF - '\u05d1' # 0x42 -> HEBREW LETTER BET - '\u05d2' # 0x43 -> HEBREW LETTER GIMEL - '\u05d3' # 0x44 -> HEBREW LETTER DALET - '\u05d4' # 0x45 -> HEBREW LETTER HE - '\u05d5' # 0x46 -> HEBREW LETTER VAV - '\u05d6' # 0x47 -> HEBREW LETTER ZAYIN - '\u05d7' # 0x48 -> HEBREW LETTER HET - '\u05d8' # 0x49 -> HEBREW LETTER TET - '\xa2' # 0x4A -> CENT SIGN - '.' # 0x4B -> FULL STOP - '<' # 0x4C -> LESS-THAN SIGN - '(' # 0x4D -> LEFT PARENTHESIS - '+' # 0x4E -> PLUS SIGN - '|' # 0x4F -> VERTICAL LINE - '&' # 0x50 -> AMPERSAND - '\u05d9' # 0x51 -> HEBREW LETTER YOD - '\u05da' # 0x52 -> HEBREW LETTER FINAL KAF - '\u05db' # 0x53 -> HEBREW LETTER KAF - '\u05dc' # 0x54 -> HEBREW LETTER LAMED - '\u05dd' # 0x55 -> HEBREW LETTER FINAL MEM - '\u05de' # 0x56 -> HEBREW LETTER MEM - '\u05df' # 0x57 -> HEBREW LETTER FINAL NUN - '\u05e0' # 0x58 -> HEBREW LETTER NUN - '\u05e1' # 0x59 -> HEBREW LETTER SAMEKH - '!' # 0x5A -> EXCLAMATION MARK - '$' # 0x5B -> DOLLAR SIGN - '*' # 0x5C -> ASTERISK - ')' # 0x5D -> RIGHT PARENTHESIS - ';' # 0x5E -> SEMICOLON - '\xac' # 0x5F -> NOT SIGN - '-' # 0x60 -> HYPHEN-MINUS - '/' # 0x61 -> SOLIDUS - '\u05e2' # 0x62 -> HEBREW LETTER AYIN - '\u05e3' # 0x63 -> HEBREW LETTER FINAL PE - '\u05e4' # 0x64 -> HEBREW LETTER PE - '\u05e5' # 0x65 -> HEBREW LETTER FINAL TSADI - '\u05e6' # 0x66 -> HEBREW LETTER TSADI - '\u05e7' # 0x67 -> HEBREW LETTER QOF - '\u05e8' # 0x68 -> HEBREW LETTER RESH - '\u05e9' # 0x69 -> HEBREW LETTER SHIN - '\xa6' # 0x6A -> BROKEN BAR - ',' # 0x6B -> COMMA - '%' # 0x6C -> PERCENT SIGN - '_' # 0x6D -> LOW LINE - '>' # 0x6E -> GREATER-THAN SIGN - '?' # 0x6F -> QUESTION MARK - '\ufffe' # 0x70 -> UNDEFINED - '\u05ea' # 0x71 -> HEBREW LETTER TAV - '\ufffe' # 0x72 -> UNDEFINED - '\ufffe' # 0x73 -> UNDEFINED - '\xa0' # 0x74 -> NO-BREAK SPACE - '\ufffe' # 0x75 -> UNDEFINED - '\ufffe' # 0x76 -> UNDEFINED - '\ufffe' # 0x77 -> UNDEFINED - '\u2017' # 0x78 -> DOUBLE LOW LINE - '`' # 0x79 -> GRAVE ACCENT - ':' # 0x7A -> COLON - '#' # 0x7B -> NUMBER SIGN - '@' # 0x7C -> COMMERCIAL AT - "'" # 0x7D -> APOSTROPHE - '=' # 0x7E -> EQUALS SIGN - '"' # 0x7F -> QUOTATION MARK - '\ufffe' # 0x80 -> UNDEFINED - 'a' # 0x81 -> LATIN SMALL LETTER A - 'b' # 0x82 -> LATIN SMALL LETTER B - 'c' # 0x83 -> LATIN SMALL LETTER C - 'd' # 0x84 -> LATIN SMALL LETTER D - 'e' # 0x85 -> LATIN SMALL LETTER E - 'f' # 0x86 -> LATIN SMALL LETTER F - 'g' # 0x87 -> LATIN SMALL LETTER G - 'h' # 0x88 -> LATIN SMALL LETTER H - 'i' # 0x89 -> LATIN SMALL LETTER I - '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\ufffe' # 0x8C -> UNDEFINED - '\ufffe' # 0x8D -> UNDEFINED - '\ufffe' # 0x8E -> UNDEFINED - '\xb1' # 0x8F -> PLUS-MINUS SIGN - '\xb0' # 0x90 -> DEGREE SIGN - 'j' # 0x91 -> LATIN SMALL LETTER J - 'k' # 0x92 -> LATIN SMALL LETTER K - 'l' # 0x93 -> LATIN SMALL LETTER L - 'm' # 0x94 -> LATIN SMALL LETTER M - 'n' # 0x95 -> LATIN SMALL LETTER N - 'o' # 0x96 -> LATIN SMALL LETTER O - 'p' # 0x97 -> LATIN SMALL LETTER P - 'q' # 0x98 -> LATIN SMALL LETTER Q - 'r' # 0x99 -> LATIN SMALL LETTER R - '\ufffe' # 0x9A -> UNDEFINED - '\ufffe' # 0x9B -> UNDEFINED - '\ufffe' # 0x9C -> UNDEFINED - '\xb8' # 0x9D -> CEDILLA - '\ufffe' # 0x9E -> UNDEFINED - '\xa4' # 0x9F -> CURRENCY SIGN - '\xb5' # 0xA0 -> MICRO SIGN - '~' # 0xA1 -> TILDE - 's' # 0xA2 -> LATIN SMALL LETTER S - 't' # 0xA3 -> LATIN SMALL LETTER T - 'u' # 0xA4 -> LATIN SMALL LETTER U - 'v' # 0xA5 -> LATIN SMALL LETTER V - 'w' # 0xA6 -> LATIN SMALL LETTER W - 'x' # 0xA7 -> LATIN SMALL LETTER X - 'y' # 0xA8 -> LATIN SMALL LETTER Y - 'z' # 0xA9 -> LATIN SMALL LETTER Z - '\ufffe' # 0xAA -> UNDEFINED - '\ufffe' # 0xAB -> UNDEFINED - '\ufffe' # 0xAC -> UNDEFINED - '\ufffe' # 0xAD -> UNDEFINED - '\ufffe' # 0xAE -> UNDEFINED - '\xae' # 0xAF -> REGISTERED SIGN - '^' # 0xB0 -> CIRCUMFLEX ACCENT - '\xa3' # 0xB1 -> POUND SIGN - '\xa5' # 0xB2 -> YEN SIGN - '\xb7' # 0xB3 -> MIDDLE DOT - '\xa9' # 0xB4 -> COPYRIGHT SIGN - '\xa7' # 0xB5 -> SECTION SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF - '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS - '[' # 0xBA -> LEFT SQUARE BRACKET - ']' # 0xBB -> RIGHT SQUARE BRACKET - '\xaf' # 0xBC -> MACRON - '\xa8' # 0xBD -> DIAERESIS - '\xb4' # 0xBE -> ACUTE ACCENT - '\xd7' # 0xBF -> MULTIPLICATION SIGN - '{' # 0xC0 -> LEFT CURLY BRACKET - 'A' # 0xC1 -> LATIN CAPITAL LETTER A - 'B' # 0xC2 -> LATIN CAPITAL LETTER B - 'C' # 0xC3 -> LATIN CAPITAL LETTER C - 'D' # 0xC4 -> LATIN CAPITAL LETTER D - 'E' # 0xC5 -> LATIN CAPITAL LETTER E - 'F' # 0xC6 -> LATIN CAPITAL LETTER F - 'G' # 0xC7 -> LATIN CAPITAL LETTER G - 'H' # 0xC8 -> LATIN CAPITAL LETTER H - 'I' # 0xC9 -> LATIN CAPITAL LETTER I - '\xad' # 0xCA -> SOFT HYPHEN - '\ufffe' # 0xCB -> UNDEFINED - '\ufffe' # 0xCC -> UNDEFINED - '\ufffe' # 0xCD -> UNDEFINED - '\ufffe' # 0xCE -> UNDEFINED - '\ufffe' # 0xCF -> UNDEFINED - '}' # 0xD0 -> RIGHT CURLY BRACKET - 'J' # 0xD1 -> LATIN CAPITAL LETTER J - 'K' # 0xD2 -> LATIN CAPITAL LETTER K - 'L' # 0xD3 -> LATIN CAPITAL LETTER L - 'M' # 0xD4 -> LATIN CAPITAL LETTER M - 'N' # 0xD5 -> LATIN CAPITAL LETTER N - 'O' # 0xD6 -> LATIN CAPITAL LETTER O - 'P' # 0xD7 -> LATIN CAPITAL LETTER P - 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q - 'R' # 0xD9 -> LATIN CAPITAL LETTER R - '\xb9' # 0xDA -> SUPERSCRIPT ONE - '\ufffe' # 0xDB -> UNDEFINED - '\ufffe' # 0xDC -> UNDEFINED - '\ufffe' # 0xDD -> UNDEFINED - '\ufffe' # 0xDE -> UNDEFINED - '\ufffe' # 0xDF -> UNDEFINED - '\\' # 0xE0 -> REVERSE SOLIDUS - '\xf7' # 0xE1 -> DIVISION SIGN - 'S' # 0xE2 -> LATIN CAPITAL LETTER S - 'T' # 0xE3 -> LATIN CAPITAL LETTER T - 'U' # 0xE4 -> LATIN CAPITAL LETTER U - 'V' # 0xE5 -> LATIN CAPITAL LETTER V - 'W' # 0xE6 -> LATIN CAPITAL LETTER W - 'X' # 0xE7 -> LATIN CAPITAL LETTER X - 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y - 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z - '\xb2' # 0xEA -> SUPERSCRIPT TWO - '\ufffe' # 0xEB -> UNDEFINED - '\ufffe' # 0xEC -> UNDEFINED - '\ufffe' # 0xED -> UNDEFINED - '\ufffe' # 0xEE -> UNDEFINED - '\ufffe' # 0xEF -> UNDEFINED - '0' # 0xF0 -> DIGIT ZERO - '1' # 0xF1 -> DIGIT ONE - '2' # 0xF2 -> DIGIT TWO - '3' # 0xF3 -> DIGIT THREE - '4' # 0xF4 -> DIGIT FOUR - '5' # 0xF5 -> DIGIT FIVE - '6' # 0xF6 -> DIGIT SIX - '7' # 0xF7 -> DIGIT SEVEN - '8' # 0xF8 -> DIGIT EIGHT - '9' # 0xF9 -> DIGIT NINE - '\xb3' # 0xFA -> SUPERSCRIPT THREE - '\ufffe' # 0xFB -> UNDEFINED - '\ufffe' # 0xFC -> UNDEFINED - '\ufffe' # 0xFD -> UNDEFINED - '\ufffe' # 0xFE -> UNDEFINED - '\x9f' # 0xFF -> EIGHT ONES -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp437.py b/python/Lib/encodings/cp437.py deleted file mode 100644 index 5620867..0000000 --- a/python/Lib/encodings/cp437.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec cp437 generated from 'VENDORS/MICSFT/PC/CP437.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp437', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE - 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS - 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE - 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE - 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA - 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS - 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE - 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS - 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE - 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE - 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE - 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE - 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS - 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE - 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE - 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS - 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x009b: 0x00a2, # CENT SIGN - 0x009c: 0x00a3, # POUND SIGN - 0x009d: 0x00a5, # YEN SIGN - 0x009e: 0x20a7, # PESETA SIGN - 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK - 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE - 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE - 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE - 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE - 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE - 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR - 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR - 0x00a8: 0x00bf, # INVERTED QUESTION MARK - 0x00a9: 0x2310, # REVERSED NOT SIGN - 0x00aa: 0x00ac, # NOT SIGN - 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF - 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER - 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x258c, # LEFT HALF BLOCK - 0x00de: 0x2590, # RIGHT HALF BLOCK - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA - 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S - 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA - 0x00e3: 0x03c0, # GREEK SMALL LETTER PI - 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA - 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA - 0x00e6: 0x00b5, # MICRO SIGN - 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU - 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI - 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA - 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA - 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA - 0x00ec: 0x221e, # INFINITY - 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI - 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON - 0x00ef: 0x2229, # INTERSECTION - 0x00f0: 0x2261, # IDENTICAL TO - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO - 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO - 0x00f4: 0x2320, # TOP HALF INTEGRAL - 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x2248, # ALMOST EQUAL TO - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x2219, # BULLET OPERATOR - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x221a, # SQUARE ROOT - 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N - 0x00fd: 0x00b2, # SUPERSCRIPT TWO - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS - '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE - '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE - '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA - '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE - '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS - '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE - '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE - '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE - '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE - '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE - '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS - '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xa2' # 0x009b -> CENT SIGN - '\xa3' # 0x009c -> POUND SIGN - '\xa5' # 0x009d -> YEN SIGN - '\u20a7' # 0x009e -> PESETA SIGN - '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK - '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE - '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE - '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE - '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE - '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE - '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE - '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR - '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR - '\xbf' # 0x00a8 -> INVERTED QUESTION MARK - '\u2310' # 0x00a9 -> REVERSED NOT SIGN - '\xac' # 0x00aa -> NOT SIGN - '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF - '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER - '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u258c' # 0x00dd -> LEFT HALF BLOCK - '\u2590' # 0x00de -> RIGHT HALF BLOCK - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA - '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S - '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA - '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI - '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA - '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA - '\xb5' # 0x00e6 -> MICRO SIGN - '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU - '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI - '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA - '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA - '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA - '\u221e' # 0x00ec -> INFINITY - '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI - '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON - '\u2229' # 0x00ef -> INTERSECTION - '\u2261' # 0x00f0 -> IDENTICAL TO - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO - '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO - '\u2320' # 0x00f4 -> TOP HALF INTEGRAL - '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL - '\xf7' # 0x00f6 -> DIVISION SIGN - '\u2248' # 0x00f7 -> ALMOST EQUAL TO - '\xb0' # 0x00f8 -> DEGREE SIGN - '\u2219' # 0x00f9 -> BULLET OPERATOR - '\xb7' # 0x00fa -> MIDDLE DOT - '\u221a' # 0x00fb -> SQUARE ROOT - '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N - '\xb2' # 0x00fd -> SUPERSCRIPT TWO - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK - 0x00a2: 0x009b, # CENT SIGN - 0x00a3: 0x009c, # POUND SIGN - 0x00a5: 0x009d, # YEN SIGN - 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x00aa, # NOT SIGN - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x00fd, # SUPERSCRIPT TWO - 0x00b5: 0x00e6, # MICRO SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER - 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF - 0x00bf: 0x00a8, # INVERTED QUESTION MARK - 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE - 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE - 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE - 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S - 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE - 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE - 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS - 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE - 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE - 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA - 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE - 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE - 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS - 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE - 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE - 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS - 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE - 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE - 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE - 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS - 0x00f7: 0x00f6, # DIVISION SIGN - 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE - 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE - 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS - 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS - 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK - 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA - 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA - 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA - 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI - 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA - 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA - 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA - 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON - 0x03c0: 0x00e3, # GREEK SMALL LETTER PI - 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA - 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU - 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI - 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N - 0x20a7: 0x009e, # PESETA SIGN - 0x2219: 0x00f9, # BULLET OPERATOR - 0x221a: 0x00fb, # SQUARE ROOT - 0x221e: 0x00ec, # INFINITY - 0x2229: 0x00ef, # INTERSECTION - 0x2248: 0x00f7, # ALMOST EQUAL TO - 0x2261: 0x00f0, # IDENTICAL TO - 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO - 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO - 0x2310: 0x00a9, # REVERSED NOT SIGN - 0x2320: 0x00f4, # TOP HALF INTEGRAL - 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x258c: 0x00dd, # LEFT HALF BLOCK - 0x2590: 0x00de, # RIGHT HALF BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp500.py b/python/Lib/encodings/cp500.py deleted file mode 100644 index 491ce30..0000000 --- a/python/Lib/encodings/cp500.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp500 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp500', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x9c' # 0x04 -> CONTROL - '\t' # 0x05 -> HORIZONTAL TABULATION - '\x86' # 0x06 -> CONTROL - '\x7f' # 0x07 -> DELETE - '\x97' # 0x08 -> CONTROL - '\x8d' # 0x09 -> CONTROL - '\x8e' # 0x0A -> CONTROL - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x9d' # 0x14 -> CONTROL - '\x85' # 0x15 -> CONTROL - '\x08' # 0x16 -> BACKSPACE - '\x87' # 0x17 -> CONTROL - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x92' # 0x1A -> CONTROL - '\x8f' # 0x1B -> CONTROL - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - '\x80' # 0x20 -> CONTROL - '\x81' # 0x21 -> CONTROL - '\x82' # 0x22 -> CONTROL - '\x83' # 0x23 -> CONTROL - '\x84' # 0x24 -> CONTROL - '\n' # 0x25 -> LINE FEED - '\x17' # 0x26 -> END OF TRANSMISSION BLOCK - '\x1b' # 0x27 -> ESCAPE - '\x88' # 0x28 -> CONTROL - '\x89' # 0x29 -> CONTROL - '\x8a' # 0x2A -> CONTROL - '\x8b' # 0x2B -> CONTROL - '\x8c' # 0x2C -> CONTROL - '\x05' # 0x2D -> ENQUIRY - '\x06' # 0x2E -> ACKNOWLEDGE - '\x07' # 0x2F -> BELL - '\x90' # 0x30 -> CONTROL - '\x91' # 0x31 -> CONTROL - '\x16' # 0x32 -> SYNCHRONOUS IDLE - '\x93' # 0x33 -> CONTROL - '\x94' # 0x34 -> CONTROL - '\x95' # 0x35 -> CONTROL - '\x96' # 0x36 -> CONTROL - '\x04' # 0x37 -> END OF TRANSMISSION - '\x98' # 0x38 -> CONTROL - '\x99' # 0x39 -> CONTROL - '\x9a' # 0x3A -> CONTROL - '\x9b' # 0x3B -> CONTROL - '\x14' # 0x3C -> DEVICE CONTROL FOUR - '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE - '\x9e' # 0x3E -> CONTROL - '\x1a' # 0x3F -> SUBSTITUTE - ' ' # 0x40 -> SPACE - '\xa0' # 0x41 -> NO-BREAK SPACE - '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE - '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE - '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA - '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE - '[' # 0x4A -> LEFT SQUARE BRACKET - '.' # 0x4B -> FULL STOP - '<' # 0x4C -> LESS-THAN SIGN - '(' # 0x4D -> LEFT PARENTHESIS - '+' # 0x4E -> PLUS SIGN - '!' # 0x4F -> EXCLAMATION MARK - '&' # 0x50 -> AMPERSAND - '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE - '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE - '\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) - ']' # 0x5A -> RIGHT SQUARE BRACKET - '$' # 0x5B -> DOLLAR SIGN - '*' # 0x5C -> ASTERISK - ')' # 0x5D -> RIGHT PARENTHESIS - ';' # 0x5E -> SEMICOLON - '^' # 0x5F -> CIRCUMFLEX ACCENT - '-' # 0x60 -> HYPHEN-MINUS - '/' # 0x61 -> SOLIDUS - '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE - '\xa6' # 0x6A -> BROKEN BAR - ',' # 0x6B -> COMMA - '%' # 0x6C -> PERCENT SIGN - '_' # 0x6D -> LOW LINE - '>' # 0x6E -> GREATER-THAN SIGN - '?' # 0x6F -> QUESTION MARK - '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE - '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE - '`' # 0x79 -> GRAVE ACCENT - ':' # 0x7A -> COLON - '#' # 0x7B -> NUMBER SIGN - '@' # 0x7C -> COMMERCIAL AT - "'" # 0x7D -> APOSTROPHE - '=' # 0x7E -> EQUALS SIGN - '"' # 0x7F -> QUOTATION MARK - '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE - 'a' # 0x81 -> LATIN SMALL LETTER A - 'b' # 0x82 -> LATIN SMALL LETTER B - 'c' # 0x83 -> LATIN SMALL LETTER C - 'd' # 0x84 -> LATIN SMALL LETTER D - 'e' # 0x85 -> LATIN SMALL LETTER E - 'f' # 0x86 -> LATIN SMALL LETTER F - 'g' # 0x87 -> LATIN SMALL LETTER G - 'h' # 0x88 -> LATIN SMALL LETTER H - 'i' # 0x89 -> LATIN SMALL LETTER I - '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xf0' # 0x8C -> LATIN SMALL LETTER ETH (ICELANDIC) - '\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE - '\xfe' # 0x8E -> LATIN SMALL LETTER THORN (ICELANDIC) - '\xb1' # 0x8F -> PLUS-MINUS SIGN - '\xb0' # 0x90 -> DEGREE SIGN - 'j' # 0x91 -> LATIN SMALL LETTER J - 'k' # 0x92 -> LATIN SMALL LETTER K - 'l' # 0x93 -> LATIN SMALL LETTER L - 'm' # 0x94 -> LATIN SMALL LETTER M - 'n' # 0x95 -> LATIN SMALL LETTER N - 'o' # 0x96 -> LATIN SMALL LETTER O - 'p' # 0x97 -> LATIN SMALL LETTER P - 'q' # 0x98 -> LATIN SMALL LETTER Q - 'r' # 0x99 -> LATIN SMALL LETTER R - '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR - '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR - '\xe6' # 0x9C -> LATIN SMALL LIGATURE AE - '\xb8' # 0x9D -> CEDILLA - '\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE - '\xa4' # 0x9F -> CURRENCY SIGN - '\xb5' # 0xA0 -> MICRO SIGN - '~' # 0xA1 -> TILDE - 's' # 0xA2 -> LATIN SMALL LETTER S - 't' # 0xA3 -> LATIN SMALL LETTER T - 'u' # 0xA4 -> LATIN SMALL LETTER U - 'v' # 0xA5 -> LATIN SMALL LETTER V - 'w' # 0xA6 -> LATIN SMALL LETTER W - 'x' # 0xA7 -> LATIN SMALL LETTER X - 'y' # 0xA8 -> LATIN SMALL LETTER Y - 'z' # 0xA9 -> LATIN SMALL LETTER Z - '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK - '\xbf' # 0xAB -> INVERTED QUESTION MARK - '\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC) - '\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC) - '\xae' # 0xAF -> REGISTERED SIGN - '\xa2' # 0xB0 -> CENT SIGN - '\xa3' # 0xB1 -> POUND SIGN - '\xa5' # 0xB2 -> YEN SIGN - '\xb7' # 0xB3 -> MIDDLE DOT - '\xa9' # 0xB4 -> COPYRIGHT SIGN - '\xa7' # 0xB5 -> SECTION SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF - '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS - '\xac' # 0xBA -> NOT SIGN - '|' # 0xBB -> VERTICAL LINE - '\xaf' # 0xBC -> MACRON - '\xa8' # 0xBD -> DIAERESIS - '\xb4' # 0xBE -> ACUTE ACCENT - '\xd7' # 0xBF -> MULTIPLICATION SIGN - '{' # 0xC0 -> LEFT CURLY BRACKET - 'A' # 0xC1 -> LATIN CAPITAL LETTER A - 'B' # 0xC2 -> LATIN CAPITAL LETTER B - 'C' # 0xC3 -> LATIN CAPITAL LETTER C - 'D' # 0xC4 -> LATIN CAPITAL LETTER D - 'E' # 0xC5 -> LATIN CAPITAL LETTER E - 'F' # 0xC6 -> LATIN CAPITAL LETTER F - 'G' # 0xC7 -> LATIN CAPITAL LETTER G - 'H' # 0xC8 -> LATIN CAPITAL LETTER H - 'I' # 0xC9 -> LATIN CAPITAL LETTER I - '\xad' # 0xCA -> SOFT HYPHEN - '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0xCC -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE - '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE - '}' # 0xD0 -> RIGHT CURLY BRACKET - 'J' # 0xD1 -> LATIN CAPITAL LETTER J - 'K' # 0xD2 -> LATIN CAPITAL LETTER K - 'L' # 0xD3 -> LATIN CAPITAL LETTER L - 'M' # 0xD4 -> LATIN CAPITAL LETTER M - 'N' # 0xD5 -> LATIN CAPITAL LETTER N - 'O' # 0xD6 -> LATIN CAPITAL LETTER O - 'P' # 0xD7 -> LATIN CAPITAL LETTER P - 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q - 'R' # 0xD9 -> LATIN CAPITAL LETTER R - '\xb9' # 0xDA -> SUPERSCRIPT ONE - '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xDC -> LATIN SMALL LETTER U WITH DIAERESIS - '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE - '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS - '\\' # 0xE0 -> REVERSE SOLIDUS - '\xf7' # 0xE1 -> DIVISION SIGN - 'S' # 0xE2 -> LATIN CAPITAL LETTER S - 'T' # 0xE3 -> LATIN CAPITAL LETTER T - 'U' # 0xE4 -> LATIN CAPITAL LETTER U - 'V' # 0xE5 -> LATIN CAPITAL LETTER V - 'W' # 0xE6 -> LATIN CAPITAL LETTER W - 'X' # 0xE7 -> LATIN CAPITAL LETTER X - 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y - 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z - '\xb2' # 0xEA -> SUPERSCRIPT TWO - '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd6' # 0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE - '0' # 0xF0 -> DIGIT ZERO - '1' # 0xF1 -> DIGIT ONE - '2' # 0xF2 -> DIGIT TWO - '3' # 0xF3 -> DIGIT THREE - '4' # 0xF4 -> DIGIT FOUR - '5' # 0xF5 -> DIGIT FIVE - '6' # 0xF6 -> DIGIT SIX - '7' # 0xF7 -> DIGIT SEVEN - '8' # 0xF8 -> DIGIT EIGHT - '9' # 0xF9 -> DIGIT NINE - '\xb3' # 0xFA -> SUPERSCRIPT THREE - '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE - '\x9f' # 0xFF -> CONTROL -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp720.py b/python/Lib/encodings/cp720.py deleted file mode 100644 index 5e2890e..0000000 --- a/python/Lib/encodings/cp720.py +++ /dev/null @@ -1,309 +0,0 @@ -"""Python Character Mapping Codec cp720 generated on Windows: -Vista 6.0.6002 SP2 Multiprocessor Free with the command: - python Tools/unicode/genwincodec.py 720 -"""#" - - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp720', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> CONTROL CHARACTER - '\x01' # 0x01 -> CONTROL CHARACTER - '\x02' # 0x02 -> CONTROL CHARACTER - '\x03' # 0x03 -> CONTROL CHARACTER - '\x04' # 0x04 -> CONTROL CHARACTER - '\x05' # 0x05 -> CONTROL CHARACTER - '\x06' # 0x06 -> CONTROL CHARACTER - '\x07' # 0x07 -> CONTROL CHARACTER - '\x08' # 0x08 -> CONTROL CHARACTER - '\t' # 0x09 -> CONTROL CHARACTER - '\n' # 0x0A -> CONTROL CHARACTER - '\x0b' # 0x0B -> CONTROL CHARACTER - '\x0c' # 0x0C -> CONTROL CHARACTER - '\r' # 0x0D -> CONTROL CHARACTER - '\x0e' # 0x0E -> CONTROL CHARACTER - '\x0f' # 0x0F -> CONTROL CHARACTER - '\x10' # 0x10 -> CONTROL CHARACTER - '\x11' # 0x11 -> CONTROL CHARACTER - '\x12' # 0x12 -> CONTROL CHARACTER - '\x13' # 0x13 -> CONTROL CHARACTER - '\x14' # 0x14 -> CONTROL CHARACTER - '\x15' # 0x15 -> CONTROL CHARACTER - '\x16' # 0x16 -> CONTROL CHARACTER - '\x17' # 0x17 -> CONTROL CHARACTER - '\x18' # 0x18 -> CONTROL CHARACTER - '\x19' # 0x19 -> CONTROL CHARACTER - '\x1a' # 0x1A -> CONTROL CHARACTER - '\x1b' # 0x1B -> CONTROL CHARACTER - '\x1c' # 0x1C -> CONTROL CHARACTER - '\x1d' # 0x1D -> CONTROL CHARACTER - '\x1e' # 0x1E -> CONTROL CHARACTER - '\x1f' # 0x1F -> CONTROL CHARACTER - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> CONTROL CHARACTER - '\x80' - '\x81' - '\xe9' # 0x82 -> LATIN SMALL LETTER E WITH ACUTE - '\xe2' # 0x83 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\x84' - '\xe0' # 0x85 -> LATIN SMALL LETTER A WITH GRAVE - '\x86' - '\xe7' # 0x87 -> LATIN SMALL LETTER C WITH CEDILLA - '\xea' # 0x88 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x89 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x8A -> LATIN SMALL LETTER E WITH GRAVE - '\xef' # 0x8B -> LATIN SMALL LETTER I WITH DIAERESIS - '\xee' # 0x8C -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\x8d' - '\x8e' - '\x8f' - '\x90' - '\u0651' # 0x91 -> ARABIC SHADDA - '\u0652' # 0x92 -> ARABIC SUKUN - '\xf4' # 0x93 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xa4' # 0x94 -> CURRENCY SIGN - '\u0640' # 0x95 -> ARABIC TATWEEL - '\xfb' # 0x96 -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xf9' # 0x97 -> LATIN SMALL LETTER U WITH GRAVE - '\u0621' # 0x98 -> ARABIC LETTER HAMZA - '\u0622' # 0x99 -> ARABIC LETTER ALEF WITH MADDA ABOVE - '\u0623' # 0x9A -> ARABIC LETTER ALEF WITH HAMZA ABOVE - '\u0624' # 0x9B -> ARABIC LETTER WAW WITH HAMZA ABOVE - '\xa3' # 0x9C -> POUND SIGN - '\u0625' # 0x9D -> ARABIC LETTER ALEF WITH HAMZA BELOW - '\u0626' # 0x9E -> ARABIC LETTER YEH WITH HAMZA ABOVE - '\u0627' # 0x9F -> ARABIC LETTER ALEF - '\u0628' # 0xA0 -> ARABIC LETTER BEH - '\u0629' # 0xA1 -> ARABIC LETTER TEH MARBUTA - '\u062a' # 0xA2 -> ARABIC LETTER TEH - '\u062b' # 0xA3 -> ARABIC LETTER THEH - '\u062c' # 0xA4 -> ARABIC LETTER JEEM - '\u062d' # 0xA5 -> ARABIC LETTER HAH - '\u062e' # 0xA6 -> ARABIC LETTER KHAH - '\u062f' # 0xA7 -> ARABIC LETTER DAL - '\u0630' # 0xA8 -> ARABIC LETTER THAL - '\u0631' # 0xA9 -> ARABIC LETTER REH - '\u0632' # 0xAA -> ARABIC LETTER ZAIN - '\u0633' # 0xAB -> ARABIC LETTER SEEN - '\u0634' # 0xAC -> ARABIC LETTER SHEEN - '\u0635' # 0xAD -> ARABIC LETTER SAD - '\xab' # 0xAE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0xAF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0xB0 -> LIGHT SHADE - '\u2592' # 0xB1 -> MEDIUM SHADE - '\u2593' # 0xB2 -> DARK SHADE - '\u2502' # 0xB3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0xB4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u2561' # 0xB5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u2562' # 0xB6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - '\u2556' # 0xB7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - '\u2555' # 0xB8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - '\u2563' # 0xB9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0xBA -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0xBB -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0xBC -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255c' # 0xBD -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - '\u255b' # 0xBE -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u2510' # 0xBF -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0xC0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0xC1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0xC2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0xC3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0xC4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0xC5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u255e' # 0xC6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0xC7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u255a' # 0xC8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0xC9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0xCA -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0xCB -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0xCC -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0xCD -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0xCE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u2567' # 0xCF -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0xD0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2564' # 0xD1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - '\u2565' # 0xD2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - '\u2559' # 0xD3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u2558' # 0xD4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2552' # 0xD5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u2553' # 0xD6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - '\u256b' # 0xD7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - '\u256a' # 0xD8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u2518' # 0xD9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0xDA -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0xDB -> FULL BLOCK - '\u2584' # 0xDC -> LOWER HALF BLOCK - '\u258c' # 0xDD -> LEFT HALF BLOCK - '\u2590' # 0xDE -> RIGHT HALF BLOCK - '\u2580' # 0xDF -> UPPER HALF BLOCK - '\u0636' # 0xE0 -> ARABIC LETTER DAD - '\u0637' # 0xE1 -> ARABIC LETTER TAH - '\u0638' # 0xE2 -> ARABIC LETTER ZAH - '\u0639' # 0xE3 -> ARABIC LETTER AIN - '\u063a' # 0xE4 -> ARABIC LETTER GHAIN - '\u0641' # 0xE5 -> ARABIC LETTER FEH - '\xb5' # 0xE6 -> MICRO SIGN - '\u0642' # 0xE7 -> ARABIC LETTER QAF - '\u0643' # 0xE8 -> ARABIC LETTER KAF - '\u0644' # 0xE9 -> ARABIC LETTER LAM - '\u0645' # 0xEA -> ARABIC LETTER MEEM - '\u0646' # 0xEB -> ARABIC LETTER NOON - '\u0647' # 0xEC -> ARABIC LETTER HEH - '\u0648' # 0xED -> ARABIC LETTER WAW - '\u0649' # 0xEE -> ARABIC LETTER ALEF MAKSURA - '\u064a' # 0xEF -> ARABIC LETTER YEH - '\u2261' # 0xF0 -> IDENTICAL TO - '\u064b' # 0xF1 -> ARABIC FATHATAN - '\u064c' # 0xF2 -> ARABIC DAMMATAN - '\u064d' # 0xF3 -> ARABIC KASRATAN - '\u064e' # 0xF4 -> ARABIC FATHA - '\u064f' # 0xF5 -> ARABIC DAMMA - '\u0650' # 0xF6 -> ARABIC KASRA - '\u2248' # 0xF7 -> ALMOST EQUAL TO - '\xb0' # 0xF8 -> DEGREE SIGN - '\u2219' # 0xF9 -> BULLET OPERATOR - '\xb7' # 0xFA -> MIDDLE DOT - '\u221a' # 0xFB -> SQUARE ROOT - '\u207f' # 0xFC -> SUPERSCRIPT LATIN SMALL LETTER N - '\xb2' # 0xFD -> SUPERSCRIPT TWO - '\u25a0' # 0xFE -> BLACK SQUARE - '\xa0' # 0xFF -> NO-BREAK SPACE -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp737.py b/python/Lib/encodings/cp737.py deleted file mode 100644 index 5c7d0cd..0000000 --- a/python/Lib/encodings/cp737.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec cp737 generated from 'VENDORS/MICSFT/PC/CP737.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp737', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x0391, # GREEK CAPITAL LETTER ALPHA - 0x0081: 0x0392, # GREEK CAPITAL LETTER BETA - 0x0082: 0x0393, # GREEK CAPITAL LETTER GAMMA - 0x0083: 0x0394, # GREEK CAPITAL LETTER DELTA - 0x0084: 0x0395, # GREEK CAPITAL LETTER EPSILON - 0x0085: 0x0396, # GREEK CAPITAL LETTER ZETA - 0x0086: 0x0397, # GREEK CAPITAL LETTER ETA - 0x0087: 0x0398, # GREEK CAPITAL LETTER THETA - 0x0088: 0x0399, # GREEK CAPITAL LETTER IOTA - 0x0089: 0x039a, # GREEK CAPITAL LETTER KAPPA - 0x008a: 0x039b, # GREEK CAPITAL LETTER LAMDA - 0x008b: 0x039c, # GREEK CAPITAL LETTER MU - 0x008c: 0x039d, # GREEK CAPITAL LETTER NU - 0x008d: 0x039e, # GREEK CAPITAL LETTER XI - 0x008e: 0x039f, # GREEK CAPITAL LETTER OMICRON - 0x008f: 0x03a0, # GREEK CAPITAL LETTER PI - 0x0090: 0x03a1, # GREEK CAPITAL LETTER RHO - 0x0091: 0x03a3, # GREEK CAPITAL LETTER SIGMA - 0x0092: 0x03a4, # GREEK CAPITAL LETTER TAU - 0x0093: 0x03a5, # GREEK CAPITAL LETTER UPSILON - 0x0094: 0x03a6, # GREEK CAPITAL LETTER PHI - 0x0095: 0x03a7, # GREEK CAPITAL LETTER CHI - 0x0096: 0x03a8, # GREEK CAPITAL LETTER PSI - 0x0097: 0x03a9, # GREEK CAPITAL LETTER OMEGA - 0x0098: 0x03b1, # GREEK SMALL LETTER ALPHA - 0x0099: 0x03b2, # GREEK SMALL LETTER BETA - 0x009a: 0x03b3, # GREEK SMALL LETTER GAMMA - 0x009b: 0x03b4, # GREEK SMALL LETTER DELTA - 0x009c: 0x03b5, # GREEK SMALL LETTER EPSILON - 0x009d: 0x03b6, # GREEK SMALL LETTER ZETA - 0x009e: 0x03b7, # GREEK SMALL LETTER ETA - 0x009f: 0x03b8, # GREEK SMALL LETTER THETA - 0x00a0: 0x03b9, # GREEK SMALL LETTER IOTA - 0x00a1: 0x03ba, # GREEK SMALL LETTER KAPPA - 0x00a2: 0x03bb, # GREEK SMALL LETTER LAMDA - 0x00a3: 0x03bc, # GREEK SMALL LETTER MU - 0x00a4: 0x03bd, # GREEK SMALL LETTER NU - 0x00a5: 0x03be, # GREEK SMALL LETTER XI - 0x00a6: 0x03bf, # GREEK SMALL LETTER OMICRON - 0x00a7: 0x03c0, # GREEK SMALL LETTER PI - 0x00a8: 0x03c1, # GREEK SMALL LETTER RHO - 0x00a9: 0x03c3, # GREEK SMALL LETTER SIGMA - 0x00aa: 0x03c2, # GREEK SMALL LETTER FINAL SIGMA - 0x00ab: 0x03c4, # GREEK SMALL LETTER TAU - 0x00ac: 0x03c5, # GREEK SMALL LETTER UPSILON - 0x00ad: 0x03c6, # GREEK SMALL LETTER PHI - 0x00ae: 0x03c7, # GREEK SMALL LETTER CHI - 0x00af: 0x03c8, # GREEK SMALL LETTER PSI - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x258c, # LEFT HALF BLOCK - 0x00de: 0x2590, # RIGHT HALF BLOCK - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x03c9, # GREEK SMALL LETTER OMEGA - 0x00e1: 0x03ac, # GREEK SMALL LETTER ALPHA WITH TONOS - 0x00e2: 0x03ad, # GREEK SMALL LETTER EPSILON WITH TONOS - 0x00e3: 0x03ae, # GREEK SMALL LETTER ETA WITH TONOS - 0x00e4: 0x03ca, # GREEK SMALL LETTER IOTA WITH DIALYTIKA - 0x00e5: 0x03af, # GREEK SMALL LETTER IOTA WITH TONOS - 0x00e6: 0x03cc, # GREEK SMALL LETTER OMICRON WITH TONOS - 0x00e7: 0x03cd, # GREEK SMALL LETTER UPSILON WITH TONOS - 0x00e8: 0x03cb, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA - 0x00e9: 0x03ce, # GREEK SMALL LETTER OMEGA WITH TONOS - 0x00ea: 0x0386, # GREEK CAPITAL LETTER ALPHA WITH TONOS - 0x00eb: 0x0388, # GREEK CAPITAL LETTER EPSILON WITH TONOS - 0x00ec: 0x0389, # GREEK CAPITAL LETTER ETA WITH TONOS - 0x00ed: 0x038a, # GREEK CAPITAL LETTER IOTA WITH TONOS - 0x00ee: 0x038c, # GREEK CAPITAL LETTER OMICRON WITH TONOS - 0x00ef: 0x038e, # GREEK CAPITAL LETTER UPSILON WITH TONOS - 0x00f0: 0x038f, # GREEK CAPITAL LETTER OMEGA WITH TONOS - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO - 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO - 0x00f4: 0x03aa, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - 0x00f5: 0x03ab, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x2248, # ALMOST EQUAL TO - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x2219, # BULLET OPERATOR - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x221a, # SQUARE ROOT - 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N - 0x00fd: 0x00b2, # SUPERSCRIPT TWO - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\u0391' # 0x0080 -> GREEK CAPITAL LETTER ALPHA - '\u0392' # 0x0081 -> GREEK CAPITAL LETTER BETA - '\u0393' # 0x0082 -> GREEK CAPITAL LETTER GAMMA - '\u0394' # 0x0083 -> GREEK CAPITAL LETTER DELTA - '\u0395' # 0x0084 -> GREEK CAPITAL LETTER EPSILON - '\u0396' # 0x0085 -> GREEK CAPITAL LETTER ZETA - '\u0397' # 0x0086 -> GREEK CAPITAL LETTER ETA - '\u0398' # 0x0087 -> GREEK CAPITAL LETTER THETA - '\u0399' # 0x0088 -> GREEK CAPITAL LETTER IOTA - '\u039a' # 0x0089 -> GREEK CAPITAL LETTER KAPPA - '\u039b' # 0x008a -> GREEK CAPITAL LETTER LAMDA - '\u039c' # 0x008b -> GREEK CAPITAL LETTER MU - '\u039d' # 0x008c -> GREEK CAPITAL LETTER NU - '\u039e' # 0x008d -> GREEK CAPITAL LETTER XI - '\u039f' # 0x008e -> GREEK CAPITAL LETTER OMICRON - '\u03a0' # 0x008f -> GREEK CAPITAL LETTER PI - '\u03a1' # 0x0090 -> GREEK CAPITAL LETTER RHO - '\u03a3' # 0x0091 -> GREEK CAPITAL LETTER SIGMA - '\u03a4' # 0x0092 -> GREEK CAPITAL LETTER TAU - '\u03a5' # 0x0093 -> GREEK CAPITAL LETTER UPSILON - '\u03a6' # 0x0094 -> GREEK CAPITAL LETTER PHI - '\u03a7' # 0x0095 -> GREEK CAPITAL LETTER CHI - '\u03a8' # 0x0096 -> GREEK CAPITAL LETTER PSI - '\u03a9' # 0x0097 -> GREEK CAPITAL LETTER OMEGA - '\u03b1' # 0x0098 -> GREEK SMALL LETTER ALPHA - '\u03b2' # 0x0099 -> GREEK SMALL LETTER BETA - '\u03b3' # 0x009a -> GREEK SMALL LETTER GAMMA - '\u03b4' # 0x009b -> GREEK SMALL LETTER DELTA - '\u03b5' # 0x009c -> GREEK SMALL LETTER EPSILON - '\u03b6' # 0x009d -> GREEK SMALL LETTER ZETA - '\u03b7' # 0x009e -> GREEK SMALL LETTER ETA - '\u03b8' # 0x009f -> GREEK SMALL LETTER THETA - '\u03b9' # 0x00a0 -> GREEK SMALL LETTER IOTA - '\u03ba' # 0x00a1 -> GREEK SMALL LETTER KAPPA - '\u03bb' # 0x00a2 -> GREEK SMALL LETTER LAMDA - '\u03bc' # 0x00a3 -> GREEK SMALL LETTER MU - '\u03bd' # 0x00a4 -> GREEK SMALL LETTER NU - '\u03be' # 0x00a5 -> GREEK SMALL LETTER XI - '\u03bf' # 0x00a6 -> GREEK SMALL LETTER OMICRON - '\u03c0' # 0x00a7 -> GREEK SMALL LETTER PI - '\u03c1' # 0x00a8 -> GREEK SMALL LETTER RHO - '\u03c3' # 0x00a9 -> GREEK SMALL LETTER SIGMA - '\u03c2' # 0x00aa -> GREEK SMALL LETTER FINAL SIGMA - '\u03c4' # 0x00ab -> GREEK SMALL LETTER TAU - '\u03c5' # 0x00ac -> GREEK SMALL LETTER UPSILON - '\u03c6' # 0x00ad -> GREEK SMALL LETTER PHI - '\u03c7' # 0x00ae -> GREEK SMALL LETTER CHI - '\u03c8' # 0x00af -> GREEK SMALL LETTER PSI - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u258c' # 0x00dd -> LEFT HALF BLOCK - '\u2590' # 0x00de -> RIGHT HALF BLOCK - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\u03c9' # 0x00e0 -> GREEK SMALL LETTER OMEGA - '\u03ac' # 0x00e1 -> GREEK SMALL LETTER ALPHA WITH TONOS - '\u03ad' # 0x00e2 -> GREEK SMALL LETTER EPSILON WITH TONOS - '\u03ae' # 0x00e3 -> GREEK SMALL LETTER ETA WITH TONOS - '\u03ca' # 0x00e4 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA - '\u03af' # 0x00e5 -> GREEK SMALL LETTER IOTA WITH TONOS - '\u03cc' # 0x00e6 -> GREEK SMALL LETTER OMICRON WITH TONOS - '\u03cd' # 0x00e7 -> GREEK SMALL LETTER UPSILON WITH TONOS - '\u03cb' # 0x00e8 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA - '\u03ce' # 0x00e9 -> GREEK SMALL LETTER OMEGA WITH TONOS - '\u0386' # 0x00ea -> GREEK CAPITAL LETTER ALPHA WITH TONOS - '\u0388' # 0x00eb -> GREEK CAPITAL LETTER EPSILON WITH TONOS - '\u0389' # 0x00ec -> GREEK CAPITAL LETTER ETA WITH TONOS - '\u038a' # 0x00ed -> GREEK CAPITAL LETTER IOTA WITH TONOS - '\u038c' # 0x00ee -> GREEK CAPITAL LETTER OMICRON WITH TONOS - '\u038e' # 0x00ef -> GREEK CAPITAL LETTER UPSILON WITH TONOS - '\u038f' # 0x00f0 -> GREEK CAPITAL LETTER OMEGA WITH TONOS - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO - '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO - '\u03aa' # 0x00f4 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - '\u03ab' # 0x00f5 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - '\xf7' # 0x00f6 -> DIVISION SIGN - '\u2248' # 0x00f7 -> ALMOST EQUAL TO - '\xb0' # 0x00f8 -> DEGREE SIGN - '\u2219' # 0x00f9 -> BULLET OPERATOR - '\xb7' # 0x00fa -> MIDDLE DOT - '\u221a' # 0x00fb -> SQUARE ROOT - '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N - '\xb2' # 0x00fd -> SUPERSCRIPT TWO - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x00fd, # SUPERSCRIPT TWO - 0x00b7: 0x00fa, # MIDDLE DOT - 0x00f7: 0x00f6, # DIVISION SIGN - 0x0386: 0x00ea, # GREEK CAPITAL LETTER ALPHA WITH TONOS - 0x0388: 0x00eb, # GREEK CAPITAL LETTER EPSILON WITH TONOS - 0x0389: 0x00ec, # GREEK CAPITAL LETTER ETA WITH TONOS - 0x038a: 0x00ed, # GREEK CAPITAL LETTER IOTA WITH TONOS - 0x038c: 0x00ee, # GREEK CAPITAL LETTER OMICRON WITH TONOS - 0x038e: 0x00ef, # GREEK CAPITAL LETTER UPSILON WITH TONOS - 0x038f: 0x00f0, # GREEK CAPITAL LETTER OMEGA WITH TONOS - 0x0391: 0x0080, # GREEK CAPITAL LETTER ALPHA - 0x0392: 0x0081, # GREEK CAPITAL LETTER BETA - 0x0393: 0x0082, # GREEK CAPITAL LETTER GAMMA - 0x0394: 0x0083, # GREEK CAPITAL LETTER DELTA - 0x0395: 0x0084, # GREEK CAPITAL LETTER EPSILON - 0x0396: 0x0085, # GREEK CAPITAL LETTER ZETA - 0x0397: 0x0086, # GREEK CAPITAL LETTER ETA - 0x0398: 0x0087, # GREEK CAPITAL LETTER THETA - 0x0399: 0x0088, # GREEK CAPITAL LETTER IOTA - 0x039a: 0x0089, # GREEK CAPITAL LETTER KAPPA - 0x039b: 0x008a, # GREEK CAPITAL LETTER LAMDA - 0x039c: 0x008b, # GREEK CAPITAL LETTER MU - 0x039d: 0x008c, # GREEK CAPITAL LETTER NU - 0x039e: 0x008d, # GREEK CAPITAL LETTER XI - 0x039f: 0x008e, # GREEK CAPITAL LETTER OMICRON - 0x03a0: 0x008f, # GREEK CAPITAL LETTER PI - 0x03a1: 0x0090, # GREEK CAPITAL LETTER RHO - 0x03a3: 0x0091, # GREEK CAPITAL LETTER SIGMA - 0x03a4: 0x0092, # GREEK CAPITAL LETTER TAU - 0x03a5: 0x0093, # GREEK CAPITAL LETTER UPSILON - 0x03a6: 0x0094, # GREEK CAPITAL LETTER PHI - 0x03a7: 0x0095, # GREEK CAPITAL LETTER CHI - 0x03a8: 0x0096, # GREEK CAPITAL LETTER PSI - 0x03a9: 0x0097, # GREEK CAPITAL LETTER OMEGA - 0x03aa: 0x00f4, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - 0x03ab: 0x00f5, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - 0x03ac: 0x00e1, # GREEK SMALL LETTER ALPHA WITH TONOS - 0x03ad: 0x00e2, # GREEK SMALL LETTER EPSILON WITH TONOS - 0x03ae: 0x00e3, # GREEK SMALL LETTER ETA WITH TONOS - 0x03af: 0x00e5, # GREEK SMALL LETTER IOTA WITH TONOS - 0x03b1: 0x0098, # GREEK SMALL LETTER ALPHA - 0x03b2: 0x0099, # GREEK SMALL LETTER BETA - 0x03b3: 0x009a, # GREEK SMALL LETTER GAMMA - 0x03b4: 0x009b, # GREEK SMALL LETTER DELTA - 0x03b5: 0x009c, # GREEK SMALL LETTER EPSILON - 0x03b6: 0x009d, # GREEK SMALL LETTER ZETA - 0x03b7: 0x009e, # GREEK SMALL LETTER ETA - 0x03b8: 0x009f, # GREEK SMALL LETTER THETA - 0x03b9: 0x00a0, # GREEK SMALL LETTER IOTA - 0x03ba: 0x00a1, # GREEK SMALL LETTER KAPPA - 0x03bb: 0x00a2, # GREEK SMALL LETTER LAMDA - 0x03bc: 0x00a3, # GREEK SMALL LETTER MU - 0x03bd: 0x00a4, # GREEK SMALL LETTER NU - 0x03be: 0x00a5, # GREEK SMALL LETTER XI - 0x03bf: 0x00a6, # GREEK SMALL LETTER OMICRON - 0x03c0: 0x00a7, # GREEK SMALL LETTER PI - 0x03c1: 0x00a8, # GREEK SMALL LETTER RHO - 0x03c2: 0x00aa, # GREEK SMALL LETTER FINAL SIGMA - 0x03c3: 0x00a9, # GREEK SMALL LETTER SIGMA - 0x03c4: 0x00ab, # GREEK SMALL LETTER TAU - 0x03c5: 0x00ac, # GREEK SMALL LETTER UPSILON - 0x03c6: 0x00ad, # GREEK SMALL LETTER PHI - 0x03c7: 0x00ae, # GREEK SMALL LETTER CHI - 0x03c8: 0x00af, # GREEK SMALL LETTER PSI - 0x03c9: 0x00e0, # GREEK SMALL LETTER OMEGA - 0x03ca: 0x00e4, # GREEK SMALL LETTER IOTA WITH DIALYTIKA - 0x03cb: 0x00e8, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA - 0x03cc: 0x00e6, # GREEK SMALL LETTER OMICRON WITH TONOS - 0x03cd: 0x00e7, # GREEK SMALL LETTER UPSILON WITH TONOS - 0x03ce: 0x00e9, # GREEK SMALL LETTER OMEGA WITH TONOS - 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N - 0x2219: 0x00f9, # BULLET OPERATOR - 0x221a: 0x00fb, # SQUARE ROOT - 0x2248: 0x00f7, # ALMOST EQUAL TO - 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO - 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x258c: 0x00dd, # LEFT HALF BLOCK - 0x2590: 0x00de, # RIGHT HALF BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp775.py b/python/Lib/encodings/cp775.py deleted file mode 100644 index 72ed83e..0000000 --- a/python/Lib/encodings/cp775.py +++ /dev/null @@ -1,697 +0,0 @@ -""" Python Character Mapping Codec cp775 generated from 'VENDORS/MICSFT/PC/CP775.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp775', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE - 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE - 0x0083: 0x0101, # LATIN SMALL LETTER A WITH MACRON - 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS - 0x0085: 0x0123, # LATIN SMALL LETTER G WITH CEDILLA - 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE - 0x0087: 0x0107, # LATIN SMALL LETTER C WITH ACUTE - 0x0088: 0x0142, # LATIN SMALL LETTER L WITH STROKE - 0x0089: 0x0113, # LATIN SMALL LETTER E WITH MACRON - 0x008a: 0x0156, # LATIN CAPITAL LETTER R WITH CEDILLA - 0x008b: 0x0157, # LATIN SMALL LETTER R WITH CEDILLA - 0x008c: 0x012b, # LATIN SMALL LETTER I WITH MACRON - 0x008d: 0x0179, # LATIN CAPITAL LETTER Z WITH ACUTE - 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE - 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE - 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE - 0x0093: 0x014d, # LATIN SMALL LETTER O WITH MACRON - 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS - 0x0095: 0x0122, # LATIN CAPITAL LETTER G WITH CEDILLA - 0x0096: 0x00a2, # CENT SIGN - 0x0097: 0x015a, # LATIN CAPITAL LETTER S WITH ACUTE - 0x0098: 0x015b, # LATIN SMALL LETTER S WITH ACUTE - 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE - 0x009c: 0x00a3, # POUND SIGN - 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE - 0x009e: 0x00d7, # MULTIPLICATION SIGN - 0x009f: 0x00a4, # CURRENCY SIGN - 0x00a0: 0x0100, # LATIN CAPITAL LETTER A WITH MACRON - 0x00a1: 0x012a, # LATIN CAPITAL LETTER I WITH MACRON - 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x00a3: 0x017b, # LATIN CAPITAL LETTER Z WITH DOT ABOVE - 0x00a4: 0x017c, # LATIN SMALL LETTER Z WITH DOT ABOVE - 0x00a5: 0x017a, # LATIN SMALL LETTER Z WITH ACUTE - 0x00a6: 0x201d, # RIGHT DOUBLE QUOTATION MARK - 0x00a7: 0x00a6, # BROKEN BAR - 0x00a8: 0x00a9, # COPYRIGHT SIGN - 0x00a9: 0x00ae, # REGISTERED SIGN - 0x00aa: 0x00ac, # NOT SIGN - 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF - 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER - 0x00ad: 0x0141, # LATIN CAPITAL LETTER L WITH STROKE - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK - 0x00b6: 0x010c, # LATIN CAPITAL LETTER C WITH CARON - 0x00b7: 0x0118, # LATIN CAPITAL LETTER E WITH OGONEK - 0x00b8: 0x0116, # LATIN CAPITAL LETTER E WITH DOT ABOVE - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x012e, # LATIN CAPITAL LETTER I WITH OGONEK - 0x00be: 0x0160, # LATIN CAPITAL LETTER S WITH CARON - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x0172, # LATIN CAPITAL LETTER U WITH OGONEK - 0x00c7: 0x016a, # LATIN CAPITAL LETTER U WITH MACRON - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x017d, # LATIN CAPITAL LETTER Z WITH CARON - 0x00d0: 0x0105, # LATIN SMALL LETTER A WITH OGONEK - 0x00d1: 0x010d, # LATIN SMALL LETTER C WITH CARON - 0x00d2: 0x0119, # LATIN SMALL LETTER E WITH OGONEK - 0x00d3: 0x0117, # LATIN SMALL LETTER E WITH DOT ABOVE - 0x00d4: 0x012f, # LATIN SMALL LETTER I WITH OGONEK - 0x00d5: 0x0161, # LATIN SMALL LETTER S WITH CARON - 0x00d6: 0x0173, # LATIN SMALL LETTER U WITH OGONEK - 0x00d7: 0x016b, # LATIN SMALL LETTER U WITH MACRON - 0x00d8: 0x017e, # LATIN SMALL LETTER Z WITH CARON - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x258c, # LEFT HALF BLOCK - 0x00de: 0x2590, # RIGHT HALF BLOCK - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S (GERMAN) - 0x00e2: 0x014c, # LATIN CAPITAL LETTER O WITH MACRON - 0x00e3: 0x0143, # LATIN CAPITAL LETTER N WITH ACUTE - 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE - 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE - 0x00e6: 0x00b5, # MICRO SIGN - 0x00e7: 0x0144, # LATIN SMALL LETTER N WITH ACUTE - 0x00e8: 0x0136, # LATIN CAPITAL LETTER K WITH CEDILLA - 0x00e9: 0x0137, # LATIN SMALL LETTER K WITH CEDILLA - 0x00ea: 0x013b, # LATIN CAPITAL LETTER L WITH CEDILLA - 0x00eb: 0x013c, # LATIN SMALL LETTER L WITH CEDILLA - 0x00ec: 0x0146, # LATIN SMALL LETTER N WITH CEDILLA - 0x00ed: 0x0112, # LATIN CAPITAL LETTER E WITH MACRON - 0x00ee: 0x0145, # LATIN CAPITAL LETTER N WITH CEDILLA - 0x00ef: 0x2019, # RIGHT SINGLE QUOTATION MARK - 0x00f0: 0x00ad, # SOFT HYPHEN - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: 0x201c, # LEFT DOUBLE QUOTATION MARK - 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS - 0x00f4: 0x00b6, # PILCROW SIGN - 0x00f5: 0x00a7, # SECTION SIGN - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x201e, # DOUBLE LOW-9 QUOTATION MARK - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x2219, # BULLET OPERATOR - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x00b9, # SUPERSCRIPT ONE - 0x00fc: 0x00b3, # SUPERSCRIPT THREE - 0x00fd: 0x00b2, # SUPERSCRIPT TWO - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\u0106' # 0x0080 -> LATIN CAPITAL LETTER C WITH ACUTE - '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS - '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE - '\u0101' # 0x0083 -> LATIN SMALL LETTER A WITH MACRON - '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS - '\u0123' # 0x0085 -> LATIN SMALL LETTER G WITH CEDILLA - '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE - '\u0107' # 0x0087 -> LATIN SMALL LETTER C WITH ACUTE - '\u0142' # 0x0088 -> LATIN SMALL LETTER L WITH STROKE - '\u0113' # 0x0089 -> LATIN SMALL LETTER E WITH MACRON - '\u0156' # 0x008a -> LATIN CAPITAL LETTER R WITH CEDILLA - '\u0157' # 0x008b -> LATIN SMALL LETTER R WITH CEDILLA - '\u012b' # 0x008c -> LATIN SMALL LETTER I WITH MACRON - '\u0179' # 0x008d -> LATIN CAPITAL LETTER Z WITH ACUTE - '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE - '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE - '\u014d' # 0x0093 -> LATIN SMALL LETTER O WITH MACRON - '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS - '\u0122' # 0x0095 -> LATIN CAPITAL LETTER G WITH CEDILLA - '\xa2' # 0x0096 -> CENT SIGN - '\u015a' # 0x0097 -> LATIN CAPITAL LETTER S WITH ACUTE - '\u015b' # 0x0098 -> LATIN SMALL LETTER S WITH ACUTE - '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE - '\xa3' # 0x009c -> POUND SIGN - '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE - '\xd7' # 0x009e -> MULTIPLICATION SIGN - '\xa4' # 0x009f -> CURRENCY SIGN - '\u0100' # 0x00a0 -> LATIN CAPITAL LETTER A WITH MACRON - '\u012a' # 0x00a1 -> LATIN CAPITAL LETTER I WITH MACRON - '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE - '\u017b' # 0x00a3 -> LATIN CAPITAL LETTER Z WITH DOT ABOVE - '\u017c' # 0x00a4 -> LATIN SMALL LETTER Z WITH DOT ABOVE - '\u017a' # 0x00a5 -> LATIN SMALL LETTER Z WITH ACUTE - '\u201d' # 0x00a6 -> RIGHT DOUBLE QUOTATION MARK - '\xa6' # 0x00a7 -> BROKEN BAR - '\xa9' # 0x00a8 -> COPYRIGHT SIGN - '\xae' # 0x00a9 -> REGISTERED SIGN - '\xac' # 0x00aa -> NOT SIGN - '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF - '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER - '\u0141' # 0x00ad -> LATIN CAPITAL LETTER L WITH STROKE - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u0104' # 0x00b5 -> LATIN CAPITAL LETTER A WITH OGONEK - '\u010c' # 0x00b6 -> LATIN CAPITAL LETTER C WITH CARON - '\u0118' # 0x00b7 -> LATIN CAPITAL LETTER E WITH OGONEK - '\u0116' # 0x00b8 -> LATIN CAPITAL LETTER E WITH DOT ABOVE - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u012e' # 0x00bd -> LATIN CAPITAL LETTER I WITH OGONEK - '\u0160' # 0x00be -> LATIN CAPITAL LETTER S WITH CARON - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u0172' # 0x00c6 -> LATIN CAPITAL LETTER U WITH OGONEK - '\u016a' # 0x00c7 -> LATIN CAPITAL LETTER U WITH MACRON - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u017d' # 0x00cf -> LATIN CAPITAL LETTER Z WITH CARON - '\u0105' # 0x00d0 -> LATIN SMALL LETTER A WITH OGONEK - '\u010d' # 0x00d1 -> LATIN SMALL LETTER C WITH CARON - '\u0119' # 0x00d2 -> LATIN SMALL LETTER E WITH OGONEK - '\u0117' # 0x00d3 -> LATIN SMALL LETTER E WITH DOT ABOVE - '\u012f' # 0x00d4 -> LATIN SMALL LETTER I WITH OGONEK - '\u0161' # 0x00d5 -> LATIN SMALL LETTER S WITH CARON - '\u0173' # 0x00d6 -> LATIN SMALL LETTER U WITH OGONEK - '\u016b' # 0x00d7 -> LATIN SMALL LETTER U WITH MACRON - '\u017e' # 0x00d8 -> LATIN SMALL LETTER Z WITH CARON - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u258c' # 0x00dd -> LEFT HALF BLOCK - '\u2590' # 0x00de -> RIGHT HALF BLOCK - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S (GERMAN) - '\u014c' # 0x00e2 -> LATIN CAPITAL LETTER O WITH MACRON - '\u0143' # 0x00e3 -> LATIN CAPITAL LETTER N WITH ACUTE - '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE - '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xb5' # 0x00e6 -> MICRO SIGN - '\u0144' # 0x00e7 -> LATIN SMALL LETTER N WITH ACUTE - '\u0136' # 0x00e8 -> LATIN CAPITAL LETTER K WITH CEDILLA - '\u0137' # 0x00e9 -> LATIN SMALL LETTER K WITH CEDILLA - '\u013b' # 0x00ea -> LATIN CAPITAL LETTER L WITH CEDILLA - '\u013c' # 0x00eb -> LATIN SMALL LETTER L WITH CEDILLA - '\u0146' # 0x00ec -> LATIN SMALL LETTER N WITH CEDILLA - '\u0112' # 0x00ed -> LATIN CAPITAL LETTER E WITH MACRON - '\u0145' # 0x00ee -> LATIN CAPITAL LETTER N WITH CEDILLA - '\u2019' # 0x00ef -> RIGHT SINGLE QUOTATION MARK - '\xad' # 0x00f0 -> SOFT HYPHEN - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\u201c' # 0x00f2 -> LEFT DOUBLE QUOTATION MARK - '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS - '\xb6' # 0x00f4 -> PILCROW SIGN - '\xa7' # 0x00f5 -> SECTION SIGN - '\xf7' # 0x00f6 -> DIVISION SIGN - '\u201e' # 0x00f7 -> DOUBLE LOW-9 QUOTATION MARK - '\xb0' # 0x00f8 -> DEGREE SIGN - '\u2219' # 0x00f9 -> BULLET OPERATOR - '\xb7' # 0x00fa -> MIDDLE DOT - '\xb9' # 0x00fb -> SUPERSCRIPT ONE - '\xb3' # 0x00fc -> SUPERSCRIPT THREE - '\xb2' # 0x00fd -> SUPERSCRIPT TWO - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a2: 0x0096, # CENT SIGN - 0x00a3: 0x009c, # POUND SIGN - 0x00a4: 0x009f, # CURRENCY SIGN - 0x00a6: 0x00a7, # BROKEN BAR - 0x00a7: 0x00f5, # SECTION SIGN - 0x00a9: 0x00a8, # COPYRIGHT SIGN - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x00aa, # NOT SIGN - 0x00ad: 0x00f0, # SOFT HYPHEN - 0x00ae: 0x00a9, # REGISTERED SIGN - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x00fd, # SUPERSCRIPT TWO - 0x00b3: 0x00fc, # SUPERSCRIPT THREE - 0x00b5: 0x00e6, # MICRO SIGN - 0x00b6: 0x00f4, # PILCROW SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x00b9: 0x00fb, # SUPERSCRIPT ONE - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER - 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF - 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS - 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE - 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE - 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE - 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x00d7: 0x009e, # MULTIPLICATION SIGN - 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE - 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S (GERMAN) - 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS - 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE - 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE - 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE - 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE - 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE - 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS - 0x00f7: 0x00f6, # DIVISION SIGN - 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE - 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0100: 0x00a0, # LATIN CAPITAL LETTER A WITH MACRON - 0x0101: 0x0083, # LATIN SMALL LETTER A WITH MACRON - 0x0104: 0x00b5, # LATIN CAPITAL LETTER A WITH OGONEK - 0x0105: 0x00d0, # LATIN SMALL LETTER A WITH OGONEK - 0x0106: 0x0080, # LATIN CAPITAL LETTER C WITH ACUTE - 0x0107: 0x0087, # LATIN SMALL LETTER C WITH ACUTE - 0x010c: 0x00b6, # LATIN CAPITAL LETTER C WITH CARON - 0x010d: 0x00d1, # LATIN SMALL LETTER C WITH CARON - 0x0112: 0x00ed, # LATIN CAPITAL LETTER E WITH MACRON - 0x0113: 0x0089, # LATIN SMALL LETTER E WITH MACRON - 0x0116: 0x00b8, # LATIN CAPITAL LETTER E WITH DOT ABOVE - 0x0117: 0x00d3, # LATIN SMALL LETTER E WITH DOT ABOVE - 0x0118: 0x00b7, # LATIN CAPITAL LETTER E WITH OGONEK - 0x0119: 0x00d2, # LATIN SMALL LETTER E WITH OGONEK - 0x0122: 0x0095, # LATIN CAPITAL LETTER G WITH CEDILLA - 0x0123: 0x0085, # LATIN SMALL LETTER G WITH CEDILLA - 0x012a: 0x00a1, # LATIN CAPITAL LETTER I WITH MACRON - 0x012b: 0x008c, # LATIN SMALL LETTER I WITH MACRON - 0x012e: 0x00bd, # LATIN CAPITAL LETTER I WITH OGONEK - 0x012f: 0x00d4, # LATIN SMALL LETTER I WITH OGONEK - 0x0136: 0x00e8, # LATIN CAPITAL LETTER K WITH CEDILLA - 0x0137: 0x00e9, # LATIN SMALL LETTER K WITH CEDILLA - 0x013b: 0x00ea, # LATIN CAPITAL LETTER L WITH CEDILLA - 0x013c: 0x00eb, # LATIN SMALL LETTER L WITH CEDILLA - 0x0141: 0x00ad, # LATIN CAPITAL LETTER L WITH STROKE - 0x0142: 0x0088, # LATIN SMALL LETTER L WITH STROKE - 0x0143: 0x00e3, # LATIN CAPITAL LETTER N WITH ACUTE - 0x0144: 0x00e7, # LATIN SMALL LETTER N WITH ACUTE - 0x0145: 0x00ee, # LATIN CAPITAL LETTER N WITH CEDILLA - 0x0146: 0x00ec, # LATIN SMALL LETTER N WITH CEDILLA - 0x014c: 0x00e2, # LATIN CAPITAL LETTER O WITH MACRON - 0x014d: 0x0093, # LATIN SMALL LETTER O WITH MACRON - 0x0156: 0x008a, # LATIN CAPITAL LETTER R WITH CEDILLA - 0x0157: 0x008b, # LATIN SMALL LETTER R WITH CEDILLA - 0x015a: 0x0097, # LATIN CAPITAL LETTER S WITH ACUTE - 0x015b: 0x0098, # LATIN SMALL LETTER S WITH ACUTE - 0x0160: 0x00be, # LATIN CAPITAL LETTER S WITH CARON - 0x0161: 0x00d5, # LATIN SMALL LETTER S WITH CARON - 0x016a: 0x00c7, # LATIN CAPITAL LETTER U WITH MACRON - 0x016b: 0x00d7, # LATIN SMALL LETTER U WITH MACRON - 0x0172: 0x00c6, # LATIN CAPITAL LETTER U WITH OGONEK - 0x0173: 0x00d6, # LATIN SMALL LETTER U WITH OGONEK - 0x0179: 0x008d, # LATIN CAPITAL LETTER Z WITH ACUTE - 0x017a: 0x00a5, # LATIN SMALL LETTER Z WITH ACUTE - 0x017b: 0x00a3, # LATIN CAPITAL LETTER Z WITH DOT ABOVE - 0x017c: 0x00a4, # LATIN SMALL LETTER Z WITH DOT ABOVE - 0x017d: 0x00cf, # LATIN CAPITAL LETTER Z WITH CARON - 0x017e: 0x00d8, # LATIN SMALL LETTER Z WITH CARON - 0x2019: 0x00ef, # RIGHT SINGLE QUOTATION MARK - 0x201c: 0x00f2, # LEFT DOUBLE QUOTATION MARK - 0x201d: 0x00a6, # RIGHT DOUBLE QUOTATION MARK - 0x201e: 0x00f7, # DOUBLE LOW-9 QUOTATION MARK - 0x2219: 0x00f9, # BULLET OPERATOR - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x258c: 0x00dd, # LEFT HALF BLOCK - 0x2590: 0x00de, # RIGHT HALF BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp850.py b/python/Lib/encodings/cp850.py deleted file mode 100644 index 6ccb111..0000000 --- a/python/Lib/encodings/cp850.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP850.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp850', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE - 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS - 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE - 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE - 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA - 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS - 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE - 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS - 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE - 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE - 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE - 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE - 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS - 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE - 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE - 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS - 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE - 0x009c: 0x00a3, # POUND SIGN - 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE - 0x009e: 0x00d7, # MULTIPLICATION SIGN - 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK - 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE - 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE - 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE - 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE - 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE - 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR - 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR - 0x00a8: 0x00bf, # INVERTED QUESTION MARK - 0x00a9: 0x00ae, # REGISTERED SIGN - 0x00aa: 0x00ac, # NOT SIGN - 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF - 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER - 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE - 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE - 0x00b8: 0x00a9, # COPYRIGHT SIGN - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x00a2, # CENT SIGN - 0x00be: 0x00a5, # YEN SIGN - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE - 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x00a4, # CURRENCY SIGN - 0x00d0: 0x00f0, # LATIN SMALL LETTER ETH - 0x00d1: 0x00d0, # LATIN CAPITAL LETTER ETH - 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX - 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS - 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE - 0x00d5: 0x0131, # LATIN SMALL LETTER DOTLESS I - 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE - 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX - 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x00a6, # BROKEN BAR - 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S - 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE - 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE - 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE - 0x00e6: 0x00b5, # MICRO SIGN - 0x00e7: 0x00fe, # LATIN SMALL LETTER THORN - 0x00e8: 0x00de, # LATIN CAPITAL LETTER THORN - 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE - 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX - 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE - 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE - 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE - 0x00ee: 0x00af, # MACRON - 0x00ef: 0x00b4, # ACUTE ACCENT - 0x00f0: 0x00ad, # SOFT HYPHEN - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: 0x2017, # DOUBLE LOW LINE - 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS - 0x00f4: 0x00b6, # PILCROW SIGN - 0x00f5: 0x00a7, # SECTION SIGN - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x00b8, # CEDILLA - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x00a8, # DIAERESIS - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x00b9, # SUPERSCRIPT ONE - 0x00fc: 0x00b3, # SUPERSCRIPT THREE - 0x00fd: 0x00b2, # SUPERSCRIPT TWO - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS - '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE - '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE - '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA - '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE - '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS - '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE - '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE - '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE - '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE - '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE - '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS - '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE - '\xa3' # 0x009c -> POUND SIGN - '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE - '\xd7' # 0x009e -> MULTIPLICATION SIGN - '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK - '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE - '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE - '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE - '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE - '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE - '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE - '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR - '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR - '\xbf' # 0x00a8 -> INVERTED QUESTION MARK - '\xae' # 0x00a9 -> REGISTERED SIGN - '\xac' # 0x00aa -> NOT SIGN - '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF - '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER - '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xa9' # 0x00b8 -> COPYRIGHT SIGN - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\xa2' # 0x00bd -> CENT SIGN - '\xa5' # 0x00be -> YEN SIGN - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE - '\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\xa4' # 0x00cf -> CURRENCY SIGN - '\xf0' # 0x00d0 -> LATIN SMALL LETTER ETH - '\xd0' # 0x00d1 -> LATIN CAPITAL LETTER ETH - '\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE - '\u0131' # 0x00d5 -> LATIN SMALL LETTER DOTLESS I - '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\xa6' # 0x00dd -> BROKEN BAR - '\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S - '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE - '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xb5' # 0x00e6 -> MICRO SIGN - '\xfe' # 0x00e7 -> LATIN SMALL LETTER THORN - '\xde' # 0x00e8 -> LATIN CAPITAL LETTER THORN - '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE - '\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE - '\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xaf' # 0x00ee -> MACRON - '\xb4' # 0x00ef -> ACUTE ACCENT - '\xad' # 0x00f0 -> SOFT HYPHEN - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\u2017' # 0x00f2 -> DOUBLE LOW LINE - '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS - '\xb6' # 0x00f4 -> PILCROW SIGN - '\xa7' # 0x00f5 -> SECTION SIGN - '\xf7' # 0x00f6 -> DIVISION SIGN - '\xb8' # 0x00f7 -> CEDILLA - '\xb0' # 0x00f8 -> DEGREE SIGN - '\xa8' # 0x00f9 -> DIAERESIS - '\xb7' # 0x00fa -> MIDDLE DOT - '\xb9' # 0x00fb -> SUPERSCRIPT ONE - '\xb3' # 0x00fc -> SUPERSCRIPT THREE - '\xb2' # 0x00fd -> SUPERSCRIPT TWO - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK - 0x00a2: 0x00bd, # CENT SIGN - 0x00a3: 0x009c, # POUND SIGN - 0x00a4: 0x00cf, # CURRENCY SIGN - 0x00a5: 0x00be, # YEN SIGN - 0x00a6: 0x00dd, # BROKEN BAR - 0x00a7: 0x00f5, # SECTION SIGN - 0x00a8: 0x00f9, # DIAERESIS - 0x00a9: 0x00b8, # COPYRIGHT SIGN - 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x00aa, # NOT SIGN - 0x00ad: 0x00f0, # SOFT HYPHEN - 0x00ae: 0x00a9, # REGISTERED SIGN - 0x00af: 0x00ee, # MACRON - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x00fd, # SUPERSCRIPT TWO - 0x00b3: 0x00fc, # SUPERSCRIPT THREE - 0x00b4: 0x00ef, # ACUTE ACCENT - 0x00b5: 0x00e6, # MICRO SIGN - 0x00b6: 0x00f4, # PILCROW SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x00b8: 0x00f7, # CEDILLA - 0x00b9: 0x00fb, # SUPERSCRIPT ONE - 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER - 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF - 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS - 0x00bf: 0x00a8, # INVERTED QUESTION MARK - 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE - 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE - 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE - 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE - 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE - 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE - 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX - 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS - 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE - 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE - 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX - 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS - 0x00d0: 0x00d1, # LATIN CAPITAL LETTER ETH - 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE - 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE - 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE - 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x00d7: 0x009e, # MULTIPLICATION SIGN - 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE - 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE - 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE - 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX - 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE - 0x00de: 0x00e8, # LATIN CAPITAL LETTER THORN - 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S - 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE - 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE - 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE - 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS - 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE - 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE - 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA - 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE - 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE - 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS - 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE - 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE - 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS - 0x00f0: 0x00d0, # LATIN SMALL LETTER ETH - 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE - 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE - 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE - 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE - 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS - 0x00f7: 0x00f6, # DIVISION SIGN - 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE - 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE - 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE - 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS - 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE - 0x00fe: 0x00e7, # LATIN SMALL LETTER THORN - 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS - 0x0131: 0x00d5, # LATIN SMALL LETTER DOTLESS I - 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK - 0x2017: 0x00f2, # DOUBLE LOW LINE - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp852.py b/python/Lib/encodings/cp852.py deleted file mode 100644 index 19a2871..0000000 --- a/python/Lib/encodings/cp852.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP852.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp852', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE - 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS - 0x0085: 0x016f, # LATIN SMALL LETTER U WITH RING ABOVE - 0x0086: 0x0107, # LATIN SMALL LETTER C WITH ACUTE - 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA - 0x0088: 0x0142, # LATIN SMALL LETTER L WITH STROKE - 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS - 0x008a: 0x0150, # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE - 0x008b: 0x0151, # LATIN SMALL LETTER O WITH DOUBLE ACUTE - 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x008d: 0x0179, # LATIN CAPITAL LETTER Z WITH ACUTE - 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x008f: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE - 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE - 0x0091: 0x0139, # LATIN CAPITAL LETTER L WITH ACUTE - 0x0092: 0x013a, # LATIN SMALL LETTER L WITH ACUTE - 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS - 0x0095: 0x013d, # LATIN CAPITAL LETTER L WITH CARON - 0x0096: 0x013e, # LATIN SMALL LETTER L WITH CARON - 0x0097: 0x015a, # LATIN CAPITAL LETTER S WITH ACUTE - 0x0098: 0x015b, # LATIN SMALL LETTER S WITH ACUTE - 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x009b: 0x0164, # LATIN CAPITAL LETTER T WITH CARON - 0x009c: 0x0165, # LATIN SMALL LETTER T WITH CARON - 0x009d: 0x0141, # LATIN CAPITAL LETTER L WITH STROKE - 0x009e: 0x00d7, # MULTIPLICATION SIGN - 0x009f: 0x010d, # LATIN SMALL LETTER C WITH CARON - 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE - 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE - 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE - 0x00a4: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK - 0x00a5: 0x0105, # LATIN SMALL LETTER A WITH OGONEK - 0x00a6: 0x017d, # LATIN CAPITAL LETTER Z WITH CARON - 0x00a7: 0x017e, # LATIN SMALL LETTER Z WITH CARON - 0x00a8: 0x0118, # LATIN CAPITAL LETTER E WITH OGONEK - 0x00a9: 0x0119, # LATIN SMALL LETTER E WITH OGONEK - 0x00aa: 0x00ac, # NOT SIGN - 0x00ab: 0x017a, # LATIN SMALL LETTER Z WITH ACUTE - 0x00ac: 0x010c, # LATIN CAPITAL LETTER C WITH CARON - 0x00ad: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE - 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x00b7: 0x011a, # LATIN CAPITAL LETTER E WITH CARON - 0x00b8: 0x015e, # LATIN CAPITAL LETTER S WITH CEDILLA - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x017b, # LATIN CAPITAL LETTER Z WITH DOT ABOVE - 0x00be: 0x017c, # LATIN SMALL LETTER Z WITH DOT ABOVE - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x0102, # LATIN CAPITAL LETTER A WITH BREVE - 0x00c7: 0x0103, # LATIN SMALL LETTER A WITH BREVE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x00a4, # CURRENCY SIGN - 0x00d0: 0x0111, # LATIN SMALL LETTER D WITH STROKE - 0x00d1: 0x0110, # LATIN CAPITAL LETTER D WITH STROKE - 0x00d2: 0x010e, # LATIN CAPITAL LETTER D WITH CARON - 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS - 0x00d4: 0x010f, # LATIN SMALL LETTER D WITH CARON - 0x00d5: 0x0147, # LATIN CAPITAL LETTER N WITH CARON - 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE - 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX - 0x00d8: 0x011b, # LATIN SMALL LETTER E WITH CARON - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x0162, # LATIN CAPITAL LETTER T WITH CEDILLA - 0x00de: 0x016e, # LATIN CAPITAL LETTER U WITH RING ABOVE - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S - 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x00e3: 0x0143, # LATIN CAPITAL LETTER N WITH ACUTE - 0x00e4: 0x0144, # LATIN SMALL LETTER N WITH ACUTE - 0x00e5: 0x0148, # LATIN SMALL LETTER N WITH CARON - 0x00e6: 0x0160, # LATIN CAPITAL LETTER S WITH CARON - 0x00e7: 0x0161, # LATIN SMALL LETTER S WITH CARON - 0x00e8: 0x0154, # LATIN CAPITAL LETTER R WITH ACUTE - 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE - 0x00ea: 0x0155, # LATIN SMALL LETTER R WITH ACUTE - 0x00eb: 0x0170, # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE - 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE - 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE - 0x00ee: 0x0163, # LATIN SMALL LETTER T WITH CEDILLA - 0x00ef: 0x00b4, # ACUTE ACCENT - 0x00f0: 0x00ad, # SOFT HYPHEN - 0x00f1: 0x02dd, # DOUBLE ACUTE ACCENT - 0x00f2: 0x02db, # OGONEK - 0x00f3: 0x02c7, # CARON - 0x00f4: 0x02d8, # BREVE - 0x00f5: 0x00a7, # SECTION SIGN - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x00b8, # CEDILLA - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x00a8, # DIAERESIS - 0x00fa: 0x02d9, # DOT ABOVE - 0x00fb: 0x0171, # LATIN SMALL LETTER U WITH DOUBLE ACUTE - 0x00fc: 0x0158, # LATIN CAPITAL LETTER R WITH CARON - 0x00fd: 0x0159, # LATIN SMALL LETTER R WITH CARON - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS - '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE - '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS - '\u016f' # 0x0085 -> LATIN SMALL LETTER U WITH RING ABOVE - '\u0107' # 0x0086 -> LATIN SMALL LETTER C WITH ACUTE - '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA - '\u0142' # 0x0088 -> LATIN SMALL LETTER L WITH STROKE - '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS - '\u0150' # 0x008a -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE - '\u0151' # 0x008b -> LATIN SMALL LETTER O WITH DOUBLE ACUTE - '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\u0179' # 0x008d -> LATIN CAPITAL LETTER Z WITH ACUTE - '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\u0106' # 0x008f -> LATIN CAPITAL LETTER C WITH ACUTE - '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE - '\u0139' # 0x0091 -> LATIN CAPITAL LETTER L WITH ACUTE - '\u013a' # 0x0092 -> LATIN SMALL LETTER L WITH ACUTE - '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS - '\u013d' # 0x0095 -> LATIN CAPITAL LETTER L WITH CARON - '\u013e' # 0x0096 -> LATIN SMALL LETTER L WITH CARON - '\u015a' # 0x0097 -> LATIN CAPITAL LETTER S WITH ACUTE - '\u015b' # 0x0098 -> LATIN SMALL LETTER S WITH ACUTE - '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\u0164' # 0x009b -> LATIN CAPITAL LETTER T WITH CARON - '\u0165' # 0x009c -> LATIN SMALL LETTER T WITH CARON - '\u0141' # 0x009d -> LATIN CAPITAL LETTER L WITH STROKE - '\xd7' # 0x009e -> MULTIPLICATION SIGN - '\u010d' # 0x009f -> LATIN SMALL LETTER C WITH CARON - '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE - '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE - '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE - '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE - '\u0104' # 0x00a4 -> LATIN CAPITAL LETTER A WITH OGONEK - '\u0105' # 0x00a5 -> LATIN SMALL LETTER A WITH OGONEK - '\u017d' # 0x00a6 -> LATIN CAPITAL LETTER Z WITH CARON - '\u017e' # 0x00a7 -> LATIN SMALL LETTER Z WITH CARON - '\u0118' # 0x00a8 -> LATIN CAPITAL LETTER E WITH OGONEK - '\u0119' # 0x00a9 -> LATIN SMALL LETTER E WITH OGONEK - '\xac' # 0x00aa -> NOT SIGN - '\u017a' # 0x00ab -> LATIN SMALL LETTER Z WITH ACUTE - '\u010c' # 0x00ac -> LATIN CAPITAL LETTER C WITH CARON - '\u015f' # 0x00ad -> LATIN SMALL LETTER S WITH CEDILLA - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\u011a' # 0x00b7 -> LATIN CAPITAL LETTER E WITH CARON - '\u015e' # 0x00b8 -> LATIN CAPITAL LETTER S WITH CEDILLA - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u017b' # 0x00bd -> LATIN CAPITAL LETTER Z WITH DOT ABOVE - '\u017c' # 0x00be -> LATIN SMALL LETTER Z WITH DOT ABOVE - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u0102' # 0x00c6 -> LATIN CAPITAL LETTER A WITH BREVE - '\u0103' # 0x00c7 -> LATIN SMALL LETTER A WITH BREVE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\xa4' # 0x00cf -> CURRENCY SIGN - '\u0111' # 0x00d0 -> LATIN SMALL LETTER D WITH STROKE - '\u0110' # 0x00d1 -> LATIN CAPITAL LETTER D WITH STROKE - '\u010e' # 0x00d2 -> LATIN CAPITAL LETTER D WITH CARON - '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\u010f' # 0x00d4 -> LATIN SMALL LETTER D WITH CARON - '\u0147' # 0x00d5 -> LATIN CAPITAL LETTER N WITH CARON - '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\u011b' # 0x00d8 -> LATIN SMALL LETTER E WITH CARON - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u0162' # 0x00dd -> LATIN CAPITAL LETTER T WITH CEDILLA - '\u016e' # 0x00de -> LATIN CAPITAL LETTER U WITH RING ABOVE - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S - '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\u0143' # 0x00e3 -> LATIN CAPITAL LETTER N WITH ACUTE - '\u0144' # 0x00e4 -> LATIN SMALL LETTER N WITH ACUTE - '\u0148' # 0x00e5 -> LATIN SMALL LETTER N WITH CARON - '\u0160' # 0x00e6 -> LATIN CAPITAL LETTER S WITH CARON - '\u0161' # 0x00e7 -> LATIN SMALL LETTER S WITH CARON - '\u0154' # 0x00e8 -> LATIN CAPITAL LETTER R WITH ACUTE - '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE - '\u0155' # 0x00ea -> LATIN SMALL LETTER R WITH ACUTE - '\u0170' # 0x00eb -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE - '\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE - '\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE - '\u0163' # 0x00ee -> LATIN SMALL LETTER T WITH CEDILLA - '\xb4' # 0x00ef -> ACUTE ACCENT - '\xad' # 0x00f0 -> SOFT HYPHEN - '\u02dd' # 0x00f1 -> DOUBLE ACUTE ACCENT - '\u02db' # 0x00f2 -> OGONEK - '\u02c7' # 0x00f3 -> CARON - '\u02d8' # 0x00f4 -> BREVE - '\xa7' # 0x00f5 -> SECTION SIGN - '\xf7' # 0x00f6 -> DIVISION SIGN - '\xb8' # 0x00f7 -> CEDILLA - '\xb0' # 0x00f8 -> DEGREE SIGN - '\xa8' # 0x00f9 -> DIAERESIS - '\u02d9' # 0x00fa -> DOT ABOVE - '\u0171' # 0x00fb -> LATIN SMALL LETTER U WITH DOUBLE ACUTE - '\u0158' # 0x00fc -> LATIN CAPITAL LETTER R WITH CARON - '\u0159' # 0x00fd -> LATIN SMALL LETTER R WITH CARON - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a4: 0x00cf, # CURRENCY SIGN - 0x00a7: 0x00f5, # SECTION SIGN - 0x00a8: 0x00f9, # DIAERESIS - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x00aa, # NOT SIGN - 0x00ad: 0x00f0, # SOFT HYPHEN - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b4: 0x00ef, # ACUTE ACCENT - 0x00b8: 0x00f7, # CEDILLA - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE - 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE - 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS - 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE - 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX - 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x00d7: 0x009e, # MULTIPLICATION SIGN - 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE - 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE - 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S - 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE - 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS - 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA - 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE - 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS - 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE - 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE - 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS - 0x00f7: 0x00f6, # DIVISION SIGN - 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE - 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS - 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE - 0x0102: 0x00c6, # LATIN CAPITAL LETTER A WITH BREVE - 0x0103: 0x00c7, # LATIN SMALL LETTER A WITH BREVE - 0x0104: 0x00a4, # LATIN CAPITAL LETTER A WITH OGONEK - 0x0105: 0x00a5, # LATIN SMALL LETTER A WITH OGONEK - 0x0106: 0x008f, # LATIN CAPITAL LETTER C WITH ACUTE - 0x0107: 0x0086, # LATIN SMALL LETTER C WITH ACUTE - 0x010c: 0x00ac, # LATIN CAPITAL LETTER C WITH CARON - 0x010d: 0x009f, # LATIN SMALL LETTER C WITH CARON - 0x010e: 0x00d2, # LATIN CAPITAL LETTER D WITH CARON - 0x010f: 0x00d4, # LATIN SMALL LETTER D WITH CARON - 0x0110: 0x00d1, # LATIN CAPITAL LETTER D WITH STROKE - 0x0111: 0x00d0, # LATIN SMALL LETTER D WITH STROKE - 0x0118: 0x00a8, # LATIN CAPITAL LETTER E WITH OGONEK - 0x0119: 0x00a9, # LATIN SMALL LETTER E WITH OGONEK - 0x011a: 0x00b7, # LATIN CAPITAL LETTER E WITH CARON - 0x011b: 0x00d8, # LATIN SMALL LETTER E WITH CARON - 0x0139: 0x0091, # LATIN CAPITAL LETTER L WITH ACUTE - 0x013a: 0x0092, # LATIN SMALL LETTER L WITH ACUTE - 0x013d: 0x0095, # LATIN CAPITAL LETTER L WITH CARON - 0x013e: 0x0096, # LATIN SMALL LETTER L WITH CARON - 0x0141: 0x009d, # LATIN CAPITAL LETTER L WITH STROKE - 0x0142: 0x0088, # LATIN SMALL LETTER L WITH STROKE - 0x0143: 0x00e3, # LATIN CAPITAL LETTER N WITH ACUTE - 0x0144: 0x00e4, # LATIN SMALL LETTER N WITH ACUTE - 0x0147: 0x00d5, # LATIN CAPITAL LETTER N WITH CARON - 0x0148: 0x00e5, # LATIN SMALL LETTER N WITH CARON - 0x0150: 0x008a, # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE - 0x0151: 0x008b, # LATIN SMALL LETTER O WITH DOUBLE ACUTE - 0x0154: 0x00e8, # LATIN CAPITAL LETTER R WITH ACUTE - 0x0155: 0x00ea, # LATIN SMALL LETTER R WITH ACUTE - 0x0158: 0x00fc, # LATIN CAPITAL LETTER R WITH CARON - 0x0159: 0x00fd, # LATIN SMALL LETTER R WITH CARON - 0x015a: 0x0097, # LATIN CAPITAL LETTER S WITH ACUTE - 0x015b: 0x0098, # LATIN SMALL LETTER S WITH ACUTE - 0x015e: 0x00b8, # LATIN CAPITAL LETTER S WITH CEDILLA - 0x015f: 0x00ad, # LATIN SMALL LETTER S WITH CEDILLA - 0x0160: 0x00e6, # LATIN CAPITAL LETTER S WITH CARON - 0x0161: 0x00e7, # LATIN SMALL LETTER S WITH CARON - 0x0162: 0x00dd, # LATIN CAPITAL LETTER T WITH CEDILLA - 0x0163: 0x00ee, # LATIN SMALL LETTER T WITH CEDILLA - 0x0164: 0x009b, # LATIN CAPITAL LETTER T WITH CARON - 0x0165: 0x009c, # LATIN SMALL LETTER T WITH CARON - 0x016e: 0x00de, # LATIN CAPITAL LETTER U WITH RING ABOVE - 0x016f: 0x0085, # LATIN SMALL LETTER U WITH RING ABOVE - 0x0170: 0x00eb, # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE - 0x0171: 0x00fb, # LATIN SMALL LETTER U WITH DOUBLE ACUTE - 0x0179: 0x008d, # LATIN CAPITAL LETTER Z WITH ACUTE - 0x017a: 0x00ab, # LATIN SMALL LETTER Z WITH ACUTE - 0x017b: 0x00bd, # LATIN CAPITAL LETTER Z WITH DOT ABOVE - 0x017c: 0x00be, # LATIN SMALL LETTER Z WITH DOT ABOVE - 0x017d: 0x00a6, # LATIN CAPITAL LETTER Z WITH CARON - 0x017e: 0x00a7, # LATIN SMALL LETTER Z WITH CARON - 0x02c7: 0x00f3, # CARON - 0x02d8: 0x00f4, # BREVE - 0x02d9: 0x00fa, # DOT ABOVE - 0x02db: 0x00f2, # OGONEK - 0x02dd: 0x00f1, # DOUBLE ACUTE ACCENT - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp855.py b/python/Lib/encodings/cp855.py deleted file mode 100644 index 7f2fa49..0000000 --- a/python/Lib/encodings/cp855.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP855.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp855', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x0452, # CYRILLIC SMALL LETTER DJE - 0x0081: 0x0402, # CYRILLIC CAPITAL LETTER DJE - 0x0082: 0x0453, # CYRILLIC SMALL LETTER GJE - 0x0083: 0x0403, # CYRILLIC CAPITAL LETTER GJE - 0x0084: 0x0451, # CYRILLIC SMALL LETTER IO - 0x0085: 0x0401, # CYRILLIC CAPITAL LETTER IO - 0x0086: 0x0454, # CYRILLIC SMALL LETTER UKRAINIAN IE - 0x0087: 0x0404, # CYRILLIC CAPITAL LETTER UKRAINIAN IE - 0x0088: 0x0455, # CYRILLIC SMALL LETTER DZE - 0x0089: 0x0405, # CYRILLIC CAPITAL LETTER DZE - 0x008a: 0x0456, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - 0x008b: 0x0406, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - 0x008c: 0x0457, # CYRILLIC SMALL LETTER YI - 0x008d: 0x0407, # CYRILLIC CAPITAL LETTER YI - 0x008e: 0x0458, # CYRILLIC SMALL LETTER JE - 0x008f: 0x0408, # CYRILLIC CAPITAL LETTER JE - 0x0090: 0x0459, # CYRILLIC SMALL LETTER LJE - 0x0091: 0x0409, # CYRILLIC CAPITAL LETTER LJE - 0x0092: 0x045a, # CYRILLIC SMALL LETTER NJE - 0x0093: 0x040a, # CYRILLIC CAPITAL LETTER NJE - 0x0094: 0x045b, # CYRILLIC SMALL LETTER TSHE - 0x0095: 0x040b, # CYRILLIC CAPITAL LETTER TSHE - 0x0096: 0x045c, # CYRILLIC SMALL LETTER KJE - 0x0097: 0x040c, # CYRILLIC CAPITAL LETTER KJE - 0x0098: 0x045e, # CYRILLIC SMALL LETTER SHORT U - 0x0099: 0x040e, # CYRILLIC CAPITAL LETTER SHORT U - 0x009a: 0x045f, # CYRILLIC SMALL LETTER DZHE - 0x009b: 0x040f, # CYRILLIC CAPITAL LETTER DZHE - 0x009c: 0x044e, # CYRILLIC SMALL LETTER YU - 0x009d: 0x042e, # CYRILLIC CAPITAL LETTER YU - 0x009e: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN - 0x009f: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN - 0x00a0: 0x0430, # CYRILLIC SMALL LETTER A - 0x00a1: 0x0410, # CYRILLIC CAPITAL LETTER A - 0x00a2: 0x0431, # CYRILLIC SMALL LETTER BE - 0x00a3: 0x0411, # CYRILLIC CAPITAL LETTER BE - 0x00a4: 0x0446, # CYRILLIC SMALL LETTER TSE - 0x00a5: 0x0426, # CYRILLIC CAPITAL LETTER TSE - 0x00a6: 0x0434, # CYRILLIC SMALL LETTER DE - 0x00a7: 0x0414, # CYRILLIC CAPITAL LETTER DE - 0x00a8: 0x0435, # CYRILLIC SMALL LETTER IE - 0x00a9: 0x0415, # CYRILLIC CAPITAL LETTER IE - 0x00aa: 0x0444, # CYRILLIC SMALL LETTER EF - 0x00ab: 0x0424, # CYRILLIC CAPITAL LETTER EF - 0x00ac: 0x0433, # CYRILLIC SMALL LETTER GHE - 0x00ad: 0x0413, # CYRILLIC CAPITAL LETTER GHE - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x0445, # CYRILLIC SMALL LETTER HA - 0x00b6: 0x0425, # CYRILLIC CAPITAL LETTER HA - 0x00b7: 0x0438, # CYRILLIC SMALL LETTER I - 0x00b8: 0x0418, # CYRILLIC CAPITAL LETTER I - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x0439, # CYRILLIC SMALL LETTER SHORT I - 0x00be: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x043a, # CYRILLIC SMALL LETTER KA - 0x00c7: 0x041a, # CYRILLIC CAPITAL LETTER KA - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x00a4, # CURRENCY SIGN - 0x00d0: 0x043b, # CYRILLIC SMALL LETTER EL - 0x00d1: 0x041b, # CYRILLIC CAPITAL LETTER EL - 0x00d2: 0x043c, # CYRILLIC SMALL LETTER EM - 0x00d3: 0x041c, # CYRILLIC CAPITAL LETTER EM - 0x00d4: 0x043d, # CYRILLIC SMALL LETTER EN - 0x00d5: 0x041d, # CYRILLIC CAPITAL LETTER EN - 0x00d6: 0x043e, # CYRILLIC SMALL LETTER O - 0x00d7: 0x041e, # CYRILLIC CAPITAL LETTER O - 0x00d8: 0x043f, # CYRILLIC SMALL LETTER PE - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x041f, # CYRILLIC CAPITAL LETTER PE - 0x00de: 0x044f, # CYRILLIC SMALL LETTER YA - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x042f, # CYRILLIC CAPITAL LETTER YA - 0x00e1: 0x0440, # CYRILLIC SMALL LETTER ER - 0x00e2: 0x0420, # CYRILLIC CAPITAL LETTER ER - 0x00e3: 0x0441, # CYRILLIC SMALL LETTER ES - 0x00e4: 0x0421, # CYRILLIC CAPITAL LETTER ES - 0x00e5: 0x0442, # CYRILLIC SMALL LETTER TE - 0x00e6: 0x0422, # CYRILLIC CAPITAL LETTER TE - 0x00e7: 0x0443, # CYRILLIC SMALL LETTER U - 0x00e8: 0x0423, # CYRILLIC CAPITAL LETTER U - 0x00e9: 0x0436, # CYRILLIC SMALL LETTER ZHE - 0x00ea: 0x0416, # CYRILLIC CAPITAL LETTER ZHE - 0x00eb: 0x0432, # CYRILLIC SMALL LETTER VE - 0x00ec: 0x0412, # CYRILLIC CAPITAL LETTER VE - 0x00ed: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN - 0x00ee: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN - 0x00ef: 0x2116, # NUMERO SIGN - 0x00f0: 0x00ad, # SOFT HYPHEN - 0x00f1: 0x044b, # CYRILLIC SMALL LETTER YERU - 0x00f2: 0x042b, # CYRILLIC CAPITAL LETTER YERU - 0x00f3: 0x0437, # CYRILLIC SMALL LETTER ZE - 0x00f4: 0x0417, # CYRILLIC CAPITAL LETTER ZE - 0x00f5: 0x0448, # CYRILLIC SMALL LETTER SHA - 0x00f6: 0x0428, # CYRILLIC CAPITAL LETTER SHA - 0x00f7: 0x044d, # CYRILLIC SMALL LETTER E - 0x00f8: 0x042d, # CYRILLIC CAPITAL LETTER E - 0x00f9: 0x0449, # CYRILLIC SMALL LETTER SHCHA - 0x00fa: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA - 0x00fb: 0x0447, # CYRILLIC SMALL LETTER CHE - 0x00fc: 0x0427, # CYRILLIC CAPITAL LETTER CHE - 0x00fd: 0x00a7, # SECTION SIGN - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\u0452' # 0x0080 -> CYRILLIC SMALL LETTER DJE - '\u0402' # 0x0081 -> CYRILLIC CAPITAL LETTER DJE - '\u0453' # 0x0082 -> CYRILLIC SMALL LETTER GJE - '\u0403' # 0x0083 -> CYRILLIC CAPITAL LETTER GJE - '\u0451' # 0x0084 -> CYRILLIC SMALL LETTER IO - '\u0401' # 0x0085 -> CYRILLIC CAPITAL LETTER IO - '\u0454' # 0x0086 -> CYRILLIC SMALL LETTER UKRAINIAN IE - '\u0404' # 0x0087 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE - '\u0455' # 0x0088 -> CYRILLIC SMALL LETTER DZE - '\u0405' # 0x0089 -> CYRILLIC CAPITAL LETTER DZE - '\u0456' # 0x008a -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0406' # 0x008b -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0457' # 0x008c -> CYRILLIC SMALL LETTER YI - '\u0407' # 0x008d -> CYRILLIC CAPITAL LETTER YI - '\u0458' # 0x008e -> CYRILLIC SMALL LETTER JE - '\u0408' # 0x008f -> CYRILLIC CAPITAL LETTER JE - '\u0459' # 0x0090 -> CYRILLIC SMALL LETTER LJE - '\u0409' # 0x0091 -> CYRILLIC CAPITAL LETTER LJE - '\u045a' # 0x0092 -> CYRILLIC SMALL LETTER NJE - '\u040a' # 0x0093 -> CYRILLIC CAPITAL LETTER NJE - '\u045b' # 0x0094 -> CYRILLIC SMALL LETTER TSHE - '\u040b' # 0x0095 -> CYRILLIC CAPITAL LETTER TSHE - '\u045c' # 0x0096 -> CYRILLIC SMALL LETTER KJE - '\u040c' # 0x0097 -> CYRILLIC CAPITAL LETTER KJE - '\u045e' # 0x0098 -> CYRILLIC SMALL LETTER SHORT U - '\u040e' # 0x0099 -> CYRILLIC CAPITAL LETTER SHORT U - '\u045f' # 0x009a -> CYRILLIC SMALL LETTER DZHE - '\u040f' # 0x009b -> CYRILLIC CAPITAL LETTER DZHE - '\u044e' # 0x009c -> CYRILLIC SMALL LETTER YU - '\u042e' # 0x009d -> CYRILLIC CAPITAL LETTER YU - '\u044a' # 0x009e -> CYRILLIC SMALL LETTER HARD SIGN - '\u042a' # 0x009f -> CYRILLIC CAPITAL LETTER HARD SIGN - '\u0430' # 0x00a0 -> CYRILLIC SMALL LETTER A - '\u0410' # 0x00a1 -> CYRILLIC CAPITAL LETTER A - '\u0431' # 0x00a2 -> CYRILLIC SMALL LETTER BE - '\u0411' # 0x00a3 -> CYRILLIC CAPITAL LETTER BE - '\u0446' # 0x00a4 -> CYRILLIC SMALL LETTER TSE - '\u0426' # 0x00a5 -> CYRILLIC CAPITAL LETTER TSE - '\u0434' # 0x00a6 -> CYRILLIC SMALL LETTER DE - '\u0414' # 0x00a7 -> CYRILLIC CAPITAL LETTER DE - '\u0435' # 0x00a8 -> CYRILLIC SMALL LETTER IE - '\u0415' # 0x00a9 -> CYRILLIC CAPITAL LETTER IE - '\u0444' # 0x00aa -> CYRILLIC SMALL LETTER EF - '\u0424' # 0x00ab -> CYRILLIC CAPITAL LETTER EF - '\u0433' # 0x00ac -> CYRILLIC SMALL LETTER GHE - '\u0413' # 0x00ad -> CYRILLIC CAPITAL LETTER GHE - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u0445' # 0x00b5 -> CYRILLIC SMALL LETTER HA - '\u0425' # 0x00b6 -> CYRILLIC CAPITAL LETTER HA - '\u0438' # 0x00b7 -> CYRILLIC SMALL LETTER I - '\u0418' # 0x00b8 -> CYRILLIC CAPITAL LETTER I - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u0439' # 0x00bd -> CYRILLIC SMALL LETTER SHORT I - '\u0419' # 0x00be -> CYRILLIC CAPITAL LETTER SHORT I - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u043a' # 0x00c6 -> CYRILLIC SMALL LETTER KA - '\u041a' # 0x00c7 -> CYRILLIC CAPITAL LETTER KA - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\xa4' # 0x00cf -> CURRENCY SIGN - '\u043b' # 0x00d0 -> CYRILLIC SMALL LETTER EL - '\u041b' # 0x00d1 -> CYRILLIC CAPITAL LETTER EL - '\u043c' # 0x00d2 -> CYRILLIC SMALL LETTER EM - '\u041c' # 0x00d3 -> CYRILLIC CAPITAL LETTER EM - '\u043d' # 0x00d4 -> CYRILLIC SMALL LETTER EN - '\u041d' # 0x00d5 -> CYRILLIC CAPITAL LETTER EN - '\u043e' # 0x00d6 -> CYRILLIC SMALL LETTER O - '\u041e' # 0x00d7 -> CYRILLIC CAPITAL LETTER O - '\u043f' # 0x00d8 -> CYRILLIC SMALL LETTER PE - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u041f' # 0x00dd -> CYRILLIC CAPITAL LETTER PE - '\u044f' # 0x00de -> CYRILLIC SMALL LETTER YA - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\u042f' # 0x00e0 -> CYRILLIC CAPITAL LETTER YA - '\u0440' # 0x00e1 -> CYRILLIC SMALL LETTER ER - '\u0420' # 0x00e2 -> CYRILLIC CAPITAL LETTER ER - '\u0441' # 0x00e3 -> CYRILLIC SMALL LETTER ES - '\u0421' # 0x00e4 -> CYRILLIC CAPITAL LETTER ES - '\u0442' # 0x00e5 -> CYRILLIC SMALL LETTER TE - '\u0422' # 0x00e6 -> CYRILLIC CAPITAL LETTER TE - '\u0443' # 0x00e7 -> CYRILLIC SMALL LETTER U - '\u0423' # 0x00e8 -> CYRILLIC CAPITAL LETTER U - '\u0436' # 0x00e9 -> CYRILLIC SMALL LETTER ZHE - '\u0416' # 0x00ea -> CYRILLIC CAPITAL LETTER ZHE - '\u0432' # 0x00eb -> CYRILLIC SMALL LETTER VE - '\u0412' # 0x00ec -> CYRILLIC CAPITAL LETTER VE - '\u044c' # 0x00ed -> CYRILLIC SMALL LETTER SOFT SIGN - '\u042c' # 0x00ee -> CYRILLIC CAPITAL LETTER SOFT SIGN - '\u2116' # 0x00ef -> NUMERO SIGN - '\xad' # 0x00f0 -> SOFT HYPHEN - '\u044b' # 0x00f1 -> CYRILLIC SMALL LETTER YERU - '\u042b' # 0x00f2 -> CYRILLIC CAPITAL LETTER YERU - '\u0437' # 0x00f3 -> CYRILLIC SMALL LETTER ZE - '\u0417' # 0x00f4 -> CYRILLIC CAPITAL LETTER ZE - '\u0448' # 0x00f5 -> CYRILLIC SMALL LETTER SHA - '\u0428' # 0x00f6 -> CYRILLIC CAPITAL LETTER SHA - '\u044d' # 0x00f7 -> CYRILLIC SMALL LETTER E - '\u042d' # 0x00f8 -> CYRILLIC CAPITAL LETTER E - '\u0449' # 0x00f9 -> CYRILLIC SMALL LETTER SHCHA - '\u0429' # 0x00fa -> CYRILLIC CAPITAL LETTER SHCHA - '\u0447' # 0x00fb -> CYRILLIC SMALL LETTER CHE - '\u0427' # 0x00fc -> CYRILLIC CAPITAL LETTER CHE - '\xa7' # 0x00fd -> SECTION SIGN - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a4: 0x00cf, # CURRENCY SIGN - 0x00a7: 0x00fd, # SECTION SIGN - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ad: 0x00f0, # SOFT HYPHEN - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x0401: 0x0085, # CYRILLIC CAPITAL LETTER IO - 0x0402: 0x0081, # CYRILLIC CAPITAL LETTER DJE - 0x0403: 0x0083, # CYRILLIC CAPITAL LETTER GJE - 0x0404: 0x0087, # CYRILLIC CAPITAL LETTER UKRAINIAN IE - 0x0405: 0x0089, # CYRILLIC CAPITAL LETTER DZE - 0x0406: 0x008b, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - 0x0407: 0x008d, # CYRILLIC CAPITAL LETTER YI - 0x0408: 0x008f, # CYRILLIC CAPITAL LETTER JE - 0x0409: 0x0091, # CYRILLIC CAPITAL LETTER LJE - 0x040a: 0x0093, # CYRILLIC CAPITAL LETTER NJE - 0x040b: 0x0095, # CYRILLIC CAPITAL LETTER TSHE - 0x040c: 0x0097, # CYRILLIC CAPITAL LETTER KJE - 0x040e: 0x0099, # CYRILLIC CAPITAL LETTER SHORT U - 0x040f: 0x009b, # CYRILLIC CAPITAL LETTER DZHE - 0x0410: 0x00a1, # CYRILLIC CAPITAL LETTER A - 0x0411: 0x00a3, # CYRILLIC CAPITAL LETTER BE - 0x0412: 0x00ec, # CYRILLIC CAPITAL LETTER VE - 0x0413: 0x00ad, # CYRILLIC CAPITAL LETTER GHE - 0x0414: 0x00a7, # CYRILLIC CAPITAL LETTER DE - 0x0415: 0x00a9, # CYRILLIC CAPITAL LETTER IE - 0x0416: 0x00ea, # CYRILLIC CAPITAL LETTER ZHE - 0x0417: 0x00f4, # CYRILLIC CAPITAL LETTER ZE - 0x0418: 0x00b8, # CYRILLIC CAPITAL LETTER I - 0x0419: 0x00be, # CYRILLIC CAPITAL LETTER SHORT I - 0x041a: 0x00c7, # CYRILLIC CAPITAL LETTER KA - 0x041b: 0x00d1, # CYRILLIC CAPITAL LETTER EL - 0x041c: 0x00d3, # CYRILLIC CAPITAL LETTER EM - 0x041d: 0x00d5, # CYRILLIC CAPITAL LETTER EN - 0x041e: 0x00d7, # CYRILLIC CAPITAL LETTER O - 0x041f: 0x00dd, # CYRILLIC CAPITAL LETTER PE - 0x0420: 0x00e2, # CYRILLIC CAPITAL LETTER ER - 0x0421: 0x00e4, # CYRILLIC CAPITAL LETTER ES - 0x0422: 0x00e6, # CYRILLIC CAPITAL LETTER TE - 0x0423: 0x00e8, # CYRILLIC CAPITAL LETTER U - 0x0424: 0x00ab, # CYRILLIC CAPITAL LETTER EF - 0x0425: 0x00b6, # CYRILLIC CAPITAL LETTER HA - 0x0426: 0x00a5, # CYRILLIC CAPITAL LETTER TSE - 0x0427: 0x00fc, # CYRILLIC CAPITAL LETTER CHE - 0x0428: 0x00f6, # CYRILLIC CAPITAL LETTER SHA - 0x0429: 0x00fa, # CYRILLIC CAPITAL LETTER SHCHA - 0x042a: 0x009f, # CYRILLIC CAPITAL LETTER HARD SIGN - 0x042b: 0x00f2, # CYRILLIC CAPITAL LETTER YERU - 0x042c: 0x00ee, # CYRILLIC CAPITAL LETTER SOFT SIGN - 0x042d: 0x00f8, # CYRILLIC CAPITAL LETTER E - 0x042e: 0x009d, # CYRILLIC CAPITAL LETTER YU - 0x042f: 0x00e0, # CYRILLIC CAPITAL LETTER YA - 0x0430: 0x00a0, # CYRILLIC SMALL LETTER A - 0x0431: 0x00a2, # CYRILLIC SMALL LETTER BE - 0x0432: 0x00eb, # CYRILLIC SMALL LETTER VE - 0x0433: 0x00ac, # CYRILLIC SMALL LETTER GHE - 0x0434: 0x00a6, # CYRILLIC SMALL LETTER DE - 0x0435: 0x00a8, # CYRILLIC SMALL LETTER IE - 0x0436: 0x00e9, # CYRILLIC SMALL LETTER ZHE - 0x0437: 0x00f3, # CYRILLIC SMALL LETTER ZE - 0x0438: 0x00b7, # CYRILLIC SMALL LETTER I - 0x0439: 0x00bd, # CYRILLIC SMALL LETTER SHORT I - 0x043a: 0x00c6, # CYRILLIC SMALL LETTER KA - 0x043b: 0x00d0, # CYRILLIC SMALL LETTER EL - 0x043c: 0x00d2, # CYRILLIC SMALL LETTER EM - 0x043d: 0x00d4, # CYRILLIC SMALL LETTER EN - 0x043e: 0x00d6, # CYRILLIC SMALL LETTER O - 0x043f: 0x00d8, # CYRILLIC SMALL LETTER PE - 0x0440: 0x00e1, # CYRILLIC SMALL LETTER ER - 0x0441: 0x00e3, # CYRILLIC SMALL LETTER ES - 0x0442: 0x00e5, # CYRILLIC SMALL LETTER TE - 0x0443: 0x00e7, # CYRILLIC SMALL LETTER U - 0x0444: 0x00aa, # CYRILLIC SMALL LETTER EF - 0x0445: 0x00b5, # CYRILLIC SMALL LETTER HA - 0x0446: 0x00a4, # CYRILLIC SMALL LETTER TSE - 0x0447: 0x00fb, # CYRILLIC SMALL LETTER CHE - 0x0448: 0x00f5, # CYRILLIC SMALL LETTER SHA - 0x0449: 0x00f9, # CYRILLIC SMALL LETTER SHCHA - 0x044a: 0x009e, # CYRILLIC SMALL LETTER HARD SIGN - 0x044b: 0x00f1, # CYRILLIC SMALL LETTER YERU - 0x044c: 0x00ed, # CYRILLIC SMALL LETTER SOFT SIGN - 0x044d: 0x00f7, # CYRILLIC SMALL LETTER E - 0x044e: 0x009c, # CYRILLIC SMALL LETTER YU - 0x044f: 0x00de, # CYRILLIC SMALL LETTER YA - 0x0451: 0x0084, # CYRILLIC SMALL LETTER IO - 0x0452: 0x0080, # CYRILLIC SMALL LETTER DJE - 0x0453: 0x0082, # CYRILLIC SMALL LETTER GJE - 0x0454: 0x0086, # CYRILLIC SMALL LETTER UKRAINIAN IE - 0x0455: 0x0088, # CYRILLIC SMALL LETTER DZE - 0x0456: 0x008a, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - 0x0457: 0x008c, # CYRILLIC SMALL LETTER YI - 0x0458: 0x008e, # CYRILLIC SMALL LETTER JE - 0x0459: 0x0090, # CYRILLIC SMALL LETTER LJE - 0x045a: 0x0092, # CYRILLIC SMALL LETTER NJE - 0x045b: 0x0094, # CYRILLIC SMALL LETTER TSHE - 0x045c: 0x0096, # CYRILLIC SMALL LETTER KJE - 0x045e: 0x0098, # CYRILLIC SMALL LETTER SHORT U - 0x045f: 0x009a, # CYRILLIC SMALL LETTER DZHE - 0x2116: 0x00ef, # NUMERO SIGN - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp856.py b/python/Lib/encodings/cp856.py deleted file mode 100644 index 1fc2d25..0000000 --- a/python/Lib/encodings/cp856.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp856 generated from 'MAPPINGS/VENDORS/MISC/CP856.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp856', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u05d0' # 0x80 -> HEBREW LETTER ALEF - '\u05d1' # 0x81 -> HEBREW LETTER BET - '\u05d2' # 0x82 -> HEBREW LETTER GIMEL - '\u05d3' # 0x83 -> HEBREW LETTER DALET - '\u05d4' # 0x84 -> HEBREW LETTER HE - '\u05d5' # 0x85 -> HEBREW LETTER VAV - '\u05d6' # 0x86 -> HEBREW LETTER ZAYIN - '\u05d7' # 0x87 -> HEBREW LETTER HET - '\u05d8' # 0x88 -> HEBREW LETTER TET - '\u05d9' # 0x89 -> HEBREW LETTER YOD - '\u05da' # 0x8A -> HEBREW LETTER FINAL KAF - '\u05db' # 0x8B -> HEBREW LETTER KAF - '\u05dc' # 0x8C -> HEBREW LETTER LAMED - '\u05dd' # 0x8D -> HEBREW LETTER FINAL MEM - '\u05de' # 0x8E -> HEBREW LETTER MEM - '\u05df' # 0x8F -> HEBREW LETTER FINAL NUN - '\u05e0' # 0x90 -> HEBREW LETTER NUN - '\u05e1' # 0x91 -> HEBREW LETTER SAMEKH - '\u05e2' # 0x92 -> HEBREW LETTER AYIN - '\u05e3' # 0x93 -> HEBREW LETTER FINAL PE - '\u05e4' # 0x94 -> HEBREW LETTER PE - '\u05e5' # 0x95 -> HEBREW LETTER FINAL TSADI - '\u05e6' # 0x96 -> HEBREW LETTER TSADI - '\u05e7' # 0x97 -> HEBREW LETTER QOF - '\u05e8' # 0x98 -> HEBREW LETTER RESH - '\u05e9' # 0x99 -> HEBREW LETTER SHIN - '\u05ea' # 0x9A -> HEBREW LETTER TAV - '\ufffe' # 0x9B -> UNDEFINED - '\xa3' # 0x9C -> POUND SIGN - '\ufffe' # 0x9D -> UNDEFINED - '\xd7' # 0x9E -> MULTIPLICATION SIGN - '\ufffe' # 0x9F -> UNDEFINED - '\ufffe' # 0xA0 -> UNDEFINED - '\ufffe' # 0xA1 -> UNDEFINED - '\ufffe' # 0xA2 -> UNDEFINED - '\ufffe' # 0xA3 -> UNDEFINED - '\ufffe' # 0xA4 -> UNDEFINED - '\ufffe' # 0xA5 -> UNDEFINED - '\ufffe' # 0xA6 -> UNDEFINED - '\ufffe' # 0xA7 -> UNDEFINED - '\ufffe' # 0xA8 -> UNDEFINED - '\xae' # 0xA9 -> REGISTERED SIGN - '\xac' # 0xAA -> NOT SIGN - '\xbd' # 0xAB -> VULGAR FRACTION ONE HALF - '\xbc' # 0xAC -> VULGAR FRACTION ONE QUARTER - '\ufffe' # 0xAD -> UNDEFINED - '\xab' # 0xAE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0xAF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0xB0 -> LIGHT SHADE - '\u2592' # 0xB1 -> MEDIUM SHADE - '\u2593' # 0xB2 -> DARK SHADE - '\u2502' # 0xB3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0xB4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\ufffe' # 0xB5 -> UNDEFINED - '\ufffe' # 0xB6 -> UNDEFINED - '\ufffe' # 0xB7 -> UNDEFINED - '\xa9' # 0xB8 -> COPYRIGHT SIGN - '\u2563' # 0xB9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0xBA -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0xBB -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0xBC -> BOX DRAWINGS DOUBLE UP AND LEFT - '\xa2' # 0xBD -> CENT SIGN - '\xa5' # 0xBE -> YEN SIGN - '\u2510' # 0xBF -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0xC0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0xC1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0xC2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0xC3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0xC4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0xC5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\ufffe' # 0xC6 -> UNDEFINED - '\ufffe' # 0xC7 -> UNDEFINED - '\u255a' # 0xC8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0xC9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0xCA -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0xCB -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0xCC -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0xCD -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0xCE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\xa4' # 0xCF -> CURRENCY SIGN - '\ufffe' # 0xD0 -> UNDEFINED - '\ufffe' # 0xD1 -> UNDEFINED - '\ufffe' # 0xD2 -> UNDEFINED - '\ufffe' # 0xD3 -> UNDEFINEDS - '\ufffe' # 0xD4 -> UNDEFINED - '\ufffe' # 0xD5 -> UNDEFINED - '\ufffe' # 0xD6 -> UNDEFINEDE - '\ufffe' # 0xD7 -> UNDEFINED - '\ufffe' # 0xD8 -> UNDEFINED - '\u2518' # 0xD9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0xDA -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0xDB -> FULL BLOCK - '\u2584' # 0xDC -> LOWER HALF BLOCK - '\xa6' # 0xDD -> BROKEN BAR - '\ufffe' # 0xDE -> UNDEFINED - '\u2580' # 0xDF -> UPPER HALF BLOCK - '\ufffe' # 0xE0 -> UNDEFINED - '\ufffe' # 0xE1 -> UNDEFINED - '\ufffe' # 0xE2 -> UNDEFINED - '\ufffe' # 0xE3 -> UNDEFINED - '\ufffe' # 0xE4 -> UNDEFINED - '\ufffe' # 0xE5 -> UNDEFINED - '\xb5' # 0xE6 -> MICRO SIGN - '\ufffe' # 0xE7 -> UNDEFINED - '\ufffe' # 0xE8 -> UNDEFINED - '\ufffe' # 0xE9 -> UNDEFINED - '\ufffe' # 0xEA -> UNDEFINED - '\ufffe' # 0xEB -> UNDEFINED - '\ufffe' # 0xEC -> UNDEFINED - '\ufffe' # 0xED -> UNDEFINED - '\xaf' # 0xEE -> MACRON - '\xb4' # 0xEF -> ACUTE ACCENT - '\xad' # 0xF0 -> SOFT HYPHEN - '\xb1' # 0xF1 -> PLUS-MINUS SIGN - '\u2017' # 0xF2 -> DOUBLE LOW LINE - '\xbe' # 0xF3 -> VULGAR FRACTION THREE QUARTERS - '\xb6' # 0xF4 -> PILCROW SIGN - '\xa7' # 0xF5 -> SECTION SIGN - '\xf7' # 0xF6 -> DIVISION SIGN - '\xb8' # 0xF7 -> CEDILLA - '\xb0' # 0xF8 -> DEGREE SIGN - '\xa8' # 0xF9 -> DIAERESIS - '\xb7' # 0xFA -> MIDDLE DOT - '\xb9' # 0xFB -> SUPERSCRIPT ONE - '\xb3' # 0xFC -> SUPERSCRIPT THREE - '\xb2' # 0xFD -> SUPERSCRIPT TWO - '\u25a0' # 0xFE -> BLACK SQUARE - '\xa0' # 0xFF -> NO-BREAK SPACE -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp857.py b/python/Lib/encodings/cp857.py deleted file mode 100644 index 240a304..0000000 --- a/python/Lib/encodings/cp857.py +++ /dev/null @@ -1,694 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP857.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp857', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE - 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS - 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE - 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE - 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA - 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS - 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE - 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS - 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x008d: 0x0131, # LATIN SMALL LETTER DOTLESS I - 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE - 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE - 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE - 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS - 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE - 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE - 0x0098: 0x0130, # LATIN CAPITAL LETTER I WITH DOT ABOVE - 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE - 0x009c: 0x00a3, # POUND SIGN - 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE - 0x009e: 0x015e, # LATIN CAPITAL LETTER S WITH CEDILLA - 0x009f: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA - 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE - 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE - 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE - 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE - 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE - 0x00a6: 0x011e, # LATIN CAPITAL LETTER G WITH BREVE - 0x00a7: 0x011f, # LATIN SMALL LETTER G WITH BREVE - 0x00a8: 0x00bf, # INVERTED QUESTION MARK - 0x00a9: 0x00ae, # REGISTERED SIGN - 0x00aa: 0x00ac, # NOT SIGN - 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF - 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER - 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE - 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE - 0x00b8: 0x00a9, # COPYRIGHT SIGN - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x00a2, # CENT SIGN - 0x00be: 0x00a5, # YEN SIGN - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE - 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x00a4, # CURRENCY SIGN - 0x00d0: 0x00ba, # MASCULINE ORDINAL INDICATOR - 0x00d1: 0x00aa, # FEMININE ORDINAL INDICATOR - 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX - 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS - 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE - 0x00d5: None, # UNDEFINED - 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE - 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX - 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x00a6, # BROKEN BAR - 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S - 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE - 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE - 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE - 0x00e6: 0x00b5, # MICRO SIGN - 0x00e7: None, # UNDEFINED - 0x00e8: 0x00d7, # MULTIPLICATION SIGN - 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE - 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX - 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE - 0x00ed: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS - 0x00ee: 0x00af, # MACRON - 0x00ef: 0x00b4, # ACUTE ACCENT - 0x00f0: 0x00ad, # SOFT HYPHEN - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: None, # UNDEFINED - 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS - 0x00f4: 0x00b6, # PILCROW SIGN - 0x00f5: 0x00a7, # SECTION SIGN - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x00b8, # CEDILLA - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x00a8, # DIAERESIS - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x00b9, # SUPERSCRIPT ONE - 0x00fc: 0x00b3, # SUPERSCRIPT THREE - 0x00fd: 0x00b2, # SUPERSCRIPT TWO - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS - '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE - '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE - '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA - '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE - '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS - '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\u0131' # 0x008d -> LATIN SMALL LETTER DOTLESS I - '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE - '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE - '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE - '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE - '\u0130' # 0x0098 -> LATIN CAPITAL LETTER I WITH DOT ABOVE - '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE - '\xa3' # 0x009c -> POUND SIGN - '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE - '\u015e' # 0x009e -> LATIN CAPITAL LETTER S WITH CEDILLA - '\u015f' # 0x009f -> LATIN SMALL LETTER S WITH CEDILLA - '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE - '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE - '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE - '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE - '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE - '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE - '\u011e' # 0x00a6 -> LATIN CAPITAL LETTER G WITH BREVE - '\u011f' # 0x00a7 -> LATIN SMALL LETTER G WITH BREVE - '\xbf' # 0x00a8 -> INVERTED QUESTION MARK - '\xae' # 0x00a9 -> REGISTERED SIGN - '\xac' # 0x00aa -> NOT SIGN - '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF - '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER - '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xa9' # 0x00b8 -> COPYRIGHT SIGN - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\xa2' # 0x00bd -> CENT SIGN - '\xa5' # 0x00be -> YEN SIGN - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE - '\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\xa4' # 0x00cf -> CURRENCY SIGN - '\xba' # 0x00d0 -> MASCULINE ORDINAL INDICATOR - '\xaa' # 0x00d1 -> FEMININE ORDINAL INDICATOR - '\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE - '\ufffe' # 0x00d5 -> UNDEFINED - '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\xa6' # 0x00dd -> BROKEN BAR - '\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S - '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE - '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xb5' # 0x00e6 -> MICRO SIGN - '\ufffe' # 0x00e7 -> UNDEFINED - '\xd7' # 0x00e8 -> MULTIPLICATION SIGN - '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE - '\xec' # 0x00ec -> LATIN SMALL LETTER I WITH GRAVE - '\xff' # 0x00ed -> LATIN SMALL LETTER Y WITH DIAERESIS - '\xaf' # 0x00ee -> MACRON - '\xb4' # 0x00ef -> ACUTE ACCENT - '\xad' # 0x00f0 -> SOFT HYPHEN - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\ufffe' # 0x00f2 -> UNDEFINED - '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS - '\xb6' # 0x00f4 -> PILCROW SIGN - '\xa7' # 0x00f5 -> SECTION SIGN - '\xf7' # 0x00f6 -> DIVISION SIGN - '\xb8' # 0x00f7 -> CEDILLA - '\xb0' # 0x00f8 -> DEGREE SIGN - '\xa8' # 0x00f9 -> DIAERESIS - '\xb7' # 0x00fa -> MIDDLE DOT - '\xb9' # 0x00fb -> SUPERSCRIPT ONE - '\xb3' # 0x00fc -> SUPERSCRIPT THREE - '\xb2' # 0x00fd -> SUPERSCRIPT TWO - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK - 0x00a2: 0x00bd, # CENT SIGN - 0x00a3: 0x009c, # POUND SIGN - 0x00a4: 0x00cf, # CURRENCY SIGN - 0x00a5: 0x00be, # YEN SIGN - 0x00a6: 0x00dd, # BROKEN BAR - 0x00a7: 0x00f5, # SECTION SIGN - 0x00a8: 0x00f9, # DIAERESIS - 0x00a9: 0x00b8, # COPYRIGHT SIGN - 0x00aa: 0x00d1, # FEMININE ORDINAL INDICATOR - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x00aa, # NOT SIGN - 0x00ad: 0x00f0, # SOFT HYPHEN - 0x00ae: 0x00a9, # REGISTERED SIGN - 0x00af: 0x00ee, # MACRON - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x00fd, # SUPERSCRIPT TWO - 0x00b3: 0x00fc, # SUPERSCRIPT THREE - 0x00b4: 0x00ef, # ACUTE ACCENT - 0x00b5: 0x00e6, # MICRO SIGN - 0x00b6: 0x00f4, # PILCROW SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x00b8: 0x00f7, # CEDILLA - 0x00b9: 0x00fb, # SUPERSCRIPT ONE - 0x00ba: 0x00d0, # MASCULINE ORDINAL INDICATOR - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER - 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF - 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS - 0x00bf: 0x00a8, # INVERTED QUESTION MARK - 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE - 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE - 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE - 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE - 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE - 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE - 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX - 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS - 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE - 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE - 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX - 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS - 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE - 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE - 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE - 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x00d7: 0x00e8, # MULTIPLICATION SIGN - 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE - 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE - 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE - 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX - 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S - 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE - 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE - 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE - 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS - 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE - 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE - 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA - 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE - 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE - 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS - 0x00ec: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE - 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE - 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS - 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE - 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE - 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE - 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE - 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS - 0x00f7: 0x00f6, # DIVISION SIGN - 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE - 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE - 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE - 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS - 0x00ff: 0x00ed, # LATIN SMALL LETTER Y WITH DIAERESIS - 0x011e: 0x00a6, # LATIN CAPITAL LETTER G WITH BREVE - 0x011f: 0x00a7, # LATIN SMALL LETTER G WITH BREVE - 0x0130: 0x0098, # LATIN CAPITAL LETTER I WITH DOT ABOVE - 0x0131: 0x008d, # LATIN SMALL LETTER DOTLESS I - 0x015e: 0x009e, # LATIN CAPITAL LETTER S WITH CEDILLA - 0x015f: 0x009f, # LATIN SMALL LETTER S WITH CEDILLA - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp858.py b/python/Lib/encodings/cp858.py deleted file mode 100644 index 74d8698..0000000 --- a/python/Lib/encodings/cp858.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec for CP858, modified from cp850. - -""" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp858', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE - 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS - 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE - 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE - 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA - 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS - 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE - 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS - 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE - 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE - 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE - 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE - 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS - 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE - 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE - 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS - 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE - 0x009c: 0x00a3, # POUND SIGN - 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE - 0x009e: 0x00d7, # MULTIPLICATION SIGN - 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK - 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE - 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE - 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE - 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE - 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE - 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR - 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR - 0x00a8: 0x00bf, # INVERTED QUESTION MARK - 0x00a9: 0x00ae, # REGISTERED SIGN - 0x00aa: 0x00ac, # NOT SIGN - 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF - 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER - 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE - 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE - 0x00b8: 0x00a9, # COPYRIGHT SIGN - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x00a2, # CENT SIGN - 0x00be: 0x00a5, # YEN SIGN - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE - 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x00a4, # CURRENCY SIGN - 0x00d0: 0x00f0, # LATIN SMALL LETTER ETH - 0x00d1: 0x00d0, # LATIN CAPITAL LETTER ETH - 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX - 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS - 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE - 0x00d5: 0x20ac, # EURO SIGN - 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE - 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX - 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x00a6, # BROKEN BAR - 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S - 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE - 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE - 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE - 0x00e6: 0x00b5, # MICRO SIGN - 0x00e7: 0x00fe, # LATIN SMALL LETTER THORN - 0x00e8: 0x00de, # LATIN CAPITAL LETTER THORN - 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE - 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX - 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE - 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE - 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE - 0x00ee: 0x00af, # MACRON - 0x00ef: 0x00b4, # ACUTE ACCENT - 0x00f0: 0x00ad, # SOFT HYPHEN - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: 0x2017, # DOUBLE LOW LINE - 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS - 0x00f4: 0x00b6, # PILCROW SIGN - 0x00f5: 0x00a7, # SECTION SIGN - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x00b8, # CEDILLA - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x00a8, # DIAERESIS - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x00b9, # SUPERSCRIPT ONE - 0x00fc: 0x00b3, # SUPERSCRIPT THREE - 0x00fd: 0x00b2, # SUPERSCRIPT TWO - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS - '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE - '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE - '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA - '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE - '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS - '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE - '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE - '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE - '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE - '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE - '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS - '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE - '\xa3' # 0x009c -> POUND SIGN - '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE - '\xd7' # 0x009e -> MULTIPLICATION SIGN - '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK - '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE - '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE - '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE - '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE - '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE - '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE - '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR - '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR - '\xbf' # 0x00a8 -> INVERTED QUESTION MARK - '\xae' # 0x00a9 -> REGISTERED SIGN - '\xac' # 0x00aa -> NOT SIGN - '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF - '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER - '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xa9' # 0x00b8 -> COPYRIGHT SIGN - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\xa2' # 0x00bd -> CENT SIGN - '\xa5' # 0x00be -> YEN SIGN - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE - '\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\xa4' # 0x00cf -> CURRENCY SIGN - '\xf0' # 0x00d0 -> LATIN SMALL LETTER ETH - '\xd0' # 0x00d1 -> LATIN CAPITAL LETTER ETH - '\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE - '\u20ac' # 0x00d5 -> EURO SIGN - '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\xa6' # 0x00dd -> BROKEN BAR - '\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S - '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE - '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xb5' # 0x00e6 -> MICRO SIGN - '\xfe' # 0x00e7 -> LATIN SMALL LETTER THORN - '\xde' # 0x00e8 -> LATIN CAPITAL LETTER THORN - '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE - '\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE - '\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xaf' # 0x00ee -> MACRON - '\xb4' # 0x00ef -> ACUTE ACCENT - '\xad' # 0x00f0 -> SOFT HYPHEN - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\u2017' # 0x00f2 -> DOUBLE LOW LINE - '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS - '\xb6' # 0x00f4 -> PILCROW SIGN - '\xa7' # 0x00f5 -> SECTION SIGN - '\xf7' # 0x00f6 -> DIVISION SIGN - '\xb8' # 0x00f7 -> CEDILLA - '\xb0' # 0x00f8 -> DEGREE SIGN - '\xa8' # 0x00f9 -> DIAERESIS - '\xb7' # 0x00fa -> MIDDLE DOT - '\xb9' # 0x00fb -> SUPERSCRIPT ONE - '\xb3' # 0x00fc -> SUPERSCRIPT THREE - '\xb2' # 0x00fd -> SUPERSCRIPT TWO - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK - 0x00a2: 0x00bd, # CENT SIGN - 0x00a3: 0x009c, # POUND SIGN - 0x00a4: 0x00cf, # CURRENCY SIGN - 0x00a5: 0x00be, # YEN SIGN - 0x00a6: 0x00dd, # BROKEN BAR - 0x00a7: 0x00f5, # SECTION SIGN - 0x00a8: 0x00f9, # DIAERESIS - 0x00a9: 0x00b8, # COPYRIGHT SIGN - 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x00aa, # NOT SIGN - 0x00ad: 0x00f0, # SOFT HYPHEN - 0x00ae: 0x00a9, # REGISTERED SIGN - 0x00af: 0x00ee, # MACRON - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x00fd, # SUPERSCRIPT TWO - 0x00b3: 0x00fc, # SUPERSCRIPT THREE - 0x00b4: 0x00ef, # ACUTE ACCENT - 0x00b5: 0x00e6, # MICRO SIGN - 0x00b6: 0x00f4, # PILCROW SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x00b8: 0x00f7, # CEDILLA - 0x00b9: 0x00fb, # SUPERSCRIPT ONE - 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER - 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF - 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS - 0x00bf: 0x00a8, # INVERTED QUESTION MARK - 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE - 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE - 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE - 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE - 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE - 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE - 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX - 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS - 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE - 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE - 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX - 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS - 0x00d0: 0x00d1, # LATIN CAPITAL LETTER ETH - 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE - 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE - 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE - 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x00d7: 0x009e, # MULTIPLICATION SIGN - 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE - 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE - 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE - 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX - 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE - 0x00de: 0x00e8, # LATIN CAPITAL LETTER THORN - 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S - 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE - 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE - 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE - 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS - 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE - 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE - 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA - 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE - 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE - 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS - 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE - 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE - 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS - 0x00f0: 0x00d0, # LATIN SMALL LETTER ETH - 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE - 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE - 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE - 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE - 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS - 0x00f7: 0x00f6, # DIVISION SIGN - 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE - 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE - 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE - 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS - 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE - 0x00fe: 0x00e7, # LATIN SMALL LETTER THORN - 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS - 0x20ac: 0x00d5, # EURO SIGN - 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK - 0x2017: 0x00f2, # DOUBLE LOW LINE - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp860.py b/python/Lib/encodings/cp860.py deleted file mode 100644 index bce0b8e..0000000 --- a/python/Lib/encodings/cp860.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP860.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp860', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE - 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x0084: 0x00e3, # LATIN SMALL LETTER A WITH TILDE - 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE - 0x0086: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE - 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA - 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x0089: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX - 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE - 0x008b: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE - 0x008c: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE - 0x008e: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE - 0x008f: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE - 0x0091: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE - 0x0092: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE - 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x0094: 0x00f5, # LATIN SMALL LETTER O WITH TILDE - 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE - 0x0096: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE - 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE - 0x0098: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE - 0x0099: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE - 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x009b: 0x00a2, # CENT SIGN - 0x009c: 0x00a3, # POUND SIGN - 0x009d: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE - 0x009e: 0x20a7, # PESETA SIGN - 0x009f: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE - 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE - 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE - 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE - 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE - 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR - 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR - 0x00a8: 0x00bf, # INVERTED QUESTION MARK - 0x00a9: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE - 0x00aa: 0x00ac, # NOT SIGN - 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF - 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER - 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x258c, # LEFT HALF BLOCK - 0x00de: 0x2590, # RIGHT HALF BLOCK - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA - 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S - 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA - 0x00e3: 0x03c0, # GREEK SMALL LETTER PI - 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA - 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA - 0x00e6: 0x00b5, # MICRO SIGN - 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU - 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI - 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA - 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA - 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA - 0x00ec: 0x221e, # INFINITY - 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI - 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON - 0x00ef: 0x2229, # INTERSECTION - 0x00f0: 0x2261, # IDENTICAL TO - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO - 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO - 0x00f4: 0x2320, # TOP HALF INTEGRAL - 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x2248, # ALMOST EQUAL TO - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x2219, # BULLET OPERATOR - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x221a, # SQUARE ROOT - 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N - 0x00fd: 0x00b2, # SUPERSCRIPT TWO - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS - '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE - '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe3' # 0x0084 -> LATIN SMALL LETTER A WITH TILDE - '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE - '\xc1' # 0x0086 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA - '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xca' # 0x0089 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE - '\xcd' # 0x008b -> LATIN CAPITAL LETTER I WITH ACUTE - '\xd4' # 0x008c -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE - '\xc3' # 0x008e -> LATIN CAPITAL LETTER A WITH TILDE - '\xc2' # 0x008f -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xc0' # 0x0091 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc8' # 0x0092 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf5' # 0x0094 -> LATIN SMALL LETTER O WITH TILDE - '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE - '\xda' # 0x0096 -> LATIN CAPITAL LETTER U WITH ACUTE - '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE - '\xcc' # 0x0098 -> LATIN CAPITAL LETTER I WITH GRAVE - '\xd5' # 0x0099 -> LATIN CAPITAL LETTER O WITH TILDE - '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xa2' # 0x009b -> CENT SIGN - '\xa3' # 0x009c -> POUND SIGN - '\xd9' # 0x009d -> LATIN CAPITAL LETTER U WITH GRAVE - '\u20a7' # 0x009e -> PESETA SIGN - '\xd3' # 0x009f -> LATIN CAPITAL LETTER O WITH ACUTE - '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE - '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE - '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE - '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE - '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE - '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE - '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR - '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR - '\xbf' # 0x00a8 -> INVERTED QUESTION MARK - '\xd2' # 0x00a9 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xac' # 0x00aa -> NOT SIGN - '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF - '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER - '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u258c' # 0x00dd -> LEFT HALF BLOCK - '\u2590' # 0x00de -> RIGHT HALF BLOCK - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA - '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S - '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA - '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI - '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA - '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA - '\xb5' # 0x00e6 -> MICRO SIGN - '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU - '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI - '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA - '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA - '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA - '\u221e' # 0x00ec -> INFINITY - '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI - '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON - '\u2229' # 0x00ef -> INTERSECTION - '\u2261' # 0x00f0 -> IDENTICAL TO - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO - '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO - '\u2320' # 0x00f4 -> TOP HALF INTEGRAL - '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL - '\xf7' # 0x00f6 -> DIVISION SIGN - '\u2248' # 0x00f7 -> ALMOST EQUAL TO - '\xb0' # 0x00f8 -> DEGREE SIGN - '\u2219' # 0x00f9 -> BULLET OPERATOR - '\xb7' # 0x00fa -> MIDDLE DOT - '\u221a' # 0x00fb -> SQUARE ROOT - '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N - '\xb2' # 0x00fd -> SUPERSCRIPT TWO - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK - 0x00a2: 0x009b, # CENT SIGN - 0x00a3: 0x009c, # POUND SIGN - 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x00aa, # NOT SIGN - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x00fd, # SUPERSCRIPT TWO - 0x00b5: 0x00e6, # MICRO SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER - 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF - 0x00bf: 0x00a8, # INVERTED QUESTION MARK - 0x00c0: 0x0091, # LATIN CAPITAL LETTER A WITH GRAVE - 0x00c1: 0x0086, # LATIN CAPITAL LETTER A WITH ACUTE - 0x00c2: 0x008f, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x00c3: 0x008e, # LATIN CAPITAL LETTER A WITH TILDE - 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x00c8: 0x0092, # LATIN CAPITAL LETTER E WITH GRAVE - 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE - 0x00ca: 0x0089, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX - 0x00cc: 0x0098, # LATIN CAPITAL LETTER I WITH GRAVE - 0x00cd: 0x008b, # LATIN CAPITAL LETTER I WITH ACUTE - 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE - 0x00d2: 0x00a9, # LATIN CAPITAL LETTER O WITH GRAVE - 0x00d3: 0x009f, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00d4: 0x008c, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x00d5: 0x0099, # LATIN CAPITAL LETTER O WITH TILDE - 0x00d9: 0x009d, # LATIN CAPITAL LETTER U WITH GRAVE - 0x00da: 0x0096, # LATIN CAPITAL LETTER U WITH ACUTE - 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S - 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE - 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE - 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x00e3: 0x0084, # LATIN SMALL LETTER A WITH TILDE - 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA - 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE - 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE - 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE - 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE - 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE - 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE - 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE - 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x00f5: 0x0094, # LATIN SMALL LETTER O WITH TILDE - 0x00f7: 0x00f6, # DIVISION SIGN - 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE - 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE - 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA - 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA - 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA - 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI - 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA - 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA - 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA - 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON - 0x03c0: 0x00e3, # GREEK SMALL LETTER PI - 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA - 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU - 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI - 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N - 0x20a7: 0x009e, # PESETA SIGN - 0x2219: 0x00f9, # BULLET OPERATOR - 0x221a: 0x00fb, # SQUARE ROOT - 0x221e: 0x00ec, # INFINITY - 0x2229: 0x00ef, # INTERSECTION - 0x2248: 0x00f7, # ALMOST EQUAL TO - 0x2261: 0x00f0, # IDENTICAL TO - 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO - 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO - 0x2320: 0x00f4, # TOP HALF INTEGRAL - 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x258c: 0x00dd, # LEFT HALF BLOCK - 0x2590: 0x00de, # RIGHT HALF BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp861.py b/python/Lib/encodings/cp861.py deleted file mode 100644 index c573fec..0000000 --- a/python/Lib/encodings/cp861.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP861.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp861', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE - 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS - 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE - 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE - 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA - 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS - 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE - 0x008b: 0x00d0, # LATIN CAPITAL LETTER ETH - 0x008c: 0x00f0, # LATIN SMALL LETTER ETH - 0x008d: 0x00de, # LATIN CAPITAL LETTER THORN - 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE - 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE - 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE - 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS - 0x0095: 0x00fe, # LATIN SMALL LETTER THORN - 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x0097: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE - 0x0098: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE - 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE - 0x009c: 0x00a3, # POUND SIGN - 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE - 0x009e: 0x20a7, # PESETA SIGN - 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK - 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE - 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE - 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE - 0x00a4: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE - 0x00a5: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE - 0x00a6: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00a7: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE - 0x00a8: 0x00bf, # INVERTED QUESTION MARK - 0x00a9: 0x2310, # REVERSED NOT SIGN - 0x00aa: 0x00ac, # NOT SIGN - 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF - 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER - 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x258c, # LEFT HALF BLOCK - 0x00de: 0x2590, # RIGHT HALF BLOCK - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA - 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S - 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA - 0x00e3: 0x03c0, # GREEK SMALL LETTER PI - 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA - 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA - 0x00e6: 0x00b5, # MICRO SIGN - 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU - 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI - 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA - 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA - 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA - 0x00ec: 0x221e, # INFINITY - 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI - 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON - 0x00ef: 0x2229, # INTERSECTION - 0x00f0: 0x2261, # IDENTICAL TO - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO - 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO - 0x00f4: 0x2320, # TOP HALF INTEGRAL - 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x2248, # ALMOST EQUAL TO - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x2219, # BULLET OPERATOR - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x221a, # SQUARE ROOT - 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N - 0x00fd: 0x00b2, # SUPERSCRIPT TWO - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS - '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE - '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE - '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA - '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE - '\xd0' # 0x008b -> LATIN CAPITAL LETTER ETH - '\xf0' # 0x008c -> LATIN SMALL LETTER ETH - '\xde' # 0x008d -> LATIN CAPITAL LETTER THORN - '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE - '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE - '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xfe' # 0x0095 -> LATIN SMALL LETTER THORN - '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xdd' # 0x0097 -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xfd' # 0x0098 -> LATIN SMALL LETTER Y WITH ACUTE - '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE - '\xa3' # 0x009c -> POUND SIGN - '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE - '\u20a7' # 0x009e -> PESETA SIGN - '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK - '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE - '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE - '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE - '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE - '\xc1' # 0x00a4 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xcd' # 0x00a5 -> LATIN CAPITAL LETTER I WITH ACUTE - '\xd3' # 0x00a6 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xda' # 0x00a7 -> LATIN CAPITAL LETTER U WITH ACUTE - '\xbf' # 0x00a8 -> INVERTED QUESTION MARK - '\u2310' # 0x00a9 -> REVERSED NOT SIGN - '\xac' # 0x00aa -> NOT SIGN - '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF - '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER - '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u258c' # 0x00dd -> LEFT HALF BLOCK - '\u2590' # 0x00de -> RIGHT HALF BLOCK - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA - '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S - '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA - '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI - '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA - '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA - '\xb5' # 0x00e6 -> MICRO SIGN - '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU - '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI - '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA - '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA - '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA - '\u221e' # 0x00ec -> INFINITY - '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI - '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON - '\u2229' # 0x00ef -> INTERSECTION - '\u2261' # 0x00f0 -> IDENTICAL TO - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO - '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO - '\u2320' # 0x00f4 -> TOP HALF INTEGRAL - '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL - '\xf7' # 0x00f6 -> DIVISION SIGN - '\u2248' # 0x00f7 -> ALMOST EQUAL TO - '\xb0' # 0x00f8 -> DEGREE SIGN - '\u2219' # 0x00f9 -> BULLET OPERATOR - '\xb7' # 0x00fa -> MIDDLE DOT - '\u221a' # 0x00fb -> SQUARE ROOT - '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N - '\xb2' # 0x00fd -> SUPERSCRIPT TWO - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK - 0x00a3: 0x009c, # POUND SIGN - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x00aa, # NOT SIGN - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x00fd, # SUPERSCRIPT TWO - 0x00b5: 0x00e6, # MICRO SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER - 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF - 0x00bf: 0x00a8, # INVERTED QUESTION MARK - 0x00c1: 0x00a4, # LATIN CAPITAL LETTER A WITH ACUTE - 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE - 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE - 0x00cd: 0x00a5, # LATIN CAPITAL LETTER I WITH ACUTE - 0x00d0: 0x008b, # LATIN CAPITAL LETTER ETH - 0x00d3: 0x00a6, # LATIN CAPITAL LETTER O WITH ACUTE - 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE - 0x00da: 0x00a7, # LATIN CAPITAL LETTER U WITH ACUTE - 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00dd: 0x0097, # LATIN CAPITAL LETTER Y WITH ACUTE - 0x00de: 0x008d, # LATIN CAPITAL LETTER THORN - 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S - 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE - 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE - 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS - 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE - 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE - 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA - 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE - 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE - 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS - 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE - 0x00f0: 0x008c, # LATIN SMALL LETTER ETH - 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE - 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS - 0x00f7: 0x00f6, # DIVISION SIGN - 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE - 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE - 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS - 0x00fd: 0x0098, # LATIN SMALL LETTER Y WITH ACUTE - 0x00fe: 0x0095, # LATIN SMALL LETTER THORN - 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK - 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA - 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA - 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA - 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI - 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA - 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA - 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA - 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON - 0x03c0: 0x00e3, # GREEK SMALL LETTER PI - 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA - 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU - 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI - 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N - 0x20a7: 0x009e, # PESETA SIGN - 0x2219: 0x00f9, # BULLET OPERATOR - 0x221a: 0x00fb, # SQUARE ROOT - 0x221e: 0x00ec, # INFINITY - 0x2229: 0x00ef, # INTERSECTION - 0x2248: 0x00f7, # ALMOST EQUAL TO - 0x2261: 0x00f0, # IDENTICAL TO - 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO - 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO - 0x2310: 0x00a9, # REVERSED NOT SIGN - 0x2320: 0x00f4, # TOP HALF INTEGRAL - 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x258c: 0x00dd, # LEFT HALF BLOCK - 0x2590: 0x00de, # RIGHT HALF BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp862.py b/python/Lib/encodings/cp862.py deleted file mode 100644 index 1e51d58..0000000 --- a/python/Lib/encodings/cp862.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP862.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp862', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x05d0, # HEBREW LETTER ALEF - 0x0081: 0x05d1, # HEBREW LETTER BET - 0x0082: 0x05d2, # HEBREW LETTER GIMEL - 0x0083: 0x05d3, # HEBREW LETTER DALET - 0x0084: 0x05d4, # HEBREW LETTER HE - 0x0085: 0x05d5, # HEBREW LETTER VAV - 0x0086: 0x05d6, # HEBREW LETTER ZAYIN - 0x0087: 0x05d7, # HEBREW LETTER HET - 0x0088: 0x05d8, # HEBREW LETTER TET - 0x0089: 0x05d9, # HEBREW LETTER YOD - 0x008a: 0x05da, # HEBREW LETTER FINAL KAF - 0x008b: 0x05db, # HEBREW LETTER KAF - 0x008c: 0x05dc, # HEBREW LETTER LAMED - 0x008d: 0x05dd, # HEBREW LETTER FINAL MEM - 0x008e: 0x05de, # HEBREW LETTER MEM - 0x008f: 0x05df, # HEBREW LETTER FINAL NUN - 0x0090: 0x05e0, # HEBREW LETTER NUN - 0x0091: 0x05e1, # HEBREW LETTER SAMEKH - 0x0092: 0x05e2, # HEBREW LETTER AYIN - 0x0093: 0x05e3, # HEBREW LETTER FINAL PE - 0x0094: 0x05e4, # HEBREW LETTER PE - 0x0095: 0x05e5, # HEBREW LETTER FINAL TSADI - 0x0096: 0x05e6, # HEBREW LETTER TSADI - 0x0097: 0x05e7, # HEBREW LETTER QOF - 0x0098: 0x05e8, # HEBREW LETTER RESH - 0x0099: 0x05e9, # HEBREW LETTER SHIN - 0x009a: 0x05ea, # HEBREW LETTER TAV - 0x009b: 0x00a2, # CENT SIGN - 0x009c: 0x00a3, # POUND SIGN - 0x009d: 0x00a5, # YEN SIGN - 0x009e: 0x20a7, # PESETA SIGN - 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK - 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE - 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE - 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE - 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE - 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE - 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR - 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR - 0x00a8: 0x00bf, # INVERTED QUESTION MARK - 0x00a9: 0x2310, # REVERSED NOT SIGN - 0x00aa: 0x00ac, # NOT SIGN - 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF - 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER - 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x258c, # LEFT HALF BLOCK - 0x00de: 0x2590, # RIGHT HALF BLOCK - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA - 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S (GERMAN) - 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA - 0x00e3: 0x03c0, # GREEK SMALL LETTER PI - 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA - 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA - 0x00e6: 0x00b5, # MICRO SIGN - 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU - 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI - 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA - 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA - 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA - 0x00ec: 0x221e, # INFINITY - 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI - 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON - 0x00ef: 0x2229, # INTERSECTION - 0x00f0: 0x2261, # IDENTICAL TO - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO - 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO - 0x00f4: 0x2320, # TOP HALF INTEGRAL - 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x2248, # ALMOST EQUAL TO - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x2219, # BULLET OPERATOR - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x221a, # SQUARE ROOT - 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N - 0x00fd: 0x00b2, # SUPERSCRIPT TWO - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\u05d0' # 0x0080 -> HEBREW LETTER ALEF - '\u05d1' # 0x0081 -> HEBREW LETTER BET - '\u05d2' # 0x0082 -> HEBREW LETTER GIMEL - '\u05d3' # 0x0083 -> HEBREW LETTER DALET - '\u05d4' # 0x0084 -> HEBREW LETTER HE - '\u05d5' # 0x0085 -> HEBREW LETTER VAV - '\u05d6' # 0x0086 -> HEBREW LETTER ZAYIN - '\u05d7' # 0x0087 -> HEBREW LETTER HET - '\u05d8' # 0x0088 -> HEBREW LETTER TET - '\u05d9' # 0x0089 -> HEBREW LETTER YOD - '\u05da' # 0x008a -> HEBREW LETTER FINAL KAF - '\u05db' # 0x008b -> HEBREW LETTER KAF - '\u05dc' # 0x008c -> HEBREW LETTER LAMED - '\u05dd' # 0x008d -> HEBREW LETTER FINAL MEM - '\u05de' # 0x008e -> HEBREW LETTER MEM - '\u05df' # 0x008f -> HEBREW LETTER FINAL NUN - '\u05e0' # 0x0090 -> HEBREW LETTER NUN - '\u05e1' # 0x0091 -> HEBREW LETTER SAMEKH - '\u05e2' # 0x0092 -> HEBREW LETTER AYIN - '\u05e3' # 0x0093 -> HEBREW LETTER FINAL PE - '\u05e4' # 0x0094 -> HEBREW LETTER PE - '\u05e5' # 0x0095 -> HEBREW LETTER FINAL TSADI - '\u05e6' # 0x0096 -> HEBREW LETTER TSADI - '\u05e7' # 0x0097 -> HEBREW LETTER QOF - '\u05e8' # 0x0098 -> HEBREW LETTER RESH - '\u05e9' # 0x0099 -> HEBREW LETTER SHIN - '\u05ea' # 0x009a -> HEBREW LETTER TAV - '\xa2' # 0x009b -> CENT SIGN - '\xa3' # 0x009c -> POUND SIGN - '\xa5' # 0x009d -> YEN SIGN - '\u20a7' # 0x009e -> PESETA SIGN - '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK - '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE - '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE - '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE - '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE - '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE - '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE - '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR - '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR - '\xbf' # 0x00a8 -> INVERTED QUESTION MARK - '\u2310' # 0x00a9 -> REVERSED NOT SIGN - '\xac' # 0x00aa -> NOT SIGN - '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF - '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER - '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u258c' # 0x00dd -> LEFT HALF BLOCK - '\u2590' # 0x00de -> RIGHT HALF BLOCK - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA - '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S (GERMAN) - '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA - '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI - '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA - '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA - '\xb5' # 0x00e6 -> MICRO SIGN - '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU - '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI - '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA - '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA - '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA - '\u221e' # 0x00ec -> INFINITY - '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI - '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON - '\u2229' # 0x00ef -> INTERSECTION - '\u2261' # 0x00f0 -> IDENTICAL TO - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO - '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO - '\u2320' # 0x00f4 -> TOP HALF INTEGRAL - '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL - '\xf7' # 0x00f6 -> DIVISION SIGN - '\u2248' # 0x00f7 -> ALMOST EQUAL TO - '\xb0' # 0x00f8 -> DEGREE SIGN - '\u2219' # 0x00f9 -> BULLET OPERATOR - '\xb7' # 0x00fa -> MIDDLE DOT - '\u221a' # 0x00fb -> SQUARE ROOT - '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N - '\xb2' # 0x00fd -> SUPERSCRIPT TWO - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK - 0x00a2: 0x009b, # CENT SIGN - 0x00a3: 0x009c, # POUND SIGN - 0x00a5: 0x009d, # YEN SIGN - 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x00aa, # NOT SIGN - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x00fd, # SUPERSCRIPT TWO - 0x00b5: 0x00e6, # MICRO SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER - 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF - 0x00bf: 0x00a8, # INVERTED QUESTION MARK - 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE - 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S (GERMAN) - 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE - 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE - 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE - 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE - 0x00f7: 0x00f6, # DIVISION SIGN - 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE - 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK - 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA - 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA - 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA - 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI - 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA - 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA - 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA - 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON - 0x03c0: 0x00e3, # GREEK SMALL LETTER PI - 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA - 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU - 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI - 0x05d0: 0x0080, # HEBREW LETTER ALEF - 0x05d1: 0x0081, # HEBREW LETTER BET - 0x05d2: 0x0082, # HEBREW LETTER GIMEL - 0x05d3: 0x0083, # HEBREW LETTER DALET - 0x05d4: 0x0084, # HEBREW LETTER HE - 0x05d5: 0x0085, # HEBREW LETTER VAV - 0x05d6: 0x0086, # HEBREW LETTER ZAYIN - 0x05d7: 0x0087, # HEBREW LETTER HET - 0x05d8: 0x0088, # HEBREW LETTER TET - 0x05d9: 0x0089, # HEBREW LETTER YOD - 0x05da: 0x008a, # HEBREW LETTER FINAL KAF - 0x05db: 0x008b, # HEBREW LETTER KAF - 0x05dc: 0x008c, # HEBREW LETTER LAMED - 0x05dd: 0x008d, # HEBREW LETTER FINAL MEM - 0x05de: 0x008e, # HEBREW LETTER MEM - 0x05df: 0x008f, # HEBREW LETTER FINAL NUN - 0x05e0: 0x0090, # HEBREW LETTER NUN - 0x05e1: 0x0091, # HEBREW LETTER SAMEKH - 0x05e2: 0x0092, # HEBREW LETTER AYIN - 0x05e3: 0x0093, # HEBREW LETTER FINAL PE - 0x05e4: 0x0094, # HEBREW LETTER PE - 0x05e5: 0x0095, # HEBREW LETTER FINAL TSADI - 0x05e6: 0x0096, # HEBREW LETTER TSADI - 0x05e7: 0x0097, # HEBREW LETTER QOF - 0x05e8: 0x0098, # HEBREW LETTER RESH - 0x05e9: 0x0099, # HEBREW LETTER SHIN - 0x05ea: 0x009a, # HEBREW LETTER TAV - 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N - 0x20a7: 0x009e, # PESETA SIGN - 0x2219: 0x00f9, # BULLET OPERATOR - 0x221a: 0x00fb, # SQUARE ROOT - 0x221e: 0x00ec, # INFINITY - 0x2229: 0x00ef, # INTERSECTION - 0x2248: 0x00f7, # ALMOST EQUAL TO - 0x2261: 0x00f0, # IDENTICAL TO - 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO - 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO - 0x2310: 0x00a9, # REVERSED NOT SIGN - 0x2320: 0x00f4, # TOP HALF INTEGRAL - 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x258c: 0x00dd, # LEFT HALF BLOCK - 0x2590: 0x00de, # RIGHT HALF BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp863.py b/python/Lib/encodings/cp863.py deleted file mode 100644 index 3d35ccd..0000000 --- a/python/Lib/encodings/cp863.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP863.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp863', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE - 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x0084: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE - 0x0086: 0x00b6, # PILCROW SIGN - 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA - 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS - 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE - 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS - 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x008d: 0x2017, # DOUBLE LOW LINE - 0x008e: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE - 0x008f: 0x00a7, # SECTION SIGN - 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE - 0x0091: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE - 0x0092: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX - 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x0094: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS - 0x0095: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS - 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE - 0x0098: 0x00a4, # CURRENCY SIGN - 0x0099: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x009b: 0x00a2, # CENT SIGN - 0x009c: 0x00a3, # POUND SIGN - 0x009d: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE - 0x009e: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX - 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK - 0x00a0: 0x00a6, # BROKEN BAR - 0x00a1: 0x00b4, # ACUTE ACCENT - 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE - 0x00a4: 0x00a8, # DIAERESIS - 0x00a5: 0x00b8, # CEDILLA - 0x00a6: 0x00b3, # SUPERSCRIPT THREE - 0x00a7: 0x00af, # MACRON - 0x00a8: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX - 0x00a9: 0x2310, # REVERSED NOT SIGN - 0x00aa: 0x00ac, # NOT SIGN - 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF - 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER - 0x00ad: 0x00be, # VULGAR FRACTION THREE QUARTERS - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x258c, # LEFT HALF BLOCK - 0x00de: 0x2590, # RIGHT HALF BLOCK - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA - 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S - 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA - 0x00e3: 0x03c0, # GREEK SMALL LETTER PI - 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA - 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA - 0x00e6: 0x00b5, # MICRO SIGN - 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU - 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI - 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA - 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA - 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA - 0x00ec: 0x221e, # INFINITY - 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI - 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON - 0x00ef: 0x2229, # INTERSECTION - 0x00f0: 0x2261, # IDENTICAL TO - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO - 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO - 0x00f4: 0x2320, # TOP HALF INTEGRAL - 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x2248, # ALMOST EQUAL TO - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x2219, # BULLET OPERATOR - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x221a, # SQUARE ROOT - 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N - 0x00fd: 0x00b2, # SUPERSCRIPT TWO - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS - '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE - '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xc2' # 0x0084 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE - '\xb6' # 0x0086 -> PILCROW SIGN - '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA - '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE - '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS - '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\u2017' # 0x008d -> DOUBLE LOW LINE - '\xc0' # 0x008e -> LATIN CAPITAL LETTER A WITH GRAVE - '\xa7' # 0x008f -> SECTION SIGN - '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xc8' # 0x0091 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xca' # 0x0092 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xcb' # 0x0094 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xcf' # 0x0095 -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE - '\xa4' # 0x0098 -> CURRENCY SIGN - '\xd4' # 0x0099 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xa2' # 0x009b -> CENT SIGN - '\xa3' # 0x009c -> POUND SIGN - '\xd9' # 0x009d -> LATIN CAPITAL LETTER U WITH GRAVE - '\xdb' # 0x009e -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK - '\xa6' # 0x00a0 -> BROKEN BAR - '\xb4' # 0x00a1 -> ACUTE ACCENT - '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE - '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE - '\xa8' # 0x00a4 -> DIAERESIS - '\xb8' # 0x00a5 -> CEDILLA - '\xb3' # 0x00a6 -> SUPERSCRIPT THREE - '\xaf' # 0x00a7 -> MACRON - '\xce' # 0x00a8 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\u2310' # 0x00a9 -> REVERSED NOT SIGN - '\xac' # 0x00aa -> NOT SIGN - '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF - '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER - '\xbe' # 0x00ad -> VULGAR FRACTION THREE QUARTERS - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u258c' # 0x00dd -> LEFT HALF BLOCK - '\u2590' # 0x00de -> RIGHT HALF BLOCK - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA - '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S - '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA - '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI - '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA - '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA - '\xb5' # 0x00e6 -> MICRO SIGN - '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU - '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI - '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA - '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA - '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA - '\u221e' # 0x00ec -> INFINITY - '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI - '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON - '\u2229' # 0x00ef -> INTERSECTION - '\u2261' # 0x00f0 -> IDENTICAL TO - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO - '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO - '\u2320' # 0x00f4 -> TOP HALF INTEGRAL - '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL - '\xf7' # 0x00f6 -> DIVISION SIGN - '\u2248' # 0x00f7 -> ALMOST EQUAL TO - '\xb0' # 0x00f8 -> DEGREE SIGN - '\u2219' # 0x00f9 -> BULLET OPERATOR - '\xb7' # 0x00fa -> MIDDLE DOT - '\u221a' # 0x00fb -> SQUARE ROOT - '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N - '\xb2' # 0x00fd -> SUPERSCRIPT TWO - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a2: 0x009b, # CENT SIGN - 0x00a3: 0x009c, # POUND SIGN - 0x00a4: 0x0098, # CURRENCY SIGN - 0x00a6: 0x00a0, # BROKEN BAR - 0x00a7: 0x008f, # SECTION SIGN - 0x00a8: 0x00a4, # DIAERESIS - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x00aa, # NOT SIGN - 0x00af: 0x00a7, # MACRON - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x00fd, # SUPERSCRIPT TWO - 0x00b3: 0x00a6, # SUPERSCRIPT THREE - 0x00b4: 0x00a1, # ACUTE ACCENT - 0x00b5: 0x00e6, # MICRO SIGN - 0x00b6: 0x0086, # PILCROW SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x00b8: 0x00a5, # CEDILLA - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER - 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF - 0x00be: 0x00ad, # VULGAR FRACTION THREE QUARTERS - 0x00c0: 0x008e, # LATIN CAPITAL LETTER A WITH GRAVE - 0x00c2: 0x0084, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x00c8: 0x0091, # LATIN CAPITAL LETTER E WITH GRAVE - 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE - 0x00ca: 0x0092, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX - 0x00cb: 0x0094, # LATIN CAPITAL LETTER E WITH DIAERESIS - 0x00ce: 0x00a8, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX - 0x00cf: 0x0095, # LATIN CAPITAL LETTER I WITH DIAERESIS - 0x00d4: 0x0099, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 0x00d9: 0x009d, # LATIN CAPITAL LETTER U WITH GRAVE - 0x00db: 0x009e, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX - 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S - 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE - 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA - 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE - 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE - 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS - 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS - 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE - 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x00f7: 0x00f6, # DIVISION SIGN - 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE - 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE - 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK - 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA - 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA - 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA - 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI - 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA - 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA - 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA - 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON - 0x03c0: 0x00e3, # GREEK SMALL LETTER PI - 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA - 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU - 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI - 0x2017: 0x008d, # DOUBLE LOW LINE - 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N - 0x2219: 0x00f9, # BULLET OPERATOR - 0x221a: 0x00fb, # SQUARE ROOT - 0x221e: 0x00ec, # INFINITY - 0x2229: 0x00ef, # INTERSECTION - 0x2248: 0x00f7, # ALMOST EQUAL TO - 0x2261: 0x00f0, # IDENTICAL TO - 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO - 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO - 0x2310: 0x00a9, # REVERSED NOT SIGN - 0x2320: 0x00f4, # TOP HALF INTEGRAL - 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x258c: 0x00dd, # LEFT HALF BLOCK - 0x2590: 0x00de, # RIGHT HALF BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp864.py b/python/Lib/encodings/cp864.py deleted file mode 100644 index 043c2bd..0000000 --- a/python/Lib/encodings/cp864.py +++ /dev/null @@ -1,690 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP864.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp864', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0025: 0x066a, # ARABIC PERCENT SIGN - 0x0080: 0x00b0, # DEGREE SIGN - 0x0081: 0x00b7, # MIDDLE DOT - 0x0082: 0x2219, # BULLET OPERATOR - 0x0083: 0x221a, # SQUARE ROOT - 0x0084: 0x2592, # MEDIUM SHADE - 0x0085: 0x2500, # FORMS LIGHT HORIZONTAL - 0x0086: 0x2502, # FORMS LIGHT VERTICAL - 0x0087: 0x253c, # FORMS LIGHT VERTICAL AND HORIZONTAL - 0x0088: 0x2524, # FORMS LIGHT VERTICAL AND LEFT - 0x0089: 0x252c, # FORMS LIGHT DOWN AND HORIZONTAL - 0x008a: 0x251c, # FORMS LIGHT VERTICAL AND RIGHT - 0x008b: 0x2534, # FORMS LIGHT UP AND HORIZONTAL - 0x008c: 0x2510, # FORMS LIGHT DOWN AND LEFT - 0x008d: 0x250c, # FORMS LIGHT DOWN AND RIGHT - 0x008e: 0x2514, # FORMS LIGHT UP AND RIGHT - 0x008f: 0x2518, # FORMS LIGHT UP AND LEFT - 0x0090: 0x03b2, # GREEK SMALL BETA - 0x0091: 0x221e, # INFINITY - 0x0092: 0x03c6, # GREEK SMALL PHI - 0x0093: 0x00b1, # PLUS-OR-MINUS SIGN - 0x0094: 0x00bd, # FRACTION 1/2 - 0x0095: 0x00bc, # FRACTION 1/4 - 0x0096: 0x2248, # ALMOST EQUAL TO - 0x0097: 0x00ab, # LEFT POINTING GUILLEMET - 0x0098: 0x00bb, # RIGHT POINTING GUILLEMET - 0x0099: 0xfef7, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM - 0x009a: 0xfef8, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM - 0x009b: None, # UNDEFINED - 0x009c: None, # UNDEFINED - 0x009d: 0xfefb, # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM - 0x009e: 0xfefc, # ARABIC LIGATURE LAM WITH ALEF FINAL FORM - 0x009f: None, # UNDEFINED - 0x00a1: 0x00ad, # SOFT HYPHEN - 0x00a2: 0xfe82, # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM - 0x00a5: 0xfe84, # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM - 0x00a6: None, # UNDEFINED - 0x00a7: None, # UNDEFINED - 0x00a8: 0xfe8e, # ARABIC LETTER ALEF FINAL FORM - 0x00a9: 0xfe8f, # ARABIC LETTER BEH ISOLATED FORM - 0x00aa: 0xfe95, # ARABIC LETTER TEH ISOLATED FORM - 0x00ab: 0xfe99, # ARABIC LETTER THEH ISOLATED FORM - 0x00ac: 0x060c, # ARABIC COMMA - 0x00ad: 0xfe9d, # ARABIC LETTER JEEM ISOLATED FORM - 0x00ae: 0xfea1, # ARABIC LETTER HAH ISOLATED FORM - 0x00af: 0xfea5, # ARABIC LETTER KHAH ISOLATED FORM - 0x00b0: 0x0660, # ARABIC-INDIC DIGIT ZERO - 0x00b1: 0x0661, # ARABIC-INDIC DIGIT ONE - 0x00b2: 0x0662, # ARABIC-INDIC DIGIT TWO - 0x00b3: 0x0663, # ARABIC-INDIC DIGIT THREE - 0x00b4: 0x0664, # ARABIC-INDIC DIGIT FOUR - 0x00b5: 0x0665, # ARABIC-INDIC DIGIT FIVE - 0x00b6: 0x0666, # ARABIC-INDIC DIGIT SIX - 0x00b7: 0x0667, # ARABIC-INDIC DIGIT SEVEN - 0x00b8: 0x0668, # ARABIC-INDIC DIGIT EIGHT - 0x00b9: 0x0669, # ARABIC-INDIC DIGIT NINE - 0x00ba: 0xfed1, # ARABIC LETTER FEH ISOLATED FORM - 0x00bb: 0x061b, # ARABIC SEMICOLON - 0x00bc: 0xfeb1, # ARABIC LETTER SEEN ISOLATED FORM - 0x00bd: 0xfeb5, # ARABIC LETTER SHEEN ISOLATED FORM - 0x00be: 0xfeb9, # ARABIC LETTER SAD ISOLATED FORM - 0x00bf: 0x061f, # ARABIC QUESTION MARK - 0x00c0: 0x00a2, # CENT SIGN - 0x00c1: 0xfe80, # ARABIC LETTER HAMZA ISOLATED FORM - 0x00c2: 0xfe81, # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM - 0x00c3: 0xfe83, # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM - 0x00c4: 0xfe85, # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM - 0x00c5: 0xfeca, # ARABIC LETTER AIN FINAL FORM - 0x00c6: 0xfe8b, # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM - 0x00c7: 0xfe8d, # ARABIC LETTER ALEF ISOLATED FORM - 0x00c8: 0xfe91, # ARABIC LETTER BEH INITIAL FORM - 0x00c9: 0xfe93, # ARABIC LETTER TEH MARBUTA ISOLATED FORM - 0x00ca: 0xfe97, # ARABIC LETTER TEH INITIAL FORM - 0x00cb: 0xfe9b, # ARABIC LETTER THEH INITIAL FORM - 0x00cc: 0xfe9f, # ARABIC LETTER JEEM INITIAL FORM - 0x00cd: 0xfea3, # ARABIC LETTER HAH INITIAL FORM - 0x00ce: 0xfea7, # ARABIC LETTER KHAH INITIAL FORM - 0x00cf: 0xfea9, # ARABIC LETTER DAL ISOLATED FORM - 0x00d0: 0xfeab, # ARABIC LETTER THAL ISOLATED FORM - 0x00d1: 0xfead, # ARABIC LETTER REH ISOLATED FORM - 0x00d2: 0xfeaf, # ARABIC LETTER ZAIN ISOLATED FORM - 0x00d3: 0xfeb3, # ARABIC LETTER SEEN INITIAL FORM - 0x00d4: 0xfeb7, # ARABIC LETTER SHEEN INITIAL FORM - 0x00d5: 0xfebb, # ARABIC LETTER SAD INITIAL FORM - 0x00d6: 0xfebf, # ARABIC LETTER DAD INITIAL FORM - 0x00d7: 0xfec1, # ARABIC LETTER TAH ISOLATED FORM - 0x00d8: 0xfec5, # ARABIC LETTER ZAH ISOLATED FORM - 0x00d9: 0xfecb, # ARABIC LETTER AIN INITIAL FORM - 0x00da: 0xfecf, # ARABIC LETTER GHAIN INITIAL FORM - 0x00db: 0x00a6, # BROKEN VERTICAL BAR - 0x00dc: 0x00ac, # NOT SIGN - 0x00dd: 0x00f7, # DIVISION SIGN - 0x00de: 0x00d7, # MULTIPLICATION SIGN - 0x00df: 0xfec9, # ARABIC LETTER AIN ISOLATED FORM - 0x00e0: 0x0640, # ARABIC TATWEEL - 0x00e1: 0xfed3, # ARABIC LETTER FEH INITIAL FORM - 0x00e2: 0xfed7, # ARABIC LETTER QAF INITIAL FORM - 0x00e3: 0xfedb, # ARABIC LETTER KAF INITIAL FORM - 0x00e4: 0xfedf, # ARABIC LETTER LAM INITIAL FORM - 0x00e5: 0xfee3, # ARABIC LETTER MEEM INITIAL FORM - 0x00e6: 0xfee7, # ARABIC LETTER NOON INITIAL FORM - 0x00e7: 0xfeeb, # ARABIC LETTER HEH INITIAL FORM - 0x00e8: 0xfeed, # ARABIC LETTER WAW ISOLATED FORM - 0x00e9: 0xfeef, # ARABIC LETTER ALEF MAKSURA ISOLATED FORM - 0x00ea: 0xfef3, # ARABIC LETTER YEH INITIAL FORM - 0x00eb: 0xfebd, # ARABIC LETTER DAD ISOLATED FORM - 0x00ec: 0xfecc, # ARABIC LETTER AIN MEDIAL FORM - 0x00ed: 0xfece, # ARABIC LETTER GHAIN FINAL FORM - 0x00ee: 0xfecd, # ARABIC LETTER GHAIN ISOLATED FORM - 0x00ef: 0xfee1, # ARABIC LETTER MEEM ISOLATED FORM - 0x00f0: 0xfe7d, # ARABIC SHADDA MEDIAL FORM - 0x00f1: 0x0651, # ARABIC SHADDAH - 0x00f2: 0xfee5, # ARABIC LETTER NOON ISOLATED FORM - 0x00f3: 0xfee9, # ARABIC LETTER HEH ISOLATED FORM - 0x00f4: 0xfeec, # ARABIC LETTER HEH MEDIAL FORM - 0x00f5: 0xfef0, # ARABIC LETTER ALEF MAKSURA FINAL FORM - 0x00f6: 0xfef2, # ARABIC LETTER YEH FINAL FORM - 0x00f7: 0xfed0, # ARABIC LETTER GHAIN MEDIAL FORM - 0x00f8: 0xfed5, # ARABIC LETTER QAF ISOLATED FORM - 0x00f9: 0xfef5, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM - 0x00fa: 0xfef6, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM - 0x00fb: 0xfedd, # ARABIC LETTER LAM ISOLATED FORM - 0x00fc: 0xfed9, # ARABIC LETTER KAF ISOLATED FORM - 0x00fd: 0xfef1, # ARABIC LETTER YEH ISOLATED FORM - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: None, # UNDEFINED -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '\u066a' # 0x0025 -> ARABIC PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\xb0' # 0x0080 -> DEGREE SIGN - '\xb7' # 0x0081 -> MIDDLE DOT - '\u2219' # 0x0082 -> BULLET OPERATOR - '\u221a' # 0x0083 -> SQUARE ROOT - '\u2592' # 0x0084 -> MEDIUM SHADE - '\u2500' # 0x0085 -> FORMS LIGHT HORIZONTAL - '\u2502' # 0x0086 -> FORMS LIGHT VERTICAL - '\u253c' # 0x0087 -> FORMS LIGHT VERTICAL AND HORIZONTAL - '\u2524' # 0x0088 -> FORMS LIGHT VERTICAL AND LEFT - '\u252c' # 0x0089 -> FORMS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x008a -> FORMS LIGHT VERTICAL AND RIGHT - '\u2534' # 0x008b -> FORMS LIGHT UP AND HORIZONTAL - '\u2510' # 0x008c -> FORMS LIGHT DOWN AND LEFT - '\u250c' # 0x008d -> FORMS LIGHT DOWN AND RIGHT - '\u2514' # 0x008e -> FORMS LIGHT UP AND RIGHT - '\u2518' # 0x008f -> FORMS LIGHT UP AND LEFT - '\u03b2' # 0x0090 -> GREEK SMALL BETA - '\u221e' # 0x0091 -> INFINITY - '\u03c6' # 0x0092 -> GREEK SMALL PHI - '\xb1' # 0x0093 -> PLUS-OR-MINUS SIGN - '\xbd' # 0x0094 -> FRACTION 1/2 - '\xbc' # 0x0095 -> FRACTION 1/4 - '\u2248' # 0x0096 -> ALMOST EQUAL TO - '\xab' # 0x0097 -> LEFT POINTING GUILLEMET - '\xbb' # 0x0098 -> RIGHT POINTING GUILLEMET - '\ufef7' # 0x0099 -> ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM - '\ufef8' # 0x009a -> ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM - '\ufffe' # 0x009b -> UNDEFINED - '\ufffe' # 0x009c -> UNDEFINED - '\ufefb' # 0x009d -> ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM - '\ufefc' # 0x009e -> ARABIC LIGATURE LAM WITH ALEF FINAL FORM - '\ufffe' # 0x009f -> UNDEFINED - '\xa0' # 0x00a0 -> NON-BREAKING SPACE - '\xad' # 0x00a1 -> SOFT HYPHEN - '\ufe82' # 0x00a2 -> ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM - '\xa3' # 0x00a3 -> POUND SIGN - '\xa4' # 0x00a4 -> CURRENCY SIGN - '\ufe84' # 0x00a5 -> ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM - '\ufffe' # 0x00a6 -> UNDEFINED - '\ufffe' # 0x00a7 -> UNDEFINED - '\ufe8e' # 0x00a8 -> ARABIC LETTER ALEF FINAL FORM - '\ufe8f' # 0x00a9 -> ARABIC LETTER BEH ISOLATED FORM - '\ufe95' # 0x00aa -> ARABIC LETTER TEH ISOLATED FORM - '\ufe99' # 0x00ab -> ARABIC LETTER THEH ISOLATED FORM - '\u060c' # 0x00ac -> ARABIC COMMA - '\ufe9d' # 0x00ad -> ARABIC LETTER JEEM ISOLATED FORM - '\ufea1' # 0x00ae -> ARABIC LETTER HAH ISOLATED FORM - '\ufea5' # 0x00af -> ARABIC LETTER KHAH ISOLATED FORM - '\u0660' # 0x00b0 -> ARABIC-INDIC DIGIT ZERO - '\u0661' # 0x00b1 -> ARABIC-INDIC DIGIT ONE - '\u0662' # 0x00b2 -> ARABIC-INDIC DIGIT TWO - '\u0663' # 0x00b3 -> ARABIC-INDIC DIGIT THREE - '\u0664' # 0x00b4 -> ARABIC-INDIC DIGIT FOUR - '\u0665' # 0x00b5 -> ARABIC-INDIC DIGIT FIVE - '\u0666' # 0x00b6 -> ARABIC-INDIC DIGIT SIX - '\u0667' # 0x00b7 -> ARABIC-INDIC DIGIT SEVEN - '\u0668' # 0x00b8 -> ARABIC-INDIC DIGIT EIGHT - '\u0669' # 0x00b9 -> ARABIC-INDIC DIGIT NINE - '\ufed1' # 0x00ba -> ARABIC LETTER FEH ISOLATED FORM - '\u061b' # 0x00bb -> ARABIC SEMICOLON - '\ufeb1' # 0x00bc -> ARABIC LETTER SEEN ISOLATED FORM - '\ufeb5' # 0x00bd -> ARABIC LETTER SHEEN ISOLATED FORM - '\ufeb9' # 0x00be -> ARABIC LETTER SAD ISOLATED FORM - '\u061f' # 0x00bf -> ARABIC QUESTION MARK - '\xa2' # 0x00c0 -> CENT SIGN - '\ufe80' # 0x00c1 -> ARABIC LETTER HAMZA ISOLATED FORM - '\ufe81' # 0x00c2 -> ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM - '\ufe83' # 0x00c3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM - '\ufe85' # 0x00c4 -> ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM - '\ufeca' # 0x00c5 -> ARABIC LETTER AIN FINAL FORM - '\ufe8b' # 0x00c6 -> ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM - '\ufe8d' # 0x00c7 -> ARABIC LETTER ALEF ISOLATED FORM - '\ufe91' # 0x00c8 -> ARABIC LETTER BEH INITIAL FORM - '\ufe93' # 0x00c9 -> ARABIC LETTER TEH MARBUTA ISOLATED FORM - '\ufe97' # 0x00ca -> ARABIC LETTER TEH INITIAL FORM - '\ufe9b' # 0x00cb -> ARABIC LETTER THEH INITIAL FORM - '\ufe9f' # 0x00cc -> ARABIC LETTER JEEM INITIAL FORM - '\ufea3' # 0x00cd -> ARABIC LETTER HAH INITIAL FORM - '\ufea7' # 0x00ce -> ARABIC LETTER KHAH INITIAL FORM - '\ufea9' # 0x00cf -> ARABIC LETTER DAL ISOLATED FORM - '\ufeab' # 0x00d0 -> ARABIC LETTER THAL ISOLATED FORM - '\ufead' # 0x00d1 -> ARABIC LETTER REH ISOLATED FORM - '\ufeaf' # 0x00d2 -> ARABIC LETTER ZAIN ISOLATED FORM - '\ufeb3' # 0x00d3 -> ARABIC LETTER SEEN INITIAL FORM - '\ufeb7' # 0x00d4 -> ARABIC LETTER SHEEN INITIAL FORM - '\ufebb' # 0x00d5 -> ARABIC LETTER SAD INITIAL FORM - '\ufebf' # 0x00d6 -> ARABIC LETTER DAD INITIAL FORM - '\ufec1' # 0x00d7 -> ARABIC LETTER TAH ISOLATED FORM - '\ufec5' # 0x00d8 -> ARABIC LETTER ZAH ISOLATED FORM - '\ufecb' # 0x00d9 -> ARABIC LETTER AIN INITIAL FORM - '\ufecf' # 0x00da -> ARABIC LETTER GHAIN INITIAL FORM - '\xa6' # 0x00db -> BROKEN VERTICAL BAR - '\xac' # 0x00dc -> NOT SIGN - '\xf7' # 0x00dd -> DIVISION SIGN - '\xd7' # 0x00de -> MULTIPLICATION SIGN - '\ufec9' # 0x00df -> ARABIC LETTER AIN ISOLATED FORM - '\u0640' # 0x00e0 -> ARABIC TATWEEL - '\ufed3' # 0x00e1 -> ARABIC LETTER FEH INITIAL FORM - '\ufed7' # 0x00e2 -> ARABIC LETTER QAF INITIAL FORM - '\ufedb' # 0x00e3 -> ARABIC LETTER KAF INITIAL FORM - '\ufedf' # 0x00e4 -> ARABIC LETTER LAM INITIAL FORM - '\ufee3' # 0x00e5 -> ARABIC LETTER MEEM INITIAL FORM - '\ufee7' # 0x00e6 -> ARABIC LETTER NOON INITIAL FORM - '\ufeeb' # 0x00e7 -> ARABIC LETTER HEH INITIAL FORM - '\ufeed' # 0x00e8 -> ARABIC LETTER WAW ISOLATED FORM - '\ufeef' # 0x00e9 -> ARABIC LETTER ALEF MAKSURA ISOLATED FORM - '\ufef3' # 0x00ea -> ARABIC LETTER YEH INITIAL FORM - '\ufebd' # 0x00eb -> ARABIC LETTER DAD ISOLATED FORM - '\ufecc' # 0x00ec -> ARABIC LETTER AIN MEDIAL FORM - '\ufece' # 0x00ed -> ARABIC LETTER GHAIN FINAL FORM - '\ufecd' # 0x00ee -> ARABIC LETTER GHAIN ISOLATED FORM - '\ufee1' # 0x00ef -> ARABIC LETTER MEEM ISOLATED FORM - '\ufe7d' # 0x00f0 -> ARABIC SHADDA MEDIAL FORM - '\u0651' # 0x00f1 -> ARABIC SHADDAH - '\ufee5' # 0x00f2 -> ARABIC LETTER NOON ISOLATED FORM - '\ufee9' # 0x00f3 -> ARABIC LETTER HEH ISOLATED FORM - '\ufeec' # 0x00f4 -> ARABIC LETTER HEH MEDIAL FORM - '\ufef0' # 0x00f5 -> ARABIC LETTER ALEF MAKSURA FINAL FORM - '\ufef2' # 0x00f6 -> ARABIC LETTER YEH FINAL FORM - '\ufed0' # 0x00f7 -> ARABIC LETTER GHAIN MEDIAL FORM - '\ufed5' # 0x00f8 -> ARABIC LETTER QAF ISOLATED FORM - '\ufef5' # 0x00f9 -> ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM - '\ufef6' # 0x00fa -> ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM - '\ufedd' # 0x00fb -> ARABIC LETTER LAM ISOLATED FORM - '\ufed9' # 0x00fc -> ARABIC LETTER KAF ISOLATED FORM - '\ufef1' # 0x00fd -> ARABIC LETTER YEH ISOLATED FORM - '\u25a0' # 0x00fe -> BLACK SQUARE - '\ufffe' # 0x00ff -> UNDEFINED -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00a0, # NON-BREAKING SPACE - 0x00a2: 0x00c0, # CENT SIGN - 0x00a3: 0x00a3, # POUND SIGN - 0x00a4: 0x00a4, # CURRENCY SIGN - 0x00a6: 0x00db, # BROKEN VERTICAL BAR - 0x00ab: 0x0097, # LEFT POINTING GUILLEMET - 0x00ac: 0x00dc, # NOT SIGN - 0x00ad: 0x00a1, # SOFT HYPHEN - 0x00b0: 0x0080, # DEGREE SIGN - 0x00b1: 0x0093, # PLUS-OR-MINUS SIGN - 0x00b7: 0x0081, # MIDDLE DOT - 0x00bb: 0x0098, # RIGHT POINTING GUILLEMET - 0x00bc: 0x0095, # FRACTION 1/4 - 0x00bd: 0x0094, # FRACTION 1/2 - 0x00d7: 0x00de, # MULTIPLICATION SIGN - 0x00f7: 0x00dd, # DIVISION SIGN - 0x03b2: 0x0090, # GREEK SMALL BETA - 0x03c6: 0x0092, # GREEK SMALL PHI - 0x060c: 0x00ac, # ARABIC COMMA - 0x061b: 0x00bb, # ARABIC SEMICOLON - 0x061f: 0x00bf, # ARABIC QUESTION MARK - 0x0640: 0x00e0, # ARABIC TATWEEL - 0x0651: 0x00f1, # ARABIC SHADDAH - 0x0660: 0x00b0, # ARABIC-INDIC DIGIT ZERO - 0x0661: 0x00b1, # ARABIC-INDIC DIGIT ONE - 0x0662: 0x00b2, # ARABIC-INDIC DIGIT TWO - 0x0663: 0x00b3, # ARABIC-INDIC DIGIT THREE - 0x0664: 0x00b4, # ARABIC-INDIC DIGIT FOUR - 0x0665: 0x00b5, # ARABIC-INDIC DIGIT FIVE - 0x0666: 0x00b6, # ARABIC-INDIC DIGIT SIX - 0x0667: 0x00b7, # ARABIC-INDIC DIGIT SEVEN - 0x0668: 0x00b8, # ARABIC-INDIC DIGIT EIGHT - 0x0669: 0x00b9, # ARABIC-INDIC DIGIT NINE - 0x066a: 0x0025, # ARABIC PERCENT SIGN - 0x2219: 0x0082, # BULLET OPERATOR - 0x221a: 0x0083, # SQUARE ROOT - 0x221e: 0x0091, # INFINITY - 0x2248: 0x0096, # ALMOST EQUAL TO - 0x2500: 0x0085, # FORMS LIGHT HORIZONTAL - 0x2502: 0x0086, # FORMS LIGHT VERTICAL - 0x250c: 0x008d, # FORMS LIGHT DOWN AND RIGHT - 0x2510: 0x008c, # FORMS LIGHT DOWN AND LEFT - 0x2514: 0x008e, # FORMS LIGHT UP AND RIGHT - 0x2518: 0x008f, # FORMS LIGHT UP AND LEFT - 0x251c: 0x008a, # FORMS LIGHT VERTICAL AND RIGHT - 0x2524: 0x0088, # FORMS LIGHT VERTICAL AND LEFT - 0x252c: 0x0089, # FORMS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x008b, # FORMS LIGHT UP AND HORIZONTAL - 0x253c: 0x0087, # FORMS LIGHT VERTICAL AND HORIZONTAL - 0x2592: 0x0084, # MEDIUM SHADE - 0x25a0: 0x00fe, # BLACK SQUARE - 0xfe7d: 0x00f0, # ARABIC SHADDA MEDIAL FORM - 0xfe80: 0x00c1, # ARABIC LETTER HAMZA ISOLATED FORM - 0xfe81: 0x00c2, # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM - 0xfe82: 0x00a2, # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM - 0xfe83: 0x00c3, # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM - 0xfe84: 0x00a5, # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM - 0xfe85: 0x00c4, # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM - 0xfe8b: 0x00c6, # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM - 0xfe8d: 0x00c7, # ARABIC LETTER ALEF ISOLATED FORM - 0xfe8e: 0x00a8, # ARABIC LETTER ALEF FINAL FORM - 0xfe8f: 0x00a9, # ARABIC LETTER BEH ISOLATED FORM - 0xfe91: 0x00c8, # ARABIC LETTER BEH INITIAL FORM - 0xfe93: 0x00c9, # ARABIC LETTER TEH MARBUTA ISOLATED FORM - 0xfe95: 0x00aa, # ARABIC LETTER TEH ISOLATED FORM - 0xfe97: 0x00ca, # ARABIC LETTER TEH INITIAL FORM - 0xfe99: 0x00ab, # ARABIC LETTER THEH ISOLATED FORM - 0xfe9b: 0x00cb, # ARABIC LETTER THEH INITIAL FORM - 0xfe9d: 0x00ad, # ARABIC LETTER JEEM ISOLATED FORM - 0xfe9f: 0x00cc, # ARABIC LETTER JEEM INITIAL FORM - 0xfea1: 0x00ae, # ARABIC LETTER HAH ISOLATED FORM - 0xfea3: 0x00cd, # ARABIC LETTER HAH INITIAL FORM - 0xfea5: 0x00af, # ARABIC LETTER KHAH ISOLATED FORM - 0xfea7: 0x00ce, # ARABIC LETTER KHAH INITIAL FORM - 0xfea9: 0x00cf, # ARABIC LETTER DAL ISOLATED FORM - 0xfeab: 0x00d0, # ARABIC LETTER THAL ISOLATED FORM - 0xfead: 0x00d1, # ARABIC LETTER REH ISOLATED FORM - 0xfeaf: 0x00d2, # ARABIC LETTER ZAIN ISOLATED FORM - 0xfeb1: 0x00bc, # ARABIC LETTER SEEN ISOLATED FORM - 0xfeb3: 0x00d3, # ARABIC LETTER SEEN INITIAL FORM - 0xfeb5: 0x00bd, # ARABIC LETTER SHEEN ISOLATED FORM - 0xfeb7: 0x00d4, # ARABIC LETTER SHEEN INITIAL FORM - 0xfeb9: 0x00be, # ARABIC LETTER SAD ISOLATED FORM - 0xfebb: 0x00d5, # ARABIC LETTER SAD INITIAL FORM - 0xfebd: 0x00eb, # ARABIC LETTER DAD ISOLATED FORM - 0xfebf: 0x00d6, # ARABIC LETTER DAD INITIAL FORM - 0xfec1: 0x00d7, # ARABIC LETTER TAH ISOLATED FORM - 0xfec5: 0x00d8, # ARABIC LETTER ZAH ISOLATED FORM - 0xfec9: 0x00df, # ARABIC LETTER AIN ISOLATED FORM - 0xfeca: 0x00c5, # ARABIC LETTER AIN FINAL FORM - 0xfecb: 0x00d9, # ARABIC LETTER AIN INITIAL FORM - 0xfecc: 0x00ec, # ARABIC LETTER AIN MEDIAL FORM - 0xfecd: 0x00ee, # ARABIC LETTER GHAIN ISOLATED FORM - 0xfece: 0x00ed, # ARABIC LETTER GHAIN FINAL FORM - 0xfecf: 0x00da, # ARABIC LETTER GHAIN INITIAL FORM - 0xfed0: 0x00f7, # ARABIC LETTER GHAIN MEDIAL FORM - 0xfed1: 0x00ba, # ARABIC LETTER FEH ISOLATED FORM - 0xfed3: 0x00e1, # ARABIC LETTER FEH INITIAL FORM - 0xfed5: 0x00f8, # ARABIC LETTER QAF ISOLATED FORM - 0xfed7: 0x00e2, # ARABIC LETTER QAF INITIAL FORM - 0xfed9: 0x00fc, # ARABIC LETTER KAF ISOLATED FORM - 0xfedb: 0x00e3, # ARABIC LETTER KAF INITIAL FORM - 0xfedd: 0x00fb, # ARABIC LETTER LAM ISOLATED FORM - 0xfedf: 0x00e4, # ARABIC LETTER LAM INITIAL FORM - 0xfee1: 0x00ef, # ARABIC LETTER MEEM ISOLATED FORM - 0xfee3: 0x00e5, # ARABIC LETTER MEEM INITIAL FORM - 0xfee5: 0x00f2, # ARABIC LETTER NOON ISOLATED FORM - 0xfee7: 0x00e6, # ARABIC LETTER NOON INITIAL FORM - 0xfee9: 0x00f3, # ARABIC LETTER HEH ISOLATED FORM - 0xfeeb: 0x00e7, # ARABIC LETTER HEH INITIAL FORM - 0xfeec: 0x00f4, # ARABIC LETTER HEH MEDIAL FORM - 0xfeed: 0x00e8, # ARABIC LETTER WAW ISOLATED FORM - 0xfeef: 0x00e9, # ARABIC LETTER ALEF MAKSURA ISOLATED FORM - 0xfef0: 0x00f5, # ARABIC LETTER ALEF MAKSURA FINAL FORM - 0xfef1: 0x00fd, # ARABIC LETTER YEH ISOLATED FORM - 0xfef2: 0x00f6, # ARABIC LETTER YEH FINAL FORM - 0xfef3: 0x00ea, # ARABIC LETTER YEH INITIAL FORM - 0xfef5: 0x00f9, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM - 0xfef6: 0x00fa, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM - 0xfef7: 0x0099, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM - 0xfef8: 0x009a, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM - 0xfefb: 0x009d, # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM - 0xfefc: 0x009e, # ARABIC LIGATURE LAM WITH ALEF FINAL FORM -} diff --git a/python/Lib/encodings/cp865.py b/python/Lib/encodings/cp865.py deleted file mode 100644 index fe64f64..0000000 --- a/python/Lib/encodings/cp865.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP865.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp865', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS - 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE - 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS - 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE - 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE - 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA - 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS - 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE - 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS - 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE - 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE - 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE - 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE - 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS - 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE - 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE - 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS - 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE - 0x009c: 0x00a3, # POUND SIGN - 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE - 0x009e: 0x20a7, # PESETA SIGN - 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK - 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE - 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE - 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE - 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE - 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE - 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR - 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR - 0x00a8: 0x00bf, # INVERTED QUESTION MARK - 0x00a9: 0x2310, # REVERSED NOT SIGN - 0x00aa: 0x00ac, # NOT SIGN - 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF - 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER - 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00a4, # CURRENCY SIGN - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x258c, # LEFT HALF BLOCK - 0x00de: 0x2590, # RIGHT HALF BLOCK - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA - 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S - 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA - 0x00e3: 0x03c0, # GREEK SMALL LETTER PI - 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA - 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA - 0x00e6: 0x00b5, # MICRO SIGN - 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU - 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI - 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA - 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA - 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA - 0x00ec: 0x221e, # INFINITY - 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI - 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON - 0x00ef: 0x2229, # INTERSECTION - 0x00f0: 0x2261, # IDENTICAL TO - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO - 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO - 0x00f4: 0x2320, # TOP HALF INTEGRAL - 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL - 0x00f6: 0x00f7, # DIVISION SIGN - 0x00f7: 0x2248, # ALMOST EQUAL TO - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x2219, # BULLET OPERATOR - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x221a, # SQUARE ROOT - 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N - 0x00fd: 0x00b2, # SUPERSCRIPT TWO - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS - '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE - '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE - '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA - '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE - '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS - '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE - '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE - '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE - '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE - '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE - '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS - '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE - '\xa3' # 0x009c -> POUND SIGN - '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE - '\u20a7' # 0x009e -> PESETA SIGN - '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK - '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE - '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE - '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE - '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE - '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE - '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE - '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR - '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR - '\xbf' # 0x00a8 -> INVERTED QUESTION MARK - '\u2310' # 0x00a9 -> REVERSED NOT SIGN - '\xac' # 0x00aa -> NOT SIGN - '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF - '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER - '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xa4' # 0x00af -> CURRENCY SIGN - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u258c' # 0x00dd -> LEFT HALF BLOCK - '\u2590' # 0x00de -> RIGHT HALF BLOCK - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA - '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S - '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA - '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI - '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA - '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA - '\xb5' # 0x00e6 -> MICRO SIGN - '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU - '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI - '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA - '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA - '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA - '\u221e' # 0x00ec -> INFINITY - '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI - '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON - '\u2229' # 0x00ef -> INTERSECTION - '\u2261' # 0x00f0 -> IDENTICAL TO - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO - '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO - '\u2320' # 0x00f4 -> TOP HALF INTEGRAL - '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL - '\xf7' # 0x00f6 -> DIVISION SIGN - '\u2248' # 0x00f7 -> ALMOST EQUAL TO - '\xb0' # 0x00f8 -> DEGREE SIGN - '\u2219' # 0x00f9 -> BULLET OPERATOR - '\xb7' # 0x00fa -> MIDDLE DOT - '\u221a' # 0x00fb -> SQUARE ROOT - '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N - '\xb2' # 0x00fd -> SUPERSCRIPT TWO - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK - 0x00a3: 0x009c, # POUND SIGN - 0x00a4: 0x00af, # CURRENCY SIGN - 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x00aa, # NOT SIGN - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x00fd, # SUPERSCRIPT TWO - 0x00b5: 0x00e6, # MICRO SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR - 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER - 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF - 0x00bf: 0x00a8, # INVERTED QUESTION MARK - 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE - 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE - 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE - 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE - 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE - 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S - 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE - 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE - 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS - 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE - 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE - 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA - 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE - 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE - 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS - 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE - 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE - 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS - 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE - 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE - 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE - 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS - 0x00f7: 0x00f6, # DIVISION SIGN - 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE - 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE - 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE - 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS - 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS - 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK - 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA - 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA - 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA - 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI - 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA - 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA - 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA - 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON - 0x03c0: 0x00e3, # GREEK SMALL LETTER PI - 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA - 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU - 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI - 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N - 0x20a7: 0x009e, # PESETA SIGN - 0x2219: 0x00f9, # BULLET OPERATOR - 0x221a: 0x00fb, # SQUARE ROOT - 0x221e: 0x00ec, # INFINITY - 0x2229: 0x00ef, # INTERSECTION - 0x2248: 0x00f7, # ALMOST EQUAL TO - 0x2261: 0x00f0, # IDENTICAL TO - 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO - 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO - 0x2310: 0x00a9, # REVERSED NOT SIGN - 0x2320: 0x00f4, # TOP HALF INTEGRAL - 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x258c: 0x00dd, # LEFT HALF BLOCK - 0x2590: 0x00de, # RIGHT HALF BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp866.py b/python/Lib/encodings/cp866.py deleted file mode 100644 index 7145b1f..0000000 --- a/python/Lib/encodings/cp866.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP866.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp866', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x0410, # CYRILLIC CAPITAL LETTER A - 0x0081: 0x0411, # CYRILLIC CAPITAL LETTER BE - 0x0082: 0x0412, # CYRILLIC CAPITAL LETTER VE - 0x0083: 0x0413, # CYRILLIC CAPITAL LETTER GHE - 0x0084: 0x0414, # CYRILLIC CAPITAL LETTER DE - 0x0085: 0x0415, # CYRILLIC CAPITAL LETTER IE - 0x0086: 0x0416, # CYRILLIC CAPITAL LETTER ZHE - 0x0087: 0x0417, # CYRILLIC CAPITAL LETTER ZE - 0x0088: 0x0418, # CYRILLIC CAPITAL LETTER I - 0x0089: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I - 0x008a: 0x041a, # CYRILLIC CAPITAL LETTER KA - 0x008b: 0x041b, # CYRILLIC CAPITAL LETTER EL - 0x008c: 0x041c, # CYRILLIC CAPITAL LETTER EM - 0x008d: 0x041d, # CYRILLIC CAPITAL LETTER EN - 0x008e: 0x041e, # CYRILLIC CAPITAL LETTER O - 0x008f: 0x041f, # CYRILLIC CAPITAL LETTER PE - 0x0090: 0x0420, # CYRILLIC CAPITAL LETTER ER - 0x0091: 0x0421, # CYRILLIC CAPITAL LETTER ES - 0x0092: 0x0422, # CYRILLIC CAPITAL LETTER TE - 0x0093: 0x0423, # CYRILLIC CAPITAL LETTER U - 0x0094: 0x0424, # CYRILLIC CAPITAL LETTER EF - 0x0095: 0x0425, # CYRILLIC CAPITAL LETTER HA - 0x0096: 0x0426, # CYRILLIC CAPITAL LETTER TSE - 0x0097: 0x0427, # CYRILLIC CAPITAL LETTER CHE - 0x0098: 0x0428, # CYRILLIC CAPITAL LETTER SHA - 0x0099: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA - 0x009a: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN - 0x009b: 0x042b, # CYRILLIC CAPITAL LETTER YERU - 0x009c: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN - 0x009d: 0x042d, # CYRILLIC CAPITAL LETTER E - 0x009e: 0x042e, # CYRILLIC CAPITAL LETTER YU - 0x009f: 0x042f, # CYRILLIC CAPITAL LETTER YA - 0x00a0: 0x0430, # CYRILLIC SMALL LETTER A - 0x00a1: 0x0431, # CYRILLIC SMALL LETTER BE - 0x00a2: 0x0432, # CYRILLIC SMALL LETTER VE - 0x00a3: 0x0433, # CYRILLIC SMALL LETTER GHE - 0x00a4: 0x0434, # CYRILLIC SMALL LETTER DE - 0x00a5: 0x0435, # CYRILLIC SMALL LETTER IE - 0x00a6: 0x0436, # CYRILLIC SMALL LETTER ZHE - 0x00a7: 0x0437, # CYRILLIC SMALL LETTER ZE - 0x00a8: 0x0438, # CYRILLIC SMALL LETTER I - 0x00a9: 0x0439, # CYRILLIC SMALL LETTER SHORT I - 0x00aa: 0x043a, # CYRILLIC SMALL LETTER KA - 0x00ab: 0x043b, # CYRILLIC SMALL LETTER EL - 0x00ac: 0x043c, # CYRILLIC SMALL LETTER EM - 0x00ad: 0x043d, # CYRILLIC SMALL LETTER EN - 0x00ae: 0x043e, # CYRILLIC SMALL LETTER O - 0x00af: 0x043f, # CYRILLIC SMALL LETTER PE - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x258c, # LEFT HALF BLOCK - 0x00de: 0x2590, # RIGHT HALF BLOCK - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x0440, # CYRILLIC SMALL LETTER ER - 0x00e1: 0x0441, # CYRILLIC SMALL LETTER ES - 0x00e2: 0x0442, # CYRILLIC SMALL LETTER TE - 0x00e3: 0x0443, # CYRILLIC SMALL LETTER U - 0x00e4: 0x0444, # CYRILLIC SMALL LETTER EF - 0x00e5: 0x0445, # CYRILLIC SMALL LETTER HA - 0x00e6: 0x0446, # CYRILLIC SMALL LETTER TSE - 0x00e7: 0x0447, # CYRILLIC SMALL LETTER CHE - 0x00e8: 0x0448, # CYRILLIC SMALL LETTER SHA - 0x00e9: 0x0449, # CYRILLIC SMALL LETTER SHCHA - 0x00ea: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN - 0x00eb: 0x044b, # CYRILLIC SMALL LETTER YERU - 0x00ec: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN - 0x00ed: 0x044d, # CYRILLIC SMALL LETTER E - 0x00ee: 0x044e, # CYRILLIC SMALL LETTER YU - 0x00ef: 0x044f, # CYRILLIC SMALL LETTER YA - 0x00f0: 0x0401, # CYRILLIC CAPITAL LETTER IO - 0x00f1: 0x0451, # CYRILLIC SMALL LETTER IO - 0x00f2: 0x0404, # CYRILLIC CAPITAL LETTER UKRAINIAN IE - 0x00f3: 0x0454, # CYRILLIC SMALL LETTER UKRAINIAN IE - 0x00f4: 0x0407, # CYRILLIC CAPITAL LETTER YI - 0x00f5: 0x0457, # CYRILLIC SMALL LETTER YI - 0x00f6: 0x040e, # CYRILLIC CAPITAL LETTER SHORT U - 0x00f7: 0x045e, # CYRILLIC SMALL LETTER SHORT U - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x2219, # BULLET OPERATOR - 0x00fa: 0x00b7, # MIDDLE DOT - 0x00fb: 0x221a, # SQUARE ROOT - 0x00fc: 0x2116, # NUMERO SIGN - 0x00fd: 0x00a4, # CURRENCY SIGN - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\u0410' # 0x0080 -> CYRILLIC CAPITAL LETTER A - '\u0411' # 0x0081 -> CYRILLIC CAPITAL LETTER BE - '\u0412' # 0x0082 -> CYRILLIC CAPITAL LETTER VE - '\u0413' # 0x0083 -> CYRILLIC CAPITAL LETTER GHE - '\u0414' # 0x0084 -> CYRILLIC CAPITAL LETTER DE - '\u0415' # 0x0085 -> CYRILLIC CAPITAL LETTER IE - '\u0416' # 0x0086 -> CYRILLIC CAPITAL LETTER ZHE - '\u0417' # 0x0087 -> CYRILLIC CAPITAL LETTER ZE - '\u0418' # 0x0088 -> CYRILLIC CAPITAL LETTER I - '\u0419' # 0x0089 -> CYRILLIC CAPITAL LETTER SHORT I - '\u041a' # 0x008a -> CYRILLIC CAPITAL LETTER KA - '\u041b' # 0x008b -> CYRILLIC CAPITAL LETTER EL - '\u041c' # 0x008c -> CYRILLIC CAPITAL LETTER EM - '\u041d' # 0x008d -> CYRILLIC CAPITAL LETTER EN - '\u041e' # 0x008e -> CYRILLIC CAPITAL LETTER O - '\u041f' # 0x008f -> CYRILLIC CAPITAL LETTER PE - '\u0420' # 0x0090 -> CYRILLIC CAPITAL LETTER ER - '\u0421' # 0x0091 -> CYRILLIC CAPITAL LETTER ES - '\u0422' # 0x0092 -> CYRILLIC CAPITAL LETTER TE - '\u0423' # 0x0093 -> CYRILLIC CAPITAL LETTER U - '\u0424' # 0x0094 -> CYRILLIC CAPITAL LETTER EF - '\u0425' # 0x0095 -> CYRILLIC CAPITAL LETTER HA - '\u0426' # 0x0096 -> CYRILLIC CAPITAL LETTER TSE - '\u0427' # 0x0097 -> CYRILLIC CAPITAL LETTER CHE - '\u0428' # 0x0098 -> CYRILLIC CAPITAL LETTER SHA - '\u0429' # 0x0099 -> CYRILLIC CAPITAL LETTER SHCHA - '\u042a' # 0x009a -> CYRILLIC CAPITAL LETTER HARD SIGN - '\u042b' # 0x009b -> CYRILLIC CAPITAL LETTER YERU - '\u042c' # 0x009c -> CYRILLIC CAPITAL LETTER SOFT SIGN - '\u042d' # 0x009d -> CYRILLIC CAPITAL LETTER E - '\u042e' # 0x009e -> CYRILLIC CAPITAL LETTER YU - '\u042f' # 0x009f -> CYRILLIC CAPITAL LETTER YA - '\u0430' # 0x00a0 -> CYRILLIC SMALL LETTER A - '\u0431' # 0x00a1 -> CYRILLIC SMALL LETTER BE - '\u0432' # 0x00a2 -> CYRILLIC SMALL LETTER VE - '\u0433' # 0x00a3 -> CYRILLIC SMALL LETTER GHE - '\u0434' # 0x00a4 -> CYRILLIC SMALL LETTER DE - '\u0435' # 0x00a5 -> CYRILLIC SMALL LETTER IE - '\u0436' # 0x00a6 -> CYRILLIC SMALL LETTER ZHE - '\u0437' # 0x00a7 -> CYRILLIC SMALL LETTER ZE - '\u0438' # 0x00a8 -> CYRILLIC SMALL LETTER I - '\u0439' # 0x00a9 -> CYRILLIC SMALL LETTER SHORT I - '\u043a' # 0x00aa -> CYRILLIC SMALL LETTER KA - '\u043b' # 0x00ab -> CYRILLIC SMALL LETTER EL - '\u043c' # 0x00ac -> CYRILLIC SMALL LETTER EM - '\u043d' # 0x00ad -> CYRILLIC SMALL LETTER EN - '\u043e' # 0x00ae -> CYRILLIC SMALL LETTER O - '\u043f' # 0x00af -> CYRILLIC SMALL LETTER PE - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u258c' # 0x00dd -> LEFT HALF BLOCK - '\u2590' # 0x00de -> RIGHT HALF BLOCK - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\u0440' # 0x00e0 -> CYRILLIC SMALL LETTER ER - '\u0441' # 0x00e1 -> CYRILLIC SMALL LETTER ES - '\u0442' # 0x00e2 -> CYRILLIC SMALL LETTER TE - '\u0443' # 0x00e3 -> CYRILLIC SMALL LETTER U - '\u0444' # 0x00e4 -> CYRILLIC SMALL LETTER EF - '\u0445' # 0x00e5 -> CYRILLIC SMALL LETTER HA - '\u0446' # 0x00e6 -> CYRILLIC SMALL LETTER TSE - '\u0447' # 0x00e7 -> CYRILLIC SMALL LETTER CHE - '\u0448' # 0x00e8 -> CYRILLIC SMALL LETTER SHA - '\u0449' # 0x00e9 -> CYRILLIC SMALL LETTER SHCHA - '\u044a' # 0x00ea -> CYRILLIC SMALL LETTER HARD SIGN - '\u044b' # 0x00eb -> CYRILLIC SMALL LETTER YERU - '\u044c' # 0x00ec -> CYRILLIC SMALL LETTER SOFT SIGN - '\u044d' # 0x00ed -> CYRILLIC SMALL LETTER E - '\u044e' # 0x00ee -> CYRILLIC SMALL LETTER YU - '\u044f' # 0x00ef -> CYRILLIC SMALL LETTER YA - '\u0401' # 0x00f0 -> CYRILLIC CAPITAL LETTER IO - '\u0451' # 0x00f1 -> CYRILLIC SMALL LETTER IO - '\u0404' # 0x00f2 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE - '\u0454' # 0x00f3 -> CYRILLIC SMALL LETTER UKRAINIAN IE - '\u0407' # 0x00f4 -> CYRILLIC CAPITAL LETTER YI - '\u0457' # 0x00f5 -> CYRILLIC SMALL LETTER YI - '\u040e' # 0x00f6 -> CYRILLIC CAPITAL LETTER SHORT U - '\u045e' # 0x00f7 -> CYRILLIC SMALL LETTER SHORT U - '\xb0' # 0x00f8 -> DEGREE SIGN - '\u2219' # 0x00f9 -> BULLET OPERATOR - '\xb7' # 0x00fa -> MIDDLE DOT - '\u221a' # 0x00fb -> SQUARE ROOT - '\u2116' # 0x00fc -> NUMERO SIGN - '\xa4' # 0x00fd -> CURRENCY SIGN - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a4: 0x00fd, # CURRENCY SIGN - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b7: 0x00fa, # MIDDLE DOT - 0x0401: 0x00f0, # CYRILLIC CAPITAL LETTER IO - 0x0404: 0x00f2, # CYRILLIC CAPITAL LETTER UKRAINIAN IE - 0x0407: 0x00f4, # CYRILLIC CAPITAL LETTER YI - 0x040e: 0x00f6, # CYRILLIC CAPITAL LETTER SHORT U - 0x0410: 0x0080, # CYRILLIC CAPITAL LETTER A - 0x0411: 0x0081, # CYRILLIC CAPITAL LETTER BE - 0x0412: 0x0082, # CYRILLIC CAPITAL LETTER VE - 0x0413: 0x0083, # CYRILLIC CAPITAL LETTER GHE - 0x0414: 0x0084, # CYRILLIC CAPITAL LETTER DE - 0x0415: 0x0085, # CYRILLIC CAPITAL LETTER IE - 0x0416: 0x0086, # CYRILLIC CAPITAL LETTER ZHE - 0x0417: 0x0087, # CYRILLIC CAPITAL LETTER ZE - 0x0418: 0x0088, # CYRILLIC CAPITAL LETTER I - 0x0419: 0x0089, # CYRILLIC CAPITAL LETTER SHORT I - 0x041a: 0x008a, # CYRILLIC CAPITAL LETTER KA - 0x041b: 0x008b, # CYRILLIC CAPITAL LETTER EL - 0x041c: 0x008c, # CYRILLIC CAPITAL LETTER EM - 0x041d: 0x008d, # CYRILLIC CAPITAL LETTER EN - 0x041e: 0x008e, # CYRILLIC CAPITAL LETTER O - 0x041f: 0x008f, # CYRILLIC CAPITAL LETTER PE - 0x0420: 0x0090, # CYRILLIC CAPITAL LETTER ER - 0x0421: 0x0091, # CYRILLIC CAPITAL LETTER ES - 0x0422: 0x0092, # CYRILLIC CAPITAL LETTER TE - 0x0423: 0x0093, # CYRILLIC CAPITAL LETTER U - 0x0424: 0x0094, # CYRILLIC CAPITAL LETTER EF - 0x0425: 0x0095, # CYRILLIC CAPITAL LETTER HA - 0x0426: 0x0096, # CYRILLIC CAPITAL LETTER TSE - 0x0427: 0x0097, # CYRILLIC CAPITAL LETTER CHE - 0x0428: 0x0098, # CYRILLIC CAPITAL LETTER SHA - 0x0429: 0x0099, # CYRILLIC CAPITAL LETTER SHCHA - 0x042a: 0x009a, # CYRILLIC CAPITAL LETTER HARD SIGN - 0x042b: 0x009b, # CYRILLIC CAPITAL LETTER YERU - 0x042c: 0x009c, # CYRILLIC CAPITAL LETTER SOFT SIGN - 0x042d: 0x009d, # CYRILLIC CAPITAL LETTER E - 0x042e: 0x009e, # CYRILLIC CAPITAL LETTER YU - 0x042f: 0x009f, # CYRILLIC CAPITAL LETTER YA - 0x0430: 0x00a0, # CYRILLIC SMALL LETTER A - 0x0431: 0x00a1, # CYRILLIC SMALL LETTER BE - 0x0432: 0x00a2, # CYRILLIC SMALL LETTER VE - 0x0433: 0x00a3, # CYRILLIC SMALL LETTER GHE - 0x0434: 0x00a4, # CYRILLIC SMALL LETTER DE - 0x0435: 0x00a5, # CYRILLIC SMALL LETTER IE - 0x0436: 0x00a6, # CYRILLIC SMALL LETTER ZHE - 0x0437: 0x00a7, # CYRILLIC SMALL LETTER ZE - 0x0438: 0x00a8, # CYRILLIC SMALL LETTER I - 0x0439: 0x00a9, # CYRILLIC SMALL LETTER SHORT I - 0x043a: 0x00aa, # CYRILLIC SMALL LETTER KA - 0x043b: 0x00ab, # CYRILLIC SMALL LETTER EL - 0x043c: 0x00ac, # CYRILLIC SMALL LETTER EM - 0x043d: 0x00ad, # CYRILLIC SMALL LETTER EN - 0x043e: 0x00ae, # CYRILLIC SMALL LETTER O - 0x043f: 0x00af, # CYRILLIC SMALL LETTER PE - 0x0440: 0x00e0, # CYRILLIC SMALL LETTER ER - 0x0441: 0x00e1, # CYRILLIC SMALL LETTER ES - 0x0442: 0x00e2, # CYRILLIC SMALL LETTER TE - 0x0443: 0x00e3, # CYRILLIC SMALL LETTER U - 0x0444: 0x00e4, # CYRILLIC SMALL LETTER EF - 0x0445: 0x00e5, # CYRILLIC SMALL LETTER HA - 0x0446: 0x00e6, # CYRILLIC SMALL LETTER TSE - 0x0447: 0x00e7, # CYRILLIC SMALL LETTER CHE - 0x0448: 0x00e8, # CYRILLIC SMALL LETTER SHA - 0x0449: 0x00e9, # CYRILLIC SMALL LETTER SHCHA - 0x044a: 0x00ea, # CYRILLIC SMALL LETTER HARD SIGN - 0x044b: 0x00eb, # CYRILLIC SMALL LETTER YERU - 0x044c: 0x00ec, # CYRILLIC SMALL LETTER SOFT SIGN - 0x044d: 0x00ed, # CYRILLIC SMALL LETTER E - 0x044e: 0x00ee, # CYRILLIC SMALL LETTER YU - 0x044f: 0x00ef, # CYRILLIC SMALL LETTER YA - 0x0451: 0x00f1, # CYRILLIC SMALL LETTER IO - 0x0454: 0x00f3, # CYRILLIC SMALL LETTER UKRAINIAN IE - 0x0457: 0x00f5, # CYRILLIC SMALL LETTER YI - 0x045e: 0x00f7, # CYRILLIC SMALL LETTER SHORT U - 0x2116: 0x00fc, # NUMERO SIGN - 0x2219: 0x00f9, # BULLET OPERATOR - 0x221a: 0x00fb, # SQUARE ROOT - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x258c: 0x00dd, # LEFT HALF BLOCK - 0x2590: 0x00de, # RIGHT HALF BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp869.py b/python/Lib/encodings/cp869.py deleted file mode 100644 index a7b7889..0000000 --- a/python/Lib/encodings/cp869.py +++ /dev/null @@ -1,689 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP869.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp869', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: None, # UNDEFINED - 0x0081: None, # UNDEFINED - 0x0082: None, # UNDEFINED - 0x0083: None, # UNDEFINED - 0x0084: None, # UNDEFINED - 0x0085: None, # UNDEFINED - 0x0086: 0x0386, # GREEK CAPITAL LETTER ALPHA WITH TONOS - 0x0087: None, # UNDEFINED - 0x0088: 0x00b7, # MIDDLE DOT - 0x0089: 0x00ac, # NOT SIGN - 0x008a: 0x00a6, # BROKEN BAR - 0x008b: 0x2018, # LEFT SINGLE QUOTATION MARK - 0x008c: 0x2019, # RIGHT SINGLE QUOTATION MARK - 0x008d: 0x0388, # GREEK CAPITAL LETTER EPSILON WITH TONOS - 0x008e: 0x2015, # HORIZONTAL BAR - 0x008f: 0x0389, # GREEK CAPITAL LETTER ETA WITH TONOS - 0x0090: 0x038a, # GREEK CAPITAL LETTER IOTA WITH TONOS - 0x0091: 0x03aa, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - 0x0092: 0x038c, # GREEK CAPITAL LETTER OMICRON WITH TONOS - 0x0093: None, # UNDEFINED - 0x0094: None, # UNDEFINED - 0x0095: 0x038e, # GREEK CAPITAL LETTER UPSILON WITH TONOS - 0x0096: 0x03ab, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - 0x0097: 0x00a9, # COPYRIGHT SIGN - 0x0098: 0x038f, # GREEK CAPITAL LETTER OMEGA WITH TONOS - 0x0099: 0x00b2, # SUPERSCRIPT TWO - 0x009a: 0x00b3, # SUPERSCRIPT THREE - 0x009b: 0x03ac, # GREEK SMALL LETTER ALPHA WITH TONOS - 0x009c: 0x00a3, # POUND SIGN - 0x009d: 0x03ad, # GREEK SMALL LETTER EPSILON WITH TONOS - 0x009e: 0x03ae, # GREEK SMALL LETTER ETA WITH TONOS - 0x009f: 0x03af, # GREEK SMALL LETTER IOTA WITH TONOS - 0x00a0: 0x03ca, # GREEK SMALL LETTER IOTA WITH DIALYTIKA - 0x00a1: 0x0390, # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - 0x00a2: 0x03cc, # GREEK SMALL LETTER OMICRON WITH TONOS - 0x00a3: 0x03cd, # GREEK SMALL LETTER UPSILON WITH TONOS - 0x00a4: 0x0391, # GREEK CAPITAL LETTER ALPHA - 0x00a5: 0x0392, # GREEK CAPITAL LETTER BETA - 0x00a6: 0x0393, # GREEK CAPITAL LETTER GAMMA - 0x00a7: 0x0394, # GREEK CAPITAL LETTER DELTA - 0x00a8: 0x0395, # GREEK CAPITAL LETTER EPSILON - 0x00a9: 0x0396, # GREEK CAPITAL LETTER ZETA - 0x00aa: 0x0397, # GREEK CAPITAL LETTER ETA - 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF - 0x00ac: 0x0398, # GREEK CAPITAL LETTER THETA - 0x00ad: 0x0399, # GREEK CAPITAL LETTER IOTA - 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00b0: 0x2591, # LIGHT SHADE - 0x00b1: 0x2592, # MEDIUM SHADE - 0x00b2: 0x2593, # DARK SHADE - 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL - 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x00b5: 0x039a, # GREEK CAPITAL LETTER KAPPA - 0x00b6: 0x039b, # GREEK CAPITAL LETTER LAMDA - 0x00b7: 0x039c, # GREEK CAPITAL LETTER MU - 0x00b8: 0x039d, # GREEK CAPITAL LETTER NU - 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL - 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x00bd: 0x039e, # GREEK CAPITAL LETTER XI - 0x00be: 0x039f, # GREEK CAPITAL LETTER OMICRON - 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL - 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x00c6: 0x03a0, # GREEK CAPITAL LETTER PI - 0x00c7: 0x03a1, # GREEK CAPITAL LETTER RHO - 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x00cf: 0x03a3, # GREEK CAPITAL LETTER SIGMA - 0x00d0: 0x03a4, # GREEK CAPITAL LETTER TAU - 0x00d1: 0x03a5, # GREEK CAPITAL LETTER UPSILON - 0x00d2: 0x03a6, # GREEK CAPITAL LETTER PHI - 0x00d3: 0x03a7, # GREEK CAPITAL LETTER CHI - 0x00d4: 0x03a8, # GREEK CAPITAL LETTER PSI - 0x00d5: 0x03a9, # GREEK CAPITAL LETTER OMEGA - 0x00d6: 0x03b1, # GREEK SMALL LETTER ALPHA - 0x00d7: 0x03b2, # GREEK SMALL LETTER BETA - 0x00d8: 0x03b3, # GREEK SMALL LETTER GAMMA - 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT - 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x00db: 0x2588, # FULL BLOCK - 0x00dc: 0x2584, # LOWER HALF BLOCK - 0x00dd: 0x03b4, # GREEK SMALL LETTER DELTA - 0x00de: 0x03b5, # GREEK SMALL LETTER EPSILON - 0x00df: 0x2580, # UPPER HALF BLOCK - 0x00e0: 0x03b6, # GREEK SMALL LETTER ZETA - 0x00e1: 0x03b7, # GREEK SMALL LETTER ETA - 0x00e2: 0x03b8, # GREEK SMALL LETTER THETA - 0x00e3: 0x03b9, # GREEK SMALL LETTER IOTA - 0x00e4: 0x03ba, # GREEK SMALL LETTER KAPPA - 0x00e5: 0x03bb, # GREEK SMALL LETTER LAMDA - 0x00e6: 0x03bc, # GREEK SMALL LETTER MU - 0x00e7: 0x03bd, # GREEK SMALL LETTER NU - 0x00e8: 0x03be, # GREEK SMALL LETTER XI - 0x00e9: 0x03bf, # GREEK SMALL LETTER OMICRON - 0x00ea: 0x03c0, # GREEK SMALL LETTER PI - 0x00eb: 0x03c1, # GREEK SMALL LETTER RHO - 0x00ec: 0x03c3, # GREEK SMALL LETTER SIGMA - 0x00ed: 0x03c2, # GREEK SMALL LETTER FINAL SIGMA - 0x00ee: 0x03c4, # GREEK SMALL LETTER TAU - 0x00ef: 0x0384, # GREEK TONOS - 0x00f0: 0x00ad, # SOFT HYPHEN - 0x00f1: 0x00b1, # PLUS-MINUS SIGN - 0x00f2: 0x03c5, # GREEK SMALL LETTER UPSILON - 0x00f3: 0x03c6, # GREEK SMALL LETTER PHI - 0x00f4: 0x03c7, # GREEK SMALL LETTER CHI - 0x00f5: 0x00a7, # SECTION SIGN - 0x00f6: 0x03c8, # GREEK SMALL LETTER PSI - 0x00f7: 0x0385, # GREEK DIALYTIKA TONOS - 0x00f8: 0x00b0, # DEGREE SIGN - 0x00f9: 0x00a8, # DIAERESIS - 0x00fa: 0x03c9, # GREEK SMALL LETTER OMEGA - 0x00fb: 0x03cb, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA - 0x00fc: 0x03b0, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - 0x00fd: 0x03ce, # GREEK SMALL LETTER OMEGA WITH TONOS - 0x00fe: 0x25a0, # BLACK SQUARE - 0x00ff: 0x00a0, # NO-BREAK SPACE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> NULL - '\x01' # 0x0001 -> START OF HEADING - '\x02' # 0x0002 -> START OF TEXT - '\x03' # 0x0003 -> END OF TEXT - '\x04' # 0x0004 -> END OF TRANSMISSION - '\x05' # 0x0005 -> ENQUIRY - '\x06' # 0x0006 -> ACKNOWLEDGE - '\x07' # 0x0007 -> BELL - '\x08' # 0x0008 -> BACKSPACE - '\t' # 0x0009 -> HORIZONTAL TABULATION - '\n' # 0x000a -> LINE FEED - '\x0b' # 0x000b -> VERTICAL TABULATION - '\x0c' # 0x000c -> FORM FEED - '\r' # 0x000d -> CARRIAGE RETURN - '\x0e' # 0x000e -> SHIFT OUT - '\x0f' # 0x000f -> SHIFT IN - '\x10' # 0x0010 -> DATA LINK ESCAPE - '\x11' # 0x0011 -> DEVICE CONTROL ONE - '\x12' # 0x0012 -> DEVICE CONTROL TWO - '\x13' # 0x0013 -> DEVICE CONTROL THREE - '\x14' # 0x0014 -> DEVICE CONTROL FOUR - '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x0016 -> SYNCHRONOUS IDLE - '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK - '\x18' # 0x0018 -> CANCEL - '\x19' # 0x0019 -> END OF MEDIUM - '\x1a' # 0x001a -> SUBSTITUTE - '\x1b' # 0x001b -> ESCAPE - '\x1c' # 0x001c -> FILE SEPARATOR - '\x1d' # 0x001d -> GROUP SEPARATOR - '\x1e' # 0x001e -> RECORD SEPARATOR - '\x1f' # 0x001f -> UNIT SEPARATOR - ' ' # 0x0020 -> SPACE - '!' # 0x0021 -> EXCLAMATION MARK - '"' # 0x0022 -> QUOTATION MARK - '#' # 0x0023 -> NUMBER SIGN - '$' # 0x0024 -> DOLLAR SIGN - '%' # 0x0025 -> PERCENT SIGN - '&' # 0x0026 -> AMPERSAND - "'" # 0x0027 -> APOSTROPHE - '(' # 0x0028 -> LEFT PARENTHESIS - ')' # 0x0029 -> RIGHT PARENTHESIS - '*' # 0x002a -> ASTERISK - '+' # 0x002b -> PLUS SIGN - ',' # 0x002c -> COMMA - '-' # 0x002d -> HYPHEN-MINUS - '.' # 0x002e -> FULL STOP - '/' # 0x002f -> SOLIDUS - '0' # 0x0030 -> DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE - '2' # 0x0032 -> DIGIT TWO - '3' # 0x0033 -> DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE - ':' # 0x003a -> COLON - ';' # 0x003b -> SEMICOLON - '<' # 0x003c -> LESS-THAN SIGN - '=' # 0x003d -> EQUALS SIGN - '>' # 0x003e -> GREATER-THAN SIGN - '?' # 0x003f -> QUESTION MARK - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET - '\\' # 0x005c -> REVERSE SOLIDUS - ']' # 0x005d -> RIGHT SQUARE BRACKET - '^' # 0x005e -> CIRCUMFLEX ACCENT - '_' # 0x005f -> LOW LINE - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET - '|' # 0x007c -> VERTICAL LINE - '}' # 0x007d -> RIGHT CURLY BRACKET - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> DELETE - '\ufffe' # 0x0080 -> UNDEFINED - '\ufffe' # 0x0081 -> UNDEFINED - '\ufffe' # 0x0082 -> UNDEFINED - '\ufffe' # 0x0083 -> UNDEFINED - '\ufffe' # 0x0084 -> UNDEFINED - '\ufffe' # 0x0085 -> UNDEFINED - '\u0386' # 0x0086 -> GREEK CAPITAL LETTER ALPHA WITH TONOS - '\ufffe' # 0x0087 -> UNDEFINED - '\xb7' # 0x0088 -> MIDDLE DOT - '\xac' # 0x0089 -> NOT SIGN - '\xa6' # 0x008a -> BROKEN BAR - '\u2018' # 0x008b -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x008c -> RIGHT SINGLE QUOTATION MARK - '\u0388' # 0x008d -> GREEK CAPITAL LETTER EPSILON WITH TONOS - '\u2015' # 0x008e -> HORIZONTAL BAR - '\u0389' # 0x008f -> GREEK CAPITAL LETTER ETA WITH TONOS - '\u038a' # 0x0090 -> GREEK CAPITAL LETTER IOTA WITH TONOS - '\u03aa' # 0x0091 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - '\u038c' # 0x0092 -> GREEK CAPITAL LETTER OMICRON WITH TONOS - '\ufffe' # 0x0093 -> UNDEFINED - '\ufffe' # 0x0094 -> UNDEFINED - '\u038e' # 0x0095 -> GREEK CAPITAL LETTER UPSILON WITH TONOS - '\u03ab' # 0x0096 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - '\xa9' # 0x0097 -> COPYRIGHT SIGN - '\u038f' # 0x0098 -> GREEK CAPITAL LETTER OMEGA WITH TONOS - '\xb2' # 0x0099 -> SUPERSCRIPT TWO - '\xb3' # 0x009a -> SUPERSCRIPT THREE - '\u03ac' # 0x009b -> GREEK SMALL LETTER ALPHA WITH TONOS - '\xa3' # 0x009c -> POUND SIGN - '\u03ad' # 0x009d -> GREEK SMALL LETTER EPSILON WITH TONOS - '\u03ae' # 0x009e -> GREEK SMALL LETTER ETA WITH TONOS - '\u03af' # 0x009f -> GREEK SMALL LETTER IOTA WITH TONOS - '\u03ca' # 0x00a0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA - '\u0390' # 0x00a1 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - '\u03cc' # 0x00a2 -> GREEK SMALL LETTER OMICRON WITH TONOS - '\u03cd' # 0x00a3 -> GREEK SMALL LETTER UPSILON WITH TONOS - '\u0391' # 0x00a4 -> GREEK CAPITAL LETTER ALPHA - '\u0392' # 0x00a5 -> GREEK CAPITAL LETTER BETA - '\u0393' # 0x00a6 -> GREEK CAPITAL LETTER GAMMA - '\u0394' # 0x00a7 -> GREEK CAPITAL LETTER DELTA - '\u0395' # 0x00a8 -> GREEK CAPITAL LETTER EPSILON - '\u0396' # 0x00a9 -> GREEK CAPITAL LETTER ZETA - '\u0397' # 0x00aa -> GREEK CAPITAL LETTER ETA - '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF - '\u0398' # 0x00ac -> GREEK CAPITAL LETTER THETA - '\u0399' # 0x00ad -> GREEK CAPITAL LETTER IOTA - '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2591' # 0x00b0 -> LIGHT SHADE - '\u2592' # 0x00b1 -> MEDIUM SHADE - '\u2593' # 0x00b2 -> DARK SHADE - '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL - '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u039a' # 0x00b5 -> GREEK CAPITAL LETTER KAPPA - '\u039b' # 0x00b6 -> GREEK CAPITAL LETTER LAMDA - '\u039c' # 0x00b7 -> GREEK CAPITAL LETTER MU - '\u039d' # 0x00b8 -> GREEK CAPITAL LETTER NU - '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL - '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u039e' # 0x00bd -> GREEK CAPITAL LETTER XI - '\u039f' # 0x00be -> GREEK CAPITAL LETTER OMICRON - '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u03a0' # 0x00c6 -> GREEK CAPITAL LETTER PI - '\u03a1' # 0x00c7 -> GREEK CAPITAL LETTER RHO - '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\u03a3' # 0x00cf -> GREEK CAPITAL LETTER SIGMA - '\u03a4' # 0x00d0 -> GREEK CAPITAL LETTER TAU - '\u03a5' # 0x00d1 -> GREEK CAPITAL LETTER UPSILON - '\u03a6' # 0x00d2 -> GREEK CAPITAL LETTER PHI - '\u03a7' # 0x00d3 -> GREEK CAPITAL LETTER CHI - '\u03a8' # 0x00d4 -> GREEK CAPITAL LETTER PSI - '\u03a9' # 0x00d5 -> GREEK CAPITAL LETTER OMEGA - '\u03b1' # 0x00d6 -> GREEK SMALL LETTER ALPHA - '\u03b2' # 0x00d7 -> GREEK SMALL LETTER BETA - '\u03b3' # 0x00d8 -> GREEK SMALL LETTER GAMMA - '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2588' # 0x00db -> FULL BLOCK - '\u2584' # 0x00dc -> LOWER HALF BLOCK - '\u03b4' # 0x00dd -> GREEK SMALL LETTER DELTA - '\u03b5' # 0x00de -> GREEK SMALL LETTER EPSILON - '\u2580' # 0x00df -> UPPER HALF BLOCK - '\u03b6' # 0x00e0 -> GREEK SMALL LETTER ZETA - '\u03b7' # 0x00e1 -> GREEK SMALL LETTER ETA - '\u03b8' # 0x00e2 -> GREEK SMALL LETTER THETA - '\u03b9' # 0x00e3 -> GREEK SMALL LETTER IOTA - '\u03ba' # 0x00e4 -> GREEK SMALL LETTER KAPPA - '\u03bb' # 0x00e5 -> GREEK SMALL LETTER LAMDA - '\u03bc' # 0x00e6 -> GREEK SMALL LETTER MU - '\u03bd' # 0x00e7 -> GREEK SMALL LETTER NU - '\u03be' # 0x00e8 -> GREEK SMALL LETTER XI - '\u03bf' # 0x00e9 -> GREEK SMALL LETTER OMICRON - '\u03c0' # 0x00ea -> GREEK SMALL LETTER PI - '\u03c1' # 0x00eb -> GREEK SMALL LETTER RHO - '\u03c3' # 0x00ec -> GREEK SMALL LETTER SIGMA - '\u03c2' # 0x00ed -> GREEK SMALL LETTER FINAL SIGMA - '\u03c4' # 0x00ee -> GREEK SMALL LETTER TAU - '\u0384' # 0x00ef -> GREEK TONOS - '\xad' # 0x00f0 -> SOFT HYPHEN - '\xb1' # 0x00f1 -> PLUS-MINUS SIGN - '\u03c5' # 0x00f2 -> GREEK SMALL LETTER UPSILON - '\u03c6' # 0x00f3 -> GREEK SMALL LETTER PHI - '\u03c7' # 0x00f4 -> GREEK SMALL LETTER CHI - '\xa7' # 0x00f5 -> SECTION SIGN - '\u03c8' # 0x00f6 -> GREEK SMALL LETTER PSI - '\u0385' # 0x00f7 -> GREEK DIALYTIKA TONOS - '\xb0' # 0x00f8 -> DEGREE SIGN - '\xa8' # 0x00f9 -> DIAERESIS - '\u03c9' # 0x00fa -> GREEK SMALL LETTER OMEGA - '\u03cb' # 0x00fb -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA - '\u03b0' # 0x00fc -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - '\u03ce' # 0x00fd -> GREEK SMALL LETTER OMEGA WITH TONOS - '\u25a0' # 0x00fe -> BLACK SQUARE - '\xa0' # 0x00ff -> NO-BREAK SPACE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # NULL - 0x0001: 0x0001, # START OF HEADING - 0x0002: 0x0002, # START OF TEXT - 0x0003: 0x0003, # END OF TEXT - 0x0004: 0x0004, # END OF TRANSMISSION - 0x0005: 0x0005, # ENQUIRY - 0x0006: 0x0006, # ACKNOWLEDGE - 0x0007: 0x0007, # BELL - 0x0008: 0x0008, # BACKSPACE - 0x0009: 0x0009, # HORIZONTAL TABULATION - 0x000a: 0x000a, # LINE FEED - 0x000b: 0x000b, # VERTICAL TABULATION - 0x000c: 0x000c, # FORM FEED - 0x000d: 0x000d, # CARRIAGE RETURN - 0x000e: 0x000e, # SHIFT OUT - 0x000f: 0x000f, # SHIFT IN - 0x0010: 0x0010, # DATA LINK ESCAPE - 0x0011: 0x0011, # DEVICE CONTROL ONE - 0x0012: 0x0012, # DEVICE CONTROL TWO - 0x0013: 0x0013, # DEVICE CONTROL THREE - 0x0014: 0x0014, # DEVICE CONTROL FOUR - 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE - 0x0016: 0x0016, # SYNCHRONOUS IDLE - 0x0017: 0x0017, # END OF TRANSMISSION BLOCK - 0x0018: 0x0018, # CANCEL - 0x0019: 0x0019, # END OF MEDIUM - 0x001a: 0x001a, # SUBSTITUTE - 0x001b: 0x001b, # ESCAPE - 0x001c: 0x001c, # FILE SEPARATOR - 0x001d: 0x001d, # GROUP SEPARATOR - 0x001e: 0x001e, # RECORD SEPARATOR - 0x001f: 0x001f, # UNIT SEPARATOR - 0x0020: 0x0020, # SPACE - 0x0021: 0x0021, # EXCLAMATION MARK - 0x0022: 0x0022, # QUOTATION MARK - 0x0023: 0x0023, # NUMBER SIGN - 0x0024: 0x0024, # DOLLAR SIGN - 0x0025: 0x0025, # PERCENT SIGN - 0x0026: 0x0026, # AMPERSAND - 0x0027: 0x0027, # APOSTROPHE - 0x0028: 0x0028, # LEFT PARENTHESIS - 0x0029: 0x0029, # RIGHT PARENTHESIS - 0x002a: 0x002a, # ASTERISK - 0x002b: 0x002b, # PLUS SIGN - 0x002c: 0x002c, # COMMA - 0x002d: 0x002d, # HYPHEN-MINUS - 0x002e: 0x002e, # FULL STOP - 0x002f: 0x002f, # SOLIDUS - 0x0030: 0x0030, # DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE - 0x003a: 0x003a, # COLON - 0x003b: 0x003b, # SEMICOLON - 0x003c: 0x003c, # LESS-THAN SIGN - 0x003d: 0x003d, # EQUALS SIGN - 0x003e: 0x003e, # GREATER-THAN SIGN - 0x003f: 0x003f, # QUESTION MARK - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET - 0x005c: 0x005c, # REVERSE SOLIDUS - 0x005d: 0x005d, # RIGHT SQUARE BRACKET - 0x005e: 0x005e, # CIRCUMFLEX ACCENT - 0x005f: 0x005f, # LOW LINE - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET - 0x007c: 0x007c, # VERTICAL LINE - 0x007d: 0x007d, # RIGHT CURLY BRACKET - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # DELETE - 0x00a0: 0x00ff, # NO-BREAK SPACE - 0x00a3: 0x009c, # POUND SIGN - 0x00a6: 0x008a, # BROKEN BAR - 0x00a7: 0x00f5, # SECTION SIGN - 0x00a8: 0x00f9, # DIAERESIS - 0x00a9: 0x0097, # COPYRIGHT SIGN - 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00ac: 0x0089, # NOT SIGN - 0x00ad: 0x00f0, # SOFT HYPHEN - 0x00b0: 0x00f8, # DEGREE SIGN - 0x00b1: 0x00f1, # PLUS-MINUS SIGN - 0x00b2: 0x0099, # SUPERSCRIPT TWO - 0x00b3: 0x009a, # SUPERSCRIPT THREE - 0x00b7: 0x0088, # MIDDLE DOT - 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF - 0x0384: 0x00ef, # GREEK TONOS - 0x0385: 0x00f7, # GREEK DIALYTIKA TONOS - 0x0386: 0x0086, # GREEK CAPITAL LETTER ALPHA WITH TONOS - 0x0388: 0x008d, # GREEK CAPITAL LETTER EPSILON WITH TONOS - 0x0389: 0x008f, # GREEK CAPITAL LETTER ETA WITH TONOS - 0x038a: 0x0090, # GREEK CAPITAL LETTER IOTA WITH TONOS - 0x038c: 0x0092, # GREEK CAPITAL LETTER OMICRON WITH TONOS - 0x038e: 0x0095, # GREEK CAPITAL LETTER UPSILON WITH TONOS - 0x038f: 0x0098, # GREEK CAPITAL LETTER OMEGA WITH TONOS - 0x0390: 0x00a1, # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - 0x0391: 0x00a4, # GREEK CAPITAL LETTER ALPHA - 0x0392: 0x00a5, # GREEK CAPITAL LETTER BETA - 0x0393: 0x00a6, # GREEK CAPITAL LETTER GAMMA - 0x0394: 0x00a7, # GREEK CAPITAL LETTER DELTA - 0x0395: 0x00a8, # GREEK CAPITAL LETTER EPSILON - 0x0396: 0x00a9, # GREEK CAPITAL LETTER ZETA - 0x0397: 0x00aa, # GREEK CAPITAL LETTER ETA - 0x0398: 0x00ac, # GREEK CAPITAL LETTER THETA - 0x0399: 0x00ad, # GREEK CAPITAL LETTER IOTA - 0x039a: 0x00b5, # GREEK CAPITAL LETTER KAPPA - 0x039b: 0x00b6, # GREEK CAPITAL LETTER LAMDA - 0x039c: 0x00b7, # GREEK CAPITAL LETTER MU - 0x039d: 0x00b8, # GREEK CAPITAL LETTER NU - 0x039e: 0x00bd, # GREEK CAPITAL LETTER XI - 0x039f: 0x00be, # GREEK CAPITAL LETTER OMICRON - 0x03a0: 0x00c6, # GREEK CAPITAL LETTER PI - 0x03a1: 0x00c7, # GREEK CAPITAL LETTER RHO - 0x03a3: 0x00cf, # GREEK CAPITAL LETTER SIGMA - 0x03a4: 0x00d0, # GREEK CAPITAL LETTER TAU - 0x03a5: 0x00d1, # GREEK CAPITAL LETTER UPSILON - 0x03a6: 0x00d2, # GREEK CAPITAL LETTER PHI - 0x03a7: 0x00d3, # GREEK CAPITAL LETTER CHI - 0x03a8: 0x00d4, # GREEK CAPITAL LETTER PSI - 0x03a9: 0x00d5, # GREEK CAPITAL LETTER OMEGA - 0x03aa: 0x0091, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - 0x03ab: 0x0096, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - 0x03ac: 0x009b, # GREEK SMALL LETTER ALPHA WITH TONOS - 0x03ad: 0x009d, # GREEK SMALL LETTER EPSILON WITH TONOS - 0x03ae: 0x009e, # GREEK SMALL LETTER ETA WITH TONOS - 0x03af: 0x009f, # GREEK SMALL LETTER IOTA WITH TONOS - 0x03b0: 0x00fc, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - 0x03b1: 0x00d6, # GREEK SMALL LETTER ALPHA - 0x03b2: 0x00d7, # GREEK SMALL LETTER BETA - 0x03b3: 0x00d8, # GREEK SMALL LETTER GAMMA - 0x03b4: 0x00dd, # GREEK SMALL LETTER DELTA - 0x03b5: 0x00de, # GREEK SMALL LETTER EPSILON - 0x03b6: 0x00e0, # GREEK SMALL LETTER ZETA - 0x03b7: 0x00e1, # GREEK SMALL LETTER ETA - 0x03b8: 0x00e2, # GREEK SMALL LETTER THETA - 0x03b9: 0x00e3, # GREEK SMALL LETTER IOTA - 0x03ba: 0x00e4, # GREEK SMALL LETTER KAPPA - 0x03bb: 0x00e5, # GREEK SMALL LETTER LAMDA - 0x03bc: 0x00e6, # GREEK SMALL LETTER MU - 0x03bd: 0x00e7, # GREEK SMALL LETTER NU - 0x03be: 0x00e8, # GREEK SMALL LETTER XI - 0x03bf: 0x00e9, # GREEK SMALL LETTER OMICRON - 0x03c0: 0x00ea, # GREEK SMALL LETTER PI - 0x03c1: 0x00eb, # GREEK SMALL LETTER RHO - 0x03c2: 0x00ed, # GREEK SMALL LETTER FINAL SIGMA - 0x03c3: 0x00ec, # GREEK SMALL LETTER SIGMA - 0x03c4: 0x00ee, # GREEK SMALL LETTER TAU - 0x03c5: 0x00f2, # GREEK SMALL LETTER UPSILON - 0x03c6: 0x00f3, # GREEK SMALL LETTER PHI - 0x03c7: 0x00f4, # GREEK SMALL LETTER CHI - 0x03c8: 0x00f6, # GREEK SMALL LETTER PSI - 0x03c9: 0x00fa, # GREEK SMALL LETTER OMEGA - 0x03ca: 0x00a0, # GREEK SMALL LETTER IOTA WITH DIALYTIKA - 0x03cb: 0x00fb, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA - 0x03cc: 0x00a2, # GREEK SMALL LETTER OMICRON WITH TONOS - 0x03cd: 0x00a3, # GREEK SMALL LETTER UPSILON WITH TONOS - 0x03ce: 0x00fd, # GREEK SMALL LETTER OMEGA WITH TONOS - 0x2015: 0x008e, # HORIZONTAL BAR - 0x2018: 0x008b, # LEFT SINGLE QUOTATION MARK - 0x2019: 0x008c, # RIGHT SINGLE QUOTATION MARK - 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL - 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL - 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT - 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT - 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL - 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL - 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT - 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT - 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2580: 0x00df, # UPPER HALF BLOCK - 0x2584: 0x00dc, # LOWER HALF BLOCK - 0x2588: 0x00db, # FULL BLOCK - 0x2591: 0x00b0, # LIGHT SHADE - 0x2592: 0x00b1, # MEDIUM SHADE - 0x2593: 0x00b2, # DARK SHADE - 0x25a0: 0x00fe, # BLACK SQUARE -} diff --git a/python/Lib/encodings/cp874.py b/python/Lib/encodings/cp874.py deleted file mode 100644 index eb19134..0000000 --- a/python/Lib/encodings/cp874.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp874 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp874', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u20ac' # 0x80 -> EURO SIGN - '\ufffe' # 0x81 -> UNDEFINED - '\ufffe' # 0x82 -> UNDEFINED - '\ufffe' # 0x83 -> UNDEFINED - '\ufffe' # 0x84 -> UNDEFINED - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\ufffe' # 0x86 -> UNDEFINED - '\ufffe' # 0x87 -> UNDEFINED - '\ufffe' # 0x88 -> UNDEFINED - '\ufffe' # 0x89 -> UNDEFINED - '\ufffe' # 0x8A -> UNDEFINED - '\ufffe' # 0x8B -> UNDEFINED - '\ufffe' # 0x8C -> UNDEFINED - '\ufffe' # 0x8D -> UNDEFINED - '\ufffe' # 0x8E -> UNDEFINED - '\ufffe' # 0x8F -> UNDEFINED - '\ufffe' # 0x90 -> UNDEFINED - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\ufffe' # 0x98 -> UNDEFINED - '\ufffe' # 0x99 -> UNDEFINED - '\ufffe' # 0x9A -> UNDEFINED - '\ufffe' # 0x9B -> UNDEFINED - '\ufffe' # 0x9C -> UNDEFINED - '\ufffe' # 0x9D -> UNDEFINED - '\ufffe' # 0x9E -> UNDEFINED - '\ufffe' # 0x9F -> UNDEFINED - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u0e01' # 0xA1 -> THAI CHARACTER KO KAI - '\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI - '\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT - '\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI - '\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON - '\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG - '\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU - '\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN - '\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING - '\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG - '\u0e0b' # 0xAB -> THAI CHARACTER SO SO - '\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE - '\u0e0d' # 0xAD -> THAI CHARACTER YO YING - '\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA - '\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK - '\u0e10' # 0xB0 -> THAI CHARACTER THO THAN - '\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO - '\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO - '\u0e13' # 0xB3 -> THAI CHARACTER NO NEN - '\u0e14' # 0xB4 -> THAI CHARACTER DO DEK - '\u0e15' # 0xB5 -> THAI CHARACTER TO TAO - '\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG - '\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN - '\u0e18' # 0xB8 -> THAI CHARACTER THO THONG - '\u0e19' # 0xB9 -> THAI CHARACTER NO NU - '\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI - '\u0e1b' # 0xBB -> THAI CHARACTER PO PLA - '\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG - '\u0e1d' # 0xBD -> THAI CHARACTER FO FA - '\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN - '\u0e1f' # 0xBF -> THAI CHARACTER FO FAN - '\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO - '\u0e21' # 0xC1 -> THAI CHARACTER MO MA - '\u0e22' # 0xC2 -> THAI CHARACTER YO YAK - '\u0e23' # 0xC3 -> THAI CHARACTER RO RUA - '\u0e24' # 0xC4 -> THAI CHARACTER RU - '\u0e25' # 0xC5 -> THAI CHARACTER LO LING - '\u0e26' # 0xC6 -> THAI CHARACTER LU - '\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN - '\u0e28' # 0xC8 -> THAI CHARACTER SO SALA - '\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI - '\u0e2a' # 0xCA -> THAI CHARACTER SO SUA - '\u0e2b' # 0xCB -> THAI CHARACTER HO HIP - '\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA - '\u0e2d' # 0xCD -> THAI CHARACTER O ANG - '\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK - '\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI - '\u0e30' # 0xD0 -> THAI CHARACTER SARA A - '\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT - '\u0e32' # 0xD2 -> THAI CHARACTER SARA AA - '\u0e33' # 0xD3 -> THAI CHARACTER SARA AM - '\u0e34' # 0xD4 -> THAI CHARACTER SARA I - '\u0e35' # 0xD5 -> THAI CHARACTER SARA II - '\u0e36' # 0xD6 -> THAI CHARACTER SARA UE - '\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE - '\u0e38' # 0xD8 -> THAI CHARACTER SARA U - '\u0e39' # 0xD9 -> THAI CHARACTER SARA UU - '\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU - '\ufffe' # 0xDB -> UNDEFINED - '\ufffe' # 0xDC -> UNDEFINED - '\ufffe' # 0xDD -> UNDEFINED - '\ufffe' # 0xDE -> UNDEFINED - '\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT - '\u0e40' # 0xE0 -> THAI CHARACTER SARA E - '\u0e41' # 0xE1 -> THAI CHARACTER SARA AE - '\u0e42' # 0xE2 -> THAI CHARACTER SARA O - '\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN - '\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI - '\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO - '\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK - '\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU - '\u0e48' # 0xE8 -> THAI CHARACTER MAI EK - '\u0e49' # 0xE9 -> THAI CHARACTER MAI THO - '\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI - '\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA - '\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT - '\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT - '\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN - '\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN - '\u0e50' # 0xF0 -> THAI DIGIT ZERO - '\u0e51' # 0xF1 -> THAI DIGIT ONE - '\u0e52' # 0xF2 -> THAI DIGIT TWO - '\u0e53' # 0xF3 -> THAI DIGIT THREE - '\u0e54' # 0xF4 -> THAI DIGIT FOUR - '\u0e55' # 0xF5 -> THAI DIGIT FIVE - '\u0e56' # 0xF6 -> THAI DIGIT SIX - '\u0e57' # 0xF7 -> THAI DIGIT SEVEN - '\u0e58' # 0xF8 -> THAI DIGIT EIGHT - '\u0e59' # 0xF9 -> THAI DIGIT NINE - '\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU - '\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT - '\ufffe' # 0xFC -> UNDEFINED - '\ufffe' # 0xFD -> UNDEFINED - '\ufffe' # 0xFE -> UNDEFINED - '\ufffe' # 0xFF -> UNDEFINED -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp875.py b/python/Lib/encodings/cp875.py deleted file mode 100644 index 0d7114f..0000000 --- a/python/Lib/encodings/cp875.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec cp875 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP875.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='cp875', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x9c' # 0x04 -> CONTROL - '\t' # 0x05 -> HORIZONTAL TABULATION - '\x86' # 0x06 -> CONTROL - '\x7f' # 0x07 -> DELETE - '\x97' # 0x08 -> CONTROL - '\x8d' # 0x09 -> CONTROL - '\x8e' # 0x0A -> CONTROL - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x9d' # 0x14 -> CONTROL - '\x85' # 0x15 -> CONTROL - '\x08' # 0x16 -> BACKSPACE - '\x87' # 0x17 -> CONTROL - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x92' # 0x1A -> CONTROL - '\x8f' # 0x1B -> CONTROL - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - '\x80' # 0x20 -> CONTROL - '\x81' # 0x21 -> CONTROL - '\x82' # 0x22 -> CONTROL - '\x83' # 0x23 -> CONTROL - '\x84' # 0x24 -> CONTROL - '\n' # 0x25 -> LINE FEED - '\x17' # 0x26 -> END OF TRANSMISSION BLOCK - '\x1b' # 0x27 -> ESCAPE - '\x88' # 0x28 -> CONTROL - '\x89' # 0x29 -> CONTROL - '\x8a' # 0x2A -> CONTROL - '\x8b' # 0x2B -> CONTROL - '\x8c' # 0x2C -> CONTROL - '\x05' # 0x2D -> ENQUIRY - '\x06' # 0x2E -> ACKNOWLEDGE - '\x07' # 0x2F -> BELL - '\x90' # 0x30 -> CONTROL - '\x91' # 0x31 -> CONTROL - '\x16' # 0x32 -> SYNCHRONOUS IDLE - '\x93' # 0x33 -> CONTROL - '\x94' # 0x34 -> CONTROL - '\x95' # 0x35 -> CONTROL - '\x96' # 0x36 -> CONTROL - '\x04' # 0x37 -> END OF TRANSMISSION - '\x98' # 0x38 -> CONTROL - '\x99' # 0x39 -> CONTROL - '\x9a' # 0x3A -> CONTROL - '\x9b' # 0x3B -> CONTROL - '\x14' # 0x3C -> DEVICE CONTROL FOUR - '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE - '\x9e' # 0x3E -> CONTROL - '\x1a' # 0x3F -> SUBSTITUTE - ' ' # 0x40 -> SPACE - '\u0391' # 0x41 -> GREEK CAPITAL LETTER ALPHA - '\u0392' # 0x42 -> GREEK CAPITAL LETTER BETA - '\u0393' # 0x43 -> GREEK CAPITAL LETTER GAMMA - '\u0394' # 0x44 -> GREEK CAPITAL LETTER DELTA - '\u0395' # 0x45 -> GREEK CAPITAL LETTER EPSILON - '\u0396' # 0x46 -> GREEK CAPITAL LETTER ZETA - '\u0397' # 0x47 -> GREEK CAPITAL LETTER ETA - '\u0398' # 0x48 -> GREEK CAPITAL LETTER THETA - '\u0399' # 0x49 -> GREEK CAPITAL LETTER IOTA - '[' # 0x4A -> LEFT SQUARE BRACKET - '.' # 0x4B -> FULL STOP - '<' # 0x4C -> LESS-THAN SIGN - '(' # 0x4D -> LEFT PARENTHESIS - '+' # 0x4E -> PLUS SIGN - '!' # 0x4F -> EXCLAMATION MARK - '&' # 0x50 -> AMPERSAND - '\u039a' # 0x51 -> GREEK CAPITAL LETTER KAPPA - '\u039b' # 0x52 -> GREEK CAPITAL LETTER LAMDA - '\u039c' # 0x53 -> GREEK CAPITAL LETTER MU - '\u039d' # 0x54 -> GREEK CAPITAL LETTER NU - '\u039e' # 0x55 -> GREEK CAPITAL LETTER XI - '\u039f' # 0x56 -> GREEK CAPITAL LETTER OMICRON - '\u03a0' # 0x57 -> GREEK CAPITAL LETTER PI - '\u03a1' # 0x58 -> GREEK CAPITAL LETTER RHO - '\u03a3' # 0x59 -> GREEK CAPITAL LETTER SIGMA - ']' # 0x5A -> RIGHT SQUARE BRACKET - '$' # 0x5B -> DOLLAR SIGN - '*' # 0x5C -> ASTERISK - ')' # 0x5D -> RIGHT PARENTHESIS - ';' # 0x5E -> SEMICOLON - '^' # 0x5F -> CIRCUMFLEX ACCENT - '-' # 0x60 -> HYPHEN-MINUS - '/' # 0x61 -> SOLIDUS - '\u03a4' # 0x62 -> GREEK CAPITAL LETTER TAU - '\u03a5' # 0x63 -> GREEK CAPITAL LETTER UPSILON - '\u03a6' # 0x64 -> GREEK CAPITAL LETTER PHI - '\u03a7' # 0x65 -> GREEK CAPITAL LETTER CHI - '\u03a8' # 0x66 -> GREEK CAPITAL LETTER PSI - '\u03a9' # 0x67 -> GREEK CAPITAL LETTER OMEGA - '\u03aa' # 0x68 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - '\u03ab' # 0x69 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - '|' # 0x6A -> VERTICAL LINE - ',' # 0x6B -> COMMA - '%' # 0x6C -> PERCENT SIGN - '_' # 0x6D -> LOW LINE - '>' # 0x6E -> GREATER-THAN SIGN - '?' # 0x6F -> QUESTION MARK - '\xa8' # 0x70 -> DIAERESIS - '\u0386' # 0x71 -> GREEK CAPITAL LETTER ALPHA WITH TONOS - '\u0388' # 0x72 -> GREEK CAPITAL LETTER EPSILON WITH TONOS - '\u0389' # 0x73 -> GREEK CAPITAL LETTER ETA WITH TONOS - '\xa0' # 0x74 -> NO-BREAK SPACE - '\u038a' # 0x75 -> GREEK CAPITAL LETTER IOTA WITH TONOS - '\u038c' # 0x76 -> GREEK CAPITAL LETTER OMICRON WITH TONOS - '\u038e' # 0x77 -> GREEK CAPITAL LETTER UPSILON WITH TONOS - '\u038f' # 0x78 -> GREEK CAPITAL LETTER OMEGA WITH TONOS - '`' # 0x79 -> GRAVE ACCENT - ':' # 0x7A -> COLON - '#' # 0x7B -> NUMBER SIGN - '@' # 0x7C -> COMMERCIAL AT - "'" # 0x7D -> APOSTROPHE - '=' # 0x7E -> EQUALS SIGN - '"' # 0x7F -> QUOTATION MARK - '\u0385' # 0x80 -> GREEK DIALYTIKA TONOS - 'a' # 0x81 -> LATIN SMALL LETTER A - 'b' # 0x82 -> LATIN SMALL LETTER B - 'c' # 0x83 -> LATIN SMALL LETTER C - 'd' # 0x84 -> LATIN SMALL LETTER D - 'e' # 0x85 -> LATIN SMALL LETTER E - 'f' # 0x86 -> LATIN SMALL LETTER F - 'g' # 0x87 -> LATIN SMALL LETTER G - 'h' # 0x88 -> LATIN SMALL LETTER H - 'i' # 0x89 -> LATIN SMALL LETTER I - '\u03b1' # 0x8A -> GREEK SMALL LETTER ALPHA - '\u03b2' # 0x8B -> GREEK SMALL LETTER BETA - '\u03b3' # 0x8C -> GREEK SMALL LETTER GAMMA - '\u03b4' # 0x8D -> GREEK SMALL LETTER DELTA - '\u03b5' # 0x8E -> GREEK SMALL LETTER EPSILON - '\u03b6' # 0x8F -> GREEK SMALL LETTER ZETA - '\xb0' # 0x90 -> DEGREE SIGN - 'j' # 0x91 -> LATIN SMALL LETTER J - 'k' # 0x92 -> LATIN SMALL LETTER K - 'l' # 0x93 -> LATIN SMALL LETTER L - 'm' # 0x94 -> LATIN SMALL LETTER M - 'n' # 0x95 -> LATIN SMALL LETTER N - 'o' # 0x96 -> LATIN SMALL LETTER O - 'p' # 0x97 -> LATIN SMALL LETTER P - 'q' # 0x98 -> LATIN SMALL LETTER Q - 'r' # 0x99 -> LATIN SMALL LETTER R - '\u03b7' # 0x9A -> GREEK SMALL LETTER ETA - '\u03b8' # 0x9B -> GREEK SMALL LETTER THETA - '\u03b9' # 0x9C -> GREEK SMALL LETTER IOTA - '\u03ba' # 0x9D -> GREEK SMALL LETTER KAPPA - '\u03bb' # 0x9E -> GREEK SMALL LETTER LAMDA - '\u03bc' # 0x9F -> GREEK SMALL LETTER MU - '\xb4' # 0xA0 -> ACUTE ACCENT - '~' # 0xA1 -> TILDE - 's' # 0xA2 -> LATIN SMALL LETTER S - 't' # 0xA3 -> LATIN SMALL LETTER T - 'u' # 0xA4 -> LATIN SMALL LETTER U - 'v' # 0xA5 -> LATIN SMALL LETTER V - 'w' # 0xA6 -> LATIN SMALL LETTER W - 'x' # 0xA7 -> LATIN SMALL LETTER X - 'y' # 0xA8 -> LATIN SMALL LETTER Y - 'z' # 0xA9 -> LATIN SMALL LETTER Z - '\u03bd' # 0xAA -> GREEK SMALL LETTER NU - '\u03be' # 0xAB -> GREEK SMALL LETTER XI - '\u03bf' # 0xAC -> GREEK SMALL LETTER OMICRON - '\u03c0' # 0xAD -> GREEK SMALL LETTER PI - '\u03c1' # 0xAE -> GREEK SMALL LETTER RHO - '\u03c3' # 0xAF -> GREEK SMALL LETTER SIGMA - '\xa3' # 0xB0 -> POUND SIGN - '\u03ac' # 0xB1 -> GREEK SMALL LETTER ALPHA WITH TONOS - '\u03ad' # 0xB2 -> GREEK SMALL LETTER EPSILON WITH TONOS - '\u03ae' # 0xB3 -> GREEK SMALL LETTER ETA WITH TONOS - '\u03ca' # 0xB4 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA - '\u03af' # 0xB5 -> GREEK SMALL LETTER IOTA WITH TONOS - '\u03cc' # 0xB6 -> GREEK SMALL LETTER OMICRON WITH TONOS - '\u03cd' # 0xB7 -> GREEK SMALL LETTER UPSILON WITH TONOS - '\u03cb' # 0xB8 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA - '\u03ce' # 0xB9 -> GREEK SMALL LETTER OMEGA WITH TONOS - '\u03c2' # 0xBA -> GREEK SMALL LETTER FINAL SIGMA - '\u03c4' # 0xBB -> GREEK SMALL LETTER TAU - '\u03c5' # 0xBC -> GREEK SMALL LETTER UPSILON - '\u03c6' # 0xBD -> GREEK SMALL LETTER PHI - '\u03c7' # 0xBE -> GREEK SMALL LETTER CHI - '\u03c8' # 0xBF -> GREEK SMALL LETTER PSI - '{' # 0xC0 -> LEFT CURLY BRACKET - 'A' # 0xC1 -> LATIN CAPITAL LETTER A - 'B' # 0xC2 -> LATIN CAPITAL LETTER B - 'C' # 0xC3 -> LATIN CAPITAL LETTER C - 'D' # 0xC4 -> LATIN CAPITAL LETTER D - 'E' # 0xC5 -> LATIN CAPITAL LETTER E - 'F' # 0xC6 -> LATIN CAPITAL LETTER F - 'G' # 0xC7 -> LATIN CAPITAL LETTER G - 'H' # 0xC8 -> LATIN CAPITAL LETTER H - 'I' # 0xC9 -> LATIN CAPITAL LETTER I - '\xad' # 0xCA -> SOFT HYPHEN - '\u03c9' # 0xCB -> GREEK SMALL LETTER OMEGA - '\u0390' # 0xCC -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - '\u03b0' # 0xCD -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - '\u2018' # 0xCE -> LEFT SINGLE QUOTATION MARK - '\u2015' # 0xCF -> HORIZONTAL BAR - '}' # 0xD0 -> RIGHT CURLY BRACKET - 'J' # 0xD1 -> LATIN CAPITAL LETTER J - 'K' # 0xD2 -> LATIN CAPITAL LETTER K - 'L' # 0xD3 -> LATIN CAPITAL LETTER L - 'M' # 0xD4 -> LATIN CAPITAL LETTER M - 'N' # 0xD5 -> LATIN CAPITAL LETTER N - 'O' # 0xD6 -> LATIN CAPITAL LETTER O - 'P' # 0xD7 -> LATIN CAPITAL LETTER P - 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q - 'R' # 0xD9 -> LATIN CAPITAL LETTER R - '\xb1' # 0xDA -> PLUS-MINUS SIGN - '\xbd' # 0xDB -> VULGAR FRACTION ONE HALF - '\x1a' # 0xDC -> SUBSTITUTE - '\u0387' # 0xDD -> GREEK ANO TELEIA - '\u2019' # 0xDE -> RIGHT SINGLE QUOTATION MARK - '\xa6' # 0xDF -> BROKEN BAR - '\\' # 0xE0 -> REVERSE SOLIDUS - '\x1a' # 0xE1 -> SUBSTITUTE - 'S' # 0xE2 -> LATIN CAPITAL LETTER S - 'T' # 0xE3 -> LATIN CAPITAL LETTER T - 'U' # 0xE4 -> LATIN CAPITAL LETTER U - 'V' # 0xE5 -> LATIN CAPITAL LETTER V - 'W' # 0xE6 -> LATIN CAPITAL LETTER W - 'X' # 0xE7 -> LATIN CAPITAL LETTER X - 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y - 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z - '\xb2' # 0xEA -> SUPERSCRIPT TWO - '\xa7' # 0xEB -> SECTION SIGN - '\x1a' # 0xEC -> SUBSTITUTE - '\x1a' # 0xED -> SUBSTITUTE - '\xab' # 0xEE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xEF -> NOT SIGN - '0' # 0xF0 -> DIGIT ZERO - '1' # 0xF1 -> DIGIT ONE - '2' # 0xF2 -> DIGIT TWO - '3' # 0xF3 -> DIGIT THREE - '4' # 0xF4 -> DIGIT FOUR - '5' # 0xF5 -> DIGIT FIVE - '6' # 0xF6 -> DIGIT SIX - '7' # 0xF7 -> DIGIT SEVEN - '8' # 0xF8 -> DIGIT EIGHT - '9' # 0xF9 -> DIGIT NINE - '\xb3' # 0xFA -> SUPERSCRIPT THREE - '\xa9' # 0xFB -> COPYRIGHT SIGN - '\x1a' # 0xFC -> SUBSTITUTE - '\x1a' # 0xFD -> SUBSTITUTE - '\xbb' # 0xFE -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\x9f' # 0xFF -> CONTROL -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/cp932.py b/python/Lib/encodings/cp932.py deleted file mode 100644 index 6321c20..0000000 --- a/python/Lib/encodings/cp932.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# cp932.py: Python Unicode Codec for CP932 -# -# Written by Hye-Shik Chang -# - -import _codecs_jp, codecs -import _multibytecodec as mbc - -codec = _codecs_jp.getcodec('cp932') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='cp932', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/cp949.py b/python/Lib/encodings/cp949.py deleted file mode 100644 index 1d9725d..0000000 --- a/python/Lib/encodings/cp949.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# cp949.py: Python Unicode Codec for CP949 -# -# Written by Hye-Shik Chang -# - -import _codecs_kr, codecs -import _multibytecodec as mbc - -codec = _codecs_kr.getcodec('cp949') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='cp949', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/cp950.py b/python/Lib/encodings/cp950.py deleted file mode 100644 index e7772b1..0000000 --- a/python/Lib/encodings/cp950.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# cp950.py: Python Unicode Codec for CP950 -# -# Written by Hye-Shik Chang -# - -import _codecs_tw, codecs -import _multibytecodec as mbc - -codec = _codecs_tw.getcodec('cp950') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='cp950', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/euc_jis_2004.py b/python/Lib/encodings/euc_jis_2004.py deleted file mode 100644 index bb35520..0000000 --- a/python/Lib/encodings/euc_jis_2004.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# euc_jis_2004.py: Python Unicode Codec for EUC_JIS_2004 -# -# Written by Hye-Shik Chang -# - -import _codecs_jp, codecs -import _multibytecodec as mbc - -codec = _codecs_jp.getcodec('euc_jis_2004') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='euc_jis_2004', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/euc_jisx0213.py b/python/Lib/encodings/euc_jisx0213.py deleted file mode 100644 index 9914c4f..0000000 --- a/python/Lib/encodings/euc_jisx0213.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# euc_jisx0213.py: Python Unicode Codec for EUC_JISX0213 -# -# Written by Hye-Shik Chang -# - -import _codecs_jp, codecs -import _multibytecodec as mbc - -codec = _codecs_jp.getcodec('euc_jisx0213') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='euc_jisx0213', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/euc_jp.py b/python/Lib/encodings/euc_jp.py deleted file mode 100644 index 29406b6..0000000 --- a/python/Lib/encodings/euc_jp.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# euc_jp.py: Python Unicode Codec for EUC_JP -# -# Written by Hye-Shik Chang -# - -import _codecs_jp, codecs -import _multibytecodec as mbc - -codec = _codecs_jp.getcodec('euc_jp') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='euc_jp', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/euc_kr.py b/python/Lib/encodings/euc_kr.py deleted file mode 100644 index 7d5eca4..0000000 --- a/python/Lib/encodings/euc_kr.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# euc_kr.py: Python Unicode Codec for EUC_KR -# -# Written by Hye-Shik Chang -# - -import _codecs_kr, codecs -import _multibytecodec as mbc - -codec = _codecs_kr.getcodec('euc_kr') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='euc_kr', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/gb18030.py b/python/Lib/encodings/gb18030.py deleted file mode 100644 index 99059ff..0000000 --- a/python/Lib/encodings/gb18030.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# gb18030.py: Python Unicode Codec for GB18030 -# -# Written by Hye-Shik Chang -# - -import _codecs_cn, codecs -import _multibytecodec as mbc - -codec = _codecs_cn.getcodec('gb18030') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='gb18030', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/gb2312.py b/python/Lib/encodings/gb2312.py deleted file mode 100644 index 4e396fa..0000000 --- a/python/Lib/encodings/gb2312.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# gb2312.py: Python Unicode Codec for GB2312 -# -# Written by Hye-Shik Chang -# - -import _codecs_cn, codecs -import _multibytecodec as mbc - -codec = _codecs_cn.getcodec('gb2312') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='gb2312', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/gbk.py b/python/Lib/encodings/gbk.py deleted file mode 100644 index 0fd2734..0000000 --- a/python/Lib/encodings/gbk.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# gbk.py: Python Unicode Codec for GBK -# -# Written by Hye-Shik Chang -# - -import _codecs_cn, codecs -import _multibytecodec as mbc - -codec = _codecs_cn.getcodec('gbk') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='gbk', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/hex_codec.py b/python/Lib/encodings/hex_codec.py deleted file mode 100644 index a3e1cb2..0000000 --- a/python/Lib/encodings/hex_codec.py +++ /dev/null @@ -1,55 +0,0 @@ -"""Python 'hex_codec' Codec - 2-digit hex content transfer encoding. - -This codec de/encodes from bytes to bytes. - -Written by Marc-Andre Lemburg (mal@lemburg.com). -""" - -import codecs -import binascii - -### Codec APIs - -def hex_encode(input, errors='strict'): - assert errors == 'strict' - return (binascii.b2a_hex(input), len(input)) - -def hex_decode(input, errors='strict'): - assert errors == 'strict' - return (binascii.a2b_hex(input), len(input)) - -class Codec(codecs.Codec): - def encode(self, input, errors='strict'): - return hex_encode(input, errors) - def decode(self, input, errors='strict'): - return hex_decode(input, errors) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - assert self.errors == 'strict' - return binascii.b2a_hex(input) - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - assert self.errors == 'strict' - return binascii.a2b_hex(input) - -class StreamWriter(Codec, codecs.StreamWriter): - charbuffertype = bytes - -class StreamReader(Codec, codecs.StreamReader): - charbuffertype = bytes - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='hex', - encode=hex_encode, - decode=hex_decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - _is_text_encoding=False, - ) diff --git a/python/Lib/encodings/hp_roman8.py b/python/Lib/encodings/hp_roman8.py deleted file mode 100644 index a80c5bf..0000000 --- a/python/Lib/encodings/hp_roman8.py +++ /dev/null @@ -1,314 +0,0 @@ -""" Python Character Mapping Codec generated from 'hp_roman8.txt' with gencodec.py. - - Based on data from ftp://dkuug.dk/i18n/charmaps/HP-ROMAN8 (Keld Simonsen) - - Original source: LaserJet IIP Printer User's Manual HP part no - 33471-90901, Hewlet-Packard, June 1989. - - (Used with permission) - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='hp-roman8', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\xc0' # 0xA1 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc2' # 0xA2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc8' # 0xA3 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xca' # 0xA4 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0xA5 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xce' # 0xA6 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xA7 -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xb4' # 0xA8 -> ACUTE ACCENT - '\u02cb' # 0xA9 -> MODIFIER LETTER GRAVE ACCENT (MANDARIN CHINESE FOURTH TONE) - '\u02c6' # 0xAA -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\xa8' # 0xAB -> DIAERESIS - '\u02dc' # 0xAC -> SMALL TILDE - '\xd9' # 0xAD -> LATIN CAPITAL LETTER U WITH GRAVE - '\xdb' # 0xAE -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\u20a4' # 0xAF -> LIRA SIGN - '\xaf' # 0xB0 -> MACRON - '\xdd' # 0xB1 -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xfd' # 0xB2 -> LATIN SMALL LETTER Y WITH ACUTE - '\xb0' # 0xB3 -> DEGREE SIGN - '\xc7' # 0xB4 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xe7' # 0xB5 -> LATIN SMALL LETTER C WITH CEDILLA - '\xd1' # 0xB6 -> LATIN CAPITAL LETTER N WITH TILDE - '\xf1' # 0xB7 -> LATIN SMALL LETTER N WITH TILDE - '\xa1' # 0xB8 -> INVERTED EXCLAMATION MARK - '\xbf' # 0xB9 -> INVERTED QUESTION MARK - '\xa4' # 0xBA -> CURRENCY SIGN - '\xa3' # 0xBB -> POUND SIGN - '\xa5' # 0xBC -> YEN SIGN - '\xa7' # 0xBD -> SECTION SIGN - '\u0192' # 0xBE -> LATIN SMALL LETTER F WITH HOOK - '\xa2' # 0xBF -> CENT SIGN - '\xe2' # 0xC0 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xea' # 0xC1 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xf4' # 0xC2 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xfb' # 0xC3 -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xe1' # 0xC4 -> LATIN SMALL LETTER A WITH ACUTE - '\xe9' # 0xC5 -> LATIN SMALL LETTER E WITH ACUTE - '\xf3' # 0xC6 -> LATIN SMALL LETTER O WITH ACUTE - '\xfa' # 0xC7 -> LATIN SMALL LETTER U WITH ACUTE - '\xe0' # 0xC8 -> LATIN SMALL LETTER A WITH GRAVE - '\xe8' # 0xC9 -> LATIN SMALL LETTER E WITH GRAVE - '\xf2' # 0xCA -> LATIN SMALL LETTER O WITH GRAVE - '\xf9' # 0xCB -> LATIN SMALL LETTER U WITH GRAVE - '\xe4' # 0xCC -> LATIN SMALL LETTER A WITH DIAERESIS - '\xeb' # 0xCD -> LATIN SMALL LETTER E WITH DIAERESIS - '\xf6' # 0xCE -> LATIN SMALL LETTER O WITH DIAERESIS - '\xfc' # 0xCF -> LATIN SMALL LETTER U WITH DIAERESIS - '\xc5' # 0xD0 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xee' # 0xD1 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xd8' # 0xD2 -> LATIN CAPITAL LETTER O WITH STROKE - '\xc6' # 0xD3 -> LATIN CAPITAL LETTER AE - '\xe5' # 0xD4 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xed' # 0xD5 -> LATIN SMALL LETTER I WITH ACUTE - '\xf8' # 0xD6 -> LATIN SMALL LETTER O WITH STROKE - '\xe6' # 0xD7 -> LATIN SMALL LETTER AE - '\xc4' # 0xD8 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xec' # 0xD9 -> LATIN SMALL LETTER I WITH GRAVE - '\xd6' # 0xDA -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0xDB -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xc9' # 0xDC -> LATIN CAPITAL LETTER E WITH ACUTE - '\xef' # 0xDD -> LATIN SMALL LETTER I WITH DIAERESIS - '\xdf' # 0xDE -> LATIN SMALL LETTER SHARP S (GERMAN) - '\xd4' # 0xDF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xc1' # 0xE0 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc3' # 0xE1 -> LATIN CAPITAL LETTER A WITH TILDE - '\xe3' # 0xE2 -> LATIN SMALL LETTER A WITH TILDE - '\xd0' # 0xE3 -> LATIN CAPITAL LETTER ETH (ICELANDIC) - '\xf0' # 0xE4 -> LATIN SMALL LETTER ETH (ICELANDIC) - '\xcd' # 0xE5 -> LATIN CAPITAL LETTER I WITH ACUTE - '\xcc' # 0xE6 -> LATIN CAPITAL LETTER I WITH GRAVE - '\xd3' # 0xE7 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd2' # 0xE8 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd5' # 0xE9 -> LATIN CAPITAL LETTER O WITH TILDE - '\xf5' # 0xEA -> LATIN SMALL LETTER O WITH TILDE - '\u0160' # 0xEB -> LATIN CAPITAL LETTER S WITH CARON - '\u0161' # 0xEC -> LATIN SMALL LETTER S WITH CARON - '\xda' # 0xED -> LATIN CAPITAL LETTER U WITH ACUTE - '\u0178' # 0xEE -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\xff' # 0xEF -> LATIN SMALL LETTER Y WITH DIAERESIS - '\xde' # 0xF0 -> LATIN CAPITAL LETTER THORN (ICELANDIC) - '\xfe' # 0xF1 -> LATIN SMALL LETTER THORN (ICELANDIC) - '\xb7' # 0xF2 -> MIDDLE DOT - '\xb5' # 0xF3 -> MICRO SIGN - '\xb6' # 0xF4 -> PILCROW SIGN - '\xbe' # 0xF5 -> VULGAR FRACTION THREE QUARTERS - '\u2014' # 0xF6 -> EM DASH - '\xbc' # 0xF7 -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xF8 -> VULGAR FRACTION ONE HALF - '\xaa' # 0xF9 -> FEMININE ORDINAL INDICATOR - '\xba' # 0xFA -> MASCULINE ORDINAL INDICATOR - '\xab' # 0xFB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u25a0' # 0xFC -> BLACK SQUARE - '\xbb' # 0xFD -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xb1' # 0xFE -> PLUS-MINUS SIGN - '\ufffe' -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/hz.py b/python/Lib/encodings/hz.py deleted file mode 100644 index 027c4fb..0000000 --- a/python/Lib/encodings/hz.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# hz.py: Python Unicode Codec for HZ -# -# Written by Hye-Shik Chang -# - -import _codecs_cn, codecs -import _multibytecodec as mbc - -codec = _codecs_cn.getcodec('hz') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='hz', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/idna.py b/python/Lib/encodings/idna.py deleted file mode 100644 index 330e5b2..0000000 --- a/python/Lib/encodings/idna.py +++ /dev/null @@ -1,307 +0,0 @@ -# This module implements the RFCs 3490 (IDNA) and 3491 (Nameprep) - -import stringprep, re, codecs -from unicodedata import ucd_3_2_0 as unicodedata - -# IDNA section 3.1 -dots = re.compile("[\u002E\u3002\uFF0E\uFF61]") - -# IDNA section 5 -ace_prefix = b"xn--" -sace_prefix = "xn--" - -# This assumes query strings, so AllowUnassigned is true -def nameprep(label): - # Map - newlabel = [] - for c in label: - if stringprep.in_table_b1(c): - # Map to nothing - continue - newlabel.append(stringprep.map_table_b2(c)) - label = "".join(newlabel) - - # Normalize - label = unicodedata.normalize("NFKC", label) - - # Prohibit - for c in label: - if stringprep.in_table_c12(c) or \ - stringprep.in_table_c22(c) or \ - stringprep.in_table_c3(c) or \ - stringprep.in_table_c4(c) or \ - stringprep.in_table_c5(c) or \ - stringprep.in_table_c6(c) or \ - stringprep.in_table_c7(c) or \ - stringprep.in_table_c8(c) or \ - stringprep.in_table_c9(c): - raise UnicodeError("Invalid character %r" % c) - - # Check bidi - RandAL = [stringprep.in_table_d1(x) for x in label] - if any(RandAL): - # There is a RandAL char in the string. Must perform further - # tests: - # 1) The characters in section 5.8 MUST be prohibited. - # This is table C.8, which was already checked - # 2) If a string contains any RandALCat character, the string - # MUST NOT contain any LCat character. - if any(stringprep.in_table_d2(x) for x in label): - raise UnicodeError("Violation of BIDI requirement 2") - # 3) If a string contains any RandALCat character, a - # RandALCat character MUST be the first character of the - # string, and a RandALCat character MUST be the last - # character of the string. - if not RandAL[0] or not RandAL[-1]: - raise UnicodeError("Violation of BIDI requirement 3") - - return label - -def ToASCII(label): - try: - # Step 1: try ASCII - label = label.encode("ascii") - except UnicodeError: - pass - else: - # Skip to step 3: UseSTD3ASCIIRules is false, so - # Skip to step 8. - if 0 < len(label) < 64: - return label - raise UnicodeError("label empty or too long") - - # Step 2: nameprep - label = nameprep(label) - - # Step 3: UseSTD3ASCIIRules is false - # Step 4: try ASCII - try: - label = label.encode("ascii") - except UnicodeError: - pass - else: - # Skip to step 8. - if 0 < len(label) < 64: - return label - raise UnicodeError("label empty or too long") - - # Step 5: Check ACE prefix - if label.startswith(sace_prefix): - raise UnicodeError("Label starts with ACE prefix") - - # Step 6: Encode with PUNYCODE - label = label.encode("punycode") - - # Step 7: Prepend ACE prefix - label = ace_prefix + label - - # Step 8: Check size - if 0 < len(label) < 64: - return label - raise UnicodeError("label empty or too long") - -def ToUnicode(label): - # Step 1: Check for ASCII - if isinstance(label, bytes): - pure_ascii = True - else: - try: - label = label.encode("ascii") - pure_ascii = True - except UnicodeError: - pure_ascii = False - if not pure_ascii: - # Step 2: Perform nameprep - label = nameprep(label) - # It doesn't say this, but apparently, it should be ASCII now - try: - label = label.encode("ascii") - except UnicodeError: - raise UnicodeError("Invalid character in IDN label") - # Step 3: Check for ACE prefix - if not label.startswith(ace_prefix): - return str(label, "ascii") - - # Step 4: Remove ACE prefix - label1 = label[len(ace_prefix):] - - # Step 5: Decode using PUNYCODE - result = label1.decode("punycode") - - # Step 6: Apply ToASCII - label2 = ToASCII(result) - - # Step 7: Compare the result of step 6 with the one of step 3 - # label2 will already be in lower case. - if str(label, "ascii").lower() != str(label2, "ascii"): - raise UnicodeError("IDNA does not round-trip", label, label2) - - # Step 8: return the result of step 5 - return result - -### Codec APIs - -class Codec(codecs.Codec): - def encode(self, input, errors='strict'): - - if errors != 'strict': - # IDNA is quite clear that implementations must be strict - raise UnicodeError("unsupported error handling "+errors) - - if not input: - return b'', 0 - - try: - result = input.encode('ascii') - except UnicodeEncodeError: - pass - else: - # ASCII name: fast path - labels = result.split(b'.') - for label in labels[:-1]: - if not (0 < len(label) < 64): - raise UnicodeError("label empty or too long") - if len(labels[-1]) >= 64: - raise UnicodeError("label too long") - return result, len(input) - - result = bytearray() - labels = dots.split(input) - if labels and not labels[-1]: - trailing_dot = b'.' - del labels[-1] - else: - trailing_dot = b'' - for label in labels: - if result: - # Join with U+002E - result.extend(b'.') - result.extend(ToASCII(label)) - return bytes(result+trailing_dot), len(input) - - def decode(self, input, errors='strict'): - - if errors != 'strict': - raise UnicodeError("Unsupported error handling "+errors) - - if not input: - return "", 0 - - # IDNA allows decoding to operate on Unicode strings, too. - if not isinstance(input, bytes): - # XXX obviously wrong, see #3232 - input = bytes(input) - - if ace_prefix not in input: - # Fast path - try: - return input.decode('ascii'), len(input) - except UnicodeDecodeError: - pass - - labels = input.split(b".") - - if labels and len(labels[-1]) == 0: - trailing_dot = '.' - del labels[-1] - else: - trailing_dot = '' - - result = [] - for label in labels: - result.append(ToUnicode(label)) - - return ".".join(result)+trailing_dot, len(input) - -class IncrementalEncoder(codecs.BufferedIncrementalEncoder): - def _buffer_encode(self, input, errors, final): - if errors != 'strict': - # IDNA is quite clear that implementations must be strict - raise UnicodeError("unsupported error handling "+errors) - - if not input: - return (b'', 0) - - labels = dots.split(input) - trailing_dot = b'' - if labels: - if not labels[-1]: - trailing_dot = b'.' - del labels[-1] - elif not final: - # Keep potentially unfinished label until the next call - del labels[-1] - if labels: - trailing_dot = b'.' - - result = bytearray() - size = 0 - for label in labels: - if size: - # Join with U+002E - result.extend(b'.') - size += 1 - result.extend(ToASCII(label)) - size += len(label) - - result += trailing_dot - size += len(trailing_dot) - return (bytes(result), size) - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - def _buffer_decode(self, input, errors, final): - if errors != 'strict': - raise UnicodeError("Unsupported error handling "+errors) - - if not input: - return ("", 0) - - # IDNA allows decoding to operate on Unicode strings, too. - if isinstance(input, str): - labels = dots.split(input) - else: - # Must be ASCII string - input = str(input, "ascii") - labels = input.split(".") - - trailing_dot = '' - if labels: - if not labels[-1]: - trailing_dot = '.' - del labels[-1] - elif not final: - # Keep potentially unfinished label until the next call - del labels[-1] - if labels: - trailing_dot = '.' - - result = [] - size = 0 - for label in labels: - result.append(ToUnicode(label)) - if size: - size += 1 - size += len(label) - - result = ".".join(result) + trailing_dot - size += len(trailing_dot) - return (result, size) - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='idna', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) diff --git a/python/Lib/encodings/iso2022_jp.py b/python/Lib/encodings/iso2022_jp.py deleted file mode 100644 index 3471999..0000000 --- a/python/Lib/encodings/iso2022_jp.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# iso2022_jp.py: Python Unicode Codec for ISO2022_JP -# -# Written by Hye-Shik Chang -# - -import _codecs_iso2022, codecs -import _multibytecodec as mbc - -codec = _codecs_iso2022.getcodec('iso2022_jp') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='iso2022_jp', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/iso2022_jp_1.py b/python/Lib/encodings/iso2022_jp_1.py deleted file mode 100644 index 8b04b84..0000000 --- a/python/Lib/encodings/iso2022_jp_1.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# iso2022_jp_1.py: Python Unicode Codec for ISO2022_JP_1 -# -# Written by Hye-Shik Chang -# - -import _codecs_iso2022, codecs -import _multibytecodec as mbc - -codec = _codecs_iso2022.getcodec('iso2022_jp_1') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='iso2022_jp_1', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/iso2022_jp_2.py b/python/Lib/encodings/iso2022_jp_2.py deleted file mode 100644 index df92673..0000000 --- a/python/Lib/encodings/iso2022_jp_2.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# iso2022_jp_2.py: Python Unicode Codec for ISO2022_JP_2 -# -# Written by Hye-Shik Chang -# - -import _codecs_iso2022, codecs -import _multibytecodec as mbc - -codec = _codecs_iso2022.getcodec('iso2022_jp_2') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='iso2022_jp_2', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/iso2022_jp_2004.py b/python/Lib/encodings/iso2022_jp_2004.py deleted file mode 100644 index 138e628..0000000 --- a/python/Lib/encodings/iso2022_jp_2004.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# iso2022_jp_2004.py: Python Unicode Codec for ISO2022_JP_2004 -# -# Written by Hye-Shik Chang -# - -import _codecs_iso2022, codecs -import _multibytecodec as mbc - -codec = _codecs_iso2022.getcodec('iso2022_jp_2004') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='iso2022_jp_2004', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/iso2022_jp_3.py b/python/Lib/encodings/iso2022_jp_3.py deleted file mode 100644 index 5fd5825..0000000 --- a/python/Lib/encodings/iso2022_jp_3.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# iso2022_jp_3.py: Python Unicode Codec for ISO2022_JP_3 -# -# Written by Hye-Shik Chang -# - -import _codecs_iso2022, codecs -import _multibytecodec as mbc - -codec = _codecs_iso2022.getcodec('iso2022_jp_3') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='iso2022_jp_3', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/iso2022_jp_ext.py b/python/Lib/encodings/iso2022_jp_ext.py deleted file mode 100644 index 4ac8a0c..0000000 --- a/python/Lib/encodings/iso2022_jp_ext.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# iso2022_jp_ext.py: Python Unicode Codec for ISO2022_JP_EXT -# -# Written by Hye-Shik Chang -# - -import _codecs_iso2022, codecs -import _multibytecodec as mbc - -codec = _codecs_iso2022.getcodec('iso2022_jp_ext') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='iso2022_jp_ext', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/iso2022_kr.py b/python/Lib/encodings/iso2022_kr.py deleted file mode 100644 index 3dfe986..0000000 --- a/python/Lib/encodings/iso2022_kr.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# iso2022_kr.py: Python Unicode Codec for ISO2022_KR -# -# Written by Hye-Shik Chang -# - -import _codecs_iso2022, codecs -import _multibytecodec as mbc - -codec = _codecs_iso2022.getcodec('iso2022_kr') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='iso2022_kr', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/iso8859_1.py b/python/Lib/encodings/iso8859_1.py deleted file mode 100644 index 8940ae3..0000000 --- a/python/Lib/encodings/iso8859_1.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_1 generated from 'MAPPINGS/ISO8859/8859-1.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-1', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\xa5' # 0xA5 -> YEN SIGN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xaf' # 0xAF -> MACRON - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xb8' # 0xB8 -> CEDILLA - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS - '\xbf' # 0xBF -> INVERTED QUESTION MARK - '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic) - '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE - '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN (Icelandic) - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) - '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe6' # 0xE6 -> LATIN SMALL LETTER AE - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH (Icelandic) - '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE - '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE - '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE - '\xfe' # 0xFE -> LATIN SMALL LETTER THORN (Icelandic) - '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_10.py b/python/Lib/encodings/iso8859_10.py deleted file mode 100644 index 9ebe1be..0000000 --- a/python/Lib/encodings/iso8859_10.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_10 generated from 'MAPPINGS/ISO8859/8859-10.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-10', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK - '\u0112' # 0xA2 -> LATIN CAPITAL LETTER E WITH MACRON - '\u0122' # 0xA3 -> LATIN CAPITAL LETTER G WITH CEDILLA - '\u012a' # 0xA4 -> LATIN CAPITAL LETTER I WITH MACRON - '\u0128' # 0xA5 -> LATIN CAPITAL LETTER I WITH TILDE - '\u0136' # 0xA6 -> LATIN CAPITAL LETTER K WITH CEDILLA - '\xa7' # 0xA7 -> SECTION SIGN - '\u013b' # 0xA8 -> LATIN CAPITAL LETTER L WITH CEDILLA - '\u0110' # 0xA9 -> LATIN CAPITAL LETTER D WITH STROKE - '\u0160' # 0xAA -> LATIN CAPITAL LETTER S WITH CARON - '\u0166' # 0xAB -> LATIN CAPITAL LETTER T WITH STROKE - '\u017d' # 0xAC -> LATIN CAPITAL LETTER Z WITH CARON - '\xad' # 0xAD -> SOFT HYPHEN - '\u016a' # 0xAE -> LATIN CAPITAL LETTER U WITH MACRON - '\u014a' # 0xAF -> LATIN CAPITAL LETTER ENG - '\xb0' # 0xB0 -> DEGREE SIGN - '\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK - '\u0113' # 0xB2 -> LATIN SMALL LETTER E WITH MACRON - '\u0123' # 0xB3 -> LATIN SMALL LETTER G WITH CEDILLA - '\u012b' # 0xB4 -> LATIN SMALL LETTER I WITH MACRON - '\u0129' # 0xB5 -> LATIN SMALL LETTER I WITH TILDE - '\u0137' # 0xB6 -> LATIN SMALL LETTER K WITH CEDILLA - '\xb7' # 0xB7 -> MIDDLE DOT - '\u013c' # 0xB8 -> LATIN SMALL LETTER L WITH CEDILLA - '\u0111' # 0xB9 -> LATIN SMALL LETTER D WITH STROKE - '\u0161' # 0xBA -> LATIN SMALL LETTER S WITH CARON - '\u0167' # 0xBB -> LATIN SMALL LETTER T WITH STROKE - '\u017e' # 0xBC -> LATIN SMALL LETTER Z WITH CARON - '\u2015' # 0xBD -> HORIZONTAL BAR - '\u016b' # 0xBE -> LATIN SMALL LETTER U WITH MACRON - '\u014b' # 0xBF -> LATIN SMALL LETTER ENG - '\u0100' # 0xC0 -> LATIN CAPITAL LETTER A WITH MACRON - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE - '\u012e' # 0xC7 -> LATIN CAPITAL LETTER I WITH OGONEK - '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\u0116' # 0xCC -> LATIN CAPITAL LETTER E WITH DOT ABOVE - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic) - '\u0145' # 0xD1 -> LATIN CAPITAL LETTER N WITH CEDILLA - '\u014c' # 0xD2 -> LATIN CAPITAL LETTER O WITH MACRON - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\u0168' # 0xD7 -> LATIN CAPITAL LETTER U WITH TILDE - '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE - '\u0172' # 0xD9 -> LATIN CAPITAL LETTER U WITH OGONEK - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN (Icelandic) - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) - '\u0101' # 0xE0 -> LATIN SMALL LETTER A WITH MACRON - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe6' # 0xE6 -> LATIN SMALL LETTER AE - '\u012f' # 0xE7 -> LATIN SMALL LETTER I WITH OGONEK - '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\u0117' # 0xEC -> LATIN SMALL LETTER E WITH DOT ABOVE - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH (Icelandic) - '\u0146' # 0xF1 -> LATIN SMALL LETTER N WITH CEDILLA - '\u014d' # 0xF2 -> LATIN SMALL LETTER O WITH MACRON - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\u0169' # 0xF7 -> LATIN SMALL LETTER U WITH TILDE - '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE - '\u0173' # 0xF9 -> LATIN SMALL LETTER U WITH OGONEK - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE - '\xfe' # 0xFE -> LATIN SMALL LETTER THORN (Icelandic) - '\u0138' # 0xFF -> LATIN SMALL LETTER KRA -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_11.py b/python/Lib/encodings/iso8859_11.py deleted file mode 100644 index 2485e72..0000000 --- a/python/Lib/encodings/iso8859_11.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_11 generated from 'MAPPINGS/ISO8859/8859-11.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-11', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u0e01' # 0xA1 -> THAI CHARACTER KO KAI - '\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI - '\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT - '\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI - '\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON - '\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG - '\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU - '\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN - '\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING - '\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG - '\u0e0b' # 0xAB -> THAI CHARACTER SO SO - '\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE - '\u0e0d' # 0xAD -> THAI CHARACTER YO YING - '\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA - '\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK - '\u0e10' # 0xB0 -> THAI CHARACTER THO THAN - '\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO - '\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO - '\u0e13' # 0xB3 -> THAI CHARACTER NO NEN - '\u0e14' # 0xB4 -> THAI CHARACTER DO DEK - '\u0e15' # 0xB5 -> THAI CHARACTER TO TAO - '\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG - '\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN - '\u0e18' # 0xB8 -> THAI CHARACTER THO THONG - '\u0e19' # 0xB9 -> THAI CHARACTER NO NU - '\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI - '\u0e1b' # 0xBB -> THAI CHARACTER PO PLA - '\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG - '\u0e1d' # 0xBD -> THAI CHARACTER FO FA - '\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN - '\u0e1f' # 0xBF -> THAI CHARACTER FO FAN - '\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO - '\u0e21' # 0xC1 -> THAI CHARACTER MO MA - '\u0e22' # 0xC2 -> THAI CHARACTER YO YAK - '\u0e23' # 0xC3 -> THAI CHARACTER RO RUA - '\u0e24' # 0xC4 -> THAI CHARACTER RU - '\u0e25' # 0xC5 -> THAI CHARACTER LO LING - '\u0e26' # 0xC6 -> THAI CHARACTER LU - '\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN - '\u0e28' # 0xC8 -> THAI CHARACTER SO SALA - '\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI - '\u0e2a' # 0xCA -> THAI CHARACTER SO SUA - '\u0e2b' # 0xCB -> THAI CHARACTER HO HIP - '\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA - '\u0e2d' # 0xCD -> THAI CHARACTER O ANG - '\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK - '\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI - '\u0e30' # 0xD0 -> THAI CHARACTER SARA A - '\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT - '\u0e32' # 0xD2 -> THAI CHARACTER SARA AA - '\u0e33' # 0xD3 -> THAI CHARACTER SARA AM - '\u0e34' # 0xD4 -> THAI CHARACTER SARA I - '\u0e35' # 0xD5 -> THAI CHARACTER SARA II - '\u0e36' # 0xD6 -> THAI CHARACTER SARA UE - '\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE - '\u0e38' # 0xD8 -> THAI CHARACTER SARA U - '\u0e39' # 0xD9 -> THAI CHARACTER SARA UU - '\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT - '\u0e40' # 0xE0 -> THAI CHARACTER SARA E - '\u0e41' # 0xE1 -> THAI CHARACTER SARA AE - '\u0e42' # 0xE2 -> THAI CHARACTER SARA O - '\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN - '\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI - '\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO - '\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK - '\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU - '\u0e48' # 0xE8 -> THAI CHARACTER MAI EK - '\u0e49' # 0xE9 -> THAI CHARACTER MAI THO - '\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI - '\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA - '\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT - '\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT - '\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN - '\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN - '\u0e50' # 0xF0 -> THAI DIGIT ZERO - '\u0e51' # 0xF1 -> THAI DIGIT ONE - '\u0e52' # 0xF2 -> THAI DIGIT TWO - '\u0e53' # 0xF3 -> THAI DIGIT THREE - '\u0e54' # 0xF4 -> THAI DIGIT FOUR - '\u0e55' # 0xF5 -> THAI DIGIT FIVE - '\u0e56' # 0xF6 -> THAI DIGIT SIX - '\u0e57' # 0xF7 -> THAI DIGIT SEVEN - '\u0e58' # 0xF8 -> THAI DIGIT EIGHT - '\u0e59' # 0xF9 -> THAI DIGIT NINE - '\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU - '\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_13.py b/python/Lib/encodings/iso8859_13.py deleted file mode 100644 index 0179f03..0000000 --- a/python/Lib/encodings/iso8859_13.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_13 generated from 'MAPPINGS/ISO8859/8859-13.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-13', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u201d' # 0xA1 -> RIGHT DOUBLE QUOTATION MARK - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\u201e' # 0xA5 -> DOUBLE LOW-9 QUOTATION MARK - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xd8' # 0xA8 -> LATIN CAPITAL LETTER O WITH STROKE - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u0156' # 0xAA -> LATIN CAPITAL LETTER R WITH CEDILLA - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xc6' # 0xAF -> LATIN CAPITAL LETTER AE - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\u201c' # 0xB4 -> LEFT DOUBLE QUOTATION MARK - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xf8' # 0xB8 -> LATIN SMALL LETTER O WITH STROKE - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\u0157' # 0xBA -> LATIN SMALL LETTER R WITH CEDILLA - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS - '\xe6' # 0xBF -> LATIN SMALL LETTER AE - '\u0104' # 0xC0 -> LATIN CAPITAL LETTER A WITH OGONEK - '\u012e' # 0xC1 -> LATIN CAPITAL LETTER I WITH OGONEK - '\u0100' # 0xC2 -> LATIN CAPITAL LETTER A WITH MACRON - '\u0106' # 0xC3 -> LATIN CAPITAL LETTER C WITH ACUTE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\u0118' # 0xC6 -> LATIN CAPITAL LETTER E WITH OGONEK - '\u0112' # 0xC7 -> LATIN CAPITAL LETTER E WITH MACRON - '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\u0179' # 0xCA -> LATIN CAPITAL LETTER Z WITH ACUTE - '\u0116' # 0xCB -> LATIN CAPITAL LETTER E WITH DOT ABOVE - '\u0122' # 0xCC -> LATIN CAPITAL LETTER G WITH CEDILLA - '\u0136' # 0xCD -> LATIN CAPITAL LETTER K WITH CEDILLA - '\u012a' # 0xCE -> LATIN CAPITAL LETTER I WITH MACRON - '\u013b' # 0xCF -> LATIN CAPITAL LETTER L WITH CEDILLA - '\u0160' # 0xD0 -> LATIN CAPITAL LETTER S WITH CARON - '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE - '\u0145' # 0xD2 -> LATIN CAPITAL LETTER N WITH CEDILLA - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\u014c' # 0xD4 -> LATIN CAPITAL LETTER O WITH MACRON - '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\u0172' # 0xD8 -> LATIN CAPITAL LETTER U WITH OGONEK - '\u0141' # 0xD9 -> LATIN CAPITAL LETTER L WITH STROKE - '\u015a' # 0xDA -> LATIN CAPITAL LETTER S WITH ACUTE - '\u016a' # 0xDB -> LATIN CAPITAL LETTER U WITH MACRON - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\u017b' # 0xDD -> LATIN CAPITAL LETTER Z WITH DOT ABOVE - '\u017d' # 0xDE -> LATIN CAPITAL LETTER Z WITH CARON - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) - '\u0105' # 0xE0 -> LATIN SMALL LETTER A WITH OGONEK - '\u012f' # 0xE1 -> LATIN SMALL LETTER I WITH OGONEK - '\u0101' # 0xE2 -> LATIN SMALL LETTER A WITH MACRON - '\u0107' # 0xE3 -> LATIN SMALL LETTER C WITH ACUTE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\u0119' # 0xE6 -> LATIN SMALL LETTER E WITH OGONEK - '\u0113' # 0xE7 -> LATIN SMALL LETTER E WITH MACRON - '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\u017a' # 0xEA -> LATIN SMALL LETTER Z WITH ACUTE - '\u0117' # 0xEB -> LATIN SMALL LETTER E WITH DOT ABOVE - '\u0123' # 0xEC -> LATIN SMALL LETTER G WITH CEDILLA - '\u0137' # 0xED -> LATIN SMALL LETTER K WITH CEDILLA - '\u012b' # 0xEE -> LATIN SMALL LETTER I WITH MACRON - '\u013c' # 0xEF -> LATIN SMALL LETTER L WITH CEDILLA - '\u0161' # 0xF0 -> LATIN SMALL LETTER S WITH CARON - '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE - '\u0146' # 0xF2 -> LATIN SMALL LETTER N WITH CEDILLA - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\u014d' # 0xF4 -> LATIN SMALL LETTER O WITH MACRON - '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\u0173' # 0xF8 -> LATIN SMALL LETTER U WITH OGONEK - '\u0142' # 0xF9 -> LATIN SMALL LETTER L WITH STROKE - '\u015b' # 0xFA -> LATIN SMALL LETTER S WITH ACUTE - '\u016b' # 0xFB -> LATIN SMALL LETTER U WITH MACRON - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE - '\u017e' # 0xFE -> LATIN SMALL LETTER Z WITH CARON - '\u2019' # 0xFF -> RIGHT SINGLE QUOTATION MARK -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_14.py b/python/Lib/encodings/iso8859_14.py deleted file mode 100644 index da23365..0000000 --- a/python/Lib/encodings/iso8859_14.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_14 generated from 'MAPPINGS/ISO8859/8859-14.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-14', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u1e02' # 0xA1 -> LATIN CAPITAL LETTER B WITH DOT ABOVE - '\u1e03' # 0xA2 -> LATIN SMALL LETTER B WITH DOT ABOVE - '\xa3' # 0xA3 -> POUND SIGN - '\u010a' # 0xA4 -> LATIN CAPITAL LETTER C WITH DOT ABOVE - '\u010b' # 0xA5 -> LATIN SMALL LETTER C WITH DOT ABOVE - '\u1e0a' # 0xA6 -> LATIN CAPITAL LETTER D WITH DOT ABOVE - '\xa7' # 0xA7 -> SECTION SIGN - '\u1e80' # 0xA8 -> LATIN CAPITAL LETTER W WITH GRAVE - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u1e82' # 0xAA -> LATIN CAPITAL LETTER W WITH ACUTE - '\u1e0b' # 0xAB -> LATIN SMALL LETTER D WITH DOT ABOVE - '\u1ef2' # 0xAC -> LATIN CAPITAL LETTER Y WITH GRAVE - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\u0178' # 0xAF -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\u1e1e' # 0xB0 -> LATIN CAPITAL LETTER F WITH DOT ABOVE - '\u1e1f' # 0xB1 -> LATIN SMALL LETTER F WITH DOT ABOVE - '\u0120' # 0xB2 -> LATIN CAPITAL LETTER G WITH DOT ABOVE - '\u0121' # 0xB3 -> LATIN SMALL LETTER G WITH DOT ABOVE - '\u1e40' # 0xB4 -> LATIN CAPITAL LETTER M WITH DOT ABOVE - '\u1e41' # 0xB5 -> LATIN SMALL LETTER M WITH DOT ABOVE - '\xb6' # 0xB6 -> PILCROW SIGN - '\u1e56' # 0xB7 -> LATIN CAPITAL LETTER P WITH DOT ABOVE - '\u1e81' # 0xB8 -> LATIN SMALL LETTER W WITH GRAVE - '\u1e57' # 0xB9 -> LATIN SMALL LETTER P WITH DOT ABOVE - '\u1e83' # 0xBA -> LATIN SMALL LETTER W WITH ACUTE - '\u1e60' # 0xBB -> LATIN CAPITAL LETTER S WITH DOT ABOVE - '\u1ef3' # 0xBC -> LATIN SMALL LETTER Y WITH GRAVE - '\u1e84' # 0xBD -> LATIN CAPITAL LETTER W WITH DIAERESIS - '\u1e85' # 0xBE -> LATIN SMALL LETTER W WITH DIAERESIS - '\u1e61' # 0xBF -> LATIN SMALL LETTER S WITH DOT ABOVE - '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\u0174' # 0xD0 -> LATIN CAPITAL LETTER W WITH CIRCUMFLEX - '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\u1e6a' # 0xD7 -> LATIN CAPITAL LETTER T WITH DOT ABOVE - '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE - '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\u0176' # 0xDE -> LATIN CAPITAL LETTER Y WITH CIRCUMFLEX - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe6' # 0xE6 -> LATIN SMALL LETTER AE - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\u0175' # 0xF0 -> LATIN SMALL LETTER W WITH CIRCUMFLEX - '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE - '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\u1e6b' # 0xF7 -> LATIN SMALL LETTER T WITH DOT ABOVE - '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE - '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE - '\u0177' # 0xFE -> LATIN SMALL LETTER Y WITH CIRCUMFLEX - '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_15.py b/python/Lib/encodings/iso8859_15.py deleted file mode 100644 index c98c053..0000000 --- a/python/Lib/encodings/iso8859_15.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_15 generated from 'MAPPINGS/ISO8859/8859-15.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-15', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\u20ac' # 0xA4 -> EURO SIGN - '\xa5' # 0xA5 -> YEN SIGN - '\u0160' # 0xA6 -> LATIN CAPITAL LETTER S WITH CARON - '\xa7' # 0xA7 -> SECTION SIGN - '\u0161' # 0xA8 -> LATIN SMALL LETTER S WITH CARON - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xaf' # 0xAF -> MACRON - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\u017d' # 0xB4 -> LATIN CAPITAL LETTER Z WITH CARON - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\u017e' # 0xB8 -> LATIN SMALL LETTER Z WITH CARON - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u0152' # 0xBC -> LATIN CAPITAL LIGATURE OE - '\u0153' # 0xBD -> LATIN SMALL LIGATURE OE - '\u0178' # 0xBE -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\xbf' # 0xBF -> INVERTED QUESTION MARK - '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH - '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE - '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe6' # 0xE6 -> LATIN SMALL LETTER AE - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH - '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE - '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE - '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE - '\xfe' # 0xFE -> LATIN SMALL LETTER THORN - '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_16.py b/python/Lib/encodings/iso8859_16.py deleted file mode 100644 index d763346..0000000 --- a/python/Lib/encodings/iso8859_16.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_16 generated from 'MAPPINGS/ISO8859/8859-16.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-16', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK - '\u0105' # 0xA2 -> LATIN SMALL LETTER A WITH OGONEK - '\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE - '\u20ac' # 0xA4 -> EURO SIGN - '\u201e' # 0xA5 -> DOUBLE LOW-9 QUOTATION MARK - '\u0160' # 0xA6 -> LATIN CAPITAL LETTER S WITH CARON - '\xa7' # 0xA7 -> SECTION SIGN - '\u0161' # 0xA8 -> LATIN SMALL LETTER S WITH CARON - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u0218' # 0xAA -> LATIN CAPITAL LETTER S WITH COMMA BELOW - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u0179' # 0xAC -> LATIN CAPITAL LETTER Z WITH ACUTE - '\xad' # 0xAD -> SOFT HYPHEN - '\u017a' # 0xAE -> LATIN SMALL LETTER Z WITH ACUTE - '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\u010c' # 0xB2 -> LATIN CAPITAL LETTER C WITH CARON - '\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE - '\u017d' # 0xB4 -> LATIN CAPITAL LETTER Z WITH CARON - '\u201d' # 0xB5 -> RIGHT DOUBLE QUOTATION MARK - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\u017e' # 0xB8 -> LATIN SMALL LETTER Z WITH CARON - '\u010d' # 0xB9 -> LATIN SMALL LETTER C WITH CARON - '\u0219' # 0xBA -> LATIN SMALL LETTER S WITH COMMA BELOW - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u0152' # 0xBC -> LATIN CAPITAL LIGATURE OE - '\u0153' # 0xBD -> LATIN SMALL LIGATURE OE - '\u0178' # 0xBE -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE - '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\u0106' # 0xC5 -> LATIN CAPITAL LETTER C WITH ACUTE - '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE - '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE - '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\u015a' # 0xD7 -> LATIN CAPITAL LETTER S WITH ACUTE - '\u0170' # 0xD8 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE - '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\u0118' # 0xDD -> LATIN CAPITAL LETTER E WITH OGONEK - '\u021a' # 0xDE -> LATIN CAPITAL LETTER T WITH COMMA BELOW - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\u0107' # 0xE5 -> LATIN SMALL LETTER C WITH ACUTE - '\xe6' # 0xE6 -> LATIN SMALL LETTER AE - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE - '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE - '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\u015b' # 0xF7 -> LATIN SMALL LETTER S WITH ACUTE - '\u0171' # 0xF8 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE - '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\u0119' # 0xFD -> LATIN SMALL LETTER E WITH OGONEK - '\u021b' # 0xFE -> LATIN SMALL LETTER T WITH COMMA BELOW - '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_2.py b/python/Lib/encodings/iso8859_2.py deleted file mode 100644 index b08e48b..0000000 --- a/python/Lib/encodings/iso8859_2.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_2 generated from 'MAPPINGS/ISO8859/8859-2.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-2', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK - '\u02d8' # 0xA2 -> BREVE - '\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE - '\xa4' # 0xA4 -> CURRENCY SIGN - '\u013d' # 0xA5 -> LATIN CAPITAL LETTER L WITH CARON - '\u015a' # 0xA6 -> LATIN CAPITAL LETTER S WITH ACUTE - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON - '\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA - '\u0164' # 0xAB -> LATIN CAPITAL LETTER T WITH CARON - '\u0179' # 0xAC -> LATIN CAPITAL LETTER Z WITH ACUTE - '\xad' # 0xAD -> SOFT HYPHEN - '\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON - '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE - '\xb0' # 0xB0 -> DEGREE SIGN - '\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK - '\u02db' # 0xB2 -> OGONEK - '\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\u013e' # 0xB5 -> LATIN SMALL LETTER L WITH CARON - '\u015b' # 0xB6 -> LATIN SMALL LETTER S WITH ACUTE - '\u02c7' # 0xB7 -> CARON - '\xb8' # 0xB8 -> CEDILLA - '\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON - '\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA - '\u0165' # 0xBB -> LATIN SMALL LETTER T WITH CARON - '\u017a' # 0xBC -> LATIN SMALL LETTER Z WITH ACUTE - '\u02dd' # 0xBD -> DOUBLE ACUTE ACCENT - '\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON - '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE - '\u0154' # 0xC0 -> LATIN CAPITAL LETTER R WITH ACUTE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\u0139' # 0xC5 -> LATIN CAPITAL LETTER L WITH ACUTE - '\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\u011a' # 0xCC -> LATIN CAPITAL LETTER E WITH CARON - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\u010e' # 0xCF -> LATIN CAPITAL LETTER D WITH CARON - '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE - '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE - '\u0147' # 0xD2 -> LATIN CAPITAL LETTER N WITH CARON - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\u0158' # 0xD8 -> LATIN CAPITAL LETTER R WITH CARON - '\u016e' # 0xD9 -> LATIN CAPITAL LETTER U WITH RING ABOVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\u0170' # 0xDB -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\u0162' # 0xDE -> LATIN CAPITAL LETTER T WITH CEDILLA - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\u0155' # 0xE0 -> LATIN SMALL LETTER R WITH ACUTE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\u013a' # 0xE5 -> LATIN SMALL LETTER L WITH ACUTE - '\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\u011b' # 0xEC -> LATIN SMALL LETTER E WITH CARON - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\u010f' # 0xEF -> LATIN SMALL LETTER D WITH CARON - '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE - '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE - '\u0148' # 0xF2 -> LATIN SMALL LETTER N WITH CARON - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\u0159' # 0xF8 -> LATIN SMALL LETTER R WITH CARON - '\u016f' # 0xF9 -> LATIN SMALL LETTER U WITH RING ABOVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\u0171' # 0xFB -> LATIN SMALL LETTER U WITH DOUBLE ACUTE - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE - '\u0163' # 0xFE -> LATIN SMALL LETTER T WITH CEDILLA - '\u02d9' # 0xFF -> DOT ABOVE -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_3.py b/python/Lib/encodings/iso8859_3.py deleted file mode 100644 index be191aa..0000000 --- a/python/Lib/encodings/iso8859_3.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_3 generated from 'MAPPINGS/ISO8859/8859-3.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-3', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u0126' # 0xA1 -> LATIN CAPITAL LETTER H WITH STROKE - '\u02d8' # 0xA2 -> BREVE - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\ufffe' - '\u0124' # 0xA6 -> LATIN CAPITAL LETTER H WITH CIRCUMFLEX - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\u0130' # 0xA9 -> LATIN CAPITAL LETTER I WITH DOT ABOVE - '\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA - '\u011e' # 0xAB -> LATIN CAPITAL LETTER G WITH BREVE - '\u0134' # 0xAC -> LATIN CAPITAL LETTER J WITH CIRCUMFLEX - '\xad' # 0xAD -> SOFT HYPHEN - '\ufffe' - '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE - '\xb0' # 0xB0 -> DEGREE SIGN - '\u0127' # 0xB1 -> LATIN SMALL LETTER H WITH STROKE - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\u0125' # 0xB6 -> LATIN SMALL LETTER H WITH CIRCUMFLEX - '\xb7' # 0xB7 -> MIDDLE DOT - '\xb8' # 0xB8 -> CEDILLA - '\u0131' # 0xB9 -> LATIN SMALL LETTER DOTLESS I - '\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA - '\u011f' # 0xBB -> LATIN SMALL LETTER G WITH BREVE - '\u0135' # 0xBC -> LATIN SMALL LETTER J WITH CIRCUMFLEX - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\ufffe' - '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE - '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\ufffe' - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\u010a' # 0xC5 -> LATIN CAPITAL LETTER C WITH DOT ABOVE - '\u0108' # 0xC6 -> LATIN CAPITAL LETTER C WITH CIRCUMFLEX - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\ufffe' - '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\u0120' # 0xD5 -> LATIN CAPITAL LETTER G WITH DOT ABOVE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\u011c' # 0xD8 -> LATIN CAPITAL LETTER G WITH CIRCUMFLEX - '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\u016c' # 0xDD -> LATIN CAPITAL LETTER U WITH BREVE - '\u015c' # 0xDE -> LATIN CAPITAL LETTER S WITH CIRCUMFLEX - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\ufffe' - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\u010b' # 0xE5 -> LATIN SMALL LETTER C WITH DOT ABOVE - '\u0109' # 0xE6 -> LATIN SMALL LETTER C WITH CIRCUMFLEX - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\ufffe' - '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE - '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\u0121' # 0xF5 -> LATIN SMALL LETTER G WITH DOT ABOVE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\u011d' # 0xF8 -> LATIN SMALL LETTER G WITH CIRCUMFLEX - '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\u016d' # 0xFD -> LATIN SMALL LETTER U WITH BREVE - '\u015d' # 0xFE -> LATIN SMALL LETTER S WITH CIRCUMFLEX - '\u02d9' # 0xFF -> DOT ABOVE -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_4.py b/python/Lib/encodings/iso8859_4.py deleted file mode 100644 index 107ad9e..0000000 --- a/python/Lib/encodings/iso8859_4.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_4 generated from 'MAPPINGS/ISO8859/8859-4.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-4', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK - '\u0138' # 0xA2 -> LATIN SMALL LETTER KRA - '\u0156' # 0xA3 -> LATIN CAPITAL LETTER R WITH CEDILLA - '\xa4' # 0xA4 -> CURRENCY SIGN - '\u0128' # 0xA5 -> LATIN CAPITAL LETTER I WITH TILDE - '\u013b' # 0xA6 -> LATIN CAPITAL LETTER L WITH CEDILLA - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON - '\u0112' # 0xAA -> LATIN CAPITAL LETTER E WITH MACRON - '\u0122' # 0xAB -> LATIN CAPITAL LETTER G WITH CEDILLA - '\u0166' # 0xAC -> LATIN CAPITAL LETTER T WITH STROKE - '\xad' # 0xAD -> SOFT HYPHEN - '\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON - '\xaf' # 0xAF -> MACRON - '\xb0' # 0xB0 -> DEGREE SIGN - '\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK - '\u02db' # 0xB2 -> OGONEK - '\u0157' # 0xB3 -> LATIN SMALL LETTER R WITH CEDILLA - '\xb4' # 0xB4 -> ACUTE ACCENT - '\u0129' # 0xB5 -> LATIN SMALL LETTER I WITH TILDE - '\u013c' # 0xB6 -> LATIN SMALL LETTER L WITH CEDILLA - '\u02c7' # 0xB7 -> CARON - '\xb8' # 0xB8 -> CEDILLA - '\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON - '\u0113' # 0xBA -> LATIN SMALL LETTER E WITH MACRON - '\u0123' # 0xBB -> LATIN SMALL LETTER G WITH CEDILLA - '\u0167' # 0xBC -> LATIN SMALL LETTER T WITH STROKE - '\u014a' # 0xBD -> LATIN CAPITAL LETTER ENG - '\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON - '\u014b' # 0xBF -> LATIN SMALL LETTER ENG - '\u0100' # 0xC0 -> LATIN CAPITAL LETTER A WITH MACRON - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE - '\u012e' # 0xC7 -> LATIN CAPITAL LETTER I WITH OGONEK - '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\u0116' # 0xCC -> LATIN CAPITAL LETTER E WITH DOT ABOVE - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\u012a' # 0xCF -> LATIN CAPITAL LETTER I WITH MACRON - '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE - '\u0145' # 0xD1 -> LATIN CAPITAL LETTER N WITH CEDILLA - '\u014c' # 0xD2 -> LATIN CAPITAL LETTER O WITH MACRON - '\u0136' # 0xD3 -> LATIN CAPITAL LETTER K WITH CEDILLA - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE - '\u0172' # 0xD9 -> LATIN CAPITAL LETTER U WITH OGONEK - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\u0168' # 0xDD -> LATIN CAPITAL LETTER U WITH TILDE - '\u016a' # 0xDE -> LATIN CAPITAL LETTER U WITH MACRON - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\u0101' # 0xE0 -> LATIN SMALL LETTER A WITH MACRON - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe6' # 0xE6 -> LATIN SMALL LETTER AE - '\u012f' # 0xE7 -> LATIN SMALL LETTER I WITH OGONEK - '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\u0117' # 0xEC -> LATIN SMALL LETTER E WITH DOT ABOVE - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\u012b' # 0xEF -> LATIN SMALL LETTER I WITH MACRON - '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE - '\u0146' # 0xF1 -> LATIN SMALL LETTER N WITH CEDILLA - '\u014d' # 0xF2 -> LATIN SMALL LETTER O WITH MACRON - '\u0137' # 0xF3 -> LATIN SMALL LETTER K WITH CEDILLA - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE - '\u0173' # 0xF9 -> LATIN SMALL LETTER U WITH OGONEK - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\u0169' # 0xFD -> LATIN SMALL LETTER U WITH TILDE - '\u016b' # 0xFE -> LATIN SMALL LETTER U WITH MACRON - '\u02d9' # 0xFF -> DOT ABOVE -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_5.py b/python/Lib/encodings/iso8859_5.py deleted file mode 100644 index 08f12d9..0000000 --- a/python/Lib/encodings/iso8859_5.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_5 generated from 'MAPPINGS/ISO8859/8859-5.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-5', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u0401' # 0xA1 -> CYRILLIC CAPITAL LETTER IO - '\u0402' # 0xA2 -> CYRILLIC CAPITAL LETTER DJE - '\u0403' # 0xA3 -> CYRILLIC CAPITAL LETTER GJE - '\u0404' # 0xA4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE - '\u0405' # 0xA5 -> CYRILLIC CAPITAL LETTER DZE - '\u0406' # 0xA6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0407' # 0xA7 -> CYRILLIC CAPITAL LETTER YI - '\u0408' # 0xA8 -> CYRILLIC CAPITAL LETTER JE - '\u0409' # 0xA9 -> CYRILLIC CAPITAL LETTER LJE - '\u040a' # 0xAA -> CYRILLIC CAPITAL LETTER NJE - '\u040b' # 0xAB -> CYRILLIC CAPITAL LETTER TSHE - '\u040c' # 0xAC -> CYRILLIC CAPITAL LETTER KJE - '\xad' # 0xAD -> SOFT HYPHEN - '\u040e' # 0xAE -> CYRILLIC CAPITAL LETTER SHORT U - '\u040f' # 0xAF -> CYRILLIC CAPITAL LETTER DZHE - '\u0410' # 0xB0 -> CYRILLIC CAPITAL LETTER A - '\u0411' # 0xB1 -> CYRILLIC CAPITAL LETTER BE - '\u0412' # 0xB2 -> CYRILLIC CAPITAL LETTER VE - '\u0413' # 0xB3 -> CYRILLIC CAPITAL LETTER GHE - '\u0414' # 0xB4 -> CYRILLIC CAPITAL LETTER DE - '\u0415' # 0xB5 -> CYRILLIC CAPITAL LETTER IE - '\u0416' # 0xB6 -> CYRILLIC CAPITAL LETTER ZHE - '\u0417' # 0xB7 -> CYRILLIC CAPITAL LETTER ZE - '\u0418' # 0xB8 -> CYRILLIC CAPITAL LETTER I - '\u0419' # 0xB9 -> CYRILLIC CAPITAL LETTER SHORT I - '\u041a' # 0xBA -> CYRILLIC CAPITAL LETTER KA - '\u041b' # 0xBB -> CYRILLIC CAPITAL LETTER EL - '\u041c' # 0xBC -> CYRILLIC CAPITAL LETTER EM - '\u041d' # 0xBD -> CYRILLIC CAPITAL LETTER EN - '\u041e' # 0xBE -> CYRILLIC CAPITAL LETTER O - '\u041f' # 0xBF -> CYRILLIC CAPITAL LETTER PE - '\u0420' # 0xC0 -> CYRILLIC CAPITAL LETTER ER - '\u0421' # 0xC1 -> CYRILLIC CAPITAL LETTER ES - '\u0422' # 0xC2 -> CYRILLIC CAPITAL LETTER TE - '\u0423' # 0xC3 -> CYRILLIC CAPITAL LETTER U - '\u0424' # 0xC4 -> CYRILLIC CAPITAL LETTER EF - '\u0425' # 0xC5 -> CYRILLIC CAPITAL LETTER HA - '\u0426' # 0xC6 -> CYRILLIC CAPITAL LETTER TSE - '\u0427' # 0xC7 -> CYRILLIC CAPITAL LETTER CHE - '\u0428' # 0xC8 -> CYRILLIC CAPITAL LETTER SHA - '\u0429' # 0xC9 -> CYRILLIC CAPITAL LETTER SHCHA - '\u042a' # 0xCA -> CYRILLIC CAPITAL LETTER HARD SIGN - '\u042b' # 0xCB -> CYRILLIC CAPITAL LETTER YERU - '\u042c' # 0xCC -> CYRILLIC CAPITAL LETTER SOFT SIGN - '\u042d' # 0xCD -> CYRILLIC CAPITAL LETTER E - '\u042e' # 0xCE -> CYRILLIC CAPITAL LETTER YU - '\u042f' # 0xCF -> CYRILLIC CAPITAL LETTER YA - '\u0430' # 0xD0 -> CYRILLIC SMALL LETTER A - '\u0431' # 0xD1 -> CYRILLIC SMALL LETTER BE - '\u0432' # 0xD2 -> CYRILLIC SMALL LETTER VE - '\u0433' # 0xD3 -> CYRILLIC SMALL LETTER GHE - '\u0434' # 0xD4 -> CYRILLIC SMALL LETTER DE - '\u0435' # 0xD5 -> CYRILLIC SMALL LETTER IE - '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE - '\u0437' # 0xD7 -> CYRILLIC SMALL LETTER ZE - '\u0438' # 0xD8 -> CYRILLIC SMALL LETTER I - '\u0439' # 0xD9 -> CYRILLIC SMALL LETTER SHORT I - '\u043a' # 0xDA -> CYRILLIC SMALL LETTER KA - '\u043b' # 0xDB -> CYRILLIC SMALL LETTER EL - '\u043c' # 0xDC -> CYRILLIC SMALL LETTER EM - '\u043d' # 0xDD -> CYRILLIC SMALL LETTER EN - '\u043e' # 0xDE -> CYRILLIC SMALL LETTER O - '\u043f' # 0xDF -> CYRILLIC SMALL LETTER PE - '\u0440' # 0xE0 -> CYRILLIC SMALL LETTER ER - '\u0441' # 0xE1 -> CYRILLIC SMALL LETTER ES - '\u0442' # 0xE2 -> CYRILLIC SMALL LETTER TE - '\u0443' # 0xE3 -> CYRILLIC SMALL LETTER U - '\u0444' # 0xE4 -> CYRILLIC SMALL LETTER EF - '\u0445' # 0xE5 -> CYRILLIC SMALL LETTER HA - '\u0446' # 0xE6 -> CYRILLIC SMALL LETTER TSE - '\u0447' # 0xE7 -> CYRILLIC SMALL LETTER CHE - '\u0448' # 0xE8 -> CYRILLIC SMALL LETTER SHA - '\u0449' # 0xE9 -> CYRILLIC SMALL LETTER SHCHA - '\u044a' # 0xEA -> CYRILLIC SMALL LETTER HARD SIGN - '\u044b' # 0xEB -> CYRILLIC SMALL LETTER YERU - '\u044c' # 0xEC -> CYRILLIC SMALL LETTER SOFT SIGN - '\u044d' # 0xED -> CYRILLIC SMALL LETTER E - '\u044e' # 0xEE -> CYRILLIC SMALL LETTER YU - '\u044f' # 0xEF -> CYRILLIC SMALL LETTER YA - '\u2116' # 0xF0 -> NUMERO SIGN - '\u0451' # 0xF1 -> CYRILLIC SMALL LETTER IO - '\u0452' # 0xF2 -> CYRILLIC SMALL LETTER DJE - '\u0453' # 0xF3 -> CYRILLIC SMALL LETTER GJE - '\u0454' # 0xF4 -> CYRILLIC SMALL LETTER UKRAINIAN IE - '\u0455' # 0xF5 -> CYRILLIC SMALL LETTER DZE - '\u0456' # 0xF6 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0457' # 0xF7 -> CYRILLIC SMALL LETTER YI - '\u0458' # 0xF8 -> CYRILLIC SMALL LETTER JE - '\u0459' # 0xF9 -> CYRILLIC SMALL LETTER LJE - '\u045a' # 0xFA -> CYRILLIC SMALL LETTER NJE - '\u045b' # 0xFB -> CYRILLIC SMALL LETTER TSHE - '\u045c' # 0xFC -> CYRILLIC SMALL LETTER KJE - '\xa7' # 0xFD -> SECTION SIGN - '\u045e' # 0xFE -> CYRILLIC SMALL LETTER SHORT U - '\u045f' # 0xFF -> CYRILLIC SMALL LETTER DZHE -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_6.py b/python/Lib/encodings/iso8859_6.py deleted file mode 100644 index dce39b5..0000000 --- a/python/Lib/encodings/iso8859_6.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_6 generated from 'MAPPINGS/ISO8859/8859-6.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-6', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\ufffe' - '\ufffe' - '\ufffe' - '\xa4' # 0xA4 -> CURRENCY SIGN - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\u060c' # 0xAC -> ARABIC COMMA - '\xad' # 0xAD -> SOFT HYPHEN - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\u061b' # 0xBB -> ARABIC SEMICOLON - '\ufffe' - '\ufffe' - '\ufffe' - '\u061f' # 0xBF -> ARABIC QUESTION MARK - '\ufffe' - '\u0621' # 0xC1 -> ARABIC LETTER HAMZA - '\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE - '\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE - '\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE - '\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW - '\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE - '\u0627' # 0xC7 -> ARABIC LETTER ALEF - '\u0628' # 0xC8 -> ARABIC LETTER BEH - '\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA - '\u062a' # 0xCA -> ARABIC LETTER TEH - '\u062b' # 0xCB -> ARABIC LETTER THEH - '\u062c' # 0xCC -> ARABIC LETTER JEEM - '\u062d' # 0xCD -> ARABIC LETTER HAH - '\u062e' # 0xCE -> ARABIC LETTER KHAH - '\u062f' # 0xCF -> ARABIC LETTER DAL - '\u0630' # 0xD0 -> ARABIC LETTER THAL - '\u0631' # 0xD1 -> ARABIC LETTER REH - '\u0632' # 0xD2 -> ARABIC LETTER ZAIN - '\u0633' # 0xD3 -> ARABIC LETTER SEEN - '\u0634' # 0xD4 -> ARABIC LETTER SHEEN - '\u0635' # 0xD5 -> ARABIC LETTER SAD - '\u0636' # 0xD6 -> ARABIC LETTER DAD - '\u0637' # 0xD7 -> ARABIC LETTER TAH - '\u0638' # 0xD8 -> ARABIC LETTER ZAH - '\u0639' # 0xD9 -> ARABIC LETTER AIN - '\u063a' # 0xDA -> ARABIC LETTER GHAIN - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\u0640' # 0xE0 -> ARABIC TATWEEL - '\u0641' # 0xE1 -> ARABIC LETTER FEH - '\u0642' # 0xE2 -> ARABIC LETTER QAF - '\u0643' # 0xE3 -> ARABIC LETTER KAF - '\u0644' # 0xE4 -> ARABIC LETTER LAM - '\u0645' # 0xE5 -> ARABIC LETTER MEEM - '\u0646' # 0xE6 -> ARABIC LETTER NOON - '\u0647' # 0xE7 -> ARABIC LETTER HEH - '\u0648' # 0xE8 -> ARABIC LETTER WAW - '\u0649' # 0xE9 -> ARABIC LETTER ALEF MAKSURA - '\u064a' # 0xEA -> ARABIC LETTER YEH - '\u064b' # 0xEB -> ARABIC FATHATAN - '\u064c' # 0xEC -> ARABIC DAMMATAN - '\u064d' # 0xED -> ARABIC KASRATAN - '\u064e' # 0xEE -> ARABIC FATHA - '\u064f' # 0xEF -> ARABIC DAMMA - '\u0650' # 0xF0 -> ARABIC KASRA - '\u0651' # 0xF1 -> ARABIC SHADDA - '\u0652' # 0xF2 -> ARABIC SUKUN - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_7.py b/python/Lib/encodings/iso8859_7.py deleted file mode 100644 index 6d5982d..0000000 --- a/python/Lib/encodings/iso8859_7.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_7 generated from 'MAPPINGS/ISO8859/8859-7.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-7', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u2018' # 0xA1 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0xA2 -> RIGHT SINGLE QUOTATION MARK - '\xa3' # 0xA3 -> POUND SIGN - '\u20ac' # 0xA4 -> EURO SIGN - '\u20af' # 0xA5 -> DRACHMA SIGN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u037a' # 0xAA -> GREEK YPOGEGRAMMENI - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\ufffe' - '\u2015' # 0xAF -> HORIZONTAL BAR - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\u0384' # 0xB4 -> GREEK TONOS - '\u0385' # 0xB5 -> GREEK DIALYTIKA TONOS - '\u0386' # 0xB6 -> GREEK CAPITAL LETTER ALPHA WITH TONOS - '\xb7' # 0xB7 -> MIDDLE DOT - '\u0388' # 0xB8 -> GREEK CAPITAL LETTER EPSILON WITH TONOS - '\u0389' # 0xB9 -> GREEK CAPITAL LETTER ETA WITH TONOS - '\u038a' # 0xBA -> GREEK CAPITAL LETTER IOTA WITH TONOS - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u038c' # 0xBC -> GREEK CAPITAL LETTER OMICRON WITH TONOS - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\u038e' # 0xBE -> GREEK CAPITAL LETTER UPSILON WITH TONOS - '\u038f' # 0xBF -> GREEK CAPITAL LETTER OMEGA WITH TONOS - '\u0390' # 0xC0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - '\u0391' # 0xC1 -> GREEK CAPITAL LETTER ALPHA - '\u0392' # 0xC2 -> GREEK CAPITAL LETTER BETA - '\u0393' # 0xC3 -> GREEK CAPITAL LETTER GAMMA - '\u0394' # 0xC4 -> GREEK CAPITAL LETTER DELTA - '\u0395' # 0xC5 -> GREEK CAPITAL LETTER EPSILON - '\u0396' # 0xC6 -> GREEK CAPITAL LETTER ZETA - '\u0397' # 0xC7 -> GREEK CAPITAL LETTER ETA - '\u0398' # 0xC8 -> GREEK CAPITAL LETTER THETA - '\u0399' # 0xC9 -> GREEK CAPITAL LETTER IOTA - '\u039a' # 0xCA -> GREEK CAPITAL LETTER KAPPA - '\u039b' # 0xCB -> GREEK CAPITAL LETTER LAMDA - '\u039c' # 0xCC -> GREEK CAPITAL LETTER MU - '\u039d' # 0xCD -> GREEK CAPITAL LETTER NU - '\u039e' # 0xCE -> GREEK CAPITAL LETTER XI - '\u039f' # 0xCF -> GREEK CAPITAL LETTER OMICRON - '\u03a0' # 0xD0 -> GREEK CAPITAL LETTER PI - '\u03a1' # 0xD1 -> GREEK CAPITAL LETTER RHO - '\ufffe' - '\u03a3' # 0xD3 -> GREEK CAPITAL LETTER SIGMA - '\u03a4' # 0xD4 -> GREEK CAPITAL LETTER TAU - '\u03a5' # 0xD5 -> GREEK CAPITAL LETTER UPSILON - '\u03a6' # 0xD6 -> GREEK CAPITAL LETTER PHI - '\u03a7' # 0xD7 -> GREEK CAPITAL LETTER CHI - '\u03a8' # 0xD8 -> GREEK CAPITAL LETTER PSI - '\u03a9' # 0xD9 -> GREEK CAPITAL LETTER OMEGA - '\u03aa' # 0xDA -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - '\u03ab' # 0xDB -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - '\u03ac' # 0xDC -> GREEK SMALL LETTER ALPHA WITH TONOS - '\u03ad' # 0xDD -> GREEK SMALL LETTER EPSILON WITH TONOS - '\u03ae' # 0xDE -> GREEK SMALL LETTER ETA WITH TONOS - '\u03af' # 0xDF -> GREEK SMALL LETTER IOTA WITH TONOS - '\u03b0' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - '\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA - '\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA - '\u03b3' # 0xE3 -> GREEK SMALL LETTER GAMMA - '\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA - '\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON - '\u03b6' # 0xE6 -> GREEK SMALL LETTER ZETA - '\u03b7' # 0xE7 -> GREEK SMALL LETTER ETA - '\u03b8' # 0xE8 -> GREEK SMALL LETTER THETA - '\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA - '\u03ba' # 0xEA -> GREEK SMALL LETTER KAPPA - '\u03bb' # 0xEB -> GREEK SMALL LETTER LAMDA - '\u03bc' # 0xEC -> GREEK SMALL LETTER MU - '\u03bd' # 0xED -> GREEK SMALL LETTER NU - '\u03be' # 0xEE -> GREEK SMALL LETTER XI - '\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON - '\u03c0' # 0xF0 -> GREEK SMALL LETTER PI - '\u03c1' # 0xF1 -> GREEK SMALL LETTER RHO - '\u03c2' # 0xF2 -> GREEK SMALL LETTER FINAL SIGMA - '\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA - '\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU - '\u03c5' # 0xF5 -> GREEK SMALL LETTER UPSILON - '\u03c6' # 0xF6 -> GREEK SMALL LETTER PHI - '\u03c7' # 0xF7 -> GREEK SMALL LETTER CHI - '\u03c8' # 0xF8 -> GREEK SMALL LETTER PSI - '\u03c9' # 0xF9 -> GREEK SMALL LETTER OMEGA - '\u03ca' # 0xFA -> GREEK SMALL LETTER IOTA WITH DIALYTIKA - '\u03cb' # 0xFB -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA - '\u03cc' # 0xFC -> GREEK SMALL LETTER OMICRON WITH TONOS - '\u03cd' # 0xFD -> GREEK SMALL LETTER UPSILON WITH TONOS - '\u03ce' # 0xFE -> GREEK SMALL LETTER OMEGA WITH TONOS - '\ufffe' -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_8.py b/python/Lib/encodings/iso8859_8.py deleted file mode 100644 index 3418ace..0000000 --- a/python/Lib/encodings/iso8859_8.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_8 generated from 'MAPPINGS/ISO8859/8859-8.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-8', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\ufffe' - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\xa5' # 0xA5 -> YEN SIGN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\xd7' # 0xAA -> MULTIPLICATION SIGN - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xaf' # 0xAF -> MACRON - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xb8' # 0xB8 -> CEDILLA - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\xf7' # 0xBA -> DIVISION SIGN - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\u2017' # 0xDF -> DOUBLE LOW LINE - '\u05d0' # 0xE0 -> HEBREW LETTER ALEF - '\u05d1' # 0xE1 -> HEBREW LETTER BET - '\u05d2' # 0xE2 -> HEBREW LETTER GIMEL - '\u05d3' # 0xE3 -> HEBREW LETTER DALET - '\u05d4' # 0xE4 -> HEBREW LETTER HE - '\u05d5' # 0xE5 -> HEBREW LETTER VAV - '\u05d6' # 0xE6 -> HEBREW LETTER ZAYIN - '\u05d7' # 0xE7 -> HEBREW LETTER HET - '\u05d8' # 0xE8 -> HEBREW LETTER TET - '\u05d9' # 0xE9 -> HEBREW LETTER YOD - '\u05da' # 0xEA -> HEBREW LETTER FINAL KAF - '\u05db' # 0xEB -> HEBREW LETTER KAF - '\u05dc' # 0xEC -> HEBREW LETTER LAMED - '\u05dd' # 0xED -> HEBREW LETTER FINAL MEM - '\u05de' # 0xEE -> HEBREW LETTER MEM - '\u05df' # 0xEF -> HEBREW LETTER FINAL NUN - '\u05e0' # 0xF0 -> HEBREW LETTER NUN - '\u05e1' # 0xF1 -> HEBREW LETTER SAMEKH - '\u05e2' # 0xF2 -> HEBREW LETTER AYIN - '\u05e3' # 0xF3 -> HEBREW LETTER FINAL PE - '\u05e4' # 0xF4 -> HEBREW LETTER PE - '\u05e5' # 0xF5 -> HEBREW LETTER FINAL TSADI - '\u05e6' # 0xF6 -> HEBREW LETTER TSADI - '\u05e7' # 0xF7 -> HEBREW LETTER QOF - '\u05e8' # 0xF8 -> HEBREW LETTER RESH - '\u05e9' # 0xF9 -> HEBREW LETTER SHIN - '\u05ea' # 0xFA -> HEBREW LETTER TAV - '\ufffe' - '\ufffe' - '\u200e' # 0xFD -> LEFT-TO-RIGHT MARK - '\u200f' # 0xFE -> RIGHT-TO-LEFT MARK - '\ufffe' -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/iso8859_9.py b/python/Lib/encodings/iso8859_9.py deleted file mode 100644 index 725387f..0000000 --- a/python/Lib/encodings/iso8859_9.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec iso8859_9 generated from 'MAPPINGS/ISO8859/8859-9.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-9', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\xa5' # 0xA5 -> YEN SIGN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xaf' # 0xAF -> MACRON - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xb8' # 0xB8 -> CEDILLA - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS - '\xbf' # 0xBF -> INVERTED QUESTION MARK - '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\u011e' # 0xD0 -> LATIN CAPITAL LETTER G WITH BREVE - '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE - '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\u0130' # 0xDD -> LATIN CAPITAL LETTER I WITH DOT ABOVE - '\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S - '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe6' # 0xE6 -> LATIN SMALL LETTER AE - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\u011f' # 0xF0 -> LATIN SMALL LETTER G WITH BREVE - '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE - '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE - '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\u0131' # 0xFD -> LATIN SMALL LETTER DOTLESS I - '\u015f' # 0xFE -> LATIN SMALL LETTER S WITH CEDILLA - '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/johab.py b/python/Lib/encodings/johab.py deleted file mode 100644 index 5c767cd..0000000 --- a/python/Lib/encodings/johab.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# johab.py: Python Unicode Codec for JOHAB -# -# Written by Hye-Shik Chang -# - -import _codecs_kr, codecs -import _multibytecodec as mbc - -codec = _codecs_kr.getcodec('johab') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='johab', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/koi8_r.py b/python/Lib/encodings/koi8_r.py deleted file mode 100644 index c6d057d..0000000 --- a/python/Lib/encodings/koi8_r.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec koi8_r generated from 'MAPPINGS/VENDORS/MISC/KOI8-R.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='koi8-r', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u2500' # 0x80 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u2502' # 0x81 -> BOX DRAWINGS LIGHT VERTICAL - '\u250c' # 0x82 -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2510' # 0x83 -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x84 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2518' # 0x85 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u251c' # 0x86 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2524' # 0x87 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u252c' # 0x88 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u2534' # 0x89 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u253c' # 0x8A -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u2580' # 0x8B -> UPPER HALF BLOCK - '\u2584' # 0x8C -> LOWER HALF BLOCK - '\u2588' # 0x8D -> FULL BLOCK - '\u258c' # 0x8E -> LEFT HALF BLOCK - '\u2590' # 0x8F -> RIGHT HALF BLOCK - '\u2591' # 0x90 -> LIGHT SHADE - '\u2592' # 0x91 -> MEDIUM SHADE - '\u2593' # 0x92 -> DARK SHADE - '\u2320' # 0x93 -> TOP HALF INTEGRAL - '\u25a0' # 0x94 -> BLACK SQUARE - '\u2219' # 0x95 -> BULLET OPERATOR - '\u221a' # 0x96 -> SQUARE ROOT - '\u2248' # 0x97 -> ALMOST EQUAL TO - '\u2264' # 0x98 -> LESS-THAN OR EQUAL TO - '\u2265' # 0x99 -> GREATER-THAN OR EQUAL TO - '\xa0' # 0x9A -> NO-BREAK SPACE - '\u2321' # 0x9B -> BOTTOM HALF INTEGRAL - '\xb0' # 0x9C -> DEGREE SIGN - '\xb2' # 0x9D -> SUPERSCRIPT TWO - '\xb7' # 0x9E -> MIDDLE DOT - '\xf7' # 0x9F -> DIVISION SIGN - '\u2550' # 0xA0 -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u2551' # 0xA1 -> BOX DRAWINGS DOUBLE VERTICAL - '\u2552' # 0xA2 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO - '\u2553' # 0xA4 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - '\u2554' # 0xA5 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u2555' # 0xA6 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - '\u2556' # 0xA7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - '\u2557' # 0xA8 -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u2558' # 0xA9 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2559' # 0xAA -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u255a' # 0xAB -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u255b' # 0xAC -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u255c' # 0xAD -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - '\u255d' # 0xAE -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255e' # 0xAF -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0xB0 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u2560' # 0xB1 -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2561' # 0xB2 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO - '\u2562' # 0xB4 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - '\u2563' # 0xB5 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u2564' # 0xB6 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - '\u2565' # 0xB7 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - '\u2566' # 0xB8 -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2567' # 0xB9 -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0xBA -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2569' # 0xBB -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u256a' # 0xBC -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u256b' # 0xBD -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - '\u256c' # 0xBE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\xa9' # 0xBF -> COPYRIGHT SIGN - '\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU - '\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A - '\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE - '\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE - '\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE - '\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE - '\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF - '\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE - '\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA - '\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I - '\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I - '\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA - '\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL - '\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM - '\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN - '\u043e' # 0xCF -> CYRILLIC SMALL LETTER O - '\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE - '\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA - '\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER - '\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES - '\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE - '\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U - '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE - '\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE - '\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN - '\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU - '\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE - '\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA - '\u044d' # 0xDC -> CYRILLIC SMALL LETTER E - '\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA - '\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE - '\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN - '\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU - '\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A - '\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE - '\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE - '\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE - '\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE - '\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF - '\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE - '\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA - '\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I - '\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I - '\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA - '\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL - '\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM - '\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN - '\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O - '\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE - '\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA - '\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER - '\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES - '\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE - '\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U - '\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE - '\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE - '\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN - '\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU - '\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE - '\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA - '\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E - '\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA - '\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE - '\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/koi8_t.py b/python/Lib/encodings/koi8_t.py deleted file mode 100644 index 300ea50..0000000 --- a/python/Lib/encodings/koi8_t.py +++ /dev/null @@ -1,308 +0,0 @@ -""" Python Character Mapping Codec koi8_t -""" -# http://ru.wikipedia.org/wiki/КОИ-8 -# http://www.opensource.apple.com/source/libiconv/libiconv-4/libiconv/tests/KOI8-T.TXT - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='koi8-t', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u049b' # 0x80 -> CYRILLIC SMALL LETTER KA WITH DESCENDER - '\u0493' # 0x81 -> CYRILLIC SMALL LETTER GHE WITH STROKE - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\u0492' # 0x83 -> CYRILLIC CAPITAL LETTER GHE WITH STROKE - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\ufffe' # 0x88 -> UNDEFINED - '\u2030' # 0x89 -> PER MILLE SIGN - '\u04b3' # 0x8A -> CYRILLIC SMALL LETTER HA WITH DESCENDER - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u04b2' # 0x8C -> CYRILLIC CAPITAL LETTER HA WITH DESCENDER - '\u04b7' # 0x8D -> CYRILLIC SMALL LETTER CHE WITH DESCENDER - '\u04b6' # 0x8E -> CYRILLIC CAPITAL LETTER CHE WITH DESCENDER - '\ufffe' # 0x8F -> UNDEFINED - '\u049a' # 0x90 -> CYRILLIC CAPITAL LETTER KA WITH DESCENDER - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\ufffe' # 0x98 -> UNDEFINED - '\u2122' # 0x99 -> TRADE MARK SIGN - '\ufffe' # 0x9A -> UNDEFINED - '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\ufffe' # 0x9C -> UNDEFINED - '\ufffe' # 0x9D -> UNDEFINED - '\ufffe' # 0x9E -> UNDEFINED - '\ufffe' # 0x9F -> UNDEFINED - '\ufffe' # 0xA0 -> UNDEFINED - '\u04ef' # 0xA1 -> CYRILLIC SMALL LETTER U WITH MACRON - '\u04ee' # 0xA2 -> CYRILLIC CAPITAL LETTER U WITH MACRON - '\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO - '\xa4' # 0xA4 -> CURRENCY SIGN - '\u04e3' # 0xA5 -> CYRILLIC SMALL LETTER I WITH MACRON - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\ufffe' # 0xA8 -> UNDEFINED - '\ufffe' # 0xA9 -> UNDEFINED - '\ufffe' # 0xAA -> UNDEFINED - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\ufffe' # 0xAF -> UNDEFINED - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO - '\ufffe' # 0xB4 -> UNDEFINED - '\u04e2' # 0xB5 -> CYRILLIC CAPITAL LETTER I WITH MACRON - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\ufffe' # 0xB8 -> UNDEFINED - '\u2116' # 0xB9 -> NUMERO SIGN - '\ufffe' # 0xBA -> UNDEFINED - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\ufffe' # 0xBC -> UNDEFINED - '\ufffe' # 0xBD -> UNDEFINED - '\ufffe' # 0xBE -> UNDEFINED - '\xa9' # 0xBF -> COPYRIGHT SIGN - '\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU - '\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A - '\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE - '\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE - '\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE - '\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE - '\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF - '\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE - '\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA - '\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I - '\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I - '\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA - '\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL - '\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM - '\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN - '\u043e' # 0xCF -> CYRILLIC SMALL LETTER O - '\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE - '\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA - '\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER - '\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES - '\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE - '\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U - '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE - '\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE - '\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN - '\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU - '\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE - '\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA - '\u044d' # 0xDC -> CYRILLIC SMALL LETTER E - '\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA - '\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE - '\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN - '\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU - '\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A - '\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE - '\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE - '\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE - '\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE - '\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF - '\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE - '\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA - '\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I - '\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I - '\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA - '\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL - '\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM - '\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN - '\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O - '\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE - '\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA - '\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER - '\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES - '\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE - '\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U - '\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE - '\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE - '\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN - '\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU - '\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE - '\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA - '\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E - '\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA - '\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE - '\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/koi8_u.py b/python/Lib/encodings/koi8_u.py deleted file mode 100644 index 72d6383..0000000 --- a/python/Lib/encodings/koi8_u.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec koi8_u generated from 'python-mappings/KOI8-U.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='koi8-u', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u2500' # 0x80 -> BOX DRAWINGS LIGHT HORIZONTAL - '\u2502' # 0x81 -> BOX DRAWINGS LIGHT VERTICAL - '\u250c' # 0x82 -> BOX DRAWINGS LIGHT DOWN AND RIGHT - '\u2510' # 0x83 -> BOX DRAWINGS LIGHT DOWN AND LEFT - '\u2514' # 0x84 -> BOX DRAWINGS LIGHT UP AND RIGHT - '\u2518' # 0x85 -> BOX DRAWINGS LIGHT UP AND LEFT - '\u251c' # 0x86 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT - '\u2524' # 0x87 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT - '\u252c' # 0x88 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - '\u2534' # 0x89 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL - '\u253c' # 0x8A -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - '\u2580' # 0x8B -> UPPER HALF BLOCK - '\u2584' # 0x8C -> LOWER HALF BLOCK - '\u2588' # 0x8D -> FULL BLOCK - '\u258c' # 0x8E -> LEFT HALF BLOCK - '\u2590' # 0x8F -> RIGHT HALF BLOCK - '\u2591' # 0x90 -> LIGHT SHADE - '\u2592' # 0x91 -> MEDIUM SHADE - '\u2593' # 0x92 -> DARK SHADE - '\u2320' # 0x93 -> TOP HALF INTEGRAL - '\u25a0' # 0x94 -> BLACK SQUARE - '\u2219' # 0x95 -> BULLET OPERATOR - '\u221a' # 0x96 -> SQUARE ROOT - '\u2248' # 0x97 -> ALMOST EQUAL TO - '\u2264' # 0x98 -> LESS-THAN OR EQUAL TO - '\u2265' # 0x99 -> GREATER-THAN OR EQUAL TO - '\xa0' # 0x9A -> NO-BREAK SPACE - '\u2321' # 0x9B -> BOTTOM HALF INTEGRAL - '\xb0' # 0x9C -> DEGREE SIGN - '\xb2' # 0x9D -> SUPERSCRIPT TWO - '\xb7' # 0x9E -> MIDDLE DOT - '\xf7' # 0x9F -> DIVISION SIGN - '\u2550' # 0xA0 -> BOX DRAWINGS DOUBLE HORIZONTAL - '\u2551' # 0xA1 -> BOX DRAWINGS DOUBLE VERTICAL - '\u2552' # 0xA2 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - '\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO - '\u0454' # 0xA4 -> CYRILLIC SMALL LETTER UKRAINIAN IE - '\u2554' # 0xA5 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT - '\u0456' # 0xA6 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0457' # 0xA7 -> CYRILLIC SMALL LETTER YI (UKRAINIAN) - '\u2557' # 0xA8 -> BOX DRAWINGS DOUBLE DOWN AND LEFT - '\u2558' # 0xA9 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - '\u2559' # 0xAA -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - '\u255a' # 0xAB -> BOX DRAWINGS DOUBLE UP AND RIGHT - '\u255b' # 0xAC -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - '\u0491' # 0xAD -> CYRILLIC SMALL LETTER UKRAINIAN GHE WITH UPTURN - '\u255d' # 0xAE -> BOX DRAWINGS DOUBLE UP AND LEFT - '\u255e' # 0xAF -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - '\u255f' # 0xB0 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - '\u2560' # 0xB1 -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - '\u2561' # 0xB2 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - '\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO - '\u0404' # 0xB4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE - '\u2563' # 0xB5 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT - '\u0406' # 0xB6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0407' # 0xB7 -> CYRILLIC CAPITAL LETTER YI (UKRAINIAN) - '\u2566' # 0xB8 -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - '\u2567' # 0xB9 -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - '\u2568' # 0xBA -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - '\u2569' # 0xBB -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL - '\u256a' # 0xBC -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - '\u0490' # 0xBD -> CYRILLIC CAPITAL LETTER UKRAINIAN GHE WITH UPTURN - '\u256c' # 0xBE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - '\xa9' # 0xBF -> COPYRIGHT SIGN - '\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU - '\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A - '\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE - '\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE - '\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE - '\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE - '\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF - '\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE - '\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA - '\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I - '\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I - '\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA - '\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL - '\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM - '\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN - '\u043e' # 0xCF -> CYRILLIC SMALL LETTER O - '\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE - '\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA - '\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER - '\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES - '\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE - '\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U - '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE - '\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE - '\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN - '\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU - '\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE - '\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA - '\u044d' # 0xDC -> CYRILLIC SMALL LETTER E - '\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA - '\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE - '\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN - '\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU - '\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A - '\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE - '\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE - '\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE - '\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE - '\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF - '\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE - '\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA - '\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I - '\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I - '\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA - '\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL - '\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM - '\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN - '\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O - '\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE - '\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA - '\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER - '\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES - '\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE - '\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U - '\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE - '\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE - '\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN - '\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU - '\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE - '\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA - '\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E - '\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA - '\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE - '\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/kz1048.py b/python/Lib/encodings/kz1048.py deleted file mode 100644 index 95142ac..0000000 --- a/python/Lib/encodings/kz1048.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec kz1048 generated from 'MAPPINGS/VENDORS/MISC/KZ1048.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self, input, errors='strict'): - return codecs.charmap_encode(input, errors, encoding_table) - - def decode(self, input, errors='strict'): - return codecs.charmap_decode(input, errors, decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input, self.errors, encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input, self.errors, decoding_table)[0] - -class StreamWriter(Codec, codecs.StreamWriter): - pass - -class StreamReader(Codec, codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='kz1048', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u0402' # 0x80 -> CYRILLIC CAPITAL LETTER DJE - '\u0403' # 0x81 -> CYRILLIC CAPITAL LETTER GJE - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\u0453' # 0x83 -> CYRILLIC SMALL LETTER GJE - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\u20ac' # 0x88 -> EURO SIGN - '\u2030' # 0x89 -> PER MILLE SIGN - '\u0409' # 0x8A -> CYRILLIC CAPITAL LETTER LJE - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u040a' # 0x8C -> CYRILLIC CAPITAL LETTER NJE - '\u049a' # 0x8D -> CYRILLIC CAPITAL LETTER KA WITH DESCENDER - '\u04ba' # 0x8E -> CYRILLIC CAPITAL LETTER SHHA - '\u040f' # 0x8F -> CYRILLIC CAPITAL LETTER DZHE - '\u0452' # 0x90 -> CYRILLIC SMALL LETTER DJE - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\ufffe' # 0x98 -> UNDEFINED - '\u2122' # 0x99 -> TRADE MARK SIGN - '\u0459' # 0x9A -> CYRILLIC SMALL LETTER LJE - '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\u045a' # 0x9C -> CYRILLIC SMALL LETTER NJE - '\u049b' # 0x9D -> CYRILLIC SMALL LETTER KA WITH DESCENDER - '\u04bb' # 0x9E -> CYRILLIC SMALL LETTER SHHA - '\u045f' # 0x9F -> CYRILLIC SMALL LETTER DZHE - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u04b0' # 0xA1 -> CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE - '\u04b1' # 0xA2 -> CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE - '\u04d8' # 0xA3 -> CYRILLIC CAPITAL LETTER SCHWA - '\xa4' # 0xA4 -> CURRENCY SIGN - '\u04e8' # 0xA5 -> CYRILLIC CAPITAL LETTER BARRED O - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\u0401' # 0xA8 -> CYRILLIC CAPITAL LETTER IO - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u0492' # 0xAA -> CYRILLIC CAPITAL LETTER GHE WITH STROKE - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\u04ae' # 0xAF -> CYRILLIC CAPITAL LETTER STRAIGHT U - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\u0406' # 0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0456' # 0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - '\u04e9' # 0xB4 -> CYRILLIC SMALL LETTER BARRED O - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\u0451' # 0xB8 -> CYRILLIC SMALL LETTER IO - '\u2116' # 0xB9 -> NUMERO SIGN - '\u0493' # 0xBA -> CYRILLIC SMALL LETTER GHE WITH STROKE - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u04d9' # 0xBC -> CYRILLIC SMALL LETTER SCHWA - '\u04a2' # 0xBD -> CYRILLIC CAPITAL LETTER EN WITH DESCENDER - '\u04a3' # 0xBE -> CYRILLIC SMALL LETTER EN WITH DESCENDER - '\u04af' # 0xBF -> CYRILLIC SMALL LETTER STRAIGHT U - '\u0410' # 0xC0 -> CYRILLIC CAPITAL LETTER A - '\u0411' # 0xC1 -> CYRILLIC CAPITAL LETTER BE - '\u0412' # 0xC2 -> CYRILLIC CAPITAL LETTER VE - '\u0413' # 0xC3 -> CYRILLIC CAPITAL LETTER GHE - '\u0414' # 0xC4 -> CYRILLIC CAPITAL LETTER DE - '\u0415' # 0xC5 -> CYRILLIC CAPITAL LETTER IE - '\u0416' # 0xC6 -> CYRILLIC CAPITAL LETTER ZHE - '\u0417' # 0xC7 -> CYRILLIC CAPITAL LETTER ZE - '\u0418' # 0xC8 -> CYRILLIC CAPITAL LETTER I - '\u0419' # 0xC9 -> CYRILLIC CAPITAL LETTER SHORT I - '\u041a' # 0xCA -> CYRILLIC CAPITAL LETTER KA - '\u041b' # 0xCB -> CYRILLIC CAPITAL LETTER EL - '\u041c' # 0xCC -> CYRILLIC CAPITAL LETTER EM - '\u041d' # 0xCD -> CYRILLIC CAPITAL LETTER EN - '\u041e' # 0xCE -> CYRILLIC CAPITAL LETTER O - '\u041f' # 0xCF -> CYRILLIC CAPITAL LETTER PE - '\u0420' # 0xD0 -> CYRILLIC CAPITAL LETTER ER - '\u0421' # 0xD1 -> CYRILLIC CAPITAL LETTER ES - '\u0422' # 0xD2 -> CYRILLIC CAPITAL LETTER TE - '\u0423' # 0xD3 -> CYRILLIC CAPITAL LETTER U - '\u0424' # 0xD4 -> CYRILLIC CAPITAL LETTER EF - '\u0425' # 0xD5 -> CYRILLIC CAPITAL LETTER HA - '\u0426' # 0xD6 -> CYRILLIC CAPITAL LETTER TSE - '\u0427' # 0xD7 -> CYRILLIC CAPITAL LETTER CHE - '\u0428' # 0xD8 -> CYRILLIC CAPITAL LETTER SHA - '\u0429' # 0xD9 -> CYRILLIC CAPITAL LETTER SHCHA - '\u042a' # 0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN - '\u042b' # 0xDB -> CYRILLIC CAPITAL LETTER YERU - '\u042c' # 0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN - '\u042d' # 0xDD -> CYRILLIC CAPITAL LETTER E - '\u042e' # 0xDE -> CYRILLIC CAPITAL LETTER YU - '\u042f' # 0xDF -> CYRILLIC CAPITAL LETTER YA - '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A - '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE - '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE - '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE - '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE - '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE - '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE - '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE - '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I - '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I - '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA - '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL - '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM - '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN - '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O - '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE - '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER - '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES - '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE - '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U - '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF - '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA - '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE - '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE - '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA - '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA - '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN - '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU - '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN - '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E - '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU - '\u044f' # 0xFF -> CYRILLIC SMALL LETTER YA -) - -### Encoding table -encoding_table = codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/latin_1.py b/python/Lib/encodings/latin_1.py deleted file mode 100644 index a6193bc..0000000 --- a/python/Lib/encodings/latin_1.py +++ /dev/null @@ -1,50 +0,0 @@ -""" Python 'latin-1' Codec - - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -""" -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - # Note: Binding these as C functions will result in the class not - # converting them to methods. This is intended. - encode = codecs.latin_1_encode - decode = codecs.latin_1_decode - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.latin_1_encode(input,self.errors)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.latin_1_decode(input,self.errors)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -class StreamConverter(StreamWriter,StreamReader): - - encode = codecs.latin_1_decode - decode = codecs.latin_1_encode - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='iso8859-1', - encode=Codec.encode, - decode=Codec.decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/mac_arabic.py b/python/Lib/encodings/mac_arabic.py deleted file mode 100644 index 6385b2a..0000000 --- a/python/Lib/encodings/mac_arabic.py +++ /dev/null @@ -1,698 +0,0 @@ -""" Python Character Mapping Codec generated from 'VENDORS/APPLE/ARABIC.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_map)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mac-arabic', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - -### Decoding Map - -decoding_map = codecs.make_identity_dict(range(256)) -decoding_map.update({ - 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x0081: 0x00a0, # NO-BREAK SPACE, right-left - 0x0082: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x0083: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE - 0x0084: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE - 0x0085: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x0086: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x0087: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE - 0x0088: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE - 0x0089: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x008a: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS - 0x008b: 0x06ba, # ARABIC LETTER NOON GHUNNA - 0x008c: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left - 0x008d: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA - 0x008e: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE - 0x008f: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE - 0x0090: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x0091: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS - 0x0092: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE - 0x0093: 0x2026, # HORIZONTAL ELLIPSIS, right-left - 0x0094: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x0095: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS - 0x0096: 0x00f1, # LATIN SMALL LETTER N WITH TILDE - 0x0097: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE - 0x0098: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left - 0x0099: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x009a: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS - 0x009b: 0x00f7, # DIVISION SIGN, right-left - 0x009c: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE - 0x009d: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE - 0x009e: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x009f: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS - 0x00a0: 0x0020, # SPACE, right-left - 0x00a1: 0x0021, # EXCLAMATION MARK, right-left - 0x00a2: 0x0022, # QUOTATION MARK, right-left - 0x00a3: 0x0023, # NUMBER SIGN, right-left - 0x00a4: 0x0024, # DOLLAR SIGN, right-left - 0x00a5: 0x066a, # ARABIC PERCENT SIGN - 0x00a6: 0x0026, # AMPERSAND, right-left - 0x00a7: 0x0027, # APOSTROPHE, right-left - 0x00a8: 0x0028, # LEFT PARENTHESIS, right-left - 0x00a9: 0x0029, # RIGHT PARENTHESIS, right-left - 0x00aa: 0x002a, # ASTERISK, right-left - 0x00ab: 0x002b, # PLUS SIGN, right-left - 0x00ac: 0x060c, # ARABIC COMMA - 0x00ad: 0x002d, # HYPHEN-MINUS, right-left - 0x00ae: 0x002e, # FULL STOP, right-left - 0x00af: 0x002f, # SOLIDUS, right-left - 0x00b0: 0x0660, # ARABIC-INDIC DIGIT ZERO, right-left (need override) - 0x00b1: 0x0661, # ARABIC-INDIC DIGIT ONE, right-left (need override) - 0x00b2: 0x0662, # ARABIC-INDIC DIGIT TWO, right-left (need override) - 0x00b3: 0x0663, # ARABIC-INDIC DIGIT THREE, right-left (need override) - 0x00b4: 0x0664, # ARABIC-INDIC DIGIT FOUR, right-left (need override) - 0x00b5: 0x0665, # ARABIC-INDIC DIGIT FIVE, right-left (need override) - 0x00b6: 0x0666, # ARABIC-INDIC DIGIT SIX, right-left (need override) - 0x00b7: 0x0667, # ARABIC-INDIC DIGIT SEVEN, right-left (need override) - 0x00b8: 0x0668, # ARABIC-INDIC DIGIT EIGHT, right-left (need override) - 0x00b9: 0x0669, # ARABIC-INDIC DIGIT NINE, right-left (need override) - 0x00ba: 0x003a, # COLON, right-left - 0x00bb: 0x061b, # ARABIC SEMICOLON - 0x00bc: 0x003c, # LESS-THAN SIGN, right-left - 0x00bd: 0x003d, # EQUALS SIGN, right-left - 0x00be: 0x003e, # GREATER-THAN SIGN, right-left - 0x00bf: 0x061f, # ARABIC QUESTION MARK - 0x00c0: 0x274a, # EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left - 0x00c1: 0x0621, # ARABIC LETTER HAMZA - 0x00c2: 0x0622, # ARABIC LETTER ALEF WITH MADDA ABOVE - 0x00c3: 0x0623, # ARABIC LETTER ALEF WITH HAMZA ABOVE - 0x00c4: 0x0624, # ARABIC LETTER WAW WITH HAMZA ABOVE - 0x00c5: 0x0625, # ARABIC LETTER ALEF WITH HAMZA BELOW - 0x00c6: 0x0626, # ARABIC LETTER YEH WITH HAMZA ABOVE - 0x00c7: 0x0627, # ARABIC LETTER ALEF - 0x00c8: 0x0628, # ARABIC LETTER BEH - 0x00c9: 0x0629, # ARABIC LETTER TEH MARBUTA - 0x00ca: 0x062a, # ARABIC LETTER TEH - 0x00cb: 0x062b, # ARABIC LETTER THEH - 0x00cc: 0x062c, # ARABIC LETTER JEEM - 0x00cd: 0x062d, # ARABIC LETTER HAH - 0x00ce: 0x062e, # ARABIC LETTER KHAH - 0x00cf: 0x062f, # ARABIC LETTER DAL - 0x00d0: 0x0630, # ARABIC LETTER THAL - 0x00d1: 0x0631, # ARABIC LETTER REH - 0x00d2: 0x0632, # ARABIC LETTER ZAIN - 0x00d3: 0x0633, # ARABIC LETTER SEEN - 0x00d4: 0x0634, # ARABIC LETTER SHEEN - 0x00d5: 0x0635, # ARABIC LETTER SAD - 0x00d6: 0x0636, # ARABIC LETTER DAD - 0x00d7: 0x0637, # ARABIC LETTER TAH - 0x00d8: 0x0638, # ARABIC LETTER ZAH - 0x00d9: 0x0639, # ARABIC LETTER AIN - 0x00da: 0x063a, # ARABIC LETTER GHAIN - 0x00db: 0x005b, # LEFT SQUARE BRACKET, right-left - 0x00dc: 0x005c, # REVERSE SOLIDUS, right-left - 0x00dd: 0x005d, # RIGHT SQUARE BRACKET, right-left - 0x00de: 0x005e, # CIRCUMFLEX ACCENT, right-left - 0x00df: 0x005f, # LOW LINE, right-left - 0x00e0: 0x0640, # ARABIC TATWEEL - 0x00e1: 0x0641, # ARABIC LETTER FEH - 0x00e2: 0x0642, # ARABIC LETTER QAF - 0x00e3: 0x0643, # ARABIC LETTER KAF - 0x00e4: 0x0644, # ARABIC LETTER LAM - 0x00e5: 0x0645, # ARABIC LETTER MEEM - 0x00e6: 0x0646, # ARABIC LETTER NOON - 0x00e7: 0x0647, # ARABIC LETTER HEH - 0x00e8: 0x0648, # ARABIC LETTER WAW - 0x00e9: 0x0649, # ARABIC LETTER ALEF MAKSURA - 0x00ea: 0x064a, # ARABIC LETTER YEH - 0x00eb: 0x064b, # ARABIC FATHATAN - 0x00ec: 0x064c, # ARABIC DAMMATAN - 0x00ed: 0x064d, # ARABIC KASRATAN - 0x00ee: 0x064e, # ARABIC FATHA - 0x00ef: 0x064f, # ARABIC DAMMA - 0x00f0: 0x0650, # ARABIC KASRA - 0x00f1: 0x0651, # ARABIC SHADDA - 0x00f2: 0x0652, # ARABIC SUKUN - 0x00f3: 0x067e, # ARABIC LETTER PEH - 0x00f4: 0x0679, # ARABIC LETTER TTEH - 0x00f5: 0x0686, # ARABIC LETTER TCHEH - 0x00f6: 0x06d5, # ARABIC LETTER AE - 0x00f7: 0x06a4, # ARABIC LETTER VEH - 0x00f8: 0x06af, # ARABIC LETTER GAF - 0x00f9: 0x0688, # ARABIC LETTER DDAL - 0x00fa: 0x0691, # ARABIC LETTER RREH - 0x00fb: 0x007b, # LEFT CURLY BRACKET, right-left - 0x00fc: 0x007c, # VERTICAL LINE, right-left - 0x00fd: 0x007d, # RIGHT CURLY BRACKET, right-left - 0x00fe: 0x0698, # ARABIC LETTER JEH - 0x00ff: 0x06d2, # ARABIC LETTER YEH BARREE -}) - -### Decoding Table - -decoding_table = ( - '\x00' # 0x0000 -> CONTROL CHARACTER - '\x01' # 0x0001 -> CONTROL CHARACTER - '\x02' # 0x0002 -> CONTROL CHARACTER - '\x03' # 0x0003 -> CONTROL CHARACTER - '\x04' # 0x0004 -> CONTROL CHARACTER - '\x05' # 0x0005 -> CONTROL CHARACTER - '\x06' # 0x0006 -> CONTROL CHARACTER - '\x07' # 0x0007 -> CONTROL CHARACTER - '\x08' # 0x0008 -> CONTROL CHARACTER - '\t' # 0x0009 -> CONTROL CHARACTER - '\n' # 0x000a -> CONTROL CHARACTER - '\x0b' # 0x000b -> CONTROL CHARACTER - '\x0c' # 0x000c -> CONTROL CHARACTER - '\r' # 0x000d -> CONTROL CHARACTER - '\x0e' # 0x000e -> CONTROL CHARACTER - '\x0f' # 0x000f -> CONTROL CHARACTER - '\x10' # 0x0010 -> CONTROL CHARACTER - '\x11' # 0x0011 -> CONTROL CHARACTER - '\x12' # 0x0012 -> CONTROL CHARACTER - '\x13' # 0x0013 -> CONTROL CHARACTER - '\x14' # 0x0014 -> CONTROL CHARACTER - '\x15' # 0x0015 -> CONTROL CHARACTER - '\x16' # 0x0016 -> CONTROL CHARACTER - '\x17' # 0x0017 -> CONTROL CHARACTER - '\x18' # 0x0018 -> CONTROL CHARACTER - '\x19' # 0x0019 -> CONTROL CHARACTER - '\x1a' # 0x001a -> CONTROL CHARACTER - '\x1b' # 0x001b -> CONTROL CHARACTER - '\x1c' # 0x001c -> CONTROL CHARACTER - '\x1d' # 0x001d -> CONTROL CHARACTER - '\x1e' # 0x001e -> CONTROL CHARACTER - '\x1f' # 0x001f -> CONTROL CHARACTER - ' ' # 0x0020 -> SPACE, left-right - '!' # 0x0021 -> EXCLAMATION MARK, left-right - '"' # 0x0022 -> QUOTATION MARK, left-right - '#' # 0x0023 -> NUMBER SIGN, left-right - '$' # 0x0024 -> DOLLAR SIGN, left-right - '%' # 0x0025 -> PERCENT SIGN, left-right - '&' # 0x0026 -> AMPERSAND, left-right - "'" # 0x0027 -> APOSTROPHE, left-right - '(' # 0x0028 -> LEFT PARENTHESIS, left-right - ')' # 0x0029 -> RIGHT PARENTHESIS, left-right - '*' # 0x002a -> ASTERISK, left-right - '+' # 0x002b -> PLUS SIGN, left-right - ',' # 0x002c -> COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR - '-' # 0x002d -> HYPHEN-MINUS, left-right - '.' # 0x002e -> FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR - '/' # 0x002f -> SOLIDUS, left-right - '0' # 0x0030 -> DIGIT ZERO; in Arabic-script context, displayed as 0x0660 ARABIC-INDIC DIGIT ZERO - '1' # 0x0031 -> DIGIT ONE; in Arabic-script context, displayed as 0x0661 ARABIC-INDIC DIGIT ONE - '2' # 0x0032 -> DIGIT TWO; in Arabic-script context, displayed as 0x0662 ARABIC-INDIC DIGIT TWO - '3' # 0x0033 -> DIGIT THREE; in Arabic-script context, displayed as 0x0663 ARABIC-INDIC DIGIT THREE - '4' # 0x0034 -> DIGIT FOUR; in Arabic-script context, displayed as 0x0664 ARABIC-INDIC DIGIT FOUR - '5' # 0x0035 -> DIGIT FIVE; in Arabic-script context, displayed as 0x0665 ARABIC-INDIC DIGIT FIVE - '6' # 0x0036 -> DIGIT SIX; in Arabic-script context, displayed as 0x0666 ARABIC-INDIC DIGIT SIX - '7' # 0x0037 -> DIGIT SEVEN; in Arabic-script context, displayed as 0x0667 ARABIC-INDIC DIGIT SEVEN - '8' # 0x0038 -> DIGIT EIGHT; in Arabic-script context, displayed as 0x0668 ARABIC-INDIC DIGIT EIGHT - '9' # 0x0039 -> DIGIT NINE; in Arabic-script context, displayed as 0x0669 ARABIC-INDIC DIGIT NINE - ':' # 0x003a -> COLON, left-right - ';' # 0x003b -> SEMICOLON, left-right - '<' # 0x003c -> LESS-THAN SIGN, left-right - '=' # 0x003d -> EQUALS SIGN, left-right - '>' # 0x003e -> GREATER-THAN SIGN, left-right - '?' # 0x003f -> QUESTION MARK, left-right - '@' # 0x0040 -> COMMERCIAL AT - 'A' # 0x0041 -> LATIN CAPITAL LETTER A - 'B' # 0x0042 -> LATIN CAPITAL LETTER B - 'C' # 0x0043 -> LATIN CAPITAL LETTER C - 'D' # 0x0044 -> LATIN CAPITAL LETTER D - 'E' # 0x0045 -> LATIN CAPITAL LETTER E - 'F' # 0x0046 -> LATIN CAPITAL LETTER F - 'G' # 0x0047 -> LATIN CAPITAL LETTER G - 'H' # 0x0048 -> LATIN CAPITAL LETTER H - 'I' # 0x0049 -> LATIN CAPITAL LETTER I - 'J' # 0x004a -> LATIN CAPITAL LETTER J - 'K' # 0x004b -> LATIN CAPITAL LETTER K - 'L' # 0x004c -> LATIN CAPITAL LETTER L - 'M' # 0x004d -> LATIN CAPITAL LETTER M - 'N' # 0x004e -> LATIN CAPITAL LETTER N - 'O' # 0x004f -> LATIN CAPITAL LETTER O - 'P' # 0x0050 -> LATIN CAPITAL LETTER P - 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q - 'R' # 0x0052 -> LATIN CAPITAL LETTER R - 'S' # 0x0053 -> LATIN CAPITAL LETTER S - 'T' # 0x0054 -> LATIN CAPITAL LETTER T - 'U' # 0x0055 -> LATIN CAPITAL LETTER U - 'V' # 0x0056 -> LATIN CAPITAL LETTER V - 'W' # 0x0057 -> LATIN CAPITAL LETTER W - 'X' # 0x0058 -> LATIN CAPITAL LETTER X - 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y - 'Z' # 0x005a -> LATIN CAPITAL LETTER Z - '[' # 0x005b -> LEFT SQUARE BRACKET, left-right - '\\' # 0x005c -> REVERSE SOLIDUS, left-right - ']' # 0x005d -> RIGHT SQUARE BRACKET, left-right - '^' # 0x005e -> CIRCUMFLEX ACCENT, left-right - '_' # 0x005f -> LOW LINE, left-right - '`' # 0x0060 -> GRAVE ACCENT - 'a' # 0x0061 -> LATIN SMALL LETTER A - 'b' # 0x0062 -> LATIN SMALL LETTER B - 'c' # 0x0063 -> LATIN SMALL LETTER C - 'd' # 0x0064 -> LATIN SMALL LETTER D - 'e' # 0x0065 -> LATIN SMALL LETTER E - 'f' # 0x0066 -> LATIN SMALL LETTER F - 'g' # 0x0067 -> LATIN SMALL LETTER G - 'h' # 0x0068 -> LATIN SMALL LETTER H - 'i' # 0x0069 -> LATIN SMALL LETTER I - 'j' # 0x006a -> LATIN SMALL LETTER J - 'k' # 0x006b -> LATIN SMALL LETTER K - 'l' # 0x006c -> LATIN SMALL LETTER L - 'm' # 0x006d -> LATIN SMALL LETTER M - 'n' # 0x006e -> LATIN SMALL LETTER N - 'o' # 0x006f -> LATIN SMALL LETTER O - 'p' # 0x0070 -> LATIN SMALL LETTER P - 'q' # 0x0071 -> LATIN SMALL LETTER Q - 'r' # 0x0072 -> LATIN SMALL LETTER R - 's' # 0x0073 -> LATIN SMALL LETTER S - 't' # 0x0074 -> LATIN SMALL LETTER T - 'u' # 0x0075 -> LATIN SMALL LETTER U - 'v' # 0x0076 -> LATIN SMALL LETTER V - 'w' # 0x0077 -> LATIN SMALL LETTER W - 'x' # 0x0078 -> LATIN SMALL LETTER X - 'y' # 0x0079 -> LATIN SMALL LETTER Y - 'z' # 0x007a -> LATIN SMALL LETTER Z - '{' # 0x007b -> LEFT CURLY BRACKET, left-right - '|' # 0x007c -> VERTICAL LINE, left-right - '}' # 0x007d -> RIGHT CURLY BRACKET, left-right - '~' # 0x007e -> TILDE - '\x7f' # 0x007f -> CONTROL CHARACTER - '\xc4' # 0x0080 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xa0' # 0x0081 -> NO-BREAK SPACE, right-left - '\xc7' # 0x0082 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc9' # 0x0083 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xd1' # 0x0084 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd6' # 0x0085 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x0086 -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xe1' # 0x0087 -> LATIN SMALL LETTER A WITH ACUTE - '\xe0' # 0x0088 -> LATIN SMALL LETTER A WITH GRAVE - '\xe2' # 0x0089 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x008a -> LATIN SMALL LETTER A WITH DIAERESIS - '\u06ba' # 0x008b -> ARABIC LETTER NOON GHUNNA - '\xab' # 0x008c -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left - '\xe7' # 0x008d -> LATIN SMALL LETTER C WITH CEDILLA - '\xe9' # 0x008e -> LATIN SMALL LETTER E WITH ACUTE - '\xe8' # 0x008f -> LATIN SMALL LETTER E WITH GRAVE - '\xea' # 0x0090 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x0091 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xed' # 0x0092 -> LATIN SMALL LETTER I WITH ACUTE - '\u2026' # 0x0093 -> HORIZONTAL ELLIPSIS, right-left - '\xee' # 0x0094 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x0095 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf1' # 0x0096 -> LATIN SMALL LETTER N WITH TILDE - '\xf3' # 0x0097 -> LATIN SMALL LETTER O WITH ACUTE - '\xbb' # 0x0098 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left - '\xf4' # 0x0099 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x009a -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0x009b -> DIVISION SIGN, right-left - '\xfa' # 0x009c -> LATIN SMALL LETTER U WITH ACUTE - '\xf9' # 0x009d -> LATIN SMALL LETTER U WITH GRAVE - '\xfb' # 0x009e -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0x009f -> LATIN SMALL LETTER U WITH DIAERESIS - ' ' # 0x00a0 -> SPACE, right-left - '!' # 0x00a1 -> EXCLAMATION MARK, right-left - '"' # 0x00a2 -> QUOTATION MARK, right-left - '#' # 0x00a3 -> NUMBER SIGN, right-left - '$' # 0x00a4 -> DOLLAR SIGN, right-left - '\u066a' # 0x00a5 -> ARABIC PERCENT SIGN - '&' # 0x00a6 -> AMPERSAND, right-left - "'" # 0x00a7 -> APOSTROPHE, right-left - '(' # 0x00a8 -> LEFT PARENTHESIS, right-left - ')' # 0x00a9 -> RIGHT PARENTHESIS, right-left - '*' # 0x00aa -> ASTERISK, right-left - '+' # 0x00ab -> PLUS SIGN, right-left - '\u060c' # 0x00ac -> ARABIC COMMA - '-' # 0x00ad -> HYPHEN-MINUS, right-left - '.' # 0x00ae -> FULL STOP, right-left - '/' # 0x00af -> SOLIDUS, right-left - '\u0660' # 0x00b0 -> ARABIC-INDIC DIGIT ZERO, right-left (need override) - '\u0661' # 0x00b1 -> ARABIC-INDIC DIGIT ONE, right-left (need override) - '\u0662' # 0x00b2 -> ARABIC-INDIC DIGIT TWO, right-left (need override) - '\u0663' # 0x00b3 -> ARABIC-INDIC DIGIT THREE, right-left (need override) - '\u0664' # 0x00b4 -> ARABIC-INDIC DIGIT FOUR, right-left (need override) - '\u0665' # 0x00b5 -> ARABIC-INDIC DIGIT FIVE, right-left (need override) - '\u0666' # 0x00b6 -> ARABIC-INDIC DIGIT SIX, right-left (need override) - '\u0667' # 0x00b7 -> ARABIC-INDIC DIGIT SEVEN, right-left (need override) - '\u0668' # 0x00b8 -> ARABIC-INDIC DIGIT EIGHT, right-left (need override) - '\u0669' # 0x00b9 -> ARABIC-INDIC DIGIT NINE, right-left (need override) - ':' # 0x00ba -> COLON, right-left - '\u061b' # 0x00bb -> ARABIC SEMICOLON - '<' # 0x00bc -> LESS-THAN SIGN, right-left - '=' # 0x00bd -> EQUALS SIGN, right-left - '>' # 0x00be -> GREATER-THAN SIGN, right-left - '\u061f' # 0x00bf -> ARABIC QUESTION MARK - '\u274a' # 0x00c0 -> EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left - '\u0621' # 0x00c1 -> ARABIC LETTER HAMZA - '\u0622' # 0x00c2 -> ARABIC LETTER ALEF WITH MADDA ABOVE - '\u0623' # 0x00c3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE - '\u0624' # 0x00c4 -> ARABIC LETTER WAW WITH HAMZA ABOVE - '\u0625' # 0x00c5 -> ARABIC LETTER ALEF WITH HAMZA BELOW - '\u0626' # 0x00c6 -> ARABIC LETTER YEH WITH HAMZA ABOVE - '\u0627' # 0x00c7 -> ARABIC LETTER ALEF - '\u0628' # 0x00c8 -> ARABIC LETTER BEH - '\u0629' # 0x00c9 -> ARABIC LETTER TEH MARBUTA - '\u062a' # 0x00ca -> ARABIC LETTER TEH - '\u062b' # 0x00cb -> ARABIC LETTER THEH - '\u062c' # 0x00cc -> ARABIC LETTER JEEM - '\u062d' # 0x00cd -> ARABIC LETTER HAH - '\u062e' # 0x00ce -> ARABIC LETTER KHAH - '\u062f' # 0x00cf -> ARABIC LETTER DAL - '\u0630' # 0x00d0 -> ARABIC LETTER THAL - '\u0631' # 0x00d1 -> ARABIC LETTER REH - '\u0632' # 0x00d2 -> ARABIC LETTER ZAIN - '\u0633' # 0x00d3 -> ARABIC LETTER SEEN - '\u0634' # 0x00d4 -> ARABIC LETTER SHEEN - '\u0635' # 0x00d5 -> ARABIC LETTER SAD - '\u0636' # 0x00d6 -> ARABIC LETTER DAD - '\u0637' # 0x00d7 -> ARABIC LETTER TAH - '\u0638' # 0x00d8 -> ARABIC LETTER ZAH - '\u0639' # 0x00d9 -> ARABIC LETTER AIN - '\u063a' # 0x00da -> ARABIC LETTER GHAIN - '[' # 0x00db -> LEFT SQUARE BRACKET, right-left - '\\' # 0x00dc -> REVERSE SOLIDUS, right-left - ']' # 0x00dd -> RIGHT SQUARE BRACKET, right-left - '^' # 0x00de -> CIRCUMFLEX ACCENT, right-left - '_' # 0x00df -> LOW LINE, right-left - '\u0640' # 0x00e0 -> ARABIC TATWEEL - '\u0641' # 0x00e1 -> ARABIC LETTER FEH - '\u0642' # 0x00e2 -> ARABIC LETTER QAF - '\u0643' # 0x00e3 -> ARABIC LETTER KAF - '\u0644' # 0x00e4 -> ARABIC LETTER LAM - '\u0645' # 0x00e5 -> ARABIC LETTER MEEM - '\u0646' # 0x00e6 -> ARABIC LETTER NOON - '\u0647' # 0x00e7 -> ARABIC LETTER HEH - '\u0648' # 0x00e8 -> ARABIC LETTER WAW - '\u0649' # 0x00e9 -> ARABIC LETTER ALEF MAKSURA - '\u064a' # 0x00ea -> ARABIC LETTER YEH - '\u064b' # 0x00eb -> ARABIC FATHATAN - '\u064c' # 0x00ec -> ARABIC DAMMATAN - '\u064d' # 0x00ed -> ARABIC KASRATAN - '\u064e' # 0x00ee -> ARABIC FATHA - '\u064f' # 0x00ef -> ARABIC DAMMA - '\u0650' # 0x00f0 -> ARABIC KASRA - '\u0651' # 0x00f1 -> ARABIC SHADDA - '\u0652' # 0x00f2 -> ARABIC SUKUN - '\u067e' # 0x00f3 -> ARABIC LETTER PEH - '\u0679' # 0x00f4 -> ARABIC LETTER TTEH - '\u0686' # 0x00f5 -> ARABIC LETTER TCHEH - '\u06d5' # 0x00f6 -> ARABIC LETTER AE - '\u06a4' # 0x00f7 -> ARABIC LETTER VEH - '\u06af' # 0x00f8 -> ARABIC LETTER GAF - '\u0688' # 0x00f9 -> ARABIC LETTER DDAL - '\u0691' # 0x00fa -> ARABIC LETTER RREH - '{' # 0x00fb -> LEFT CURLY BRACKET, right-left - '|' # 0x00fc -> VERTICAL LINE, right-left - '}' # 0x00fd -> RIGHT CURLY BRACKET, right-left - '\u0698' # 0x00fe -> ARABIC LETTER JEH - '\u06d2' # 0x00ff -> ARABIC LETTER YEH BARREE -) - -### Encoding Map - -encoding_map = { - 0x0000: 0x0000, # CONTROL CHARACTER - 0x0001: 0x0001, # CONTROL CHARACTER - 0x0002: 0x0002, # CONTROL CHARACTER - 0x0003: 0x0003, # CONTROL CHARACTER - 0x0004: 0x0004, # CONTROL CHARACTER - 0x0005: 0x0005, # CONTROL CHARACTER - 0x0006: 0x0006, # CONTROL CHARACTER - 0x0007: 0x0007, # CONTROL CHARACTER - 0x0008: 0x0008, # CONTROL CHARACTER - 0x0009: 0x0009, # CONTROL CHARACTER - 0x000a: 0x000a, # CONTROL CHARACTER - 0x000b: 0x000b, # CONTROL CHARACTER - 0x000c: 0x000c, # CONTROL CHARACTER - 0x000d: 0x000d, # CONTROL CHARACTER - 0x000e: 0x000e, # CONTROL CHARACTER - 0x000f: 0x000f, # CONTROL CHARACTER - 0x0010: 0x0010, # CONTROL CHARACTER - 0x0011: 0x0011, # CONTROL CHARACTER - 0x0012: 0x0012, # CONTROL CHARACTER - 0x0013: 0x0013, # CONTROL CHARACTER - 0x0014: 0x0014, # CONTROL CHARACTER - 0x0015: 0x0015, # CONTROL CHARACTER - 0x0016: 0x0016, # CONTROL CHARACTER - 0x0017: 0x0017, # CONTROL CHARACTER - 0x0018: 0x0018, # CONTROL CHARACTER - 0x0019: 0x0019, # CONTROL CHARACTER - 0x001a: 0x001a, # CONTROL CHARACTER - 0x001b: 0x001b, # CONTROL CHARACTER - 0x001c: 0x001c, # CONTROL CHARACTER - 0x001d: 0x001d, # CONTROL CHARACTER - 0x001e: 0x001e, # CONTROL CHARACTER - 0x001f: 0x001f, # CONTROL CHARACTER - 0x0020: 0x0020, # SPACE, left-right - 0x0020: 0x00a0, # SPACE, right-left - 0x0021: 0x0021, # EXCLAMATION MARK, left-right - 0x0021: 0x00a1, # EXCLAMATION MARK, right-left - 0x0022: 0x0022, # QUOTATION MARK, left-right - 0x0022: 0x00a2, # QUOTATION MARK, right-left - 0x0023: 0x0023, # NUMBER SIGN, left-right - 0x0023: 0x00a3, # NUMBER SIGN, right-left - 0x0024: 0x0024, # DOLLAR SIGN, left-right - 0x0024: 0x00a4, # DOLLAR SIGN, right-left - 0x0025: 0x0025, # PERCENT SIGN, left-right - 0x0026: 0x0026, # AMPERSAND, left-right - 0x0026: 0x00a6, # AMPERSAND, right-left - 0x0027: 0x0027, # APOSTROPHE, left-right - 0x0027: 0x00a7, # APOSTROPHE, right-left - 0x0028: 0x0028, # LEFT PARENTHESIS, left-right - 0x0028: 0x00a8, # LEFT PARENTHESIS, right-left - 0x0029: 0x0029, # RIGHT PARENTHESIS, left-right - 0x0029: 0x00a9, # RIGHT PARENTHESIS, right-left - 0x002a: 0x002a, # ASTERISK, left-right - 0x002a: 0x00aa, # ASTERISK, right-left - 0x002b: 0x002b, # PLUS SIGN, left-right - 0x002b: 0x00ab, # PLUS SIGN, right-left - 0x002c: 0x002c, # COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR - 0x002d: 0x002d, # HYPHEN-MINUS, left-right - 0x002d: 0x00ad, # HYPHEN-MINUS, right-left - 0x002e: 0x002e, # FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR - 0x002e: 0x00ae, # FULL STOP, right-left - 0x002f: 0x002f, # SOLIDUS, left-right - 0x002f: 0x00af, # SOLIDUS, right-left - 0x0030: 0x0030, # DIGIT ZERO; in Arabic-script context, displayed as 0x0660 ARABIC-INDIC DIGIT ZERO - 0x0031: 0x0031, # DIGIT ONE; in Arabic-script context, displayed as 0x0661 ARABIC-INDIC DIGIT ONE - 0x0032: 0x0032, # DIGIT TWO; in Arabic-script context, displayed as 0x0662 ARABIC-INDIC DIGIT TWO - 0x0033: 0x0033, # DIGIT THREE; in Arabic-script context, displayed as 0x0663 ARABIC-INDIC DIGIT THREE - 0x0034: 0x0034, # DIGIT FOUR; in Arabic-script context, displayed as 0x0664 ARABIC-INDIC DIGIT FOUR - 0x0035: 0x0035, # DIGIT FIVE; in Arabic-script context, displayed as 0x0665 ARABIC-INDIC DIGIT FIVE - 0x0036: 0x0036, # DIGIT SIX; in Arabic-script context, displayed as 0x0666 ARABIC-INDIC DIGIT SIX - 0x0037: 0x0037, # DIGIT SEVEN; in Arabic-script context, displayed as 0x0667 ARABIC-INDIC DIGIT SEVEN - 0x0038: 0x0038, # DIGIT EIGHT; in Arabic-script context, displayed as 0x0668 ARABIC-INDIC DIGIT EIGHT - 0x0039: 0x0039, # DIGIT NINE; in Arabic-script context, displayed as 0x0669 ARABIC-INDIC DIGIT NINE - 0x003a: 0x003a, # COLON, left-right - 0x003a: 0x00ba, # COLON, right-left - 0x003b: 0x003b, # SEMICOLON, left-right - 0x003c: 0x003c, # LESS-THAN SIGN, left-right - 0x003c: 0x00bc, # LESS-THAN SIGN, right-left - 0x003d: 0x003d, # EQUALS SIGN, left-right - 0x003d: 0x00bd, # EQUALS SIGN, right-left - 0x003e: 0x003e, # GREATER-THAN SIGN, left-right - 0x003e: 0x00be, # GREATER-THAN SIGN, right-left - 0x003f: 0x003f, # QUESTION MARK, left-right - 0x0040: 0x0040, # COMMERCIAL AT - 0x0041: 0x0041, # LATIN CAPITAL LETTER A - 0x0042: 0x0042, # LATIN CAPITAL LETTER B - 0x0043: 0x0043, # LATIN CAPITAL LETTER C - 0x0044: 0x0044, # LATIN CAPITAL LETTER D - 0x0045: 0x0045, # LATIN CAPITAL LETTER E - 0x0046: 0x0046, # LATIN CAPITAL LETTER F - 0x0047: 0x0047, # LATIN CAPITAL LETTER G - 0x0048: 0x0048, # LATIN CAPITAL LETTER H - 0x0049: 0x0049, # LATIN CAPITAL LETTER I - 0x004a: 0x004a, # LATIN CAPITAL LETTER J - 0x004b: 0x004b, # LATIN CAPITAL LETTER K - 0x004c: 0x004c, # LATIN CAPITAL LETTER L - 0x004d: 0x004d, # LATIN CAPITAL LETTER M - 0x004e: 0x004e, # LATIN CAPITAL LETTER N - 0x004f: 0x004f, # LATIN CAPITAL LETTER O - 0x0050: 0x0050, # LATIN CAPITAL LETTER P - 0x0051: 0x0051, # LATIN CAPITAL LETTER Q - 0x0052: 0x0052, # LATIN CAPITAL LETTER R - 0x0053: 0x0053, # LATIN CAPITAL LETTER S - 0x0054: 0x0054, # LATIN CAPITAL LETTER T - 0x0055: 0x0055, # LATIN CAPITAL LETTER U - 0x0056: 0x0056, # LATIN CAPITAL LETTER V - 0x0057: 0x0057, # LATIN CAPITAL LETTER W - 0x0058: 0x0058, # LATIN CAPITAL LETTER X - 0x0059: 0x0059, # LATIN CAPITAL LETTER Y - 0x005a: 0x005a, # LATIN CAPITAL LETTER Z - 0x005b: 0x005b, # LEFT SQUARE BRACKET, left-right - 0x005b: 0x00db, # LEFT SQUARE BRACKET, right-left - 0x005c: 0x005c, # REVERSE SOLIDUS, left-right - 0x005c: 0x00dc, # REVERSE SOLIDUS, right-left - 0x005d: 0x005d, # RIGHT SQUARE BRACKET, left-right - 0x005d: 0x00dd, # RIGHT SQUARE BRACKET, right-left - 0x005e: 0x005e, # CIRCUMFLEX ACCENT, left-right - 0x005e: 0x00de, # CIRCUMFLEX ACCENT, right-left - 0x005f: 0x005f, # LOW LINE, left-right - 0x005f: 0x00df, # LOW LINE, right-left - 0x0060: 0x0060, # GRAVE ACCENT - 0x0061: 0x0061, # LATIN SMALL LETTER A - 0x0062: 0x0062, # LATIN SMALL LETTER B - 0x0063: 0x0063, # LATIN SMALL LETTER C - 0x0064: 0x0064, # LATIN SMALL LETTER D - 0x0065: 0x0065, # LATIN SMALL LETTER E - 0x0066: 0x0066, # LATIN SMALL LETTER F - 0x0067: 0x0067, # LATIN SMALL LETTER G - 0x0068: 0x0068, # LATIN SMALL LETTER H - 0x0069: 0x0069, # LATIN SMALL LETTER I - 0x006a: 0x006a, # LATIN SMALL LETTER J - 0x006b: 0x006b, # LATIN SMALL LETTER K - 0x006c: 0x006c, # LATIN SMALL LETTER L - 0x006d: 0x006d, # LATIN SMALL LETTER M - 0x006e: 0x006e, # LATIN SMALL LETTER N - 0x006f: 0x006f, # LATIN SMALL LETTER O - 0x0070: 0x0070, # LATIN SMALL LETTER P - 0x0071: 0x0071, # LATIN SMALL LETTER Q - 0x0072: 0x0072, # LATIN SMALL LETTER R - 0x0073: 0x0073, # LATIN SMALL LETTER S - 0x0074: 0x0074, # LATIN SMALL LETTER T - 0x0075: 0x0075, # LATIN SMALL LETTER U - 0x0076: 0x0076, # LATIN SMALL LETTER V - 0x0077: 0x0077, # LATIN SMALL LETTER W - 0x0078: 0x0078, # LATIN SMALL LETTER X - 0x0079: 0x0079, # LATIN SMALL LETTER Y - 0x007a: 0x007a, # LATIN SMALL LETTER Z - 0x007b: 0x007b, # LEFT CURLY BRACKET, left-right - 0x007b: 0x00fb, # LEFT CURLY BRACKET, right-left - 0x007c: 0x007c, # VERTICAL LINE, left-right - 0x007c: 0x00fc, # VERTICAL LINE, right-left - 0x007d: 0x007d, # RIGHT CURLY BRACKET, left-right - 0x007d: 0x00fd, # RIGHT CURLY BRACKET, right-left - 0x007e: 0x007e, # TILDE - 0x007f: 0x007f, # CONTROL CHARACTER - 0x00a0: 0x0081, # NO-BREAK SPACE, right-left - 0x00ab: 0x008c, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left - 0x00bb: 0x0098, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left - 0x00c4: 0x0080, # LATIN CAPITAL LETTER A WITH DIAERESIS - 0x00c7: 0x0082, # LATIN CAPITAL LETTER C WITH CEDILLA - 0x00c9: 0x0083, # LATIN CAPITAL LETTER E WITH ACUTE - 0x00d1: 0x0084, # LATIN CAPITAL LETTER N WITH TILDE - 0x00d6: 0x0085, # LATIN CAPITAL LETTER O WITH DIAERESIS - 0x00dc: 0x0086, # LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00e0: 0x0088, # LATIN SMALL LETTER A WITH GRAVE - 0x00e1: 0x0087, # LATIN SMALL LETTER A WITH ACUTE - 0x00e2: 0x0089, # LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x00e4: 0x008a, # LATIN SMALL LETTER A WITH DIAERESIS - 0x00e7: 0x008d, # LATIN SMALL LETTER C WITH CEDILLA - 0x00e8: 0x008f, # LATIN SMALL LETTER E WITH GRAVE - 0x00e9: 0x008e, # LATIN SMALL LETTER E WITH ACUTE - 0x00ea: 0x0090, # LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x00eb: 0x0091, # LATIN SMALL LETTER E WITH DIAERESIS - 0x00ed: 0x0092, # LATIN SMALL LETTER I WITH ACUTE - 0x00ee: 0x0094, # LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x00ef: 0x0095, # LATIN SMALL LETTER I WITH DIAERESIS - 0x00f1: 0x0096, # LATIN SMALL LETTER N WITH TILDE - 0x00f3: 0x0097, # LATIN SMALL LETTER O WITH ACUTE - 0x00f4: 0x0099, # LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x00f6: 0x009a, # LATIN SMALL LETTER O WITH DIAERESIS - 0x00f7: 0x009b, # DIVISION SIGN, right-left - 0x00f9: 0x009d, # LATIN SMALL LETTER U WITH GRAVE - 0x00fa: 0x009c, # LATIN SMALL LETTER U WITH ACUTE - 0x00fb: 0x009e, # LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x00fc: 0x009f, # LATIN SMALL LETTER U WITH DIAERESIS - 0x060c: 0x00ac, # ARABIC COMMA - 0x061b: 0x00bb, # ARABIC SEMICOLON - 0x061f: 0x00bf, # ARABIC QUESTION MARK - 0x0621: 0x00c1, # ARABIC LETTER HAMZA - 0x0622: 0x00c2, # ARABIC LETTER ALEF WITH MADDA ABOVE - 0x0623: 0x00c3, # ARABIC LETTER ALEF WITH HAMZA ABOVE - 0x0624: 0x00c4, # ARABIC LETTER WAW WITH HAMZA ABOVE - 0x0625: 0x00c5, # ARABIC LETTER ALEF WITH HAMZA BELOW - 0x0626: 0x00c6, # ARABIC LETTER YEH WITH HAMZA ABOVE - 0x0627: 0x00c7, # ARABIC LETTER ALEF - 0x0628: 0x00c8, # ARABIC LETTER BEH - 0x0629: 0x00c9, # ARABIC LETTER TEH MARBUTA - 0x062a: 0x00ca, # ARABIC LETTER TEH - 0x062b: 0x00cb, # ARABIC LETTER THEH - 0x062c: 0x00cc, # ARABIC LETTER JEEM - 0x062d: 0x00cd, # ARABIC LETTER HAH - 0x062e: 0x00ce, # ARABIC LETTER KHAH - 0x062f: 0x00cf, # ARABIC LETTER DAL - 0x0630: 0x00d0, # ARABIC LETTER THAL - 0x0631: 0x00d1, # ARABIC LETTER REH - 0x0632: 0x00d2, # ARABIC LETTER ZAIN - 0x0633: 0x00d3, # ARABIC LETTER SEEN - 0x0634: 0x00d4, # ARABIC LETTER SHEEN - 0x0635: 0x00d5, # ARABIC LETTER SAD - 0x0636: 0x00d6, # ARABIC LETTER DAD - 0x0637: 0x00d7, # ARABIC LETTER TAH - 0x0638: 0x00d8, # ARABIC LETTER ZAH - 0x0639: 0x00d9, # ARABIC LETTER AIN - 0x063a: 0x00da, # ARABIC LETTER GHAIN - 0x0640: 0x00e0, # ARABIC TATWEEL - 0x0641: 0x00e1, # ARABIC LETTER FEH - 0x0642: 0x00e2, # ARABIC LETTER QAF - 0x0643: 0x00e3, # ARABIC LETTER KAF - 0x0644: 0x00e4, # ARABIC LETTER LAM - 0x0645: 0x00e5, # ARABIC LETTER MEEM - 0x0646: 0x00e6, # ARABIC LETTER NOON - 0x0647: 0x00e7, # ARABIC LETTER HEH - 0x0648: 0x00e8, # ARABIC LETTER WAW - 0x0649: 0x00e9, # ARABIC LETTER ALEF MAKSURA - 0x064a: 0x00ea, # ARABIC LETTER YEH - 0x064b: 0x00eb, # ARABIC FATHATAN - 0x064c: 0x00ec, # ARABIC DAMMATAN - 0x064d: 0x00ed, # ARABIC KASRATAN - 0x064e: 0x00ee, # ARABIC FATHA - 0x064f: 0x00ef, # ARABIC DAMMA - 0x0650: 0x00f0, # ARABIC KASRA - 0x0651: 0x00f1, # ARABIC SHADDA - 0x0652: 0x00f2, # ARABIC SUKUN - 0x0660: 0x00b0, # ARABIC-INDIC DIGIT ZERO, right-left (need override) - 0x0661: 0x00b1, # ARABIC-INDIC DIGIT ONE, right-left (need override) - 0x0662: 0x00b2, # ARABIC-INDIC DIGIT TWO, right-left (need override) - 0x0663: 0x00b3, # ARABIC-INDIC DIGIT THREE, right-left (need override) - 0x0664: 0x00b4, # ARABIC-INDIC DIGIT FOUR, right-left (need override) - 0x0665: 0x00b5, # ARABIC-INDIC DIGIT FIVE, right-left (need override) - 0x0666: 0x00b6, # ARABIC-INDIC DIGIT SIX, right-left (need override) - 0x0667: 0x00b7, # ARABIC-INDIC DIGIT SEVEN, right-left (need override) - 0x0668: 0x00b8, # ARABIC-INDIC DIGIT EIGHT, right-left (need override) - 0x0669: 0x00b9, # ARABIC-INDIC DIGIT NINE, right-left (need override) - 0x066a: 0x00a5, # ARABIC PERCENT SIGN - 0x0679: 0x00f4, # ARABIC LETTER TTEH - 0x067e: 0x00f3, # ARABIC LETTER PEH - 0x0686: 0x00f5, # ARABIC LETTER TCHEH - 0x0688: 0x00f9, # ARABIC LETTER DDAL - 0x0691: 0x00fa, # ARABIC LETTER RREH - 0x0698: 0x00fe, # ARABIC LETTER JEH - 0x06a4: 0x00f7, # ARABIC LETTER VEH - 0x06af: 0x00f8, # ARABIC LETTER GAF - 0x06ba: 0x008b, # ARABIC LETTER NOON GHUNNA - 0x06d2: 0x00ff, # ARABIC LETTER YEH BARREE - 0x06d5: 0x00f6, # ARABIC LETTER AE - 0x2026: 0x0093, # HORIZONTAL ELLIPSIS, right-left - 0x274a: 0x00c0, # EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left -} diff --git a/python/Lib/encodings/mac_croatian.py b/python/Lib/encodings/mac_croatian.py deleted file mode 100644 index 86fdf8b..0000000 --- a/python/Lib/encodings/mac_croatian.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec mac_croatian generated from 'MAPPINGS/VENDORS/APPLE/CROATIAN.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mac-croatian', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> CONTROL CHARACTER - '\x01' # 0x01 -> CONTROL CHARACTER - '\x02' # 0x02 -> CONTROL CHARACTER - '\x03' # 0x03 -> CONTROL CHARACTER - '\x04' # 0x04 -> CONTROL CHARACTER - '\x05' # 0x05 -> CONTROL CHARACTER - '\x06' # 0x06 -> CONTROL CHARACTER - '\x07' # 0x07 -> CONTROL CHARACTER - '\x08' # 0x08 -> CONTROL CHARACTER - '\t' # 0x09 -> CONTROL CHARACTER - '\n' # 0x0A -> CONTROL CHARACTER - '\x0b' # 0x0B -> CONTROL CHARACTER - '\x0c' # 0x0C -> CONTROL CHARACTER - '\r' # 0x0D -> CONTROL CHARACTER - '\x0e' # 0x0E -> CONTROL CHARACTER - '\x0f' # 0x0F -> CONTROL CHARACTER - '\x10' # 0x10 -> CONTROL CHARACTER - '\x11' # 0x11 -> CONTROL CHARACTER - '\x12' # 0x12 -> CONTROL CHARACTER - '\x13' # 0x13 -> CONTROL CHARACTER - '\x14' # 0x14 -> CONTROL CHARACTER - '\x15' # 0x15 -> CONTROL CHARACTER - '\x16' # 0x16 -> CONTROL CHARACTER - '\x17' # 0x17 -> CONTROL CHARACTER - '\x18' # 0x18 -> CONTROL CHARACTER - '\x19' # 0x19 -> CONTROL CHARACTER - '\x1a' # 0x1A -> CONTROL CHARACTER - '\x1b' # 0x1B -> CONTROL CHARACTER - '\x1c' # 0x1C -> CONTROL CHARACTER - '\x1d' # 0x1D -> CONTROL CHARACTER - '\x1e' # 0x1E -> CONTROL CHARACTER - '\x1f' # 0x1F -> CONTROL CHARACTER - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> CONTROL CHARACTER - '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE - '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE - '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE - '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA - '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE - '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE - '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE - '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE - '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE - '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE - '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE - '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE - '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE - '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE - '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS - '\u2020' # 0xA0 -> DAGGER - '\xb0' # 0xA1 -> DEGREE SIGN - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa7' # 0xA4 -> SECTION SIGN - '\u2022' # 0xA5 -> BULLET - '\xb6' # 0xA6 -> PILCROW SIGN - '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S - '\xae' # 0xA8 -> REGISTERED SIGN - '\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON - '\u2122' # 0xAA -> TRADE MARK SIGN - '\xb4' # 0xAB -> ACUTE ACCENT - '\xa8' # 0xAC -> DIAERESIS - '\u2260' # 0xAD -> NOT EQUAL TO - '\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON - '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE - '\u221e' # 0xB0 -> INFINITY - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO - '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO - '\u2206' # 0xB4 -> INCREMENT - '\xb5' # 0xB5 -> MICRO SIGN - '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL - '\u2211' # 0xB7 -> N-ARY SUMMATION - '\u220f' # 0xB8 -> N-ARY PRODUCT - '\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON - '\u222b' # 0xBA -> INTEGRAL - '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR - '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR - '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA - '\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON - '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE - '\xbf' # 0xC0 -> INVERTED QUESTION MARK - '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK - '\xac' # 0xC2 -> NOT SIGN - '\u221a' # 0xC3 -> SQUARE ROOT - '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK - '\u2248' # 0xC5 -> ALMOST EQUAL TO - '\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE - '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON - '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS - '\xa0' # 0xCA -> NO-BREAK SPACE - '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE - '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE - '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE - '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE - '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE - '\u2014' # 0xD1 -> EM DASH - '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK - '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK - '\xf7' # 0xD6 -> DIVISION SIGN - '\u25ca' # 0xD7 -> LOZENGE - '\uf8ff' # 0xD8 -> Apple logo - '\xa9' # 0xD9 -> COPYRIGHT SIGN - '\u2044' # 0xDA -> FRACTION SLASH - '\u20ac' # 0xDB -> EURO SIGN - '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\xc6' # 0xDE -> LATIN CAPITAL LETTER AE - '\xbb' # 0xDF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2013' # 0xE0 -> EN DASH - '\xb7' # 0xE1 -> MIDDLE DOT - '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK - '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK - '\u2030' # 0xE4 -> PER MILLE SIGN - '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE - '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE - '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON - '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE - '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE - '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I - '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\u02dc' # 0xF7 -> SMALL TILDE - '\xaf' # 0xF8 -> MACRON - '\u03c0' # 0xF9 -> GREEK SMALL LETTER PI - '\xcb' # 0xFA -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\u02da' # 0xFB -> RING ABOVE - '\xb8' # 0xFC -> CEDILLA - '\xca' # 0xFD -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xe6' # 0xFE -> LATIN SMALL LETTER AE - '\u02c7' # 0xFF -> CARON -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/mac_cyrillic.py b/python/Lib/encodings/mac_cyrillic.py deleted file mode 100644 index 2c59620..0000000 --- a/python/Lib/encodings/mac_cyrillic.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec mac_cyrillic generated from 'MAPPINGS/VENDORS/APPLE/CYRILLIC.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mac-cyrillic', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> CONTROL CHARACTER - '\x01' # 0x01 -> CONTROL CHARACTER - '\x02' # 0x02 -> CONTROL CHARACTER - '\x03' # 0x03 -> CONTROL CHARACTER - '\x04' # 0x04 -> CONTROL CHARACTER - '\x05' # 0x05 -> CONTROL CHARACTER - '\x06' # 0x06 -> CONTROL CHARACTER - '\x07' # 0x07 -> CONTROL CHARACTER - '\x08' # 0x08 -> CONTROL CHARACTER - '\t' # 0x09 -> CONTROL CHARACTER - '\n' # 0x0A -> CONTROL CHARACTER - '\x0b' # 0x0B -> CONTROL CHARACTER - '\x0c' # 0x0C -> CONTROL CHARACTER - '\r' # 0x0D -> CONTROL CHARACTER - '\x0e' # 0x0E -> CONTROL CHARACTER - '\x0f' # 0x0F -> CONTROL CHARACTER - '\x10' # 0x10 -> CONTROL CHARACTER - '\x11' # 0x11 -> CONTROL CHARACTER - '\x12' # 0x12 -> CONTROL CHARACTER - '\x13' # 0x13 -> CONTROL CHARACTER - '\x14' # 0x14 -> CONTROL CHARACTER - '\x15' # 0x15 -> CONTROL CHARACTER - '\x16' # 0x16 -> CONTROL CHARACTER - '\x17' # 0x17 -> CONTROL CHARACTER - '\x18' # 0x18 -> CONTROL CHARACTER - '\x19' # 0x19 -> CONTROL CHARACTER - '\x1a' # 0x1A -> CONTROL CHARACTER - '\x1b' # 0x1B -> CONTROL CHARACTER - '\x1c' # 0x1C -> CONTROL CHARACTER - '\x1d' # 0x1D -> CONTROL CHARACTER - '\x1e' # 0x1E -> CONTROL CHARACTER - '\x1f' # 0x1F -> CONTROL CHARACTER - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> CONTROL CHARACTER - '\u0410' # 0x80 -> CYRILLIC CAPITAL LETTER A - '\u0411' # 0x81 -> CYRILLIC CAPITAL LETTER BE - '\u0412' # 0x82 -> CYRILLIC CAPITAL LETTER VE - '\u0413' # 0x83 -> CYRILLIC CAPITAL LETTER GHE - '\u0414' # 0x84 -> CYRILLIC CAPITAL LETTER DE - '\u0415' # 0x85 -> CYRILLIC CAPITAL LETTER IE - '\u0416' # 0x86 -> CYRILLIC CAPITAL LETTER ZHE - '\u0417' # 0x87 -> CYRILLIC CAPITAL LETTER ZE - '\u0418' # 0x88 -> CYRILLIC CAPITAL LETTER I - '\u0419' # 0x89 -> CYRILLIC CAPITAL LETTER SHORT I - '\u041a' # 0x8A -> CYRILLIC CAPITAL LETTER KA - '\u041b' # 0x8B -> CYRILLIC CAPITAL LETTER EL - '\u041c' # 0x8C -> CYRILLIC CAPITAL LETTER EM - '\u041d' # 0x8D -> CYRILLIC CAPITAL LETTER EN - '\u041e' # 0x8E -> CYRILLIC CAPITAL LETTER O - '\u041f' # 0x8F -> CYRILLIC CAPITAL LETTER PE - '\u0420' # 0x90 -> CYRILLIC CAPITAL LETTER ER - '\u0421' # 0x91 -> CYRILLIC CAPITAL LETTER ES - '\u0422' # 0x92 -> CYRILLIC CAPITAL LETTER TE - '\u0423' # 0x93 -> CYRILLIC CAPITAL LETTER U - '\u0424' # 0x94 -> CYRILLIC CAPITAL LETTER EF - '\u0425' # 0x95 -> CYRILLIC CAPITAL LETTER HA - '\u0426' # 0x96 -> CYRILLIC CAPITAL LETTER TSE - '\u0427' # 0x97 -> CYRILLIC CAPITAL LETTER CHE - '\u0428' # 0x98 -> CYRILLIC CAPITAL LETTER SHA - '\u0429' # 0x99 -> CYRILLIC CAPITAL LETTER SHCHA - '\u042a' # 0x9A -> CYRILLIC CAPITAL LETTER HARD SIGN - '\u042b' # 0x9B -> CYRILLIC CAPITAL LETTER YERU - '\u042c' # 0x9C -> CYRILLIC CAPITAL LETTER SOFT SIGN - '\u042d' # 0x9D -> CYRILLIC CAPITAL LETTER E - '\u042e' # 0x9E -> CYRILLIC CAPITAL LETTER YU - '\u042f' # 0x9F -> CYRILLIC CAPITAL LETTER YA - '\u2020' # 0xA0 -> DAGGER - '\xb0' # 0xA1 -> DEGREE SIGN - '\u0490' # 0xA2 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN - '\xa3' # 0xA3 -> POUND SIGN - '\xa7' # 0xA4 -> SECTION SIGN - '\u2022' # 0xA5 -> BULLET - '\xb6' # 0xA6 -> PILCROW SIGN - '\u0406' # 0xA7 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - '\xae' # 0xA8 -> REGISTERED SIGN - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u2122' # 0xAA -> TRADE MARK SIGN - '\u0402' # 0xAB -> CYRILLIC CAPITAL LETTER DJE - '\u0452' # 0xAC -> CYRILLIC SMALL LETTER DJE - '\u2260' # 0xAD -> NOT EQUAL TO - '\u0403' # 0xAE -> CYRILLIC CAPITAL LETTER GJE - '\u0453' # 0xAF -> CYRILLIC SMALL LETTER GJE - '\u221e' # 0xB0 -> INFINITY - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO - '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO - '\u0456' # 0xB4 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - '\xb5' # 0xB5 -> MICRO SIGN - '\u0491' # 0xB6 -> CYRILLIC SMALL LETTER GHE WITH UPTURN - '\u0408' # 0xB7 -> CYRILLIC CAPITAL LETTER JE - '\u0404' # 0xB8 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE - '\u0454' # 0xB9 -> CYRILLIC SMALL LETTER UKRAINIAN IE - '\u0407' # 0xBA -> CYRILLIC CAPITAL LETTER YI - '\u0457' # 0xBB -> CYRILLIC SMALL LETTER YI - '\u0409' # 0xBC -> CYRILLIC CAPITAL LETTER LJE - '\u0459' # 0xBD -> CYRILLIC SMALL LETTER LJE - '\u040a' # 0xBE -> CYRILLIC CAPITAL LETTER NJE - '\u045a' # 0xBF -> CYRILLIC SMALL LETTER NJE - '\u0458' # 0xC0 -> CYRILLIC SMALL LETTER JE - '\u0405' # 0xC1 -> CYRILLIC CAPITAL LETTER DZE - '\xac' # 0xC2 -> NOT SIGN - '\u221a' # 0xC3 -> SQUARE ROOT - '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK - '\u2248' # 0xC5 -> ALMOST EQUAL TO - '\u2206' # 0xC6 -> INCREMENT - '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS - '\xa0' # 0xCA -> NO-BREAK SPACE - '\u040b' # 0xCB -> CYRILLIC CAPITAL LETTER TSHE - '\u045b' # 0xCC -> CYRILLIC SMALL LETTER TSHE - '\u040c' # 0xCD -> CYRILLIC CAPITAL LETTER KJE - '\u045c' # 0xCE -> CYRILLIC SMALL LETTER KJE - '\u0455' # 0xCF -> CYRILLIC SMALL LETTER DZE - '\u2013' # 0xD0 -> EN DASH - '\u2014' # 0xD1 -> EM DASH - '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK - '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK - '\xf7' # 0xD6 -> DIVISION SIGN - '\u201e' # 0xD7 -> DOUBLE LOW-9 QUOTATION MARK - '\u040e' # 0xD8 -> CYRILLIC CAPITAL LETTER SHORT U - '\u045e' # 0xD9 -> CYRILLIC SMALL LETTER SHORT U - '\u040f' # 0xDA -> CYRILLIC CAPITAL LETTER DZHE - '\u045f' # 0xDB -> CYRILLIC SMALL LETTER DZHE - '\u2116' # 0xDC -> NUMERO SIGN - '\u0401' # 0xDD -> CYRILLIC CAPITAL LETTER IO - '\u0451' # 0xDE -> CYRILLIC SMALL LETTER IO - '\u044f' # 0xDF -> CYRILLIC SMALL LETTER YA - '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A - '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE - '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE - '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE - '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE - '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE - '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE - '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE - '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I - '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I - '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA - '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL - '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM - '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN - '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O - '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE - '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER - '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES - '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE - '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U - '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF - '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA - '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE - '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE - '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA - '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA - '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN - '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU - '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN - '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E - '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU - '\u20ac' # 0xFF -> EURO SIGN -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/mac_farsi.py b/python/Lib/encodings/mac_farsi.py deleted file mode 100644 index 46561e4..0000000 --- a/python/Lib/encodings/mac_farsi.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec mac_farsi generated from 'MAPPINGS/VENDORS/APPLE/FARSI.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mac-farsi', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> CONTROL CHARACTER - '\x01' # 0x01 -> CONTROL CHARACTER - '\x02' # 0x02 -> CONTROL CHARACTER - '\x03' # 0x03 -> CONTROL CHARACTER - '\x04' # 0x04 -> CONTROL CHARACTER - '\x05' # 0x05 -> CONTROL CHARACTER - '\x06' # 0x06 -> CONTROL CHARACTER - '\x07' # 0x07 -> CONTROL CHARACTER - '\x08' # 0x08 -> CONTROL CHARACTER - '\t' # 0x09 -> CONTROL CHARACTER - '\n' # 0x0A -> CONTROL CHARACTER - '\x0b' # 0x0B -> CONTROL CHARACTER - '\x0c' # 0x0C -> CONTROL CHARACTER - '\r' # 0x0D -> CONTROL CHARACTER - '\x0e' # 0x0E -> CONTROL CHARACTER - '\x0f' # 0x0F -> CONTROL CHARACTER - '\x10' # 0x10 -> CONTROL CHARACTER - '\x11' # 0x11 -> CONTROL CHARACTER - '\x12' # 0x12 -> CONTROL CHARACTER - '\x13' # 0x13 -> CONTROL CHARACTER - '\x14' # 0x14 -> CONTROL CHARACTER - '\x15' # 0x15 -> CONTROL CHARACTER - '\x16' # 0x16 -> CONTROL CHARACTER - '\x17' # 0x17 -> CONTROL CHARACTER - '\x18' # 0x18 -> CONTROL CHARACTER - '\x19' # 0x19 -> CONTROL CHARACTER - '\x1a' # 0x1A -> CONTROL CHARACTER - '\x1b' # 0x1B -> CONTROL CHARACTER - '\x1c' # 0x1C -> CONTROL CHARACTER - '\x1d' # 0x1D -> CONTROL CHARACTER - '\x1e' # 0x1E -> CONTROL CHARACTER - '\x1f' # 0x1F -> CONTROL CHARACTER - ' ' # 0x20 -> SPACE, left-right - '!' # 0x21 -> EXCLAMATION MARK, left-right - '"' # 0x22 -> QUOTATION MARK, left-right - '#' # 0x23 -> NUMBER SIGN, left-right - '$' # 0x24 -> DOLLAR SIGN, left-right - '%' # 0x25 -> PERCENT SIGN, left-right - '&' # 0x26 -> AMPERSAND, left-right - "'" # 0x27 -> APOSTROPHE, left-right - '(' # 0x28 -> LEFT PARENTHESIS, left-right - ')' # 0x29 -> RIGHT PARENTHESIS, left-right - '*' # 0x2A -> ASTERISK, left-right - '+' # 0x2B -> PLUS SIGN, left-right - ',' # 0x2C -> COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR - '-' # 0x2D -> HYPHEN-MINUS, left-right - '.' # 0x2E -> FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR - '/' # 0x2F -> SOLIDUS, left-right - '0' # 0x30 -> DIGIT ZERO; in Arabic-script context, displayed as 0x06F0 EXTENDED ARABIC-INDIC DIGIT ZERO - '1' # 0x31 -> DIGIT ONE; in Arabic-script context, displayed as 0x06F1 EXTENDED ARABIC-INDIC DIGIT ONE - '2' # 0x32 -> DIGIT TWO; in Arabic-script context, displayed as 0x06F2 EXTENDED ARABIC-INDIC DIGIT TWO - '3' # 0x33 -> DIGIT THREE; in Arabic-script context, displayed as 0x06F3 EXTENDED ARABIC-INDIC DIGIT THREE - '4' # 0x34 -> DIGIT FOUR; in Arabic-script context, displayed as 0x06F4 EXTENDED ARABIC-INDIC DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE; in Arabic-script context, displayed as 0x06F5 EXTENDED ARABIC-INDIC DIGIT FIVE - '6' # 0x36 -> DIGIT SIX; in Arabic-script context, displayed as 0x06F6 EXTENDED ARABIC-INDIC DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN; in Arabic-script context, displayed as 0x06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT; in Arabic-script context, displayed as 0x06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE; in Arabic-script context, displayed as 0x06F9 EXTENDED ARABIC-INDIC DIGIT NINE - ':' # 0x3A -> COLON, left-right - ';' # 0x3B -> SEMICOLON, left-right - '<' # 0x3C -> LESS-THAN SIGN, left-right - '=' # 0x3D -> EQUALS SIGN, left-right - '>' # 0x3E -> GREATER-THAN SIGN, left-right - '?' # 0x3F -> QUESTION MARK, left-right - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET, left-right - '\\' # 0x5C -> REVERSE SOLIDUS, left-right - ']' # 0x5D -> RIGHT SQUARE BRACKET, left-right - '^' # 0x5E -> CIRCUMFLEX ACCENT, left-right - '_' # 0x5F -> LOW LINE, left-right - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET, left-right - '|' # 0x7C -> VERTICAL LINE, left-right - '}' # 0x7D -> RIGHT CURLY BRACKET, left-right - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> CONTROL CHARACTER - '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xa0' # 0x81 -> NO-BREAK SPACE, right-left - '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE - '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE - '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS - '\u06ba' # 0x8B -> ARABIC LETTER NOON GHUNNA - '\xab' # 0x8C -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left - '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA - '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE - '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE - '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE - '\u2026' # 0x93 -> HORIZONTAL ELLIPSIS, right-left - '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE - '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE - '\xbb' # 0x98 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left - '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0x9B -> DIVISION SIGN, right-left - '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE - '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE - '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS - ' ' # 0xA0 -> SPACE, right-left - '!' # 0xA1 -> EXCLAMATION MARK, right-left - '"' # 0xA2 -> QUOTATION MARK, right-left - '#' # 0xA3 -> NUMBER SIGN, right-left - '$' # 0xA4 -> DOLLAR SIGN, right-left - '\u066a' # 0xA5 -> ARABIC PERCENT SIGN - '&' # 0xA6 -> AMPERSAND, right-left - "'" # 0xA7 -> APOSTROPHE, right-left - '(' # 0xA8 -> LEFT PARENTHESIS, right-left - ')' # 0xA9 -> RIGHT PARENTHESIS, right-left - '*' # 0xAA -> ASTERISK, right-left - '+' # 0xAB -> PLUS SIGN, right-left - '\u060c' # 0xAC -> ARABIC COMMA - '-' # 0xAD -> HYPHEN-MINUS, right-left - '.' # 0xAE -> FULL STOP, right-left - '/' # 0xAF -> SOLIDUS, right-left - '\u06f0' # 0xB0 -> EXTENDED ARABIC-INDIC DIGIT ZERO, right-left (need override) - '\u06f1' # 0xB1 -> EXTENDED ARABIC-INDIC DIGIT ONE, right-left (need override) - '\u06f2' # 0xB2 -> EXTENDED ARABIC-INDIC DIGIT TWO, right-left (need override) - '\u06f3' # 0xB3 -> EXTENDED ARABIC-INDIC DIGIT THREE, right-left (need override) - '\u06f4' # 0xB4 -> EXTENDED ARABIC-INDIC DIGIT FOUR, right-left (need override) - '\u06f5' # 0xB5 -> EXTENDED ARABIC-INDIC DIGIT FIVE, right-left (need override) - '\u06f6' # 0xB6 -> EXTENDED ARABIC-INDIC DIGIT SIX, right-left (need override) - '\u06f7' # 0xB7 -> EXTENDED ARABIC-INDIC DIGIT SEVEN, right-left (need override) - '\u06f8' # 0xB8 -> EXTENDED ARABIC-INDIC DIGIT EIGHT, right-left (need override) - '\u06f9' # 0xB9 -> EXTENDED ARABIC-INDIC DIGIT NINE, right-left (need override) - ':' # 0xBA -> COLON, right-left - '\u061b' # 0xBB -> ARABIC SEMICOLON - '<' # 0xBC -> LESS-THAN SIGN, right-left - '=' # 0xBD -> EQUALS SIGN, right-left - '>' # 0xBE -> GREATER-THAN SIGN, right-left - '\u061f' # 0xBF -> ARABIC QUESTION MARK - '\u274a' # 0xC0 -> EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left - '\u0621' # 0xC1 -> ARABIC LETTER HAMZA - '\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE - '\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE - '\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE - '\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW - '\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE - '\u0627' # 0xC7 -> ARABIC LETTER ALEF - '\u0628' # 0xC8 -> ARABIC LETTER BEH - '\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA - '\u062a' # 0xCA -> ARABIC LETTER TEH - '\u062b' # 0xCB -> ARABIC LETTER THEH - '\u062c' # 0xCC -> ARABIC LETTER JEEM - '\u062d' # 0xCD -> ARABIC LETTER HAH - '\u062e' # 0xCE -> ARABIC LETTER KHAH - '\u062f' # 0xCF -> ARABIC LETTER DAL - '\u0630' # 0xD0 -> ARABIC LETTER THAL - '\u0631' # 0xD1 -> ARABIC LETTER REH - '\u0632' # 0xD2 -> ARABIC LETTER ZAIN - '\u0633' # 0xD3 -> ARABIC LETTER SEEN - '\u0634' # 0xD4 -> ARABIC LETTER SHEEN - '\u0635' # 0xD5 -> ARABIC LETTER SAD - '\u0636' # 0xD6 -> ARABIC LETTER DAD - '\u0637' # 0xD7 -> ARABIC LETTER TAH - '\u0638' # 0xD8 -> ARABIC LETTER ZAH - '\u0639' # 0xD9 -> ARABIC LETTER AIN - '\u063a' # 0xDA -> ARABIC LETTER GHAIN - '[' # 0xDB -> LEFT SQUARE BRACKET, right-left - '\\' # 0xDC -> REVERSE SOLIDUS, right-left - ']' # 0xDD -> RIGHT SQUARE BRACKET, right-left - '^' # 0xDE -> CIRCUMFLEX ACCENT, right-left - '_' # 0xDF -> LOW LINE, right-left - '\u0640' # 0xE0 -> ARABIC TATWEEL - '\u0641' # 0xE1 -> ARABIC LETTER FEH - '\u0642' # 0xE2 -> ARABIC LETTER QAF - '\u0643' # 0xE3 -> ARABIC LETTER KAF - '\u0644' # 0xE4 -> ARABIC LETTER LAM - '\u0645' # 0xE5 -> ARABIC LETTER MEEM - '\u0646' # 0xE6 -> ARABIC LETTER NOON - '\u0647' # 0xE7 -> ARABIC LETTER HEH - '\u0648' # 0xE8 -> ARABIC LETTER WAW - '\u0649' # 0xE9 -> ARABIC LETTER ALEF MAKSURA - '\u064a' # 0xEA -> ARABIC LETTER YEH - '\u064b' # 0xEB -> ARABIC FATHATAN - '\u064c' # 0xEC -> ARABIC DAMMATAN - '\u064d' # 0xED -> ARABIC KASRATAN - '\u064e' # 0xEE -> ARABIC FATHA - '\u064f' # 0xEF -> ARABIC DAMMA - '\u0650' # 0xF0 -> ARABIC KASRA - '\u0651' # 0xF1 -> ARABIC SHADDA - '\u0652' # 0xF2 -> ARABIC SUKUN - '\u067e' # 0xF3 -> ARABIC LETTER PEH - '\u0679' # 0xF4 -> ARABIC LETTER TTEH - '\u0686' # 0xF5 -> ARABIC LETTER TCHEH - '\u06d5' # 0xF6 -> ARABIC LETTER AE - '\u06a4' # 0xF7 -> ARABIC LETTER VEH - '\u06af' # 0xF8 -> ARABIC LETTER GAF - '\u0688' # 0xF9 -> ARABIC LETTER DDAL - '\u0691' # 0xFA -> ARABIC LETTER RREH - '{' # 0xFB -> LEFT CURLY BRACKET, right-left - '|' # 0xFC -> VERTICAL LINE, right-left - '}' # 0xFD -> RIGHT CURLY BRACKET, right-left - '\u0698' # 0xFE -> ARABIC LETTER JEH - '\u06d2' # 0xFF -> ARABIC LETTER YEH BARREE -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/mac_greek.py b/python/Lib/encodings/mac_greek.py deleted file mode 100644 index fe21217..0000000 --- a/python/Lib/encodings/mac_greek.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec mac_greek generated from 'MAPPINGS/VENDORS/APPLE/GREEK.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mac-greek', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> CONTROL CHARACTER - '\x01' # 0x01 -> CONTROL CHARACTER - '\x02' # 0x02 -> CONTROL CHARACTER - '\x03' # 0x03 -> CONTROL CHARACTER - '\x04' # 0x04 -> CONTROL CHARACTER - '\x05' # 0x05 -> CONTROL CHARACTER - '\x06' # 0x06 -> CONTROL CHARACTER - '\x07' # 0x07 -> CONTROL CHARACTER - '\x08' # 0x08 -> CONTROL CHARACTER - '\t' # 0x09 -> CONTROL CHARACTER - '\n' # 0x0A -> CONTROL CHARACTER - '\x0b' # 0x0B -> CONTROL CHARACTER - '\x0c' # 0x0C -> CONTROL CHARACTER - '\r' # 0x0D -> CONTROL CHARACTER - '\x0e' # 0x0E -> CONTROL CHARACTER - '\x0f' # 0x0F -> CONTROL CHARACTER - '\x10' # 0x10 -> CONTROL CHARACTER - '\x11' # 0x11 -> CONTROL CHARACTER - '\x12' # 0x12 -> CONTROL CHARACTER - '\x13' # 0x13 -> CONTROL CHARACTER - '\x14' # 0x14 -> CONTROL CHARACTER - '\x15' # 0x15 -> CONTROL CHARACTER - '\x16' # 0x16 -> CONTROL CHARACTER - '\x17' # 0x17 -> CONTROL CHARACTER - '\x18' # 0x18 -> CONTROL CHARACTER - '\x19' # 0x19 -> CONTROL CHARACTER - '\x1a' # 0x1A -> CONTROL CHARACTER - '\x1b' # 0x1B -> CONTROL CHARACTER - '\x1c' # 0x1C -> CONTROL CHARACTER - '\x1d' # 0x1D -> CONTROL CHARACTER - '\x1e' # 0x1E -> CONTROL CHARACTER - '\x1f' # 0x1F -> CONTROL CHARACTER - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> CONTROL CHARACTER - '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xb9' # 0x81 -> SUPERSCRIPT ONE - '\xb2' # 0x82 -> SUPERSCRIPT TWO - '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xb3' # 0x84 -> SUPERSCRIPT THREE - '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\u0385' # 0x87 -> GREEK DIALYTIKA TONOS - '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE - '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS - '\u0384' # 0x8B -> GREEK TONOS - '\xa8' # 0x8C -> DIAERESIS - '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA - '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE - '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE - '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xa3' # 0x92 -> POUND SIGN - '\u2122' # 0x93 -> TRADE MARK SIGN - '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS - '\u2022' # 0x96 -> BULLET - '\xbd' # 0x97 -> VULGAR FRACTION ONE HALF - '\u2030' # 0x98 -> PER MILLE SIGN - '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS - '\xa6' # 0x9B -> BROKEN BAR - '\u20ac' # 0x9C -> EURO SIGN # before Mac OS 9.2.2, was SOFT HYPHEN - '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE - '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS - '\u2020' # 0xA0 -> DAGGER - '\u0393' # 0xA1 -> GREEK CAPITAL LETTER GAMMA - '\u0394' # 0xA2 -> GREEK CAPITAL LETTER DELTA - '\u0398' # 0xA3 -> GREEK CAPITAL LETTER THETA - '\u039b' # 0xA4 -> GREEK CAPITAL LETTER LAMDA - '\u039e' # 0xA5 -> GREEK CAPITAL LETTER XI - '\u03a0' # 0xA6 -> GREEK CAPITAL LETTER PI - '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S - '\xae' # 0xA8 -> REGISTERED SIGN - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u03a3' # 0xAA -> GREEK CAPITAL LETTER SIGMA - '\u03aa' # 0xAB -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - '\xa7' # 0xAC -> SECTION SIGN - '\u2260' # 0xAD -> NOT EQUAL TO - '\xb0' # 0xAE -> DEGREE SIGN - '\xb7' # 0xAF -> MIDDLE DOT - '\u0391' # 0xB0 -> GREEK CAPITAL LETTER ALPHA - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO - '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO - '\xa5' # 0xB4 -> YEN SIGN - '\u0392' # 0xB5 -> GREEK CAPITAL LETTER BETA - '\u0395' # 0xB6 -> GREEK CAPITAL LETTER EPSILON - '\u0396' # 0xB7 -> GREEK CAPITAL LETTER ZETA - '\u0397' # 0xB8 -> GREEK CAPITAL LETTER ETA - '\u0399' # 0xB9 -> GREEK CAPITAL LETTER IOTA - '\u039a' # 0xBA -> GREEK CAPITAL LETTER KAPPA - '\u039c' # 0xBB -> GREEK CAPITAL LETTER MU - '\u03a6' # 0xBC -> GREEK CAPITAL LETTER PHI - '\u03ab' # 0xBD -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - '\u03a8' # 0xBE -> GREEK CAPITAL LETTER PSI - '\u03a9' # 0xBF -> GREEK CAPITAL LETTER OMEGA - '\u03ac' # 0xC0 -> GREEK SMALL LETTER ALPHA WITH TONOS - '\u039d' # 0xC1 -> GREEK CAPITAL LETTER NU - '\xac' # 0xC2 -> NOT SIGN - '\u039f' # 0xC3 -> GREEK CAPITAL LETTER OMICRON - '\u03a1' # 0xC4 -> GREEK CAPITAL LETTER RHO - '\u2248' # 0xC5 -> ALMOST EQUAL TO - '\u03a4' # 0xC6 -> GREEK CAPITAL LETTER TAU - '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS - '\xa0' # 0xCA -> NO-BREAK SPACE - '\u03a5' # 0xCB -> GREEK CAPITAL LETTER UPSILON - '\u03a7' # 0xCC -> GREEK CAPITAL LETTER CHI - '\u0386' # 0xCD -> GREEK CAPITAL LETTER ALPHA WITH TONOS - '\u0388' # 0xCE -> GREEK CAPITAL LETTER EPSILON WITH TONOS - '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE - '\u2013' # 0xD0 -> EN DASH - '\u2015' # 0xD1 -> HORIZONTAL BAR - '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK - '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK - '\xf7' # 0xD6 -> DIVISION SIGN - '\u0389' # 0xD7 -> GREEK CAPITAL LETTER ETA WITH TONOS - '\u038a' # 0xD8 -> GREEK CAPITAL LETTER IOTA WITH TONOS - '\u038c' # 0xD9 -> GREEK CAPITAL LETTER OMICRON WITH TONOS - '\u038e' # 0xDA -> GREEK CAPITAL LETTER UPSILON WITH TONOS - '\u03ad' # 0xDB -> GREEK SMALL LETTER EPSILON WITH TONOS - '\u03ae' # 0xDC -> GREEK SMALL LETTER ETA WITH TONOS - '\u03af' # 0xDD -> GREEK SMALL LETTER IOTA WITH TONOS - '\u03cc' # 0xDE -> GREEK SMALL LETTER OMICRON WITH TONOS - '\u038f' # 0xDF -> GREEK CAPITAL LETTER OMEGA WITH TONOS - '\u03cd' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH TONOS - '\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA - '\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA - '\u03c8' # 0xE3 -> GREEK SMALL LETTER PSI - '\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA - '\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON - '\u03c6' # 0xE6 -> GREEK SMALL LETTER PHI - '\u03b3' # 0xE7 -> GREEK SMALL LETTER GAMMA - '\u03b7' # 0xE8 -> GREEK SMALL LETTER ETA - '\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA - '\u03be' # 0xEA -> GREEK SMALL LETTER XI - '\u03ba' # 0xEB -> GREEK SMALL LETTER KAPPA - '\u03bb' # 0xEC -> GREEK SMALL LETTER LAMDA - '\u03bc' # 0xED -> GREEK SMALL LETTER MU - '\u03bd' # 0xEE -> GREEK SMALL LETTER NU - '\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON - '\u03c0' # 0xF0 -> GREEK SMALL LETTER PI - '\u03ce' # 0xF1 -> GREEK SMALL LETTER OMEGA WITH TONOS - '\u03c1' # 0xF2 -> GREEK SMALL LETTER RHO - '\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA - '\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU - '\u03b8' # 0xF5 -> GREEK SMALL LETTER THETA - '\u03c9' # 0xF6 -> GREEK SMALL LETTER OMEGA - '\u03c2' # 0xF7 -> GREEK SMALL LETTER FINAL SIGMA - '\u03c7' # 0xF8 -> GREEK SMALL LETTER CHI - '\u03c5' # 0xF9 -> GREEK SMALL LETTER UPSILON - '\u03b6' # 0xFA -> GREEK SMALL LETTER ZETA - '\u03ca' # 0xFB -> GREEK SMALL LETTER IOTA WITH DIALYTIKA - '\u03cb' # 0xFC -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA - '\u0390' # 0xFD -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - '\u03b0' # 0xFE -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - '\xad' # 0xFF -> SOFT HYPHEN # before Mac OS 9.2.2, was undefined -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/mac_iceland.py b/python/Lib/encodings/mac_iceland.py deleted file mode 100644 index 2d57542..0000000 --- a/python/Lib/encodings/mac_iceland.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec mac_iceland generated from 'MAPPINGS/VENDORS/APPLE/ICELAND.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mac-iceland', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> CONTROL CHARACTER - '\x01' # 0x01 -> CONTROL CHARACTER - '\x02' # 0x02 -> CONTROL CHARACTER - '\x03' # 0x03 -> CONTROL CHARACTER - '\x04' # 0x04 -> CONTROL CHARACTER - '\x05' # 0x05 -> CONTROL CHARACTER - '\x06' # 0x06 -> CONTROL CHARACTER - '\x07' # 0x07 -> CONTROL CHARACTER - '\x08' # 0x08 -> CONTROL CHARACTER - '\t' # 0x09 -> CONTROL CHARACTER - '\n' # 0x0A -> CONTROL CHARACTER - '\x0b' # 0x0B -> CONTROL CHARACTER - '\x0c' # 0x0C -> CONTROL CHARACTER - '\r' # 0x0D -> CONTROL CHARACTER - '\x0e' # 0x0E -> CONTROL CHARACTER - '\x0f' # 0x0F -> CONTROL CHARACTER - '\x10' # 0x10 -> CONTROL CHARACTER - '\x11' # 0x11 -> CONTROL CHARACTER - '\x12' # 0x12 -> CONTROL CHARACTER - '\x13' # 0x13 -> CONTROL CHARACTER - '\x14' # 0x14 -> CONTROL CHARACTER - '\x15' # 0x15 -> CONTROL CHARACTER - '\x16' # 0x16 -> CONTROL CHARACTER - '\x17' # 0x17 -> CONTROL CHARACTER - '\x18' # 0x18 -> CONTROL CHARACTER - '\x19' # 0x19 -> CONTROL CHARACTER - '\x1a' # 0x1A -> CONTROL CHARACTER - '\x1b' # 0x1B -> CONTROL CHARACTER - '\x1c' # 0x1C -> CONTROL CHARACTER - '\x1d' # 0x1D -> CONTROL CHARACTER - '\x1e' # 0x1E -> CONTROL CHARACTER - '\x1f' # 0x1F -> CONTROL CHARACTER - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> CONTROL CHARACTER - '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE - '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE - '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE - '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA - '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE - '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE - '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE - '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE - '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE - '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE - '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE - '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE - '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE - '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE - '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS - '\xdd' # 0xA0 -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xb0' # 0xA1 -> DEGREE SIGN - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa7' # 0xA4 -> SECTION SIGN - '\u2022' # 0xA5 -> BULLET - '\xb6' # 0xA6 -> PILCROW SIGN - '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S - '\xae' # 0xA8 -> REGISTERED SIGN - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u2122' # 0xAA -> TRADE MARK SIGN - '\xb4' # 0xAB -> ACUTE ACCENT - '\xa8' # 0xAC -> DIAERESIS - '\u2260' # 0xAD -> NOT EQUAL TO - '\xc6' # 0xAE -> LATIN CAPITAL LETTER AE - '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE - '\u221e' # 0xB0 -> INFINITY - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO - '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO - '\xa5' # 0xB4 -> YEN SIGN - '\xb5' # 0xB5 -> MICRO SIGN - '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL - '\u2211' # 0xB7 -> N-ARY SUMMATION - '\u220f' # 0xB8 -> N-ARY PRODUCT - '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI - '\u222b' # 0xBA -> INTEGRAL - '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR - '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR - '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA - '\xe6' # 0xBE -> LATIN SMALL LETTER AE - '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE - '\xbf' # 0xC0 -> INVERTED QUESTION MARK - '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK - '\xac' # 0xC2 -> NOT SIGN - '\u221a' # 0xC3 -> SQUARE ROOT - '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK - '\u2248' # 0xC5 -> ALMOST EQUAL TO - '\u2206' # 0xC6 -> INCREMENT - '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS - '\xa0' # 0xCA -> NO-BREAK SPACE - '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE - '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE - '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE - '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE - '\u2013' # 0xD0 -> EN DASH - '\u2014' # 0xD1 -> EM DASH - '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK - '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK - '\xf7' # 0xD6 -> DIVISION SIGN - '\u25ca' # 0xD7 -> LOZENGE - '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS - '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\u2044' # 0xDA -> FRACTION SLASH - '\u20ac' # 0xDB -> EURO SIGN - '\xd0' # 0xDC -> LATIN CAPITAL LETTER ETH - '\xf0' # 0xDD -> LATIN SMALL LETTER ETH - '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN - '\xfe' # 0xDF -> LATIN SMALL LETTER THORN - '\xfd' # 0xE0 -> LATIN SMALL LETTER Y WITH ACUTE - '\xb7' # 0xE1 -> MIDDLE DOT - '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK - '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK - '\u2030' # 0xE4 -> PER MILLE SIGN - '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\uf8ff' # 0xF0 -> Apple logo - '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE - '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I - '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\u02dc' # 0xF7 -> SMALL TILDE - '\xaf' # 0xF8 -> MACRON - '\u02d8' # 0xF9 -> BREVE - '\u02d9' # 0xFA -> DOT ABOVE - '\u02da' # 0xFB -> RING ABOVE - '\xb8' # 0xFC -> CEDILLA - '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT - '\u02db' # 0xFE -> OGONEK - '\u02c7' # 0xFF -> CARON -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/mac_latin2.py b/python/Lib/encodings/mac_latin2.py deleted file mode 100644 index fc24a8c..0000000 --- a/python/Lib/encodings/mac_latin2.py +++ /dev/null @@ -1,312 +0,0 @@ -""" Python Character Mapping Codec mac_latin2 generated from 'MAPPINGS/VENDORS/MICSFT/MAC/LATIN2.TXT' with gencodec.py. - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. -(c) Copyright 2000 Guido van Rossum. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mac-latin2', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\u0100' # 0x81 -> LATIN CAPITAL LETTER A WITH MACRON - '\u0101' # 0x82 -> LATIN SMALL LETTER A WITH MACRON - '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE - '\u0104' # 0x84 -> LATIN CAPITAL LETTER A WITH OGONEK - '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE - '\u0105' # 0x88 -> LATIN SMALL LETTER A WITH OGONEK - '\u010c' # 0x89 -> LATIN CAPITAL LETTER C WITH CARON - '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS - '\u010d' # 0x8B -> LATIN SMALL LETTER C WITH CARON - '\u0106' # 0x8C -> LATIN CAPITAL LETTER C WITH ACUTE - '\u0107' # 0x8D -> LATIN SMALL LETTER C WITH ACUTE - '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE - '\u0179' # 0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE - '\u017a' # 0x90 -> LATIN SMALL LETTER Z WITH ACUTE - '\u010e' # 0x91 -> LATIN CAPITAL LETTER D WITH CARON - '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE - '\u010f' # 0x93 -> LATIN SMALL LETTER D WITH CARON - '\u0112' # 0x94 -> LATIN CAPITAL LETTER E WITH MACRON - '\u0113' # 0x95 -> LATIN SMALL LETTER E WITH MACRON - '\u0116' # 0x96 -> LATIN CAPITAL LETTER E WITH DOT ABOVE - '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE - '\u0117' # 0x98 -> LATIN SMALL LETTER E WITH DOT ABOVE - '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE - '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE - '\u011a' # 0x9D -> LATIN CAPITAL LETTER E WITH CARON - '\u011b' # 0x9E -> LATIN SMALL LETTER E WITH CARON - '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS - '\u2020' # 0xA0 -> DAGGER - '\xb0' # 0xA1 -> DEGREE SIGN - '\u0118' # 0xA2 -> LATIN CAPITAL LETTER E WITH OGONEK - '\xa3' # 0xA3 -> POUND SIGN - '\xa7' # 0xA4 -> SECTION SIGN - '\u2022' # 0xA5 -> BULLET - '\xb6' # 0xA6 -> PILCROW SIGN - '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S - '\xae' # 0xA8 -> REGISTERED SIGN - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u2122' # 0xAA -> TRADE MARK SIGN - '\u0119' # 0xAB -> LATIN SMALL LETTER E WITH OGONEK - '\xa8' # 0xAC -> DIAERESIS - '\u2260' # 0xAD -> NOT EQUAL TO - '\u0123' # 0xAE -> LATIN SMALL LETTER G WITH CEDILLA - '\u012e' # 0xAF -> LATIN CAPITAL LETTER I WITH OGONEK - '\u012f' # 0xB0 -> LATIN SMALL LETTER I WITH OGONEK - '\u012a' # 0xB1 -> LATIN CAPITAL LETTER I WITH MACRON - '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO - '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO - '\u012b' # 0xB4 -> LATIN SMALL LETTER I WITH MACRON - '\u0136' # 0xB5 -> LATIN CAPITAL LETTER K WITH CEDILLA - '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL - '\u2211' # 0xB7 -> N-ARY SUMMATION - '\u0142' # 0xB8 -> LATIN SMALL LETTER L WITH STROKE - '\u013b' # 0xB9 -> LATIN CAPITAL LETTER L WITH CEDILLA - '\u013c' # 0xBA -> LATIN SMALL LETTER L WITH CEDILLA - '\u013d' # 0xBB -> LATIN CAPITAL LETTER L WITH CARON - '\u013e' # 0xBC -> LATIN SMALL LETTER L WITH CARON - '\u0139' # 0xBD -> LATIN CAPITAL LETTER L WITH ACUTE - '\u013a' # 0xBE -> LATIN SMALL LETTER L WITH ACUTE - '\u0145' # 0xBF -> LATIN CAPITAL LETTER N WITH CEDILLA - '\u0146' # 0xC0 -> LATIN SMALL LETTER N WITH CEDILLA - '\u0143' # 0xC1 -> LATIN CAPITAL LETTER N WITH ACUTE - '\xac' # 0xC2 -> NOT SIGN - '\u221a' # 0xC3 -> SQUARE ROOT - '\u0144' # 0xC4 -> LATIN SMALL LETTER N WITH ACUTE - '\u0147' # 0xC5 -> LATIN CAPITAL LETTER N WITH CARON - '\u2206' # 0xC6 -> INCREMENT - '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS - '\xa0' # 0xCA -> NO-BREAK SPACE - '\u0148' # 0xCB -> LATIN SMALL LETTER N WITH CARON - '\u0150' # 0xCC -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE - '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE - '\u0151' # 0xCE -> LATIN SMALL LETTER O WITH DOUBLE ACUTE - '\u014c' # 0xCF -> LATIN CAPITAL LETTER O WITH MACRON - '\u2013' # 0xD0 -> EN DASH - '\u2014' # 0xD1 -> EM DASH - '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK - '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK - '\xf7' # 0xD6 -> DIVISION SIGN - '\u25ca' # 0xD7 -> LOZENGE - '\u014d' # 0xD8 -> LATIN SMALL LETTER O WITH MACRON - '\u0154' # 0xD9 -> LATIN CAPITAL LETTER R WITH ACUTE - '\u0155' # 0xDA -> LATIN SMALL LETTER R WITH ACUTE - '\u0158' # 0xDB -> LATIN CAPITAL LETTER R WITH CARON - '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\u0159' # 0xDE -> LATIN SMALL LETTER R WITH CARON - '\u0156' # 0xDF -> LATIN CAPITAL LETTER R WITH CEDILLA - '\u0157' # 0xE0 -> LATIN SMALL LETTER R WITH CEDILLA - '\u0160' # 0xE1 -> LATIN CAPITAL LETTER S WITH CARON - '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK - '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK - '\u0161' # 0xE4 -> LATIN SMALL LETTER S WITH CARON - '\u015a' # 0xE5 -> LATIN CAPITAL LETTER S WITH ACUTE - '\u015b' # 0xE6 -> LATIN SMALL LETTER S WITH ACUTE - '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE - '\u0164' # 0xE8 -> LATIN CAPITAL LETTER T WITH CARON - '\u0165' # 0xE9 -> LATIN SMALL LETTER T WITH CARON - '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE - '\u017d' # 0xEB -> LATIN CAPITAL LETTER Z WITH CARON - '\u017e' # 0xEC -> LATIN SMALL LETTER Z WITH CARON - '\u016a' # 0xED -> LATIN CAPITAL LETTER U WITH MACRON - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\u016b' # 0xF0 -> LATIN SMALL LETTER U WITH MACRON - '\u016e' # 0xF1 -> LATIN CAPITAL LETTER U WITH RING ABOVE - '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE - '\u016f' # 0xF3 -> LATIN SMALL LETTER U WITH RING ABOVE - '\u0170' # 0xF4 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE - '\u0171' # 0xF5 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE - '\u0172' # 0xF6 -> LATIN CAPITAL LETTER U WITH OGONEK - '\u0173' # 0xF7 -> LATIN SMALL LETTER U WITH OGONEK - '\xdd' # 0xF8 -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xfd' # 0xF9 -> LATIN SMALL LETTER Y WITH ACUTE - '\u0137' # 0xFA -> LATIN SMALL LETTER K WITH CEDILLA - '\u017b' # 0xFB -> LATIN CAPITAL LETTER Z WITH DOT ABOVE - '\u0141' # 0xFC -> LATIN CAPITAL LETTER L WITH STROKE - '\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE - '\u0122' # 0xFE -> LATIN CAPITAL LETTER G WITH CEDILLA - '\u02c7' # 0xFF -> CARON -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/mac_roman.py b/python/Lib/encodings/mac_roman.py deleted file mode 100644 index 550787f..0000000 --- a/python/Lib/encodings/mac_roman.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec mac_roman generated from 'MAPPINGS/VENDORS/APPLE/ROMAN.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mac-roman', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> CONTROL CHARACTER - '\x01' # 0x01 -> CONTROL CHARACTER - '\x02' # 0x02 -> CONTROL CHARACTER - '\x03' # 0x03 -> CONTROL CHARACTER - '\x04' # 0x04 -> CONTROL CHARACTER - '\x05' # 0x05 -> CONTROL CHARACTER - '\x06' # 0x06 -> CONTROL CHARACTER - '\x07' # 0x07 -> CONTROL CHARACTER - '\x08' # 0x08 -> CONTROL CHARACTER - '\t' # 0x09 -> CONTROL CHARACTER - '\n' # 0x0A -> CONTROL CHARACTER - '\x0b' # 0x0B -> CONTROL CHARACTER - '\x0c' # 0x0C -> CONTROL CHARACTER - '\r' # 0x0D -> CONTROL CHARACTER - '\x0e' # 0x0E -> CONTROL CHARACTER - '\x0f' # 0x0F -> CONTROL CHARACTER - '\x10' # 0x10 -> CONTROL CHARACTER - '\x11' # 0x11 -> CONTROL CHARACTER - '\x12' # 0x12 -> CONTROL CHARACTER - '\x13' # 0x13 -> CONTROL CHARACTER - '\x14' # 0x14 -> CONTROL CHARACTER - '\x15' # 0x15 -> CONTROL CHARACTER - '\x16' # 0x16 -> CONTROL CHARACTER - '\x17' # 0x17 -> CONTROL CHARACTER - '\x18' # 0x18 -> CONTROL CHARACTER - '\x19' # 0x19 -> CONTROL CHARACTER - '\x1a' # 0x1A -> CONTROL CHARACTER - '\x1b' # 0x1B -> CONTROL CHARACTER - '\x1c' # 0x1C -> CONTROL CHARACTER - '\x1d' # 0x1D -> CONTROL CHARACTER - '\x1e' # 0x1E -> CONTROL CHARACTER - '\x1f' # 0x1F -> CONTROL CHARACTER - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> CONTROL CHARACTER - '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE - '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE - '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE - '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA - '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE - '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE - '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE - '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE - '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE - '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE - '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE - '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE - '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE - '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE - '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS - '\u2020' # 0xA0 -> DAGGER - '\xb0' # 0xA1 -> DEGREE SIGN - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa7' # 0xA4 -> SECTION SIGN - '\u2022' # 0xA5 -> BULLET - '\xb6' # 0xA6 -> PILCROW SIGN - '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S - '\xae' # 0xA8 -> REGISTERED SIGN - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u2122' # 0xAA -> TRADE MARK SIGN - '\xb4' # 0xAB -> ACUTE ACCENT - '\xa8' # 0xAC -> DIAERESIS - '\u2260' # 0xAD -> NOT EQUAL TO - '\xc6' # 0xAE -> LATIN CAPITAL LETTER AE - '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE - '\u221e' # 0xB0 -> INFINITY - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO - '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO - '\xa5' # 0xB4 -> YEN SIGN - '\xb5' # 0xB5 -> MICRO SIGN - '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL - '\u2211' # 0xB7 -> N-ARY SUMMATION - '\u220f' # 0xB8 -> N-ARY PRODUCT - '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI - '\u222b' # 0xBA -> INTEGRAL - '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR - '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR - '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA - '\xe6' # 0xBE -> LATIN SMALL LETTER AE - '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE - '\xbf' # 0xC0 -> INVERTED QUESTION MARK - '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK - '\xac' # 0xC2 -> NOT SIGN - '\u221a' # 0xC3 -> SQUARE ROOT - '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK - '\u2248' # 0xC5 -> ALMOST EQUAL TO - '\u2206' # 0xC6 -> INCREMENT - '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS - '\xa0' # 0xCA -> NO-BREAK SPACE - '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE - '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE - '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE - '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE - '\u2013' # 0xD0 -> EN DASH - '\u2014' # 0xD1 -> EM DASH - '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK - '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK - '\xf7' # 0xD6 -> DIVISION SIGN - '\u25ca' # 0xD7 -> LOZENGE - '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS - '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\u2044' # 0xDA -> FRACTION SLASH - '\u20ac' # 0xDB -> EURO SIGN - '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\ufb01' # 0xDE -> LATIN SMALL LIGATURE FI - '\ufb02' # 0xDF -> LATIN SMALL LIGATURE FL - '\u2021' # 0xE0 -> DOUBLE DAGGER - '\xb7' # 0xE1 -> MIDDLE DOT - '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK - '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK - '\u2030' # 0xE4 -> PER MILLE SIGN - '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\uf8ff' # 0xF0 -> Apple logo - '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE - '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I - '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\u02dc' # 0xF7 -> SMALL TILDE - '\xaf' # 0xF8 -> MACRON - '\u02d8' # 0xF9 -> BREVE - '\u02d9' # 0xFA -> DOT ABOVE - '\u02da' # 0xFB -> RING ABOVE - '\xb8' # 0xFC -> CEDILLA - '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT - '\u02db' # 0xFE -> OGONEK - '\u02c7' # 0xFF -> CARON -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/mac_romanian.py b/python/Lib/encodings/mac_romanian.py deleted file mode 100644 index 715eaac..0000000 --- a/python/Lib/encodings/mac_romanian.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec mac_romanian generated from 'MAPPINGS/VENDORS/APPLE/ROMANIAN.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mac-romanian', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> CONTROL CHARACTER - '\x01' # 0x01 -> CONTROL CHARACTER - '\x02' # 0x02 -> CONTROL CHARACTER - '\x03' # 0x03 -> CONTROL CHARACTER - '\x04' # 0x04 -> CONTROL CHARACTER - '\x05' # 0x05 -> CONTROL CHARACTER - '\x06' # 0x06 -> CONTROL CHARACTER - '\x07' # 0x07 -> CONTROL CHARACTER - '\x08' # 0x08 -> CONTROL CHARACTER - '\t' # 0x09 -> CONTROL CHARACTER - '\n' # 0x0A -> CONTROL CHARACTER - '\x0b' # 0x0B -> CONTROL CHARACTER - '\x0c' # 0x0C -> CONTROL CHARACTER - '\r' # 0x0D -> CONTROL CHARACTER - '\x0e' # 0x0E -> CONTROL CHARACTER - '\x0f' # 0x0F -> CONTROL CHARACTER - '\x10' # 0x10 -> CONTROL CHARACTER - '\x11' # 0x11 -> CONTROL CHARACTER - '\x12' # 0x12 -> CONTROL CHARACTER - '\x13' # 0x13 -> CONTROL CHARACTER - '\x14' # 0x14 -> CONTROL CHARACTER - '\x15' # 0x15 -> CONTROL CHARACTER - '\x16' # 0x16 -> CONTROL CHARACTER - '\x17' # 0x17 -> CONTROL CHARACTER - '\x18' # 0x18 -> CONTROL CHARACTER - '\x19' # 0x19 -> CONTROL CHARACTER - '\x1a' # 0x1A -> CONTROL CHARACTER - '\x1b' # 0x1B -> CONTROL CHARACTER - '\x1c' # 0x1C -> CONTROL CHARACTER - '\x1d' # 0x1D -> CONTROL CHARACTER - '\x1e' # 0x1E -> CONTROL CHARACTER - '\x1f' # 0x1F -> CONTROL CHARACTER - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> CONTROL CHARACTER - '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE - '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE - '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE - '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA - '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE - '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE - '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE - '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE - '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE - '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE - '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE - '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE - '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE - '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE - '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS - '\u2020' # 0xA0 -> DAGGER - '\xb0' # 0xA1 -> DEGREE SIGN - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa7' # 0xA4 -> SECTION SIGN - '\u2022' # 0xA5 -> BULLET - '\xb6' # 0xA6 -> PILCROW SIGN - '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S - '\xae' # 0xA8 -> REGISTERED SIGN - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u2122' # 0xAA -> TRADE MARK SIGN - '\xb4' # 0xAB -> ACUTE ACCENT - '\xa8' # 0xAC -> DIAERESIS - '\u2260' # 0xAD -> NOT EQUAL TO - '\u0102' # 0xAE -> LATIN CAPITAL LETTER A WITH BREVE - '\u0218' # 0xAF -> LATIN CAPITAL LETTER S WITH COMMA BELOW # for Unicode 3.0 and later - '\u221e' # 0xB0 -> INFINITY - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO - '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO - '\xa5' # 0xB4 -> YEN SIGN - '\xb5' # 0xB5 -> MICRO SIGN - '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL - '\u2211' # 0xB7 -> N-ARY SUMMATION - '\u220f' # 0xB8 -> N-ARY PRODUCT - '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI - '\u222b' # 0xBA -> INTEGRAL - '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR - '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR - '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA - '\u0103' # 0xBE -> LATIN SMALL LETTER A WITH BREVE - '\u0219' # 0xBF -> LATIN SMALL LETTER S WITH COMMA BELOW # for Unicode 3.0 and later - '\xbf' # 0xC0 -> INVERTED QUESTION MARK - '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK - '\xac' # 0xC2 -> NOT SIGN - '\u221a' # 0xC3 -> SQUARE ROOT - '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK - '\u2248' # 0xC5 -> ALMOST EQUAL TO - '\u2206' # 0xC6 -> INCREMENT - '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS - '\xa0' # 0xCA -> NO-BREAK SPACE - '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE - '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE - '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE - '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE - '\u2013' # 0xD0 -> EN DASH - '\u2014' # 0xD1 -> EM DASH - '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK - '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK - '\xf7' # 0xD6 -> DIVISION SIGN - '\u25ca' # 0xD7 -> LOZENGE - '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS - '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\u2044' # 0xDA -> FRACTION SLASH - '\u20ac' # 0xDB -> EURO SIGN - '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\u021a' # 0xDE -> LATIN CAPITAL LETTER T WITH COMMA BELOW # for Unicode 3.0 and later - '\u021b' # 0xDF -> LATIN SMALL LETTER T WITH COMMA BELOW # for Unicode 3.0 and later - '\u2021' # 0xE0 -> DOUBLE DAGGER - '\xb7' # 0xE1 -> MIDDLE DOT - '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK - '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK - '\u2030' # 0xE4 -> PER MILLE SIGN - '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\uf8ff' # 0xF0 -> Apple logo - '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE - '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I - '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\u02dc' # 0xF7 -> SMALL TILDE - '\xaf' # 0xF8 -> MACRON - '\u02d8' # 0xF9 -> BREVE - '\u02d9' # 0xFA -> DOT ABOVE - '\u02da' # 0xFB -> RING ABOVE - '\xb8' # 0xFC -> CEDILLA - '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT - '\u02db' # 0xFE -> OGONEK - '\u02c7' # 0xFF -> CARON -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/mac_turkish.py b/python/Lib/encodings/mac_turkish.py deleted file mode 100644 index 005bbc4..0000000 --- a/python/Lib/encodings/mac_turkish.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec mac_turkish generated from 'MAPPINGS/VENDORS/APPLE/TURKISH.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mac-turkish', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> CONTROL CHARACTER - '\x01' # 0x01 -> CONTROL CHARACTER - '\x02' # 0x02 -> CONTROL CHARACTER - '\x03' # 0x03 -> CONTROL CHARACTER - '\x04' # 0x04 -> CONTROL CHARACTER - '\x05' # 0x05 -> CONTROL CHARACTER - '\x06' # 0x06 -> CONTROL CHARACTER - '\x07' # 0x07 -> CONTROL CHARACTER - '\x08' # 0x08 -> CONTROL CHARACTER - '\t' # 0x09 -> CONTROL CHARACTER - '\n' # 0x0A -> CONTROL CHARACTER - '\x0b' # 0x0B -> CONTROL CHARACTER - '\x0c' # 0x0C -> CONTROL CHARACTER - '\r' # 0x0D -> CONTROL CHARACTER - '\x0e' # 0x0E -> CONTROL CHARACTER - '\x0f' # 0x0F -> CONTROL CHARACTER - '\x10' # 0x10 -> CONTROL CHARACTER - '\x11' # 0x11 -> CONTROL CHARACTER - '\x12' # 0x12 -> CONTROL CHARACTER - '\x13' # 0x13 -> CONTROL CHARACTER - '\x14' # 0x14 -> CONTROL CHARACTER - '\x15' # 0x15 -> CONTROL CHARACTER - '\x16' # 0x16 -> CONTROL CHARACTER - '\x17' # 0x17 -> CONTROL CHARACTER - '\x18' # 0x18 -> CONTROL CHARACTER - '\x19' # 0x19 -> CONTROL CHARACTER - '\x1a' # 0x1A -> CONTROL CHARACTER - '\x1b' # 0x1B -> CONTROL CHARACTER - '\x1c' # 0x1C -> CONTROL CHARACTER - '\x1d' # 0x1D -> CONTROL CHARACTER - '\x1e' # 0x1E -> CONTROL CHARACTER - '\x1f' # 0x1F -> CONTROL CHARACTER - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> CONTROL CHARACTER - '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE - '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE - '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE - '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA - '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE - '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE - '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS - '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE - '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE - '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE - '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE - '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE - '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE - '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE - '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE - '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS - '\u2020' # 0xA0 -> DAGGER - '\xb0' # 0xA1 -> DEGREE SIGN - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa7' # 0xA4 -> SECTION SIGN - '\u2022' # 0xA5 -> BULLET - '\xb6' # 0xA6 -> PILCROW SIGN - '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S - '\xae' # 0xA8 -> REGISTERED SIGN - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u2122' # 0xAA -> TRADE MARK SIGN - '\xb4' # 0xAB -> ACUTE ACCENT - '\xa8' # 0xAC -> DIAERESIS - '\u2260' # 0xAD -> NOT EQUAL TO - '\xc6' # 0xAE -> LATIN CAPITAL LETTER AE - '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE - '\u221e' # 0xB0 -> INFINITY - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO - '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO - '\xa5' # 0xB4 -> YEN SIGN - '\xb5' # 0xB5 -> MICRO SIGN - '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL - '\u2211' # 0xB7 -> N-ARY SUMMATION - '\u220f' # 0xB8 -> N-ARY PRODUCT - '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI - '\u222b' # 0xBA -> INTEGRAL - '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR - '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR - '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA - '\xe6' # 0xBE -> LATIN SMALL LETTER AE - '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE - '\xbf' # 0xC0 -> INVERTED QUESTION MARK - '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK - '\xac' # 0xC2 -> NOT SIGN - '\u221a' # 0xC3 -> SQUARE ROOT - '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK - '\u2248' # 0xC5 -> ALMOST EQUAL TO - '\u2206' # 0xC6 -> INCREMENT - '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS - '\xa0' # 0xCA -> NO-BREAK SPACE - '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE - '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE - '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE - '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE - '\u2013' # 0xD0 -> EN DASH - '\u2014' # 0xD1 -> EM DASH - '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK - '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK - '\xf7' # 0xD6 -> DIVISION SIGN - '\u25ca' # 0xD7 -> LOZENGE - '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS - '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\u011e' # 0xDA -> LATIN CAPITAL LETTER G WITH BREVE - '\u011f' # 0xDB -> LATIN SMALL LETTER G WITH BREVE - '\u0130' # 0xDC -> LATIN CAPITAL LETTER I WITH DOT ABOVE - '\u0131' # 0xDD -> LATIN SMALL LETTER DOTLESS I - '\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA - '\u015f' # 0xDF -> LATIN SMALL LETTER S WITH CEDILLA - '\u2021' # 0xE0 -> DOUBLE DAGGER - '\xb7' # 0xE1 -> MIDDLE DOT - '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK - '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK - '\u2030' # 0xE4 -> PER MILLE SIGN - '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\uf8ff' # 0xF0 -> Apple logo - '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE - '\uf8a0' # 0xF5 -> undefined1 - '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\u02dc' # 0xF7 -> SMALL TILDE - '\xaf' # 0xF8 -> MACRON - '\u02d8' # 0xF9 -> BREVE - '\u02d9' # 0xFA -> DOT ABOVE - '\u02da' # 0xFB -> RING ABOVE - '\xb8' # 0xFC -> CEDILLA - '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT - '\u02db' # 0xFE -> OGONEK - '\u02c7' # 0xFF -> CARON -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/mbcs.py b/python/Lib/encodings/mbcs.py deleted file mode 100644 index d6b17b5..0000000 --- a/python/Lib/encodings/mbcs.py +++ /dev/null @@ -1,47 +0,0 @@ -""" Python 'mbcs' Codec for Windows - - -Cloned by Mark Hammond (mhammond@skippinet.com.au) from ascii.py, -which was written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -""" -# Import them explicitly to cause an ImportError -# on non-Windows systems -from codecs import mbcs_encode, mbcs_decode -# for IncrementalDecoder, IncrementalEncoder, ... -import codecs - -### Codec APIs - -encode = mbcs_encode - -def decode(input, errors='strict'): - return mbcs_decode(input, errors, True) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return mbcs_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - _buffer_decode = mbcs_decode - -class StreamWriter(codecs.StreamWriter): - encode = mbcs_encode - -class StreamReader(codecs.StreamReader): - decode = mbcs_decode - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mbcs', - encode=encode, - decode=decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/oem.py b/python/Lib/encodings/oem.py deleted file mode 100644 index e4a5fbe..0000000 --- a/python/Lib/encodings/oem.py +++ /dev/null @@ -1,41 +0,0 @@ -""" Python 'oem' Codec for Windows - -""" -# Import them explicitly to cause an ImportError -# on non-Windows systems -from codecs import oem_encode, oem_decode -# for IncrementalDecoder, IncrementalEncoder, ... -import codecs - -### Codec APIs - -encode = oem_encode - -def decode(input, errors='strict'): - return oem_decode(input, errors, True) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return oem_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - _buffer_decode = oem_decode - -class StreamWriter(codecs.StreamWriter): - encode = oem_encode - -class StreamReader(codecs.StreamReader): - decode = oem_decode - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='oem', - encode=encode, - decode=decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/palmos.py b/python/Lib/encodings/palmos.py deleted file mode 100644 index 63ce417..0000000 --- a/python/Lib/encodings/palmos.py +++ /dev/null @@ -1,308 +0,0 @@ -""" Python Character Mapping Codec for PalmOS 3.5. - -Written by Sjoerd Mullender (sjoerd@acm.org); based on iso8859_15.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='palmos', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\u20ac' # 0x80 -> EURO SIGN - '\x81' # 0x81 -> - '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK - '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u2020' # 0x86 -> DAGGER - '\u2021' # 0x87 -> DOUBLE DAGGER - '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT - '\u2030' # 0x89 -> PER MILLE SIGN - '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON - '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE - '\u2666' # 0x8D -> BLACK DIAMOND SUIT - '\u2663' # 0x8E -> BLACK CLUB SUIT - '\u2665' # 0x8F -> BLACK HEART SUIT - '\u2660' # 0x90 -> BLACK SPADE SUIT - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\u02dc' # 0x98 -> SMALL TILDE - '\u2122' # 0x99 -> TRADE MARK SIGN - '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON - '\x9b' # 0x9B -> - '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK - '\xa2' # 0xA2 -> CENT SIGN - '\xa3' # 0xA3 -> POUND SIGN - '\xa4' # 0xA4 -> CURRENCY SIGN - '\xa5' # 0xA5 -> YEN SIGN - '\xa6' # 0xA6 -> BROKEN BAR - '\xa7' # 0xA7 -> SECTION SIGN - '\xa8' # 0xA8 -> DIAERESIS - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\xad' # 0xAD -> SOFT HYPHEN - '\xae' # 0xAE -> REGISTERED SIGN - '\xaf' # 0xAF -> MACRON - '\xb0' # 0xB0 -> DEGREE SIGN - '\xb1' # 0xB1 -> PLUS-MINUS SIGN - '\xb2' # 0xB2 -> SUPERSCRIPT TWO - '\xb3' # 0xB3 -> SUPERSCRIPT THREE - '\xb4' # 0xB4 -> ACUTE ACCENT - '\xb5' # 0xB5 -> MICRO SIGN - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\xb8' # 0xB8 -> CEDILLA - '\xb9' # 0xB9 -> SUPERSCRIPT ONE - '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER - '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF - '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS - '\xbf' # 0xBF -> INVERTED QUESTION MARK - '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE - '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE - '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX - '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE - '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE - '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE - '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA - '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE - '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE - '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX - '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS - '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE - '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE - '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX - '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS - '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic) - '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE - '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE - '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE - '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xd7' # 0xD7 -> MULTIPLICATION SIGN - '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE - '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE - '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE - '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX - '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN (Icelandic) - '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) - '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE - '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE - '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX - '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE - '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS - '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE - '\xe6' # 0xE6 -> LATIN SMALL LETTER AE - '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA - '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE - '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE - '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX - '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS - '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE - '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE - '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX - '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS - '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH (Icelandic) - '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE - '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE - '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE - '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE - '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf7' # 0xF7 -> DIVISION SIGN - '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE - '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE - '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE - '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX - '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS - '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE - '\xfe' # 0xFE -> LATIN SMALL LETTER THORN (Icelandic) - '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/ptcp154.py b/python/Lib/encodings/ptcp154.py deleted file mode 100644 index 5c52059..0000000 --- a/python/Lib/encodings/ptcp154.py +++ /dev/null @@ -1,312 +0,0 @@ -""" Python Character Mapping Codec generated from 'PTCP154.txt' with gencodec.py. - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. -(c) Copyright 2000 Guido van Rossum. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='ptcp154', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE (DEL) - '\u0496' # 0x80 -> CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER - '\u0492' # 0x81 -> CYRILLIC CAPITAL LETTER GHE WITH STROKE - '\u04ee' # 0x82 -> CYRILLIC CAPITAL LETTER U WITH MACRON - '\u0493' # 0x83 -> CYRILLIC SMALL LETTER GHE WITH STROKE - '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK - '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS - '\u04b6' # 0x86 -> CYRILLIC CAPITAL LETTER CHE WITH DESCENDER - '\u04ae' # 0x87 -> CYRILLIC CAPITAL LETTER STRAIGHT U - '\u04b2' # 0x88 -> CYRILLIC CAPITAL LETTER HA WITH DESCENDER - '\u04af' # 0x89 -> CYRILLIC SMALL LETTER STRAIGHT U - '\u04a0' # 0x8A -> CYRILLIC CAPITAL LETTER BASHKIR KA - '\u04e2' # 0x8B -> CYRILLIC CAPITAL LETTER I WITH MACRON - '\u04a2' # 0x8C -> CYRILLIC CAPITAL LETTER EN WITH DESCENDER - '\u049a' # 0x8D -> CYRILLIC CAPITAL LETTER KA WITH DESCENDER - '\u04ba' # 0x8E -> CYRILLIC CAPITAL LETTER SHHA - '\u04b8' # 0x8F -> CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE - '\u0497' # 0x90 -> CYRILLIC SMALL LETTER ZHE WITH DESCENDER - '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK - '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK - '\u2022' # 0x95 -> BULLET - '\u2013' # 0x96 -> EN DASH - '\u2014' # 0x97 -> EM DASH - '\u04b3' # 0x98 -> CYRILLIC SMALL LETTER HA WITH DESCENDER - '\u04b7' # 0x99 -> CYRILLIC SMALL LETTER CHE WITH DESCENDER - '\u04a1' # 0x9A -> CYRILLIC SMALL LETTER BASHKIR KA - '\u04e3' # 0x9B -> CYRILLIC SMALL LETTER I WITH MACRON - '\u04a3' # 0x9C -> CYRILLIC SMALL LETTER EN WITH DESCENDER - '\u049b' # 0x9D -> CYRILLIC SMALL LETTER KA WITH DESCENDER - '\u04bb' # 0x9E -> CYRILLIC SMALL LETTER SHHA - '\u04b9' # 0x9F -> CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE - '\xa0' # 0xA0 -> NO-BREAK SPACE - '\u040e' # 0xA1 -> CYRILLIC CAPITAL LETTER SHORT U (Byelorussian) - '\u045e' # 0xA2 -> CYRILLIC SMALL LETTER SHORT U (Byelorussian) - '\u0408' # 0xA3 -> CYRILLIC CAPITAL LETTER JE - '\u04e8' # 0xA4 -> CYRILLIC CAPITAL LETTER BARRED O - '\u0498' # 0xA5 -> CYRILLIC CAPITAL LETTER ZE WITH DESCENDER - '\u04b0' # 0xA6 -> CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE - '\xa7' # 0xA7 -> SECTION SIGN - '\u0401' # 0xA8 -> CYRILLIC CAPITAL LETTER IO - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u04d8' # 0xAA -> CYRILLIC CAPITAL LETTER SCHWA - '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xac' # 0xAC -> NOT SIGN - '\u04ef' # 0xAD -> CYRILLIC SMALL LETTER U WITH MACRON - '\xae' # 0xAE -> REGISTERED SIGN - '\u049c' # 0xAF -> CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE - '\xb0' # 0xB0 -> DEGREE SIGN - '\u04b1' # 0xB1 -> CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE - '\u0406' # 0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0456' # 0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - '\u0499' # 0xB4 -> CYRILLIC SMALL LETTER ZE WITH DESCENDER - '\u04e9' # 0xB5 -> CYRILLIC SMALL LETTER BARRED O - '\xb6' # 0xB6 -> PILCROW SIGN - '\xb7' # 0xB7 -> MIDDLE DOT - '\u0451' # 0xB8 -> CYRILLIC SMALL LETTER IO - '\u2116' # 0xB9 -> NUMERO SIGN - '\u04d9' # 0xBA -> CYRILLIC SMALL LETTER SCHWA - '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u0458' # 0xBC -> CYRILLIC SMALL LETTER JE - '\u04aa' # 0xBD -> CYRILLIC CAPITAL LETTER ES WITH DESCENDER - '\u04ab' # 0xBE -> CYRILLIC SMALL LETTER ES WITH DESCENDER - '\u049d' # 0xBF -> CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE - '\u0410' # 0xC0 -> CYRILLIC CAPITAL LETTER A - '\u0411' # 0xC1 -> CYRILLIC CAPITAL LETTER BE - '\u0412' # 0xC2 -> CYRILLIC CAPITAL LETTER VE - '\u0413' # 0xC3 -> CYRILLIC CAPITAL LETTER GHE - '\u0414' # 0xC4 -> CYRILLIC CAPITAL LETTER DE - '\u0415' # 0xC5 -> CYRILLIC CAPITAL LETTER IE - '\u0416' # 0xC6 -> CYRILLIC CAPITAL LETTER ZHE - '\u0417' # 0xC7 -> CYRILLIC CAPITAL LETTER ZE - '\u0418' # 0xC8 -> CYRILLIC CAPITAL LETTER I - '\u0419' # 0xC9 -> CYRILLIC CAPITAL LETTER SHORT I - '\u041a' # 0xCA -> CYRILLIC CAPITAL LETTER KA - '\u041b' # 0xCB -> CYRILLIC CAPITAL LETTER EL - '\u041c' # 0xCC -> CYRILLIC CAPITAL LETTER EM - '\u041d' # 0xCD -> CYRILLIC CAPITAL LETTER EN - '\u041e' # 0xCE -> CYRILLIC CAPITAL LETTER O - '\u041f' # 0xCF -> CYRILLIC CAPITAL LETTER PE - '\u0420' # 0xD0 -> CYRILLIC CAPITAL LETTER ER - '\u0421' # 0xD1 -> CYRILLIC CAPITAL LETTER ES - '\u0422' # 0xD2 -> CYRILLIC CAPITAL LETTER TE - '\u0423' # 0xD3 -> CYRILLIC CAPITAL LETTER U - '\u0424' # 0xD4 -> CYRILLIC CAPITAL LETTER EF - '\u0425' # 0xD5 -> CYRILLIC CAPITAL LETTER HA - '\u0426' # 0xD6 -> CYRILLIC CAPITAL LETTER TSE - '\u0427' # 0xD7 -> CYRILLIC CAPITAL LETTER CHE - '\u0428' # 0xD8 -> CYRILLIC CAPITAL LETTER SHA - '\u0429' # 0xD9 -> CYRILLIC CAPITAL LETTER SHCHA - '\u042a' # 0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN - '\u042b' # 0xDB -> CYRILLIC CAPITAL LETTER YERU - '\u042c' # 0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN - '\u042d' # 0xDD -> CYRILLIC CAPITAL LETTER E - '\u042e' # 0xDE -> CYRILLIC CAPITAL LETTER YU - '\u042f' # 0xDF -> CYRILLIC CAPITAL LETTER YA - '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A - '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE - '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE - '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE - '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE - '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE - '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE - '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE - '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I - '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I - '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA - '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL - '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM - '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN - '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O - '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE - '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER - '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES - '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE - '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U - '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF - '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA - '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE - '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE - '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA - '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA - '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN - '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU - '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN - '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E - '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU - '\u044f' # 0xFF -> CYRILLIC SMALL LETTER YA -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/punycode.py b/python/Lib/encodings/punycode.py deleted file mode 100644 index 7190c70..0000000 --- a/python/Lib/encodings/punycode.py +++ /dev/null @@ -1,237 +0,0 @@ -""" Codec for the Punicode encoding, as specified in RFC 3492 - -Written by Martin v. Löwis. -""" - -import codecs - -##################### Encoding ##################################### - -def segregate(str): - """3.1 Basic code point segregation""" - base = bytearray() - extended = set() - for c in str: - if ord(c) < 128: - base.append(ord(c)) - else: - extended.add(c) - extended = sorted(extended) - return bytes(base), extended - -def selective_len(str, max): - """Return the length of str, considering only characters below max.""" - res = 0 - for c in str: - if ord(c) < max: - res += 1 - return res - -def selective_find(str, char, index, pos): - """Return a pair (index, pos), indicating the next occurrence of - char in str. index is the position of the character considering - only ordinals up to and including char, and pos is the position in - the full string. index/pos is the starting position in the full - string.""" - - l = len(str) - while 1: - pos += 1 - if pos == l: - return (-1, -1) - c = str[pos] - if c == char: - return index+1, pos - elif c < char: - index += 1 - -def insertion_unsort(str, extended): - """3.2 Insertion unsort coding""" - oldchar = 0x80 - result = [] - oldindex = -1 - for c in extended: - index = pos = -1 - char = ord(c) - curlen = selective_len(str, char) - delta = (curlen+1) * (char - oldchar) - while 1: - index,pos = selective_find(str,c,index,pos) - if index == -1: - break - delta += index - oldindex - result.append(delta-1) - oldindex = index - delta = 0 - oldchar = char - - return result - -def T(j, bias): - # Punycode parameters: tmin = 1, tmax = 26, base = 36 - res = 36 * (j + 1) - bias - if res < 1: return 1 - if res > 26: return 26 - return res - -digits = b"abcdefghijklmnopqrstuvwxyz0123456789" -def generate_generalized_integer(N, bias): - """3.3 Generalized variable-length integers""" - result = bytearray() - j = 0 - while 1: - t = T(j, bias) - if N < t: - result.append(digits[N]) - return bytes(result) - result.append(digits[t + ((N - t) % (36 - t))]) - N = (N - t) // (36 - t) - j += 1 - -def adapt(delta, first, numchars): - if first: - delta //= 700 - else: - delta //= 2 - delta += delta // numchars - # ((base - tmin) * tmax) // 2 == 455 - divisions = 0 - while delta > 455: - delta = delta // 35 # base - tmin - divisions += 36 - bias = divisions + (36 * delta // (delta + 38)) - return bias - - -def generate_integers(baselen, deltas): - """3.4 Bias adaptation""" - # Punycode parameters: initial bias = 72, damp = 700, skew = 38 - result = bytearray() - bias = 72 - for points, delta in enumerate(deltas): - s = generate_generalized_integer(delta, bias) - result.extend(s) - bias = adapt(delta, points==0, baselen+points+1) - return bytes(result) - -def punycode_encode(text): - base, extended = segregate(text) - deltas = insertion_unsort(text, extended) - extended = generate_integers(len(base), deltas) - if base: - return base + b"-" + extended - return extended - -##################### Decoding ##################################### - -def decode_generalized_number(extended, extpos, bias, errors): - """3.3 Generalized variable-length integers""" - result = 0 - w = 1 - j = 0 - while 1: - try: - char = ord(extended[extpos]) - except IndexError: - if errors == "strict": - raise UnicodeError("incomplete punicode string") - return extpos + 1, None - extpos += 1 - if 0x41 <= char <= 0x5A: # A-Z - digit = char - 0x41 - elif 0x30 <= char <= 0x39: - digit = char - 22 # 0x30-26 - elif errors == "strict": - raise UnicodeError("Invalid extended code point '%s'" - % extended[extpos-1]) - else: - return extpos, None - t = T(j, bias) - result += digit * w - if digit < t: - return extpos, result - w = w * (36 - t) - j += 1 - - -def insertion_sort(base, extended, errors): - """3.2 Insertion unsort coding""" - char = 0x80 - pos = -1 - bias = 72 - extpos = 0 - while extpos < len(extended): - newpos, delta = decode_generalized_number(extended, extpos, - bias, errors) - if delta is None: - # There was an error in decoding. We can't continue because - # synchronization is lost. - return base - pos += delta+1 - char += pos // (len(base) + 1) - if char > 0x10FFFF: - if errors == "strict": - raise UnicodeError("Invalid character U+%x" % char) - char = ord('?') - pos = pos % (len(base) + 1) - base = base[:pos] + chr(char) + base[pos:] - bias = adapt(delta, (extpos == 0), len(base)) - extpos = newpos - return base - -def punycode_decode(text, errors): - if isinstance(text, str): - text = text.encode("ascii") - if isinstance(text, memoryview): - text = bytes(text) - pos = text.rfind(b"-") - if pos == -1: - base = "" - extended = str(text, "ascii").upper() - else: - base = str(text[:pos], "ascii", errors) - extended = str(text[pos+1:], "ascii").upper() - return insertion_sort(base, extended, errors) - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self, input, errors='strict'): - res = punycode_encode(input) - return res, len(input) - - def decode(self, input, errors='strict'): - if errors not in ('strict', 'replace', 'ignore'): - raise UnicodeError("Unsupported error handling "+errors) - res = punycode_decode(input, errors) - return res, len(input) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return punycode_encode(input) - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - if self.errors not in ('strict', 'replace', 'ignore'): - raise UnicodeError("Unsupported error handling "+self.errors) - return punycode_decode(input, self.errors) - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='punycode', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) diff --git a/python/Lib/encodings/quopri_codec.py b/python/Lib/encodings/quopri_codec.py deleted file mode 100644 index 449fe27..0000000 --- a/python/Lib/encodings/quopri_codec.py +++ /dev/null @@ -1,56 +0,0 @@ -"""Codec for quoted-printable encoding. - -This codec de/encodes from bytes to bytes. -""" - -import codecs -import quopri -from io import BytesIO - -def quopri_encode(input, errors='strict'): - assert errors == 'strict' - f = BytesIO(input) - g = BytesIO() - quopri.encode(f, g, quotetabs=True) - return (g.getvalue(), len(input)) - -def quopri_decode(input, errors='strict'): - assert errors == 'strict' - f = BytesIO(input) - g = BytesIO() - quopri.decode(f, g) - return (g.getvalue(), len(input)) - -class Codec(codecs.Codec): - def encode(self, input, errors='strict'): - return quopri_encode(input, errors) - def decode(self, input, errors='strict'): - return quopri_decode(input, errors) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return quopri_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return quopri_decode(input, self.errors)[0] - -class StreamWriter(Codec, codecs.StreamWriter): - charbuffertype = bytes - -class StreamReader(Codec, codecs.StreamReader): - charbuffertype = bytes - -# encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='quopri', - encode=quopri_encode, - decode=quopri_decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - _is_text_encoding=False, - ) diff --git a/python/Lib/encodings/raw_unicode_escape.py b/python/Lib/encodings/raw_unicode_escape.py deleted file mode 100644 index 8e9661b..0000000 --- a/python/Lib/encodings/raw_unicode_escape.py +++ /dev/null @@ -1,46 +0,0 @@ -""" Python 'raw-unicode-escape' Codec - - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -""" -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - # Note: Binding these as C functions will result in the class not - # converting them to methods. This is intended. - encode = codecs.raw_unicode_escape_encode - decode = codecs.raw_unicode_escape_decode - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.raw_unicode_escape_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - def _buffer_decode(self, input, errors, final): - return codecs.raw_unicode_escape_decode(input, errors, final) - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - def decode(self, input, errors='strict'): - return codecs.raw_unicode_escape_decode(input, errors, False) - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='raw-unicode-escape', - encode=Codec.encode, - decode=Codec.decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) diff --git a/python/Lib/encodings/rot_13.py b/python/Lib/encodings/rot_13.py deleted file mode 100644 index e14b428..0000000 --- a/python/Lib/encodings/rot_13.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python -""" Python Character Mapping Codec for ROT13. - -This codec de/encodes from str to str. - -Written by Marc-Andre Lemburg (mal@lemburg.com). -""" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - def encode(self, input, errors='strict'): - return (str.translate(input, rot13_map), len(input)) - - def decode(self, input, errors='strict'): - return (str.translate(input, rot13_map), len(input)) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return str.translate(input, rot13_map) - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return str.translate(input, rot13_map) - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='rot-13', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - _is_text_encoding=False, - ) - -### Map - -rot13_map = codecs.make_identity_dict(range(256)) -rot13_map.update({ - 0x0041: 0x004e, - 0x0042: 0x004f, - 0x0043: 0x0050, - 0x0044: 0x0051, - 0x0045: 0x0052, - 0x0046: 0x0053, - 0x0047: 0x0054, - 0x0048: 0x0055, - 0x0049: 0x0056, - 0x004a: 0x0057, - 0x004b: 0x0058, - 0x004c: 0x0059, - 0x004d: 0x005a, - 0x004e: 0x0041, - 0x004f: 0x0042, - 0x0050: 0x0043, - 0x0051: 0x0044, - 0x0052: 0x0045, - 0x0053: 0x0046, - 0x0054: 0x0047, - 0x0055: 0x0048, - 0x0056: 0x0049, - 0x0057: 0x004a, - 0x0058: 0x004b, - 0x0059: 0x004c, - 0x005a: 0x004d, - 0x0061: 0x006e, - 0x0062: 0x006f, - 0x0063: 0x0070, - 0x0064: 0x0071, - 0x0065: 0x0072, - 0x0066: 0x0073, - 0x0067: 0x0074, - 0x0068: 0x0075, - 0x0069: 0x0076, - 0x006a: 0x0077, - 0x006b: 0x0078, - 0x006c: 0x0079, - 0x006d: 0x007a, - 0x006e: 0x0061, - 0x006f: 0x0062, - 0x0070: 0x0063, - 0x0071: 0x0064, - 0x0072: 0x0065, - 0x0073: 0x0066, - 0x0074: 0x0067, - 0x0075: 0x0068, - 0x0076: 0x0069, - 0x0077: 0x006a, - 0x0078: 0x006b, - 0x0079: 0x006c, - 0x007a: 0x006d, -}) - -### Filter API - -def rot13(infile, outfile): - outfile.write(codecs.encode(infile.read(), 'rot-13')) - -if __name__ == '__main__': - import sys - rot13(sys.stdin, sys.stdout) diff --git a/python/Lib/encodings/shift_jis.py b/python/Lib/encodings/shift_jis.py deleted file mode 100644 index 3db9364..0000000 --- a/python/Lib/encodings/shift_jis.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# shift_jis.py: Python Unicode Codec for SHIFT_JIS -# -# Written by Hye-Shik Chang -# - -import _codecs_jp, codecs -import _multibytecodec as mbc - -codec = _codecs_jp.getcodec('shift_jis') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='shift_jis', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/shift_jis_2004.py b/python/Lib/encodings/shift_jis_2004.py deleted file mode 100644 index 3e48bb7..0000000 --- a/python/Lib/encodings/shift_jis_2004.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# shift_jis_2004.py: Python Unicode Codec for SHIFT_JIS_2004 -# -# Written by Hye-Shik Chang -# - -import _codecs_jp, codecs -import _multibytecodec as mbc - -codec = _codecs_jp.getcodec('shift_jis_2004') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='shift_jis_2004', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/shift_jisx0213.py b/python/Lib/encodings/shift_jisx0213.py deleted file mode 100644 index 4092e41..0000000 --- a/python/Lib/encodings/shift_jisx0213.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# shift_jisx0213.py: Python Unicode Codec for SHIFT_JISX0213 -# -# Written by Hye-Shik Chang -# - -import _codecs_jp, codecs -import _multibytecodec as mbc - -codec = _codecs_jp.getcodec('shift_jisx0213') - -class Codec(codecs.Codec): - encode = codec.encode - decode = codec.decode - -class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, - codecs.IncrementalEncoder): - codec = codec - -class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, - codecs.IncrementalDecoder): - codec = codec - -class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): - codec = codec - -class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): - codec = codec - -def getregentry(): - return codecs.CodecInfo( - name='shift_jisx0213', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/tis_620.py b/python/Lib/encodings/tis_620.py deleted file mode 100644 index 1ff11b2..0000000 --- a/python/Lib/encodings/tis_620.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec tis_620 generated from 'python-mappings/TIS-620.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='tis-620', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> NULL - '\x01' # 0x01 -> START OF HEADING - '\x02' # 0x02 -> START OF TEXT - '\x03' # 0x03 -> END OF TEXT - '\x04' # 0x04 -> END OF TRANSMISSION - '\x05' # 0x05 -> ENQUIRY - '\x06' # 0x06 -> ACKNOWLEDGE - '\x07' # 0x07 -> BELL - '\x08' # 0x08 -> BACKSPACE - '\t' # 0x09 -> HORIZONTAL TABULATION - '\n' # 0x0A -> LINE FEED - '\x0b' # 0x0B -> VERTICAL TABULATION - '\x0c' # 0x0C -> FORM FEED - '\r' # 0x0D -> CARRIAGE RETURN - '\x0e' # 0x0E -> SHIFT OUT - '\x0f' # 0x0F -> SHIFT IN - '\x10' # 0x10 -> DATA LINK ESCAPE - '\x11' # 0x11 -> DEVICE CONTROL ONE - '\x12' # 0x12 -> DEVICE CONTROL TWO - '\x13' # 0x13 -> DEVICE CONTROL THREE - '\x14' # 0x14 -> DEVICE CONTROL FOUR - '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE - '\x16' # 0x16 -> SYNCHRONOUS IDLE - '\x17' # 0x17 -> END OF TRANSMISSION BLOCK - '\x18' # 0x18 -> CANCEL - '\x19' # 0x19 -> END OF MEDIUM - '\x1a' # 0x1A -> SUBSTITUTE - '\x1b' # 0x1B -> ESCAPE - '\x1c' # 0x1C -> FILE SEPARATOR - '\x1d' # 0x1D -> GROUP SEPARATOR - '\x1e' # 0x1E -> RECORD SEPARATOR - '\x1f' # 0x1F -> UNIT SEPARATOR - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> DELETE - '\x80' # 0x80 -> - '\x81' # 0x81 -> - '\x82' # 0x82 -> - '\x83' # 0x83 -> - '\x84' # 0x84 -> - '\x85' # 0x85 -> - '\x86' # 0x86 -> - '\x87' # 0x87 -> - '\x88' # 0x88 -> - '\x89' # 0x89 -> - '\x8a' # 0x8A -> - '\x8b' # 0x8B -> - '\x8c' # 0x8C -> - '\x8d' # 0x8D -> - '\x8e' # 0x8E -> - '\x8f' # 0x8F -> - '\x90' # 0x90 -> - '\x91' # 0x91 -> - '\x92' # 0x92 -> - '\x93' # 0x93 -> - '\x94' # 0x94 -> - '\x95' # 0x95 -> - '\x96' # 0x96 -> - '\x97' # 0x97 -> - '\x98' # 0x98 -> - '\x99' # 0x99 -> - '\x9a' # 0x9A -> - '\x9b' # 0x9B -> - '\x9c' # 0x9C -> - '\x9d' # 0x9D -> - '\x9e' # 0x9E -> - '\x9f' # 0x9F -> - '\ufffe' - '\u0e01' # 0xA1 -> THAI CHARACTER KO KAI - '\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI - '\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT - '\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI - '\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON - '\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG - '\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU - '\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN - '\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING - '\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG - '\u0e0b' # 0xAB -> THAI CHARACTER SO SO - '\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE - '\u0e0d' # 0xAD -> THAI CHARACTER YO YING - '\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA - '\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK - '\u0e10' # 0xB0 -> THAI CHARACTER THO THAN - '\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO - '\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO - '\u0e13' # 0xB3 -> THAI CHARACTER NO NEN - '\u0e14' # 0xB4 -> THAI CHARACTER DO DEK - '\u0e15' # 0xB5 -> THAI CHARACTER TO TAO - '\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG - '\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN - '\u0e18' # 0xB8 -> THAI CHARACTER THO THONG - '\u0e19' # 0xB9 -> THAI CHARACTER NO NU - '\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI - '\u0e1b' # 0xBB -> THAI CHARACTER PO PLA - '\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG - '\u0e1d' # 0xBD -> THAI CHARACTER FO FA - '\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN - '\u0e1f' # 0xBF -> THAI CHARACTER FO FAN - '\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO - '\u0e21' # 0xC1 -> THAI CHARACTER MO MA - '\u0e22' # 0xC2 -> THAI CHARACTER YO YAK - '\u0e23' # 0xC3 -> THAI CHARACTER RO RUA - '\u0e24' # 0xC4 -> THAI CHARACTER RU - '\u0e25' # 0xC5 -> THAI CHARACTER LO LING - '\u0e26' # 0xC6 -> THAI CHARACTER LU - '\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN - '\u0e28' # 0xC8 -> THAI CHARACTER SO SALA - '\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI - '\u0e2a' # 0xCA -> THAI CHARACTER SO SUA - '\u0e2b' # 0xCB -> THAI CHARACTER HO HIP - '\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA - '\u0e2d' # 0xCD -> THAI CHARACTER O ANG - '\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK - '\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI - '\u0e30' # 0xD0 -> THAI CHARACTER SARA A - '\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT - '\u0e32' # 0xD2 -> THAI CHARACTER SARA AA - '\u0e33' # 0xD3 -> THAI CHARACTER SARA AM - '\u0e34' # 0xD4 -> THAI CHARACTER SARA I - '\u0e35' # 0xD5 -> THAI CHARACTER SARA II - '\u0e36' # 0xD6 -> THAI CHARACTER SARA UE - '\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE - '\u0e38' # 0xD8 -> THAI CHARACTER SARA U - '\u0e39' # 0xD9 -> THAI CHARACTER SARA UU - '\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' - '\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT - '\u0e40' # 0xE0 -> THAI CHARACTER SARA E - '\u0e41' # 0xE1 -> THAI CHARACTER SARA AE - '\u0e42' # 0xE2 -> THAI CHARACTER SARA O - '\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN - '\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI - '\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO - '\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK - '\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU - '\u0e48' # 0xE8 -> THAI CHARACTER MAI EK - '\u0e49' # 0xE9 -> THAI CHARACTER MAI THO - '\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI - '\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA - '\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT - '\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT - '\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN - '\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN - '\u0e50' # 0xF0 -> THAI DIGIT ZERO - '\u0e51' # 0xF1 -> THAI DIGIT ONE - '\u0e52' # 0xF2 -> THAI DIGIT TWO - '\u0e53' # 0xF3 -> THAI DIGIT THREE - '\u0e54' # 0xF4 -> THAI DIGIT FOUR - '\u0e55' # 0xF5 -> THAI DIGIT FIVE - '\u0e56' # 0xF6 -> THAI DIGIT SIX - '\u0e57' # 0xF7 -> THAI DIGIT SEVEN - '\u0e58' # 0xF8 -> THAI DIGIT EIGHT - '\u0e59' # 0xF9 -> THAI DIGIT NINE - '\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU - '\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT - '\ufffe' - '\ufffe' - '\ufffe' - '\ufffe' -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) diff --git a/python/Lib/encodings/undefined.py b/python/Lib/encodings/undefined.py deleted file mode 100644 index a077fd6..0000000 --- a/python/Lib/encodings/undefined.py +++ /dev/null @@ -1,49 +0,0 @@ -""" Python 'undefined' Codec - - This codec will always raise a ValueError exception when being - used. It is intended for use by the site.py file to switch off - automatic string to Unicode coercion. - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -""" -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - raise UnicodeError("undefined encoding") - - def decode(self,input,errors='strict'): - raise UnicodeError("undefined encoding") - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - raise UnicodeError("undefined encoding") - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - raise UnicodeError("undefined encoding") - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='undefined', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) diff --git a/python/Lib/encodings/unicode_escape.py b/python/Lib/encodings/unicode_escape.py deleted file mode 100644 index a22aca1..0000000 --- a/python/Lib/encodings/unicode_escape.py +++ /dev/null @@ -1,46 +0,0 @@ -""" Python 'unicode-escape' Codec - - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -""" -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - # Note: Binding these as C functions will result in the class not - # converting them to methods. This is intended. - encode = codecs.unicode_escape_encode - decode = codecs.unicode_escape_decode - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.unicode_escape_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - def _buffer_decode(self, input, errors, final): - return codecs.unicode_escape_decode(input, errors, final) - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - def decode(self, input, errors='strict'): - return codecs.unicode_escape_decode(input, errors, False) - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='unicode-escape', - encode=Codec.encode, - decode=Codec.decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) diff --git a/python/Lib/encodings/utf_16.py b/python/Lib/encodings/utf_16.py deleted file mode 100644 index c1680de..0000000 --- a/python/Lib/encodings/utf_16.py +++ /dev/null @@ -1,155 +0,0 @@ -""" Python 'utf-16' Codec - - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -""" -import codecs, sys - -### Codec APIs - -encode = codecs.utf_16_encode - -def decode(input, errors='strict'): - return codecs.utf_16_decode(input, errors, True) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def __init__(self, errors='strict'): - codecs.IncrementalEncoder.__init__(self, errors) - self.encoder = None - - def encode(self, input, final=False): - if self.encoder is None: - result = codecs.utf_16_encode(input, self.errors)[0] - if sys.byteorder == 'little': - self.encoder = codecs.utf_16_le_encode - else: - self.encoder = codecs.utf_16_be_encode - return result - return self.encoder(input, self.errors)[0] - - def reset(self): - codecs.IncrementalEncoder.reset(self) - self.encoder = None - - def getstate(self): - # state info we return to the caller: - # 0: stream is in natural order for this platform - # 2: endianness hasn't been determined yet - # (we're never writing in unnatural order) - return (2 if self.encoder is None else 0) - - def setstate(self, state): - if state: - self.encoder = None - else: - if sys.byteorder == 'little': - self.encoder = codecs.utf_16_le_encode - else: - self.encoder = codecs.utf_16_be_encode - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - def __init__(self, errors='strict'): - codecs.BufferedIncrementalDecoder.__init__(self, errors) - self.decoder = None - - def _buffer_decode(self, input, errors, final): - if self.decoder is None: - (output, consumed, byteorder) = \ - codecs.utf_16_ex_decode(input, errors, 0, final) - if byteorder == -1: - self.decoder = codecs.utf_16_le_decode - elif byteorder == 1: - self.decoder = codecs.utf_16_be_decode - elif consumed >= 2: - raise UnicodeError("UTF-16 stream does not start with BOM") - return (output, consumed) - return self.decoder(input, self.errors, final) - - def reset(self): - codecs.BufferedIncrementalDecoder.reset(self) - self.decoder = None - - def getstate(self): - # additional state info from the base class must be None here, - # as it isn't passed along to the caller - state = codecs.BufferedIncrementalDecoder.getstate(self)[0] - # additional state info we pass to the caller: - # 0: stream is in natural order for this platform - # 1: stream is in unnatural order - # 2: endianness hasn't been determined yet - if self.decoder is None: - return (state, 2) - addstate = int((sys.byteorder == "big") != - (self.decoder is codecs.utf_16_be_decode)) - return (state, addstate) - - def setstate(self, state): - # state[1] will be ignored by BufferedIncrementalDecoder.setstate() - codecs.BufferedIncrementalDecoder.setstate(self, state) - state = state[1] - if state == 0: - self.decoder = (codecs.utf_16_be_decode - if sys.byteorder == "big" - else codecs.utf_16_le_decode) - elif state == 1: - self.decoder = (codecs.utf_16_le_decode - if sys.byteorder == "big" - else codecs.utf_16_be_decode) - else: - self.decoder = None - -class StreamWriter(codecs.StreamWriter): - def __init__(self, stream, errors='strict'): - codecs.StreamWriter.__init__(self, stream, errors) - self.encoder = None - - def reset(self): - codecs.StreamWriter.reset(self) - self.encoder = None - - def encode(self, input, errors='strict'): - if self.encoder is None: - result = codecs.utf_16_encode(input, errors) - if sys.byteorder == 'little': - self.encoder = codecs.utf_16_le_encode - else: - self.encoder = codecs.utf_16_be_encode - return result - else: - return self.encoder(input, errors) - -class StreamReader(codecs.StreamReader): - - def reset(self): - codecs.StreamReader.reset(self) - try: - del self.decode - except AttributeError: - pass - - def decode(self, input, errors='strict'): - (object, consumed, byteorder) = \ - codecs.utf_16_ex_decode(input, errors, 0, False) - if byteorder == -1: - self.decode = codecs.utf_16_le_decode - elif byteorder == 1: - self.decode = codecs.utf_16_be_decode - elif consumed>=2: - raise UnicodeError("UTF-16 stream does not start with BOM") - return (object, consumed) - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='utf-16', - encode=encode, - decode=decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/utf_16_be.py b/python/Lib/encodings/utf_16_be.py deleted file mode 100644 index 780c499..0000000 --- a/python/Lib/encodings/utf_16_be.py +++ /dev/null @@ -1,42 +0,0 @@ -""" Python 'utf-16-be' Codec - - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -""" -import codecs - -### Codec APIs - -encode = codecs.utf_16_be_encode - -def decode(input, errors='strict'): - return codecs.utf_16_be_decode(input, errors, True) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.utf_16_be_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - _buffer_decode = codecs.utf_16_be_decode - -class StreamWriter(codecs.StreamWriter): - encode = codecs.utf_16_be_encode - -class StreamReader(codecs.StreamReader): - decode = codecs.utf_16_be_decode - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='utf-16-be', - encode=encode, - decode=decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/utf_16_le.py b/python/Lib/encodings/utf_16_le.py deleted file mode 100644 index 3964124..0000000 --- a/python/Lib/encodings/utf_16_le.py +++ /dev/null @@ -1,42 +0,0 @@ -""" Python 'utf-16-le' Codec - - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -""" -import codecs - -### Codec APIs - -encode = codecs.utf_16_le_encode - -def decode(input, errors='strict'): - return codecs.utf_16_le_decode(input, errors, True) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.utf_16_le_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - _buffer_decode = codecs.utf_16_le_decode - -class StreamWriter(codecs.StreamWriter): - encode = codecs.utf_16_le_encode - -class StreamReader(codecs.StreamReader): - decode = codecs.utf_16_le_decode - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='utf-16-le', - encode=encode, - decode=decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/utf_32.py b/python/Lib/encodings/utf_32.py deleted file mode 100644 index 4c20b54..0000000 --- a/python/Lib/encodings/utf_32.py +++ /dev/null @@ -1,150 +0,0 @@ -""" -Python 'utf-32' Codec -""" -import codecs, sys - -### Codec APIs - -encode = codecs.utf_32_encode - -def decode(input, errors='strict'): - return codecs.utf_32_decode(input, errors, True) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def __init__(self, errors='strict'): - codecs.IncrementalEncoder.__init__(self, errors) - self.encoder = None - - def encode(self, input, final=False): - if self.encoder is None: - result = codecs.utf_32_encode(input, self.errors)[0] - if sys.byteorder == 'little': - self.encoder = codecs.utf_32_le_encode - else: - self.encoder = codecs.utf_32_be_encode - return result - return self.encoder(input, self.errors)[0] - - def reset(self): - codecs.IncrementalEncoder.reset(self) - self.encoder = None - - def getstate(self): - # state info we return to the caller: - # 0: stream is in natural order for this platform - # 2: endianness hasn't been determined yet - # (we're never writing in unnatural order) - return (2 if self.encoder is None else 0) - - def setstate(self, state): - if state: - self.encoder = None - else: - if sys.byteorder == 'little': - self.encoder = codecs.utf_32_le_encode - else: - self.encoder = codecs.utf_32_be_encode - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - def __init__(self, errors='strict'): - codecs.BufferedIncrementalDecoder.__init__(self, errors) - self.decoder = None - - def _buffer_decode(self, input, errors, final): - if self.decoder is None: - (output, consumed, byteorder) = \ - codecs.utf_32_ex_decode(input, errors, 0, final) - if byteorder == -1: - self.decoder = codecs.utf_32_le_decode - elif byteorder == 1: - self.decoder = codecs.utf_32_be_decode - elif consumed >= 4: - raise UnicodeError("UTF-32 stream does not start with BOM") - return (output, consumed) - return self.decoder(input, self.errors, final) - - def reset(self): - codecs.BufferedIncrementalDecoder.reset(self) - self.decoder = None - - def getstate(self): - # additional state info from the base class must be None here, - # as it isn't passed along to the caller - state = codecs.BufferedIncrementalDecoder.getstate(self)[0] - # additional state info we pass to the caller: - # 0: stream is in natural order for this platform - # 1: stream is in unnatural order - # 2: endianness hasn't been determined yet - if self.decoder is None: - return (state, 2) - addstate = int((sys.byteorder == "big") != - (self.decoder is codecs.utf_32_be_decode)) - return (state, addstate) - - def setstate(self, state): - # state[1] will be ignored by BufferedIncrementalDecoder.setstate() - codecs.BufferedIncrementalDecoder.setstate(self, state) - state = state[1] - if state == 0: - self.decoder = (codecs.utf_32_be_decode - if sys.byteorder == "big" - else codecs.utf_32_le_decode) - elif state == 1: - self.decoder = (codecs.utf_32_le_decode - if sys.byteorder == "big" - else codecs.utf_32_be_decode) - else: - self.decoder = None - -class StreamWriter(codecs.StreamWriter): - def __init__(self, stream, errors='strict'): - self.encoder = None - codecs.StreamWriter.__init__(self, stream, errors) - - def reset(self): - codecs.StreamWriter.reset(self) - self.encoder = None - - def encode(self, input, errors='strict'): - if self.encoder is None: - result = codecs.utf_32_encode(input, errors) - if sys.byteorder == 'little': - self.encoder = codecs.utf_32_le_encode - else: - self.encoder = codecs.utf_32_be_encode - return result - else: - return self.encoder(input, errors) - -class StreamReader(codecs.StreamReader): - - def reset(self): - codecs.StreamReader.reset(self) - try: - del self.decode - except AttributeError: - pass - - def decode(self, input, errors='strict'): - (object, consumed, byteorder) = \ - codecs.utf_32_ex_decode(input, errors, 0, False) - if byteorder == -1: - self.decode = codecs.utf_32_le_decode - elif byteorder == 1: - self.decode = codecs.utf_32_be_decode - elif consumed>=4: - raise UnicodeError("UTF-32 stream does not start with BOM") - return (object, consumed) - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='utf-32', - encode=encode, - decode=decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/utf_32_be.py b/python/Lib/encodings/utf_32_be.py deleted file mode 100644 index f7c4b87..0000000 --- a/python/Lib/encodings/utf_32_be.py +++ /dev/null @@ -1,37 +0,0 @@ -""" -Python 'utf-32-be' Codec -""" -import codecs - -### Codec APIs - -encode = codecs.utf_32_be_encode - -def decode(input, errors='strict'): - return codecs.utf_32_be_decode(input, errors, True) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.utf_32_be_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - _buffer_decode = codecs.utf_32_be_decode - -class StreamWriter(codecs.StreamWriter): - encode = codecs.utf_32_be_encode - -class StreamReader(codecs.StreamReader): - decode = codecs.utf_32_be_decode - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='utf-32-be', - encode=encode, - decode=decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/utf_32_le.py b/python/Lib/encodings/utf_32_le.py deleted file mode 100644 index 4346a12..0000000 --- a/python/Lib/encodings/utf_32_le.py +++ /dev/null @@ -1,37 +0,0 @@ -""" -Python 'utf-32-le' Codec -""" -import codecs - -### Codec APIs - -encode = codecs.utf_32_le_encode - -def decode(input, errors='strict'): - return codecs.utf_32_le_decode(input, errors, True) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.utf_32_le_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - _buffer_decode = codecs.utf_32_le_decode - -class StreamWriter(codecs.StreamWriter): - encode = codecs.utf_32_le_encode - -class StreamReader(codecs.StreamReader): - decode = codecs.utf_32_le_decode - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='utf-32-le', - encode=encode, - decode=decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/utf_7.py b/python/Lib/encodings/utf_7.py deleted file mode 100644 index 6c30538..0000000 --- a/python/Lib/encodings/utf_7.py +++ /dev/null @@ -1,38 +0,0 @@ -""" Python 'utf-7' Codec - -Written by Brian Quinlan (brian@sweetapp.com). -""" -import codecs - -### Codec APIs - -encode = codecs.utf_7_encode - -def decode(input, errors='strict'): - return codecs.utf_7_decode(input, errors, True) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.utf_7_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - _buffer_decode = codecs.utf_7_decode - -class StreamWriter(codecs.StreamWriter): - encode = codecs.utf_7_encode - -class StreamReader(codecs.StreamReader): - decode = codecs.utf_7_decode - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='utf-7', - encode=encode, - decode=decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/utf_8.py b/python/Lib/encodings/utf_8.py deleted file mode 100644 index cc118ac..0000000 --- a/python/Lib/encodings/utf_8.py +++ /dev/null @@ -1,42 +0,0 @@ -""" Python 'utf-8' Codec - - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. - -""" -import codecs - -### Codec APIs - -encode = codecs.utf_8_encode - -def decode(input, errors='strict'): - return codecs.utf_8_decode(input, errors, True) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.utf_8_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - _buffer_decode = codecs.utf_8_decode - -class StreamWriter(codecs.StreamWriter): - encode = codecs.utf_8_encode - -class StreamReader(codecs.StreamReader): - decode = codecs.utf_8_decode - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='utf-8', - encode=encode, - decode=decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/utf_8_sig.py b/python/Lib/encodings/utf_8_sig.py deleted file mode 100644 index 1a7742b..0000000 --- a/python/Lib/encodings/utf_8_sig.py +++ /dev/null @@ -1,130 +0,0 @@ -""" Python 'utf-8-sig' Codec -This work similar to UTF-8 with the following changes: - -* On encoding/writing a UTF-8 encoded BOM will be prepended/written as the - first three bytes. - -* On decoding/reading if the first three bytes are a UTF-8 encoded BOM, these - bytes will be skipped. -""" -import codecs - -### Codec APIs - -def encode(input, errors='strict'): - return (codecs.BOM_UTF8 + codecs.utf_8_encode(input, errors)[0], - len(input)) - -def decode(input, errors='strict'): - prefix = 0 - if input[:3] == codecs.BOM_UTF8: - input = input[3:] - prefix = 3 - (output, consumed) = codecs.utf_8_decode(input, errors, True) - return (output, consumed+prefix) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def __init__(self, errors='strict'): - codecs.IncrementalEncoder.__init__(self, errors) - self.first = 1 - - def encode(self, input, final=False): - if self.first: - self.first = 0 - return codecs.BOM_UTF8 + \ - codecs.utf_8_encode(input, self.errors)[0] - else: - return codecs.utf_8_encode(input, self.errors)[0] - - def reset(self): - codecs.IncrementalEncoder.reset(self) - self.first = 1 - - def getstate(self): - return self.first - - def setstate(self, state): - self.first = state - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - def __init__(self, errors='strict'): - codecs.BufferedIncrementalDecoder.__init__(self, errors) - self.first = 1 - - def _buffer_decode(self, input, errors, final): - if self.first: - if len(input) < 3: - if codecs.BOM_UTF8.startswith(input): - # not enough data to decide if this really is a BOM - # => try again on the next call - return ("", 0) - else: - self.first = 0 - else: - self.first = 0 - if input[:3] == codecs.BOM_UTF8: - (output, consumed) = \ - codecs.utf_8_decode(input[3:], errors, final) - return (output, consumed+3) - return codecs.utf_8_decode(input, errors, final) - - def reset(self): - codecs.BufferedIncrementalDecoder.reset(self) - self.first = 1 - - def getstate(self): - state = codecs.BufferedIncrementalDecoder.getstate(self) - # state[1] must be 0 here, as it isn't passed along to the caller - return (state[0], self.first) - - def setstate(self, state): - # state[1] will be ignored by BufferedIncrementalDecoder.setstate() - codecs.BufferedIncrementalDecoder.setstate(self, state) - self.first = state[1] - -class StreamWriter(codecs.StreamWriter): - def reset(self): - codecs.StreamWriter.reset(self) - try: - del self.encode - except AttributeError: - pass - - def encode(self, input, errors='strict'): - self.encode = codecs.utf_8_encode - return encode(input, errors) - -class StreamReader(codecs.StreamReader): - def reset(self): - codecs.StreamReader.reset(self) - try: - del self.decode - except AttributeError: - pass - - def decode(self, input, errors='strict'): - if len(input) < 3: - if codecs.BOM_UTF8.startswith(input): - # not enough data to decide if this is a BOM - # => try again on the next call - return ("", 0) - elif input[:3] == codecs.BOM_UTF8: - self.decode = codecs.utf_8_decode - (output, consumed) = codecs.utf_8_decode(input[3:],errors) - return (output, consumed+3) - # (else) no BOM present - self.decode = codecs.utf_8_decode - return codecs.utf_8_decode(input, errors) - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='utf-8-sig', - encode=encode, - decode=decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) diff --git a/python/Lib/encodings/uu_codec.py b/python/Lib/encodings/uu_codec.py deleted file mode 100644 index cb585a3..0000000 --- a/python/Lib/encodings/uu_codec.py +++ /dev/null @@ -1,103 +0,0 @@ -"""Python 'uu_codec' Codec - UU content transfer encoding. - -This codec de/encodes from bytes to bytes. - -Written by Marc-Andre Lemburg (mal@lemburg.com). Some details were -adapted from uu.py which was written by Lance Ellinghouse and -modified by Jack Jansen and Fredrik Lundh. -""" - -import codecs -import binascii -from io import BytesIO - -### Codec APIs - -def uu_encode(input, errors='strict', filename='', mode=0o666): - assert errors == 'strict' - infile = BytesIO(input) - outfile = BytesIO() - read = infile.read - write = outfile.write - - # Remove newline chars from filename - filename = filename.replace('\n','\\n') - filename = filename.replace('\r','\\r') - - # Encode - write(('begin %o %s\n' % (mode & 0o777, filename)).encode('ascii')) - chunk = read(45) - while chunk: - write(binascii.b2a_uu(chunk)) - chunk = read(45) - write(b' \nend\n') - - return (outfile.getvalue(), len(input)) - -def uu_decode(input, errors='strict'): - assert errors == 'strict' - infile = BytesIO(input) - outfile = BytesIO() - readline = infile.readline - write = outfile.write - - # Find start of encoded data - while 1: - s = readline() - if not s: - raise ValueError('Missing "begin" line in input data') - if s[:5] == b'begin': - break - - # Decode - while True: - s = readline() - if not s or s == b'end\n': - break - try: - data = binascii.a2b_uu(s) - except binascii.Error as v: - # Workaround for broken uuencoders by /Fredrik Lundh - nbytes = (((s[0]-32) & 63) * 4 + 5) // 3 - data = binascii.a2b_uu(s[:nbytes]) - #sys.stderr.write("Warning: %s\n" % str(v)) - write(data) - if not s: - raise ValueError('Truncated input data') - - return (outfile.getvalue(), len(input)) - -class Codec(codecs.Codec): - def encode(self, input, errors='strict'): - return uu_encode(input, errors) - - def decode(self, input, errors='strict'): - return uu_decode(input, errors) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return uu_encode(input, self.errors)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return uu_decode(input, self.errors)[0] - -class StreamWriter(Codec, codecs.StreamWriter): - charbuffertype = bytes - -class StreamReader(Codec, codecs.StreamReader): - charbuffertype = bytes - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='uu', - encode=uu_encode, - decode=uu_decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - _is_text_encoding=False, - ) diff --git a/python/Lib/encodings/zlib_codec.py b/python/Lib/encodings/zlib_codec.py deleted file mode 100644 index 011f76d..0000000 --- a/python/Lib/encodings/zlib_codec.py +++ /dev/null @@ -1,77 +0,0 @@ -"""Python 'zlib_codec' Codec - zlib compression encoding. - -This codec de/encodes from bytes to bytes. - -Written by Marc-Andre Lemburg (mal@lemburg.com). -""" - -import codecs -import zlib # this codec needs the optional zlib module ! - -### Codec APIs - -def zlib_encode(input, errors='strict'): - assert errors == 'strict' - return (zlib.compress(input), len(input)) - -def zlib_decode(input, errors='strict'): - assert errors == 'strict' - return (zlib.decompress(input), len(input)) - -class Codec(codecs.Codec): - def encode(self, input, errors='strict'): - return zlib_encode(input, errors) - def decode(self, input, errors='strict'): - return zlib_decode(input, errors) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def __init__(self, errors='strict'): - assert errors == 'strict' - self.errors = errors - self.compressobj = zlib.compressobj() - - def encode(self, input, final=False): - if final: - c = self.compressobj.compress(input) - return c + self.compressobj.flush() - else: - return self.compressobj.compress(input) - - def reset(self): - self.compressobj = zlib.compressobj() - -class IncrementalDecoder(codecs.IncrementalDecoder): - def __init__(self, errors='strict'): - assert errors == 'strict' - self.errors = errors - self.decompressobj = zlib.decompressobj() - - def decode(self, input, final=False): - if final: - c = self.decompressobj.decompress(input) - return c + self.decompressobj.flush() - else: - return self.decompressobj.decompress(input) - - def reset(self): - self.decompressobj = zlib.decompressobj() - -class StreamWriter(Codec, codecs.StreamWriter): - charbuffertype = bytes - -class StreamReader(Codec, codecs.StreamReader): - charbuffertype = bytes - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='zlib', - encode=zlib_encode, - decode=zlib_decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - _is_text_encoding=False, - ) diff --git a/python/Lib/enum.py b/python/Lib/enum.py deleted file mode 100644 index 0e2f63c..0000000 --- a/python/Lib/enum.py +++ /dev/null @@ -1,2039 +0,0 @@ -import sys -import builtins as bltns -from types import MappingProxyType, DynamicClassAttribute -from operator import or_ as _or_ -from functools import reduce - - -__all__ = [ - 'EnumType', 'EnumMeta', - 'Enum', 'IntEnum', 'StrEnum', 'Flag', 'IntFlag', 'ReprEnum', - 'auto', 'unique', 'property', 'verify', 'member', 'nonmember', - 'FlagBoundary', 'STRICT', 'CONFORM', 'EJECT', 'KEEP', - 'global_flag_repr', 'global_enum_repr', 'global_str', 'global_enum', - 'EnumCheck', 'CONTINUOUS', 'NAMED_FLAGS', 'UNIQUE', - ] - - -# Dummy value for Enum and Flag as there are explicit checks for them -# before they have been created. -# This is also why there are checks in EnumType like `if Enum is not None` -Enum = Flag = EJECT = _stdlib_enums = ReprEnum = None - -class nonmember(object): - """ - Protects item from becoming an Enum member during class creation. - """ - def __init__(self, value): - self.value = value - -class member(object): - """ - Forces item to become an Enum member during class creation. - """ - def __init__(self, value): - self.value = value - -def _is_descriptor(obj): - """ - Returns True if obj is a descriptor, False otherwise. - """ - return ( - hasattr(obj, '__get__') or - hasattr(obj, '__set__') or - hasattr(obj, '__delete__') - ) - -def _is_dunder(name): - """ - Returns True if a __dunder__ name, False otherwise. - """ - return ( - len(name) > 4 and - name[:2] == name[-2:] == '__' and - name[2] != '_' and - name[-3] != '_' - ) - -def _is_sunder(name): - """ - Returns True if a _sunder_ name, False otherwise. - """ - return ( - len(name) > 2 and - name[0] == name[-1] == '_' and - name[1:2] != '_' and - name[-2:-1] != '_' - ) - -def _is_internal_class(cls_name, obj): - # do not use `re` as `re` imports `enum` - if not isinstance(obj, type): - return False - qualname = getattr(obj, '__qualname__', '') - s_pattern = cls_name + '.' + getattr(obj, '__name__', '') - e_pattern = '.' + s_pattern - return qualname == s_pattern or qualname.endswith(e_pattern) - -def _is_private(cls_name, name): - # do not use `re` as `re` imports `enum` - pattern = '_%s__' % (cls_name, ) - pat_len = len(pattern) - if ( - len(name) > pat_len - and name.startswith(pattern) - and name[pat_len:pat_len+1] != ['_'] - and (name[-1] != '_' or name[-2] != '_') - ): - return True - else: - return False - -def _is_single_bit(num): - """ - True if only one bit set in num (should be an int) - """ - if num == 0: - return False - num &= num - 1 - return num == 0 - -def _make_class_unpicklable(obj): - """ - Make the given obj un-picklable. - - obj should be either a dictionary, or an Enum - """ - def _break_on_call_reduce(self, proto): - raise TypeError('%r cannot be pickled' % self) - if isinstance(obj, dict): - obj['__reduce_ex__'] = _break_on_call_reduce - obj['__module__'] = '' - else: - setattr(obj, '__reduce_ex__', _break_on_call_reduce) - setattr(obj, '__module__', '') - -def _iter_bits_lsb(num): - # num must be a positive integer - original = num - if isinstance(num, Enum): - num = num.value - if num < 0: - raise ValueError('%r is not a positive integer' % original) - while num: - b = num & (~num + 1) - yield b - num ^= b - -def show_flag_values(value): - return list(_iter_bits_lsb(value)) - -def bin(num, max_bits=None): - """ - Like built-in bin(), except negative values are represented in - twos-compliment, and the leading bit always indicates sign - (0=positive, 1=negative). - - >>> bin(10) - '0b0 1010' - >>> bin(~10) # ~10 is -11 - '0b1 0101' - """ - - ceiling = 2 ** (num).bit_length() - if num >= 0: - s = bltns.bin(num + ceiling).replace('1', '0', 1) - else: - s = bltns.bin(~num ^ (ceiling - 1) + ceiling) - sign = s[:3] - digits = s[3:] - if max_bits is not None: - if len(digits) < max_bits: - digits = (sign[-1] * max_bits + digits)[-max_bits:] - return "%s %s" % (sign, digits) - -def _dedent(text): - """ - Like textwrap.dedent. Rewritten because we cannot import textwrap. - """ - lines = text.split('\n') - blanks = 0 - for i, ch in enumerate(lines[0]): - if ch != ' ': - break - for j, l in enumerate(lines): - lines[j] = l[i:] - return '\n'.join(lines) - -class _auto_null: - def __repr__(self): - return '_auto_null' -_auto_null = _auto_null() - -class auto: - """ - Instances are replaced with an appropriate value in Enum class suites. - """ - def __init__(self, value=_auto_null): - self.value = value - - def __repr__(self): - return "auto(%r)" % self.value - -class property(DynamicClassAttribute): - """ - This is a descriptor, used to define attributes that act differently - when accessed through an enum member and through an enum class. - Instance access is the same as property(), but access to an attribute - through the enum class will instead look in the class' _member_map_ for - a corresponding enum member. - """ - - def __get__(self, instance, ownerclass=None): - if instance is None: - try: - return ownerclass._member_map_[self.name] - except KeyError: - raise AttributeError( - '%r has no attribute %r' % (ownerclass, self.name) - ) - else: - if self.fget is None: - raise AttributeError( - '%r member has no attribute %r' % (ownerclass, self.name) - ) - else: - return self.fget(instance) - - def __set__(self, instance, value): - if self.fset is None: - raise AttributeError( - " cannot set attribute %r" % (self.clsname, self.name) - ) - else: - return self.fset(instance, value) - - def __delete__(self, instance): - if self.fdel is None: - raise AttributeError( - " cannot delete attribute %r" % (self.clsname, self.name) - ) - else: - return self.fdel(instance) - - def __set_name__(self, ownerclass, name): - self.name = name - self.clsname = ownerclass.__name__ - - -class _proto_member: - """ - intermediate step for enum members between class execution and final creation - """ - - def __init__(self, value): - self.value = value - - def __set_name__(self, enum_class, member_name): - """ - convert each quasi-member into an instance of the new enum class - """ - # first step: remove ourself from enum_class - delattr(enum_class, member_name) - # second step: create member based on enum_class - value = self.value - if not isinstance(value, tuple): - args = (value, ) - else: - args = value - if enum_class._member_type_ is tuple: # special case for tuple enums - args = (args, ) # wrap it one more time - if not enum_class._use_args_: - enum_member = enum_class._new_member_(enum_class) - if not hasattr(enum_member, '_value_'): - try: - enum_member._value_ = enum_class._member_type_(*args) - except Exception as exc: - enum_member._value_ = value - else: - enum_member = enum_class._new_member_(enum_class, *args) - if not hasattr(enum_member, '_value_'): - if enum_class._member_type_ is object: - enum_member._value_ = value - else: - try: - enum_member._value_ = enum_class._member_type_(*args) - except Exception as exc: - raise TypeError( - '_value_ not set in __new__, unable to create it' - ) from None - value = enum_member._value_ - enum_member._name_ = member_name - enum_member.__objclass__ = enum_class - enum_member.__init__(*args) - enum_member._sort_order_ = len(enum_class._member_names_) - # If another member with the same value was already defined, the - # new member becomes an alias to the existing one. - try: - try: - # try to do a fast lookup to avoid the quadratic loop - enum_member = enum_class._value2member_map_[value] - except TypeError: - for name, canonical_member in enum_class._member_map_.items(): - if canonical_member._value_ == value: - enum_member = canonical_member - break - else: - raise KeyError - except KeyError: - # this could still be an alias if the value is multi-bit and the - # class is a flag class - if ( - Flag is None - or not issubclass(enum_class, Flag) - ): - # no other instances found, record this member in _member_names_ - enum_class._member_names_.append(member_name) - elif ( - Flag is not None - and issubclass(enum_class, Flag) - and _is_single_bit(value) - ): - # no other instances found, record this member in _member_names_ - enum_class._member_names_.append(member_name) - # get redirect in place before adding to _member_map_ - # but check for other instances in parent classes first - need_override = False - descriptor = None - for base in enum_class.__mro__[1:]: - descriptor = base.__dict__.get(member_name) - if descriptor is not None: - if isinstance(descriptor, (property, DynamicClassAttribute)): - break - else: - need_override = True - # keep looking for an enum.property - if descriptor and not need_override: - # previous enum.property found, no further action needed - pass - elif descriptor and need_override: - redirect = property() - redirect.__set_name__(enum_class, member_name) - # Previous enum.property found, but some other inherited attribute - # is in the way; copy fget, fset, fdel to this one. - redirect.fget = descriptor.fget - redirect.fset = descriptor.fset - redirect.fdel = descriptor.fdel - setattr(enum_class, member_name, redirect) - else: - setattr(enum_class, member_name, enum_member) - # now add to _member_map_ (even aliases) - enum_class._member_map_[member_name] = enum_member - try: - # This may fail if value is not hashable. We can't add the value - # to the map, and by-value lookups for this value will be - # linear. - enum_class._value2member_map_.setdefault(value, enum_member) - except TypeError: - # keep track of the value in a list so containment checks are quick - enum_class._unhashable_values_.append(value) - - -class _EnumDict(dict): - """ - Track enum member order and ensure member names are not reused. - - EnumType will use the names found in self._member_names as the - enumeration member names. - """ - def __init__(self): - super().__init__() - self._member_names = {} # use a dict to keep insertion order - self._last_values = [] - self._ignore = [] - self._auto_called = False - - def __setitem__(self, key, value): - """ - Changes anything not dundered or not a descriptor. - - If an enum member name is used twice, an error is raised; duplicate - values are not checked for. - - Single underscore (sunder) names are reserved. - """ - if _is_internal_class(self._cls_name, value): - import warnings - warnings.warn( - "In 3.13 classes created inside an enum will not become a member. " - "Use the `member` decorator to keep the current behavior.", - DeprecationWarning, - stacklevel=2, - ) - if _is_private(self._cls_name, key): - # also do nothing, name will be a normal attribute - pass - elif _is_sunder(key): - if key not in ( - '_order_', - '_generate_next_value_', '_numeric_repr_', '_missing_', '_ignore_', - '_iter_member_', '_iter_member_by_value_', '_iter_member_by_def_', - ): - raise ValueError( - '_sunder_ names, such as %r, are reserved for future Enum use' - % (key, ) - ) - if key == '_generate_next_value_': - # check if members already defined as auto() - if self._auto_called: - raise TypeError("_generate_next_value_ must be defined before members") - _gnv = value.__func__ if isinstance(value, staticmethod) else value - setattr(self, '_generate_next_value', _gnv) - elif key == '_ignore_': - if isinstance(value, str): - value = value.replace(',',' ').split() - else: - value = list(value) - self._ignore = value - already = set(value) & set(self._member_names) - if already: - raise ValueError( - '_ignore_ cannot specify already set names: %r' - % (already, ) - ) - elif _is_dunder(key): - if key == '__order__': - key = '_order_' - elif key in self._member_names: - # descriptor overwriting an enum? - raise TypeError('%r already defined as %r' % (key, self[key])) - elif key in self._ignore: - pass - elif isinstance(value, nonmember): - # unwrap value here; it won't be processed by the below `else` - value = value.value - elif _is_descriptor(value): - pass - # TODO: uncomment next three lines in 3.13 - # elif _is_internal_class(self._cls_name, value): - # # do nothing, name will be a normal attribute - # pass - else: - if key in self: - # enum overwriting a descriptor? - raise TypeError('%r already defined as %r' % (key, self[key])) - elif isinstance(value, member): - # unwrap value here -- it will become a member - value = value.value - non_auto_store = True - single = False - if isinstance(value, auto): - single = True - value = (value, ) - if isinstance(value, tuple): - auto_valued = [] - for v in value: - if isinstance(v, auto): - non_auto_store = False - if v.value == _auto_null: - v.value = self._generate_next_value( - key, 1, len(self._member_names), self._last_values[:], - ) - self._auto_called = True - v = v.value - self._last_values.append(v) - auto_valued.append(v) - if single: - value = auto_valued[0] - else: - value = tuple(auto_valued) - self._member_names[key] = None - if non_auto_store: - self._last_values.append(value) - super().__setitem__(key, value) - - def update(self, members, **more_members): - try: - for name in members.keys(): - self[name] = members[name] - except AttributeError: - for name, value in members: - self[name] = value - for name, value in more_members.items(): - self[name] = value - - -class EnumType(type): - """ - Metaclass for Enum - """ - - @classmethod - def __prepare__(metacls, cls, bases, **kwds): - # check that previous enum members do not exist - metacls._check_for_existing_members_(cls, bases) - # create the namespace dict - enum_dict = _EnumDict() - enum_dict._cls_name = cls - # inherit previous flags and _generate_next_value_ function - member_type, first_enum = metacls._get_mixins_(cls, bases) - if first_enum is not None: - enum_dict['_generate_next_value_'] = getattr( - first_enum, '_generate_next_value_', None, - ) - return enum_dict - - def __new__(metacls, cls, bases, classdict, *, boundary=None, _simple=False, **kwds): - # an Enum class is final once enumeration items have been defined; it - # cannot be mixed with other types (int, float, etc.) if it has an - # inherited __new__ unless a new __new__ is defined (or the resulting - # class will fail). - # - if _simple: - return super().__new__(metacls, cls, bases, classdict, **kwds) - # - # remove any keys listed in _ignore_ - classdict.setdefault('_ignore_', []).append('_ignore_') - ignore = classdict['_ignore_'] - for key in ignore: - classdict.pop(key, None) - # - # grab member names - member_names = classdict._member_names - # - # check for illegal enum names (any others?) - invalid_names = set(member_names) & {'mro', ''} - if invalid_names: - raise ValueError('invalid enum member name(s) %s' % ( - ','.join(repr(n) for n in invalid_names) - )) - # - # adjust the sunders - _order_ = classdict.pop('_order_', None) - # convert to normal dict - classdict = dict(classdict.items()) - # - # data type of member and the controlling Enum class - member_type, first_enum = metacls._get_mixins_(cls, bases) - __new__, save_new, use_args = metacls._find_new_( - classdict, member_type, first_enum, - ) - classdict['_new_member_'] = __new__ - classdict['_use_args_'] = use_args - # - # convert future enum members into temporary _proto_members - # and record integer values in case this will be a Flag - flag_mask = 0 - for name in member_names: - value = classdict[name] - if isinstance(value, int): - flag_mask |= value - classdict[name] = _proto_member(value) - # - # house-keeping structures - classdict['_member_names_'] = [] - classdict['_member_map_'] = {} - classdict['_value2member_map_'] = {} - classdict['_unhashable_values_'] = [] - classdict['_member_type_'] = member_type - # now set the __repr__ for the value - classdict['_value_repr_'] = metacls._find_data_repr_(cls, bases) - # - # Flag structures (will be removed if final class is not a Flag - classdict['_boundary_'] = ( - boundary - or getattr(first_enum, '_boundary_', None) - ) - classdict['_flag_mask_'] = flag_mask - classdict['_all_bits_'] = 2 ** ((flag_mask).bit_length()) - 1 - classdict['_inverted_'] = None - try: - exc = None - enum_class = super().__new__(metacls, cls, bases, classdict, **kwds) - except RuntimeError as e: - # any exceptions raised by member.__new__ will get converted to a - # RuntimeError, so get that original exception back and raise it instead - exc = e.__cause__ or e - if exc is not None: - raise exc - # - # update classdict with any changes made by __init_subclass__ - classdict.update(enum_class.__dict__) - # - # double check that repr and friends are not the mixin's or various - # things break (such as pickle) - # however, if the method is defined in the Enum itself, don't replace - # it - # - # Also, special handling for ReprEnum - if ReprEnum is not None and ReprEnum in bases: - if member_type is object: - raise TypeError( - 'ReprEnum subclasses must be mixed with a data type (i.e.' - ' int, str, float, etc.)' - ) - if '__format__' not in classdict: - enum_class.__format__ = member_type.__format__ - classdict['__format__'] = enum_class.__format__ - if '__str__' not in classdict: - method = member_type.__str__ - if method is object.__str__: - # if member_type does not define __str__, object.__str__ will use - # its __repr__ instead, so we'll also use its __repr__ - method = member_type.__repr__ - enum_class.__str__ = method - classdict['__str__'] = enum_class.__str__ - for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'): - if name not in classdict: - # check for mixin overrides before replacing - enum_method = getattr(first_enum, name) - found_method = getattr(enum_class, name) - object_method = getattr(object, name) - data_type_method = getattr(member_type, name) - if found_method in (data_type_method, object_method): - setattr(enum_class, name, enum_method) - # - # for Flag, add __or__, __and__, __xor__, and __invert__ - if Flag is not None and issubclass(enum_class, Flag): - for name in ( - '__or__', '__and__', '__xor__', - '__ror__', '__rand__', '__rxor__', - '__invert__' - ): - if name not in classdict: - enum_method = getattr(Flag, name) - setattr(enum_class, name, enum_method) - classdict[name] = enum_method - # - # replace any other __new__ with our own (as long as Enum is not None, - # anyway) -- again, this is to support pickle - if Enum is not None: - # if the user defined their own __new__, save it before it gets - # clobbered in case they subclass later - if save_new: - enum_class.__new_member__ = __new__ - enum_class.__new__ = Enum.__new__ - # - # py3 support for definition order (helps keep py2/py3 code in sync) - # - # _order_ checking is spread out into three/four steps - # - if enum_class is a Flag: - # - remove any non-single-bit flags from _order_ - # - remove any aliases from _order_ - # - check that _order_ and _member_names_ match - # - # step 1: ensure we have a list - if _order_ is not None: - if isinstance(_order_, str): - _order_ = _order_.replace(',', ' ').split() - # - # remove Flag structures if final class is not a Flag - if ( - Flag is None and cls != 'Flag' - or Flag is not None and not issubclass(enum_class, Flag) - ): - delattr(enum_class, '_boundary_') - delattr(enum_class, '_flag_mask_') - delattr(enum_class, '_all_bits_') - delattr(enum_class, '_inverted_') - elif Flag is not None and issubclass(enum_class, Flag): - # ensure _all_bits_ is correct and there are no missing flags - single_bit_total = 0 - multi_bit_total = 0 - for flag in enum_class._member_map_.values(): - flag_value = flag._value_ - if _is_single_bit(flag_value): - single_bit_total |= flag_value - else: - # multi-bit flags are considered aliases - multi_bit_total |= flag_value - enum_class._flag_mask_ = single_bit_total - # - # set correct __iter__ - member_list = [m._value_ for m in enum_class] - if member_list != sorted(member_list): - enum_class._iter_member_ = enum_class._iter_member_by_def_ - if _order_: - # _order_ step 2: remove any items from _order_ that are not single-bit - _order_ = [ - o - for o in _order_ - if o not in enum_class._member_map_ or _is_single_bit(enum_class[o]._value_) - ] - # - if _order_: - # _order_ step 3: remove aliases from _order_ - _order_ = [ - o - for o in _order_ - if ( - o not in enum_class._member_map_ - or - (o in enum_class._member_map_ and o in enum_class._member_names_) - )] - # _order_ step 4: verify that _order_ and _member_names_ match - if _order_ != enum_class._member_names_: - raise TypeError( - 'member order does not match _order_:\n %r\n %r' - % (enum_class._member_names_, _order_) - ) - - return enum_class - - def __bool__(cls): - """ - classes/types should always be True. - """ - return True - - def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None): - """ - Either returns an existing member, or creates a new enum class. - - This method is used both when an enum class is given a value to match - to an enumeration member (i.e. Color(3)) and for the functional API - (i.e. Color = Enum('Color', names='RED GREEN BLUE')). - - When used for the functional API: - - `value` will be the name of the new class. - - `names` should be either a string of white-space/comma delimited names - (values will start at `start`), or an iterator/mapping of name, value pairs. - - `module` should be set to the module this class is being created in; - if it is not set, an attempt to find that module will be made, but if - it fails the class will not be picklable. - - `qualname` should be set to the actual location this class can be found - at in its module; by default it is set to the global scope. If this is - not correct, unpickling will fail in some circumstances. - - `type`, if set, will be mixed in as the first base class. - """ - if names is None: # simple value lookup - return cls.__new__(cls, value) - # otherwise, functional API: we're creating a new Enum type - return cls._create_( - value, - names, - module=module, - qualname=qualname, - type=type, - start=start, - boundary=boundary, - ) - - def __contains__(cls, member): - """ - Return True if member is a member of this enum - raises TypeError if member is not an enum member - - note: in 3.12 TypeError will no longer be raised, and True will also be - returned if member is the value of a member in this enum - """ - if not isinstance(member, Enum): - import warnings - warnings.warn( - "in 3.12 __contains__ will no longer raise TypeError, but will return True or\n" - "False depending on whether the value is a member or the value of a member", - DeprecationWarning, - stacklevel=2, - ) - raise TypeError( - "unsupported operand type(s) for 'in': '%s' and '%s'" % ( - type(member).__qualname__, cls.__class__.__qualname__)) - return isinstance(member, cls) and member._name_ in cls._member_map_ - - def __delattr__(cls, attr): - # nicer error message when someone tries to delete an attribute - # (see issue19025). - if attr in cls._member_map_: - raise AttributeError("%r cannot delete member %r." % (cls.__name__, attr)) - super().__delattr__(attr) - - def __dir__(cls): - interesting = set([ - '__class__', '__contains__', '__doc__', '__getitem__', - '__iter__', '__len__', '__members__', '__module__', - '__name__', '__qualname__', - ] - + cls._member_names_ - ) - if cls._new_member_ is not object.__new__: - interesting.add('__new__') - if cls.__init_subclass__ is not object.__init_subclass__: - interesting.add('__init_subclass__') - if cls._member_type_ is object: - return sorted(interesting) - else: - # return whatever mixed-in data type has - return sorted(set(dir(cls._member_type_)) | interesting) - - def __getattr__(cls, name): - """ - Return the enum member matching `name` - - We use __getattr__ instead of descriptors or inserting into the enum - class' __dict__ in order to support `name` and `value` being both - properties for enum members (which live in the class' __dict__) and - enum members themselves. - """ - if _is_dunder(name): - raise AttributeError(name) - try: - return cls._member_map_[name] - except KeyError: - raise AttributeError(name) from None - - def __getitem__(cls, name): - """ - Return the member matching `name`. - """ - return cls._member_map_[name] - - def __iter__(cls): - """ - Return members in definition order. - """ - return (cls._member_map_[name] for name in cls._member_names_) - - def __len__(cls): - """ - Return the number of members (no aliases) - """ - return len(cls._member_names_) - - @bltns.property - def __members__(cls): - """ - Returns a mapping of member name->value. - - This mapping lists all enum members, including aliases. Note that this - is a read-only view of the internal mapping. - """ - return MappingProxyType(cls._member_map_) - - def __repr__(cls): - if Flag is not None and issubclass(cls, Flag): - return "" % cls.__name__ - else: - return "" % cls.__name__ - - def __reversed__(cls): - """ - Return members in reverse definition order. - """ - return (cls._member_map_[name] for name in reversed(cls._member_names_)) - - def __setattr__(cls, name, value): - """ - Block attempts to reassign Enum members. - - A simple assignment to the class namespace only changes one of the - several possible ways to get an Enum member from the Enum class, - resulting in an inconsistent Enumeration. - """ - member_map = cls.__dict__.get('_member_map_', {}) - if name in member_map: - raise AttributeError('cannot reassign member %r' % (name, )) - super().__setattr__(name, value) - - def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, start=1, boundary=None): - """ - Convenience method to create a new Enum class. - - `names` can be: - - * A string containing member names, separated either with spaces or - commas. Values are incremented by 1 from `start`. - * An iterable of member names. Values are incremented by 1 from `start`. - * An iterable of (member name, value) pairs. - * A mapping of member name -> value pairs. - """ - metacls = cls.__class__ - bases = (cls, ) if type is None else (type, cls) - _, first_enum = cls._get_mixins_(class_name, bases) - classdict = metacls.__prepare__(class_name, bases) - - # special processing needed for names? - if isinstance(names, str): - names = names.replace(',', ' ').split() - if isinstance(names, (tuple, list)) and names and isinstance(names[0], str): - original_names, names = names, [] - last_values = [] - for count, name in enumerate(original_names): - value = first_enum._generate_next_value_(name, start, count, last_values[:]) - last_values.append(value) - names.append((name, value)) - - # Here, names is either an iterable of (name, value) or a mapping. - for item in names: - if isinstance(item, str): - member_name, member_value = item, names[item] - else: - member_name, member_value = item - classdict[member_name] = member_value - - # TODO: replace the frame hack if a blessed way to know the calling - # module is ever developed - if module is None: - try: - module = sys._getframe(2).f_globals['__name__'] - except (AttributeError, ValueError, KeyError): - pass - if module is None: - _make_class_unpicklable(classdict) - else: - classdict['__module__'] = module - if qualname is not None: - classdict['__qualname__'] = qualname - - return metacls.__new__(metacls, class_name, bases, classdict, boundary=boundary) - - def _convert_(cls, name, module, filter, source=None, *, boundary=None, as_global=False): - """ - Create a new Enum subclass that replaces a collection of global constants - """ - # convert all constants from source (or module) that pass filter() to - # a new Enum called name, and export the enum and its members back to - # module; - # also, replace the __reduce_ex__ method so unpickling works in - # previous Python versions - module_globals = sys.modules[module].__dict__ - if source: - source = source.__dict__ - else: - source = module_globals - # _value2member_map_ is populated in the same order every time - # for a consistent reverse mapping of number to name when there - # are multiple names for the same number. - members = [ - (name, value) - for name, value in source.items() - if filter(name)] - try: - # sort by value - members.sort(key=lambda t: (t[1], t[0])) - except TypeError: - # unless some values aren't comparable, in which case sort by name - members.sort(key=lambda t: t[0]) - body = {t[0]: t[1] for t in members} - body['__module__'] = module - tmp_cls = type(name, (object, ), body) - cls = _simple_enum(etype=cls, boundary=boundary or KEEP)(tmp_cls) - cls.__reduce_ex__ = _reduce_ex_by_global_name - if as_global: - global_enum(cls) - else: - sys.modules[cls.__module__].__dict__.update(cls.__members__) - module_globals[name] = cls - return cls - - @classmethod - def _check_for_existing_members_(mcls, class_name, bases): - for chain in bases: - for base in chain.__mro__: - if issubclass(base, Enum) and base._member_names_: - raise TypeError( - " cannot extend %r" - % (class_name, base) - ) - - @classmethod - def _get_mixins_(mcls, class_name, bases): - """ - Returns the type for creating enum members, and the first inherited - enum class. - - bases: the tuple of bases that was given to __new__ - """ - if not bases: - return object, Enum - - mcls._check_for_existing_members_(class_name, bases) - - # ensure final parent class is an Enum derivative, find any concrete - # data type, and check that Enum has no members - first_enum = bases[-1] - if not issubclass(first_enum, Enum): - raise TypeError("new enumerations should be created as " - "`EnumName([mixin_type, ...] [data_type,] enum_type)`") - member_type = mcls._find_data_type_(class_name, bases) or object - return member_type, first_enum - - @classmethod - def _find_data_repr_(mcls, class_name, bases): - for chain in bases: - for base in chain.__mro__: - if base is object: - continue - elif issubclass(base, Enum): - # if we hit an Enum, use it's _value_repr_ - return base._value_repr_ - elif '__repr__' in base.__dict__: - # this is our data repr - return base.__dict__['__repr__'] - return None - - @classmethod - def _find_data_type_(mcls, class_name, bases): - data_types = set() - base_chain = set() - for chain in bases: - candidate = None - for base in chain.__mro__: - base_chain.add(base) - if base is object: - continue - elif issubclass(base, Enum): - if base._member_type_ is not object: - data_types.add(base._member_type_) - break - elif '__new__' in base.__dict__ or '__init__' in base.__dict__: - if issubclass(base, Enum): - continue - data_types.add(candidate or base) - break - else: - candidate = candidate or base - if len(data_types) > 1: - raise TypeError('too many data types for %r: %r' % (class_name, data_types)) - elif data_types: - return data_types.pop() - else: - return None - - @classmethod - def _find_new_(mcls, classdict, member_type, first_enum): - """ - Returns the __new__ to be used for creating the enum members. - - classdict: the class dictionary given to __new__ - member_type: the data type whose __new__ will be used by default - first_enum: enumeration to check for an overriding __new__ - """ - # now find the correct __new__, checking to see of one was defined - # by the user; also check earlier enum classes in case a __new__ was - # saved as __new_member__ - __new__ = classdict.get('__new__', None) - - # should __new__ be saved as __new_member__ later? - save_new = first_enum is not None and __new__ is not None - - if __new__ is None: - # check all possibles for __new_member__ before falling back to - # __new__ - for method in ('__new_member__', '__new__'): - for possible in (member_type, first_enum): - target = getattr(possible, method, None) - if target not in { - None, - None.__new__, - object.__new__, - Enum.__new__, - }: - __new__ = target - break - if __new__ is not None: - break - else: - __new__ = object.__new__ - - # if a non-object.__new__ is used then whatever value/tuple was - # assigned to the enum member name will be passed to __new__ and to the - # new enum member's __init__ - if first_enum is None or __new__ in (Enum.__new__, object.__new__): - use_args = False - else: - use_args = True - return __new__, save_new, use_args -EnumMeta = EnumType - - -class Enum(metaclass=EnumType): - """ - Create a collection of name/value pairs. - - Example enumeration: - - >>> class Color(Enum): - ... RED = 1 - ... BLUE = 2 - ... GREEN = 3 - - Access them by: - - - attribute access:: - - >>> Color.RED - - - - value lookup: - - >>> Color(1) - - - - name lookup: - - >>> Color['RED'] - - - Enumerations can be iterated over, and know how many members they have: - - >>> len(Color) - 3 - - >>> list(Color) - [, , ] - - Methods can be added to enumerations, and members can have their own - attributes -- see the documentation for details. - """ - - def __new__(cls, value): - # all enum instances are actually created during class construction - # without calling this method; this method is called by the metaclass' - # __call__ (i.e. Color(3) ), and by pickle - if type(value) is cls: - # For lookups like Color(Color.RED) - return value - # by-value search for a matching enum member - # see if it's in the reverse mapping (for hashable values) - try: - return cls._value2member_map_[value] - except KeyError: - # Not found, no need to do long O(n) search - pass - except TypeError: - # not there, now do long search -- O(n) behavior - for member in cls._member_map_.values(): - if member._value_ == value: - return member - # still not found -- try _missing_ hook - try: - exc = None - result = cls._missing_(value) - except Exception as e: - exc = e - result = None - try: - if isinstance(result, cls): - return result - elif ( - Flag is not None and issubclass(cls, Flag) - and cls._boundary_ is EJECT and isinstance(result, int) - ): - return result - else: - ve_exc = ValueError("%r is not a valid %s" % (value, cls.__qualname__)) - if result is None and exc is None: - raise ve_exc - elif exc is None: - exc = TypeError( - 'error in %s._missing_: returned %r instead of None or a valid member' - % (cls.__name__, result) - ) - if not isinstance(exc, ValueError): - exc.__context__ = ve_exc - raise exc - finally: - # ensure all variables that could hold an exception are destroyed - exc = None - ve_exc = None - - def __init__(self, *args, **kwds): - pass - - def _generate_next_value_(name, start, count, last_values): - """ - Generate the next value when not given. - - name: the name of the member - start: the initial start value or None - count: the number of existing members - last_values: the list of values assigned - """ - if not last_values: - return start - try: - last = last_values[-1] - last_values.sort() - if last == last_values[-1]: - # no difference between old and new methods - return last + 1 - else: - # trigger old method (with warning) - raise TypeError - except TypeError: - import warnings - warnings.warn( - "In 3.13 the default `auto()`/`_generate_next_value_` will require all values to be sortable and support adding +1\n" - "and the value returned will be the largest value in the enum incremented by 1", - DeprecationWarning, - stacklevel=3, - ) - for v in last_values: - try: - return v + 1 - except TypeError: - pass - return start - - @classmethod - def _missing_(cls, value): - return None - - def __repr__(self): - v_repr = self.__class__._value_repr_ or repr - return "<%s.%s: %s>" % (self.__class__.__name__, self._name_, v_repr(self._value_)) - - def __str__(self): - return "%s.%s" % (self.__class__.__name__, self._name_, ) - - def __dir__(self): - """ - Returns all members and all public methods - """ - if self.__class__._member_type_ is object: - interesting = set(['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'value']) - else: - interesting = set(object.__dir__(self)) - for name in getattr(self, '__dict__', []): - if name[0] != '_': - interesting.add(name) - for cls in self.__class__.mro(): - for name, obj in cls.__dict__.items(): - if name[0] == '_': - continue - if isinstance(obj, property): - # that's an enum.property - if obj.fget is not None or name not in self._member_map_: - interesting.add(name) - else: - # in case it was added by `dir(self)` - interesting.discard(name) - else: - interesting.add(name) - names = sorted( - set(['__class__', '__doc__', '__eq__', '__hash__', '__module__']) - | interesting - ) - return names - - def __format__(self, format_spec): - return str.__format__(str(self), format_spec) - - def __hash__(self): - return hash(self._name_) - - def __reduce_ex__(self, proto): - return getattr, (self.__class__, self._name_) - - # enum.property is used to provide access to the `name` and - # `value` attributes of enum members while keeping some measure of - # protection from modification, while still allowing for an enumeration - # to have members named `name` and `value`. This works because enumeration - # members are not set directly on the enum class; they are kept in a - # separate structure, _member_map_, which is where enum.property looks for - # them - - @property - def name(self): - """The name of the Enum member.""" - return self._name_ - - @property - def value(self): - """The value of the Enum member.""" - return self._value_ - - -class ReprEnum(Enum): - """ - Only changes the repr(), leaving str() and format() to the mixed-in type. - """ - - -class IntEnum(int, ReprEnum): - """ - Enum where members are also (and must be) ints - """ - - -class StrEnum(str, ReprEnum): - """ - Enum where members are also (and must be) strings - """ - - def __new__(cls, *values): - "values must already be of type `str`" - if len(values) > 3: - raise TypeError('too many arguments for str(): %r' % (values, )) - if len(values) == 1: - # it must be a string - if not isinstance(values[0], str): - raise TypeError('%r is not a string' % (values[0], )) - if len(values) >= 2: - # check that encoding argument is a string - if not isinstance(values[1], str): - raise TypeError('encoding must be a string, not %r' % (values[1], )) - if len(values) == 3: - # check that errors argument is a string - if not isinstance(values[2], str): - raise TypeError('errors must be a string, not %r' % (values[2])) - value = str(*values) - member = str.__new__(cls, value) - member._value_ = value - return member - - def _generate_next_value_(name, start, count, last_values): - """ - Return the lower-cased version of the member name. - """ - return name.lower() - - -def _reduce_ex_by_global_name(self, proto): - return self.name - -class FlagBoundary(StrEnum): - """ - control how out of range values are handled - "strict" -> error is raised [default for Flag] - "conform" -> extra bits are discarded - "eject" -> lose flag status [default for IntFlag] - "keep" -> keep flag status and all bits - """ - STRICT = auto() - CONFORM = auto() - EJECT = auto() - KEEP = auto() -STRICT, CONFORM, EJECT, KEEP = FlagBoundary - - -class Flag(Enum, boundary=CONFORM): - """ - Support for flags - """ - - def __reduce_ex__(self, proto): - cls = self.__class__ - unknown = self._value_ & ~cls._flag_mask_ - member_value = self._value_ & cls._flag_mask_ - if unknown and member_value: - return _or_, (cls(member_value), unknown) - for val in _iter_bits_lsb(member_value): - rest = member_value & ~val - if rest: - return _or_, (cls(rest), cls._value2member_map_.get(val)) - else: - break - if self._name_ is None: - return cls, (self._value_,) - else: - return getattr, (cls, self._name_) - - _numeric_repr_ = repr - - def _generate_next_value_(name, start, count, last_values): - """ - Generate the next value when not given. - - name: the name of the member - start: the initial start value or None - count: the number of existing members - last_values: the last value assigned or None - """ - if not count: - return start if start is not None else 1 - last_value = max(last_values) - try: - high_bit = _high_bit(last_value) - except Exception: - raise TypeError('invalid flag value %r' % last_value) from None - return 2 ** (high_bit+1) - - @classmethod - def _iter_member_by_value_(cls, value): - """ - Extract all members from the value in definition (i.e. increasing value) order. - """ - for val in _iter_bits_lsb(value & cls._flag_mask_): - yield cls._value2member_map_.get(val) - - _iter_member_ = _iter_member_by_value_ - - @classmethod - def _iter_member_by_def_(cls, value): - """ - Extract all members from the value in definition order. - """ - yield from sorted( - cls._iter_member_by_value_(value), - key=lambda m: m._sort_order_, - ) - - @classmethod - def _missing_(cls, value): - """ - Create a composite member containing all canonical members present in `value`. - - If non-member values are present, result depends on `_boundary_` setting. - """ - if not isinstance(value, int): - raise ValueError( - "%r is not a valid %s" % (value, cls.__qualname__) - ) - # check boundaries - # - value must be in range (e.g. -16 <-> +15, i.e. ~15 <-> 15) - # - value must not include any skipped flags (e.g. if bit 2 is not - # defined, then 0d10 is invalid) - flag_mask = cls._flag_mask_ - all_bits = cls._all_bits_ - neg_value = None - if ( - not ~all_bits <= value <= all_bits - or value & (all_bits ^ flag_mask) - ): - if cls._boundary_ is STRICT: - max_bits = max(value.bit_length(), flag_mask.bit_length()) - raise ValueError( - "%r invalid value %r\n given %s\n allowed %s" % ( - cls, value, bin(value, max_bits), bin(flag_mask, max_bits), - )) - elif cls._boundary_ is CONFORM: - value = value & flag_mask - elif cls._boundary_ is EJECT: - return value - elif cls._boundary_ is KEEP: - if value < 0: - value = ( - max(all_bits+1, 2**(value.bit_length())) - + value - ) - else: - raise ValueError( - '%r unknown flag boundary %r' % (cls, cls._boundary_, ) - ) - if value < 0: - neg_value = value - value = all_bits + 1 + value - # get members and unknown - unknown = value & ~flag_mask - member_value = value & flag_mask - if unknown and cls._boundary_ is not KEEP: - raise ValueError( - '%s(%r) --> unknown values %r [%s]' - % (cls.__name__, value, unknown, bin(unknown)) - ) - # normal Flag? - __new__ = getattr(cls, '__new_member__', None) - if cls._member_type_ is object and not __new__: - # construct a singleton enum pseudo-member - pseudo_member = object.__new__(cls) - else: - pseudo_member = (__new__ or cls._member_type_.__new__)(cls, value) - if not hasattr(pseudo_member, '_value_'): - pseudo_member._value_ = value - if member_value: - pseudo_member._name_ = '|'.join([ - m._name_ for m in cls._iter_member_(member_value) - ]) - if unknown: - pseudo_member._name_ += '|%s' % cls._numeric_repr_(unknown) - else: - pseudo_member._name_ = None - # use setdefault in case another thread already created a composite - # with this value, but only if all members are known - # note: zero is a special case -- add it - if not unknown: - pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member) - if neg_value is not None: - cls._value2member_map_[neg_value] = pseudo_member - return pseudo_member - - def __contains__(self, other): - """ - Returns True if self has at least the same flags set as other. - """ - if not isinstance(other, self.__class__): - raise TypeError( - "unsupported operand type(s) for 'in': %r and %r" % ( - type(other).__qualname__, self.__class__.__qualname__)) - return other._value_ & self._value_ == other._value_ - - def __iter__(self): - """ - Returns flags in definition order. - """ - yield from self._iter_member_(self._value_) - - def __len__(self): - return self._value_.bit_count() - - def __repr__(self): - cls_name = self.__class__.__name__ - v_repr = self.__class__._value_repr_ or repr - if self._name_ is None: - return "<%s: %s>" % (cls_name, v_repr(self._value_)) - else: - return "<%s.%s: %s>" % (cls_name, self._name_, v_repr(self._value_)) - - def __str__(self): - cls_name = self.__class__.__name__ - if self._name_ is None: - return '%s(%r)' % (cls_name, self._value_) - else: - return "%s.%s" % (cls_name, self._name_) - - def __bool__(self): - return bool(self._value_) - - def __or__(self, other): - if isinstance(other, self.__class__): - other = other._value_ - elif self._member_type_ is not object and isinstance(other, self._member_type_): - other = other - else: - return NotImplemented - value = self._value_ - return self.__class__(value | other) - - def __and__(self, other): - if isinstance(other, self.__class__): - other = other._value_ - elif self._member_type_ is not object and isinstance(other, self._member_type_): - other = other - else: - return NotImplemented - value = self._value_ - return self.__class__(value & other) - - def __xor__(self, other): - if isinstance(other, self.__class__): - other = other._value_ - elif self._member_type_ is not object and isinstance(other, self._member_type_): - other = other - else: - return NotImplemented - value = self._value_ - return self.__class__(value ^ other) - - def __invert__(self): - if self._inverted_ is None: - if self._boundary_ is KEEP: - # use all bits - self._inverted_ = self.__class__(~self._value_) - else: - # calculate flags not in this member - self._inverted_ = self.__class__(self._flag_mask_ ^ self._value_) - if isinstance(self._inverted_, self.__class__): - self._inverted_._inverted_ = self - return self._inverted_ - - __rand__ = __and__ - __ror__ = __or__ - __rxor__ = __xor__ - - -class IntFlag(int, ReprEnum, Flag, boundary=KEEP): - """ - Support for integer-based Flags - """ - - -def _high_bit(value): - """ - returns index of highest bit, or -1 if value is zero or negative - """ - return value.bit_length() - 1 - -def unique(enumeration): - """ - Class decorator for enumerations ensuring unique member values. - """ - duplicates = [] - for name, member in enumeration.__members__.items(): - if name != member.name: - duplicates.append((name, member.name)) - if duplicates: - alias_details = ', '.join( - ["%s -> %s" % (alias, name) for (alias, name) in duplicates]) - raise ValueError('duplicate values found in %r: %s' % - (enumeration, alias_details)) - return enumeration - -def _power_of_two(value): - if value < 1: - return False - return value == 2 ** _high_bit(value) - -def global_enum_repr(self): - """ - use module.enum_name instead of class.enum_name - - the module is the last module in case of a multi-module name - """ - module = self.__class__.__module__.split('.')[-1] - return '%s.%s' % (module, self._name_) - -def global_flag_repr(self): - """ - use module.flag_name instead of class.flag_name - - the module is the last module in case of a multi-module name - """ - module = self.__class__.__module__.split('.')[-1] - cls_name = self.__class__.__name__ - if self._name_ is None: - return "%s.%s(%r)" % (module, cls_name, self._value_) - if _is_single_bit(self): - return '%s.%s' % (module, self._name_) - if self._boundary_ is not FlagBoundary.KEEP: - return '|'.join(['%s.%s' % (module, name) for name in self.name.split('|')]) - else: - name = [] - for n in self._name_.split('|'): - if n[0].isdigit(): - name.append(n) - else: - name.append('%s.%s' % (module, n)) - return '|'.join(name) - -def global_str(self): - """ - use enum_name instead of class.enum_name - """ - if self._name_ is None: - cls_name = self.__class__.__name__ - return "%s(%r)" % (cls_name, self._value_) - else: - return self._name_ - -def global_enum(cls, update_str=False): - """ - decorator that makes the repr() of an enum member reference its module - instead of its class; also exports all members to the enum's module's - global namespace - """ - if issubclass(cls, Flag): - cls.__repr__ = global_flag_repr - else: - cls.__repr__ = global_enum_repr - if not issubclass(cls, ReprEnum) or update_str: - cls.__str__ = global_str - sys.modules[cls.__module__].__dict__.update(cls.__members__) - return cls - -def _simple_enum(etype=Enum, *, boundary=None, use_args=None): - """ - Class decorator that converts a normal class into an :class:`Enum`. No - safety checks are done, and some advanced behavior (such as - :func:`__init_subclass__`) is not available. Enum creation can be faster - using :func:`simple_enum`. - - >>> from enum import Enum, _simple_enum - >>> @_simple_enum(Enum) - ... class Color: - ... RED = auto() - ... GREEN = auto() - ... BLUE = auto() - >>> Color - - """ - def convert_class(cls): - nonlocal use_args - cls_name = cls.__name__ - if use_args is None: - use_args = etype._use_args_ - __new__ = cls.__dict__.get('__new__') - if __new__ is not None: - new_member = __new__.__func__ - else: - new_member = etype._member_type_.__new__ - attrs = {} - body = {} - if __new__ is not None: - body['__new_member__'] = new_member - body['_new_member_'] = new_member - body['_use_args_'] = use_args - body['_generate_next_value_'] = gnv = etype._generate_next_value_ - body['_member_names_'] = member_names = [] - body['_member_map_'] = member_map = {} - body['_value2member_map_'] = value2member_map = {} - body['_unhashable_values_'] = [] - body['_member_type_'] = member_type = etype._member_type_ - body['_value_repr_'] = etype._value_repr_ - if issubclass(etype, Flag): - body['_boundary_'] = boundary or etype._boundary_ - body['_flag_mask_'] = None - body['_all_bits_'] = None - body['_inverted_'] = None - body['__or__'] = Flag.__or__ - body['__xor__'] = Flag.__xor__ - body['__and__'] = Flag.__and__ - body['__ror__'] = Flag.__ror__ - body['__rxor__'] = Flag.__rxor__ - body['__rand__'] = Flag.__rand__ - body['__invert__'] = Flag.__invert__ - for name, obj in cls.__dict__.items(): - if name in ('__dict__', '__weakref__'): - continue - if _is_dunder(name) or _is_private(cls_name, name) or _is_sunder(name) or _is_descriptor(obj): - body[name] = obj - else: - attrs[name] = obj - if cls.__dict__.get('__doc__') is None: - body['__doc__'] = 'An enumeration.' - # - # double check that repr and friends are not the mixin's or various - # things break (such as pickle) - # however, if the method is defined in the Enum itself, don't replace - # it - enum_class = type(cls_name, (etype, ), body, boundary=boundary, _simple=True) - for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'): - if name not in body: - # check for mixin overrides before replacing - enum_method = getattr(etype, name) - found_method = getattr(enum_class, name) - object_method = getattr(object, name) - data_type_method = getattr(member_type, name) - if found_method in (data_type_method, object_method): - setattr(enum_class, name, enum_method) - gnv_last_values = [] - if issubclass(enum_class, Flag): - # Flag / IntFlag - single_bits = multi_bits = 0 - for name, value in attrs.items(): - if isinstance(value, auto) and auto.value is _auto_null: - value = gnv(name, 1, len(member_names), gnv_last_values) - if value in value2member_map: - # an alias to an existing member - redirect = property() - redirect.__set_name__(enum_class, name) - setattr(enum_class, name, redirect) - member_map[name] = value2member_map[value] - else: - # create the member - if use_args: - if not isinstance(value, tuple): - value = (value, ) - member = new_member(enum_class, *value) - value = value[0] - else: - member = new_member(enum_class) - if __new__ is None: - member._value_ = value - member._name_ = name - member.__objclass__ = enum_class - member.__init__(value) - redirect = property() - redirect.__set_name__(enum_class, name) - setattr(enum_class, name, redirect) - member_map[name] = member - member._sort_order_ = len(member_names) - value2member_map[value] = member - if _is_single_bit(value): - # not a multi-bit alias, record in _member_names_ and _flag_mask_ - member_names.append(name) - single_bits |= value - else: - multi_bits |= value - gnv_last_values.append(value) - enum_class._flag_mask_ = single_bits - enum_class._all_bits_ = 2 ** ((single_bits|multi_bits).bit_length()) - 1 - # set correct __iter__ - member_list = [m._value_ for m in enum_class] - if member_list != sorted(member_list): - enum_class._iter_member_ = enum_class._iter_member_by_def_ - else: - # Enum / IntEnum / StrEnum - for name, value in attrs.items(): - if isinstance(value, auto): - if value.value is _auto_null: - value.value = gnv(name, 1, len(member_names), gnv_last_values) - value = value.value - if value in value2member_map: - # an alias to an existing member - redirect = property() - redirect.__set_name__(enum_class, name) - setattr(enum_class, name, redirect) - member_map[name] = value2member_map[value] - else: - # create the member - if use_args: - if not isinstance(value, tuple): - value = (value, ) - member = new_member(enum_class, *value) - value = value[0] - else: - member = new_member(enum_class) - if __new__ is None: - member._value_ = value - member._name_ = name - member.__objclass__ = enum_class - member.__init__(value) - member._sort_order_ = len(member_names) - redirect = property() - redirect.__set_name__(enum_class, name) - setattr(enum_class, name, redirect) - member_map[name] = member - value2member_map[value] = member - member_names.append(name) - gnv_last_values.append(value) - if '__new__' in body: - enum_class.__new_member__ = enum_class.__new__ - enum_class.__new__ = Enum.__new__ - return enum_class - return convert_class - -@_simple_enum(StrEnum) -class EnumCheck: - """ - various conditions to check an enumeration for - """ - CONTINUOUS = "no skipped integer values" - NAMED_FLAGS = "multi-flag aliases may not contain unnamed flags" - UNIQUE = "one name per value" -CONTINUOUS, NAMED_FLAGS, UNIQUE = EnumCheck - - -class verify: - """ - Check an enumeration for various constraints. (see EnumCheck) - """ - def __init__(self, *checks): - self.checks = checks - def __call__(self, enumeration): - checks = self.checks - cls_name = enumeration.__name__ - if Flag is not None and issubclass(enumeration, Flag): - enum_type = 'flag' - elif issubclass(enumeration, Enum): - enum_type = 'enum' - else: - raise TypeError("the 'verify' decorator only works with Enum and Flag") - for check in checks: - if check is UNIQUE: - # check for duplicate names - duplicates = [] - for name, member in enumeration.__members__.items(): - if name != member.name: - duplicates.append((name, member.name)) - if duplicates: - alias_details = ', '.join( - ["%s -> %s" % (alias, name) for (alias, name) in duplicates]) - raise ValueError('aliases found in %r: %s' % - (enumeration, alias_details)) - elif check is CONTINUOUS: - values = set(e.value for e in enumeration) - if len(values) < 2: - continue - low, high = min(values), max(values) - missing = [] - if enum_type == 'flag': - # check for powers of two - for i in range(_high_bit(low)+1, _high_bit(high)): - if 2**i not in values: - missing.append(2**i) - elif enum_type == 'enum': - # check for powers of one - for i in range(low+1, high): - if i not in values: - missing.append(i) - else: - raise Exception('verify: unknown type %r' % enum_type) - if missing: - raise ValueError(('invalid %s %r: missing values %s' % ( - enum_type, cls_name, ', '.join((str(m) for m in missing))) - )[:256]) - # limit max length to protect against DOS attacks - elif check is NAMED_FLAGS: - # examine each alias and check for unnamed flags - member_names = enumeration._member_names_ - member_values = [m.value for m in enumeration] - missing_names = [] - missing_value = 0 - for name, alias in enumeration._member_map_.items(): - if name in member_names: - # not an alias - continue - if alias.value < 0: - # negative numbers are not checked - continue - values = list(_iter_bits_lsb(alias.value)) - missed = [v for v in values if v not in member_values] - if missed: - missing_names.append(name) - missing_value |= reduce(_or_, missed) - if missing_names: - if len(missing_names) == 1: - alias = 'alias %s is missing' % missing_names[0] - else: - alias = 'aliases %s and %s are missing' % ( - ', '.join(missing_names[:-1]), missing_names[-1] - ) - if _is_single_bit(missing_value): - value = 'value 0x%x' % missing_value - else: - value = 'combined values of 0x%x' % missing_value - raise ValueError( - 'invalid Flag %r: %s %s [use enum.show_flag_values(value) for details]' - % (cls_name, alias, value) - ) - return enumeration - -def _test_simple_enum(checked_enum, simple_enum): - """ - A function that can be used to test an enum created with :func:`_simple_enum` - against the version created by subclassing :class:`Enum`:: - - >>> from enum import Enum, _simple_enum, _test_simple_enum - >>> @_simple_enum(Enum) - ... class Color: - ... RED = auto() - ... GREEN = auto() - ... BLUE = auto() - >>> class CheckedColor(Enum): - ... RED = auto() - ... GREEN = auto() - ... BLUE = auto() - >>> _test_simple_enum(CheckedColor, Color) - - If differences are found, a :exc:`TypeError` is raised. - """ - failed = [] - if checked_enum.__dict__ != simple_enum.__dict__: - checked_dict = checked_enum.__dict__ - checked_keys = list(checked_dict.keys()) - simple_dict = simple_enum.__dict__ - simple_keys = list(simple_dict.keys()) - member_names = set( - list(checked_enum._member_map_.keys()) - + list(simple_enum._member_map_.keys()) - ) - for key in set(checked_keys + simple_keys): - if key in ('__module__', '_member_map_', '_value2member_map_', '__doc__'): - # keys known to be different, or very long - continue - elif key in member_names: - # members are checked below - continue - elif key not in simple_keys: - failed.append("missing key: %r" % (key, )) - elif key not in checked_keys: - failed.append("extra key: %r" % (key, )) - else: - checked_value = checked_dict[key] - simple_value = simple_dict[key] - if callable(checked_value) or isinstance(checked_value, bltns.property): - continue - if key == '__doc__': - # remove all spaces/tabs - compressed_checked_value = checked_value.replace(' ','').replace('\t','') - compressed_simple_value = simple_value.replace(' ','').replace('\t','') - if compressed_checked_value != compressed_simple_value: - failed.append("%r:\n %s\n %s" % ( - key, - "checked -> %r" % (checked_value, ), - "simple -> %r" % (simple_value, ), - )) - elif checked_value != simple_value: - failed.append("%r:\n %s\n %s" % ( - key, - "checked -> %r" % (checked_value, ), - "simple -> %r" % (simple_value, ), - )) - failed.sort() - for name in member_names: - failed_member = [] - if name not in simple_keys: - failed.append('missing member from simple enum: %r' % name) - elif name not in checked_keys: - failed.append('extra member in simple enum: %r' % name) - else: - checked_member_dict = checked_enum[name].__dict__ - checked_member_keys = list(checked_member_dict.keys()) - simple_member_dict = simple_enum[name].__dict__ - simple_member_keys = list(simple_member_dict.keys()) - for key in set(checked_member_keys + simple_member_keys): - if key in ('__module__', '__objclass__', '_inverted_'): - # keys known to be different or absent - continue - elif key not in simple_member_keys: - failed_member.append("missing key %r not in the simple enum member %r" % (key, name)) - elif key not in checked_member_keys: - failed_member.append("extra key %r in simple enum member %r" % (key, name)) - else: - checked_value = checked_member_dict[key] - simple_value = simple_member_dict[key] - if checked_value != simple_value: - failed_member.append("%r:\n %s\n %s" % ( - key, - "checked member -> %r" % (checked_value, ), - "simple member -> %r" % (simple_value, ), - )) - if failed_member: - failed.append('%r member mismatch:\n %s' % ( - name, '\n '.join(failed_member), - )) - for method in ( - '__str__', '__repr__', '__reduce_ex__', '__format__', - '__getnewargs_ex__', '__getnewargs__', '__reduce_ex__', '__reduce__' - ): - if method in simple_keys and method in checked_keys: - # cannot compare functions, and it exists in both, so we're good - continue - elif method not in simple_keys and method not in checked_keys: - # method is inherited -- check it out - checked_method = getattr(checked_enum, method, None) - simple_method = getattr(simple_enum, method, None) - if hasattr(checked_method, '__func__'): - checked_method = checked_method.__func__ - simple_method = simple_method.__func__ - if checked_method != simple_method: - failed.append("%r: %-30s %s" % ( - method, - "checked -> %r" % (checked_method, ), - "simple -> %r" % (simple_method, ), - )) - else: - # if the method existed in only one of the enums, it will have been caught - # in the first checks above - pass - if failed: - raise TypeError('enum mismatch:\n %s' % '\n '.join(failed)) - -def _old_convert_(etype, name, module, filter, source=None, *, boundary=None): - """ - Create a new Enum subclass that replaces a collection of global constants - """ - # convert all constants from source (or module) that pass filter() to - # a new Enum called name, and export the enum and its members back to - # module; - # also, replace the __reduce_ex__ method so unpickling works in - # previous Python versions - module_globals = sys.modules[module].__dict__ - if source: - source = source.__dict__ - else: - source = module_globals - # _value2member_map_ is populated in the same order every time - # for a consistent reverse mapping of number to name when there - # are multiple names for the same number. - members = [ - (name, value) - for name, value in source.items() - if filter(name)] - try: - # sort by value - members.sort(key=lambda t: (t[1], t[0])) - except TypeError: - # unless some values aren't comparable, in which case sort by name - members.sort(key=lambda t: t[0]) - cls = etype(name, members, module=module, boundary=boundary or KEEP) - cls.__reduce_ex__ = _reduce_ex_by_global_name - return cls - -_stdlib_enums = IntEnum, StrEnum, IntFlag diff --git a/python/Lib/filecmp.py b/python/Lib/filecmp.py deleted file mode 100644 index 97da022..0000000 --- a/python/Lib/filecmp.py +++ /dev/null @@ -1,313 +0,0 @@ -"""Utilities for comparing files and directories. - -Classes: - dircmp - -Functions: - cmp(f1, f2, shallow=True) -> int - cmpfiles(a, b, common) -> ([], [], []) - clear_cache() - -""" - -import os -import stat -from itertools import filterfalse -from types import GenericAlias - -__all__ = ['clear_cache', 'cmp', 'dircmp', 'cmpfiles', 'DEFAULT_IGNORES'] - -_cache = {} -BUFSIZE = 8*1024 - -DEFAULT_IGNORES = [ - 'RCS', 'CVS', 'tags', '.git', '.hg', '.bzr', '_darcs', '__pycache__'] - -def clear_cache(): - """Clear the filecmp cache.""" - _cache.clear() - -def cmp(f1, f2, shallow=True): - """Compare two files. - - Arguments: - - f1 -- First file name - - f2 -- Second file name - - shallow -- treat files as identical if their stat signatures (type, size, - mtime) are identical. Otherwise, files are considered different - if their sizes or contents differ. [default: True] - - Return value: - - True if the files are the same, False otherwise. - - This function uses a cache for past comparisons and the results, - with cache entries invalidated if their stat information - changes. The cache may be cleared by calling clear_cache(). - - """ - - s1 = _sig(os.stat(f1)) - s2 = _sig(os.stat(f2)) - if s1[0] != stat.S_IFREG or s2[0] != stat.S_IFREG: - return False - if shallow and s1 == s2: - return True - if s1[1] != s2[1]: - return False - - outcome = _cache.get((f1, f2, s1, s2)) - if outcome is None: - outcome = _do_cmp(f1, f2) - if len(_cache) > 100: # limit the maximum size of the cache - clear_cache() - _cache[f1, f2, s1, s2] = outcome - return outcome - -def _sig(st): - return (stat.S_IFMT(st.st_mode), - st.st_size, - st.st_mtime) - -def _do_cmp(f1, f2): - bufsize = BUFSIZE - with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2: - while True: - b1 = fp1.read(bufsize) - b2 = fp2.read(bufsize) - if b1 != b2: - return False - if not b1: - return True - -# Directory comparison class. -# -class dircmp: - """A class that manages the comparison of 2 directories. - - dircmp(a, b, ignore=None, hide=None) - A and B are directories. - IGNORE is a list of names to ignore, - defaults to DEFAULT_IGNORES. - HIDE is a list of names to hide, - defaults to [os.curdir, os.pardir]. - - High level usage: - x = dircmp(dir1, dir2) - x.report() -> prints a report on the differences between dir1 and dir2 - or - x.report_partial_closure() -> prints report on differences between dir1 - and dir2, and reports on common immediate subdirectories. - x.report_full_closure() -> like report_partial_closure, - but fully recursive. - - Attributes: - left_list, right_list: The files in dir1 and dir2, - filtered by hide and ignore. - common: a list of names in both dir1 and dir2. - left_only, right_only: names only in dir1, dir2. - common_dirs: subdirectories in both dir1 and dir2. - common_files: files in both dir1 and dir2. - common_funny: names in both dir1 and dir2 where the type differs between - dir1 and dir2, or the name is not stat-able. - same_files: list of identical files. - diff_files: list of filenames which differ. - funny_files: list of files which could not be compared. - subdirs: a dictionary of dircmp instances (or MyDirCmp instances if this - object is of type MyDirCmp, a subclass of dircmp), keyed by names - in common_dirs. - """ - - def __init__(self, a, b, ignore=None, hide=None): # Initialize - self.left = a - self.right = b - if hide is None: - self.hide = [os.curdir, os.pardir] # Names never to be shown - else: - self.hide = hide - if ignore is None: - self.ignore = DEFAULT_IGNORES - else: - self.ignore = ignore - - def phase0(self): # Compare everything except common subdirectories - self.left_list = _filter(os.listdir(self.left), - self.hide+self.ignore) - self.right_list = _filter(os.listdir(self.right), - self.hide+self.ignore) - self.left_list.sort() - self.right_list.sort() - - def phase1(self): # Compute common names - a = dict(zip(map(os.path.normcase, self.left_list), self.left_list)) - b = dict(zip(map(os.path.normcase, self.right_list), self.right_list)) - self.common = list(map(a.__getitem__, filter(b.__contains__, a))) - self.left_only = list(map(a.__getitem__, filterfalse(b.__contains__, a))) - self.right_only = list(map(b.__getitem__, filterfalse(a.__contains__, b))) - - def phase2(self): # Distinguish files, directories, funnies - self.common_dirs = [] - self.common_files = [] - self.common_funny = [] - - for x in self.common: - a_path = os.path.join(self.left, x) - b_path = os.path.join(self.right, x) - - ok = 1 - try: - a_stat = os.stat(a_path) - except OSError: - # print('Can\'t stat', a_path, ':', why.args[1]) - ok = 0 - try: - b_stat = os.stat(b_path) - except OSError: - # print('Can\'t stat', b_path, ':', why.args[1]) - ok = 0 - - if ok: - a_type = stat.S_IFMT(a_stat.st_mode) - b_type = stat.S_IFMT(b_stat.st_mode) - if a_type != b_type: - self.common_funny.append(x) - elif stat.S_ISDIR(a_type): - self.common_dirs.append(x) - elif stat.S_ISREG(a_type): - self.common_files.append(x) - else: - self.common_funny.append(x) - else: - self.common_funny.append(x) - - def phase3(self): # Find out differences between common files - xx = cmpfiles(self.left, self.right, self.common_files) - self.same_files, self.diff_files, self.funny_files = xx - - def phase4(self): # Find out differences between common subdirectories - # A new dircmp (or MyDirCmp if dircmp was subclassed) object is created - # for each common subdirectory, - # these are stored in a dictionary indexed by filename. - # The hide and ignore properties are inherited from the parent - self.subdirs = {} - for x in self.common_dirs: - a_x = os.path.join(self.left, x) - b_x = os.path.join(self.right, x) - self.subdirs[x] = self.__class__(a_x, b_x, self.ignore, self.hide) - - def phase4_closure(self): # Recursively call phase4() on subdirectories - self.phase4() - for sd in self.subdirs.values(): - sd.phase4_closure() - - def report(self): # Print a report on the differences between a and b - # Output format is purposely lousy - print('diff', self.left, self.right) - if self.left_only: - self.left_only.sort() - print('Only in', self.left, ':', self.left_only) - if self.right_only: - self.right_only.sort() - print('Only in', self.right, ':', self.right_only) - if self.same_files: - self.same_files.sort() - print('Identical files :', self.same_files) - if self.diff_files: - self.diff_files.sort() - print('Differing files :', self.diff_files) - if self.funny_files: - self.funny_files.sort() - print('Trouble with common files :', self.funny_files) - if self.common_dirs: - self.common_dirs.sort() - print('Common subdirectories :', self.common_dirs) - if self.common_funny: - self.common_funny.sort() - print('Common funny cases :', self.common_funny) - - def report_partial_closure(self): # Print reports on self and on subdirs - self.report() - for sd in self.subdirs.values(): - print() - sd.report() - - def report_full_closure(self): # Report on self and subdirs recursively - self.report() - for sd in self.subdirs.values(): - print() - sd.report_full_closure() - - methodmap = dict(subdirs=phase4, - same_files=phase3, diff_files=phase3, funny_files=phase3, - common_dirs = phase2, common_files=phase2, common_funny=phase2, - common=phase1, left_only=phase1, right_only=phase1, - left_list=phase0, right_list=phase0) - - def __getattr__(self, attr): - if attr not in self.methodmap: - raise AttributeError(attr) - self.methodmap[attr](self) - return getattr(self, attr) - - __class_getitem__ = classmethod(GenericAlias) - - -def cmpfiles(a, b, common, shallow=True): - """Compare common files in two directories. - - a, b -- directory names - common -- list of file names found in both directories - shallow -- if true, do comparison based solely on stat() information - - Returns a tuple of three lists: - files that compare equal - files that are different - filenames that aren't regular files. - - """ - res = ([], [], []) - for x in common: - ax = os.path.join(a, x) - bx = os.path.join(b, x) - res[_cmp(ax, bx, shallow)].append(x) - return res - - -# Compare two files. -# Return: -# 0 for equal -# 1 for different -# 2 for funny cases (can't stat, etc.) -# -def _cmp(a, b, sh, abs=abs, cmp=cmp): - try: - return not abs(cmp(a, b, sh)) - except OSError: - return 2 - - -# Return a copy with items that occur in skip removed. -# -def _filter(flist, skip): - return list(filterfalse(skip.__contains__, flist)) - - -# Demonstration and testing. -# -def demo(): - import sys - import getopt - options, args = getopt.getopt(sys.argv[1:], 'r') - if len(args) != 2: - raise getopt.GetoptError('need exactly two args', None) - dd = dircmp(args[0], args[1]) - if ('-r', '') in options: - dd.report_full_closure() - else: - dd.report() - -if __name__ == '__main__': - demo() diff --git a/python/Lib/fileinput.py b/python/Lib/fileinput.py deleted file mode 100644 index ab8bb21..0000000 --- a/python/Lib/fileinput.py +++ /dev/null @@ -1,442 +0,0 @@ -"""Helper class to quickly write a loop over all standard input files. - -Typical use is: - - import fileinput - for line in fileinput.input(encoding="utf-8"): - process(line) - -This iterates over the lines of all files listed in sys.argv[1:], -defaulting to sys.stdin if the list is empty. If a filename is '-' it -is also replaced by sys.stdin and the optional arguments mode and -openhook are ignored. To specify an alternative list of filenames, -pass it as the argument to input(). A single file name is also allowed. - -Functions filename(), lineno() return the filename and cumulative line -number of the line that has just been read; filelineno() returns its -line number in the current file; isfirstline() returns true iff the -line just read is the first line of its file; isstdin() returns true -iff the line was read from sys.stdin. Function nextfile() closes the -current file so that the next iteration will read the first line from -the next file (if any); lines not read from the file will not count -towards the cumulative line count; the filename is not changed until -after the first line of the next file has been read. Function close() -closes the sequence. - -Before any lines have been read, filename() returns None and both line -numbers are zero; nextfile() has no effect. After all lines have been -read, filename() and the line number functions return the values -pertaining to the last line read; nextfile() has no effect. - -All files are opened in text mode by default, you can override this by -setting the mode parameter to input() or FileInput.__init__(). -If an I/O error occurs during opening or reading a file, the OSError -exception is raised. - -If sys.stdin is used more than once, the second and further use will -return no lines, except perhaps for interactive use, or if it has been -explicitly reset (e.g. using sys.stdin.seek(0)). - -Empty files are opened and immediately closed; the only time their -presence in the list of filenames is noticeable at all is when the -last file opened is empty. - -It is possible that the last line of a file doesn't end in a newline -character; otherwise lines are returned including the trailing -newline. - -Class FileInput is the implementation; its methods filename(), -lineno(), fileline(), isfirstline(), isstdin(), nextfile() and close() -correspond to the functions in the module. In addition it has a -readline() method which returns the next input line, and a -__getitem__() method which implements the sequence behavior. The -sequence must be accessed in strictly sequential order; sequence -access and readline() cannot be mixed. - -Optional in-place filtering: if the keyword argument inplace=1 is -passed to input() or to the FileInput constructor, the file is moved -to a backup file and standard output is directed to the input file. -This makes it possible to write a filter that rewrites its input file -in place. If the keyword argument backup="." is also -given, it specifies the extension for the backup file, and the backup -file remains around; by default, the extension is ".bak" and it is -deleted when the output file is closed. In-place filtering is -disabled when standard input is read. XXX The current implementation -does not work for MS-DOS 8+3 filesystems. -""" - -import io -import sys, os -from types import GenericAlias - -__all__ = ["input", "close", "nextfile", "filename", "lineno", "filelineno", - "fileno", "isfirstline", "isstdin", "FileInput", "hook_compressed", - "hook_encoded"] - -_state = None - -def input(files=None, inplace=False, backup="", *, mode="r", openhook=None, - encoding=None, errors=None): - """Return an instance of the FileInput class, which can be iterated. - - The parameters are passed to the constructor of the FileInput class. - The returned instance, in addition to being an iterator, - keeps global state for the functions of this module,. - """ - global _state - if _state and _state._file: - raise RuntimeError("input() already active") - _state = FileInput(files, inplace, backup, mode=mode, openhook=openhook, - encoding=encoding, errors=errors) - return _state - -def close(): - """Close the sequence.""" - global _state - state = _state - _state = None - if state: - state.close() - -def nextfile(): - """ - Close the current file so that the next iteration will read the first - line from the next file (if any); lines not read from the file will - not count towards the cumulative line count. The filename is not - changed until after the first line of the next file has been read. - Before the first line has been read, this function has no effect; - it cannot be used to skip the first file. After the last line of the - last file has been read, this function has no effect. - """ - if not _state: - raise RuntimeError("no active input()") - return _state.nextfile() - -def filename(): - """ - Return the name of the file currently being read. - Before the first line has been read, returns None. - """ - if not _state: - raise RuntimeError("no active input()") - return _state.filename() - -def lineno(): - """ - Return the cumulative line number of the line that has just been read. - Before the first line has been read, returns 0. After the last line - of the last file has been read, returns the line number of that line. - """ - if not _state: - raise RuntimeError("no active input()") - return _state.lineno() - -def filelineno(): - """ - Return the line number in the current file. Before the first line - has been read, returns 0. After the last line of the last file has - been read, returns the line number of that line within the file. - """ - if not _state: - raise RuntimeError("no active input()") - return _state.filelineno() - -def fileno(): - """ - Return the file number of the current file. When no file is currently - opened, returns -1. - """ - if not _state: - raise RuntimeError("no active input()") - return _state.fileno() - -def isfirstline(): - """ - Returns true the line just read is the first line of its file, - otherwise returns false. - """ - if not _state: - raise RuntimeError("no active input()") - return _state.isfirstline() - -def isstdin(): - """ - Returns true if the last line was read from sys.stdin, - otherwise returns false. - """ - if not _state: - raise RuntimeError("no active input()") - return _state.isstdin() - -class FileInput: - """FileInput([files[, inplace[, backup]]], *, mode=None, openhook=None) - - Class FileInput is the implementation of the module; its methods - filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(), - nextfile() and close() correspond to the functions of the same name - in the module. - In addition it has a readline() method which returns the next - input line, and a __getitem__() method which implements the - sequence behavior. The sequence must be accessed in strictly - sequential order; random access and readline() cannot be mixed. - """ - - def __init__(self, files=None, inplace=False, backup="", *, - mode="r", openhook=None, encoding=None, errors=None): - if isinstance(files, str): - files = (files,) - elif isinstance(files, os.PathLike): - files = (os.fspath(files), ) - else: - if files is None: - files = sys.argv[1:] - if not files: - files = ('-',) - else: - files = tuple(files) - self._files = files - self._inplace = inplace - self._backup = backup - self._savestdout = None - self._output = None - self._filename = None - self._startlineno = 0 - self._filelineno = 0 - self._file = None - self._isstdin = False - self._backupfilename = None - self._encoding = encoding - self._errors = errors - - # We can not use io.text_encoding() here because old openhook doesn't - # take encoding parameter. - if (sys.flags.warn_default_encoding and - "b" not in mode and encoding is None and openhook is None): - import warnings - warnings.warn("'encoding' argument not specified.", - EncodingWarning, 2) - - # restrict mode argument to reading modes - if mode not in ('r', 'rb'): - raise ValueError("FileInput opening mode must be 'r' or 'rb'") - self._mode = mode - self._write_mode = mode.replace('r', 'w') - if openhook: - if inplace: - raise ValueError("FileInput cannot use an opening hook in inplace mode") - if not callable(openhook): - raise ValueError("FileInput openhook must be callable") - self._openhook = openhook - - def __del__(self): - self.close() - - def close(self): - try: - self.nextfile() - finally: - self._files = () - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - self.close() - - def __iter__(self): - return self - - def __next__(self): - while True: - line = self._readline() - if line: - self._filelineno += 1 - return line - if not self._file: - raise StopIteration - self.nextfile() - # repeat with next file - - def nextfile(self): - savestdout = self._savestdout - self._savestdout = None - if savestdout: - sys.stdout = savestdout - - output = self._output - self._output = None - try: - if output: - output.close() - finally: - file = self._file - self._file = None - try: - del self._readline # restore FileInput._readline - except AttributeError: - pass - try: - if file and not self._isstdin: - file.close() - finally: - backupfilename = self._backupfilename - self._backupfilename = None - if backupfilename and not self._backup: - try: os.unlink(backupfilename) - except OSError: pass - - self._isstdin = False - - def readline(self): - while True: - line = self._readline() - if line: - self._filelineno += 1 - return line - if not self._file: - return line - self.nextfile() - # repeat with next file - - def _readline(self): - if not self._files: - if 'b' in self._mode: - return b'' - else: - return '' - self._filename = self._files[0] - self._files = self._files[1:] - self._startlineno = self.lineno() - self._filelineno = 0 - self._file = None - self._isstdin = False - self._backupfilename = 0 - - # EncodingWarning is emitted in __init__() already - if "b" not in self._mode: - encoding = self._encoding or "locale" - else: - encoding = None - - if self._filename == '-': - self._filename = '' - if 'b' in self._mode: - self._file = getattr(sys.stdin, 'buffer', sys.stdin) - else: - self._file = sys.stdin - self._isstdin = True - else: - if self._inplace: - self._backupfilename = ( - os.fspath(self._filename) + (self._backup or ".bak")) - try: - os.unlink(self._backupfilename) - except OSError: - pass - # The next few lines may raise OSError - os.rename(self._filename, self._backupfilename) - self._file = open(self._backupfilename, self._mode, - encoding=encoding, errors=self._errors) - try: - perm = os.fstat(self._file.fileno()).st_mode - except OSError: - self._output = open(self._filename, self._write_mode, - encoding=encoding, errors=self._errors) - else: - mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC - if hasattr(os, 'O_BINARY'): - mode |= os.O_BINARY - - fd = os.open(self._filename, mode, perm) - self._output = os.fdopen(fd, self._write_mode, - encoding=encoding, errors=self._errors) - try: - os.chmod(self._filename, perm) - except OSError: - pass - self._savestdout = sys.stdout - sys.stdout = self._output - else: - # This may raise OSError - if self._openhook: - # Custom hooks made previous to Python 3.10 didn't have - # encoding argument - if self._encoding is None: - self._file = self._openhook(self._filename, self._mode) - else: - self._file = self._openhook( - self._filename, self._mode, encoding=self._encoding, errors=self._errors) - else: - self._file = open(self._filename, self._mode, encoding=encoding, errors=self._errors) - self._readline = self._file.readline # hide FileInput._readline - return self._readline() - - def filename(self): - return self._filename - - def lineno(self): - return self._startlineno + self._filelineno - - def filelineno(self): - return self._filelineno - - def fileno(self): - if self._file: - try: - return self._file.fileno() - except ValueError: - return -1 - else: - return -1 - - def isfirstline(self): - return self._filelineno == 1 - - def isstdin(self): - return self._isstdin - - __class_getitem__ = classmethod(GenericAlias) - - -def hook_compressed(filename, mode, *, encoding=None, errors=None): - if encoding is None: # EncodingWarning is emitted in FileInput() already. - encoding = "locale" - ext = os.path.splitext(filename)[1] - if ext == '.gz': - import gzip - stream = gzip.open(filename, mode) - elif ext == '.bz2': - import bz2 - stream = bz2.BZ2File(filename, mode) - else: - return open(filename, mode, encoding=encoding, errors=errors) - - # gzip and bz2 are binary mode by default. - if "b" not in mode: - stream = io.TextIOWrapper(stream, encoding=encoding, errors=errors) - return stream - - -def hook_encoded(encoding, errors=None): - def openhook(filename, mode): - return open(filename, mode, encoding=encoding, errors=errors) - return openhook - - -def _test(): - import getopt - inplace = False - backup = False - opts, args = getopt.getopt(sys.argv[1:], "ib:") - for o, a in opts: - if o == '-i': inplace = True - if o == '-b': backup = a - for line in input(args, inplace=inplace, backup=backup): - if line[-1:] == '\n': line = line[:-1] - if line[-1:] == '\r': line = line[:-1] - print("%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(), - isfirstline() and "*" or "", line)) - print("%d: %s[%d]" % (lineno(), filename(), filelineno())) - -if __name__ == '__main__': - _test() diff --git a/python/Lib/fnmatch.py b/python/Lib/fnmatch.py deleted file mode 100644 index 2518baf..0000000 --- a/python/Lib/fnmatch.py +++ /dev/null @@ -1,185 +0,0 @@ -"""Filename matching with shell patterns. - -fnmatch(FILENAME, PATTERN) matches according to the local convention. -fnmatchcase(FILENAME, PATTERN) always takes case in account. - -The functions operate by translating the pattern into a regular -expression. They cache the compiled regular expressions for speed. - -The function translate(PATTERN) returns a regular expression -corresponding to PATTERN. (It does not compile it.) -""" -import os -import posixpath -import re -import functools - -__all__ = ["filter", "fnmatch", "fnmatchcase", "translate"] - -def fnmatch(name, pat): - """Test whether FILENAME matches PATTERN. - - Patterns are Unix shell style: - - * matches everything - ? matches any single character - [seq] matches any character in seq - [!seq] matches any char not in seq - - An initial period in FILENAME is not special. - Both FILENAME and PATTERN are first case-normalized - if the operating system requires it. - If you don't want this, use fnmatchcase(FILENAME, PATTERN). - """ - name = os.path.normcase(name) - pat = os.path.normcase(pat) - return fnmatchcase(name, pat) - -@functools.lru_cache(maxsize=32768, typed=True) -def _compile_pattern(pat): - if isinstance(pat, bytes): - pat_str = str(pat, 'ISO-8859-1') - res_str = translate(pat_str) - res = bytes(res_str, 'ISO-8859-1') - else: - res = translate(pat) - return re.compile(res).match - -def filter(names, pat): - """Construct a list from those elements of the iterable NAMES that match PAT.""" - result = [] - pat = os.path.normcase(pat) - match = _compile_pattern(pat) - if os.path is posixpath: - # normcase on posix is NOP. Optimize it away from the loop. - for name in names: - if match(name): - result.append(name) - else: - for name in names: - if match(os.path.normcase(name)): - result.append(name) - return result - -def fnmatchcase(name, pat): - """Test whether FILENAME matches PATTERN, including case. - - This is a version of fnmatch() which doesn't case-normalize - its arguments. - """ - match = _compile_pattern(pat) - return match(name) is not None - - -def translate(pat): - """Translate a shell PATTERN to a regular expression. - - There is no way to quote meta-characters. - """ - - STAR = object() - res = [] - add = res.append - i, n = 0, len(pat) - while i < n: - c = pat[i] - i = i+1 - if c == '*': - # compress consecutive `*` into one - if (not res) or res[-1] is not STAR: - add(STAR) - elif c == '?': - add('.') - elif c == '[': - j = i - if j < n and pat[j] == '!': - j = j+1 - if j < n and pat[j] == ']': - j = j+1 - while j < n and pat[j] != ']': - j = j+1 - if j >= n: - add('\\[') - else: - stuff = pat[i:j] - if '-' not in stuff: - stuff = stuff.replace('\\', r'\\') - else: - chunks = [] - k = i+2 if pat[i] == '!' else i+1 - while True: - k = pat.find('-', k, j) - if k < 0: - break - chunks.append(pat[i:k]) - i = k+1 - k = k+3 - chunk = pat[i:j] - if chunk: - chunks.append(chunk) - else: - chunks[-1] += '-' - # Remove empty ranges -- invalid in RE. - for k in range(len(chunks)-1, 0, -1): - if chunks[k-1][-1] > chunks[k][0]: - chunks[k-1] = chunks[k-1][:-1] + chunks[k][1:] - del chunks[k] - # Escape backslashes and hyphens for set difference (--). - # Hyphens that create ranges shouldn't be escaped. - stuff = '-'.join(s.replace('\\', r'\\').replace('-', r'\-') - for s in chunks) - # Escape set operations (&&, ~~ and ||). - stuff = re.sub(r'([&~|])', r'\\\1', stuff) - i = j+1 - if not stuff: - # Empty range: never match. - add('(?!)') - elif stuff == '!': - # Negated empty range: match any character. - add('.') - else: - if stuff[0] == '!': - stuff = '^' + stuff[1:] - elif stuff[0] in ('^', '['): - stuff = '\\' + stuff - add(f'[{stuff}]') - else: - add(re.escape(c)) - assert i == n - - # Deal with STARs. - inp = res - res = [] - add = res.append - i, n = 0, len(inp) - # Fixed pieces at the start? - while i < n and inp[i] is not STAR: - add(inp[i]) - i += 1 - # Now deal with STAR fixed STAR fixed ... - # For an interior `STAR fixed` pairing, we want to do a minimal - # .*? match followed by `fixed`, with no possibility of backtracking. - # Atomic groups ("(?>...)") allow us to spell that directly. - # Note: people rely on the undocumented ability to join multiple - # translate() results together via "|" to build large regexps matching - # "one of many" shell patterns. - while i < n: - assert inp[i] is STAR - i += 1 - if i == n: - add(".*") - break - assert inp[i] is not STAR - fixed = [] - while i < n and inp[i] is not STAR: - fixed.append(inp[i]) - i += 1 - fixed = "".join(fixed) - if i == n: - add(".*") - add(fixed) - else: - add(f"(?>.*?{fixed})") - assert i == n - res = "".join(res) - return fr'(?s:{res})\Z' diff --git a/python/Lib/fractions.py b/python/Lib/fractions.py deleted file mode 100644 index 4df818e..0000000 --- a/python/Lib/fractions.py +++ /dev/null @@ -1,756 +0,0 @@ -# Originally contributed by Sjoerd Mullender. -# Significantly modified by Jeffrey Yasskin . - -"""Fraction, infinite-precision, rational numbers.""" - -from decimal import Decimal -import math -import numbers -import operator -import re -import sys - -__all__ = ['Fraction'] - - -# Constants related to the hash implementation; hash(x) is based -# on the reduction of x modulo the prime _PyHASH_MODULUS. -_PyHASH_MODULUS = sys.hash_info.modulus -# Value to be used for rationals that reduce to infinity modulo -# _PyHASH_MODULUS. -_PyHASH_INF = sys.hash_info.inf - -_RATIONAL_FORMAT = re.compile(r""" - \A\s* # optional whitespace at the start, - (?P[-+]?) # an optional sign, then - (?=\d|\.\d) # lookahead for digit or .digit - (?P\d*|\d+(_\d+)*) # numerator (possibly empty) - (?: # followed by - (?:/(?P\d+(_\d+)*))? # an optional denominator - | # or - (?:\.(?Pd*|\d+(_\d+)*))? # an optional fractional part - (?:E(?P[-+]?\d+(_\d+)*))? # and optional exponent - ) - \s*\Z # and optional whitespace to finish -""", re.VERBOSE | re.IGNORECASE) - - -class Fraction(numbers.Rational): - """This class implements rational numbers. - - In the two-argument form of the constructor, Fraction(8, 6) will - produce a rational number equivalent to 4/3. Both arguments must - be Rational. The numerator defaults to 0 and the denominator - defaults to 1 so that Fraction(3) == 3 and Fraction() == 0. - - Fractions can also be constructed from: - - - numeric strings similar to those accepted by the - float constructor (for example, '-2.3' or '1e10') - - - strings of the form '123/456' - - - float and Decimal instances - - - other Rational instances (including integers) - - """ - - __slots__ = ('_numerator', '_denominator') - - # We're immutable, so use __new__ not __init__ - def __new__(cls, numerator=0, denominator=None, *, _normalize=True): - """Constructs a Rational. - - Takes a string like '3/2' or '1.5', another Rational instance, a - numerator/denominator pair, or a float. - - Examples - -------- - - >>> Fraction(10, -8) - Fraction(-5, 4) - >>> Fraction(Fraction(1, 7), 5) - Fraction(1, 35) - >>> Fraction(Fraction(1, 7), Fraction(2, 3)) - Fraction(3, 14) - >>> Fraction('314') - Fraction(314, 1) - >>> Fraction('-35/4') - Fraction(-35, 4) - >>> Fraction('3.1415') # conversion from numeric string - Fraction(6283, 2000) - >>> Fraction('-47e-2') # string may include a decimal exponent - Fraction(-47, 100) - >>> Fraction(1.47) # direct construction from float (exact conversion) - Fraction(6620291452234629, 4503599627370496) - >>> Fraction(2.25) - Fraction(9, 4) - >>> Fraction(Decimal('1.47')) - Fraction(147, 100) - - """ - self = super(Fraction, cls).__new__(cls) - - if denominator is None: - if type(numerator) is int: - self._numerator = numerator - self._denominator = 1 - return self - - elif isinstance(numerator, numbers.Rational): - self._numerator = numerator.numerator - self._denominator = numerator.denominator - return self - - elif isinstance(numerator, (float, Decimal)): - # Exact conversion - self._numerator, self._denominator = numerator.as_integer_ratio() - return self - - elif isinstance(numerator, str): - # Handle construction from strings. - m = _RATIONAL_FORMAT.match(numerator) - if m is None: - raise ValueError('Invalid literal for Fraction: %r' % - numerator) - numerator = int(m.group('num') or '0') - denom = m.group('denom') - if denom: - denominator = int(denom) - else: - denominator = 1 - decimal = m.group('decimal') - if decimal: - decimal = decimal.replace('_', '') - scale = 10**len(decimal) - numerator = numerator * scale + int(decimal) - denominator *= scale - exp = m.group('exp') - if exp: - exp = int(exp) - if exp >= 0: - numerator *= 10**exp - else: - denominator *= 10**-exp - if m.group('sign') == '-': - numerator = -numerator - - else: - raise TypeError("argument should be a string " - "or a Rational instance") - - elif type(numerator) is int is type(denominator): - pass # *very* normal case - - elif (isinstance(numerator, numbers.Rational) and - isinstance(denominator, numbers.Rational)): - numerator, denominator = ( - numerator.numerator * denominator.denominator, - denominator.numerator * numerator.denominator - ) - else: - raise TypeError("both arguments should be " - "Rational instances") - - if denominator == 0: - raise ZeroDivisionError('Fraction(%s, 0)' % numerator) - if _normalize: - g = math.gcd(numerator, denominator) - if denominator < 0: - g = -g - numerator //= g - denominator //= g - self._numerator = numerator - self._denominator = denominator - return self - - @classmethod - def from_float(cls, f): - """Converts a finite float to a rational number, exactly. - - Beware that Fraction.from_float(0.3) != Fraction(3, 10). - - """ - if isinstance(f, numbers.Integral): - return cls(f) - elif not isinstance(f, float): - raise TypeError("%s.from_float() only takes floats, not %r (%s)" % - (cls.__name__, f, type(f).__name__)) - return cls(*f.as_integer_ratio()) - - @classmethod - def from_decimal(cls, dec): - """Converts a finite Decimal instance to a rational number, exactly.""" - from decimal import Decimal - if isinstance(dec, numbers.Integral): - dec = Decimal(int(dec)) - elif not isinstance(dec, Decimal): - raise TypeError( - "%s.from_decimal() only takes Decimals, not %r (%s)" % - (cls.__name__, dec, type(dec).__name__)) - return cls(*dec.as_integer_ratio()) - - def as_integer_ratio(self): - """Return the integer ratio as a tuple. - - Return a tuple of two integers, whose ratio is equal to the - Fraction and with a positive denominator. - """ - return (self._numerator, self._denominator) - - def limit_denominator(self, max_denominator=1000000): - """Closest Fraction to self with denominator at most max_denominator. - - >>> Fraction('3.141592653589793').limit_denominator(10) - Fraction(22, 7) - >>> Fraction('3.141592653589793').limit_denominator(100) - Fraction(311, 99) - >>> Fraction(4321, 8765).limit_denominator(10000) - Fraction(4321, 8765) - - """ - # Algorithm notes: For any real number x, define a *best upper - # approximation* to x to be a rational number p/q such that: - # - # (1) p/q >= x, and - # (2) if p/q > r/s >= x then s > q, for any rational r/s. - # - # Define *best lower approximation* similarly. Then it can be - # proved that a rational number is a best upper or lower - # approximation to x if, and only if, it is a convergent or - # semiconvergent of the (unique shortest) continued fraction - # associated to x. - # - # To find a best rational approximation with denominator <= M, - # we find the best upper and lower approximations with - # denominator <= M and take whichever of these is closer to x. - # In the event of a tie, the bound with smaller denominator is - # chosen. If both denominators are equal (which can happen - # only when max_denominator == 1 and self is midway between - # two integers) the lower bound---i.e., the floor of self, is - # taken. - - if max_denominator < 1: - raise ValueError("max_denominator should be at least 1") - if self._denominator <= max_denominator: - return Fraction(self) - - p0, q0, p1, q1 = 0, 1, 1, 0 - n, d = self._numerator, self._denominator - while True: - a = n//d - q2 = q0+a*q1 - if q2 > max_denominator: - break - p0, q0, p1, q1 = p1, q1, p0+a*p1, q2 - n, d = d, n-a*d - - k = (max_denominator-q0)//q1 - bound1 = Fraction(p0+k*p1, q0+k*q1) - bound2 = Fraction(p1, q1) - if abs(bound2 - self) <= abs(bound1-self): - return bound2 - else: - return bound1 - - @property - def numerator(a): - return a._numerator - - @property - def denominator(a): - return a._denominator - - def __repr__(self): - """repr(self)""" - return '%s(%s, %s)' % (self.__class__.__name__, - self._numerator, self._denominator) - - def __str__(self): - """str(self)""" - if self._denominator == 1: - return str(self._numerator) - else: - return '%s/%s' % (self._numerator, self._denominator) - - def _operator_fallbacks(monomorphic_operator, fallback_operator): - """Generates forward and reverse operators given a purely-rational - operator and a function from the operator module. - - Use this like: - __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op) - - In general, we want to implement the arithmetic operations so - that mixed-mode operations either call an implementation whose - author knew about the types of both arguments, or convert both - to the nearest built in type and do the operation there. In - Fraction, that means that we define __add__ and __radd__ as: - - def __add__(self, other): - # Both types have numerators/denominator attributes, - # so do the operation directly - if isinstance(other, (int, Fraction)): - return Fraction(self.numerator * other.denominator + - other.numerator * self.denominator, - self.denominator * other.denominator) - # float and complex don't have those operations, but we - # know about those types, so special case them. - elif isinstance(other, float): - return float(self) + other - elif isinstance(other, complex): - return complex(self) + other - # Let the other type take over. - return NotImplemented - - def __radd__(self, other): - # radd handles more types than add because there's - # nothing left to fall back to. - if isinstance(other, numbers.Rational): - return Fraction(self.numerator * other.denominator + - other.numerator * self.denominator, - self.denominator * other.denominator) - elif isinstance(other, Real): - return float(other) + float(self) - elif isinstance(other, Complex): - return complex(other) + complex(self) - return NotImplemented - - - There are 5 different cases for a mixed-type addition on - Fraction. I'll refer to all of the above code that doesn't - refer to Fraction, float, or complex as "boilerplate". 'r' - will be an instance of Fraction, which is a subtype of - Rational (r : Fraction <: Rational), and b : B <: - Complex. The first three involve 'r + b': - - 1. If B <: Fraction, int, float, or complex, we handle - that specially, and all is well. - 2. If Fraction falls back to the boilerplate code, and it - were to return a value from __add__, we'd miss the - possibility that B defines a more intelligent __radd__, - so the boilerplate should return NotImplemented from - __add__. In particular, we don't handle Rational - here, even though we could get an exact answer, in case - the other type wants to do something special. - 3. If B <: Fraction, Python tries B.__radd__ before - Fraction.__add__. This is ok, because it was - implemented with knowledge of Fraction, so it can - handle those instances before delegating to Real or - Complex. - - The next two situations describe 'b + r'. We assume that b - didn't know about Fraction in its implementation, and that it - uses similar boilerplate code: - - 4. If B <: Rational, then __radd_ converts both to the - builtin rational type (hey look, that's us) and - proceeds. - 5. Otherwise, __radd__ tries to find the nearest common - base ABC, and fall back to its builtin type. Since this - class doesn't subclass a concrete type, there's no - implementation to fall back to, so we need to try as - hard as possible to return an actual value, or the user - will get a TypeError. - - """ - def forward(a, b): - if isinstance(b, (int, Fraction)): - return monomorphic_operator(a, b) - elif isinstance(b, float): - return fallback_operator(float(a), b) - elif isinstance(b, complex): - return fallback_operator(complex(a), b) - else: - return NotImplemented - forward.__name__ = '__' + fallback_operator.__name__ + '__' - forward.__doc__ = monomorphic_operator.__doc__ - - def reverse(b, a): - if isinstance(a, numbers.Rational): - # Includes ints. - return monomorphic_operator(a, b) - elif isinstance(a, numbers.Real): - return fallback_operator(float(a), float(b)) - elif isinstance(a, numbers.Complex): - return fallback_operator(complex(a), complex(b)) - else: - return NotImplemented - reverse.__name__ = '__r' + fallback_operator.__name__ + '__' - reverse.__doc__ = monomorphic_operator.__doc__ - - return forward, reverse - - # Rational arithmetic algorithms: Knuth, TAOCP, Volume 2, 4.5.1. - # - # Assume input fractions a and b are normalized. - # - # 1) Consider addition/subtraction. - # - # Let g = gcd(da, db). Then - # - # na nb na*db ± nb*da - # a ± b == -- ± -- == ------------- == - # da db da*db - # - # na*(db//g) ± nb*(da//g) t - # == ----------------------- == - - # (da*db)//g d - # - # Now, if g > 1, we're working with smaller integers. - # - # Note, that t, (da//g) and (db//g) are pairwise coprime. - # - # Indeed, (da//g) and (db//g) share no common factors (they were - # removed) and da is coprime with na (since input fractions are - # normalized), hence (da//g) and na are coprime. By symmetry, - # (db//g) and nb are coprime too. Then, - # - # gcd(t, da//g) == gcd(na*(db//g), da//g) == 1 - # gcd(t, db//g) == gcd(nb*(da//g), db//g) == 1 - # - # Above allows us optimize reduction of the result to lowest - # terms. Indeed, - # - # g2 = gcd(t, d) == gcd(t, (da//g)*(db//g)*g) == gcd(t, g) - # - # t//g2 t//g2 - # a ± b == ----------------------- == ---------------- - # (da//g)*(db//g)*(g//g2) (da//g)*(db//g2) - # - # is a normalized fraction. This is useful because the unnormalized - # denominator d could be much larger than g. - # - # We should special-case g == 1 (and g2 == 1), since 60.8% of - # randomly-chosen integers are coprime: - # https://en.wikipedia.org/wiki/Coprime_integers#Probability_of_coprimality - # Note, that g2 == 1 always for fractions, obtained from floats: here - # g is a power of 2 and the unnormalized numerator t is an odd integer. - # - # 2) Consider multiplication - # - # Let g1 = gcd(na, db) and g2 = gcd(nb, da), then - # - # na*nb na*nb (na//g1)*(nb//g2) - # a*b == ----- == ----- == ----------------- - # da*db db*da (db//g1)*(da//g2) - # - # Note, that after divisions we're multiplying smaller integers. - # - # Also, the resulting fraction is normalized, because each of - # two factors in the numerator is coprime to each of the two factors - # in the denominator. - # - # Indeed, pick (na//g1). It's coprime with (da//g2), because input - # fractions are normalized. It's also coprime with (db//g1), because - # common factors are removed by g1 == gcd(na, db). - # - # As for addition/subtraction, we should special-case g1 == 1 - # and g2 == 1 for same reason. That happens also for multiplying - # rationals, obtained from floats. - - def _add(a, b): - """a + b""" - na, da = a.numerator, a.denominator - nb, db = b.numerator, b.denominator - g = math.gcd(da, db) - if g == 1: - return Fraction(na * db + da * nb, da * db, _normalize=False) - s = da // g - t = na * (db // g) + nb * s - g2 = math.gcd(t, g) - if g2 == 1: - return Fraction(t, s * db, _normalize=False) - return Fraction(t // g2, s * (db // g2), _normalize=False) - - __add__, __radd__ = _operator_fallbacks(_add, operator.add) - - def _sub(a, b): - """a - b""" - na, da = a.numerator, a.denominator - nb, db = b.numerator, b.denominator - g = math.gcd(da, db) - if g == 1: - return Fraction(na * db - da * nb, da * db, _normalize=False) - s = da // g - t = na * (db // g) - nb * s - g2 = math.gcd(t, g) - if g2 == 1: - return Fraction(t, s * db, _normalize=False) - return Fraction(t // g2, s * (db // g2), _normalize=False) - - __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub) - - def _mul(a, b): - """a * b""" - na, da = a.numerator, a.denominator - nb, db = b.numerator, b.denominator - g1 = math.gcd(na, db) - if g1 > 1: - na //= g1 - db //= g1 - g2 = math.gcd(nb, da) - if g2 > 1: - nb //= g2 - da //= g2 - return Fraction(na * nb, db * da, _normalize=False) - - __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul) - - def _div(a, b): - """a / b""" - # Same as _mul(), with inversed b. - na, da = a.numerator, a.denominator - nb, db = b.numerator, b.denominator - g1 = math.gcd(na, nb) - if g1 > 1: - na //= g1 - nb //= g1 - g2 = math.gcd(db, da) - if g2 > 1: - da //= g2 - db //= g2 - n, d = na * db, nb * da - if d < 0: - n, d = -n, -d - return Fraction(n, d, _normalize=False) - - __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv) - - def _floordiv(a, b): - """a // b""" - return (a.numerator * b.denominator) // (a.denominator * b.numerator) - - __floordiv__, __rfloordiv__ = _operator_fallbacks(_floordiv, operator.floordiv) - - def _divmod(a, b): - """(a // b, a % b)""" - da, db = a.denominator, b.denominator - div, n_mod = divmod(a.numerator * db, da * b.numerator) - return div, Fraction(n_mod, da * db) - - __divmod__, __rdivmod__ = _operator_fallbacks(_divmod, divmod) - - def _mod(a, b): - """a % b""" - da, db = a.denominator, b.denominator - return Fraction((a.numerator * db) % (b.numerator * da), da * db) - - __mod__, __rmod__ = _operator_fallbacks(_mod, operator.mod) - - def __pow__(a, b): - """a ** b - - If b is not an integer, the result will be a float or complex - since roots are generally irrational. If b is an integer, the - result will be rational. - - """ - if isinstance(b, numbers.Rational): - if b.denominator == 1: - power = b.numerator - if power >= 0: - return Fraction(a._numerator ** power, - a._denominator ** power, - _normalize=False) - elif a._numerator >= 0: - return Fraction(a._denominator ** -power, - a._numerator ** -power, - _normalize=False) - else: - return Fraction((-a._denominator) ** -power, - (-a._numerator) ** -power, - _normalize=False) - else: - # A fractional power will generally produce an - # irrational number. - return float(a) ** float(b) - else: - return float(a) ** b - - def __rpow__(b, a): - """a ** b""" - if b._denominator == 1 and b._numerator >= 0: - # If a is an int, keep it that way if possible. - return a ** b._numerator - - if isinstance(a, numbers.Rational): - return Fraction(a.numerator, a.denominator) ** b - - if b._denominator == 1: - return a ** b._numerator - - return a ** float(b) - - def __pos__(a): - """+a: Coerces a subclass instance to Fraction""" - return Fraction(a._numerator, a._denominator, _normalize=False) - - def __neg__(a): - """-a""" - return Fraction(-a._numerator, a._denominator, _normalize=False) - - def __abs__(a): - """abs(a)""" - return Fraction(abs(a._numerator), a._denominator, _normalize=False) - - def __int__(a, _index=operator.index): - """int(a)""" - if a._numerator < 0: - return _index(-(-a._numerator // a._denominator)) - else: - return _index(a._numerator // a._denominator) - - def __trunc__(a): - """math.trunc(a)""" - if a._numerator < 0: - return -(-a._numerator // a._denominator) - else: - return a._numerator // a._denominator - - def __floor__(a): - """math.floor(a)""" - return a.numerator // a.denominator - - def __ceil__(a): - """math.ceil(a)""" - # The negations cleverly convince floordiv to return the ceiling. - return -(-a.numerator // a.denominator) - - def __round__(self, ndigits=None): - """round(self, ndigits) - - Rounds half toward even. - """ - if ndigits is None: - floor, remainder = divmod(self.numerator, self.denominator) - if remainder * 2 < self.denominator: - return floor - elif remainder * 2 > self.denominator: - return floor + 1 - # Deal with the half case: - elif floor % 2 == 0: - return floor - else: - return floor + 1 - shift = 10**abs(ndigits) - # See _operator_fallbacks.forward to check that the results of - # these operations will always be Fraction and therefore have - # round(). - if ndigits > 0: - return Fraction(round(self * shift), shift) - else: - return Fraction(round(self / shift) * shift) - - def __hash__(self): - """hash(self)""" - - # To make sure that the hash of a Fraction agrees with the hash - # of a numerically equal integer, float or Decimal instance, we - # follow the rules for numeric hashes outlined in the - # documentation. (See library docs, 'Built-in Types'). - - try: - dinv = pow(self._denominator, -1, _PyHASH_MODULUS) - except ValueError: - # ValueError means there is no modular inverse. - hash_ = _PyHASH_INF - else: - # The general algorithm now specifies that the absolute value of - # the hash is - # (|N| * dinv) % P - # where N is self._numerator and P is _PyHASH_MODULUS. That's - # optimized here in two ways: first, for a non-negative int i, - # hash(i) == i % P, but the int hash implementation doesn't need - # to divide, and is faster than doing % P explicitly. So we do - # hash(|N| * dinv) - # instead. Second, N is unbounded, so its product with dinv may - # be arbitrarily expensive to compute. The final answer is the - # same if we use the bounded |N| % P instead, which can again - # be done with an int hash() call. If 0 <= i < P, hash(i) == i, - # so this nested hash() call wastes a bit of time making a - # redundant copy when |N| < P, but can save an arbitrarily large - # amount of computation for large |N|. - hash_ = hash(hash(abs(self._numerator)) * dinv) - result = hash_ if self._numerator >= 0 else -hash_ - return -2 if result == -1 else result - - def __eq__(a, b): - """a == b""" - if type(b) is int: - return a._numerator == b and a._denominator == 1 - if isinstance(b, numbers.Rational): - return (a._numerator == b.numerator and - a._denominator == b.denominator) - if isinstance(b, numbers.Complex) and b.imag == 0: - b = b.real - if isinstance(b, float): - if math.isnan(b) or math.isinf(b): - # comparisons with an infinity or nan should behave in - # the same way for any finite a, so treat a as zero. - return 0.0 == b - else: - return a == a.from_float(b) - else: - # Since a doesn't know how to compare with b, let's give b - # a chance to compare itself with a. - return NotImplemented - - def _richcmp(self, other, op): - """Helper for comparison operators, for internal use only. - - Implement comparison between a Rational instance `self`, and - either another Rational instance or a float `other`. If - `other` is not a Rational instance or a float, return - NotImplemented. `op` should be one of the six standard - comparison operators. - - """ - # convert other to a Rational instance where reasonable. - if isinstance(other, numbers.Rational): - return op(self._numerator * other.denominator, - self._denominator * other.numerator) - if isinstance(other, float): - if math.isnan(other) or math.isinf(other): - return op(0.0, other) - else: - return op(self, self.from_float(other)) - else: - return NotImplemented - - def __lt__(a, b): - """a < b""" - return a._richcmp(b, operator.lt) - - def __gt__(a, b): - """a > b""" - return a._richcmp(b, operator.gt) - - def __le__(a, b): - """a <= b""" - return a._richcmp(b, operator.le) - - def __ge__(a, b): - """a >= b""" - return a._richcmp(b, operator.ge) - - def __bool__(a): - """a != 0""" - # bpo-39274: Use bool() because (a._numerator != 0) can return an - # object which is not a bool. - return bool(a._numerator) - - # support for pickling, copy, and deepcopy - - def __reduce__(self): - return (self.__class__, (self._numerator, self._denominator)) - - def __copy__(self): - if type(self) == Fraction: - return self # I'm immutable; therefore I am my own clone - return self.__class__(self._numerator, self._denominator) - - def __deepcopy__(self, memo): - if type(self) == Fraction: - return self # My components are also immutable - return self.__class__(self._numerator, self._denominator) diff --git a/python/Lib/functools.py b/python/Lib/functools.py deleted file mode 100644 index a6d6903..0000000 --- a/python/Lib/functools.py +++ /dev/null @@ -1,1012 +0,0 @@ -"""functools.py - Tools for working with functions and callable objects -""" -# Python module wrapper for _functools C module -# to allow utilities written in Python to be added -# to the functools module. -# Written by Nick Coghlan , -# Raymond Hettinger , -# and Łukasz Langa . -# Copyright (C) 2006-2013 Python Software Foundation. -# See C source code for _functools credits/copyright - -__all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', - 'total_ordering', 'cache', 'cmp_to_key', 'lru_cache', 'reduce', - 'partial', 'partialmethod', 'singledispatch', 'singledispatchmethod', - 'cached_property'] - -from abc import get_cache_token -from collections import namedtuple -# import types, weakref # Deferred to single_dispatch() -from reprlib import recursive_repr -from _thread import RLock -from types import GenericAlias - - -################################################################################ -### update_wrapper() and wraps() decorator -################################################################################ - -# update_wrapper() and wraps() are tools to help write -# wrapper functions that can handle naive introspection - -WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__', - '__annotations__') -WRAPPER_UPDATES = ('__dict__',) -def update_wrapper(wrapper, - wrapped, - assigned = WRAPPER_ASSIGNMENTS, - updated = WRAPPER_UPDATES): - """Update a wrapper function to look like the wrapped function - - wrapper is the function to be updated - wrapped is the original function - assigned is a tuple naming the attributes assigned directly - from the wrapped function to the wrapper function (defaults to - functools.WRAPPER_ASSIGNMENTS) - updated is a tuple naming the attributes of the wrapper that - are updated with the corresponding attribute from the wrapped - function (defaults to functools.WRAPPER_UPDATES) - """ - for attr in assigned: - try: - value = getattr(wrapped, attr) - except AttributeError: - pass - else: - setattr(wrapper, attr, value) - for attr in updated: - getattr(wrapper, attr).update(getattr(wrapped, attr, {})) - # Issue #17482: set __wrapped__ last so we don't inadvertently copy it - # from the wrapped function when updating __dict__ - wrapper.__wrapped__ = wrapped - # Return the wrapper so this can be used as a decorator via partial() - return wrapper - -def wraps(wrapped, - assigned = WRAPPER_ASSIGNMENTS, - updated = WRAPPER_UPDATES): - """Decorator factory to apply update_wrapper() to a wrapper function - - Returns a decorator that invokes update_wrapper() with the decorated - function as the wrapper argument and the arguments to wraps() as the - remaining arguments. Default arguments are as for update_wrapper(). - This is a convenience function to simplify applying partial() to - update_wrapper(). - """ - return partial(update_wrapper, wrapped=wrapped, - assigned=assigned, updated=updated) - - -################################################################################ -### total_ordering class decorator -################################################################################ - -# The total ordering functions all invoke the root magic method directly -# rather than using the corresponding operator. This avoids possible -# infinite recursion that could occur when the operator dispatch logic -# detects a NotImplemented result and then calls a reflected method. - -def _gt_from_lt(self, other): - 'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).' - op_result = type(self).__lt__(self, other) - if op_result is NotImplemented: - return op_result - return not op_result and self != other - -def _le_from_lt(self, other): - 'Return a <= b. Computed by @total_ordering from (a < b) or (a == b).' - op_result = type(self).__lt__(self, other) - if op_result is NotImplemented: - return op_result - return op_result or self == other - -def _ge_from_lt(self, other): - 'Return a >= b. Computed by @total_ordering from (not a < b).' - op_result = type(self).__lt__(self, other) - if op_result is NotImplemented: - return op_result - return not op_result - -def _ge_from_le(self, other): - 'Return a >= b. Computed by @total_ordering from (not a <= b) or (a == b).' - op_result = type(self).__le__(self, other) - if op_result is NotImplemented: - return op_result - return not op_result or self == other - -def _lt_from_le(self, other): - 'Return a < b. Computed by @total_ordering from (a <= b) and (a != b).' - op_result = type(self).__le__(self, other) - if op_result is NotImplemented: - return op_result - return op_result and self != other - -def _gt_from_le(self, other): - 'Return a > b. Computed by @total_ordering from (not a <= b).' - op_result = type(self).__le__(self, other) - if op_result is NotImplemented: - return op_result - return not op_result - -def _lt_from_gt(self, other): - 'Return a < b. Computed by @total_ordering from (not a > b) and (a != b).' - op_result = type(self).__gt__(self, other) - if op_result is NotImplemented: - return op_result - return not op_result and self != other - -def _ge_from_gt(self, other): - 'Return a >= b. Computed by @total_ordering from (a > b) or (a == b).' - op_result = type(self).__gt__(self, other) - if op_result is NotImplemented: - return op_result - return op_result or self == other - -def _le_from_gt(self, other): - 'Return a <= b. Computed by @total_ordering from (not a > b).' - op_result = type(self).__gt__(self, other) - if op_result is NotImplemented: - return op_result - return not op_result - -def _le_from_ge(self, other): - 'Return a <= b. Computed by @total_ordering from (not a >= b) or (a == b).' - op_result = type(self).__ge__(self, other) - if op_result is NotImplemented: - return op_result - return not op_result or self == other - -def _gt_from_ge(self, other): - 'Return a > b. Computed by @total_ordering from (a >= b) and (a != b).' - op_result = type(self).__ge__(self, other) - if op_result is NotImplemented: - return op_result - return op_result and self != other - -def _lt_from_ge(self, other): - 'Return a < b. Computed by @total_ordering from (not a >= b).' - op_result = type(self).__ge__(self, other) - if op_result is NotImplemented: - return op_result - return not op_result - -_convert = { - '__lt__': [('__gt__', _gt_from_lt), - ('__le__', _le_from_lt), - ('__ge__', _ge_from_lt)], - '__le__': [('__ge__', _ge_from_le), - ('__lt__', _lt_from_le), - ('__gt__', _gt_from_le)], - '__gt__': [('__lt__', _lt_from_gt), - ('__ge__', _ge_from_gt), - ('__le__', _le_from_gt)], - '__ge__': [('__le__', _le_from_ge), - ('__gt__', _gt_from_ge), - ('__lt__', _lt_from_ge)] -} - -def total_ordering(cls): - """Class decorator that fills in missing ordering methods""" - # Find user-defined comparisons (not those inherited from object). - roots = {op for op in _convert if getattr(cls, op, None) is not getattr(object, op, None)} - if not roots: - raise ValueError('must define at least one ordering operation: < > <= >=') - root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__ - for opname, opfunc in _convert[root]: - if opname not in roots: - opfunc.__name__ = opname - setattr(cls, opname, opfunc) - return cls - - -################################################################################ -### cmp_to_key() function converter -################################################################################ - -def cmp_to_key(mycmp): - """Convert a cmp= function into a key= function""" - class K(object): - __slots__ = ['obj'] - def __init__(self, obj): - self.obj = obj - def __lt__(self, other): - return mycmp(self.obj, other.obj) < 0 - def __gt__(self, other): - return mycmp(self.obj, other.obj) > 0 - def __eq__(self, other): - return mycmp(self.obj, other.obj) == 0 - def __le__(self, other): - return mycmp(self.obj, other.obj) <= 0 - def __ge__(self, other): - return mycmp(self.obj, other.obj) >= 0 - __hash__ = None - return K - -try: - from _functools import cmp_to_key -except ImportError: - pass - - -################################################################################ -### reduce() sequence to a single item -################################################################################ - -_initial_missing = object() - -def reduce(function, sequence, initial=_initial_missing): - """ - reduce(function, iterable[, initial]) -> value - - Apply a function of two arguments cumulatively to the items of a sequence - or iterable, from left to right, so as to reduce the iterable to a single - value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates - ((((1+2)+3)+4)+5). If initial is present, it is placed before the items - of the iterable in the calculation, and serves as a default when the - iterable is empty. - """ - - it = iter(sequence) - - if initial is _initial_missing: - try: - value = next(it) - except StopIteration: - raise TypeError( - "reduce() of empty iterable with no initial value") from None - else: - value = initial - - for element in it: - value = function(value, element) - - return value - -try: - from _functools import reduce -except ImportError: - pass - - -################################################################################ -### partial() argument application -################################################################################ - -# Purely functional, no descriptor behaviour -class partial: - """New function with partial application of the given arguments - and keywords. - """ - - __slots__ = "func", "args", "keywords", "__dict__", "__weakref__" - - def __new__(cls, func, /, *args, **keywords): - if not callable(func): - raise TypeError("the first argument must be callable") - - if hasattr(func, "func"): - args = func.args + args - keywords = {**func.keywords, **keywords} - func = func.func - - self = super(partial, cls).__new__(cls) - - self.func = func - self.args = args - self.keywords = keywords - return self - - def __call__(self, /, *args, **keywords): - keywords = {**self.keywords, **keywords} - return self.func(*self.args, *args, **keywords) - - @recursive_repr() - def __repr__(self): - qualname = type(self).__qualname__ - args = [repr(self.func)] - args.extend(repr(x) for x in self.args) - args.extend(f"{k}={v!r}" for (k, v) in self.keywords.items()) - if type(self).__module__ == "functools": - return f"functools.{qualname}({', '.join(args)})" - return f"{qualname}({', '.join(args)})" - - def __reduce__(self): - return type(self), (self.func,), (self.func, self.args, - self.keywords or None, self.__dict__ or None) - - def __setstate__(self, state): - if not isinstance(state, tuple): - raise TypeError("argument to __setstate__ must be a tuple") - if len(state) != 4: - raise TypeError(f"expected 4 items in state, got {len(state)}") - func, args, kwds, namespace = state - if (not callable(func) or not isinstance(args, tuple) or - (kwds is not None and not isinstance(kwds, dict)) or - (namespace is not None and not isinstance(namespace, dict))): - raise TypeError("invalid partial state") - - args = tuple(args) # just in case it's a subclass - if kwds is None: - kwds = {} - elif type(kwds) is not dict: # XXX does it need to be *exactly* dict? - kwds = dict(kwds) - if namespace is None: - namespace = {} - - self.__dict__ = namespace - self.func = func - self.args = args - self.keywords = kwds - -try: - from _functools import partial -except ImportError: - pass - -# Descriptor version -class partialmethod(object): - """Method descriptor with partial application of the given arguments - and keywords. - - Supports wrapping existing descriptors and handles non-descriptor - callables as instance methods. - """ - - def __init__(self, func, /, *args, **keywords): - if not callable(func) and not hasattr(func, "__get__"): - raise TypeError("{!r} is not callable or a descriptor" - .format(func)) - - # func could be a descriptor like classmethod which isn't callable, - # so we can't inherit from partial (it verifies func is callable) - if isinstance(func, partialmethod): - # flattening is mandatory in order to place cls/self before all - # other arguments - # it's also more efficient since only one function will be called - self.func = func.func - self.args = func.args + args - self.keywords = {**func.keywords, **keywords} - else: - self.func = func - self.args = args - self.keywords = keywords - - def __repr__(self): - args = ", ".join(map(repr, self.args)) - keywords = ", ".join("{}={!r}".format(k, v) - for k, v in self.keywords.items()) - format_string = "{module}.{cls}({func}, {args}, {keywords})" - return format_string.format(module=self.__class__.__module__, - cls=self.__class__.__qualname__, - func=self.func, - args=args, - keywords=keywords) - - def _make_unbound_method(self): - def _method(cls_or_self, /, *args, **keywords): - keywords = {**self.keywords, **keywords} - return self.func(cls_or_self, *self.args, *args, **keywords) - _method.__isabstractmethod__ = self.__isabstractmethod__ - _method._partialmethod = self - return _method - - def __get__(self, obj, cls=None): - get = getattr(self.func, "__get__", None) - result = None - if get is not None: - new_func = get(obj, cls) - if new_func is not self.func: - # Assume __get__ returning something new indicates the - # creation of an appropriate callable - result = partial(new_func, *self.args, **self.keywords) - try: - result.__self__ = new_func.__self__ - except AttributeError: - pass - if result is None: - # If the underlying descriptor didn't do anything, treat this - # like an instance method - result = self._make_unbound_method().__get__(obj, cls) - return result - - @property - def __isabstractmethod__(self): - return getattr(self.func, "__isabstractmethod__", False) - - __class_getitem__ = classmethod(GenericAlias) - - -# Helper functions - -def _unwrap_partial(func): - while isinstance(func, partial): - func = func.func - return func - -################################################################################ -### LRU Cache function decorator -################################################################################ - -_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"]) - -class _HashedSeq(list): - """ This class guarantees that hash() will be called no more than once - per element. This is important because the lru_cache() will hash - the key multiple times on a cache miss. - - """ - - __slots__ = 'hashvalue' - - def __init__(self, tup, hash=hash): - self[:] = tup - self.hashvalue = hash(tup) - - def __hash__(self): - return self.hashvalue - -def _make_key(args, kwds, typed, - kwd_mark = (object(),), - fasttypes = {int, str}, - tuple=tuple, type=type, len=len): - """Make a cache key from optionally typed positional and keyword arguments - - The key is constructed in a way that is flat as possible rather than - as a nested structure that would take more memory. - - If there is only a single argument and its data type is known to cache - its hash value, then that argument is returned without a wrapper. This - saves space and improves lookup speed. - - """ - # All of code below relies on kwds preserving the order input by the user. - # Formerly, we sorted() the kwds before looping. The new way is *much* - # faster; however, it means that f(x=1, y=2) will now be treated as a - # distinct call from f(y=2, x=1) which will be cached separately. - key = args - if kwds: - key += kwd_mark - for item in kwds.items(): - key += item - if typed: - key += tuple(type(v) for v in args) - if kwds: - key += tuple(type(v) for v in kwds.values()) - elif len(key) == 1 and type(key[0]) in fasttypes: - return key[0] - return _HashedSeq(key) - -def lru_cache(maxsize=128, typed=False): - """Least-recently-used cache decorator. - - If *maxsize* is set to None, the LRU features are disabled and the cache - can grow without bound. - - If *typed* is True, arguments of different types will be cached separately. - For example, f(3.0) and f(3) will be treated as distinct calls with - distinct results. - - Arguments to the cached function must be hashable. - - View the cache statistics named tuple (hits, misses, maxsize, currsize) - with f.cache_info(). Clear the cache and statistics with f.cache_clear(). - Access the underlying function with f.__wrapped__. - - See: https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU) - - """ - - # Users should only access the lru_cache through its public API: - # cache_info, cache_clear, and f.__wrapped__ - # The internals of the lru_cache are encapsulated for thread safety and - # to allow the implementation to change (including a possible C version). - - if isinstance(maxsize, int): - # Negative maxsize is treated as 0 - if maxsize < 0: - maxsize = 0 - elif callable(maxsize) and isinstance(typed, bool): - # The user_function was passed in directly via the maxsize argument - user_function, maxsize = maxsize, 128 - wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo) - wrapper.cache_parameters = lambda : {'maxsize': maxsize, 'typed': typed} - return update_wrapper(wrapper, user_function) - elif maxsize is not None: - raise TypeError( - 'Expected first argument to be an integer, a callable, or None') - - def decorating_function(user_function): - wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo) - wrapper.cache_parameters = lambda : {'maxsize': maxsize, 'typed': typed} - return update_wrapper(wrapper, user_function) - - return decorating_function - -def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo): - # Constants shared by all lru cache instances: - sentinel = object() # unique object used to signal cache misses - make_key = _make_key # build a key from the function arguments - PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields - - cache = {} - hits = misses = 0 - full = False - cache_get = cache.get # bound method to lookup a key or return None - cache_len = cache.__len__ # get cache size without calling len() - lock = RLock() # because linkedlist updates aren't threadsafe - root = [] # root of the circular doubly linked list - root[:] = [root, root, None, None] # initialize by pointing to self - - if maxsize == 0: - - def wrapper(*args, **kwds): - # No caching -- just a statistics update - nonlocal misses - misses += 1 - result = user_function(*args, **kwds) - return result - - elif maxsize is None: - - def wrapper(*args, **kwds): - # Simple caching without ordering or size limit - nonlocal hits, misses - key = make_key(args, kwds, typed) - result = cache_get(key, sentinel) - if result is not sentinel: - hits += 1 - return result - misses += 1 - result = user_function(*args, **kwds) - cache[key] = result - return result - - else: - - def wrapper(*args, **kwds): - # Size limited caching that tracks accesses by recency - nonlocal root, hits, misses, full - key = make_key(args, kwds, typed) - with lock: - link = cache_get(key) - if link is not None: - # Move the link to the front of the circular queue - link_prev, link_next, _key, result = link - link_prev[NEXT] = link_next - link_next[PREV] = link_prev - last = root[PREV] - last[NEXT] = root[PREV] = link - link[PREV] = last - link[NEXT] = root - hits += 1 - return result - misses += 1 - result = user_function(*args, **kwds) - with lock: - if key in cache: - # Getting here means that this same key was added to the - # cache while the lock was released. Since the link - # update is already done, we need only return the - # computed result and update the count of misses. - pass - elif full: - # Use the old root to store the new key and result. - oldroot = root - oldroot[KEY] = key - oldroot[RESULT] = result - # Empty the oldest link and make it the new root. - # Keep a reference to the old key and old result to - # prevent their ref counts from going to zero during the - # update. That will prevent potentially arbitrary object - # clean-up code (i.e. __del__) from running while we're - # still adjusting the links. - root = oldroot[NEXT] - oldkey = root[KEY] - oldresult = root[RESULT] - root[KEY] = root[RESULT] = None - # Now update the cache dictionary. - del cache[oldkey] - # Save the potentially reentrant cache[key] assignment - # for last, after the root and links have been put in - # a consistent state. - cache[key] = oldroot - else: - # Put result in a new link at the front of the queue. - last = root[PREV] - link = [last, root, key, result] - last[NEXT] = root[PREV] = cache[key] = link - # Use the cache_len bound method instead of the len() function - # which could potentially be wrapped in an lru_cache itself. - full = (cache_len() >= maxsize) - return result - - def cache_info(): - """Report cache statistics""" - with lock: - return _CacheInfo(hits, misses, maxsize, cache_len()) - - def cache_clear(): - """Clear the cache and cache statistics""" - nonlocal hits, misses, full - with lock: - cache.clear() - root[:] = [root, root, None, None] - hits = misses = 0 - full = False - - wrapper.cache_info = cache_info - wrapper.cache_clear = cache_clear - return wrapper - -try: - from _functools import _lru_cache_wrapper -except ImportError: - pass - - -################################################################################ -### cache -- simplified access to the infinity cache -################################################################################ - -def cache(user_function, /): - 'Simple lightweight unbounded cache. Sometimes called "memoize".' - return lru_cache(maxsize=None)(user_function) - - -################################################################################ -### singledispatch() - single-dispatch generic function decorator -################################################################################ - -def _c3_merge(sequences): - """Merges MROs in *sequences* to a single MRO using the C3 algorithm. - - Adapted from https://www.python.org/download/releases/2.3/mro/. - - """ - result = [] - while True: - sequences = [s for s in sequences if s] # purge empty sequences - if not sequences: - return result - for s1 in sequences: # find merge candidates among seq heads - candidate = s1[0] - for s2 in sequences: - if candidate in s2[1:]: - candidate = None - break # reject the current head, it appears later - else: - break - if candidate is None: - raise RuntimeError("Inconsistent hierarchy") - result.append(candidate) - # remove the chosen candidate - for seq in sequences: - if seq[0] == candidate: - del seq[0] - -def _c3_mro(cls, abcs=None): - """Computes the method resolution order using extended C3 linearization. - - If no *abcs* are given, the algorithm works exactly like the built-in C3 - linearization used for method resolution. - - If given, *abcs* is a list of abstract base classes that should be inserted - into the resulting MRO. Unrelated ABCs are ignored and don't end up in the - result. The algorithm inserts ABCs where their functionality is introduced, - i.e. issubclass(cls, abc) returns True for the class itself but returns - False for all its direct base classes. Implicit ABCs for a given class - (either registered or inferred from the presence of a special method like - __len__) are inserted directly after the last ABC explicitly listed in the - MRO of said class. If two implicit ABCs end up next to each other in the - resulting MRO, their ordering depends on the order of types in *abcs*. - - """ - for i, base in enumerate(reversed(cls.__bases__)): - if hasattr(base, '__abstractmethods__'): - boundary = len(cls.__bases__) - i - break # Bases up to the last explicit ABC are considered first. - else: - boundary = 0 - abcs = list(abcs) if abcs else [] - explicit_bases = list(cls.__bases__[:boundary]) - abstract_bases = [] - other_bases = list(cls.__bases__[boundary:]) - for base in abcs: - if issubclass(cls, base) and not any( - issubclass(b, base) for b in cls.__bases__ - ): - # If *cls* is the class that introduces behaviour described by - # an ABC *base*, insert said ABC to its MRO. - abstract_bases.append(base) - for base in abstract_bases: - abcs.remove(base) - explicit_c3_mros = [_c3_mro(base, abcs=abcs) for base in explicit_bases] - abstract_c3_mros = [_c3_mro(base, abcs=abcs) for base in abstract_bases] - other_c3_mros = [_c3_mro(base, abcs=abcs) for base in other_bases] - return _c3_merge( - [[cls]] + - explicit_c3_mros + abstract_c3_mros + other_c3_mros + - [explicit_bases] + [abstract_bases] + [other_bases] - ) - -def _compose_mro(cls, types): - """Calculates the method resolution order for a given class *cls*. - - Includes relevant abstract base classes (with their respective bases) from - the *types* iterable. Uses a modified C3 linearization algorithm. - - """ - bases = set(cls.__mro__) - # Remove entries which are already present in the __mro__ or unrelated. - def is_related(typ): - return (typ not in bases and hasattr(typ, '__mro__') - and not isinstance(typ, GenericAlias) - and issubclass(cls, typ)) - types = [n for n in types if is_related(n)] - # Remove entries which are strict bases of other entries (they will end up - # in the MRO anyway. - def is_strict_base(typ): - for other in types: - if typ != other and typ in other.__mro__: - return True - return False - types = [n for n in types if not is_strict_base(n)] - # Subclasses of the ABCs in *types* which are also implemented by - # *cls* can be used to stabilize ABC ordering. - type_set = set(types) - mro = [] - for typ in types: - found = [] - for sub in typ.__subclasses__(): - if sub not in bases and issubclass(cls, sub): - found.append([s for s in sub.__mro__ if s in type_set]) - if not found: - mro.append(typ) - continue - # Favor subclasses with the biggest number of useful bases - found.sort(key=len, reverse=True) - for sub in found: - for subcls in sub: - if subcls not in mro: - mro.append(subcls) - return _c3_mro(cls, abcs=mro) - -def _find_impl(cls, registry): - """Returns the best matching implementation from *registry* for type *cls*. - - Where there is no registered implementation for a specific type, its method - resolution order is used to find a more generic implementation. - - Note: if *registry* does not contain an implementation for the base - *object* type, this function may return None. - - """ - mro = _compose_mro(cls, registry.keys()) - match = None - for t in mro: - if match is not None: - # If *match* is an implicit ABC but there is another unrelated, - # equally matching implicit ABC, refuse the temptation to guess. - if (t in registry and t not in cls.__mro__ - and match not in cls.__mro__ - and not issubclass(match, t)): - raise RuntimeError("Ambiguous dispatch: {} or {}".format( - match, t)) - break - if t in registry: - match = t - return registry.get(match) - -def singledispatch(func): - """Single-dispatch generic function decorator. - - Transforms a function into a generic function, which can have different - behaviours depending upon the type of its first argument. The decorated - function acts as the default implementation, and additional - implementations can be registered using the register() attribute of the - generic function. - """ - # There are many programs that use functools without singledispatch, so we - # trade-off making singledispatch marginally slower for the benefit of - # making start-up of such applications slightly faster. - import types, weakref - - registry = {} - dispatch_cache = weakref.WeakKeyDictionary() - cache_token = None - - def dispatch(cls): - """generic_func.dispatch(cls) -> - - Runs the dispatch algorithm to return the best available implementation - for the given *cls* registered on *generic_func*. - - """ - nonlocal cache_token - if cache_token is not None: - current_token = get_cache_token() - if cache_token != current_token: - dispatch_cache.clear() - cache_token = current_token - try: - impl = dispatch_cache[cls] - except KeyError: - try: - impl = registry[cls] - except KeyError: - impl = _find_impl(cls, registry) - dispatch_cache[cls] = impl - return impl - - def _is_union_type(cls): - from typing import get_origin, Union - return get_origin(cls) in {Union, types.UnionType} - - def _is_valid_dispatch_type(cls): - if isinstance(cls, type): - return True - from typing import get_args - return (_is_union_type(cls) and - all(isinstance(arg, type) for arg in get_args(cls))) - - def register(cls, func=None): - """generic_func.register(cls, func) -> func - - Registers a new implementation for the given *cls* on a *generic_func*. - - """ - nonlocal cache_token - if _is_valid_dispatch_type(cls): - if func is None: - return lambda f: register(cls, f) - else: - if func is not None: - raise TypeError( - f"Invalid first argument to `register()`. " - f"{cls!r} is not a class or union type." - ) - ann = getattr(cls, '__annotations__', {}) - if not ann: - raise TypeError( - f"Invalid first argument to `register()`: {cls!r}. " - f"Use either `@register(some_class)` or plain `@register` " - f"on an annotated function." - ) - func = cls - - # only import typing if annotation parsing is necessary - from typing import get_type_hints - argname, cls = next(iter(get_type_hints(func).items())) - if not _is_valid_dispatch_type(cls): - if _is_union_type(cls): - raise TypeError( - f"Invalid annotation for {argname!r}. " - f"{cls!r} not all arguments are classes." - ) - else: - raise TypeError( - f"Invalid annotation for {argname!r}. " - f"{cls!r} is not a class." - ) - - if _is_union_type(cls): - from typing import get_args - - for arg in get_args(cls): - registry[arg] = func - else: - registry[cls] = func - if cache_token is None and hasattr(cls, '__abstractmethods__'): - cache_token = get_cache_token() - dispatch_cache.clear() - return func - - def wrapper(*args, **kw): - if not args: - raise TypeError(f'{funcname} requires at least ' - '1 positional argument') - - return dispatch(args[0].__class__)(*args, **kw) - - funcname = getattr(func, '__name__', 'singledispatch function') - registry[object] = func - wrapper.register = register - wrapper.dispatch = dispatch - wrapper.registry = types.MappingProxyType(registry) - wrapper._clear_cache = dispatch_cache.clear - update_wrapper(wrapper, func) - return wrapper - - -# Descriptor version -class singledispatchmethod: - """Single-dispatch generic method descriptor. - - Supports wrapping existing descriptors and handles non-descriptor - callables as instance methods. - """ - - def __init__(self, func): - if not callable(func) and not hasattr(func, "__get__"): - raise TypeError(f"{func!r} is not callable or a descriptor") - - self.dispatcher = singledispatch(func) - self.func = func - - def register(self, cls, method=None): - """generic_method.register(cls, func) -> func - - Registers a new implementation for the given *cls* on a *generic_method*. - """ - return self.dispatcher.register(cls, func=method) - - def __get__(self, obj, cls=None): - def _method(*args, **kwargs): - method = self.dispatcher.dispatch(args[0].__class__) - return method.__get__(obj, cls)(*args, **kwargs) - - _method.__isabstractmethod__ = self.__isabstractmethod__ - _method.register = self.register - update_wrapper(_method, self.func) - return _method - - @property - def __isabstractmethod__(self): - return getattr(self.func, '__isabstractmethod__', False) - - -################################################################################ -### cached_property() - computed once per instance, cached as attribute -################################################################################ - -_NOT_FOUND = object() - - -class cached_property: - def __init__(self, func): - self.func = func - self.attrname = None - self.__doc__ = func.__doc__ - self.lock = RLock() - - def __set_name__(self, owner, name): - if self.attrname is None: - self.attrname = name - elif name != self.attrname: - raise TypeError( - "Cannot assign the same cached_property to two different names " - f"({self.attrname!r} and {name!r})." - ) - - def __get__(self, instance, owner=None): - if instance is None: - return self - if self.attrname is None: - raise TypeError( - "Cannot use cached_property instance without calling __set_name__ on it.") - try: - cache = instance.__dict__ - except AttributeError: # not all objects have __dict__ (e.g. class defines slots) - msg = ( - f"No '__dict__' attribute on {type(instance).__name__!r} " - f"instance to cache {self.attrname!r} property." - ) - raise TypeError(msg) from None - val = cache.get(self.attrname, _NOT_FOUND) - if val is _NOT_FOUND: - with self.lock: - # check if another thread filled cache while we awaited lock - val = cache.get(self.attrname, _NOT_FOUND) - if val is _NOT_FOUND: - val = self.func(instance) - try: - cache[self.attrname] = val - except TypeError: - msg = ( - f"The '__dict__' attribute on {type(instance).__name__!r} instance " - f"does not support item assignment for caching {self.attrname!r} property." - ) - raise TypeError(msg) from None - return val - - __class_getitem__ = classmethod(GenericAlias) diff --git a/python/Lib/genericpath.py b/python/Lib/genericpath.py deleted file mode 100644 index 546ffb0..0000000 --- a/python/Lib/genericpath.py +++ /dev/null @@ -1,155 +0,0 @@ -""" -Path operations common to more than one OS -Do not use directly. The OS specific modules import the appropriate -functions from this module themselves. -""" -import os -import stat - -__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime', - 'getsize', 'isdir', 'isfile', 'samefile', 'sameopenfile', - 'samestat'] - - -# Does a path exist? -# This is false for dangling symbolic links on systems that support them. -def exists(path): - """Test whether a path exists. Returns False for broken symbolic links""" - try: - os.stat(path) - except (OSError, ValueError): - return False - return True - - -# This follows symbolic links, so both islink() and isdir() can be true -# for the same path on systems that support symlinks -def isfile(path): - """Test whether a path is a regular file""" - try: - st = os.stat(path) - except (OSError, ValueError): - return False - return stat.S_ISREG(st.st_mode) - - -# Is a path a directory? -# This follows symbolic links, so both islink() and isdir() -# can be true for the same path on systems that support symlinks -def isdir(s): - """Return true if the pathname refers to an existing directory.""" - try: - st = os.stat(s) - except (OSError, ValueError): - return False - return stat.S_ISDIR(st.st_mode) - - -def getsize(filename): - """Return the size of a file, reported by os.stat().""" - return os.stat(filename).st_size - - -def getmtime(filename): - """Return the last modification time of a file, reported by os.stat().""" - return os.stat(filename).st_mtime - - -def getatime(filename): - """Return the last access time of a file, reported by os.stat().""" - return os.stat(filename).st_atime - - -def getctime(filename): - """Return the metadata change time of a file, reported by os.stat().""" - return os.stat(filename).st_ctime - - -# Return the longest prefix of all list elements. -def commonprefix(m): - "Given a list of pathnames, returns the longest common leading component" - if not m: return '' - # Some people pass in a list of pathname parts to operate in an OS-agnostic - # fashion; don't try to translate in that case as that's an abuse of the - # API and they are already doing what they need to be OS-agnostic and so - # they most likely won't be using an os.PathLike object in the sublists. - if not isinstance(m[0], (list, tuple)): - m = tuple(map(os.fspath, m)) - s1 = min(m) - s2 = max(m) - for i, c in enumerate(s1): - if c != s2[i]: - return s1[:i] - return s1 - -# Are two stat buffers (obtained from stat, fstat or lstat) -# describing the same file? -def samestat(s1, s2): - """Test whether two stat buffers reference the same file""" - return (s1.st_ino == s2.st_ino and - s1.st_dev == s2.st_dev) - - -# Are two filenames really pointing to the same file? -def samefile(f1, f2): - """Test whether two pathnames reference the same actual file or directory - - This is determined by the device number and i-node number and - raises an exception if an os.stat() call on either pathname fails. - """ - s1 = os.stat(f1) - s2 = os.stat(f2) - return samestat(s1, s2) - - -# Are two open files really referencing the same file? -# (Not necessarily the same file descriptor!) -def sameopenfile(fp1, fp2): - """Test whether two open file objects reference the same file""" - s1 = os.fstat(fp1) - s2 = os.fstat(fp2) - return samestat(s1, s2) - - -# Split a path in root and extension. -# The extension is everything starting at the last dot in the last -# pathname component; the root is everything before that. -# It is always true that root + ext == p. - -# Generic implementation of splitext, to be parametrized with -# the separators -def _splitext(p, sep, altsep, extsep): - """Split the extension from a pathname. - - Extension is everything from the last dot to the end, ignoring - leading dots. Returns "(root, ext)"; ext may be empty.""" - # NOTE: This code must work for text and bytes strings. - - sepIndex = p.rfind(sep) - if altsep: - altsepIndex = p.rfind(altsep) - sepIndex = max(sepIndex, altsepIndex) - - dotIndex = p.rfind(extsep) - if dotIndex > sepIndex: - # skip all leading dots - filenameIndex = sepIndex + 1 - while filenameIndex < dotIndex: - if p[filenameIndex:filenameIndex+1] != extsep: - return p[:dotIndex], p[dotIndex:] - filenameIndex += 1 - - return p, p[:0] - -def _check_arg_types(funcname, *args): - hasstr = hasbytes = False - for s in args: - if isinstance(s, str): - hasstr = True - elif isinstance(s, bytes): - hasbytes = True - else: - raise TypeError(f'{funcname}() argument must be str, bytes, or ' - f'os.PathLike object, not {s.__class__.__name__!r}') from None - if hasstr and hasbytes: - raise TypeError("Can't mix strings and bytes in path components") from None diff --git a/python/Lib/getopt.py b/python/Lib/getopt.py deleted file mode 100644 index e533efc..0000000 --- a/python/Lib/getopt.py +++ /dev/null @@ -1,215 +0,0 @@ -"""Parser for command line options. - -This module helps scripts to parse the command line arguments in -sys.argv. It supports the same conventions as the Unix getopt() -function (including the special meanings of arguments of the form `-' -and `--'). Long options similar to those supported by GNU software -may be used as well via an optional third argument. This module -provides two functions and an exception: - -getopt() -- Parse command line options -gnu_getopt() -- Like getopt(), but allow option and non-option arguments -to be intermixed. -GetoptError -- exception (class) raised with 'opt' attribute, which is the -option involved with the exception. -""" - -# Long option support added by Lars Wirzenius . -# -# Gerrit Holl moved the string-based exceptions -# to class-based exceptions. -# -# Peter Åstrand added gnu_getopt(). -# -# TODO for gnu_getopt(): -# -# - GNU getopt_long_only mechanism -# - allow the caller to specify ordering -# - RETURN_IN_ORDER option -# - GNU extension with '-' as first character of option string -# - optional arguments, specified by double colons -# - an option string with a W followed by semicolon should -# treat "-W foo" as "--foo" - -__all__ = ["GetoptError","error","getopt","gnu_getopt"] - -import os -try: - from gettext import gettext as _ -except ImportError: - # Bootstrapping Python: gettext's dependencies not built yet - def _(s): return s - -class GetoptError(Exception): - opt = '' - msg = '' - def __init__(self, msg, opt=''): - self.msg = msg - self.opt = opt - Exception.__init__(self, msg, opt) - - def __str__(self): - return self.msg - -error = GetoptError # backward compatibility - -def getopt(args, shortopts, longopts = []): - """getopt(args, options[, long_options]) -> opts, args - - Parses command line options and parameter list. args is the - argument list to be parsed, without the leading reference to the - running program. Typically, this means "sys.argv[1:]". shortopts - is the string of option letters that the script wants to - recognize, with options that require an argument followed by a - colon (i.e., the same format that Unix getopt() uses). If - specified, longopts is a list of strings with the names of the - long options which should be supported. The leading '--' - characters should not be included in the option name. Options - which require an argument should be followed by an equal sign - ('='). - - The return value consists of two elements: the first is a list of - (option, value) pairs; the second is the list of program arguments - left after the option list was stripped (this is a trailing slice - of the first argument). Each option-and-value pair returned has - the option as its first element, prefixed with a hyphen (e.g., - '-x'), and the option argument as its second element, or an empty - string if the option has no argument. The options occur in the - list in the same order in which they were found, thus allowing - multiple occurrences. Long and short options may be mixed. - - """ - - opts = [] - if type(longopts) == type(""): - longopts = [longopts] - else: - longopts = list(longopts) - while args and args[0].startswith('-') and args[0] != '-': - if args[0] == '--': - args = args[1:] - break - if args[0].startswith('--'): - opts, args = do_longs(opts, args[0][2:], longopts, args[1:]) - else: - opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:]) - - return opts, args - -def gnu_getopt(args, shortopts, longopts = []): - """getopt(args, options[, long_options]) -> opts, args - - This function works like getopt(), except that GNU style scanning - mode is used by default. This means that option and non-option - arguments may be intermixed. The getopt() function stops - processing options as soon as a non-option argument is - encountered. - - If the first character of the option string is `+', or if the - environment variable POSIXLY_CORRECT is set, then option - processing stops as soon as a non-option argument is encountered. - - """ - - opts = [] - prog_args = [] - if isinstance(longopts, str): - longopts = [longopts] - else: - longopts = list(longopts) - - # Allow options after non-option arguments? - if shortopts.startswith('+'): - shortopts = shortopts[1:] - all_options_first = True - elif os.environ.get("POSIXLY_CORRECT"): - all_options_first = True - else: - all_options_first = False - - while args: - if args[0] == '--': - prog_args += args[1:] - break - - if args[0][:2] == '--': - opts, args = do_longs(opts, args[0][2:], longopts, args[1:]) - elif args[0][:1] == '-' and args[0] != '-': - opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:]) - else: - if all_options_first: - prog_args += args - break - else: - prog_args.append(args[0]) - args = args[1:] - - return opts, prog_args - -def do_longs(opts, opt, longopts, args): - try: - i = opt.index('=') - except ValueError: - optarg = None - else: - opt, optarg = opt[:i], opt[i+1:] - - has_arg, opt = long_has_args(opt, longopts) - if has_arg: - if optarg is None: - if not args: - raise GetoptError(_('option --%s requires argument') % opt, opt) - optarg, args = args[0], args[1:] - elif optarg is not None: - raise GetoptError(_('option --%s must not have an argument') % opt, opt) - opts.append(('--' + opt, optarg or '')) - return opts, args - -# Return: -# has_arg? -# full option name -def long_has_args(opt, longopts): - possibilities = [o for o in longopts if o.startswith(opt)] - if not possibilities: - raise GetoptError(_('option --%s not recognized') % opt, opt) - # Is there an exact match? - if opt in possibilities: - return False, opt - elif opt + '=' in possibilities: - return True, opt - # No exact match, so better be unique. - if len(possibilities) > 1: - # XXX since possibilities contains all valid continuations, might be - # nice to work them into the error msg - raise GetoptError(_('option --%s not a unique prefix') % opt, opt) - assert len(possibilities) == 1 - unique_match = possibilities[0] - has_arg = unique_match.endswith('=') - if has_arg: - unique_match = unique_match[:-1] - return has_arg, unique_match - -def do_shorts(opts, optstring, shortopts, args): - while optstring != '': - opt, optstring = optstring[0], optstring[1:] - if short_has_arg(opt, shortopts): - if optstring == '': - if not args: - raise GetoptError(_('option -%s requires argument') % opt, - opt) - optstring, args = args[0], args[1:] - optarg, optstring = optstring, '' - else: - optarg = '' - opts.append(('-' + opt, optarg)) - return opts, args - -def short_has_arg(opt, shortopts): - for i in range(len(shortopts)): - if opt == shortopts[i] != ':': - return shortopts.startswith(':', i+1) - raise GetoptError(_('option -%s not recognized') % opt, opt) - -if __name__ == '__main__': - import sys - print(getopt(sys.argv[1:], "a:b", ["alpha=", "beta"])) diff --git a/python/Lib/getpass.py b/python/Lib/getpass.py deleted file mode 100644 index 09b2156..0000000 --- a/python/Lib/getpass.py +++ /dev/null @@ -1,185 +0,0 @@ -"""Utilities to get a password and/or the current user name. - -getpass(prompt[, stream]) - Prompt for a password, with echo turned off. -getuser() - Get the user name from the environment or password database. - -GetPassWarning - This UserWarning is issued when getpass() cannot prevent - echoing of the password contents while reading. - -On Windows, the msvcrt module will be used. - -""" - -# Authors: Piers Lauder (original) -# Guido van Rossum (Windows support and cleanup) -# Gregory P. Smith (tty support & GetPassWarning) - -import contextlib -import io -import os -import sys -import warnings - -__all__ = ["getpass","getuser","GetPassWarning"] - - -class GetPassWarning(UserWarning): pass - - -def unix_getpass(prompt='Password: ', stream=None): - """Prompt for a password, with echo turned off. - - Args: - prompt: Written on stream to ask for the input. Default: 'Password: ' - stream: A writable file object to display the prompt. Defaults to - the tty. If no tty is available defaults to sys.stderr. - Returns: - The seKr3t input. - Raises: - EOFError: If our input tty or stdin was closed. - GetPassWarning: When we were unable to turn echo off on the input. - - Always restores terminal settings before returning. - """ - passwd = None - with contextlib.ExitStack() as stack: - try: - # Always try reading and writing directly on the tty first. - fd = os.open('/dev/tty', os.O_RDWR|os.O_NOCTTY) - tty = io.FileIO(fd, 'w+') - stack.enter_context(tty) - input = io.TextIOWrapper(tty) - stack.enter_context(input) - if not stream: - stream = input - except OSError: - # If that fails, see if stdin can be controlled. - stack.close() - try: - fd = sys.stdin.fileno() - except (AttributeError, ValueError): - fd = None - passwd = fallback_getpass(prompt, stream) - input = sys.stdin - if not stream: - stream = sys.stderr - - if fd is not None: - try: - old = termios.tcgetattr(fd) # a copy to save - new = old[:] - new[3] &= ~termios.ECHO # 3 == 'lflags' - tcsetattr_flags = termios.TCSAFLUSH - if hasattr(termios, 'TCSASOFT'): - tcsetattr_flags |= termios.TCSASOFT - try: - termios.tcsetattr(fd, tcsetattr_flags, new) - passwd = _raw_input(prompt, stream, input=input) - finally: - termios.tcsetattr(fd, tcsetattr_flags, old) - stream.flush() # issue7208 - except termios.error: - if passwd is not None: - # _raw_input succeeded. The final tcsetattr failed. Reraise - # instead of leaving the terminal in an unknown state. - raise - # We can't control the tty or stdin. Give up and use normal IO. - # fallback_getpass() raises an appropriate warning. - if stream is not input: - # clean up unused file objects before blocking - stack.close() - passwd = fallback_getpass(prompt, stream) - - stream.write('\n') - return passwd - - -def win_getpass(prompt='Password: ', stream=None): - """Prompt for password with echo off, using Windows getwch().""" - if sys.stdin is not sys.__stdin__: - return fallback_getpass(prompt, stream) - - for c in prompt: - msvcrt.putwch(c) - pw = "" - while 1: - c = msvcrt.getwch() - if c == '\r' or c == '\n': - break - if c == '\003': - raise KeyboardInterrupt - if c == '\b': - pw = pw[:-1] - else: - pw = pw + c - msvcrt.putwch('\r') - msvcrt.putwch('\n') - return pw - - -def fallback_getpass(prompt='Password: ', stream=None): - warnings.warn("Can not control echo on the terminal.", GetPassWarning, - stacklevel=2) - if not stream: - stream = sys.stderr - print("Warning: Password input may be echoed.", file=stream) - return _raw_input(prompt, stream) - - -def _raw_input(prompt="", stream=None, input=None): - # This doesn't save the string in the GNU readline history. - if not stream: - stream = sys.stderr - if not input: - input = sys.stdin - prompt = str(prompt) - if prompt: - try: - stream.write(prompt) - except UnicodeEncodeError: - # Use replace error handler to get as much as possible printed. - prompt = prompt.encode(stream.encoding, 'replace') - prompt = prompt.decode(stream.encoding) - stream.write(prompt) - stream.flush() - # NOTE: The Python C API calls flockfile() (and unlock) during readline. - line = input.readline() - if not line: - raise EOFError - if line[-1] == '\n': - line = line[:-1] - return line - - -def getuser(): - """Get the username from the environment or password database. - - First try various environment variables, then the password - database. This works on Windows as long as USERNAME is set. - - """ - - for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'): - user = os.environ.get(name) - if user: - return user - - # If this fails, the exception will "explain" why - import pwd - return pwd.getpwuid(os.getuid())[0] - -# Bind the name getpass to the appropriate function -try: - import termios - # it's possible there is an incompatible termios from the - # McMillan Installer, make sure we have a UNIX-compatible termios - termios.tcgetattr, termios.tcsetattr -except (ImportError, AttributeError): - try: - import msvcrt - except ImportError: - getpass = fallback_getpass - else: - getpass = win_getpass -else: - getpass = unix_getpass diff --git a/python/Lib/gettext.py b/python/Lib/gettext.py deleted file mode 100644 index 6e77ab4..0000000 --- a/python/Lib/gettext.py +++ /dev/null @@ -1,634 +0,0 @@ -"""Internationalization and localization support. - -This module provides internationalization (I18N) and localization (L10N) -support for your Python programs by providing an interface to the GNU gettext -message catalog library. - -I18N refers to the operation by which a program is made aware of multiple -languages. L10N refers to the adaptation of your program, once -internationalized, to the local language and cultural habits. - -""" - -# This module represents the integration of work, contributions, feedback, and -# suggestions from the following people: -# -# Martin von Loewis, who wrote the initial implementation of the underlying -# C-based libintlmodule (later renamed _gettext), along with a skeletal -# gettext.py implementation. -# -# Peter Funk, who wrote fintl.py, a fairly complete wrapper around intlmodule, -# which also included a pure-Python implementation to read .mo files if -# intlmodule wasn't available. -# -# James Henstridge, who also wrote a gettext.py module, which has some -# interesting, but currently unsupported experimental features: the notion of -# a Catalog class and instances, and the ability to add to a catalog file via -# a Python API. -# -# Barry Warsaw integrated these modules, wrote the .install() API and code, -# and conformed all C and Python code to Python's coding standards. -# -# Francois Pinard and Marc-Andre Lemburg also contributed valuably to this -# module. -# -# J. David Ibanez implemented plural forms. Bruno Haible fixed some bugs. -# -# TODO: -# - Lazy loading of .mo files. Currently the entire catalog is loaded into -# memory, but that's probably bad for large translated programs. Instead, -# the lexical sort of original strings in GNU .mo files should be exploited -# to do binary searches and lazy initializations. Or you might want to use -# the undocumented double-hash algorithm for .mo files with hash tables, but -# you'll need to study the GNU gettext code to do this. -# -# - Support Solaris .mo file formats. Unfortunately, we've been unable to -# find this format documented anywhere. - - -import os -import re -import sys - - -__all__ = ['NullTranslations', 'GNUTranslations', 'Catalog', - 'bindtextdomain', 'find', 'translation', 'install', - 'textdomain', 'dgettext', 'dngettext', 'gettext', - 'ngettext', 'pgettext', 'dpgettext', 'npgettext', - 'dnpgettext' - ] - -_default_localedir = os.path.join(sys.base_prefix, 'share', 'locale') - -# Expression parsing for plural form selection. -# -# The gettext library supports a small subset of C syntax. The only -# incompatible difference is that integer literals starting with zero are -# decimal. -# -# https://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms -# http://git.savannah.gnu.org/cgit/gettext.git/tree/gettext-runtime/intl/plural.y - -_token_pattern = re.compile(r""" - (?P[ \t]+) | # spaces and horizontal tabs - (?P[0-9]+\b) | # decimal integer - (?Pn\b) | # only n is allowed - (?P[()]) | - (?P[-*/%+?:]|[>, - # <=, >=, ==, !=, &&, ||, - # ? : - # unary and bitwise ops - # not allowed - (?P\w+|.) # invalid token - """, re.VERBOSE|re.DOTALL) - - -def _tokenize(plural): - for mo in re.finditer(_token_pattern, plural): - kind = mo.lastgroup - if kind == 'WHITESPACES': - continue - value = mo.group(kind) - if kind == 'INVALID': - raise ValueError('invalid token in plural form: %s' % value) - yield value - yield '' - - -def _error(value): - if value: - return ValueError('unexpected token in plural form: %s' % value) - else: - return ValueError('unexpected end of plural form') - - -_binary_ops = ( - ('||',), - ('&&',), - ('==', '!='), - ('<', '>', '<=', '>='), - ('+', '-'), - ('*', '/', '%'), -) -_binary_ops = {op: i for i, ops in enumerate(_binary_ops, 1) for op in ops} -_c2py_ops = {'||': 'or', '&&': 'and', '/': '//'} - - -def _parse(tokens, priority=-1): - result = '' - nexttok = next(tokens) - while nexttok == '!': - result += 'not ' - nexttok = next(tokens) - - if nexttok == '(': - sub, nexttok = _parse(tokens) - result = '%s(%s)' % (result, sub) - if nexttok != ')': - raise ValueError('unbalanced parenthesis in plural form') - elif nexttok == 'n': - result = '%s%s' % (result, nexttok) - else: - try: - value = int(nexttok, 10) - except ValueError: - raise _error(nexttok) from None - result = '%s%d' % (result, value) - nexttok = next(tokens) - - j = 100 - while nexttok in _binary_ops: - i = _binary_ops[nexttok] - if i < priority: - break - # Break chained comparisons - if i in (3, 4) and j in (3, 4): # '==', '!=', '<', '>', '<=', '>=' - result = '(%s)' % result - # Replace some C operators by their Python equivalents - op = _c2py_ops.get(nexttok, nexttok) - right, nexttok = _parse(tokens, i + 1) - result = '%s %s %s' % (result, op, right) - j = i - if j == priority == 4: # '<', '>', '<=', '>=' - result = '(%s)' % result - - if nexttok == '?' and priority <= 0: - if_true, nexttok = _parse(tokens, 0) - if nexttok != ':': - raise _error(nexttok) - if_false, nexttok = _parse(tokens) - result = '%s if %s else %s' % (if_true, result, if_false) - if priority == 0: - result = '(%s)' % result - - return result, nexttok - - -def _as_int(n): - try: - i = round(n) - except TypeError: - raise TypeError('Plural value must be an integer, got %s' % - (n.__class__.__name__,)) from None - import warnings - warnings.warn('Plural value must be an integer, got %s' % - (n.__class__.__name__,), - DeprecationWarning, 4) - return n - - -def c2py(plural): - """Gets a C expression as used in PO files for plural forms and returns a - Python function that implements an equivalent expression. - """ - - if len(plural) > 1000: - raise ValueError('plural form expression is too long') - try: - result, nexttok = _parse(_tokenize(plural)) - if nexttok: - raise _error(nexttok) - - depth = 0 - for c in result: - if c == '(': - depth += 1 - if depth > 20: - # Python compiler limit is about 90. - # The most complex example has 2. - raise ValueError('plural form expression is too complex') - elif c == ')': - depth -= 1 - - ns = {'_as_int': _as_int} - exec('''if True: - def func(n): - if not isinstance(n, int): - n = _as_int(n) - return int(%s) - ''' % result, ns) - return ns['func'] - except RecursionError: - # Recursion error can be raised in _parse() or exec(). - raise ValueError('plural form expression is too complex') - - -def _expand_lang(loc): - import locale - loc = locale.normalize(loc) - COMPONENT_CODESET = 1 << 0 - COMPONENT_TERRITORY = 1 << 1 - COMPONENT_MODIFIER = 1 << 2 - # split up the locale into its base components - mask = 0 - pos = loc.find('@') - if pos >= 0: - modifier = loc[pos:] - loc = loc[:pos] - mask |= COMPONENT_MODIFIER - else: - modifier = '' - pos = loc.find('.') - if pos >= 0: - codeset = loc[pos:] - loc = loc[:pos] - mask |= COMPONENT_CODESET - else: - codeset = '' - pos = loc.find('_') - if pos >= 0: - territory = loc[pos:] - loc = loc[:pos] - mask |= COMPONENT_TERRITORY - else: - territory = '' - language = loc - ret = [] - for i in range(mask+1): - if not (i & ~mask): # if all components for this combo exist ... - val = language - if i & COMPONENT_TERRITORY: val += territory - if i & COMPONENT_CODESET: val += codeset - if i & COMPONENT_MODIFIER: val += modifier - ret.append(val) - ret.reverse() - return ret - - -class NullTranslations: - def __init__(self, fp=None): - self._info = {} - self._charset = None - self._fallback = None - if fp is not None: - self._parse(fp) - - def _parse(self, fp): - pass - - def add_fallback(self, fallback): - if self._fallback: - self._fallback.add_fallback(fallback) - else: - self._fallback = fallback - - def gettext(self, message): - if self._fallback: - return self._fallback.gettext(message) - return message - - def ngettext(self, msgid1, msgid2, n): - if self._fallback: - return self._fallback.ngettext(msgid1, msgid2, n) - if n == 1: - return msgid1 - else: - return msgid2 - - def pgettext(self, context, message): - if self._fallback: - return self._fallback.pgettext(context, message) - return message - - def npgettext(self, context, msgid1, msgid2, n): - if self._fallback: - return self._fallback.npgettext(context, msgid1, msgid2, n) - if n == 1: - return msgid1 - else: - return msgid2 - - def info(self): - return self._info - - def charset(self): - return self._charset - - def install(self, names=None): - import builtins - builtins.__dict__['_'] = self.gettext - if names is not None: - allowed = {'gettext', 'ngettext', 'npgettext', 'pgettext'} - for name in allowed & set(names): - builtins.__dict__[name] = getattr(self, name) - - -class GNUTranslations(NullTranslations): - # Magic number of .mo files - LE_MAGIC = 0x950412de - BE_MAGIC = 0xde120495 - - # The encoding of a msgctxt and a msgid in a .mo file is - # msgctxt + "\x04" + msgid (gettext version >= 0.15) - CONTEXT = "%s\x04%s" - - # Acceptable .mo versions - VERSIONS = (0, 1) - - def _get_versions(self, version): - """Returns a tuple of major version, minor version""" - return (version >> 16, version & 0xffff) - - def _parse(self, fp): - """Override this method to support alternative .mo formats.""" - # Delay struct import for speeding up gettext import when .mo files - # are not used. - from struct import unpack - filename = getattr(fp, 'name', '') - # Parse the .mo file header, which consists of 5 little endian 32 - # bit words. - self._catalog = catalog = {} - self.plural = lambda n: int(n != 1) # germanic plural by default - buf = fp.read() - buflen = len(buf) - # Are we big endian or little endian? - magic = unpack('4I', buf[4:20]) - ii = '>II' - else: - raise OSError(0, 'Bad magic number', filename) - - major_version, minor_version = self._get_versions(version) - - if major_version not in self.VERSIONS: - raise OSError(0, 'Bad version number ' + str(major_version), filename) - - # Now put all messages from the .mo file buffer into the catalog - # dictionary. - for i in range(0, msgcount): - mlen, moff = unpack(ii, buf[masteridx:masteridx+8]) - mend = moff + mlen - tlen, toff = unpack(ii, buf[transidx:transidx+8]) - tend = toff + tlen - if mend < buflen and tend < buflen: - msg = buf[moff:mend] - tmsg = buf[toff:tend] - else: - raise OSError(0, 'File is corrupt', filename) - # See if we're looking at GNU .mo conventions for metadata - if mlen == 0: - # Catalog description - lastk = None - for b_item in tmsg.split(b'\n'): - item = b_item.decode().strip() - if not item: - continue - # Skip over comment lines: - if item.startswith('#-#-#-#-#') and item.endswith('#-#-#-#-#'): - continue - k = v = None - if ':' in item: - k, v = item.split(':', 1) - k = k.strip().lower() - v = v.strip() - self._info[k] = v - lastk = k - elif lastk: - self._info[lastk] += '\n' + item - if k == 'content-type': - self._charset = v.split('charset=')[1] - elif k == 'plural-forms': - v = v.split(';') - plural = v[1].split('plural=')[1] - self.plural = c2py(plural) - # Note: we unconditionally convert both msgids and msgstrs to - # Unicode using the character encoding specified in the charset - # parameter of the Content-Type header. The gettext documentation - # strongly encourages msgids to be us-ascii, but some applications - # require alternative encodings (e.g. Zope's ZCML and ZPT). For - # traditional gettext applications, the msgid conversion will - # cause no problems since us-ascii should always be a subset of - # the charset encoding. We may want to fall back to 8-bit msgids - # if the Unicode conversion fails. - charset = self._charset or 'ascii' - if b'\x00' in msg: - # Plural forms - msgid1, msgid2 = msg.split(b'\x00') - tmsg = tmsg.split(b'\x00') - msgid1 = str(msgid1, charset) - for i, x in enumerate(tmsg): - catalog[(msgid1, i)] = str(x, charset) - else: - catalog[str(msg, charset)] = str(tmsg, charset) - # advance to next entry in the seek tables - masteridx += 8 - transidx += 8 - - def gettext(self, message): - missing = object() - tmsg = self._catalog.get(message, missing) - if tmsg is missing: - if self._fallback: - return self._fallback.gettext(message) - return message - return tmsg - - def ngettext(self, msgid1, msgid2, n): - try: - tmsg = self._catalog[(msgid1, self.plural(n))] - except KeyError: - if self._fallback: - return self._fallback.ngettext(msgid1, msgid2, n) - if n == 1: - tmsg = msgid1 - else: - tmsg = msgid2 - return tmsg - - def pgettext(self, context, message): - ctxt_msg_id = self.CONTEXT % (context, message) - missing = object() - tmsg = self._catalog.get(ctxt_msg_id, missing) - if tmsg is missing: - if self._fallback: - return self._fallback.pgettext(context, message) - return message - return tmsg - - def npgettext(self, context, msgid1, msgid2, n): - ctxt_msg_id = self.CONTEXT % (context, msgid1) - try: - tmsg = self._catalog[ctxt_msg_id, self.plural(n)] - except KeyError: - if self._fallback: - return self._fallback.npgettext(context, msgid1, msgid2, n) - if n == 1: - tmsg = msgid1 - else: - tmsg = msgid2 - return tmsg - - -# Locate a .mo file using the gettext strategy -def find(domain, localedir=None, languages=None, all=False): - # Get some reasonable defaults for arguments that were not supplied - if localedir is None: - localedir = _default_localedir - if languages is None: - languages = [] - for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'): - val = os.environ.get(envar) - if val: - languages = val.split(':') - break - if 'C' not in languages: - languages.append('C') - # now normalize and expand the languages - nelangs = [] - for lang in languages: - for nelang in _expand_lang(lang): - if nelang not in nelangs: - nelangs.append(nelang) - # select a language - if all: - result = [] - else: - result = None - for lang in nelangs: - if lang == 'C': - break - mofile = os.path.join(localedir, lang, 'LC_MESSAGES', '%s.mo' % domain) - if os.path.exists(mofile): - if all: - result.append(mofile) - else: - return mofile - return result - - -# a mapping between absolute .mo file path and Translation object -_translations = {} - - -def translation(domain, localedir=None, languages=None, - class_=None, fallback=False): - if class_ is None: - class_ = GNUTranslations - mofiles = find(domain, localedir, languages, all=True) - if not mofiles: - if fallback: - return NullTranslations() - from errno import ENOENT - raise FileNotFoundError(ENOENT, - 'No translation file found for domain', domain) - # Avoid opening, reading, and parsing the .mo file after it's been done - # once. - result = None - for mofile in mofiles: - key = (class_, os.path.abspath(mofile)) - t = _translations.get(key) - if t is None: - with open(mofile, 'rb') as fp: - t = _translations.setdefault(key, class_(fp)) - # Copy the translation object to allow setting fallbacks and - # output charset. All other instance data is shared with the - # cached object. - # Delay copy import for speeding up gettext import when .mo files - # are not used. - import copy - t = copy.copy(t) - if result is None: - result = t - else: - result.add_fallback(t) - return result - - -def install(domain, localedir=None, *, names=None): - t = translation(domain, localedir, fallback=True) - t.install(names) - - -# a mapping b/w domains and locale directories -_localedirs = {} -# current global domain, `messages' used for compatibility w/ GNU gettext -_current_domain = 'messages' - - -def textdomain(domain=None): - global _current_domain - if domain is not None: - _current_domain = domain - return _current_domain - - -def bindtextdomain(domain, localedir=None): - global _localedirs - if localedir is not None: - _localedirs[domain] = localedir - return _localedirs.get(domain, _default_localedir) - - -def dgettext(domain, message): - try: - t = translation(domain, _localedirs.get(domain, None)) - except OSError: - return message - return t.gettext(message) - - -def dngettext(domain, msgid1, msgid2, n): - try: - t = translation(domain, _localedirs.get(domain, None)) - except OSError: - if n == 1: - return msgid1 - else: - return msgid2 - return t.ngettext(msgid1, msgid2, n) - - -def dpgettext(domain, context, message): - try: - t = translation(domain, _localedirs.get(domain, None)) - except OSError: - return message - return t.pgettext(context, message) - - -def dnpgettext(domain, context, msgid1, msgid2, n): - try: - t = translation(domain, _localedirs.get(domain, None)) - except OSError: - if n == 1: - return msgid1 - else: - return msgid2 - return t.npgettext(context, msgid1, msgid2, n) - - -def gettext(message): - return dgettext(_current_domain, message) - - -def ngettext(msgid1, msgid2, n): - return dngettext(_current_domain, msgid1, msgid2, n) - - -def pgettext(context, message): - return dpgettext(_current_domain, context, message) - - -def npgettext(context, msgid1, msgid2, n): - return dnpgettext(_current_domain, context, msgid1, msgid2, n) - - -# dcgettext() has been deemed unnecessary and is not implemented. - -# James Henstridge's Catalog constructor from GNOME gettext. Documented usage -# was: -# -# import gettext -# cat = gettext.Catalog(PACKAGE, localedir=LOCALEDIR) -# _ = cat.gettext -# print _('Hello World') - -# The resulting catalog object currently don't support access through a -# dictionary API, which was supported (but apparently unused) in GNOME -# gettext. - -Catalog = translation diff --git a/python/Lib/glob.py b/python/Lib/glob.py deleted file mode 100644 index b5d6d12..0000000 --- a/python/Lib/glob.py +++ /dev/null @@ -1,251 +0,0 @@ -"""Filename globbing utility.""" - -import contextlib -import os -import re -import fnmatch -import itertools -import stat -import sys - -__all__ = ["glob", "iglob", "escape"] - -def glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, - include_hidden=False): - """Return a list of paths matching a pathname pattern. - - The pattern may contain simple shell-style wildcards a la - fnmatch. Unlike fnmatch, filenames starting with a - dot are special cases that are not matched by '*' and '?' - patterns by default. - - If `include_hidden` is true, the patterns '*', '?', '**' will match hidden - directories. - - If `recursive` is true, the pattern '**' will match any files and - zero or more directories and subdirectories. - """ - return list(iglob(pathname, root_dir=root_dir, dir_fd=dir_fd, recursive=recursive, - include_hidden=include_hidden)) - -def iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False, - include_hidden=False): - """Return an iterator which yields the paths matching a pathname pattern. - - The pattern may contain simple shell-style wildcards a la - fnmatch. However, unlike fnmatch, filenames starting with a - dot are special cases that are not matched by '*' and '?' - patterns. - - If recursive is true, the pattern '**' will match any files and - zero or more directories and subdirectories. - """ - sys.audit("glob.glob", pathname, recursive) - sys.audit("glob.glob/2", pathname, recursive, root_dir, dir_fd) - if root_dir is not None: - root_dir = os.fspath(root_dir) - else: - root_dir = pathname[:0] - it = _iglob(pathname, root_dir, dir_fd, recursive, False, - include_hidden=include_hidden) - if not pathname or recursive and _isrecursive(pathname[:2]): - try: - s = next(it) # skip empty string - if s: - it = itertools.chain((s,), it) - except StopIteration: - pass - return it - -def _iglob(pathname, root_dir, dir_fd, recursive, dironly, - include_hidden=False): - dirname, basename = os.path.split(pathname) - if not has_magic(pathname): - assert not dironly - if basename: - if _lexists(_join(root_dir, pathname), dir_fd): - yield pathname - else: - # Patterns ending with a slash should match only directories - if _isdir(_join(root_dir, dirname), dir_fd): - yield pathname - return - if not dirname: - if recursive and _isrecursive(basename): - yield from _glob2(root_dir, basename, dir_fd, dironly, - include_hidden=include_hidden) - else: - yield from _glob1(root_dir, basename, dir_fd, dironly, - include_hidden=include_hidden) - return - # `os.path.split()` returns the argument itself as a dirname if it is a - # drive or UNC path. Prevent an infinite recursion if a drive or UNC path - # contains magic characters (i.e. r'\\?\C:'). - if dirname != pathname and has_magic(dirname): - dirs = _iglob(dirname, root_dir, dir_fd, recursive, True, - include_hidden=include_hidden) - else: - dirs = [dirname] - if has_magic(basename): - if recursive and _isrecursive(basename): - glob_in_dir = _glob2 - else: - glob_in_dir = _glob1 - else: - glob_in_dir = _glob0 - for dirname in dirs: - for name in glob_in_dir(_join(root_dir, dirname), basename, dir_fd, dironly, - include_hidden=include_hidden): - yield os.path.join(dirname, name) - -# These 2 helper functions non-recursively glob inside a literal directory. -# They return a list of basenames. _glob1 accepts a pattern while _glob0 -# takes a literal basename (so it only has to check for its existence). - -def _glob1(dirname, pattern, dir_fd, dironly, include_hidden=False): - names = _listdir(dirname, dir_fd, dironly) - if include_hidden or not _ishidden(pattern): - names = (x for x in names if include_hidden or not _ishidden(x)) - return fnmatch.filter(names, pattern) - -def _glob0(dirname, basename, dir_fd, dironly, include_hidden=False): - if basename: - if _lexists(_join(dirname, basename), dir_fd): - return [basename] - else: - # `os.path.split()` returns an empty basename for paths ending with a - # directory separator. 'q*x/' should match only directories. - if _isdir(dirname, dir_fd): - return [basename] - return [] - -# Following functions are not public but can be used by third-party code. - -def glob0(dirname, pattern): - return _glob0(dirname, pattern, None, False) - -def glob1(dirname, pattern): - return _glob1(dirname, pattern, None, False) - -# This helper function recursively yields relative pathnames inside a literal -# directory. - -def _glob2(dirname, pattern, dir_fd, dironly, include_hidden=False): - assert _isrecursive(pattern) - yield pattern[:0] - yield from _rlistdir(dirname, dir_fd, dironly, - include_hidden=include_hidden) - -# If dironly is false, yields all file names inside a directory. -# If dironly is true, yields only directory names. -def _iterdir(dirname, dir_fd, dironly): - try: - fd = None - fsencode = None - if dir_fd is not None: - if dirname: - fd = arg = os.open(dirname, _dir_open_flags, dir_fd=dir_fd) - else: - arg = dir_fd - if isinstance(dirname, bytes): - fsencode = os.fsencode - elif dirname: - arg = dirname - elif isinstance(dirname, bytes): - arg = bytes(os.curdir, 'ASCII') - else: - arg = os.curdir - try: - with os.scandir(arg) as it: - for entry in it: - try: - if not dironly or entry.is_dir(): - if fsencode is not None: - yield fsencode(entry.name) - else: - yield entry.name - except OSError: - pass - finally: - if fd is not None: - os.close(fd) - except OSError: - return - -def _listdir(dirname, dir_fd, dironly): - with contextlib.closing(_iterdir(dirname, dir_fd, dironly)) as it: - return list(it) - -# Recursively yields relative pathnames inside a literal directory. -def _rlistdir(dirname, dir_fd, dironly, include_hidden=False): - names = _listdir(dirname, dir_fd, dironly) - for x in names: - if include_hidden or not _ishidden(x): - yield x - path = _join(dirname, x) if dirname else x - for y in _rlistdir(path, dir_fd, dironly, - include_hidden=include_hidden): - yield _join(x, y) - - -def _lexists(pathname, dir_fd): - # Same as os.path.lexists(), but with dir_fd - if dir_fd is None: - return os.path.lexists(pathname) - try: - os.lstat(pathname, dir_fd=dir_fd) - except (OSError, ValueError): - return False - else: - return True - -def _isdir(pathname, dir_fd): - # Same as os.path.isdir(), but with dir_fd - if dir_fd is None: - return os.path.isdir(pathname) - try: - st = os.stat(pathname, dir_fd=dir_fd) - except (OSError, ValueError): - return False - else: - return stat.S_ISDIR(st.st_mode) - -def _join(dirname, basename): - # It is common if dirname or basename is empty - if not dirname or not basename: - return dirname or basename - return os.path.join(dirname, basename) - -magic_check = re.compile('([*?[])') -magic_check_bytes = re.compile(b'([*?[])') - -def has_magic(s): - if isinstance(s, bytes): - match = magic_check_bytes.search(s) - else: - match = magic_check.search(s) - return match is not None - -def _ishidden(path): - return path[0] in ('.', b'.'[0]) - -def _isrecursive(pattern): - if isinstance(pattern, bytes): - return pattern == b'**' - else: - return pattern == '**' - -def escape(pathname): - """Escape all special characters. - """ - # Escaping is done by wrapping any of "*?[" between square brackets. - # Metacharacters do not work in the drive part and shouldn't be escaped. - drive, pathname = os.path.splitdrive(pathname) - if isinstance(pathname, bytes): - pathname = magic_check_bytes.sub(br'[\1]', pathname) - else: - pathname = magic_check.sub(r'[\1]', pathname) - return drive + pathname - - -_dir_open_flags = os.O_RDONLY | getattr(os, 'O_DIRECTORY', 0) diff --git a/python/Lib/graphlib.py b/python/Lib/graphlib.py deleted file mode 100644 index 1decf9d..0000000 --- a/python/Lib/graphlib.py +++ /dev/null @@ -1,250 +0,0 @@ -from types import GenericAlias - -__all__ = ["TopologicalSorter", "CycleError"] - -_NODE_OUT = -1 -_NODE_DONE = -2 - - -class _NodeInfo: - __slots__ = "node", "npredecessors", "successors" - - def __init__(self, node): - # The node this class is augmenting. - self.node = node - - # Number of predecessors, generally >= 0. When this value falls to 0, - # and is returned by get_ready(), this is set to _NODE_OUT and when the - # node is marked done by a call to done(), set to _NODE_DONE. - self.npredecessors = 0 - - # List of successor nodes. The list can contain duplicated elements as - # long as they're all reflected in the successor's npredecessors attribute. - self.successors = [] - - -class CycleError(ValueError): - """Subclass of ValueError raised by TopologicalSorter.prepare if cycles - exist in the working graph. - - If multiple cycles exist, only one undefined choice among them will be reported - and included in the exception. The detected cycle can be accessed via the second - element in the *args* attribute of the exception instance and consists in a list - of nodes, such that each node is, in the graph, an immediate predecessor of the - next node in the list. In the reported list, the first and the last node will be - the same, to make it clear that it is cyclic. - """ - - pass - - -class TopologicalSorter: - """Provides functionality to topologically sort a graph of hashable nodes""" - - def __init__(self, graph=None): - self._node2info = {} - self._ready_nodes = None - self._npassedout = 0 - self._nfinished = 0 - - if graph is not None: - for node, predecessors in graph.items(): - self.add(node, *predecessors) - - def _get_nodeinfo(self, node): - if (result := self._node2info.get(node)) is None: - self._node2info[node] = result = _NodeInfo(node) - return result - - def add(self, node, *predecessors): - """Add a new node and its predecessors to the graph. - - Both the *node* and all elements in *predecessors* must be hashable. - - If called multiple times with the same node argument, the set of dependencies - will be the union of all dependencies passed in. - - It is possible to add a node with no dependencies (*predecessors* is not provided) - as well as provide a dependency twice. If a node that has not been provided before - is included among *predecessors* it will be automatically added to the graph with - no predecessors of its own. - - Raises ValueError if called after "prepare". - """ - if self._ready_nodes is not None: - raise ValueError("Nodes cannot be added after a call to prepare()") - - # Create the node -> predecessor edges - nodeinfo = self._get_nodeinfo(node) - nodeinfo.npredecessors += len(predecessors) - - # Create the predecessor -> node edges - for pred in predecessors: - pred_info = self._get_nodeinfo(pred) - pred_info.successors.append(node) - - def prepare(self): - """Mark the graph as finished and check for cycles in the graph. - - If any cycle is detected, "CycleError" will be raised, but "get_ready" can - still be used to obtain as many nodes as possible until cycles block more - progress. After a call to this function, the graph cannot be modified and - therefore no more nodes can be added using "add". - """ - if self._ready_nodes is not None: - raise ValueError("cannot prepare() more than once") - - self._ready_nodes = [ - i.node for i in self._node2info.values() if i.npredecessors == 0 - ] - # ready_nodes is set before we look for cycles on purpose: - # if the user wants to catch the CycleError, that's fine, - # they can continue using the instance to grab as many - # nodes as possible before cycles block more progress - cycle = self._find_cycle() - if cycle: - raise CycleError(f"nodes are in a cycle", cycle) - - def get_ready(self): - """Return a tuple of all the nodes that are ready. - - Initially it returns all nodes with no predecessors; once those are marked - as processed by calling "done", further calls will return all new nodes that - have all their predecessors already processed. Once no more progress can be made, - empty tuples are returned. - - Raises ValueError if called without calling "prepare" previously. - """ - if self._ready_nodes is None: - raise ValueError("prepare() must be called first") - - # Get the nodes that are ready and mark them - result = tuple(self._ready_nodes) - n2i = self._node2info - for node in result: - n2i[node].npredecessors = _NODE_OUT - - # Clean the list of nodes that are ready and update - # the counter of nodes that we have returned. - self._ready_nodes.clear() - self._npassedout += len(result) - - return result - - def is_active(self): - """Return ``True`` if more progress can be made and ``False`` otherwise. - - Progress can be made if cycles do not block the resolution and either there - are still nodes ready that haven't yet been returned by "get_ready" or the - number of nodes marked "done" is less than the number that have been returned - by "get_ready". - - Raises ValueError if called without calling "prepare" previously. - """ - if self._ready_nodes is None: - raise ValueError("prepare() must be called first") - return self._nfinished < self._npassedout or bool(self._ready_nodes) - - def __bool__(self): - return self.is_active() - - def done(self, *nodes): - """Marks a set of nodes returned by "get_ready" as processed. - - This method unblocks any successor of each node in *nodes* for being returned - in the future by a call to "get_ready". - - Raises :exec:`ValueError` if any node in *nodes* has already been marked as - processed by a previous call to this method, if a node was not added to the - graph by using "add" or if called without calling "prepare" previously or if - node has not yet been returned by "get_ready". - """ - - if self._ready_nodes is None: - raise ValueError("prepare() must be called first") - - n2i = self._node2info - - for node in nodes: - - # Check if we know about this node (it was added previously using add() - if (nodeinfo := n2i.get(node)) is None: - raise ValueError(f"node {node!r} was not added using add()") - - # If the node has not being returned (marked as ready) previously, inform the user. - stat = nodeinfo.npredecessors - if stat != _NODE_OUT: - if stat >= 0: - raise ValueError( - f"node {node!r} was not passed out (still not ready)" - ) - elif stat == _NODE_DONE: - raise ValueError(f"node {node!r} was already marked done") - else: - assert False, f"node {node!r}: unknown status {stat}" - - # Mark the node as processed - nodeinfo.npredecessors = _NODE_DONE - - # Go to all the successors and reduce the number of predecessors, collecting all the ones - # that are ready to be returned in the next get_ready() call. - for successor in nodeinfo.successors: - successor_info = n2i[successor] - successor_info.npredecessors -= 1 - if successor_info.npredecessors == 0: - self._ready_nodes.append(successor) - self._nfinished += 1 - - def _find_cycle(self): - n2i = self._node2info - stack = [] - itstack = [] - seen = set() - node2stacki = {} - - for node in n2i: - if node in seen: - continue - - while True: - if node in seen: - # If we have seen already the node and is in the - # current stack we have found a cycle. - if node in node2stacki: - return stack[node2stacki[node] :] + [node] - # else go on to get next successor - else: - seen.add(node) - itstack.append(iter(n2i[node].successors).__next__) - node2stacki[node] = len(stack) - stack.append(node) - - # Backtrack to the topmost stack entry with - # at least another successor. - while stack: - try: - node = itstack[-1]() - break - except StopIteration: - del node2stacki[stack.pop()] - itstack.pop() - else: - break - return None - - def static_order(self): - """Returns an iterable of nodes in a topological order. - - The particular order that is returned may depend on the specific - order in which the items were inserted in the graph. - - Using this method does not require to call "prepare" or "done". If any - cycle is detected, :exc:`CycleError` will be raised. - """ - self.prepare() - while self.is_active(): - node_group = self.get_ready() - yield from node_group - self.done(*node_group) - - __class_getitem__ = classmethod(GenericAlias) diff --git a/python/Lib/gzip.py b/python/Lib/gzip.py deleted file mode 100644 index 9f2d108..0000000 --- a/python/Lib/gzip.py +++ /dev/null @@ -1,668 +0,0 @@ -"""Functions that read and write gzipped files. - -The user of the file doesn't have to worry about the compression, -but random access is not allowed.""" - -# based on Andrew Kuchling's minigzip.py distributed with the zlib module - -import struct, sys, time, os -import zlib -import builtins -import io -import _compression - -__all__ = ["BadGzipFile", "GzipFile", "open", "compress", "decompress"] - -FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16 - -READ, WRITE = 1, 2 - -_COMPRESS_LEVEL_FAST = 1 -_COMPRESS_LEVEL_TRADEOFF = 6 -_COMPRESS_LEVEL_BEST = 9 - - -def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_BEST, - encoding=None, errors=None, newline=None): - """Open a gzip-compressed file in binary or text mode. - - The filename argument can be an actual filename (a str or bytes object), or - an existing file object to read from or write to. - - The mode argument can be "r", "rb", "w", "wb", "x", "xb", "a" or "ab" for - binary mode, or "rt", "wt", "xt" or "at" for text mode. The default mode is - "rb", and the default compresslevel is 9. - - For binary mode, this function is equivalent to the GzipFile constructor: - GzipFile(filename, mode, compresslevel). In this case, the encoding, errors - and newline arguments must not be provided. - - For text mode, a GzipFile object is created, and wrapped in an - io.TextIOWrapper instance with the specified encoding, error handling - behavior, and line ending(s). - - """ - if "t" in mode: - if "b" in mode: - raise ValueError("Invalid mode: %r" % (mode,)) - else: - if encoding is not None: - raise ValueError("Argument 'encoding' not supported in binary mode") - if errors is not None: - raise ValueError("Argument 'errors' not supported in binary mode") - if newline is not None: - raise ValueError("Argument 'newline' not supported in binary mode") - - gz_mode = mode.replace("t", "") - if isinstance(filename, (str, bytes, os.PathLike)): - binary_file = GzipFile(filename, gz_mode, compresslevel) - elif hasattr(filename, "read") or hasattr(filename, "write"): - binary_file = GzipFile(None, gz_mode, compresslevel, filename) - else: - raise TypeError("filename must be a str or bytes object, or a file") - - if "t" in mode: - encoding = io.text_encoding(encoding) - return io.TextIOWrapper(binary_file, encoding, errors, newline) - else: - return binary_file - -def write32u(output, value): - # The L format writes the bit pattern correctly whether signed - # or unsigned. - output.write(struct.pack("' - - def _init_write(self, filename): - self.name = filename - self.crc = zlib.crc32(b"") - self.size = 0 - self.writebuf = [] - self.bufsize = 0 - self.offset = 0 # Current file offset for seek(), tell(), etc - - def _write_gzip_header(self, compresslevel): - self.fileobj.write(b'\037\213') # magic header - self.fileobj.write(b'\010') # compression method - try: - # RFC 1952 requires the FNAME field to be Latin-1. Do not - # include filenames that cannot be represented that way. - fname = os.path.basename(self.name) - if not isinstance(fname, bytes): - fname = fname.encode('latin-1') - if fname.endswith(b'.gz'): - fname = fname[:-3] - except UnicodeEncodeError: - fname = b'' - flags = 0 - if fname: - flags = FNAME - self.fileobj.write(chr(flags).encode('latin-1')) - mtime = self._write_mtime - if mtime is None: - mtime = time.time() - write32u(self.fileobj, int(mtime)) - if compresslevel == _COMPRESS_LEVEL_BEST: - xfl = b'\002' - elif compresslevel == _COMPRESS_LEVEL_FAST: - xfl = b'\004' - else: - xfl = b'\000' - self.fileobj.write(xfl) - self.fileobj.write(b'\377') - if fname: - self.fileobj.write(fname + b'\000') - - def write(self,data): - self._check_not_closed() - if self.mode != WRITE: - import errno - raise OSError(errno.EBADF, "write() on read-only GzipFile object") - - if self.fileobj is None: - raise ValueError("write() on closed GzipFile object") - - if isinstance(data, (bytes, bytearray)): - length = len(data) - else: - # accept any data that supports the buffer protocol - data = memoryview(data) - length = data.nbytes - - if length > 0: - self.fileobj.write(self.compress.compress(data)) - self.size += length - self.crc = zlib.crc32(data, self.crc) - self.offset += length - - return length - - def read(self, size=-1): - self._check_not_closed() - if self.mode != READ: - import errno - raise OSError(errno.EBADF, "read() on write-only GzipFile object") - return self._buffer.read(size) - - def read1(self, size=-1): - """Implements BufferedIOBase.read1() - - Reads up to a buffer's worth of data if size is negative.""" - self._check_not_closed() - if self.mode != READ: - import errno - raise OSError(errno.EBADF, "read1() on write-only GzipFile object") - - if size < 0: - size = io.DEFAULT_BUFFER_SIZE - return self._buffer.read1(size) - - def peek(self, n): - self._check_not_closed() - if self.mode != READ: - import errno - raise OSError(errno.EBADF, "peek() on write-only GzipFile object") - return self._buffer.peek(n) - - @property - def closed(self): - return self.fileobj is None - - def close(self): - fileobj = self.fileobj - if fileobj is None: - return - self.fileobj = None - try: - if self.mode == WRITE: - fileobj.write(self.compress.flush()) - write32u(fileobj, self.crc) - # self.size may exceed 2 GiB, or even 4 GiB - write32u(fileobj, self.size & 0xffffffff) - elif self.mode == READ: - self._buffer.close() - finally: - myfileobj = self.myfileobj - if myfileobj: - self.myfileobj = None - myfileobj.close() - - def flush(self,zlib_mode=zlib.Z_SYNC_FLUSH): - self._check_not_closed() - if self.mode == WRITE: - # Ensure the compressor's buffer is flushed - self.fileobj.write(self.compress.flush(zlib_mode)) - self.fileobj.flush() - - def fileno(self): - """Invoke the underlying file object's fileno() method. - - This will raise AttributeError if the underlying file object - doesn't support fileno(). - """ - return self.fileobj.fileno() - - def rewind(self): - '''Return the uncompressed stream file position indicator to the - beginning of the file''' - if self.mode != READ: - raise OSError("Can't rewind in write mode") - self._buffer.seek(0) - - def readable(self): - return self.mode == READ - - def writable(self): - return self.mode == WRITE - - def seekable(self): - return True - - def seek(self, offset, whence=io.SEEK_SET): - if self.mode == WRITE: - if whence != io.SEEK_SET: - if whence == io.SEEK_CUR: - offset = self.offset + offset - else: - raise ValueError('Seek from end not supported') - if offset < self.offset: - raise OSError('Negative seek in write mode') - count = offset - self.offset - chunk = b'\0' * 1024 - for i in range(count // 1024): - self.write(chunk) - self.write(b'\0' * (count % 1024)) - elif self.mode == READ: - self._check_not_closed() - return self._buffer.seek(offset, whence) - - return self.offset - - def readline(self, size=-1): - self._check_not_closed() - return self._buffer.readline(size) - - -def _read_exact(fp, n): - '''Read exactly *n* bytes from `fp` - - This method is required because fp may be unbuffered, - i.e. return short reads. - ''' - data = fp.read(n) - while len(data) < n: - b = fp.read(n - len(data)) - if not b: - raise EOFError("Compressed file ended before the " - "end-of-stream marker was reached") - data += b - return data - - -def _read_gzip_header(fp): - '''Read a gzip header from `fp` and progress to the end of the header. - - Returns last mtime if header was present or None otherwise. - ''' - magic = fp.read(2) - if magic == b'': - return None - - if magic != b'\037\213': - raise BadGzipFile('Not a gzipped file (%r)' % magic) - - (method, flag, last_mtime) = struct.unpack(" bytes: - """ - Write a simple gzip header with no extra fields. - :param compresslevel: Compresslevel used to determine the xfl bytes. - :param mtime: The mtime (must support conversion to a 32-bit integer). - :return: A bytes object representing the gzip header. - """ - if mtime is None: - mtime = time.time() - if compresslevel == _COMPRESS_LEVEL_BEST: - xfl = 2 - elif compresslevel == _COMPRESS_LEVEL_FAST: - xfl = 4 - else: - xfl = 0 - # Pack ID1 and ID2 magic bytes, method (8=deflate), header flags (no extra - # fields added to header), mtime, xfl and os (255 for unknown OS). - return struct.pack(">> import hashlib - >>> m = hashlib.md5() - >>> m.update(b"Nobody inspects") - >>> m.update(b" the spammish repetition") - >>> m.digest() - b'\\xbbd\\x9c\\x83\\xdd\\x1e\\xa5\\xc9\\xd9\\xde\\xc9\\xa1\\x8d\\xf0\\xff\\xe9' - -More condensed: - - >>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest() - 'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2' - -""" - -# This tuple and __get_builtin_constructor() must be modified if a new -# always available algorithm is added. -__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', - 'blake2b', 'blake2s', - 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', - 'shake_128', 'shake_256') - - -algorithms_guaranteed = set(__always_supported) -algorithms_available = set(__always_supported) - -__all__ = __always_supported + ('new', 'algorithms_guaranteed', - 'algorithms_available', 'pbkdf2_hmac', 'file_digest') - - -__builtin_constructor_cache = {} - -# Prefer our blake2 implementation -# OpenSSL 1.1.0 comes with a limited implementation of blake2b/s. The OpenSSL -# implementations neither support keyed blake2 (blake2 MAC) nor advanced -# features like salt, personalization, or tree hashing. OpenSSL hash-only -# variants are available as 'blake2b512' and 'blake2s256', though. -__block_openssl_constructor = { - 'blake2b', 'blake2s', -} - -def __get_builtin_constructor(name): - cache = __builtin_constructor_cache - constructor = cache.get(name) - if constructor is not None: - return constructor - try: - if name in {'SHA1', 'sha1'}: - import _sha1 - cache['SHA1'] = cache['sha1'] = _sha1.sha1 - elif name in {'MD5', 'md5'}: - import _md5 - cache['MD5'] = cache['md5'] = _md5.md5 - elif name in {'SHA256', 'sha256', 'SHA224', 'sha224'}: - import _sha256 - cache['SHA224'] = cache['sha224'] = _sha256.sha224 - cache['SHA256'] = cache['sha256'] = _sha256.sha256 - elif name in {'SHA512', 'sha512', 'SHA384', 'sha384'}: - import _sha512 - cache['SHA384'] = cache['sha384'] = _sha512.sha384 - cache['SHA512'] = cache['sha512'] = _sha512.sha512 - elif name in {'blake2b', 'blake2s'}: - import _blake2 - cache['blake2b'] = _blake2.blake2b - cache['blake2s'] = _blake2.blake2s - elif name in {'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512'}: - import _sha3 - cache['sha3_224'] = _sha3.sha3_224 - cache['sha3_256'] = _sha3.sha3_256 - cache['sha3_384'] = _sha3.sha3_384 - cache['sha3_512'] = _sha3.sha3_512 - elif name in {'shake_128', 'shake_256'}: - import _sha3 - cache['shake_128'] = _sha3.shake_128 - cache['shake_256'] = _sha3.shake_256 - except ImportError: - pass # no extension module, this hash is unsupported. - - constructor = cache.get(name) - if constructor is not None: - return constructor - - raise ValueError('unsupported hash type ' + name) - - -def __get_openssl_constructor(name): - if name in __block_openssl_constructor: - # Prefer our builtin blake2 implementation. - return __get_builtin_constructor(name) - try: - # MD5, SHA1, and SHA2 are in all supported OpenSSL versions - # SHA3/shake are available in OpenSSL 1.1.1+ - f = getattr(_hashlib, 'openssl_' + name) - # Allow the C module to raise ValueError. The function will be - # defined but the hash not actually available. Don't fall back to - # builtin if the current security policy blocks a digest, bpo#40695. - f(usedforsecurity=False) - # Use the C function directly (very fast) - return f - except (AttributeError, ValueError): - return __get_builtin_constructor(name) - - -def __py_new(name, data=b'', **kwargs): - """new(name, data=b'', **kwargs) - Return a new hashing object using the - named algorithm; optionally initialized with data (which must be - a bytes-like object). - """ - return __get_builtin_constructor(name)(data, **kwargs) - - -def __hash_new(name, data=b'', **kwargs): - """new(name, data=b'') - Return a new hashing object using the named algorithm; - optionally initialized with data (which must be a bytes-like object). - """ - if name in __block_openssl_constructor: - # Prefer our builtin blake2 implementation. - return __get_builtin_constructor(name)(data, **kwargs) - try: - return _hashlib.new(name, data, **kwargs) - except ValueError: - # If the _hashlib module (OpenSSL) doesn't support the named - # hash, try using our builtin implementations. - # This allows for SHA224/256 and SHA384/512 support even though - # the OpenSSL library prior to 0.9.8 doesn't provide them. - return __get_builtin_constructor(name)(data) - - -try: - import _hashlib - new = __hash_new - __get_hash = __get_openssl_constructor - algorithms_available = algorithms_available.union( - _hashlib.openssl_md_meth_names) -except ImportError: - _hashlib = None - new = __py_new - __get_hash = __get_builtin_constructor - -try: - # OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA - from _hashlib import pbkdf2_hmac -except ImportError: - from warnings import warn as _warn - _trans_5C = bytes((x ^ 0x5C) for x in range(256)) - _trans_36 = bytes((x ^ 0x36) for x in range(256)) - - def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None): - """Password based key derivation function 2 (PKCS #5 v2.0) - - This Python implementations based on the hmac module about as fast - as OpenSSL's PKCS5_PBKDF2_HMAC for short passwords and much faster - for long passwords. - """ - _warn( - "Python implementation of pbkdf2_hmac() is deprecated.", - category=DeprecationWarning, - stacklevel=2 - ) - if not isinstance(hash_name, str): - raise TypeError(hash_name) - - if not isinstance(password, (bytes, bytearray)): - password = bytes(memoryview(password)) - if not isinstance(salt, (bytes, bytearray)): - salt = bytes(memoryview(salt)) - - # Fast inline HMAC implementation - inner = new(hash_name) - outer = new(hash_name) - blocksize = getattr(inner, 'block_size', 64) - if len(password) > blocksize: - password = new(hash_name, password).digest() - password = password + b'\x00' * (blocksize - len(password)) - inner.update(password.translate(_trans_36)) - outer.update(password.translate(_trans_5C)) - - def prf(msg, inner=inner, outer=outer): - # PBKDF2_HMAC uses the password as key. We can re-use the same - # digest objects and just update copies to skip initialization. - icpy = inner.copy() - ocpy = outer.copy() - icpy.update(msg) - ocpy.update(icpy.digest()) - return ocpy.digest() - - if iterations < 1: - raise ValueError(iterations) - if dklen is None: - dklen = outer.digest_size - if dklen < 1: - raise ValueError(dklen) - - dkey = b'' - loop = 1 - from_bytes = int.from_bytes - while len(dkey) < dklen: - prev = prf(salt + loop.to_bytes(4)) - # endianness doesn't matter here as long to / from use the same - rkey = from_bytes(prev) - for i in range(iterations - 1): - prev = prf(prev) - # rkey = rkey ^ prev - rkey ^= from_bytes(prev) - loop += 1 - dkey += rkey.to_bytes(inner.digest_size) - - return dkey[:dklen] - -try: - # OpenSSL's scrypt requires OpenSSL 1.1+ - from _hashlib import scrypt -except ImportError: - pass - - -def file_digest(fileobj, digest, /, *, _bufsize=2**18): - """Hash the contents of a file-like object. Returns a digest object. - - *fileobj* must be a file-like object opened for reading in binary mode. - It accepts file objects from open(), io.BytesIO(), and SocketIO objects. - The function may bypass Python's I/O and use the file descriptor *fileno* - directly. - - *digest* must either be a hash algorithm name as a *str*, a hash - constructor, or a callable that returns a hash object. - """ - # On Linux we could use AF_ALG sockets and sendfile() to archive zero-copy - # hashing with hardware acceleration. - if isinstance(digest, str): - digestobj = new(digest) - else: - digestobj = digest() - - if hasattr(fileobj, "getbuffer"): - # io.BytesIO object, use zero-copy buffer - digestobj.update(fileobj.getbuffer()) - return digestobj - - # Only binary files implement readinto(). - if not ( - hasattr(fileobj, "readinto") - and hasattr(fileobj, "readable") - and fileobj.readable() - ): - raise ValueError( - f"'{fileobj!r}' is not a file-like object in binary reading mode." - ) - - # binary file, socket.SocketIO object - # Note: socket I/O uses different syscalls than file I/O. - buf = bytearray(_bufsize) # Reusable buffer to reduce allocations. - view = memoryview(buf) - while True: - size = fileobj.readinto(buf) - if size == 0: - break # EOF - digestobj.update(view[:size]) - - return digestobj - - -for __func_name in __always_supported: - # try them all, some may not work due to the OpenSSL - # version not supporting that algorithm. - try: - globals()[__func_name] = __get_hash(__func_name) - except ValueError: - import logging - logging.exception('code for hash %s was not found.', __func_name) - - -# Cleanup locals() -del __always_supported, __func_name, __get_hash -del __py_new, __hash_new, __get_openssl_constructor diff --git a/python/Lib/heapq.py b/python/Lib/heapq.py deleted file mode 100644 index 517ccb7..0000000 --- a/python/Lib/heapq.py +++ /dev/null @@ -1,603 +0,0 @@ -"""Heap queue algorithm (a.k.a. priority queue). - -Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for -all k, counting elements from 0. For the sake of comparison, -non-existing elements are considered to be infinite. The interesting -property of a heap is that a[0] is always its smallest element. - -Usage: - -heap = [] # creates an empty heap -heappush(heap, item) # pushes a new item on the heap -item = heappop(heap) # pops the smallest item from the heap -item = heap[0] # smallest item on the heap without popping it -heapify(x) # transforms list into a heap, in-place, in linear time -item = heappushpop(heap, item) # pushes a new item and then returns - # the smallest item; the heap size is unchanged -item = heapreplace(heap, item) # pops and returns smallest item, and adds - # new item; the heap size is unchanged - -Our API differs from textbook heap algorithms as follows: - -- We use 0-based indexing. This makes the relationship between the - index for a node and the indexes for its children slightly less - obvious, but is more suitable since Python uses 0-based indexing. - -- Our heappop() method returns the smallest item, not the largest. - -These two make it possible to view the heap as a regular Python list -without surprises: heap[0] is the smallest item, and heap.sort() -maintains the heap invariant! -""" - -# Original code by Kevin O'Connor, augmented by Tim Peters and Raymond Hettinger - -__about__ = """Heap queues - -[explanation by François Pinard] - -Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for -all k, counting elements from 0. For the sake of comparison, -non-existing elements are considered to be infinite. The interesting -property of a heap is that a[0] is always its smallest element. - -The strange invariant above is meant to be an efficient memory -representation for a tournament. The numbers below are `k', not a[k]: - - 0 - - 1 2 - - 3 4 5 6 - - 7 8 9 10 11 12 13 14 - - 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 - - -In the tree above, each cell `k' is topping `2*k+1' and `2*k+2'. In -a usual binary tournament we see in sports, each cell is the winner -over the two cells it tops, and we can trace the winner down the tree -to see all opponents s/he had. However, in many computer applications -of such tournaments, we do not need to trace the history of a winner. -To be more memory efficient, when a winner is promoted, we try to -replace it by something else at a lower level, and the rule becomes -that a cell and the two cells it tops contain three different items, -but the top cell "wins" over the two topped cells. - -If this heap invariant is protected at all time, index 0 is clearly -the overall winner. The simplest algorithmic way to remove it and -find the "next" winner is to move some loser (let's say cell 30 in the -diagram above) into the 0 position, and then percolate this new 0 down -the tree, exchanging values, until the invariant is re-established. -This is clearly logarithmic on the total number of items in the tree. -By iterating over all items, you get an O(n ln n) sort. - -A nice feature of this sort is that you can efficiently insert new -items while the sort is going on, provided that the inserted items are -not "better" than the last 0'th element you extracted. This is -especially useful in simulation contexts, where the tree holds all -incoming events, and the "win" condition means the smallest scheduled -time. When an event schedule other events for execution, they are -scheduled into the future, so they can easily go into the heap. So, a -heap is a good structure for implementing schedulers (this is what I -used for my MIDI sequencer :-). - -Various structures for implementing schedulers have been extensively -studied, and heaps are good for this, as they are reasonably speedy, -the speed is almost constant, and the worst case is not much different -than the average case. However, there are other representations which -are more efficient overall, yet the worst cases might be terrible. - -Heaps are also very useful in big disk sorts. You most probably all -know that a big sort implies producing "runs" (which are pre-sorted -sequences, which size is usually related to the amount of CPU memory), -followed by a merging passes for these runs, which merging is often -very cleverly organised[1]. It is very important that the initial -sort produces the longest runs possible. Tournaments are a good way -to that. If, using all the memory available to hold a tournament, you -replace and percolate items that happen to fit the current run, you'll -produce runs which are twice the size of the memory for random input, -and much better for input fuzzily ordered. - -Moreover, if you output the 0'th item on disk and get an input which -may not fit in the current tournament (because the value "wins" over -the last output value), it cannot fit in the heap, so the size of the -heap decreases. The freed memory could be cleverly reused immediately -for progressively building a second heap, which grows at exactly the -same rate the first heap is melting. When the first heap completely -vanishes, you switch heaps and start a new run. Clever and quite -effective! - -In a word, heaps are useful memory structures to know. I use them in -a few applications, and I think it is good to keep a `heap' module -around. :-) - --------------------- -[1] The disk balancing algorithms which are current, nowadays, are -more annoying than clever, and this is a consequence of the seeking -capabilities of the disks. On devices which cannot seek, like big -tape drives, the story was quite different, and one had to be very -clever to ensure (far in advance) that each tape movement will be the -most effective possible (that is, will best participate at -"progressing" the merge). Some tapes were even able to read -backwards, and this was also used to avoid the rewinding time. -Believe me, real good tape sorts were quite spectacular to watch! -From all times, sorting has always been a Great Art! :-) -""" - -__all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'merge', - 'nlargest', 'nsmallest', 'heappushpop'] - -def heappush(heap, item): - """Push item onto heap, maintaining the heap invariant.""" - heap.append(item) - _siftdown(heap, 0, len(heap)-1) - -def heappop(heap): - """Pop the smallest item off the heap, maintaining the heap invariant.""" - lastelt = heap.pop() # raises appropriate IndexError if heap is empty - if heap: - returnitem = heap[0] - heap[0] = lastelt - _siftup(heap, 0) - return returnitem - return lastelt - -def heapreplace(heap, item): - """Pop and return the current smallest value, and add the new item. - - This is more efficient than heappop() followed by heappush(), and can be - more appropriate when using a fixed-size heap. Note that the value - returned may be larger than item! That constrains reasonable uses of - this routine unless written as part of a conditional replacement: - - if item > heap[0]: - item = heapreplace(heap, item) - """ - returnitem = heap[0] # raises appropriate IndexError if heap is empty - heap[0] = item - _siftup(heap, 0) - return returnitem - -def heappushpop(heap, item): - """Fast version of a heappush followed by a heappop.""" - if heap and heap[0] < item: - item, heap[0] = heap[0], item - _siftup(heap, 0) - return item - -def heapify(x): - """Transform list into a heap, in-place, in O(len(x)) time.""" - n = len(x) - # Transform bottom-up. The largest index there's any point to looking at - # is the largest with a child index in-range, so must have 2*i + 1 < n, - # or i < (n-1)/2. If n is even = 2*j, this is (2*j-1)/2 = j-1/2 so - # j-1 is the largest, which is n//2 - 1. If n is odd = 2*j+1, this is - # (2*j+1-1)/2 = j so j-1 is the largest, and that's again n//2-1. - for i in reversed(range(n//2)): - _siftup(x, i) - -def _heappop_max(heap): - """Maxheap version of a heappop.""" - lastelt = heap.pop() # raises appropriate IndexError if heap is empty - if heap: - returnitem = heap[0] - heap[0] = lastelt - _siftup_max(heap, 0) - return returnitem - return lastelt - -def _heapreplace_max(heap, item): - """Maxheap version of a heappop followed by a heappush.""" - returnitem = heap[0] # raises appropriate IndexError if heap is empty - heap[0] = item - _siftup_max(heap, 0) - return returnitem - -def _heapify_max(x): - """Transform list into a maxheap, in-place, in O(len(x)) time.""" - n = len(x) - for i in reversed(range(n//2)): - _siftup_max(x, i) - -# 'heap' is a heap at all indices >= startpos, except possibly for pos. pos -# is the index of a leaf with a possibly out-of-order value. Restore the -# heap invariant. -def _siftdown(heap, startpos, pos): - newitem = heap[pos] - # Follow the path to the root, moving parents down until finding a place - # newitem fits. - while pos > startpos: - parentpos = (pos - 1) >> 1 - parent = heap[parentpos] - if newitem < parent: - heap[pos] = parent - pos = parentpos - continue - break - heap[pos] = newitem - -# The child indices of heap index pos are already heaps, and we want to make -# a heap at index pos too. We do this by bubbling the smaller child of -# pos up (and so on with that child's children, etc) until hitting a leaf, -# then using _siftdown to move the oddball originally at index pos into place. -# -# We *could* break out of the loop as soon as we find a pos where newitem <= -# both its children, but turns out that's not a good idea, and despite that -# many books write the algorithm that way. During a heap pop, the last array -# element is sifted in, and that tends to be large, so that comparing it -# against values starting from the root usually doesn't pay (= usually doesn't -# get us out of the loop early). See Knuth, Volume 3, where this is -# explained and quantified in an exercise. -# -# Cutting the # of comparisons is important, since these routines have no -# way to extract "the priority" from an array element, so that intelligence -# is likely to be hiding in custom comparison methods, or in array elements -# storing (priority, record) tuples. Comparisons are thus potentially -# expensive. -# -# On random arrays of length 1000, making this change cut the number of -# comparisons made by heapify() a little, and those made by exhaustive -# heappop() a lot, in accord with theory. Here are typical results from 3 -# runs (3 just to demonstrate how small the variance is): -# -# Compares needed by heapify Compares needed by 1000 heappops -# -------------------------- -------------------------------- -# 1837 cut to 1663 14996 cut to 8680 -# 1855 cut to 1659 14966 cut to 8678 -# 1847 cut to 1660 15024 cut to 8703 -# -# Building the heap by using heappush() 1000 times instead required -# 2198, 2148, and 2219 compares: heapify() is more efficient, when -# you can use it. -# -# The total compares needed by list.sort() on the same lists were 8627, -# 8627, and 8632 (this should be compared to the sum of heapify() and -# heappop() compares): list.sort() is (unsurprisingly!) more efficient -# for sorting. - -def _siftup(heap, pos): - endpos = len(heap) - startpos = pos - newitem = heap[pos] - # Bubble up the smaller child until hitting a leaf. - childpos = 2*pos + 1 # leftmost child position - while childpos < endpos: - # Set childpos to index of smaller child. - rightpos = childpos + 1 - if rightpos < endpos and not heap[childpos] < heap[rightpos]: - childpos = rightpos - # Move the smaller child up. - heap[pos] = heap[childpos] - pos = childpos - childpos = 2*pos + 1 - # The leaf at pos is empty now. Put newitem there, and bubble it up - # to its final resting place (by sifting its parents down). - heap[pos] = newitem - _siftdown(heap, startpos, pos) - -def _siftdown_max(heap, startpos, pos): - 'Maxheap variant of _siftdown' - newitem = heap[pos] - # Follow the path to the root, moving parents down until finding a place - # newitem fits. - while pos > startpos: - parentpos = (pos - 1) >> 1 - parent = heap[parentpos] - if parent < newitem: - heap[pos] = parent - pos = parentpos - continue - break - heap[pos] = newitem - -def _siftup_max(heap, pos): - 'Maxheap variant of _siftup' - endpos = len(heap) - startpos = pos - newitem = heap[pos] - # Bubble up the larger child until hitting a leaf. - childpos = 2*pos + 1 # leftmost child position - while childpos < endpos: - # Set childpos to index of larger child. - rightpos = childpos + 1 - if rightpos < endpos and not heap[rightpos] < heap[childpos]: - childpos = rightpos - # Move the larger child up. - heap[pos] = heap[childpos] - pos = childpos - childpos = 2*pos + 1 - # The leaf at pos is empty now. Put newitem there, and bubble it up - # to its final resting place (by sifting its parents down). - heap[pos] = newitem - _siftdown_max(heap, startpos, pos) - -def merge(*iterables, key=None, reverse=False): - '''Merge multiple sorted inputs into a single sorted output. - - Similar to sorted(itertools.chain(*iterables)) but returns a generator, - does not pull the data into memory all at once, and assumes that each of - the input streams is already sorted (smallest to largest). - - >>> list(merge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25])) - [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] - - If *key* is not None, applies a key function to each element to determine - its sort order. - - >>> list(merge(['dog', 'horse'], ['cat', 'fish', 'kangaroo'], key=len)) - ['dog', 'cat', 'fish', 'horse', 'kangaroo'] - - ''' - - h = [] - h_append = h.append - - if reverse: - _heapify = _heapify_max - _heappop = _heappop_max - _heapreplace = _heapreplace_max - direction = -1 - else: - _heapify = heapify - _heappop = heappop - _heapreplace = heapreplace - direction = 1 - - if key is None: - for order, it in enumerate(map(iter, iterables)): - try: - next = it.__next__ - h_append([next(), order * direction, next]) - except StopIteration: - pass - _heapify(h) - while len(h) > 1: - try: - while True: - value, order, next = s = h[0] - yield value - s[0] = next() # raises StopIteration when exhausted - _heapreplace(h, s) # restore heap condition - except StopIteration: - _heappop(h) # remove empty iterator - if h: - # fast case when only a single iterator remains - value, order, next = h[0] - yield value - yield from next.__self__ - return - - for order, it in enumerate(map(iter, iterables)): - try: - next = it.__next__ - value = next() - h_append([key(value), order * direction, value, next]) - except StopIteration: - pass - _heapify(h) - while len(h) > 1: - try: - while True: - key_value, order, value, next = s = h[0] - yield value - value = next() - s[0] = key(value) - s[2] = value - _heapreplace(h, s) - except StopIteration: - _heappop(h) - if h: - key_value, order, value, next = h[0] - yield value - yield from next.__self__ - - -# Algorithm notes for nlargest() and nsmallest() -# ============================================== -# -# Make a single pass over the data while keeping the k most extreme values -# in a heap. Memory consumption is limited to keeping k values in a list. -# -# Measured performance for random inputs: -# -# number of comparisons -# n inputs k-extreme values (average of 5 trials) % more than min() -# ------------- ---------------- --------------------- ----------------- -# 1,000 100 3,317 231.7% -# 10,000 100 14,046 40.5% -# 100,000 100 105,749 5.7% -# 1,000,000 100 1,007,751 0.8% -# 10,000,000 100 10,009,401 0.1% -# -# Theoretical number of comparisons for k smallest of n random inputs: -# -# Step Comparisons Action -# ---- -------------------------- --------------------------- -# 1 1.66 * k heapify the first k-inputs -# 2 n - k compare remaining elements to top of heap -# 3 k * (1 + lg2(k)) * ln(n/k) replace the topmost value on the heap -# 4 k * lg2(k) - (k/2) final sort of the k most extreme values -# -# Combining and simplifying for a rough estimate gives: -# -# comparisons = n + k * (log(k, 2) * log(n/k) + log(k, 2) + log(n/k)) -# -# Computing the number of comparisons for step 3: -# ----------------------------------------------- -# * For the i-th new value from the iterable, the probability of being in the -# k most extreme values is k/i. For example, the probability of the 101st -# value seen being in the 100 most extreme values is 100/101. -# * If the value is a new extreme value, the cost of inserting it into the -# heap is 1 + log(k, 2). -# * The probability times the cost gives: -# (k/i) * (1 + log(k, 2)) -# * Summing across the remaining n-k elements gives: -# sum((k/i) * (1 + log(k, 2)) for i in range(k+1, n+1)) -# * This reduces to: -# (H(n) - H(k)) * k * (1 + log(k, 2)) -# * Where H(n) is the n-th harmonic number estimated by: -# gamma = 0.5772156649 -# H(n) = log(n, e) + gamma + 1 / (2 * n) -# http://en.wikipedia.org/wiki/Harmonic_series_(mathematics)#Rate_of_divergence -# * Substituting the H(n) formula: -# comparisons = k * (1 + log(k, 2)) * (log(n/k, e) + (1/n - 1/k) / 2) -# -# Worst-case for step 3: -# ---------------------- -# In the worst case, the input data is reversed sorted so that every new element -# must be inserted in the heap: -# -# comparisons = 1.66 * k + log(k, 2) * (n - k) -# -# Alternative Algorithms -# ---------------------- -# Other algorithms were not used because they: -# 1) Took much more auxiliary memory, -# 2) Made multiple passes over the data. -# 3) Made more comparisons in common cases (small k, large n, semi-random input). -# See the more detailed comparison of approach at: -# http://code.activestate.com/recipes/577573-compare-algorithms-for-heapqsmallest - -def nsmallest(n, iterable, key=None): - """Find the n smallest elements in a dataset. - - Equivalent to: sorted(iterable, key=key)[:n] - """ - - # Short-cut for n==1 is to use min() - if n == 1: - it = iter(iterable) - sentinel = object() - result = min(it, default=sentinel, key=key) - return [] if result is sentinel else [result] - - # When n>=size, it's faster to use sorted() - try: - size = len(iterable) - except (TypeError, AttributeError): - pass - else: - if n >= size: - return sorted(iterable, key=key)[:n] - - # When key is none, use simpler decoration - if key is None: - it = iter(iterable) - # put the range(n) first so that zip() doesn't - # consume one too many elements from the iterator - result = [(elem, i) for i, elem in zip(range(n), it)] - if not result: - return result - _heapify_max(result) - top = result[0][0] - order = n - _heapreplace = _heapreplace_max - for elem in it: - if elem < top: - _heapreplace(result, (elem, order)) - top, _order = result[0] - order += 1 - result.sort() - return [elem for (elem, order) in result] - - # General case, slowest method - it = iter(iterable) - result = [(key(elem), i, elem) for i, elem in zip(range(n), it)] - if not result: - return result - _heapify_max(result) - top = result[0][0] - order = n - _heapreplace = _heapreplace_max - for elem in it: - k = key(elem) - if k < top: - _heapreplace(result, (k, order, elem)) - top, _order, _elem = result[0] - order += 1 - result.sort() - return [elem for (k, order, elem) in result] - -def nlargest(n, iterable, key=None): - """Find the n largest elements in a dataset. - - Equivalent to: sorted(iterable, key=key, reverse=True)[:n] - """ - - # Short-cut for n==1 is to use max() - if n == 1: - it = iter(iterable) - sentinel = object() - result = max(it, default=sentinel, key=key) - return [] if result is sentinel else [result] - - # When n>=size, it's faster to use sorted() - try: - size = len(iterable) - except (TypeError, AttributeError): - pass - else: - if n >= size: - return sorted(iterable, key=key, reverse=True)[:n] - - # When key is none, use simpler decoration - if key is None: - it = iter(iterable) - result = [(elem, i) for i, elem in zip(range(0, -n, -1), it)] - if not result: - return result - heapify(result) - top = result[0][0] - order = -n - _heapreplace = heapreplace - for elem in it: - if top < elem: - _heapreplace(result, (elem, order)) - top, _order = result[0] - order -= 1 - result.sort(reverse=True) - return [elem for (elem, order) in result] - - # General case, slowest method - it = iter(iterable) - result = [(key(elem), i, elem) for i, elem in zip(range(0, -n, -1), it)] - if not result: - return result - heapify(result) - top = result[0][0] - order = -n - _heapreplace = heapreplace - for elem in it: - k = key(elem) - if top < k: - _heapreplace(result, (k, order, elem)) - top, _order, _elem = result[0] - order -= 1 - result.sort(reverse=True) - return [elem for (k, order, elem) in result] - -# If available, use C implementation -try: - from _heapq import * -except ImportError: - pass -try: - from _heapq import _heapreplace_max -except ImportError: - pass -try: - from _heapq import _heapify_max -except ImportError: - pass -try: - from _heapq import _heappop_max -except ImportError: - pass - - -if __name__ == "__main__": - - import doctest # pragma: no cover - print(doctest.testmod()) # pragma: no cover diff --git a/python/Lib/hmac.py b/python/Lib/hmac.py deleted file mode 100644 index 2d530a1..0000000 --- a/python/Lib/hmac.py +++ /dev/null @@ -1,219 +0,0 @@ -"""HMAC (Keyed-Hashing for Message Authentication) module. - -Implements the HMAC algorithm as described by RFC 2104. -""" - -import warnings as _warnings -try: - import _hashlib as _hashopenssl -except ImportError: - _hashopenssl = None - _functype = None - from _operator import _compare_digest as compare_digest -else: - compare_digest = _hashopenssl.compare_digest - _functype = type(_hashopenssl.openssl_sha256) # builtin type - -import hashlib as _hashlib - -trans_5C = bytes((x ^ 0x5C) for x in range(256)) -trans_36 = bytes((x ^ 0x36) for x in range(256)) - -# The size of the digests returned by HMAC depends on the underlying -# hashing module used. Use digest_size from the instance of HMAC instead. -digest_size = None - - -class HMAC: - """RFC 2104 HMAC class. Also complies with RFC 4231. - - This supports the API for Cryptographic Hash Functions (PEP 247). - """ - blocksize = 64 # 512-bit HMAC; can be changed in subclasses. - - __slots__ = ( - "_hmac", "_inner", "_outer", "block_size", "digest_size" - ) - - def __init__(self, key, msg=None, digestmod=''): - """Create a new HMAC object. - - key: bytes or buffer, key for the keyed hash object. - msg: bytes or buffer, Initial input for the hash or None. - digestmod: A hash name suitable for hashlib.new(). *OR* - A hashlib constructor returning a new hash object. *OR* - A module supporting PEP 247. - - Required as of 3.8, despite its position after the optional - msg argument. Passing it as a keyword argument is - recommended, though not required for legacy API reasons. - """ - - if not isinstance(key, (bytes, bytearray)): - raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__) - - if not digestmod: - raise TypeError("Missing required parameter 'digestmod'.") - - if _hashopenssl and isinstance(digestmod, (str, _functype)): - try: - self._init_hmac(key, msg, digestmod) - except _hashopenssl.UnsupportedDigestmodError: - self._init_old(key, msg, digestmod) - else: - self._init_old(key, msg, digestmod) - - def _init_hmac(self, key, msg, digestmod): - self._hmac = _hashopenssl.hmac_new(key, msg, digestmod=digestmod) - self.digest_size = self._hmac.digest_size - self.block_size = self._hmac.block_size - - def _init_old(self, key, msg, digestmod): - if callable(digestmod): - digest_cons = digestmod - elif isinstance(digestmod, str): - digest_cons = lambda d=b'': _hashlib.new(digestmod, d) - else: - digest_cons = lambda d=b'': digestmod.new(d) - - self._hmac = None - self._outer = digest_cons() - self._inner = digest_cons() - self.digest_size = self._inner.digest_size - - if hasattr(self._inner, 'block_size'): - blocksize = self._inner.block_size - if blocksize < 16: - _warnings.warn('block_size of %d seems too small; using our ' - 'default of %d.' % (blocksize, self.blocksize), - RuntimeWarning, 2) - blocksize = self.blocksize - else: - _warnings.warn('No block_size attribute on given digest object; ' - 'Assuming %d.' % (self.blocksize), - RuntimeWarning, 2) - blocksize = self.blocksize - - if len(key) > blocksize: - key = digest_cons(key).digest() - - # self.blocksize is the default blocksize. self.block_size is - # effective block size as well as the public API attribute. - self.block_size = blocksize - - key = key.ljust(blocksize, b'\0') - self._outer.update(key.translate(trans_5C)) - self._inner.update(key.translate(trans_36)) - if msg is not None: - self.update(msg) - - @property - def name(self): - if self._hmac: - return self._hmac.name - else: - return f"hmac-{self._inner.name}" - - def update(self, msg): - """Feed data from msg into this hashing object.""" - inst = self._hmac or self._inner - inst.update(msg) - - def copy(self): - """Return a separate copy of this hashing object. - - An update to this copy won't affect the original object. - """ - # Call __new__ directly to avoid the expensive __init__. - other = self.__class__.__new__(self.__class__) - other.digest_size = self.digest_size - if self._hmac: - other._hmac = self._hmac.copy() - other._inner = other._outer = None - else: - other._hmac = None - other._inner = self._inner.copy() - other._outer = self._outer.copy() - return other - - def _current(self): - """Return a hash object for the current state. - - To be used only internally with digest() and hexdigest(). - """ - if self._hmac: - return self._hmac - else: - h = self._outer.copy() - h.update(self._inner.digest()) - return h - - def digest(self): - """Return the hash value of this hashing object. - - This returns the hmac value as bytes. The object is - not altered in any way by this function; you can continue - updating the object after calling this function. - """ - h = self._current() - return h.digest() - - def hexdigest(self): - """Like digest(), but returns a string of hexadecimal digits instead. - """ - h = self._current() - return h.hexdigest() - -def new(key, msg=None, digestmod=''): - """Create a new hashing object and return it. - - key: bytes or buffer, The starting key for the hash. - msg: bytes or buffer, Initial input for the hash, or None. - digestmod: A hash name suitable for hashlib.new(). *OR* - A hashlib constructor returning a new hash object. *OR* - A module supporting PEP 247. - - Required as of 3.8, despite its position after the optional - msg argument. Passing it as a keyword argument is - recommended, though not required for legacy API reasons. - - You can now feed arbitrary bytes into the object using its update() - method, and can ask for the hash value at any time by calling its digest() - or hexdigest() methods. - """ - return HMAC(key, msg, digestmod) - - -def digest(key, msg, digest): - """Fast inline implementation of HMAC. - - key: bytes or buffer, The key for the keyed hash object. - msg: bytes or buffer, Input message. - digest: A hash name suitable for hashlib.new() for best performance. *OR* - A hashlib constructor returning a new hash object. *OR* - A module supporting PEP 247. - """ - if _hashopenssl is not None and isinstance(digest, (str, _functype)): - try: - return _hashopenssl.hmac_digest(key, msg, digest) - except _hashopenssl.UnsupportedDigestmodError: - pass - - if callable(digest): - digest_cons = digest - elif isinstance(digest, str): - digest_cons = lambda d=b'': _hashlib.new(digest, d) - else: - digest_cons = lambda d=b'': digest.new(d) - - inner = digest_cons() - outer = digest_cons() - blocksize = getattr(inner, 'block_size', 64) - if len(key) > blocksize: - key = digest_cons(key).digest() - key = key + b'\x00' * (blocksize - len(key)) - inner.update(key.translate(trans_36)) - outer.update(key.translate(trans_5C)) - inner.update(msg) - outer.update(inner.digest()) - return outer.digest() diff --git a/python/Lib/imaplib.py b/python/Lib/imaplib.py deleted file mode 100644 index 60b54ce..0000000 --- a/python/Lib/imaplib.py +++ /dev/null @@ -1,1649 +0,0 @@ -"""IMAP4 client. - -Based on RFC 2060. - -Public class: IMAP4 -Public variable: Debug -Public functions: Internaldate2tuple - Int2AP - ParseFlags - Time2Internaldate -""" - -# Author: Piers Lauder December 1997. -# -# Authentication code contributed by Donn Cave June 1998. -# String method conversion by ESR, February 2001. -# GET/SETACL contributed by Anthony Baxter April 2001. -# IMAP4_SSL contributed by Tino Lange March 2002. -# GET/SETQUOTA contributed by Andreas Zeidler June 2002. -# PROXYAUTH contributed by Rick Holbert November 2002. -# GET/SETANNOTATION contributed by Tomas Lindroos June 2005. - -__version__ = "2.58" - -import binascii, errno, random, re, socket, subprocess, sys, time, calendar -from datetime import datetime, timezone, timedelta -from io import DEFAULT_BUFFER_SIZE - -try: - import ssl - HAVE_SSL = True -except ImportError: - HAVE_SSL = False - -__all__ = ["IMAP4", "IMAP4_stream", "Internaldate2tuple", - "Int2AP", "ParseFlags", "Time2Internaldate"] - -# Globals - -CRLF = b'\r\n' -Debug = 0 -IMAP4_PORT = 143 -IMAP4_SSL_PORT = 993 -AllowedVersions = ('IMAP4REV1', 'IMAP4') # Most recent first - -# Maximal line length when calling readline(). This is to prevent -# reading arbitrary length lines. RFC 3501 and 2060 (IMAP 4rev1) -# don't specify a line length. RFC 2683 suggests limiting client -# command lines to 1000 octets and that servers should be prepared -# to accept command lines up to 8000 octets, so we used to use 10K here. -# In the modern world (eg: gmail) the response to, for example, a -# search command can be quite large, so we now use 1M. -_MAXLINE = 1000000 - - -# Commands - -Commands = { - # name valid states - 'APPEND': ('AUTH', 'SELECTED'), - 'AUTHENTICATE': ('NONAUTH',), - 'CAPABILITY': ('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'), - 'CHECK': ('SELECTED',), - 'CLOSE': ('SELECTED',), - 'COPY': ('SELECTED',), - 'CREATE': ('AUTH', 'SELECTED'), - 'DELETE': ('AUTH', 'SELECTED'), - 'DELETEACL': ('AUTH', 'SELECTED'), - 'ENABLE': ('AUTH', ), - 'EXAMINE': ('AUTH', 'SELECTED'), - 'EXPUNGE': ('SELECTED',), - 'FETCH': ('SELECTED',), - 'GETACL': ('AUTH', 'SELECTED'), - 'GETANNOTATION':('AUTH', 'SELECTED'), - 'GETQUOTA': ('AUTH', 'SELECTED'), - 'GETQUOTAROOT': ('AUTH', 'SELECTED'), - 'MYRIGHTS': ('AUTH', 'SELECTED'), - 'LIST': ('AUTH', 'SELECTED'), - 'LOGIN': ('NONAUTH',), - 'LOGOUT': ('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'), - 'LSUB': ('AUTH', 'SELECTED'), - 'MOVE': ('SELECTED',), - 'NAMESPACE': ('AUTH', 'SELECTED'), - 'NOOP': ('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'), - 'PARTIAL': ('SELECTED',), # NB: obsolete - 'PROXYAUTH': ('AUTH',), - 'RENAME': ('AUTH', 'SELECTED'), - 'SEARCH': ('SELECTED',), - 'SELECT': ('AUTH', 'SELECTED'), - 'SETACL': ('AUTH', 'SELECTED'), - 'SETANNOTATION':('AUTH', 'SELECTED'), - 'SETQUOTA': ('AUTH', 'SELECTED'), - 'SORT': ('SELECTED',), - 'STARTTLS': ('NONAUTH',), - 'STATUS': ('AUTH', 'SELECTED'), - 'STORE': ('SELECTED',), - 'SUBSCRIBE': ('AUTH', 'SELECTED'), - 'THREAD': ('SELECTED',), - 'UID': ('SELECTED',), - 'UNSUBSCRIBE': ('AUTH', 'SELECTED'), - 'UNSELECT': ('SELECTED',), - } - -# Patterns to match server responses - -Continuation = re.compile(br'\+( (?P.*))?') -Flags = re.compile(br'.*FLAGS \((?P[^\)]*)\)') -InternalDate = re.compile(br'.*INTERNALDATE "' - br'(?P[ 0123][0-9])-(?P[A-Z][a-z][a-z])-(?P[0-9][0-9][0-9][0-9])' - br' (?P[0-9][0-9]):(?P[0-9][0-9]):(?P[0-9][0-9])' - br' (?P[-+])(?P[0-9][0-9])(?P[0-9][0-9])' - br'"') -# Literal is no longer used; kept for backward compatibility. -Literal = re.compile(br'.*{(?P\d+)}$', re.ASCII) -MapCRLF = re.compile(br'\r\n|\r|\n') -# We no longer exclude the ']' character from the data portion of the response -# code, even though it violates the RFC. Popular IMAP servers such as Gmail -# allow flags with ']', and there are programs (including imaplib!) that can -# produce them. The problem with this is if the 'text' portion of the response -# includes a ']' we'll parse the response wrong (which is the point of the RFC -# restriction). However, that seems less likely to be a problem in practice -# than being unable to correctly parse flags that include ']' chars, which -# was reported as a real-world problem in issue #21815. -Response_code = re.compile(br'\[(?P[A-Z-]+)( (?P.*))?\]') -Untagged_response = re.compile(br'\* (?P[A-Z-]+)( (?P.*))?') -# Untagged_status is no longer used; kept for backward compatibility -Untagged_status = re.compile( - br'\* (?P\d+) (?P[A-Z-]+)( (?P.*))?', re.ASCII) -# We compile these in _mode_xxx. -_Literal = br'.*{(?P\d+)}$' -_Untagged_status = br'\* (?P\d+) (?P[A-Z-]+)( (?P.*))?' - - - -class IMAP4: - - r"""IMAP4 client class. - - Instantiate with: IMAP4([host[, port[, timeout=None]]]) - - host - host's name (default: localhost); - port - port number (default: standard IMAP4 port). - timeout - socket timeout (default: None) - If timeout is not given or is None, - the global default socket timeout is used - - All IMAP4rev1 commands are supported by methods of the same - name (in lowercase). - - All arguments to commands are converted to strings, except for - AUTHENTICATE, and the last argument to APPEND which is passed as - an IMAP4 literal. If necessary (the string contains any - non-printing characters or white-space and isn't enclosed with - either parentheses or double quotes) each string is quoted. - However, the 'password' argument to the LOGIN command is always - quoted. If you want to avoid having an argument string quoted - (eg: the 'flags' argument to STORE) then enclose the string in - parentheses (eg: "(\Deleted)"). - - Each command returns a tuple: (type, [data, ...]) where 'type' - is usually 'OK' or 'NO', and 'data' is either the text from the - tagged response, or untagged results from command. Each 'data' - is either a string, or a tuple. If a tuple, then the first part - is the header of the response, and the second part contains - the data (ie: 'literal' value). - - Errors raise the exception class .error(""). - IMAP4 server errors raise .abort(""), - which is a sub-class of 'error'. Mailbox status changes - from READ-WRITE to READ-ONLY raise the exception class - .readonly(""), which is a sub-class of 'abort'. - - "error" exceptions imply a program error. - "abort" exceptions imply the connection should be reset, and - the command re-tried. - "readonly" exceptions imply the command should be re-tried. - - Note: to use this module, you must read the RFCs pertaining to the - IMAP4 protocol, as the semantics of the arguments to each IMAP4 - command are left to the invoker, not to mention the results. Also, - most IMAP servers implement a sub-set of the commands available here. - """ - - class error(Exception): pass # Logical errors - debug required - class abort(error): pass # Service errors - close and retry - class readonly(abort): pass # Mailbox status changed to READ-ONLY - - def __init__(self, host='', port=IMAP4_PORT, timeout=None): - self.debug = Debug - self.state = 'LOGOUT' - self.literal = None # A literal argument to a command - self.tagged_commands = {} # Tagged commands awaiting response - self.untagged_responses = {} # {typ: [data, ...], ...} - self.continuation_response = '' # Last continuation response - self.is_readonly = False # READ-ONLY desired state - self.tagnum = 0 - self._tls_established = False - self._mode_ascii() - - # Open socket to server. - - self.open(host, port, timeout) - - try: - self._connect() - except Exception: - try: - self.shutdown() - except OSError: - pass - raise - - def _mode_ascii(self): - self.utf8_enabled = False - self._encoding = 'ascii' - self.Literal = re.compile(_Literal, re.ASCII) - self.Untagged_status = re.compile(_Untagged_status, re.ASCII) - - - def _mode_utf8(self): - self.utf8_enabled = True - self._encoding = 'utf-8' - self.Literal = re.compile(_Literal) - self.Untagged_status = re.compile(_Untagged_status) - - - def _connect(self): - # Create unique tag for this session, - # and compile tagged response matcher. - - self.tagpre = Int2AP(random.randint(4096, 65535)) - self.tagre = re.compile(br'(?P' - + self.tagpre - + br'\d+) (?P[A-Z]+) (?P.*)', re.ASCII) - - # Get server welcome message, - # request and store CAPABILITY response. - - if __debug__: - self._cmd_log_len = 10 - self._cmd_log_idx = 0 - self._cmd_log = {} # Last `_cmd_log_len' interactions - if self.debug >= 1: - self._mesg('imaplib version %s' % __version__) - self._mesg('new IMAP4 connection, tag=%s' % self.tagpre) - - self.welcome = self._get_response() - if 'PREAUTH' in self.untagged_responses: - self.state = 'AUTH' - elif 'OK' in self.untagged_responses: - self.state = 'NONAUTH' - else: - raise self.error(self.welcome) - - self._get_capabilities() - if __debug__: - if self.debug >= 3: - self._mesg('CAPABILITIES: %r' % (self.capabilities,)) - - for version in AllowedVersions: - if not version in self.capabilities: - continue - self.PROTOCOL_VERSION = version - return - - raise self.error('server not IMAP4 compliant') - - - def __getattr__(self, attr): - # Allow UPPERCASE variants of IMAP4 command methods. - if attr in Commands: - return getattr(self, attr.lower()) - raise AttributeError("Unknown IMAP4 command: '%s'" % attr) - - def __enter__(self): - return self - - def __exit__(self, *args): - if self.state == "LOGOUT": - return - - try: - self.logout() - except OSError: - pass - - - # Overridable methods - - - def _create_socket(self, timeout): - # Default value of IMAP4.host is '', but socket.getaddrinfo() - # (which is used by socket.create_connection()) expects None - # as a default value for host. - if timeout is not None and not timeout: - raise ValueError('Non-blocking socket (timeout=0) is not supported') - host = None if not self.host else self.host - sys.audit("imaplib.open", self, self.host, self.port) - address = (host, self.port) - if timeout is not None: - return socket.create_connection(address, timeout) - return socket.create_connection(address) - - def open(self, host='', port=IMAP4_PORT, timeout=None): - """Setup connection to remote server on "host:port" - (default: localhost:standard IMAP4 port). - This connection will be used by the routines: - read, readline, send, shutdown. - """ - self.host = host - self.port = port - self.sock = self._create_socket(timeout) - self.file = self.sock.makefile('rb') - - - def read(self, size): - """Read 'size' bytes from remote.""" - return self.file.read(size) - - - def readline(self): - """Read line from remote.""" - line = self.file.readline(_MAXLINE + 1) - if len(line) > _MAXLINE: - raise self.error("got more than %d bytes" % _MAXLINE) - return line - - - def send(self, data): - """Send data to remote.""" - sys.audit("imaplib.send", self, data) - self.sock.sendall(data) - - - def shutdown(self): - """Close I/O established in "open".""" - self.file.close() - try: - self.sock.shutdown(socket.SHUT_RDWR) - except OSError as exc: - # The server might already have closed the connection. - # On Windows, this may result in WSAEINVAL (error 10022): - # An invalid operation was attempted. - if (exc.errno != errno.ENOTCONN - and getattr(exc, 'winerror', 0) != 10022): - raise - finally: - self.sock.close() - - - def socket(self): - """Return socket instance used to connect to IMAP4 server. - - socket = .socket() - """ - return self.sock - - - - # Utility methods - - - def recent(self): - """Return most recent 'RECENT' responses if any exist, - else prompt server for an update using the 'NOOP' command. - - (typ, [data]) = .recent() - - 'data' is None if no new messages, - else list of RECENT responses, most recent last. - """ - name = 'RECENT' - typ, dat = self._untagged_response('OK', [None], name) - if dat[-1]: - return typ, dat - typ, dat = self.noop() # Prod server for response - return self._untagged_response(typ, dat, name) - - - def response(self, code): - """Return data for response 'code' if received, or None. - - Old value for response 'code' is cleared. - - (code, [data]) = .response(code) - """ - return self._untagged_response(code, [None], code.upper()) - - - - # IMAP4 commands - - - def append(self, mailbox, flags, date_time, message): - """Append message to named mailbox. - - (typ, [data]) = .append(mailbox, flags, date_time, message) - - All args except `message' can be None. - """ - name = 'APPEND' - if not mailbox: - mailbox = 'INBOX' - if flags: - if (flags[0],flags[-1]) != ('(',')'): - flags = '(%s)' % flags - else: - flags = None - if date_time: - date_time = Time2Internaldate(date_time) - else: - date_time = None - literal = MapCRLF.sub(CRLF, message) - if self.utf8_enabled: - literal = b'UTF8 (' + literal + b')' - self.literal = literal - return self._simple_command(name, mailbox, flags, date_time) - - - def authenticate(self, mechanism, authobject): - """Authenticate command - requires response processing. - - 'mechanism' specifies which authentication mechanism is to - be used - it must appear in .capabilities in the - form AUTH=. - - 'authobject' must be a callable object: - - data = authobject(response) - - It will be called to process server continuation responses; the - response argument it is passed will be a bytes. It should return bytes - data that will be base64 encoded and sent to the server. It should - return None if the client abort response '*' should be sent instead. - """ - mech = mechanism.upper() - # XXX: shouldn't this code be removed, not commented out? - #cap = 'AUTH=%s' % mech - #if not cap in self.capabilities: # Let the server decide! - # raise self.error("Server doesn't allow %s authentication." % mech) - self.literal = _Authenticator(authobject).process - typ, dat = self._simple_command('AUTHENTICATE', mech) - if typ != 'OK': - raise self.error(dat[-1].decode('utf-8', 'replace')) - self.state = 'AUTH' - return typ, dat - - - def capability(self): - """(typ, [data]) = .capability() - Fetch capabilities list from server.""" - - name = 'CAPABILITY' - typ, dat = self._simple_command(name) - return self._untagged_response(typ, dat, name) - - - def check(self): - """Checkpoint mailbox on server. - - (typ, [data]) = .check() - """ - return self._simple_command('CHECK') - - - def close(self): - """Close currently selected mailbox. - - Deleted messages are removed from writable mailbox. - This is the recommended command before 'LOGOUT'. - - (typ, [data]) = .close() - """ - try: - typ, dat = self._simple_command('CLOSE') - finally: - self.state = 'AUTH' - return typ, dat - - - def copy(self, message_set, new_mailbox): - """Copy 'message_set' messages onto end of 'new_mailbox'. - - (typ, [data]) = .copy(message_set, new_mailbox) - """ - return self._simple_command('COPY', message_set, new_mailbox) - - - def create(self, mailbox): - """Create new mailbox. - - (typ, [data]) = .create(mailbox) - """ - return self._simple_command('CREATE', mailbox) - - - def delete(self, mailbox): - """Delete old mailbox. - - (typ, [data]) = .delete(mailbox) - """ - return self._simple_command('DELETE', mailbox) - - def deleteacl(self, mailbox, who): - """Delete the ACLs (remove any rights) set for who on mailbox. - - (typ, [data]) = .deleteacl(mailbox, who) - """ - return self._simple_command('DELETEACL', mailbox, who) - - def enable(self, capability): - """Send an RFC5161 enable string to the server. - - (typ, [data]) = .enable(capability) - """ - if 'ENABLE' not in self.capabilities: - raise IMAP4.error("Server does not support ENABLE") - typ, data = self._simple_command('ENABLE', capability) - if typ == 'OK' and 'UTF8=ACCEPT' in capability.upper(): - self._mode_utf8() - return typ, data - - def expunge(self): - """Permanently remove deleted items from selected mailbox. - - Generates 'EXPUNGE' response for each deleted message. - - (typ, [data]) = .expunge() - - 'data' is list of 'EXPUNGE'd message numbers in order received. - """ - name = 'EXPUNGE' - typ, dat = self._simple_command(name) - return self._untagged_response(typ, dat, name) - - - def fetch(self, message_set, message_parts): - """Fetch (parts of) messages. - - (typ, [data, ...]) = .fetch(message_set, message_parts) - - 'message_parts' should be a string of selected parts - enclosed in parentheses, eg: "(UID BODY[TEXT])". - - 'data' are tuples of message part envelope and data. - """ - name = 'FETCH' - typ, dat = self._simple_command(name, message_set, message_parts) - return self._untagged_response(typ, dat, name) - - - def getacl(self, mailbox): - """Get the ACLs for a mailbox. - - (typ, [data]) = .getacl(mailbox) - """ - typ, dat = self._simple_command('GETACL', mailbox) - return self._untagged_response(typ, dat, 'ACL') - - - def getannotation(self, mailbox, entry, attribute): - """(typ, [data]) = .getannotation(mailbox, entry, attribute) - Retrieve ANNOTATIONs.""" - - typ, dat = self._simple_command('GETANNOTATION', mailbox, entry, attribute) - return self._untagged_response(typ, dat, 'ANNOTATION') - - - def getquota(self, root): - """Get the quota root's resource usage and limits. - - Part of the IMAP4 QUOTA extension defined in rfc2087. - - (typ, [data]) = .getquota(root) - """ - typ, dat = self._simple_command('GETQUOTA', root) - return self._untagged_response(typ, dat, 'QUOTA') - - - def getquotaroot(self, mailbox): - """Get the list of quota roots for the named mailbox. - - (typ, [[QUOTAROOT responses...], [QUOTA responses]]) = .getquotaroot(mailbox) - """ - typ, dat = self._simple_command('GETQUOTAROOT', mailbox) - typ, quota = self._untagged_response(typ, dat, 'QUOTA') - typ, quotaroot = self._untagged_response(typ, dat, 'QUOTAROOT') - return typ, [quotaroot, quota] - - - def list(self, directory='""', pattern='*'): - """List mailbox names in directory matching pattern. - - (typ, [data]) = .list(directory='""', pattern='*') - - 'data' is list of LIST responses. - """ - name = 'LIST' - typ, dat = self._simple_command(name, directory, pattern) - return self._untagged_response(typ, dat, name) - - - def login(self, user, password): - """Identify client using plaintext password. - - (typ, [data]) = .login(user, password) - - NB: 'password' will be quoted. - """ - typ, dat = self._simple_command('LOGIN', user, self._quote(password)) - if typ != 'OK': - raise self.error(dat[-1]) - self.state = 'AUTH' - return typ, dat - - - def login_cram_md5(self, user, password): - """ Force use of CRAM-MD5 authentication. - - (typ, [data]) = .login_cram_md5(user, password) - """ - self.user, self.password = user, password - return self.authenticate('CRAM-MD5', self._CRAM_MD5_AUTH) - - - def _CRAM_MD5_AUTH(self, challenge): - """ Authobject to use with CRAM-MD5 authentication. """ - import hmac - pwd = (self.password.encode('utf-8') if isinstance(self.password, str) - else self.password) - return self.user + " " + hmac.HMAC(pwd, challenge, 'md5').hexdigest() - - - def logout(self): - """Shutdown connection to server. - - (typ, [data]) = .logout() - - Returns server 'BYE' response. - """ - self.state = 'LOGOUT' - typ, dat = self._simple_command('LOGOUT') - self.shutdown() - return typ, dat - - - def lsub(self, directory='""', pattern='*'): - """List 'subscribed' mailbox names in directory matching pattern. - - (typ, [data, ...]) = .lsub(directory='""', pattern='*') - - 'data' are tuples of message part envelope and data. - """ - name = 'LSUB' - typ, dat = self._simple_command(name, directory, pattern) - return self._untagged_response(typ, dat, name) - - def myrights(self, mailbox): - """Show my ACLs for a mailbox (i.e. the rights that I have on mailbox). - - (typ, [data]) = .myrights(mailbox) - """ - typ,dat = self._simple_command('MYRIGHTS', mailbox) - return self._untagged_response(typ, dat, 'MYRIGHTS') - - def namespace(self): - """ Returns IMAP namespaces ala rfc2342 - - (typ, [data, ...]) = .namespace() - """ - name = 'NAMESPACE' - typ, dat = self._simple_command(name) - return self._untagged_response(typ, dat, name) - - - def noop(self): - """Send NOOP command. - - (typ, [data]) = .noop() - """ - if __debug__: - if self.debug >= 3: - self._dump_ur(self.untagged_responses) - return self._simple_command('NOOP') - - - def partial(self, message_num, message_part, start, length): - """Fetch truncated part of a message. - - (typ, [data, ...]) = .partial(message_num, message_part, start, length) - - 'data' is tuple of message part envelope and data. - """ - name = 'PARTIAL' - typ, dat = self._simple_command(name, message_num, message_part, start, length) - return self._untagged_response(typ, dat, 'FETCH') - - - def proxyauth(self, user): - """Assume authentication as "user". - - Allows an authorised administrator to proxy into any user's - mailbox. - - (typ, [data]) = .proxyauth(user) - """ - - name = 'PROXYAUTH' - return self._simple_command('PROXYAUTH', user) - - - def rename(self, oldmailbox, newmailbox): - """Rename old mailbox name to new. - - (typ, [data]) = .rename(oldmailbox, newmailbox) - """ - return self._simple_command('RENAME', oldmailbox, newmailbox) - - - def search(self, charset, *criteria): - """Search mailbox for matching messages. - - (typ, [data]) = .search(charset, criterion, ...) - - 'data' is space separated list of matching message numbers. - If UTF8 is enabled, charset MUST be None. - """ - name = 'SEARCH' - if charset: - if self.utf8_enabled: - raise IMAP4.error("Non-None charset not valid in UTF8 mode") - typ, dat = self._simple_command(name, 'CHARSET', charset, *criteria) - else: - typ, dat = self._simple_command(name, *criteria) - return self._untagged_response(typ, dat, name) - - - def select(self, mailbox='INBOX', readonly=False): - """Select a mailbox. - - Flush all untagged responses. - - (typ, [data]) = .select(mailbox='INBOX', readonly=False) - - 'data' is count of messages in mailbox ('EXISTS' response). - - Mandated responses are ('FLAGS', 'EXISTS', 'RECENT', 'UIDVALIDITY'), so - other responses should be obtained via .response('FLAGS') etc. - """ - self.untagged_responses = {} # Flush old responses. - self.is_readonly = readonly - if readonly: - name = 'EXAMINE' - else: - name = 'SELECT' - typ, dat = self._simple_command(name, mailbox) - if typ != 'OK': - self.state = 'AUTH' # Might have been 'SELECTED' - return typ, dat - self.state = 'SELECTED' - if 'READ-ONLY' in self.untagged_responses \ - and not readonly: - if __debug__: - if self.debug >= 1: - self._dump_ur(self.untagged_responses) - raise self.readonly('%s is not writable' % mailbox) - return typ, self.untagged_responses.get('EXISTS', [None]) - - - def setacl(self, mailbox, who, what): - """Set a mailbox acl. - - (typ, [data]) = .setacl(mailbox, who, what) - """ - return self._simple_command('SETACL', mailbox, who, what) - - - def setannotation(self, *args): - """(typ, [data]) = .setannotation(mailbox[, entry, attribute]+) - Set ANNOTATIONs.""" - - typ, dat = self._simple_command('SETANNOTATION', *args) - return self._untagged_response(typ, dat, 'ANNOTATION') - - - def setquota(self, root, limits): - """Set the quota root's resource limits. - - (typ, [data]) = .setquota(root, limits) - """ - typ, dat = self._simple_command('SETQUOTA', root, limits) - return self._untagged_response(typ, dat, 'QUOTA') - - - def sort(self, sort_criteria, charset, *search_criteria): - """IMAP4rev1 extension SORT command. - - (typ, [data]) = .sort(sort_criteria, charset, search_criteria, ...) - """ - name = 'SORT' - #if not name in self.capabilities: # Let the server decide! - # raise self.error('unimplemented extension command: %s' % name) - if (sort_criteria[0],sort_criteria[-1]) != ('(',')'): - sort_criteria = '(%s)' % sort_criteria - typ, dat = self._simple_command(name, sort_criteria, charset, *search_criteria) - return self._untagged_response(typ, dat, name) - - - def starttls(self, ssl_context=None): - name = 'STARTTLS' - if not HAVE_SSL: - raise self.error('SSL support missing') - if self._tls_established: - raise self.abort('TLS session already established') - if name not in self.capabilities: - raise self.abort('TLS not supported by server') - # Generate a default SSL context if none was passed. - if ssl_context is None: - ssl_context = ssl._create_stdlib_context() - typ, dat = self._simple_command(name) - if typ == 'OK': - self.sock = ssl_context.wrap_socket(self.sock, - server_hostname=self.host) - self.file = self.sock.makefile('rb') - self._tls_established = True - self._get_capabilities() - else: - raise self.error("Couldn't establish TLS session") - return self._untagged_response(typ, dat, name) - - - def status(self, mailbox, names): - """Request named status conditions for mailbox. - - (typ, [data]) = .status(mailbox, names) - """ - name = 'STATUS' - #if self.PROTOCOL_VERSION == 'IMAP4': # Let the server decide! - # raise self.error('%s unimplemented in IMAP4 (obtain IMAP4rev1 server, or re-code)' % name) - typ, dat = self._simple_command(name, mailbox, names) - return self._untagged_response(typ, dat, name) - - - def store(self, message_set, command, flags): - """Alters flag dispositions for messages in mailbox. - - (typ, [data]) = .store(message_set, command, flags) - """ - if (flags[0],flags[-1]) != ('(',')'): - flags = '(%s)' % flags # Avoid quoting the flags - typ, dat = self._simple_command('STORE', message_set, command, flags) - return self._untagged_response(typ, dat, 'FETCH') - - - def subscribe(self, mailbox): - """Subscribe to new mailbox. - - (typ, [data]) = .subscribe(mailbox) - """ - return self._simple_command('SUBSCRIBE', mailbox) - - - def thread(self, threading_algorithm, charset, *search_criteria): - """IMAPrev1 extension THREAD command. - - (type, [data]) = .thread(threading_algorithm, charset, search_criteria, ...) - """ - name = 'THREAD' - typ, dat = self._simple_command(name, threading_algorithm, charset, *search_criteria) - return self._untagged_response(typ, dat, name) - - - def uid(self, command, *args): - """Execute "command arg ..." with messages identified by UID, - rather than message number. - - (typ, [data]) = .uid(command, arg1, arg2, ...) - - Returns response appropriate to 'command'. - """ - command = command.upper() - if not command in Commands: - raise self.error("Unknown IMAP4 UID command: %s" % command) - if self.state not in Commands[command]: - raise self.error("command %s illegal in state %s, " - "only allowed in states %s" % - (command, self.state, - ', '.join(Commands[command]))) - name = 'UID' - typ, dat = self._simple_command(name, command, *args) - if command in ('SEARCH', 'SORT', 'THREAD'): - name = command - else: - name = 'FETCH' - return self._untagged_response(typ, dat, name) - - - def unsubscribe(self, mailbox): - """Unsubscribe from old mailbox. - - (typ, [data]) = .unsubscribe(mailbox) - """ - return self._simple_command('UNSUBSCRIBE', mailbox) - - - def unselect(self): - """Free server's resources associated with the selected mailbox - and returns the server to the authenticated state. - This command performs the same actions as CLOSE, except - that no messages are permanently removed from the currently - selected mailbox. - - (typ, [data]) = .unselect() - """ - try: - typ, data = self._simple_command('UNSELECT') - finally: - self.state = 'AUTH' - return typ, data - - - def xatom(self, name, *args): - """Allow simple extension commands - notified by server in CAPABILITY response. - - Assumes command is legal in current state. - - (typ, [data]) = .xatom(name, arg, ...) - - Returns response appropriate to extension command `name'. - """ - name = name.upper() - #if not name in self.capabilities: # Let the server decide! - # raise self.error('unknown extension command: %s' % name) - if not name in Commands: - Commands[name] = (self.state,) - return self._simple_command(name, *args) - - - - # Private methods - - - def _append_untagged(self, typ, dat): - if dat is None: - dat = b'' - ur = self.untagged_responses - if __debug__: - if self.debug >= 5: - self._mesg('untagged_responses[%s] %s += ["%r"]' % - (typ, len(ur.get(typ,'')), dat)) - if typ in ur: - ur[typ].append(dat) - else: - ur[typ] = [dat] - - - def _check_bye(self): - bye = self.untagged_responses.get('BYE') - if bye: - raise self.abort(bye[-1].decode(self._encoding, 'replace')) - - - def _command(self, name, *args): - - if self.state not in Commands[name]: - self.literal = None - raise self.error("command %s illegal in state %s, " - "only allowed in states %s" % - (name, self.state, - ', '.join(Commands[name]))) - - for typ in ('OK', 'NO', 'BAD'): - if typ in self.untagged_responses: - del self.untagged_responses[typ] - - if 'READ-ONLY' in self.untagged_responses \ - and not self.is_readonly: - raise self.readonly('mailbox status changed to READ-ONLY') - - tag = self._new_tag() - name = bytes(name, self._encoding) - data = tag + b' ' + name - for arg in args: - if arg is None: continue - if isinstance(arg, str): - arg = bytes(arg, self._encoding) - data = data + b' ' + arg - - literal = self.literal - if literal is not None: - self.literal = None - if type(literal) is type(self._command): - literator = literal - else: - literator = None - data = data + bytes(' {%s}' % len(literal), self._encoding) - - if __debug__: - if self.debug >= 4: - self._mesg('> %r' % data) - else: - self._log('> %r' % data) - - try: - self.send(data + CRLF) - except OSError as val: - raise self.abort('socket error: %s' % val) - - if literal is None: - return tag - - while 1: - # Wait for continuation response - - while self._get_response(): - if self.tagged_commands[tag]: # BAD/NO? - return tag - - # Send literal - - if literator: - literal = literator(self.continuation_response) - - if __debug__: - if self.debug >= 4: - self._mesg('write literal size %s' % len(literal)) - - try: - self.send(literal) - self.send(CRLF) - except OSError as val: - raise self.abort('socket error: %s' % val) - - if not literator: - break - - return tag - - - def _command_complete(self, name, tag): - logout = (name == 'LOGOUT') - # BYE is expected after LOGOUT - if not logout: - self._check_bye() - try: - typ, data = self._get_tagged_response(tag, expect_bye=logout) - except self.abort as val: - raise self.abort('command: %s => %s' % (name, val)) - except self.error as val: - raise self.error('command: %s => %s' % (name, val)) - if not logout: - self._check_bye() - if typ == 'BAD': - raise self.error('%s command error: %s %s' % (name, typ, data)) - return typ, data - - - def _get_capabilities(self): - typ, dat = self.capability() - if dat == [None]: - raise self.error('no CAPABILITY response from server') - dat = str(dat[-1], self._encoding) - dat = dat.upper() - self.capabilities = tuple(dat.split()) - - - def _get_response(self): - - # Read response and store. - # - # Returns None for continuation responses, - # otherwise first response line received. - - resp = self._get_line() - - # Command completion response? - - if self._match(self.tagre, resp): - tag = self.mo.group('tag') - if not tag in self.tagged_commands: - raise self.abort('unexpected tagged response: %r' % resp) - - typ = self.mo.group('type') - typ = str(typ, self._encoding) - dat = self.mo.group('data') - self.tagged_commands[tag] = (typ, [dat]) - else: - dat2 = None - - # '*' (untagged) responses? - - if not self._match(Untagged_response, resp): - if self._match(self.Untagged_status, resp): - dat2 = self.mo.group('data2') - - if self.mo is None: - # Only other possibility is '+' (continuation) response... - - if self._match(Continuation, resp): - self.continuation_response = self.mo.group('data') - return None # NB: indicates continuation - - raise self.abort("unexpected response: %r" % resp) - - typ = self.mo.group('type') - typ = str(typ, self._encoding) - dat = self.mo.group('data') - if dat is None: dat = b'' # Null untagged response - if dat2: dat = dat + b' ' + dat2 - - # Is there a literal to come? - - while self._match(self.Literal, dat): - - # Read literal direct from connection. - - size = int(self.mo.group('size')) - if __debug__: - if self.debug >= 4: - self._mesg('read literal size %s' % size) - data = self.read(size) - - # Store response with literal as tuple - - self._append_untagged(typ, (dat, data)) - - # Read trailer - possibly containing another literal - - dat = self._get_line() - - self._append_untagged(typ, dat) - - # Bracketed response information? - - if typ in ('OK', 'NO', 'BAD') and self._match(Response_code, dat): - typ = self.mo.group('type') - typ = str(typ, self._encoding) - self._append_untagged(typ, self.mo.group('data')) - - if __debug__: - if self.debug >= 1 and typ in ('NO', 'BAD', 'BYE'): - self._mesg('%s response: %r' % (typ, dat)) - - return resp - - - def _get_tagged_response(self, tag, expect_bye=False): - - while 1: - result = self.tagged_commands[tag] - if result is not None: - del self.tagged_commands[tag] - return result - - if expect_bye: - typ = 'BYE' - bye = self.untagged_responses.pop(typ, None) - if bye is not None: - # Server replies to the "LOGOUT" command with "BYE" - return (typ, bye) - - # If we've seen a BYE at this point, the socket will be - # closed, so report the BYE now. - self._check_bye() - - # Some have reported "unexpected response" exceptions. - # Note that ignoring them here causes loops. - # Instead, send me details of the unexpected response and - # I'll update the code in `_get_response()'. - - try: - self._get_response() - except self.abort as val: - if __debug__: - if self.debug >= 1: - self.print_log() - raise - - - def _get_line(self): - - line = self.readline() - if not line: - raise self.abort('socket error: EOF') - - # Protocol mandates all lines terminated by CRLF - if not line.endswith(b'\r\n'): - raise self.abort('socket error: unterminated line: %r' % line) - - line = line[:-2] - if __debug__: - if self.debug >= 4: - self._mesg('< %r' % line) - else: - self._log('< %r' % line) - return line - - - def _match(self, cre, s): - - # Run compiled regular expression match method on 's'. - # Save result, return success. - - self.mo = cre.match(s) - if __debug__: - if self.mo is not None and self.debug >= 5: - self._mesg("\tmatched %r => %r" % (cre.pattern, self.mo.groups())) - return self.mo is not None - - - def _new_tag(self): - - tag = self.tagpre + bytes(str(self.tagnum), self._encoding) - self.tagnum = self.tagnum + 1 - self.tagged_commands[tag] = None - return tag - - - def _quote(self, arg): - - arg = arg.replace('\\', '\\\\') - arg = arg.replace('"', '\\"') - - return '"' + arg + '"' - - - def _simple_command(self, name, *args): - - return self._command_complete(name, self._command(name, *args)) - - - def _untagged_response(self, typ, dat, name): - if typ == 'NO': - return typ, dat - if not name in self.untagged_responses: - return typ, [None] - data = self.untagged_responses.pop(name) - if __debug__: - if self.debug >= 5: - self._mesg('untagged_responses[%s] => %s' % (name, data)) - return typ, data - - - if __debug__: - - def _mesg(self, s, secs=None): - if secs is None: - secs = time.time() - tm = time.strftime('%M:%S', time.localtime(secs)) - sys.stderr.write(' %s.%02d %s\n' % (tm, (secs*100)%100, s)) - sys.stderr.flush() - - def _dump_ur(self, untagged_resp_dict): - if not untagged_resp_dict: - return - items = (f'{key}: {value!r}' - for key, value in untagged_resp_dict.items()) - self._mesg('untagged responses dump:' + '\n\t\t'.join(items)) - - def _log(self, line): - # Keep log of last `_cmd_log_len' interactions for debugging. - self._cmd_log[self._cmd_log_idx] = (line, time.time()) - self._cmd_log_idx += 1 - if self._cmd_log_idx >= self._cmd_log_len: - self._cmd_log_idx = 0 - - def print_log(self): - self._mesg('last %d IMAP4 interactions:' % len(self._cmd_log)) - i, n = self._cmd_log_idx, self._cmd_log_len - while n: - try: - self._mesg(*self._cmd_log[i]) - except: - pass - i += 1 - if i >= self._cmd_log_len: - i = 0 - n -= 1 - - -if HAVE_SSL: - - class IMAP4_SSL(IMAP4): - - """IMAP4 client class over SSL connection - - Instantiate with: IMAP4_SSL([host[, port[, keyfile[, certfile[, ssl_context[, timeout=None]]]]]]) - - host - host's name (default: localhost); - port - port number (default: standard IMAP4 SSL port); - keyfile - PEM formatted file that contains your private key (default: None); - certfile - PEM formatted certificate chain file (default: None); - ssl_context - a SSLContext object that contains your certificate chain - and private key (default: None) - Note: if ssl_context is provided, then parameters keyfile or - certfile should not be set otherwise ValueError is raised. - timeout - socket timeout (default: None) If timeout is not given or is None, - the global default socket timeout is used - - for more documentation see the docstring of the parent class IMAP4. - """ - - - def __init__(self, host='', port=IMAP4_SSL_PORT, keyfile=None, - certfile=None, ssl_context=None, timeout=None): - if ssl_context is not None and keyfile is not None: - raise ValueError("ssl_context and keyfile arguments are mutually " - "exclusive") - if ssl_context is not None and certfile is not None: - raise ValueError("ssl_context and certfile arguments are mutually " - "exclusive") - if keyfile is not None or certfile is not None: - import warnings - warnings.warn("keyfile and certfile are deprecated, use a " - "custom ssl_context instead", DeprecationWarning, 2) - self.keyfile = keyfile - self.certfile = certfile - if ssl_context is None: - ssl_context = ssl._create_stdlib_context(certfile=certfile, - keyfile=keyfile) - self.ssl_context = ssl_context - IMAP4.__init__(self, host, port, timeout) - - def _create_socket(self, timeout): - sock = IMAP4._create_socket(self, timeout) - return self.ssl_context.wrap_socket(sock, - server_hostname=self.host) - - def open(self, host='', port=IMAP4_SSL_PORT, timeout=None): - """Setup connection to remote server on "host:port". - (default: localhost:standard IMAP4 SSL port). - This connection will be used by the routines: - read, readline, send, shutdown. - """ - IMAP4.open(self, host, port, timeout) - - __all__.append("IMAP4_SSL") - - -class IMAP4_stream(IMAP4): - - """IMAP4 client class over a stream - - Instantiate with: IMAP4_stream(command) - - "command" - a string that can be passed to subprocess.Popen() - - for more documentation see the docstring of the parent class IMAP4. - """ - - - def __init__(self, command): - self.command = command - IMAP4.__init__(self) - - - def open(self, host=None, port=None, timeout=None): - """Setup a stream connection. - This connection will be used by the routines: - read, readline, send, shutdown. - """ - self.host = None # For compatibility with parent class - self.port = None - self.sock = None - self.file = None - self.process = subprocess.Popen(self.command, - bufsize=DEFAULT_BUFFER_SIZE, - stdin=subprocess.PIPE, stdout=subprocess.PIPE, - shell=True, close_fds=True) - self.writefile = self.process.stdin - self.readfile = self.process.stdout - - def read(self, size): - """Read 'size' bytes from remote.""" - return self.readfile.read(size) - - - def readline(self): - """Read line from remote.""" - return self.readfile.readline() - - - def send(self, data): - """Send data to remote.""" - self.writefile.write(data) - self.writefile.flush() - - - def shutdown(self): - """Close I/O established in "open".""" - self.readfile.close() - self.writefile.close() - self.process.wait() - - - -class _Authenticator: - - """Private class to provide en/decoding - for base64-based authentication conversation. - """ - - def __init__(self, mechinst): - self.mech = mechinst # Callable object to provide/process data - - def process(self, data): - ret = self.mech(self.decode(data)) - if ret is None: - return b'*' # Abort conversation - return self.encode(ret) - - def encode(self, inp): - # - # Invoke binascii.b2a_base64 iteratively with - # short even length buffers, strip the trailing - # line feed from the result and append. "Even" - # means a number that factors to both 6 and 8, - # so when it gets to the end of the 8-bit input - # there's no partial 6-bit output. - # - oup = b'' - if isinstance(inp, str): - inp = inp.encode('utf-8') - while inp: - if len(inp) > 48: - t = inp[:48] - inp = inp[48:] - else: - t = inp - inp = b'' - e = binascii.b2a_base64(t) - if e: - oup = oup + e[:-1] - return oup - - def decode(self, inp): - if not inp: - return b'' - return binascii.a2b_base64(inp) - -Months = ' Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ') -Mon2num = {s.encode():n+1 for n, s in enumerate(Months[1:])} - -def Internaldate2tuple(resp): - """Parse an IMAP4 INTERNALDATE string. - - Return corresponding local time. The return value is a - time.struct_time tuple or None if the string has wrong format. - """ - - mo = InternalDate.match(resp) - if not mo: - return None - - mon = Mon2num[mo.group('mon')] - zonen = mo.group('zonen') - - day = int(mo.group('day')) - year = int(mo.group('year')) - hour = int(mo.group('hour')) - min = int(mo.group('min')) - sec = int(mo.group('sec')) - zoneh = int(mo.group('zoneh')) - zonem = int(mo.group('zonem')) - - # INTERNALDATE timezone must be subtracted to get UT - - zone = (zoneh*60 + zonem)*60 - if zonen == b'-': - zone = -zone - - tt = (year, mon, day, hour, min, sec, -1, -1, -1) - utc = calendar.timegm(tt) - zone - - return time.localtime(utc) - - - -def Int2AP(num): - - """Convert integer to A-P string representation.""" - - val = b''; AP = b'ABCDEFGHIJKLMNOP' - num = int(abs(num)) - while num: - num, mod = divmod(num, 16) - val = AP[mod:mod+1] + val - return val - - - -def ParseFlags(resp): - - """Convert IMAP4 flags response to python tuple.""" - - mo = Flags.match(resp) - if not mo: - return () - - return tuple(mo.group('flags').split()) - - -def Time2Internaldate(date_time): - - """Convert date_time to IMAP4 INTERNALDATE representation. - - Return string in form: '"DD-Mmm-YYYY HH:MM:SS +HHMM"'. The - date_time argument can be a number (int or float) representing - seconds since epoch (as returned by time.time()), a 9-tuple - representing local time, an instance of time.struct_time (as - returned by time.localtime()), an aware datetime instance or a - double-quoted string. In the last case, it is assumed to already - be in the correct format. - """ - if isinstance(date_time, (int, float)): - dt = datetime.fromtimestamp(date_time, - timezone.utc).astimezone() - elif isinstance(date_time, tuple): - try: - gmtoff = date_time.tm_gmtoff - except AttributeError: - if time.daylight: - dst = date_time[8] - if dst == -1: - dst = time.localtime(time.mktime(date_time))[8] - gmtoff = -(time.timezone, time.altzone)[dst] - else: - gmtoff = -time.timezone - delta = timedelta(seconds=gmtoff) - dt = datetime(*date_time[:6], tzinfo=timezone(delta)) - elif isinstance(date_time, datetime): - if date_time.tzinfo is None: - raise ValueError("date_time must be aware") - dt = date_time - elif isinstance(date_time, str) and (date_time[0],date_time[-1]) == ('"','"'): - return date_time # Assume in correct format - else: - raise ValueError("date_time not of a known type") - fmt = '"%d-{}-%Y %H:%M:%S %z"'.format(Months[dt.month]) - return dt.strftime(fmt) - - - -if __name__ == '__main__': - - # To test: invoke either as 'python imaplib.py [IMAP4_server_hostname]' - # or 'python imaplib.py -s "rsh IMAP4_server_hostname exec /etc/rimapd"' - # to test the IMAP4_stream class - - import getopt, getpass - - try: - optlist, args = getopt.getopt(sys.argv[1:], 'd:s:') - except getopt.error as val: - optlist, args = (), () - - stream_command = None - for opt,val in optlist: - if opt == '-d': - Debug = int(val) - elif opt == '-s': - stream_command = val - if not args: args = (stream_command,) - - if not args: args = ('',) - - host = args[0] - - USER = getpass.getuser() - PASSWD = getpass.getpass("IMAP password for %s on %s: " % (USER, host or "localhost")) - - test_mesg = 'From: %(user)s@localhost%(lf)sSubject: IMAP4 test%(lf)s%(lf)sdata...%(lf)s' % {'user':USER, 'lf':'\n'} - test_seq1 = ( - ('login', (USER, PASSWD)), - ('create', ('/tmp/xxx 1',)), - ('rename', ('/tmp/xxx 1', '/tmp/yyy')), - ('CREATE', ('/tmp/yyz 2',)), - ('append', ('/tmp/yyz 2', None, None, test_mesg)), - ('list', ('/tmp', 'yy*')), - ('select', ('/tmp/yyz 2',)), - ('search', (None, 'SUBJECT', 'test')), - ('fetch', ('1', '(FLAGS INTERNALDATE RFC822)')), - ('store', ('1', 'FLAGS', r'(\Deleted)')), - ('namespace', ()), - ('expunge', ()), - ('recent', ()), - ('close', ()), - ) - - test_seq2 = ( - ('select', ()), - ('response',('UIDVALIDITY',)), - ('uid', ('SEARCH', 'ALL')), - ('response', ('EXISTS',)), - ('append', (None, None, None, test_mesg)), - ('recent', ()), - ('logout', ()), - ) - - def run(cmd, args): - M._mesg('%s %s' % (cmd, args)) - typ, dat = getattr(M, cmd)(*args) - M._mesg('%s => %s %s' % (cmd, typ, dat)) - if typ == 'NO': raise dat[0] - return dat - - try: - if stream_command: - M = IMAP4_stream(stream_command) - else: - M = IMAP4(host) - if M.state == 'AUTH': - test_seq1 = test_seq1[1:] # Login not needed - M._mesg('PROTOCOL_VERSION = %s' % M.PROTOCOL_VERSION) - M._mesg('CAPABILITIES = %r' % (M.capabilities,)) - - for cmd,args in test_seq1: - run(cmd, args) - - for ml in run('list', ('/tmp/', 'yy%')): - mo = re.match(r'.*"([^"]+)"$', ml) - if mo: path = mo.group(1) - else: path = ml.split()[-1] - run('delete', (path,)) - - for cmd,args in test_seq2: - dat = run(cmd, args) - - if (cmd,args) != ('uid', ('SEARCH', 'ALL')): - continue - - uid = dat[-1].split() - if not uid: continue - run('uid', ('FETCH', '%s' % uid[-1], - '(FLAGS INTERNALDATE RFC822.SIZE RFC822.HEADER RFC822.TEXT)')) - - print('\nAll tests OK.') - - except: - print('\nTests failed.') - - if not Debug: - print(''' -If you would like to see debugging output, -try: %s -d5 -''' % sys.argv[0]) - - raise diff --git a/python/Lib/importlib/__init__.py b/python/Lib/importlib/__init__.py deleted file mode 100644 index 58e26af..0000000 --- a/python/Lib/importlib/__init__.py +++ /dev/null @@ -1,176 +0,0 @@ -"""A pure Python implementation of import.""" -__all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload'] - -# Bootstrap help ##################################################### - -# Until bootstrapping is complete, DO NOT import any modules that attempt -# to import importlib._bootstrap (directly or indirectly). Since this -# partially initialised package would be present in sys.modules, those -# modules would get an uninitialised copy of the source version, instead -# of a fully initialised version (either the frozen one or the one -# initialised below if the frozen one is not available). -import _imp # Just the builtin component, NOT the full Python module -import sys - -try: - import _frozen_importlib as _bootstrap -except ImportError: - from . import _bootstrap - _bootstrap._setup(sys, _imp) -else: - # importlib._bootstrap is the built-in import, ensure we don't create - # a second copy of the module. - _bootstrap.__name__ = 'importlib._bootstrap' - _bootstrap.__package__ = 'importlib' - try: - _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') - except NameError: - # __file__ is not guaranteed to be defined, e.g. if this code gets - # frozen by a tool like cx_Freeze. - pass - sys.modules['importlib._bootstrap'] = _bootstrap - -try: - import _frozen_importlib_external as _bootstrap_external -except ImportError: - from . import _bootstrap_external - _bootstrap_external._set_bootstrap_module(_bootstrap) - _bootstrap._bootstrap_external = _bootstrap_external -else: - _bootstrap_external.__name__ = 'importlib._bootstrap_external' - _bootstrap_external.__package__ = 'importlib' - try: - _bootstrap_external.__file__ = __file__.replace('__init__.py', '_bootstrap_external.py') - except NameError: - # __file__ is not guaranteed to be defined, e.g. if this code gets - # frozen by a tool like cx_Freeze. - pass - sys.modules['importlib._bootstrap_external'] = _bootstrap_external - -# To simplify imports in test code -_pack_uint32 = _bootstrap_external._pack_uint32 -_unpack_uint32 = _bootstrap_external._unpack_uint32 - -# Fully bootstrapped at this point, import whatever you like, circular -# dependencies and startup overhead minimisation permitting :) - -import warnings - - -# Public API ######################################################### - -from ._bootstrap import __import__ - - -def invalidate_caches(): - """Call the invalidate_caches() method on all meta path finders stored in - sys.meta_path (where implemented).""" - for finder in sys.meta_path: - if hasattr(finder, 'invalidate_caches'): - finder.invalidate_caches() - - -def find_loader(name, path=None): - """Return the loader for the specified module. - - This is a backward-compatible wrapper around find_spec(). - - This function is deprecated in favor of importlib.util.find_spec(). - - """ - warnings.warn('Deprecated since Python 3.4 and slated for removal in ' - 'Python 3.12; use importlib.util.find_spec() instead', - DeprecationWarning, stacklevel=2) - try: - loader = sys.modules[name].__loader__ - if loader is None: - raise ValueError('{}.__loader__ is None'.format(name)) - else: - return loader - except KeyError: - pass - except AttributeError: - raise ValueError('{}.__loader__ is not set'.format(name)) from None - - spec = _bootstrap._find_spec(name, path) - # We won't worry about malformed specs (missing attributes). - if spec is None: - return None - if spec.loader is None: - if spec.submodule_search_locations is None: - raise ImportError('spec for {} missing loader'.format(name), - name=name) - raise ImportError('namespace packages do not have loaders', - name=name) - return spec.loader - - -def import_module(name, package=None): - """Import a module. - - The 'package' argument is required when performing a relative import. It - specifies the package to use as the anchor point from which to resolve the - relative import to an absolute import. - - """ - level = 0 - if name.startswith('.'): - if not package: - msg = ("the 'package' argument is required to perform a relative " - "import for {!r}") - raise TypeError(msg.format(name)) - for character in name: - if character != '.': - break - level += 1 - return _bootstrap._gcd_import(name[level:], package, level) - - -_RELOADING = {} - - -def reload(module): - """Reload the module and return it. - - The module must have been successfully imported before. - - """ - try: - name = module.__spec__.name - except AttributeError: - try: - name = module.__name__ - except AttributeError: - raise TypeError("reload() argument must be a module") - - if sys.modules.get(name) is not module: - msg = "module {} not in sys.modules" - raise ImportError(msg.format(name), name=name) - if name in _RELOADING: - return _RELOADING[name] - _RELOADING[name] = module - try: - parent_name = name.rpartition('.')[0] - if parent_name: - try: - parent = sys.modules[parent_name] - except KeyError: - msg = "parent {!r} not in sys.modules" - raise ImportError(msg.format(parent_name), - name=parent_name) from None - else: - pkgpath = parent.__path__ - else: - pkgpath = None - target = module - spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) - if spec is None: - raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name) - _bootstrap._exec(spec, module) - # The module may have replaced itself in sys.modules! - return sys.modules[name] - finally: - try: - del _RELOADING[name] - except KeyError: - pass diff --git a/python/Lib/importlib/_abc.py b/python/Lib/importlib/_abc.py deleted file mode 100644 index 1ffc419..0000000 --- a/python/Lib/importlib/_abc.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Subset of importlib.abc used to reduce importlib.util imports.""" -from . import _bootstrap -import abc -import warnings - - -class Loader(metaclass=abc.ABCMeta): - - """Abstract base class for import loaders.""" - - def create_module(self, spec): - """Return a module to initialize and into which to load. - - This method should raise ImportError if anything prevents it - from creating a new module. It may return None to indicate - that the spec should create the new module. - """ - # By default, defer to default semantics for the new module. - return None - - # We don't define exec_module() here since that would break - # hasattr checks we do to support backward compatibility. - - def load_module(self, fullname): - """Return the loaded module. - - The module must be added to sys.modules and have import-related - attributes set properly. The fullname is a str. - - ImportError is raised on failure. - - This method is deprecated in favor of loader.exec_module(). If - exec_module() exists then it is used to provide a backwards-compatible - functionality for this method. - - """ - if not hasattr(self, 'exec_module'): - raise ImportError - # Warning implemented in _load_module_shim(). - return _bootstrap._load_module_shim(self, fullname) - - def module_repr(self, module): - """Return a module's repr. - - Used by the module type when the method does not raise - NotImplementedError. - - This method is deprecated. - - """ - warnings.warn("importlib.abc.Loader.module_repr() is deprecated and " - "slated for removal in Python 3.12", DeprecationWarning) - # The exception will cause ModuleType.__repr__ to ignore this method. - raise NotImplementedError diff --git a/python/Lib/importlib/_bootstrap.py b/python/Lib/importlib/_bootstrap.py deleted file mode 100644 index 846fd3f..0000000 --- a/python/Lib/importlib/_bootstrap.py +++ /dev/null @@ -1,1367 +0,0 @@ -"""Core implementation of import. - -This module is NOT meant to be directly imported! It has been designed such -that it can be bootstrapped into Python as the implementation of import. As -such it requires the injection of specific modules and attributes in order to -work. One should use importlib as the public-facing version of this module. - -""" -# -# IMPORTANT: Whenever making changes to this module, be sure to run a top-level -# `make regen-importlib` followed by `make` in order to get the frozen version -# of the module updated. Not doing so will result in the Makefile to fail for -# all others who don't have a ./python around to freeze the module -# in the early stages of compilation. -# - -# See importlib._setup() for what is injected into the global namespace. - -# When editing this code be aware that code executed at import time CANNOT -# reference any injected objects! This includes not only global code but also -# anything specified at the class level. - -def _object_name(obj): - try: - return obj.__qualname__ - except AttributeError: - return type(obj).__qualname__ - -# Bootstrap-related code ###################################################### - -# Modules injected manually by _setup() -_thread = None -_warnings = None -_weakref = None - -# Import done by _install_external_importers() -_bootstrap_external = None - - -def _wrap(new, old): - """Simple substitute for functools.update_wrapper.""" - for replace in ['__module__', '__name__', '__qualname__', '__doc__']: - if hasattr(old, replace): - setattr(new, replace, getattr(old, replace)) - new.__dict__.update(old.__dict__) - - -def _new_module(name): - return type(sys)(name) - - -# Module-level locking ######################################################## - -# A dict mapping module names to weakrefs of _ModuleLock instances -# Dictionary protected by the global import lock -_module_locks = {} -# A dict mapping thread ids to _ModuleLock instances -_blocking_on = {} - - -class _DeadlockError(RuntimeError): - pass - - -class _ModuleLock: - """A recursive lock implementation which is able to detect deadlocks - (e.g. thread 1 trying to take locks A then B, and thread 2 trying to - take locks B then A). - """ - - def __init__(self, name): - self.lock = _thread.allocate_lock() - self.wakeup = _thread.allocate_lock() - self.name = name - self.owner = None - self.count = 0 - self.waiters = 0 - - def has_deadlock(self): - # Deadlock avoidance for concurrent circular imports. - me = _thread.get_ident() - tid = self.owner - seen = set() - while True: - lock = _blocking_on.get(tid) - if lock is None: - return False - tid = lock.owner - if tid == me: - return True - if tid in seen: - # bpo 38091: the chain of tid's we encounter here - # eventually leads to a fixpoint or a cycle, but - # does not reach 'me'. This means we would not - # actually deadlock. This can happen if other - # threads are at the beginning of acquire() below. - return False - seen.add(tid) - - def acquire(self): - """ - Acquire the module lock. If a potential deadlock is detected, - a _DeadlockError is raised. - Otherwise, the lock is always acquired and True is returned. - """ - tid = _thread.get_ident() - _blocking_on[tid] = self - try: - while True: - with self.lock: - if self.count == 0 or self.owner == tid: - self.owner = tid - self.count += 1 - return True - if self.has_deadlock(): - raise _DeadlockError('deadlock detected by %r' % self) - if self.wakeup.acquire(False): - self.waiters += 1 - # Wait for a release() call - self.wakeup.acquire() - self.wakeup.release() - finally: - del _blocking_on[tid] - - def release(self): - tid = _thread.get_ident() - with self.lock: - if self.owner != tid: - raise RuntimeError('cannot release un-acquired lock') - assert self.count > 0 - self.count -= 1 - if self.count == 0: - self.owner = None - if self.waiters: - self.waiters -= 1 - self.wakeup.release() - - def __repr__(self): - return '_ModuleLock({!r}) at {}'.format(self.name, id(self)) - - -class _DummyModuleLock: - """A simple _ModuleLock equivalent for Python builds without - multi-threading support.""" - - def __init__(self, name): - self.name = name - self.count = 0 - - def acquire(self): - self.count += 1 - return True - - def release(self): - if self.count == 0: - raise RuntimeError('cannot release un-acquired lock') - self.count -= 1 - - def __repr__(self): - return '_DummyModuleLock({!r}) at {}'.format(self.name, id(self)) - - -class _ModuleLockManager: - - def __init__(self, name): - self._name = name - self._lock = None - - def __enter__(self): - self._lock = _get_module_lock(self._name) - self._lock.acquire() - - def __exit__(self, *args, **kwargs): - self._lock.release() - - -# The following two functions are for consumption by Python/import.c. - -def _get_module_lock(name): - """Get or create the module lock for a given module name. - - Acquire/release internally the global import lock to protect - _module_locks.""" - - _imp.acquire_lock() - try: - try: - lock = _module_locks[name]() - except KeyError: - lock = None - - if lock is None: - if _thread is None: - lock = _DummyModuleLock(name) - else: - lock = _ModuleLock(name) - - def cb(ref, name=name): - _imp.acquire_lock() - try: - # bpo-31070: Check if another thread created a new lock - # after the previous lock was destroyed - # but before the weakref callback was called. - if _module_locks.get(name) is ref: - del _module_locks[name] - finally: - _imp.release_lock() - - _module_locks[name] = _weakref.ref(lock, cb) - finally: - _imp.release_lock() - - return lock - - -def _lock_unlock_module(name): - """Acquires then releases the module lock for a given module name. - - This is used to ensure a module is completely initialized, in the - event it is being imported by another thread. - """ - lock = _get_module_lock(name) - try: - lock.acquire() - except _DeadlockError: - # Concurrent circular import, we'll accept a partially initialized - # module object. - pass - else: - lock.release() - -# Frame stripping magic ############################################### -def _call_with_frames_removed(f, *args, **kwds): - """remove_importlib_frames in import.c will always remove sequences - of importlib frames that end with a call to this function - - Use it instead of a normal call in places where including the importlib - frames introduces unwanted noise into the traceback (e.g. when executing - module code) - """ - return f(*args, **kwds) - - -def _verbose_message(message, *args, verbosity=1): - """Print the message to stderr if -v/PYTHONVERBOSE is turned on.""" - if sys.flags.verbose >= verbosity: - if not message.startswith(('#', 'import ')): - message = '# ' + message - print(message.format(*args), file=sys.stderr) - - -def _requires_builtin(fxn): - """Decorator to verify the named module is built-in.""" - def _requires_builtin_wrapper(self, fullname): - if fullname not in sys.builtin_module_names: - raise ImportError('{!r} is not a built-in module'.format(fullname), - name=fullname) - return fxn(self, fullname) - _wrap(_requires_builtin_wrapper, fxn) - return _requires_builtin_wrapper - - -def _requires_frozen(fxn): - """Decorator to verify the named module is frozen.""" - def _requires_frozen_wrapper(self, fullname): - if not _imp.is_frozen(fullname): - raise ImportError('{!r} is not a frozen module'.format(fullname), - name=fullname) - return fxn(self, fullname) - _wrap(_requires_frozen_wrapper, fxn) - return _requires_frozen_wrapper - - -# Typically used by loader classes as a method replacement. -def _load_module_shim(self, fullname): - """Load the specified module into sys.modules and return it. - - This method is deprecated. Use loader.exec_module() instead. - - """ - msg = ("the load_module() method is deprecated and slated for removal in " - "Python 3.12; use exec_module() instead") - _warnings.warn(msg, DeprecationWarning) - spec = spec_from_loader(fullname, self) - if fullname in sys.modules: - module = sys.modules[fullname] - _exec(spec, module) - return sys.modules[fullname] - else: - return _load(spec) - -# Module specifications ####################################################### - -def _module_repr(module): - """The implementation of ModuleType.__repr__().""" - loader = getattr(module, '__loader__', None) - if spec := getattr(module, "__spec__", None): - return _module_repr_from_spec(spec) - elif hasattr(loader, 'module_repr'): - try: - return loader.module_repr(module) - except Exception: - pass - # Fall through to a catch-all which always succeeds. - try: - name = module.__name__ - except AttributeError: - name = '?' - try: - filename = module.__file__ - except AttributeError: - if loader is None: - return ''.format(name) - else: - return ''.format(name, loader) - else: - return ''.format(name, filename) - - -class ModuleSpec: - """The specification for a module, used for loading. - - A module's spec is the source for information about the module. For - data associated with the module, including source, use the spec's - loader. - - `name` is the absolute name of the module. `loader` is the loader - to use when loading the module. `parent` is the name of the - package the module is in. The parent is derived from the name. - - `is_package` determines if the module is considered a package or - not. On modules this is reflected by the `__path__` attribute. - - `origin` is the specific location used by the loader from which to - load the module, if that information is available. When filename is - set, origin will match. - - `has_location` indicates that a spec's "origin" reflects a location. - When this is True, `__file__` attribute of the module is set. - - `cached` is the location of the cached bytecode file, if any. It - corresponds to the `__cached__` attribute. - - `submodule_search_locations` is the sequence of path entries to - search when importing submodules. If set, is_package should be - True--and False otherwise. - - Packages are simply modules that (may) have submodules. If a spec - has a non-None value in `submodule_search_locations`, the import - system will consider modules loaded from the spec as packages. - - Only finders (see importlib.abc.MetaPathFinder and - importlib.abc.PathEntryFinder) should modify ModuleSpec instances. - - """ - - def __init__(self, name, loader, *, origin=None, loader_state=None, - is_package=None): - self.name = name - self.loader = loader - self.origin = origin - self.loader_state = loader_state - self.submodule_search_locations = [] if is_package else None - self._uninitialized_submodules = [] - - # file-location attributes - self._set_fileattr = False - self._cached = None - - def __repr__(self): - args = ['name={!r}'.format(self.name), - 'loader={!r}'.format(self.loader)] - if self.origin is not None: - args.append('origin={!r}'.format(self.origin)) - if self.submodule_search_locations is not None: - args.append('submodule_search_locations={}' - .format(self.submodule_search_locations)) - return '{}({})'.format(self.__class__.__name__, ', '.join(args)) - - def __eq__(self, other): - smsl = self.submodule_search_locations - try: - return (self.name == other.name and - self.loader == other.loader and - self.origin == other.origin and - smsl == other.submodule_search_locations and - self.cached == other.cached and - self.has_location == other.has_location) - except AttributeError: - return NotImplemented - - @property - def cached(self): - if self._cached is None: - if self.origin is not None and self._set_fileattr: - if _bootstrap_external is None: - raise NotImplementedError - self._cached = _bootstrap_external._get_cached(self.origin) - return self._cached - - @cached.setter - def cached(self, cached): - self._cached = cached - - @property - def parent(self): - """The name of the module's parent.""" - if self.submodule_search_locations is None: - return self.name.rpartition('.')[0] - else: - return self.name - - @property - def has_location(self): - return self._set_fileattr - - @has_location.setter - def has_location(self, value): - self._set_fileattr = bool(value) - - -def spec_from_loader(name, loader, *, origin=None, is_package=None): - """Return a module spec based on various loader methods.""" - if origin is None: - origin = getattr(loader, '_ORIGIN', None) - - if not origin and hasattr(loader, 'get_filename'): - if _bootstrap_external is None: - raise NotImplementedError - spec_from_file_location = _bootstrap_external.spec_from_file_location - - if is_package is None: - return spec_from_file_location(name, loader=loader) - search = [] if is_package else None - return spec_from_file_location(name, loader=loader, - submodule_search_locations=search) - - if is_package is None: - if hasattr(loader, 'is_package'): - try: - is_package = loader.is_package(name) - except ImportError: - is_package = None # aka, undefined - else: - # the default - is_package = False - - return ModuleSpec(name, loader, origin=origin, is_package=is_package) - - -def _spec_from_module(module, loader=None, origin=None): - # This function is meant for use in _setup(). - try: - spec = module.__spec__ - except AttributeError: - pass - else: - if spec is not None: - return spec - - name = module.__name__ - if loader is None: - try: - loader = module.__loader__ - except AttributeError: - # loader will stay None. - pass - try: - location = module.__file__ - except AttributeError: - location = None - if origin is None: - if loader is not None: - origin = getattr(loader, '_ORIGIN', None) - if not origin and location is not None: - origin = location - try: - cached = module.__cached__ - except AttributeError: - cached = None - try: - submodule_search_locations = list(module.__path__) - except AttributeError: - submodule_search_locations = None - - spec = ModuleSpec(name, loader, origin=origin) - spec._set_fileattr = False if location is None else (origin == location) - spec.cached = cached - spec.submodule_search_locations = submodule_search_locations - return spec - - -def _init_module_attrs(spec, module, *, override=False): - # The passed-in module may be not support attribute assignment, - # in which case we simply don't set the attributes. - # __name__ - if (override or getattr(module, '__name__', None) is None): - try: - module.__name__ = spec.name - except AttributeError: - pass - # __loader__ - if override or getattr(module, '__loader__', None) is None: - loader = spec.loader - if loader is None: - # A backward compatibility hack. - if spec.submodule_search_locations is not None: - if _bootstrap_external is None: - raise NotImplementedError - NamespaceLoader = _bootstrap_external.NamespaceLoader - - loader = NamespaceLoader.__new__(NamespaceLoader) - loader._path = spec.submodule_search_locations - spec.loader = loader - # While the docs say that module.__file__ is not set for - # built-in modules, and the code below will avoid setting it if - # spec.has_location is false, this is incorrect for namespace - # packages. Namespace packages have no location, but their - # __spec__.origin is None, and thus their module.__file__ - # should also be None for consistency. While a bit of a hack, - # this is the best place to ensure this consistency. - # - # See # https://docs.python.org/3/library/importlib.html#importlib.abc.Loader.load_module - # and bpo-32305 - module.__file__ = None - try: - module.__loader__ = loader - except AttributeError: - pass - # __package__ - if override or getattr(module, '__package__', None) is None: - try: - module.__package__ = spec.parent - except AttributeError: - pass - # __spec__ - try: - module.__spec__ = spec - except AttributeError: - pass - # __path__ - if override or getattr(module, '__path__', None) is None: - if spec.submodule_search_locations is not None: - # XXX We should extend __path__ if it's already a list. - try: - module.__path__ = spec.submodule_search_locations - except AttributeError: - pass - # __file__/__cached__ - if spec.has_location: - if override or getattr(module, '__file__', None) is None: - try: - module.__file__ = spec.origin - except AttributeError: - pass - - if override or getattr(module, '__cached__', None) is None: - if spec.cached is not None: - try: - module.__cached__ = spec.cached - except AttributeError: - pass - return module - - -def module_from_spec(spec): - """Create a module based on the provided spec.""" - # Typically loaders will not implement create_module(). - module = None - if hasattr(spec.loader, 'create_module'): - # If create_module() returns `None` then it means default - # module creation should be used. - module = spec.loader.create_module(spec) - elif hasattr(spec.loader, 'exec_module'): - raise ImportError('loaders that define exec_module() ' - 'must also define create_module()') - if module is None: - module = _new_module(spec.name) - _init_module_attrs(spec, module) - return module - - -def _module_repr_from_spec(spec): - """Return the repr to use for the module.""" - # We mostly replicate _module_repr() using the spec attributes. - name = '?' if spec.name is None else spec.name - if spec.origin is None: - if spec.loader is None: - return ''.format(name) - else: - return ''.format(name, spec.loader) - else: - if spec.has_location: - return ''.format(name, spec.origin) - else: - return ''.format(spec.name, spec.origin) - - -# Used by importlib.reload() and _load_module_shim(). -def _exec(spec, module): - """Execute the spec's specified module in an existing module's namespace.""" - name = spec.name - with _ModuleLockManager(name): - if sys.modules.get(name) is not module: - msg = 'module {!r} not in sys.modules'.format(name) - raise ImportError(msg, name=name) - try: - if spec.loader is None: - if spec.submodule_search_locations is None: - raise ImportError('missing loader', name=spec.name) - # Namespace package. - _init_module_attrs(spec, module, override=True) - else: - _init_module_attrs(spec, module, override=True) - if not hasattr(spec.loader, 'exec_module'): - msg = (f"{_object_name(spec.loader)}.exec_module() not found; " - "falling back to load_module()") - _warnings.warn(msg, ImportWarning) - spec.loader.load_module(name) - else: - spec.loader.exec_module(module) - finally: - # Update the order of insertion into sys.modules for module - # clean-up at shutdown. - module = sys.modules.pop(spec.name) - sys.modules[spec.name] = module - return module - - -def _load_backward_compatible(spec): - # It is assumed that all callers have been warned about using load_module() - # appropriately before calling this function. - try: - spec.loader.load_module(spec.name) - except: - if spec.name in sys.modules: - module = sys.modules.pop(spec.name) - sys.modules[spec.name] = module - raise - # The module must be in sys.modules at this point! - # Move it to the end of sys.modules. - module = sys.modules.pop(spec.name) - sys.modules[spec.name] = module - if getattr(module, '__loader__', None) is None: - try: - module.__loader__ = spec.loader - except AttributeError: - pass - if getattr(module, '__package__', None) is None: - try: - # Since module.__path__ may not line up with - # spec.submodule_search_paths, we can't necessarily rely - # on spec.parent here. - module.__package__ = module.__name__ - if not hasattr(module, '__path__'): - module.__package__ = spec.name.rpartition('.')[0] - except AttributeError: - pass - if getattr(module, '__spec__', None) is None: - try: - module.__spec__ = spec - except AttributeError: - pass - return module - -def _load_unlocked(spec): - # A helper for direct use by the import system. - if spec.loader is not None: - # Not a namespace package. - if not hasattr(spec.loader, 'exec_module'): - msg = (f"{_object_name(spec.loader)}.exec_module() not found; " - "falling back to load_module()") - _warnings.warn(msg, ImportWarning) - return _load_backward_compatible(spec) - - module = module_from_spec(spec) - - # This must be done before putting the module in sys.modules - # (otherwise an optimization shortcut in import.c becomes - # wrong). - spec._initializing = True - try: - sys.modules[spec.name] = module - try: - if spec.loader is None: - if spec.submodule_search_locations is None: - raise ImportError('missing loader', name=spec.name) - # A namespace package so do nothing. - else: - spec.loader.exec_module(module) - except: - try: - del sys.modules[spec.name] - except KeyError: - pass - raise - # Move the module to the end of sys.modules. - # We don't ensure that the import-related module attributes get - # set in the sys.modules replacement case. Such modules are on - # their own. - module = sys.modules.pop(spec.name) - sys.modules[spec.name] = module - _verbose_message('import {!r} # {!r}', spec.name, spec.loader) - finally: - spec._initializing = False - - return module - -# A method used during testing of _load_unlocked() and by -# _load_module_shim(). -def _load(spec): - """Return a new module object, loaded by the spec's loader. - - The module is not added to its parent. - - If a module is already in sys.modules, that existing module gets - clobbered. - - """ - with _ModuleLockManager(spec.name): - return _load_unlocked(spec) - - -# Loaders ##################################################################### - -class BuiltinImporter: - - """Meta path import for built-in modules. - - All methods are either class or static methods to avoid the need to - instantiate the class. - - """ - - _ORIGIN = "built-in" - - @staticmethod - def module_repr(module): - """Return repr for the module. - - The method is deprecated. The import machinery does the job itself. - - """ - _warnings.warn("BuiltinImporter.module_repr() is deprecated and " - "slated for removal in Python 3.12", DeprecationWarning) - return f'' - - @classmethod - def find_spec(cls, fullname, path=None, target=None): - if path is not None: - return None - if _imp.is_builtin(fullname): - return spec_from_loader(fullname, cls, origin=cls._ORIGIN) - else: - return None - - @classmethod - def find_module(cls, fullname, path=None): - """Find the built-in module. - - If 'path' is ever specified then the search is considered a failure. - - This method is deprecated. Use find_spec() instead. - - """ - _warnings.warn("BuiltinImporter.find_module() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - spec = cls.find_spec(fullname, path) - return spec.loader if spec is not None else None - - @staticmethod - def create_module(spec): - """Create a built-in module""" - if spec.name not in sys.builtin_module_names: - raise ImportError('{!r} is not a built-in module'.format(spec.name), - name=spec.name) - return _call_with_frames_removed(_imp.create_builtin, spec) - - @staticmethod - def exec_module(module): - """Exec a built-in module""" - _call_with_frames_removed(_imp.exec_builtin, module) - - @classmethod - @_requires_builtin - def get_code(cls, fullname): - """Return None as built-in modules do not have code objects.""" - return None - - @classmethod - @_requires_builtin - def get_source(cls, fullname): - """Return None as built-in modules do not have source code.""" - return None - - @classmethod - @_requires_builtin - def is_package(cls, fullname): - """Return False as built-in modules are never packages.""" - return False - - load_module = classmethod(_load_module_shim) - - -class FrozenImporter: - - """Meta path import for frozen modules. - - All methods are either class or static methods to avoid the need to - instantiate the class. - - """ - - _ORIGIN = "frozen" - - @staticmethod - def module_repr(m): - """Return repr for the module. - - The method is deprecated. The import machinery does the job itself. - - """ - _warnings.warn("FrozenImporter.module_repr() is deprecated and " - "slated for removal in Python 3.12", DeprecationWarning) - return ''.format(m.__name__, FrozenImporter._ORIGIN) - - @classmethod - def _fix_up_module(cls, module): - spec = module.__spec__ - state = spec.loader_state - if state is None: - # The module is missing FrozenImporter-specific values. - - # Fix up the spec attrs. - origname = vars(module).pop('__origname__', None) - assert origname, 'see PyImport_ImportFrozenModuleObject()' - ispkg = hasattr(module, '__path__') - assert _imp.is_frozen_package(module.__name__) == ispkg, ispkg - filename, pkgdir = cls._resolve_filename(origname, spec.name, ispkg) - spec.loader_state = type(sys.implementation)( - filename=filename, - origname=origname, - ) - __path__ = spec.submodule_search_locations - if ispkg: - assert __path__ == [], __path__ - if pkgdir: - spec.submodule_search_locations.insert(0, pkgdir) - else: - assert __path__ is None, __path__ - - # Fix up the module attrs (the bare minimum). - assert not hasattr(module, '__file__'), module.__file__ - if filename: - try: - module.__file__ = filename - except AttributeError: - pass - if ispkg: - if module.__path__ != __path__: - assert module.__path__ == [], module.__path__ - module.__path__.extend(__path__) - else: - # These checks ensure that _fix_up_module() is only called - # in the right places. - __path__ = spec.submodule_search_locations - ispkg = __path__ is not None - # Check the loader state. - assert sorted(vars(state)) == ['filename', 'origname'], state - if state.origname: - # The only frozen modules with "origname" set are stdlib modules. - (__file__, pkgdir, - ) = cls._resolve_filename(state.origname, spec.name, ispkg) - assert state.filename == __file__, (state.filename, __file__) - if pkgdir: - assert __path__ == [pkgdir], (__path__, pkgdir) - else: - assert __path__ == ([] if ispkg else None), __path__ - else: - __file__ = None - assert state.filename is None, state.filename - assert __path__ == ([] if ispkg else None), __path__ - # Check the file attrs. - if __file__: - assert hasattr(module, '__file__') - assert module.__file__ == __file__, (module.__file__, __file__) - else: - assert not hasattr(module, '__file__'), module.__file__ - if ispkg: - assert hasattr(module, '__path__') - assert module.__path__ == __path__, (module.__path__, __path__) - else: - assert not hasattr(module, '__path__'), module.__path__ - assert not spec.has_location - - @classmethod - def _resolve_filename(cls, fullname, alias=None, ispkg=False): - if not fullname or not getattr(sys, '_stdlib_dir', None): - return None, None - try: - sep = cls._SEP - except AttributeError: - sep = cls._SEP = '\\' if sys.platform == 'win32' else '/' - - if fullname != alias: - if fullname.startswith('<'): - fullname = fullname[1:] - if not ispkg: - fullname = f'{fullname}.__init__' - else: - ispkg = False - relfile = fullname.replace('.', sep) - if ispkg: - pkgdir = f'{sys._stdlib_dir}{sep}{relfile}' - filename = f'{pkgdir}{sep}__init__.py' - else: - pkgdir = None - filename = f'{sys._stdlib_dir}{sep}{relfile}.py' - return filename, pkgdir - - @classmethod - def find_spec(cls, fullname, path=None, target=None): - info = _call_with_frames_removed(_imp.find_frozen, fullname) - if info is None: - return None - # We get the marshaled data in exec_module() (the loader - # part of the importer), instead of here (the finder part). - # The loader is the usual place to get the data that will - # be loaded into the module. (For example, see _LoaderBasics - # in _bootstra_external.py.) Most importantly, this importer - # is simpler if we wait to get the data. - # However, getting as much data in the finder as possible - # to later load the module is okay, and sometimes important. - # (That's why ModuleSpec.loader_state exists.) This is - # especially true if it avoids throwing away expensive data - # the loader would otherwise duplicate later and can be done - # efficiently. In this case it isn't worth it. - _, ispkg, origname = info - spec = spec_from_loader(fullname, cls, - origin=cls._ORIGIN, - is_package=ispkg) - filename, pkgdir = cls._resolve_filename(origname, fullname, ispkg) - spec.loader_state = type(sys.implementation)( - filename=filename, - origname=origname, - ) - if pkgdir: - spec.submodule_search_locations.insert(0, pkgdir) - return spec - - @classmethod - def find_module(cls, fullname, path=None): - """Find a frozen module. - - This method is deprecated. Use find_spec() instead. - - """ - _warnings.warn("FrozenImporter.find_module() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - return cls if _imp.is_frozen(fullname) else None - - @staticmethod - def create_module(spec): - """Set __file__, if able.""" - module = _new_module(spec.name) - try: - filename = spec.loader_state.filename - except AttributeError: - pass - else: - if filename: - module.__file__ = filename - return module - - @staticmethod - def exec_module(module): - spec = module.__spec__ - name = spec.name - code = _call_with_frames_removed(_imp.get_frozen_object, name) - exec(code, module.__dict__) - - @classmethod - def load_module(cls, fullname): - """Load a frozen module. - - This method is deprecated. Use exec_module() instead. - - """ - # Warning about deprecation implemented in _load_module_shim(). - module = _load_module_shim(cls, fullname) - info = _imp.find_frozen(fullname) - assert info is not None - _, ispkg, origname = info - module.__origname__ = origname - vars(module).pop('__file__', None) - if ispkg: - module.__path__ = [] - cls._fix_up_module(module) - return module - - @classmethod - @_requires_frozen - def get_code(cls, fullname): - """Return the code object for the frozen module.""" - return _imp.get_frozen_object(fullname) - - @classmethod - @_requires_frozen - def get_source(cls, fullname): - """Return None as frozen modules do not have source code.""" - return None - - @classmethod - @_requires_frozen - def is_package(cls, fullname): - """Return True if the frozen module is a package.""" - return _imp.is_frozen_package(fullname) - - -# Import itself ############################################################### - -class _ImportLockContext: - - """Context manager for the import lock.""" - - def __enter__(self): - """Acquire the import lock.""" - _imp.acquire_lock() - - def __exit__(self, exc_type, exc_value, exc_traceback): - """Release the import lock regardless of any raised exceptions.""" - _imp.release_lock() - - -def _resolve_name(name, package, level): - """Resolve a relative module name to an absolute one.""" - bits = package.rsplit('.', level - 1) - if len(bits) < level: - raise ImportError('attempted relative import beyond top-level package') - base = bits[0] - return '{}.{}'.format(base, name) if name else base - - -def _find_spec_legacy(finder, name, path): - msg = (f"{_object_name(finder)}.find_spec() not found; " - "falling back to find_module()") - _warnings.warn(msg, ImportWarning) - loader = finder.find_module(name, path) - if loader is None: - return None - return spec_from_loader(name, loader) - - -def _find_spec(name, path, target=None): - """Find a module's spec.""" - meta_path = sys.meta_path - if meta_path is None: - # PyImport_Cleanup() is running or has been called. - raise ImportError("sys.meta_path is None, Python is likely " - "shutting down") - - if not meta_path: - _warnings.warn('sys.meta_path is empty', ImportWarning) - - # We check sys.modules here for the reload case. While a passed-in - # target will usually indicate a reload there is no guarantee, whereas - # sys.modules provides one. - is_reload = name in sys.modules - for finder in meta_path: - with _ImportLockContext(): - try: - find_spec = finder.find_spec - except AttributeError: - spec = _find_spec_legacy(finder, name, path) - if spec is None: - continue - else: - spec = find_spec(name, path, target) - if spec is not None: - # The parent import may have already imported this module. - if not is_reload and name in sys.modules: - module = sys.modules[name] - try: - __spec__ = module.__spec__ - except AttributeError: - # We use the found spec since that is the one that - # we would have used if the parent module hadn't - # beaten us to the punch. - return spec - else: - if __spec__ is None: - return spec - else: - return __spec__ - else: - return spec - else: - return None - - -def _sanity_check(name, package, level): - """Verify arguments are "sane".""" - if not isinstance(name, str): - raise TypeError('module name must be str, not {}'.format(type(name))) - if level < 0: - raise ValueError('level must be >= 0') - if level > 0: - if not isinstance(package, str): - raise TypeError('__package__ not set to a string') - elif not package: - raise ImportError('attempted relative import with no known parent ' - 'package') - if not name and level == 0: - raise ValueError('Empty module name') - - -_ERR_MSG_PREFIX = 'No module named ' -_ERR_MSG = _ERR_MSG_PREFIX + '{!r}' - -def _find_and_load_unlocked(name, import_): - path = None - parent = name.rpartition('.')[0] - parent_spec = None - if parent: - if parent not in sys.modules: - _call_with_frames_removed(import_, parent) - # Crazy side-effects! - if name in sys.modules: - return sys.modules[name] - parent_module = sys.modules[parent] - try: - path = parent_module.__path__ - except AttributeError: - msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent) - raise ModuleNotFoundError(msg, name=name) from None - parent_spec = parent_module.__spec__ - child = name.rpartition('.')[2] - spec = _find_spec(name, path) - if spec is None: - raise ModuleNotFoundError(_ERR_MSG.format(name), name=name) - else: - if parent_spec: - # Temporarily add child we are currently importing to parent's - # _uninitialized_submodules for circular import tracking. - parent_spec._uninitialized_submodules.append(child) - try: - module = _load_unlocked(spec) - finally: - if parent_spec: - parent_spec._uninitialized_submodules.pop() - if parent: - # Set the module as an attribute on its parent. - parent_module = sys.modules[parent] - try: - setattr(parent_module, child, module) - except AttributeError: - msg = f"Cannot set an attribute on {parent!r} for child module {child!r}" - _warnings.warn(msg, ImportWarning) - return module - - -_NEEDS_LOADING = object() - - -def _find_and_load(name, import_): - """Find and load the module.""" - - # Optimization: we avoid unneeded module locking if the module - # already exists in sys.modules and is fully initialized. - module = sys.modules.get(name, _NEEDS_LOADING) - if (module is _NEEDS_LOADING or - getattr(getattr(module, "__spec__", None), "_initializing", False)): - with _ModuleLockManager(name): - module = sys.modules.get(name, _NEEDS_LOADING) - if module is _NEEDS_LOADING: - return _find_and_load_unlocked(name, import_) - - # Optimization: only call _bootstrap._lock_unlock_module() if - # module.__spec__._initializing is True. - # NOTE: because of this, initializing must be set *before* - # putting the new module in sys.modules. - _lock_unlock_module(name) - - if module is None: - message = ('import of {} halted; ' - 'None in sys.modules'.format(name)) - raise ModuleNotFoundError(message, name=name) - - return module - - -def _gcd_import(name, package=None, level=0): - """Import and return the module based on its name, the package the call is - being made from, and the level adjustment. - - This function represents the greatest common denominator of functionality - between import_module and __import__. This includes setting __package__ if - the loader did not. - - """ - _sanity_check(name, package, level) - if level > 0: - name = _resolve_name(name, package, level) - return _find_and_load(name, _gcd_import) - - -def _handle_fromlist(module, fromlist, import_, *, recursive=False): - """Figure out what __import__ should return. - - The import_ parameter is a callable which takes the name of module to - import. It is required to decouple the function from assuming importlib's - import implementation is desired. - - """ - # The hell that is fromlist ... - # If a package was imported, try to import stuff from fromlist. - for x in fromlist: - if not isinstance(x, str): - if recursive: - where = module.__name__ + '.__all__' - else: - where = "``from list''" - raise TypeError(f"Item in {where} must be str, " - f"not {type(x).__name__}") - elif x == '*': - if not recursive and hasattr(module, '__all__'): - _handle_fromlist(module, module.__all__, import_, - recursive=True) - elif not hasattr(module, x): - from_name = '{}.{}'.format(module.__name__, x) - try: - _call_with_frames_removed(import_, from_name) - except ModuleNotFoundError as exc: - # Backwards-compatibility dictates we ignore failed - # imports triggered by fromlist for modules that don't - # exist. - if (exc.name == from_name and - sys.modules.get(from_name, _NEEDS_LOADING) is not None): - continue - raise - return module - - -def _calc___package__(globals): - """Calculate what __package__ should be. - - __package__ is not guaranteed to be defined or could be set to None - to represent that its proper value is unknown. - - """ - package = globals.get('__package__') - spec = globals.get('__spec__') - if package is not None: - if spec is not None and package != spec.parent: - _warnings.warn("__package__ != __spec__.parent " - f"({package!r} != {spec.parent!r})", - ImportWarning, stacklevel=3) - return package - elif spec is not None: - return spec.parent - else: - _warnings.warn("can't resolve package from __spec__ or __package__, " - "falling back on __name__ and __path__", - ImportWarning, stacklevel=3) - package = globals['__name__'] - if '__path__' not in globals: - package = package.rpartition('.')[0] - return package - - -def __import__(name, globals=None, locals=None, fromlist=(), level=0): - """Import a module. - - The 'globals' argument is used to infer where the import is occurring from - to handle relative imports. The 'locals' argument is ignored. The - 'fromlist' argument specifies what should exist as attributes on the module - being imported (e.g. ``from module import ``). The 'level' - argument represents the package location to import from in a relative - import (e.g. ``from ..pkg import mod`` would have a 'level' of 2). - - """ - if level == 0: - module = _gcd_import(name) - else: - globals_ = globals if globals is not None else {} - package = _calc___package__(globals_) - module = _gcd_import(name, package, level) - if not fromlist: - # Return up to the first dot in 'name'. This is complicated by the fact - # that 'name' may be relative. - if level == 0: - return _gcd_import(name.partition('.')[0]) - elif not name: - return module - else: - # Figure out where to slice the module's name up to the first dot - # in 'name'. - cut_off = len(name) - len(name.partition('.')[0]) - # Slice end needs to be positive to alleviate need to special-case - # when ``'.' not in name``. - return sys.modules[module.__name__[:len(module.__name__)-cut_off]] - elif hasattr(module, '__path__'): - return _handle_fromlist(module, fromlist, _gcd_import) - else: - return module - - -def _builtin_from_name(name): - spec = BuiltinImporter.find_spec(name) - if spec is None: - raise ImportError('no built-in module named ' + name) - return _load_unlocked(spec) - - -def _setup(sys_module, _imp_module): - """Setup importlib by importing needed built-in modules and injecting them - into the global namespace. - - As sys is needed for sys.modules access and _imp is needed to load built-in - modules, those two modules must be explicitly passed in. - - """ - global _imp, sys - _imp = _imp_module - sys = sys_module - - # Set up the spec for existing builtin/frozen modules. - module_type = type(sys) - for name, module in sys.modules.items(): - if isinstance(module, module_type): - if name in sys.builtin_module_names: - loader = BuiltinImporter - elif _imp.is_frozen(name): - loader = FrozenImporter - else: - continue - spec = _spec_from_module(module, loader) - _init_module_attrs(spec, module) - if loader is FrozenImporter: - loader._fix_up_module(module) - - # Directly load built-in modules needed during bootstrap. - self_module = sys.modules[__name__] - for builtin_name in ('_thread', '_warnings', '_weakref'): - if builtin_name not in sys.modules: - builtin_module = _builtin_from_name(builtin_name) - else: - builtin_module = sys.modules[builtin_name] - setattr(self_module, builtin_name, builtin_module) - - -def _install(sys_module, _imp_module): - """Install importers for builtin and frozen modules""" - _setup(sys_module, _imp_module) - - sys.meta_path.append(BuiltinImporter) - sys.meta_path.append(FrozenImporter) - - -def _install_external_importers(): - """Install importers that require external filesystem access""" - global _bootstrap_external - import _frozen_importlib_external - _bootstrap_external = _frozen_importlib_external - _frozen_importlib_external._install(sys.modules[__name__]) diff --git a/python/Lib/importlib/_bootstrap_external.py b/python/Lib/importlib/_bootstrap_external.py deleted file mode 100644 index 7e599cc..0000000 --- a/python/Lib/importlib/_bootstrap_external.py +++ /dev/null @@ -1,1754 +0,0 @@ -"""Core implementation of path-based import. - -This module is NOT meant to be directly imported! It has been designed such -that it can be bootstrapped into Python as the implementation of import. As -such it requires the injection of specific modules and attributes in order to -work. One should use importlib as the public-facing version of this module. - -""" -# IMPORTANT: Whenever making changes to this module, be sure to run a top-level -# `make regen-importlib` followed by `make` in order to get the frozen version -# of the module updated. Not doing so will result in the Makefile to fail for -# all others who don't have a ./python around to freeze the module in the early -# stages of compilation. -# - -# See importlib._setup() for what is injected into the global namespace. - -# When editing this code be aware that code executed at import time CANNOT -# reference any injected objects! This includes not only global code but also -# anything specified at the class level. - -# Module injected manually by _set_bootstrap_module() -_bootstrap = None - -# Import builtin modules -import _imp -import _io -import sys -import _warnings -import marshal - - -_MS_WINDOWS = (sys.platform == 'win32') -if _MS_WINDOWS: - import nt as _os - import winreg -else: - import posix as _os - - -if _MS_WINDOWS: - path_separators = ['\\', '/'] -else: - path_separators = ['/'] -# Assumption made in _path_join() -assert all(len(sep) == 1 for sep in path_separators) -path_sep = path_separators[0] -path_sep_tuple = tuple(path_separators) -path_separators = ''.join(path_separators) -_pathseps_with_colon = {f':{s}' for s in path_separators} - - -# Bootstrap-related code ###################################################### -_CASE_INSENSITIVE_PLATFORMS_STR_KEY = 'win', -_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'darwin' -_CASE_INSENSITIVE_PLATFORMS = (_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY - + _CASE_INSENSITIVE_PLATFORMS_STR_KEY) - - -def _make_relax_case(): - if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): - if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS_STR_KEY): - key = 'PYTHONCASEOK' - else: - key = b'PYTHONCASEOK' - - def _relax_case(): - """True if filenames must be checked case-insensitively and ignore environment flags are not set.""" - return not sys.flags.ignore_environment and key in _os.environ - else: - def _relax_case(): - """True if filenames must be checked case-insensitively.""" - return False - return _relax_case - -_relax_case = _make_relax_case() - - -def _pack_uint32(x): - """Convert a 32-bit integer to little-endian.""" - return (int(x) & 0xFFFFFFFF).to_bytes(4, 'little') - - -def _unpack_uint32(data): - """Convert 4 bytes in little-endian to an integer.""" - assert len(data) == 4 - return int.from_bytes(data, 'little') - -def _unpack_uint16(data): - """Convert 2 bytes in little-endian to an integer.""" - assert len(data) == 2 - return int.from_bytes(data, 'little') - - -if _MS_WINDOWS: - def _path_join(*path_parts): - """Replacement for os.path.join().""" - if not path_parts: - return "" - if len(path_parts) == 1: - return path_parts[0] - root = "" - path = [] - for new_root, tail in map(_os._path_splitroot, path_parts): - if new_root.startswith(path_sep_tuple) or new_root.endswith(path_sep_tuple): - root = new_root.rstrip(path_separators) or root - path = [path_sep + tail] - elif new_root.endswith(':'): - if root.casefold() != new_root.casefold(): - # Drive relative paths have to be resolved by the OS, so we reset the - # tail but do not add a path_sep prefix. - root = new_root - path = [tail] - else: - path.append(tail) - else: - root = new_root or root - path.append(tail) - path = [p.rstrip(path_separators) for p in path if p] - if len(path) == 1 and not path[0]: - # Avoid losing the root's trailing separator when joining with nothing - return root + path_sep - return root + path_sep.join(path) - -else: - def _path_join(*path_parts): - """Replacement for os.path.join().""" - return path_sep.join([part.rstrip(path_separators) - for part in path_parts if part]) - - -def _path_split(path): - """Replacement for os.path.split().""" - i = max(path.rfind(p) for p in path_separators) - if i < 0: - return '', path - return path[:i], path[i + 1:] - - -def _path_stat(path): - """Stat the path. - - Made a separate function to make it easier to override in experiments - (e.g. cache stat results). - - """ - return _os.stat(path) - - -def _path_is_mode_type(path, mode): - """Test whether the path is the specified mode type.""" - try: - stat_info = _path_stat(path) - except OSError: - return False - return (stat_info.st_mode & 0o170000) == mode - - -def _path_isfile(path): - """Replacement for os.path.isfile.""" - return _path_is_mode_type(path, 0o100000) - - -def _path_isdir(path): - """Replacement for os.path.isdir.""" - if not path: - path = _os.getcwd() - return _path_is_mode_type(path, 0o040000) - - -if _MS_WINDOWS: - def _path_isabs(path): - """Replacement for os.path.isabs.""" - if not path: - return False - root = _os._path_splitroot(path)[0].replace('/', '\\') - return len(root) > 1 and (root.startswith('\\\\') or root.endswith('\\')) - -else: - def _path_isabs(path): - """Replacement for os.path.isabs.""" - return path.startswith(path_separators) - - -def _write_atomic(path, data, mode=0o666): - """Best-effort function to write data to a path atomically. - Be prepared to handle a FileExistsError if concurrent writing of the - temporary file is attempted.""" - # id() is used to generate a pseudo-random filename. - path_tmp = '{}.{}'.format(path, id(path)) - fd = _os.open(path_tmp, - _os.O_EXCL | _os.O_CREAT | _os.O_WRONLY, mode & 0o666) - try: - # We first write data to a temporary file, and then use os.replace() to - # perform an atomic rename. - with _io.FileIO(fd, 'wb') as file: - file.write(data) - _os.replace(path_tmp, path) - except OSError: - try: - _os.unlink(path_tmp) - except OSError: - pass - raise - - -_code_type = type(_write_atomic.__code__) - - -# Finder/loader utility code ############################################### - -# Magic word to reject .pyc files generated by other Python versions. -# It should change for each incompatible change to the bytecode. -# -# The value of CR and LF is incorporated so if you ever read or write -# a .pyc file in text mode the magic number will be wrong; also, the -# Apple MPW compiler swaps their values, botching string constants. -# -# There were a variety of old schemes for setting the magic number. -# The current working scheme is to increment the previous value by -# 10. -# -# Starting with the adoption of PEP 3147 in Python 3.2, every bump in magic -# number also includes a new "magic tag", i.e. a human readable string used -# to represent the magic number in __pycache__ directories. When you change -# the magic number, you must also set a new unique magic tag. Generally this -# can be named after the Python major version of the magic number bump, but -# it can really be anything, as long as it's different than anything else -# that's come before. The tags are included in the following table, starting -# with Python 3.2a0. -# -# Known values: -# Python 1.5: 20121 -# Python 1.5.1: 20121 -# Python 1.5.2: 20121 -# Python 1.6: 50428 -# Python 2.0: 50823 -# Python 2.0.1: 50823 -# Python 2.1: 60202 -# Python 2.1.1: 60202 -# Python 2.1.2: 60202 -# Python 2.2: 60717 -# Python 2.3a0: 62011 -# Python 2.3a0: 62021 -# Python 2.3a0: 62011 (!) -# Python 2.4a0: 62041 -# Python 2.4a3: 62051 -# Python 2.4b1: 62061 -# Python 2.5a0: 62071 -# Python 2.5a0: 62081 (ast-branch) -# Python 2.5a0: 62091 (with) -# Python 2.5a0: 62092 (changed WITH_CLEANUP opcode) -# Python 2.5b3: 62101 (fix wrong code: for x, in ...) -# Python 2.5b3: 62111 (fix wrong code: x += yield) -# Python 2.5c1: 62121 (fix wrong lnotab with for loops and -# storing constants that should have been removed) -# Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp) -# Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode) -# Python 2.6a1: 62161 (WITH_CLEANUP optimization) -# Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND) -# Python 2.7a0: 62181 (optimize conditional branches: -# introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) -# Python 2.7a0 62191 (introduce SETUP_WITH) -# Python 2.7a0 62201 (introduce BUILD_SET) -# Python 2.7a0 62211 (introduce MAP_ADD and SET_ADD) -# Python 3000: 3000 -# 3010 (removed UNARY_CONVERT) -# 3020 (added BUILD_SET) -# 3030 (added keyword-only parameters) -# 3040 (added signature annotations) -# 3050 (print becomes a function) -# 3060 (PEP 3115 metaclass syntax) -# 3061 (string literals become unicode) -# 3071 (PEP 3109 raise changes) -# 3081 (PEP 3137 make __file__ and __name__ unicode) -# 3091 (kill str8 interning) -# 3101 (merge from 2.6a0, see 62151) -# 3103 (__file__ points to source file) -# Python 3.0a4: 3111 (WITH_CLEANUP optimization). -# Python 3.0b1: 3131 (lexical exception stacking, including POP_EXCEPT - #3021) -# Python 3.1a1: 3141 (optimize list, set and dict comprehensions: -# change LIST_APPEND and SET_ADD, add MAP_ADD #2183) -# Python 3.1a1: 3151 (optimize conditional branches: -# introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE - #4715) -# Python 3.2a1: 3160 (add SETUP_WITH #6101) -# tag: cpython-32 -# Python 3.2a2: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR #9225) -# tag: cpython-32 -# Python 3.2a3 3180 (add DELETE_DEREF #4617) -# Python 3.3a1 3190 (__class__ super closure changed) -# Python 3.3a1 3200 (PEP 3155 __qualname__ added #13448) -# Python 3.3a1 3210 (added size modulo 2**32 to the pyc header #13645) -# Python 3.3a2 3220 (changed PEP 380 implementation #14230) -# Python 3.3a4 3230 (revert changes to implicit __class__ closure #14857) -# Python 3.4a1 3250 (evaluate positional default arguments before -# keyword-only defaults #16967) -# Python 3.4a1 3260 (add LOAD_CLASSDEREF; allow locals of class to override -# free vars #17853) -# Python 3.4a1 3270 (various tweaks to the __class__ closure #12370) -# Python 3.4a1 3280 (remove implicit class argument) -# Python 3.4a4 3290 (changes to __qualname__ computation #19301) -# Python 3.4a4 3300 (more changes to __qualname__ computation #19301) -# Python 3.4rc2 3310 (alter __qualname__ computation #20625) -# Python 3.5a1 3320 (PEP 465: Matrix multiplication operator #21176) -# Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations #2292) -# Python 3.5b2 3340 (fix dictionary display evaluation order #11205) -# Python 3.5b3 3350 (add GET_YIELD_FROM_ITER opcode #24400) -# Python 3.5.2 3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286) -# Python 3.6a0 3360 (add FORMAT_VALUE opcode #25483) -# Python 3.6a1 3361 (lineno delta of code.co_lnotab becomes signed #26107) -# Python 3.6a2 3370 (16 bit wordcode #26647) -# Python 3.6a2 3371 (add BUILD_CONST_KEY_MAP opcode #27140) -# Python 3.6a2 3372 (MAKE_FUNCTION simplification, remove MAKE_CLOSURE -# #27095) -# Python 3.6b1 3373 (add BUILD_STRING opcode #27078) -# Python 3.6b1 3375 (add SETUP_ANNOTATIONS and STORE_ANNOTATION opcodes -# #27985) -# Python 3.6b1 3376 (simplify CALL_FUNCTIONs & BUILD_MAP_UNPACK_WITH_CALL - #27213) -# Python 3.6b1 3377 (set __class__ cell from type.__new__ #23722) -# Python 3.6b2 3378 (add BUILD_TUPLE_UNPACK_WITH_CALL #28257) -# Python 3.6rc1 3379 (more thorough __class__ validation #23722) -# Python 3.7a1 3390 (add LOAD_METHOD and CALL_METHOD opcodes #26110) -# Python 3.7a2 3391 (update GET_AITER #31709) -# Python 3.7a4 3392 (PEP 552: Deterministic pycs #31650) -# Python 3.7b1 3393 (remove STORE_ANNOTATION opcode #32550) -# Python 3.7b5 3394 (restored docstring as the first stmt in the body; -# this might affected the first line number #32911) -# Python 3.8a1 3400 (move frame block handling to compiler #17611) -# Python 3.8a1 3401 (add END_ASYNC_FOR #33041) -# Python 3.8a1 3410 (PEP570 Python Positional-Only Parameters #36540) -# Python 3.8b2 3411 (Reverse evaluation order of key: value in dict -# comprehensions #35224) -# Python 3.8b2 3412 (Swap the position of positional args and positional -# only args in ast.arguments #37593) -# Python 3.8b4 3413 (Fix "break" and "continue" in "finally" #37830) -# Python 3.9a0 3420 (add LOAD_ASSERTION_ERROR #34880) -# Python 3.9a0 3421 (simplified bytecode for with blocks #32949) -# Python 3.9a0 3422 (remove BEGIN_FINALLY, END_FINALLY, CALL_FINALLY, POP_FINALLY bytecodes #33387) -# Python 3.9a2 3423 (add IS_OP, CONTAINS_OP and JUMP_IF_NOT_EXC_MATCH bytecodes #39156) -# Python 3.9a2 3424 (simplify bytecodes for *value unpacking) -# Python 3.9a2 3425 (simplify bytecodes for **value unpacking) -# Python 3.10a1 3430 (Make 'annotations' future by default) -# Python 3.10a1 3431 (New line number table format -- PEP 626) -# Python 3.10a2 3432 (Function annotation for MAKE_FUNCTION is changed from dict to tuple bpo-42202) -# Python 3.10a2 3433 (RERAISE restores f_lasti if oparg != 0) -# Python 3.10a6 3434 (PEP 634: Structural Pattern Matching) -# Python 3.10a7 3435 Use instruction offsets (as opposed to byte offsets). -# Python 3.10b1 3436 (Add GEN_START bytecode #43683) -# Python 3.10b1 3437 (Undo making 'annotations' future by default - We like to dance among core devs!) -# Python 3.10b1 3438 Safer line number table handling. -# Python 3.10b1 3439 (Add ROT_N) -# Python 3.11a1 3450 Use exception table for unwinding ("zero cost" exception handling) -# Python 3.11a1 3451 (Add CALL_METHOD_KW) -# Python 3.11a1 3452 (drop nlocals from marshaled code objects) -# Python 3.11a1 3453 (add co_fastlocalnames and co_fastlocalkinds) -# Python 3.11a1 3454 (compute cell offsets relative to locals bpo-43693) -# Python 3.11a1 3455 (add MAKE_CELL bpo-43693) -# Python 3.11a1 3456 (interleave cell args bpo-43693) -# Python 3.11a1 3457 (Change localsplus to a bytes object bpo-43693) -# Python 3.11a1 3458 (imported objects now don't use LOAD_METHOD/CALL_METHOD) -# Python 3.11a1 3459 (PEP 657: add end line numbers and column offsets for instructions) -# Python 3.11a1 3460 (Add co_qualname field to PyCodeObject bpo-44530) -# Python 3.11a1 3461 (JUMP_ABSOLUTE must jump backwards) -# Python 3.11a2 3462 (bpo-44511: remove COPY_DICT_WITHOUT_KEYS, change -# MATCH_CLASS and MATCH_KEYS, and add COPY) -# Python 3.11a3 3463 (bpo-45711: JUMP_IF_NOT_EXC_MATCH no longer pops the -# active exception) -# Python 3.11a3 3464 (bpo-45636: Merge numeric BINARY_*/INPLACE_* into -# BINARY_OP) -# Python 3.11a3 3465 (Add COPY_FREE_VARS opcode) -# Python 3.11a4 3466 (bpo-45292: PEP-654 except*) -# Python 3.11a4 3467 (Change CALL_xxx opcodes) -# Python 3.11a4 3468 (Add SEND opcode) -# Python 3.11a4 3469 (bpo-45711: remove type, traceback from exc_info) -# Python 3.11a4 3470 (bpo-46221: PREP_RERAISE_STAR no longer pushes lasti) -# Python 3.11a4 3471 (bpo-46202: remove pop POP_EXCEPT_AND_RERAISE) -# Python 3.11a4 3472 (bpo-46009: replace GEN_START with POP_TOP) -# Python 3.11a4 3473 (Add POP_JUMP_IF_NOT_NONE/POP_JUMP_IF_NONE opcodes) -# Python 3.11a4 3474 (Add RESUME opcode) -# Python 3.11a5 3475 (Add RETURN_GENERATOR opcode) -# Python 3.11a5 3476 (Add ASYNC_GEN_WRAP opcode) -# Python 3.11a5 3477 (Replace DUP_TOP/DUP_TOP_TWO with COPY and -# ROT_TWO/ROT_THREE/ROT_FOUR/ROT_N with SWAP) -# Python 3.11a5 3478 (New CALL opcodes) -# Python 3.11a5 3479 (Add PUSH_NULL opcode) -# Python 3.11a5 3480 (New CALL opcodes, second iteration) -# Python 3.11a5 3481 (Use inline cache for BINARY_OP) -# Python 3.11a5 3482 (Use inline caching for UNPACK_SEQUENCE and LOAD_GLOBAL) -# Python 3.11a5 3483 (Use inline caching for COMPARE_OP and BINARY_SUBSCR) -# Python 3.11a5 3484 (Use inline caching for LOAD_ATTR, LOAD_METHOD, and -# STORE_ATTR) -# Python 3.11a5 3485 (Add an oparg to GET_AWAITABLE) -# Python 3.11a6 3486 (Use inline caching for PRECALL and CALL) -# Python 3.11a6 3487 (Remove the adaptive "oparg counter" mechanism) -# Python 3.11a6 3488 (LOAD_GLOBAL can push additional NULL) -# Python 3.11a6 3489 (Add JUMP_BACKWARD, remove JUMP_ABSOLUTE) -# Python 3.11a6 3490 (remove JUMP_IF_NOT_EXC_MATCH, add CHECK_EXC_MATCH) -# Python 3.11a6 3491 (remove JUMP_IF_NOT_EG_MATCH, add CHECK_EG_MATCH, -# add JUMP_BACKWARD_NO_INTERRUPT, make JUMP_NO_INTERRUPT virtual) -# Python 3.11a7 3492 (make POP_JUMP_IF_NONE/NOT_NONE/TRUE/FALSE relative) -# Python 3.11a7 3493 (Make JUMP_IF_TRUE_OR_POP/JUMP_IF_FALSE_OR_POP relative) -# Python 3.11a7 3494 (New location info table) -# Python 3.11b4 3495 (Set line number of module's RESUME instr to 0 per PEP 626) -# Python 3.12 will start with magic number 3500 - - -# -# MAGIC must change whenever the bytecode emitted by the compiler may no -# longer be understood by older implementations of the eval loop (usually -# due to the addition of new opcodes). -# -# Starting with Python 3.11, Python 3.n starts with magic number 2900+50n. -# -# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array -# in PC/launcher.c must also be updated. - -MAGIC_NUMBER = (3495).to_bytes(2, 'little') + b'\r\n' - -_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c - -_PYCACHE = '__pycache__' -_OPT = 'opt-' - -SOURCE_SUFFIXES = ['.py'] -if _MS_WINDOWS: - SOURCE_SUFFIXES.append('.pyw') - -EXTENSION_SUFFIXES = _imp.extension_suffixes() - -BYTECODE_SUFFIXES = ['.pyc'] -# Deprecated. -DEBUG_BYTECODE_SUFFIXES = OPTIMIZED_BYTECODE_SUFFIXES = BYTECODE_SUFFIXES - -def cache_from_source(path, debug_override=None, *, optimization=None): - """Given the path to a .py file, return the path to its .pyc file. - - The .py file does not need to exist; this simply returns the path to the - .pyc file calculated as if the .py file were imported. - - The 'optimization' parameter controls the presumed optimization level of - the bytecode file. If 'optimization' is not None, the string representation - of the argument is taken and verified to be alphanumeric (else ValueError - is raised). - - The debug_override parameter is deprecated. If debug_override is not None, - a True value is the same as setting 'optimization' to the empty string - while a False value is equivalent to setting 'optimization' to '1'. - - If sys.implementation.cache_tag is None then NotImplementedError is raised. - - """ - if debug_override is not None: - _warnings.warn('the debug_override parameter is deprecated; use ' - "'optimization' instead", DeprecationWarning) - if optimization is not None: - message = 'debug_override or optimization must be set to None' - raise TypeError(message) - optimization = '' if debug_override else 1 - path = _os.fspath(path) - head, tail = _path_split(path) - base, sep, rest = tail.rpartition('.') - tag = sys.implementation.cache_tag - if tag is None: - raise NotImplementedError('sys.implementation.cache_tag is None') - almost_filename = ''.join([(base if base else rest), sep, tag]) - if optimization is None: - if sys.flags.optimize == 0: - optimization = '' - else: - optimization = sys.flags.optimize - optimization = str(optimization) - if optimization != '': - if not optimization.isalnum(): - raise ValueError('{!r} is not alphanumeric'.format(optimization)) - almost_filename = '{}.{}{}'.format(almost_filename, _OPT, optimization) - filename = almost_filename + BYTECODE_SUFFIXES[0] - if sys.pycache_prefix is not None: - # We need an absolute path to the py file to avoid the possibility of - # collisions within sys.pycache_prefix, if someone has two different - # `foo/bar.py` on their system and they import both of them using the - # same sys.pycache_prefix. Let's say sys.pycache_prefix is - # `C:\Bytecode`; the idea here is that if we get `Foo\Bar`, we first - # make it absolute (`C:\Somewhere\Foo\Bar`), then make it root-relative - # (`Somewhere\Foo\Bar`), so we end up placing the bytecode file in an - # unambiguous `C:\Bytecode\Somewhere\Foo\Bar\`. - if not _path_isabs(head): - head = _path_join(_os.getcwd(), head) - - # Strip initial drive from a Windows path. We know we have an absolute - # path here, so the second part of the check rules out a POSIX path that - # happens to contain a colon at the second character. - if head[1] == ':' and head[0] not in path_separators: - head = head[2:] - - # Strip initial path separator from `head` to complete the conversion - # back to a root-relative path before joining. - return _path_join( - sys.pycache_prefix, - head.lstrip(path_separators), - filename, - ) - return _path_join(head, _PYCACHE, filename) - - -def source_from_cache(path): - """Given the path to a .pyc. file, return the path to its .py file. - - The .pyc file does not need to exist; this simply returns the path to - the .py file calculated to correspond to the .pyc file. If path does - not conform to PEP 3147/488 format, ValueError will be raised. If - sys.implementation.cache_tag is None then NotImplementedError is raised. - - """ - if sys.implementation.cache_tag is None: - raise NotImplementedError('sys.implementation.cache_tag is None') - path = _os.fspath(path) - head, pycache_filename = _path_split(path) - found_in_pycache_prefix = False - if sys.pycache_prefix is not None: - stripped_path = sys.pycache_prefix.rstrip(path_separators) - if head.startswith(stripped_path + path_sep): - head = head[len(stripped_path):] - found_in_pycache_prefix = True - if not found_in_pycache_prefix: - head, pycache = _path_split(head) - if pycache != _PYCACHE: - raise ValueError(f'{_PYCACHE} not bottom-level directory in ' - f'{path!r}') - dot_count = pycache_filename.count('.') - if dot_count not in {2, 3}: - raise ValueError(f'expected only 2 or 3 dots in {pycache_filename!r}') - elif dot_count == 3: - optimization = pycache_filename.rsplit('.', 2)[-2] - if not optimization.startswith(_OPT): - raise ValueError("optimization portion of filename does not start " - f"with {_OPT!r}") - opt_level = optimization[len(_OPT):] - if not opt_level.isalnum(): - raise ValueError(f"optimization level {optimization!r} is not an " - "alphanumeric value") - base_filename = pycache_filename.partition('.')[0] - return _path_join(head, base_filename + SOURCE_SUFFIXES[0]) - - -def _get_sourcefile(bytecode_path): - """Convert a bytecode file path to a source path (if possible). - - This function exists purely for backwards-compatibility for - PyImport_ExecCodeModuleWithFilenames() in the C API. - - """ - if len(bytecode_path) == 0: - return None - rest, _, extension = bytecode_path.rpartition('.') - if not rest or extension.lower()[-3:-1] != 'py': - return bytecode_path - try: - source_path = source_from_cache(bytecode_path) - except (NotImplementedError, ValueError): - source_path = bytecode_path[:-1] - return source_path if _path_isfile(source_path) else bytecode_path - - -def _get_cached(filename): - if filename.endswith(tuple(SOURCE_SUFFIXES)): - try: - return cache_from_source(filename) - except NotImplementedError: - pass - elif filename.endswith(tuple(BYTECODE_SUFFIXES)): - return filename - else: - return None - - -def _calc_mode(path): - """Calculate the mode permissions for a bytecode file.""" - try: - mode = _path_stat(path).st_mode - except OSError: - mode = 0o666 - # We always ensure write access so we can update cached files - # later even when the source files are read-only on Windows (#6074) - mode |= 0o200 - return mode - - -def _check_name(method): - """Decorator to verify that the module being requested matches the one the - loader can handle. - - The first argument (self) must define _name which the second argument is - compared against. If the comparison fails then ImportError is raised. - - """ - def _check_name_wrapper(self, name=None, *args, **kwargs): - if name is None: - name = self.name - elif self.name != name: - raise ImportError('loader for %s cannot handle %s' % - (self.name, name), name=name) - return method(self, name, *args, **kwargs) - - # FIXME: @_check_name is used to define class methods before the - # _bootstrap module is set by _set_bootstrap_module(). - if _bootstrap is not None: - _wrap = _bootstrap._wrap - else: - def _wrap(new, old): - for replace in ['__module__', '__name__', '__qualname__', '__doc__']: - if hasattr(old, replace): - setattr(new, replace, getattr(old, replace)) - new.__dict__.update(old.__dict__) - - _wrap(_check_name_wrapper, method) - return _check_name_wrapper - - -def _find_module_shim(self, fullname): - """Try to find a loader for the specified module by delegating to - self.find_loader(). - - This method is deprecated in favor of finder.find_spec(). - - """ - _warnings.warn("find_module() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - # Call find_loader(). If it returns a string (indicating this - # is a namespace package portion), generate a warning and - # return None. - loader, portions = self.find_loader(fullname) - if loader is None and len(portions): - msg = 'Not importing directory {}: missing __init__' - _warnings.warn(msg.format(portions[0]), ImportWarning) - return loader - - -def _classify_pyc(data, name, exc_details): - """Perform basic validity checking of a pyc header and return the flags field, - which determines how the pyc should be further validated against the source. - - *data* is the contents of the pyc file. (Only the first 16 bytes are - required, though.) - - *name* is the name of the module being imported. It is used for logging. - - *exc_details* is a dictionary passed to ImportError if it raised for - improved debugging. - - ImportError is raised when the magic number is incorrect or when the flags - field is invalid. EOFError is raised when the data is found to be truncated. - - """ - magic = data[:4] - if magic != MAGIC_NUMBER: - message = f'bad magic number in {name!r}: {magic!r}' - _bootstrap._verbose_message('{}', message) - raise ImportError(message, **exc_details) - if len(data) < 16: - message = f'reached EOF while reading pyc header of {name!r}' - _bootstrap._verbose_message('{}', message) - raise EOFError(message) - flags = _unpack_uint32(data[4:8]) - # Only the first two flags are defined. - if flags & ~0b11: - message = f'invalid flags {flags!r} in {name!r}' - raise ImportError(message, **exc_details) - return flags - - -def _validate_timestamp_pyc(data, source_mtime, source_size, name, - exc_details): - """Validate a pyc against the source last-modified time. - - *data* is the contents of the pyc file. (Only the first 16 bytes are - required.) - - *source_mtime* is the last modified timestamp of the source file. - - *source_size* is None or the size of the source file in bytes. - - *name* is the name of the module being imported. It is used for logging. - - *exc_details* is a dictionary passed to ImportError if it raised for - improved debugging. - - An ImportError is raised if the bytecode is stale. - - """ - if _unpack_uint32(data[8:12]) != (source_mtime & 0xFFFFFFFF): - message = f'bytecode is stale for {name!r}' - _bootstrap._verbose_message('{}', message) - raise ImportError(message, **exc_details) - if (source_size is not None and - _unpack_uint32(data[12:16]) != (source_size & 0xFFFFFFFF)): - raise ImportError(f'bytecode is stale for {name!r}', **exc_details) - - -def _validate_hash_pyc(data, source_hash, name, exc_details): - """Validate a hash-based pyc by checking the real source hash against the one in - the pyc header. - - *data* is the contents of the pyc file. (Only the first 16 bytes are - required.) - - *source_hash* is the importlib.util.source_hash() of the source file. - - *name* is the name of the module being imported. It is used for logging. - - *exc_details* is a dictionary passed to ImportError if it raised for - improved debugging. - - An ImportError is raised if the bytecode is stale. - - """ - if data[8:16] != source_hash: - raise ImportError( - f'hash in bytecode doesn\'t match hash of source {name!r}', - **exc_details, - ) - - -def _compile_bytecode(data, name=None, bytecode_path=None, source_path=None): - """Compile bytecode as found in a pyc.""" - code = marshal.loads(data) - if isinstance(code, _code_type): - _bootstrap._verbose_message('code object from {!r}', bytecode_path) - if source_path is not None: - _imp._fix_co_filename(code, source_path) - return code - else: - raise ImportError('Non-code object in {!r}'.format(bytecode_path), - name=name, path=bytecode_path) - - -def _code_to_timestamp_pyc(code, mtime=0, source_size=0): - "Produce the data for a timestamp-based pyc." - data = bytearray(MAGIC_NUMBER) - data.extend(_pack_uint32(0)) - data.extend(_pack_uint32(mtime)) - data.extend(_pack_uint32(source_size)) - data.extend(marshal.dumps(code)) - return data - - -def _code_to_hash_pyc(code, source_hash, checked=True): - "Produce the data for a hash-based pyc." - data = bytearray(MAGIC_NUMBER) - flags = 0b1 | checked << 1 - data.extend(_pack_uint32(flags)) - assert len(source_hash) == 8 - data.extend(source_hash) - data.extend(marshal.dumps(code)) - return data - - -def decode_source(source_bytes): - """Decode bytes representing source code and return the string. - - Universal newline support is used in the decoding. - """ - import tokenize # To avoid bootstrap issues. - source_bytes_readline = _io.BytesIO(source_bytes).readline - encoding = tokenize.detect_encoding(source_bytes_readline) - newline_decoder = _io.IncrementalNewlineDecoder(None, True) - return newline_decoder.decode(source_bytes.decode(encoding[0])) - - -# Module specifications ####################################################### - -_POPULATE = object() - - -def spec_from_file_location(name, location=None, *, loader=None, - submodule_search_locations=_POPULATE): - """Return a module spec based on a file location. - - To indicate that the module is a package, set - submodule_search_locations to a list of directory paths. An - empty list is sufficient, though its not otherwise useful to the - import system. - - The loader must take a spec as its only __init__() arg. - - """ - if location is None: - # The caller may simply want a partially populated location- - # oriented spec. So we set the location to a bogus value and - # fill in as much as we can. - location = '' - if hasattr(loader, 'get_filename'): - # ExecutionLoader - try: - location = loader.get_filename(name) - except ImportError: - pass - else: - location = _os.fspath(location) - if not _path_isabs(location): - try: - location = _path_join(_os.getcwd(), location) - except OSError: - pass - - # If the location is on the filesystem, but doesn't actually exist, - # we could return None here, indicating that the location is not - # valid. However, we don't have a good way of testing since an - # indirect location (e.g. a zip file or URL) will look like a - # non-existent file relative to the filesystem. - - spec = _bootstrap.ModuleSpec(name, loader, origin=location) - spec._set_fileattr = True - - # Pick a loader if one wasn't provided. - if loader is None: - for loader_class, suffixes in _get_supported_file_loaders(): - if location.endswith(tuple(suffixes)): - loader = loader_class(name, location) - spec.loader = loader - break - else: - return None - - # Set submodule_search_paths appropriately. - if submodule_search_locations is _POPULATE: - # Check the loader. - if hasattr(loader, 'is_package'): - try: - is_package = loader.is_package(name) - except ImportError: - pass - else: - if is_package: - spec.submodule_search_locations = [] - else: - spec.submodule_search_locations = submodule_search_locations - if spec.submodule_search_locations == []: - if location: - dirname = _path_split(location)[0] - spec.submodule_search_locations.append(dirname) - - return spec - - -# Loaders ##################################################################### - -class WindowsRegistryFinder: - - """Meta path finder for modules declared in the Windows registry.""" - - REGISTRY_KEY = ( - 'Software\\Python\\PythonCore\\{sys_version}' - '\\Modules\\{fullname}') - REGISTRY_KEY_DEBUG = ( - 'Software\\Python\\PythonCore\\{sys_version}' - '\\Modules\\{fullname}\\Debug') - DEBUG_BUILD = (_MS_WINDOWS and '_d.pyd' in EXTENSION_SUFFIXES) - - @staticmethod - def _open_registry(key): - try: - return winreg.OpenKey(winreg.HKEY_CURRENT_USER, key) - except OSError: - return winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key) - - @classmethod - def _search_registry(cls, fullname): - if cls.DEBUG_BUILD: - registry_key = cls.REGISTRY_KEY_DEBUG - else: - registry_key = cls.REGISTRY_KEY - key = registry_key.format(fullname=fullname, - sys_version='%d.%d' % sys.version_info[:2]) - try: - with cls._open_registry(key) as hkey: - filepath = winreg.QueryValue(hkey, '') - except OSError: - return None - return filepath - - @classmethod - def find_spec(cls, fullname, path=None, target=None): - filepath = cls._search_registry(fullname) - if filepath is None: - return None - try: - _path_stat(filepath) - except OSError: - return None - for loader, suffixes in _get_supported_file_loaders(): - if filepath.endswith(tuple(suffixes)): - spec = _bootstrap.spec_from_loader(fullname, - loader(fullname, filepath), - origin=filepath) - return spec - - @classmethod - def find_module(cls, fullname, path=None): - """Find module named in the registry. - - This method is deprecated. Use find_spec() instead. - - """ - _warnings.warn("WindowsRegistryFinder.find_module() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - spec = cls.find_spec(fullname, path) - if spec is not None: - return spec.loader - else: - return None - - -class _LoaderBasics: - - """Base class of common code needed by both SourceLoader and - SourcelessFileLoader.""" - - def is_package(self, fullname): - """Concrete implementation of InspectLoader.is_package by checking if - the path returned by get_filename has a filename of '__init__.py'.""" - filename = _path_split(self.get_filename(fullname))[1] - filename_base = filename.rsplit('.', 1)[0] - tail_name = fullname.rpartition('.')[2] - return filename_base == '__init__' and tail_name != '__init__' - - def create_module(self, spec): - """Use default semantics for module creation.""" - - def exec_module(self, module): - """Execute the module.""" - code = self.get_code(module.__name__) - if code is None: - raise ImportError('cannot load module {!r} when get_code() ' - 'returns None'.format(module.__name__)) - _bootstrap._call_with_frames_removed(exec, code, module.__dict__) - - def load_module(self, fullname): - """This method is deprecated.""" - # Warning implemented in _load_module_shim(). - return _bootstrap._load_module_shim(self, fullname) - - -class SourceLoader(_LoaderBasics): - - def path_mtime(self, path): - """Optional method that returns the modification time (an int) for the - specified path (a str). - - Raises OSError when the path cannot be handled. - """ - raise OSError - - def path_stats(self, path): - """Optional method returning a metadata dict for the specified - path (a str). - - Possible keys: - - 'mtime' (mandatory) is the numeric timestamp of last source - code modification; - - 'size' (optional) is the size in bytes of the source code. - - Implementing this method allows the loader to read bytecode files. - Raises OSError when the path cannot be handled. - """ - return {'mtime': self.path_mtime(path)} - - def _cache_bytecode(self, source_path, cache_path, data): - """Optional method which writes data (bytes) to a file path (a str). - - Implementing this method allows for the writing of bytecode files. - - The source path is needed in order to correctly transfer permissions - """ - # For backwards compatibility, we delegate to set_data() - return self.set_data(cache_path, data) - - def set_data(self, path, data): - """Optional method which writes data (bytes) to a file path (a str). - - Implementing this method allows for the writing of bytecode files. - """ - - - def get_source(self, fullname): - """Concrete implementation of InspectLoader.get_source.""" - path = self.get_filename(fullname) - try: - source_bytes = self.get_data(path) - except OSError as exc: - raise ImportError('source not available through get_data()', - name=fullname) from exc - return decode_source(source_bytes) - - def source_to_code(self, data, path, *, _optimize=-1): - """Return the code object compiled from source. - - The 'data' argument can be any object type that compile() supports. - """ - return _bootstrap._call_with_frames_removed(compile, data, path, 'exec', - dont_inherit=True, optimize=_optimize) - - def get_code(self, fullname): - """Concrete implementation of InspectLoader.get_code. - - Reading of bytecode requires path_stats to be implemented. To write - bytecode, set_data must also be implemented. - - """ - source_path = self.get_filename(fullname) - source_mtime = None - source_bytes = None - source_hash = None - hash_based = False - check_source = True - try: - bytecode_path = cache_from_source(source_path) - except NotImplementedError: - bytecode_path = None - else: - try: - st = self.path_stats(source_path) - except OSError: - pass - else: - source_mtime = int(st['mtime']) - try: - data = self.get_data(bytecode_path) - except OSError: - pass - else: - exc_details = { - 'name': fullname, - 'path': bytecode_path, - } - try: - flags = _classify_pyc(data, fullname, exc_details) - bytes_data = memoryview(data)[16:] - hash_based = flags & 0b1 != 0 - if hash_based: - check_source = flags & 0b10 != 0 - if (_imp.check_hash_based_pycs != 'never' and - (check_source or - _imp.check_hash_based_pycs == 'always')): - source_bytes = self.get_data(source_path) - source_hash = _imp.source_hash( - _RAW_MAGIC_NUMBER, - source_bytes, - ) - _validate_hash_pyc(data, source_hash, fullname, - exc_details) - else: - _validate_timestamp_pyc( - data, - source_mtime, - st['size'], - fullname, - exc_details, - ) - except (ImportError, EOFError): - pass - else: - _bootstrap._verbose_message('{} matches {}', bytecode_path, - source_path) - return _compile_bytecode(bytes_data, name=fullname, - bytecode_path=bytecode_path, - source_path=source_path) - if source_bytes is None: - source_bytes = self.get_data(source_path) - code_object = self.source_to_code(source_bytes, source_path) - _bootstrap._verbose_message('code object from {}', source_path) - if (not sys.dont_write_bytecode and bytecode_path is not None and - source_mtime is not None): - if hash_based: - if source_hash is None: - source_hash = _imp.source_hash(source_bytes) - data = _code_to_hash_pyc(code_object, source_hash, check_source) - else: - data = _code_to_timestamp_pyc(code_object, source_mtime, - len(source_bytes)) - try: - self._cache_bytecode(source_path, bytecode_path, data) - except NotImplementedError: - pass - return code_object - - -class FileLoader: - - """Base file loader class which implements the loader protocol methods that - require file system usage.""" - - def __init__(self, fullname, path): - """Cache the module name and the path to the file found by the - finder.""" - self.name = fullname - self.path = path - - def __eq__(self, other): - return (self.__class__ == other.__class__ and - self.__dict__ == other.__dict__) - - def __hash__(self): - return hash(self.name) ^ hash(self.path) - - @_check_name - def load_module(self, fullname): - """Load a module from a file. - - This method is deprecated. Use exec_module() instead. - - """ - # The only reason for this method is for the name check. - # Issue #14857: Avoid the zero-argument form of super so the implementation - # of that form can be updated without breaking the frozen module. - return super(FileLoader, self).load_module(fullname) - - @_check_name - def get_filename(self, fullname): - """Return the path to the source file as found by the finder.""" - return self.path - - def get_data(self, path): - """Return the data from path as raw bytes.""" - if isinstance(self, (SourceLoader, ExtensionFileLoader)): - with _io.open_code(str(path)) as file: - return file.read() - else: - with _io.FileIO(path, 'r') as file: - return file.read() - - @_check_name - def get_resource_reader(self, module): - from importlib.readers import FileReader - return FileReader(self) - - -class SourceFileLoader(FileLoader, SourceLoader): - - """Concrete implementation of SourceLoader using the file system.""" - - def path_stats(self, path): - """Return the metadata for the path.""" - st = _path_stat(path) - return {'mtime': st.st_mtime, 'size': st.st_size} - - def _cache_bytecode(self, source_path, bytecode_path, data): - # Adapt between the two APIs - mode = _calc_mode(source_path) - return self.set_data(bytecode_path, data, _mode=mode) - - def set_data(self, path, data, *, _mode=0o666): - """Write bytes data to a file.""" - parent, filename = _path_split(path) - path_parts = [] - # Figure out what directories are missing. - while parent and not _path_isdir(parent): - parent, part = _path_split(parent) - path_parts.append(part) - # Create needed directories. - for part in reversed(path_parts): - parent = _path_join(parent, part) - try: - _os.mkdir(parent) - except FileExistsError: - # Probably another Python process already created the dir. - continue - except OSError as exc: - # Could be a permission error, read-only filesystem: just forget - # about writing the data. - _bootstrap._verbose_message('could not create {!r}: {!r}', - parent, exc) - return - try: - _write_atomic(path, data, _mode) - _bootstrap._verbose_message('created {!r}', path) - except OSError as exc: - # Same as above: just don't write the bytecode. - _bootstrap._verbose_message('could not create {!r}: {!r}', path, - exc) - - -class SourcelessFileLoader(FileLoader, _LoaderBasics): - - """Loader which handles sourceless file imports.""" - - def get_code(self, fullname): - path = self.get_filename(fullname) - data = self.get_data(path) - # Call _classify_pyc to do basic validation of the pyc but ignore the - # result. There's no source to check against. - exc_details = { - 'name': fullname, - 'path': path, - } - _classify_pyc(data, fullname, exc_details) - return _compile_bytecode( - memoryview(data)[16:], - name=fullname, - bytecode_path=path, - ) - - def get_source(self, fullname): - """Return None as there is no source code.""" - return None - - -class ExtensionFileLoader(FileLoader, _LoaderBasics): - - """Loader for extension modules. - - The constructor is designed to work with FileFinder. - - """ - - def __init__(self, name, path): - self.name = name - self.path = path - - def __eq__(self, other): - return (self.__class__ == other.__class__ and - self.__dict__ == other.__dict__) - - def __hash__(self): - return hash(self.name) ^ hash(self.path) - - def create_module(self, spec): - """Create an uninitialized extension module""" - module = _bootstrap._call_with_frames_removed( - _imp.create_dynamic, spec) - _bootstrap._verbose_message('extension module {!r} loaded from {!r}', - spec.name, self.path) - return module - - def exec_module(self, module): - """Initialize an extension module""" - _bootstrap._call_with_frames_removed(_imp.exec_dynamic, module) - _bootstrap._verbose_message('extension module {!r} executed from {!r}', - self.name, self.path) - - def is_package(self, fullname): - """Return True if the extension module is a package.""" - file_name = _path_split(self.path)[1] - return any(file_name == '__init__' + suffix - for suffix in EXTENSION_SUFFIXES) - - def get_code(self, fullname): - """Return None as an extension module cannot create a code object.""" - return None - - def get_source(self, fullname): - """Return None as extension modules have no source code.""" - return None - - @_check_name - def get_filename(self, fullname): - """Return the path to the source file as found by the finder.""" - return self.path - - -class _NamespacePath: - """Represents a namespace package's path. It uses the module name - to find its parent module, and from there it looks up the parent's - __path__. When this changes, the module's own path is recomputed, - using path_finder. For top-level modules, the parent module's path - is sys.path.""" - - # When invalidate_caches() is called, this epoch is incremented - # https://bugs.python.org/issue45703 - _epoch = 0 - - def __init__(self, name, path, path_finder): - self._name = name - self._path = path - self._last_parent_path = tuple(self._get_parent_path()) - self._last_epoch = self._epoch - self._path_finder = path_finder - - def _find_parent_path_names(self): - """Returns a tuple of (parent-module-name, parent-path-attr-name)""" - parent, dot, me = self._name.rpartition('.') - if dot == '': - # This is a top-level module. sys.path contains the parent path. - return 'sys', 'path' - # Not a top-level module. parent-module.__path__ contains the - # parent path. - return parent, '__path__' - - def _get_parent_path(self): - parent_module_name, path_attr_name = self._find_parent_path_names() - return getattr(sys.modules[parent_module_name], path_attr_name) - - def _recalculate(self): - # If the parent's path has changed, recalculate _path - parent_path = tuple(self._get_parent_path()) # Make a copy - if parent_path != self._last_parent_path or self._epoch != self._last_epoch: - spec = self._path_finder(self._name, parent_path) - # Note that no changes are made if a loader is returned, but we - # do remember the new parent path - if spec is not None and spec.loader is None: - if spec.submodule_search_locations: - self._path = spec.submodule_search_locations - self._last_parent_path = parent_path # Save the copy - self._last_epoch = self._epoch - return self._path - - def __iter__(self): - return iter(self._recalculate()) - - def __getitem__(self, index): - return self._recalculate()[index] - - def __setitem__(self, index, path): - self._path[index] = path - - def __len__(self): - return len(self._recalculate()) - - def __repr__(self): - return '_NamespacePath({!r})'.format(self._path) - - def __contains__(self, item): - return item in self._recalculate() - - def append(self, item): - self._path.append(item) - - -# This class is actually exposed publicly in a namespace package's __loader__ -# attribute, so it should be available through a non-private name. -# https://bugs.python.org/issue35673 -class NamespaceLoader: - def __init__(self, name, path, path_finder): - self._path = _NamespacePath(name, path, path_finder) - - @staticmethod - def module_repr(module): - """Return repr for the module. - - The method is deprecated. The import machinery does the job itself. - - """ - _warnings.warn("NamespaceLoader.module_repr() is deprecated and " - "slated for removal in Python 3.12", DeprecationWarning) - return ''.format(module.__name__) - - def is_package(self, fullname): - return True - - def get_source(self, fullname): - return '' - - def get_code(self, fullname): - return compile('', '', 'exec', dont_inherit=True) - - def create_module(self, spec): - """Use default semantics for module creation.""" - - def exec_module(self, module): - pass - - def load_module(self, fullname): - """Load a namespace module. - - This method is deprecated. Use exec_module() instead. - - """ - # The import system never calls this method. - _bootstrap._verbose_message('namespace module loaded with path {!r}', - self._path) - # Warning implemented in _load_module_shim(). - return _bootstrap._load_module_shim(self, fullname) - - def get_resource_reader(self, module): - from importlib.readers import NamespaceReader - return NamespaceReader(self._path) - - -# We use this exclusively in module_from_spec() for backward-compatibility. -_NamespaceLoader = NamespaceLoader - - -# Finders ##################################################################### - -class PathFinder: - - """Meta path finder for sys.path and package __path__ attributes.""" - - @staticmethod - def invalidate_caches(): - """Call the invalidate_caches() method on all path entry finders - stored in sys.path_importer_caches (where implemented).""" - for name, finder in list(sys.path_importer_cache.items()): - # Drop entry if finder name is a relative path. The current - # working directory may have changed. - if finder is None or not _path_isabs(name): - del sys.path_importer_cache[name] - elif hasattr(finder, 'invalidate_caches'): - finder.invalidate_caches() - # Also invalidate the caches of _NamespacePaths - # https://bugs.python.org/issue45703 - _NamespacePath._epoch += 1 - - @staticmethod - def _path_hooks(path): - """Search sys.path_hooks for a finder for 'path'.""" - if sys.path_hooks is not None and not sys.path_hooks: - _warnings.warn('sys.path_hooks is empty', ImportWarning) - for hook in sys.path_hooks: - try: - return hook(path) - except ImportError: - continue - else: - return None - - @classmethod - def _path_importer_cache(cls, path): - """Get the finder for the path entry from sys.path_importer_cache. - - If the path entry is not in the cache, find the appropriate finder - and cache it. If no finder is available, store None. - - """ - if path == '': - try: - path = _os.getcwd() - except FileNotFoundError: - # Don't cache the failure as the cwd can easily change to - # a valid directory later on. - return None - try: - finder = sys.path_importer_cache[path] - except KeyError: - finder = cls._path_hooks(path) - sys.path_importer_cache[path] = finder - return finder - - @classmethod - def _legacy_get_spec(cls, fullname, finder): - # This would be a good place for a DeprecationWarning if - # we ended up going that route. - if hasattr(finder, 'find_loader'): - msg = (f"{_bootstrap._object_name(finder)}.find_spec() not found; " - "falling back to find_loader()") - _warnings.warn(msg, ImportWarning) - loader, portions = finder.find_loader(fullname) - else: - msg = (f"{_bootstrap._object_name(finder)}.find_spec() not found; " - "falling back to find_module()") - _warnings.warn(msg, ImportWarning) - loader = finder.find_module(fullname) - portions = [] - if loader is not None: - return _bootstrap.spec_from_loader(fullname, loader) - spec = _bootstrap.ModuleSpec(fullname, None) - spec.submodule_search_locations = portions - return spec - - @classmethod - def _get_spec(cls, fullname, path, target=None): - """Find the loader or namespace_path for this module/package name.""" - # If this ends up being a namespace package, namespace_path is - # the list of paths that will become its __path__ - namespace_path = [] - for entry in path: - if not isinstance(entry, str): - continue - finder = cls._path_importer_cache(entry) - if finder is not None: - if hasattr(finder, 'find_spec'): - spec = finder.find_spec(fullname, target) - else: - spec = cls._legacy_get_spec(fullname, finder) - if spec is None: - continue - if spec.loader is not None: - return spec - portions = spec.submodule_search_locations - if portions is None: - raise ImportError('spec missing loader') - # This is possibly part of a namespace package. - # Remember these path entries (if any) for when we - # create a namespace package, and continue iterating - # on path. - namespace_path.extend(portions) - else: - spec = _bootstrap.ModuleSpec(fullname, None) - spec.submodule_search_locations = namespace_path - return spec - - @classmethod - def find_spec(cls, fullname, path=None, target=None): - """Try to find a spec for 'fullname' on sys.path or 'path'. - - The search is based on sys.path_hooks and sys.path_importer_cache. - """ - if path is None: - path = sys.path - spec = cls._get_spec(fullname, path, target) - if spec is None: - return None - elif spec.loader is None: - namespace_path = spec.submodule_search_locations - if namespace_path: - # We found at least one namespace path. Return a spec which - # can create the namespace package. - spec.origin = None - spec.submodule_search_locations = _NamespacePath(fullname, namespace_path, cls._get_spec) - return spec - else: - return None - else: - return spec - - @classmethod - def find_module(cls, fullname, path=None): - """find the module on sys.path or 'path' based on sys.path_hooks and - sys.path_importer_cache. - - This method is deprecated. Use find_spec() instead. - - """ - _warnings.warn("PathFinder.find_module() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - spec = cls.find_spec(fullname, path) - if spec is None: - return None - return spec.loader - - @staticmethod - def find_distributions(*args, **kwargs): - """ - Find distributions. - - Return an iterable of all Distribution instances capable of - loading the metadata for packages matching ``context.name`` - (or all names if ``None`` indicated) along the paths in the list - of directories ``context.path``. - """ - from importlib.metadata import MetadataPathFinder - return MetadataPathFinder.find_distributions(*args, **kwargs) - - -class FileFinder: - - """File-based finder. - - Interactions with the file system are cached for performance, being - refreshed when the directory the finder is handling has been modified. - - """ - - def __init__(self, path, *loader_details): - """Initialize with the path to search on and a variable number of - 2-tuples containing the loader and the file suffixes the loader - recognizes.""" - loaders = [] - for loader, suffixes in loader_details: - loaders.extend((suffix, loader) for suffix in suffixes) - self._loaders = loaders - # Base (directory) path - if not path or path == '.': - self.path = _os.getcwd() - elif not _path_isabs(path): - self.path = _path_join(_os.getcwd(), path) - else: - self.path = path - self._path_mtime = -1 - self._path_cache = set() - self._relaxed_path_cache = set() - - def invalidate_caches(self): - """Invalidate the directory mtime.""" - self._path_mtime = -1 - - find_module = _find_module_shim - - def find_loader(self, fullname): - """Try to find a loader for the specified module, or the namespace - package portions. Returns (loader, list-of-portions). - - This method is deprecated. Use find_spec() instead. - - """ - _warnings.warn("FileFinder.find_loader() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - spec = self.find_spec(fullname) - if spec is None: - return None, [] - return spec.loader, spec.submodule_search_locations or [] - - def _get_spec(self, loader_class, fullname, path, smsl, target): - loader = loader_class(fullname, path) - return spec_from_file_location(fullname, path, loader=loader, - submodule_search_locations=smsl) - - def find_spec(self, fullname, target=None): - """Try to find a spec for the specified module. - - Returns the matching spec, or None if not found. - """ - is_namespace = False - tail_module = fullname.rpartition('.')[2] - try: - mtime = _path_stat(self.path or _os.getcwd()).st_mtime - except OSError: - mtime = -1 - if mtime != self._path_mtime: - self._fill_cache() - self._path_mtime = mtime - # tail_module keeps the original casing, for __file__ and friends - if _relax_case(): - cache = self._relaxed_path_cache - cache_module = tail_module.lower() - else: - cache = self._path_cache - cache_module = tail_module - # Check if the module is the name of a directory (and thus a package). - if cache_module in cache: - base_path = _path_join(self.path, tail_module) - for suffix, loader_class in self._loaders: - init_filename = '__init__' + suffix - full_path = _path_join(base_path, init_filename) - if _path_isfile(full_path): - return self._get_spec(loader_class, fullname, full_path, [base_path], target) - else: - # If a namespace package, return the path if we don't - # find a module in the next section. - is_namespace = _path_isdir(base_path) - # Check for a file w/ a proper suffix exists. - for suffix, loader_class in self._loaders: - try: - full_path = _path_join(self.path, tail_module + suffix) - except ValueError: - return None - _bootstrap._verbose_message('trying {}', full_path, verbosity=2) - if cache_module + suffix in cache: - if _path_isfile(full_path): - return self._get_spec(loader_class, fullname, full_path, - None, target) - if is_namespace: - _bootstrap._verbose_message('possible namespace for {}', base_path) - spec = _bootstrap.ModuleSpec(fullname, None) - spec.submodule_search_locations = [base_path] - return spec - return None - - def _fill_cache(self): - """Fill the cache of potential modules and packages for this directory.""" - path = self.path - try: - contents = _os.listdir(path or _os.getcwd()) - except (FileNotFoundError, PermissionError, NotADirectoryError): - # Directory has either been removed, turned into a file, or made - # unreadable. - contents = [] - # We store two cached versions, to handle runtime changes of the - # PYTHONCASEOK environment variable. - if not sys.platform.startswith('win'): - self._path_cache = set(contents) - else: - # Windows users can import modules with case-insensitive file - # suffixes (for legacy reasons). Make the suffix lowercase here - # so it's done once instead of for every import. This is safe as - # the specified suffixes to check against are always specified in a - # case-sensitive manner. - lower_suffix_contents = set() - for item in contents: - name, dot, suffix = item.partition('.') - if dot: - new_name = '{}.{}'.format(name, suffix.lower()) - else: - new_name = name - lower_suffix_contents.add(new_name) - self._path_cache = lower_suffix_contents - if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): - self._relaxed_path_cache = {fn.lower() for fn in contents} - - @classmethod - def path_hook(cls, *loader_details): - """A class method which returns a closure to use on sys.path_hook - which will return an instance using the specified loaders and the path - called on the closure. - - If the path called on the closure is not a directory, ImportError is - raised. - - """ - def path_hook_for_FileFinder(path): - """Path hook for importlib.machinery.FileFinder.""" - if not _path_isdir(path): - raise ImportError('only directories are supported', path=path) - return cls(path, *loader_details) - - return path_hook_for_FileFinder - - def __repr__(self): - return 'FileFinder({!r})'.format(self.path) - - -# Import setup ############################################################### - -def _fix_up_module(ns, name, pathname, cpathname=None): - # This function is used by PyImport_ExecCodeModuleObject(). - loader = ns.get('__loader__') - spec = ns.get('__spec__') - if not loader: - if spec: - loader = spec.loader - elif pathname == cpathname: - loader = SourcelessFileLoader(name, pathname) - else: - loader = SourceFileLoader(name, pathname) - if not spec: - spec = spec_from_file_location(name, pathname, loader=loader) - try: - ns['__spec__'] = spec - ns['__loader__'] = loader - ns['__file__'] = pathname - ns['__cached__'] = cpathname - except Exception: - # Not important enough to report. - pass - - -def _get_supported_file_loaders(): - """Returns a list of file-based module loaders. - - Each item is a tuple (loader, suffixes). - """ - extensions = ExtensionFileLoader, _imp.extension_suffixes() - source = SourceFileLoader, SOURCE_SUFFIXES - bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES - return [extensions, source, bytecode] - - -def _set_bootstrap_module(_bootstrap_module): - global _bootstrap - _bootstrap = _bootstrap_module - - -def _install(_bootstrap_module): - """Install the path-based import components.""" - _set_bootstrap_module(_bootstrap_module) - supported_loaders = _get_supported_file_loaders() - sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)]) - sys.meta_path.append(PathFinder) diff --git a/python/Lib/importlib/abc.py b/python/Lib/importlib/abc.py deleted file mode 100644 index d866965..0000000 --- a/python/Lib/importlib/abc.py +++ /dev/null @@ -1,320 +0,0 @@ -"""Abstract base classes related to import.""" -from . import _bootstrap_external -from . import machinery -try: - import _frozen_importlib -except ImportError as exc: - if exc.name != '_frozen_importlib': - raise - _frozen_importlib = None -try: - import _frozen_importlib_external -except ImportError: - _frozen_importlib_external = _bootstrap_external -from ._abc import Loader -import abc -import warnings - -# for compatibility with Python 3.10 -from .resources.abc import ResourceReader, Traversable, TraversableResources - - -__all__ = [ - 'Loader', 'Finder', 'MetaPathFinder', 'PathEntryFinder', - 'ResourceLoader', 'InspectLoader', 'ExecutionLoader', - 'FileLoader', 'SourceLoader', - - # for compatibility with Python 3.10 - 'ResourceReader', 'Traversable', 'TraversableResources', -] - - -def _register(abstract_cls, *classes): - for cls in classes: - abstract_cls.register(cls) - if _frozen_importlib is not None: - try: - frozen_cls = getattr(_frozen_importlib, cls.__name__) - except AttributeError: - frozen_cls = getattr(_frozen_importlib_external, cls.__name__) - abstract_cls.register(frozen_cls) - - -class Finder(metaclass=abc.ABCMeta): - - """Legacy abstract base class for import finders. - - It may be subclassed for compatibility with legacy third party - reimplementations of the import system. Otherwise, finder - implementations should derive from the more specific MetaPathFinder - or PathEntryFinder ABCs. - - Deprecated since Python 3.3 - """ - - def __init__(self): - warnings.warn("the Finder ABC is deprecated and " - "slated for removal in Python 3.12; use MetaPathFinder " - "or PathEntryFinder instead", - DeprecationWarning) - - @abc.abstractmethod - def find_module(self, fullname, path=None): - """An abstract method that should find a module. - The fullname is a str and the optional path is a str or None. - Returns a Loader object or None. - """ - warnings.warn("importlib.abc.Finder along with its find_module() " - "method are deprecated and " - "slated for removal in Python 3.12; use " - "MetaPathFinder.find_spec() or " - "PathEntryFinder.find_spec() instead", - DeprecationWarning) - - -class MetaPathFinder(metaclass=abc.ABCMeta): - - """Abstract base class for import finders on sys.meta_path.""" - - # We don't define find_spec() here since that would break - # hasattr checks we do to support backward compatibility. - - def find_module(self, fullname, path): - """Return a loader for the module. - - If no module is found, return None. The fullname is a str and - the path is a list of strings or None. - - This method is deprecated since Python 3.4 in favor of - finder.find_spec(). If find_spec() exists then backwards-compatible - functionality is provided for this method. - - """ - warnings.warn("MetaPathFinder.find_module() is deprecated since Python " - "3.4 in favor of MetaPathFinder.find_spec() and is " - "slated for removal in Python 3.12", - DeprecationWarning, - stacklevel=2) - if not hasattr(self, 'find_spec'): - return None - found = self.find_spec(fullname, path) - return found.loader if found is not None else None - - def invalidate_caches(self): - """An optional method for clearing the finder's cache, if any. - This method is used by importlib.invalidate_caches(). - """ - -_register(MetaPathFinder, machinery.BuiltinImporter, machinery.FrozenImporter, - machinery.PathFinder, machinery.WindowsRegistryFinder) - - -class PathEntryFinder(metaclass=abc.ABCMeta): - - """Abstract base class for path entry finders used by PathFinder.""" - - # We don't define find_spec() here since that would break - # hasattr checks we do to support backward compatibility. - - def find_loader(self, fullname): - """Return (loader, namespace portion) for the path entry. - - The fullname is a str. The namespace portion is a sequence of - path entries contributing to part of a namespace package. The - sequence may be empty. If loader is not None, the portion will - be ignored. - - The portion will be discarded if another path entry finder - locates the module as a normal module or package. - - This method is deprecated since Python 3.4 in favor of - finder.find_spec(). If find_spec() is provided than backwards-compatible - functionality is provided. - """ - warnings.warn("PathEntryFinder.find_loader() is deprecated since Python " - "3.4 in favor of PathEntryFinder.find_spec() " - "(available since 3.4)", - DeprecationWarning, - stacklevel=2) - if not hasattr(self, 'find_spec'): - return None, [] - found = self.find_spec(fullname) - if found is not None: - if not found.submodule_search_locations: - portions = [] - else: - portions = found.submodule_search_locations - return found.loader, portions - else: - return None, [] - - find_module = _bootstrap_external._find_module_shim - - def invalidate_caches(self): - """An optional method for clearing the finder's cache, if any. - This method is used by PathFinder.invalidate_caches(). - """ - -_register(PathEntryFinder, machinery.FileFinder) - - -class ResourceLoader(Loader): - - """Abstract base class for loaders which can return data from their - back-end storage. - - This ABC represents one of the optional protocols specified by PEP 302. - - """ - - @abc.abstractmethod - def get_data(self, path): - """Abstract method which when implemented should return the bytes for - the specified path. The path must be a str.""" - raise OSError - - -class InspectLoader(Loader): - - """Abstract base class for loaders which support inspection about the - modules they can load. - - This ABC represents one of the optional protocols specified by PEP 302. - - """ - - def is_package(self, fullname): - """Optional method which when implemented should return whether the - module is a package. The fullname is a str. Returns a bool. - - Raises ImportError if the module cannot be found. - """ - raise ImportError - - def get_code(self, fullname): - """Method which returns the code object for the module. - - The fullname is a str. Returns a types.CodeType if possible, else - returns None if a code object does not make sense - (e.g. built-in module). Raises ImportError if the module cannot be - found. - """ - source = self.get_source(fullname) - if source is None: - return None - return self.source_to_code(source) - - @abc.abstractmethod - def get_source(self, fullname): - """Abstract method which should return the source code for the - module. The fullname is a str. Returns a str. - - Raises ImportError if the module cannot be found. - """ - raise ImportError - - @staticmethod - def source_to_code(data, path=''): - """Compile 'data' into a code object. - - The 'data' argument can be anything that compile() can handle. The'path' - argument should be where the data was retrieved (when applicable).""" - return compile(data, path, 'exec', dont_inherit=True) - - exec_module = _bootstrap_external._LoaderBasics.exec_module - load_module = _bootstrap_external._LoaderBasics.load_module - -_register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter, machinery.NamespaceLoader) - - -class ExecutionLoader(InspectLoader): - - """Abstract base class for loaders that wish to support the execution of - modules as scripts. - - This ABC represents one of the optional protocols specified in PEP 302. - - """ - - @abc.abstractmethod - def get_filename(self, fullname): - """Abstract method which should return the value that __file__ is to be - set to. - - Raises ImportError if the module cannot be found. - """ - raise ImportError - - def get_code(self, fullname): - """Method to return the code object for fullname. - - Should return None if not applicable (e.g. built-in module). - Raise ImportError if the module cannot be found. - """ - source = self.get_source(fullname) - if source is None: - return None - try: - path = self.get_filename(fullname) - except ImportError: - return self.source_to_code(source) - else: - return self.source_to_code(source, path) - -_register(ExecutionLoader, machinery.ExtensionFileLoader) - - -class FileLoader(_bootstrap_external.FileLoader, ResourceLoader, ExecutionLoader): - - """Abstract base class partially implementing the ResourceLoader and - ExecutionLoader ABCs.""" - -_register(FileLoader, machinery.SourceFileLoader, - machinery.SourcelessFileLoader) - - -class SourceLoader(_bootstrap_external.SourceLoader, ResourceLoader, ExecutionLoader): - - """Abstract base class for loading source code (and optionally any - corresponding bytecode). - - To support loading from source code, the abstractmethods inherited from - ResourceLoader and ExecutionLoader need to be implemented. To also support - loading from bytecode, the optional methods specified directly by this ABC - is required. - - Inherited abstractmethods not implemented in this ABC: - - * ResourceLoader.get_data - * ExecutionLoader.get_filename - - """ - - def path_mtime(self, path): - """Return the (int) modification time for the path (str).""" - if self.path_stats.__func__ is SourceLoader.path_stats: - raise OSError - return int(self.path_stats(path)['mtime']) - - def path_stats(self, path): - """Return a metadata dict for the source pointed to by the path (str). - Possible keys: - - 'mtime' (mandatory) is the numeric timestamp of last source - code modification; - - 'size' (optional) is the size in bytes of the source code. - """ - if self.path_mtime.__func__ is SourceLoader.path_mtime: - raise OSError - return {'mtime': self.path_mtime(path)} - - def set_data(self, path, data): - """Write the bytes to the path (if possible). - - Accepts a str path and data as bytes. - - Any needed intermediary directories are to be created. If for some - reason the file cannot be written because of permissions, fail - silently. - """ - -_register(SourceLoader, machinery.SourceFileLoader) diff --git a/python/Lib/importlib/machinery.py b/python/Lib/importlib/machinery.py deleted file mode 100644 index 9c82c1d..0000000 --- a/python/Lib/importlib/machinery.py +++ /dev/null @@ -1,20 +0,0 @@ -"""The machinery of importlib: finders, loaders, hooks, etc.""" - -from ._bootstrap import ModuleSpec -from ._bootstrap import BuiltinImporter -from ._bootstrap import FrozenImporter -from ._bootstrap_external import (SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES, - OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES, - EXTENSION_SUFFIXES) -from ._bootstrap_external import WindowsRegistryFinder -from ._bootstrap_external import PathFinder -from ._bootstrap_external import FileFinder -from ._bootstrap_external import SourceFileLoader -from ._bootstrap_external import SourcelessFileLoader -from ._bootstrap_external import ExtensionFileLoader -from ._bootstrap_external import NamespaceLoader - - -def all_suffixes(): - """Returns a list of all recognized module suffixes for this process""" - return SOURCE_SUFFIXES + BYTECODE_SUFFIXES + EXTENSION_SUFFIXES diff --git a/python/Lib/importlib/metadata/__init__.py b/python/Lib/importlib/metadata/__init__.py deleted file mode 100644 index 5df7354..0000000 --- a/python/Lib/importlib/metadata/__init__.py +++ /dev/null @@ -1,1088 +0,0 @@ -import os -import re -import abc -import csv -import sys -import email -import pathlib -import zipfile -import operator -import textwrap -import warnings -import functools -import itertools -import posixpath -import collections - -from . import _adapters, _meta -from ._collections import FreezableDefaultDict, Pair -from ._functools import method_cache, pass_none -from ._itertools import always_iterable, unique_everseen -from ._meta import PackageMetadata, SimplePath - -from contextlib import suppress -from importlib import import_module -from importlib.abc import MetaPathFinder -from itertools import starmap -from typing import List, Mapping, Optional, Union - - -__all__ = [ - 'Distribution', - 'DistributionFinder', - 'PackageMetadata', - 'PackageNotFoundError', - 'distribution', - 'distributions', - 'entry_points', - 'files', - 'metadata', - 'packages_distributions', - 'requires', - 'version', -] - - -class PackageNotFoundError(ModuleNotFoundError): - """The package was not found.""" - - def __str__(self): - return f"No package metadata was found for {self.name}" - - @property - def name(self): - (name,) = self.args - return name - - -class Sectioned: - """ - A simple entry point config parser for performance - - >>> for item in Sectioned.read(Sectioned._sample): - ... print(item) - Pair(name='sec1', value='# comments ignored') - Pair(name='sec1', value='a = 1') - Pair(name='sec1', value='b = 2') - Pair(name='sec2', value='a = 2') - - >>> res = Sectioned.section_pairs(Sectioned._sample) - >>> item = next(res) - >>> item.name - 'sec1' - >>> item.value - Pair(name='a', value='1') - >>> item = next(res) - >>> item.value - Pair(name='b', value='2') - >>> item = next(res) - >>> item.name - 'sec2' - >>> item.value - Pair(name='a', value='2') - >>> list(res) - [] - """ - - _sample = textwrap.dedent( - """ - [sec1] - # comments ignored - a = 1 - b = 2 - - [sec2] - a = 2 - """ - ).lstrip() - - @classmethod - def section_pairs(cls, text): - return ( - section._replace(value=Pair.parse(section.value)) - for section in cls.read(text, filter_=cls.valid) - if section.name is not None - ) - - @staticmethod - def read(text, filter_=None): - lines = filter(filter_, map(str.strip, text.splitlines())) - name = None - for value in lines: - section_match = value.startswith('[') and value.endswith(']') - if section_match: - name = value.strip('[]') - continue - yield Pair(name, value) - - @staticmethod - def valid(line): - return line and not line.startswith('#') - - -class DeprecatedTuple: - """ - Provide subscript item access for backward compatibility. - - >>> recwarn = getfixture('recwarn') - >>> ep = EntryPoint(name='name', value='value', group='group') - >>> ep[:] - ('name', 'value', 'group') - >>> ep[0] - 'name' - >>> len(recwarn) - 1 - """ - - _warn = functools.partial( - warnings.warn, - "EntryPoint tuple interface is deprecated. Access members by name.", - DeprecationWarning, - stacklevel=2, - ) - - def __getitem__(self, item): - self._warn() - return self._key()[item] - - -class EntryPoint(DeprecatedTuple): - """An entry point as defined by Python packaging conventions. - - See `the packaging docs on entry points - `_ - for more information. - - >>> ep = EntryPoint( - ... name=None, group=None, value='package.module:attr [extra1, extra2]') - >>> ep.module - 'package.module' - >>> ep.attr - 'attr' - >>> ep.extras - ['extra1', 'extra2'] - """ - - pattern = re.compile( - r'(?P[\w.]+)\s*' - r'(:\s*(?P[\w.]+)\s*)?' - r'((?P\[.*\])\s*)?$' - ) - """ - A regular expression describing the syntax for an entry point, - which might look like: - - - module - - package.module - - package.module:attribute - - package.module:object.attribute - - package.module:attr [extra1, extra2] - - Other combinations are possible as well. - - The expression is lenient about whitespace around the ':', - following the attr, and following any extras. - """ - - name: str - value: str - group: str - - dist: Optional['Distribution'] = None - - def __init__(self, name, value, group): - vars(self).update(name=name, value=value, group=group) - - def load(self): - """Load the entry point from its definition. If only a module - is indicated by the value, return that module. Otherwise, - return the named object. - """ - match = self.pattern.match(self.value) - module = import_module(match.group('module')) - attrs = filter(None, (match.group('attr') or '').split('.')) - return functools.reduce(getattr, attrs, module) - - @property - def module(self): - match = self.pattern.match(self.value) - return match.group('module') - - @property - def attr(self): - match = self.pattern.match(self.value) - return match.group('attr') - - @property - def extras(self): - match = self.pattern.match(self.value) - return re.findall(r'\w+', match.group('extras') or '') - - def _for(self, dist): - vars(self).update(dist=dist) - return self - - def __iter__(self): - """ - Supply iter so one may construct dicts of EntryPoints by name. - """ - msg = ( - "Construction of dict of EntryPoints is deprecated in " - "favor of EntryPoints." - ) - warnings.warn(msg, DeprecationWarning) - return iter((self.name, self)) - - def matches(self, **params): - """ - EntryPoint matches the given parameters. - - >>> ep = EntryPoint(group='foo', name='bar', value='bing:bong [extra1, extra2]') - >>> ep.matches(group='foo') - True - >>> ep.matches(name='bar', value='bing:bong [extra1, extra2]') - True - >>> ep.matches(group='foo', name='other') - False - >>> ep.matches() - True - >>> ep.matches(extras=['extra1', 'extra2']) - True - >>> ep.matches(module='bing') - True - >>> ep.matches(attr='bong') - True - """ - attrs = (getattr(self, param) for param in params) - return all(map(operator.eq, params.values(), attrs)) - - def _key(self): - return self.name, self.value, self.group - - def __lt__(self, other): - return self._key() < other._key() - - def __eq__(self, other): - return self._key() == other._key() - - def __setattr__(self, name, value): - raise AttributeError("EntryPoint objects are immutable.") - - def __repr__(self): - return ( - f'EntryPoint(name={self.name!r}, value={self.value!r}, ' - f'group={self.group!r})' - ) - - def __hash__(self): - return hash(self._key()) - - -class DeprecatedList(list): - """ - Allow an otherwise immutable object to implement mutability - for compatibility. - - >>> recwarn = getfixture('recwarn') - >>> dl = DeprecatedList(range(3)) - >>> dl[0] = 1 - >>> dl.append(3) - >>> del dl[3] - >>> dl.reverse() - >>> dl.sort() - >>> dl.extend([4]) - >>> dl.pop(-1) - 4 - >>> dl.remove(1) - >>> dl += [5] - >>> dl + [6] - [1, 2, 5, 6] - >>> dl + (6,) - [1, 2, 5, 6] - >>> dl.insert(0, 0) - >>> dl - [0, 1, 2, 5] - >>> dl == [0, 1, 2, 5] - True - >>> dl == (0, 1, 2, 5) - True - >>> len(recwarn) - 1 - """ - - __slots__ = () - - _warn = functools.partial( - warnings.warn, - "EntryPoints list interface is deprecated. Cast to list if needed.", - DeprecationWarning, - stacklevel=2, - ) - - def _wrap_deprecated_method(method_name: str): # type: ignore - def wrapped(self, *args, **kwargs): - self._warn() - return getattr(super(), method_name)(*args, **kwargs) - - return method_name, wrapped - - locals().update( - map( - _wrap_deprecated_method, - '__setitem__ __delitem__ append reverse extend pop remove ' - '__iadd__ insert sort'.split(), - ) - ) - - def __add__(self, other): - if not isinstance(other, tuple): - self._warn() - other = tuple(other) - return self.__class__(tuple(self) + other) - - def __eq__(self, other): - if not isinstance(other, tuple): - self._warn() - other = tuple(other) - - return tuple(self).__eq__(other) - - -class EntryPoints(DeprecatedList): - """ - An immutable collection of selectable EntryPoint objects. - """ - - __slots__ = () - - def __getitem__(self, name): # -> EntryPoint: - """ - Get the EntryPoint in self matching name. - """ - if isinstance(name, int): - warnings.warn( - "Accessing entry points by index is deprecated. " - "Cast to tuple if needed.", - DeprecationWarning, - stacklevel=2, - ) - return super().__getitem__(name) - try: - return next(iter(self.select(name=name))) - except StopIteration: - raise KeyError(name) - - def select(self, **params): - """ - Select entry points from self that match the - given parameters (typically group and/or name). - """ - return EntryPoints(ep for ep in self if ep.matches(**params)) - - @property - def names(self): - """ - Return the set of all names of all entry points. - """ - return {ep.name for ep in self} - - @property - def groups(self): - """ - Return the set of all groups of all entry points. - - For coverage while SelectableGroups is present. - >>> EntryPoints().groups - set() - """ - return {ep.group for ep in self} - - @classmethod - def _from_text_for(cls, text, dist): - return cls(ep._for(dist) for ep in cls._from_text(text)) - - @staticmethod - def _from_text(text): - return ( - EntryPoint(name=item.value.name, value=item.value.value, group=item.name) - for item in Sectioned.section_pairs(text or '') - ) - - -class Deprecated: - """ - Compatibility add-in for mapping to indicate that - mapping behavior is deprecated. - - >>> recwarn = getfixture('recwarn') - >>> class DeprecatedDict(Deprecated, dict): pass - >>> dd = DeprecatedDict(foo='bar') - >>> dd.get('baz', None) - >>> dd['foo'] - 'bar' - >>> list(dd) - ['foo'] - >>> list(dd.keys()) - ['foo'] - >>> 'foo' in dd - True - >>> list(dd.values()) - ['bar'] - >>> len(recwarn) - 1 - """ - - _warn = functools.partial( - warnings.warn, - "SelectableGroups dict interface is deprecated. Use select.", - DeprecationWarning, - stacklevel=2, - ) - - def __getitem__(self, name): - self._warn() - return super().__getitem__(name) - - def get(self, name, default=None): - self._warn() - return super().get(name, default) - - def __iter__(self): - self._warn() - return super().__iter__() - - def __contains__(self, *args): - self._warn() - return super().__contains__(*args) - - def keys(self): - self._warn() - return super().keys() - - def values(self): - self._warn() - return super().values() - - -class SelectableGroups(Deprecated, dict): - """ - A backward- and forward-compatible result from - entry_points that fully implements the dict interface. - """ - - @classmethod - def load(cls, eps): - by_group = operator.attrgetter('group') - ordered = sorted(eps, key=by_group) - grouped = itertools.groupby(ordered, by_group) - return cls((group, EntryPoints(eps)) for group, eps in grouped) - - @property - def _all(self): - """ - Reconstruct a list of all entrypoints from the groups. - """ - groups = super(Deprecated, self).values() - return EntryPoints(itertools.chain.from_iterable(groups)) - - @property - def groups(self): - return self._all.groups - - @property - def names(self): - """ - for coverage: - >>> SelectableGroups().names - set() - """ - return self._all.names - - def select(self, **params): - if not params: - return self - return self._all.select(**params) - - -class PackagePath(pathlib.PurePosixPath): - """A reference to a path in a package""" - - def read_text(self, encoding='utf-8'): - with self.locate().open(encoding=encoding) as stream: - return stream.read() - - def read_binary(self): - with self.locate().open('rb') as stream: - return stream.read() - - def locate(self): - """Return a path-like object for this path""" - return self.dist.locate_file(self) - - -class FileHash: - def __init__(self, spec): - self.mode, _, self.value = spec.partition('=') - - def __repr__(self): - return f'' - - -class Distribution: - """A Python distribution package.""" - - @abc.abstractmethod - def read_text(self, filename): - """Attempt to load metadata file given by the name. - - :param filename: The name of the file in the distribution info. - :return: The text if found, otherwise None. - """ - - @abc.abstractmethod - def locate_file(self, path): - """ - Given a path to a file in this distribution, return a path - to it. - """ - - @classmethod - def from_name(cls, name: str): - """Return the Distribution for the given package name. - - :param name: The name of the distribution package to search for. - :return: The Distribution instance (or subclass thereof) for the named - package, if found. - :raises PackageNotFoundError: When the named package's distribution - metadata cannot be found. - :raises ValueError: When an invalid value is supplied for name. - """ - if not name: - raise ValueError("A distribution name is required.") - try: - return next(cls.discover(name=name)) - except StopIteration: - raise PackageNotFoundError(name) - - @classmethod - def discover(cls, **kwargs): - """Return an iterable of Distribution objects for all packages. - - Pass a ``context`` or pass keyword arguments for constructing - a context. - - :context: A ``DistributionFinder.Context`` object. - :return: Iterable of Distribution objects for all packages. - """ - context = kwargs.pop('context', None) - if context and kwargs: - raise ValueError("cannot accept context and kwargs") - context = context or DistributionFinder.Context(**kwargs) - return itertools.chain.from_iterable( - resolver(context) for resolver in cls._discover_resolvers() - ) - - @staticmethod - def at(path): - """Return a Distribution for the indicated metadata path - - :param path: a string or path-like object - :return: a concrete Distribution instance for the path - """ - return PathDistribution(pathlib.Path(path)) - - @staticmethod - def _discover_resolvers(): - """Search the meta_path for resolvers.""" - declared = ( - getattr(finder, 'find_distributions', None) for finder in sys.meta_path - ) - return filter(None, declared) - - @property - def metadata(self) -> _meta.PackageMetadata: - """Return the parsed metadata for this Distribution. - - The returned object will have keys that name the various bits of - metadata. See PEP 566 for details. - """ - text = ( - self.read_text('METADATA') - or self.read_text('PKG-INFO') - # This last clause is here to support old egg-info files. Its - # effect is to just end up using the PathDistribution's self._path - # (which points to the egg-info file) attribute unchanged. - or self.read_text('') - ) - return _adapters.Message(email.message_from_string(text)) - - @property - def name(self): - """Return the 'Name' metadata for the distribution package.""" - return self.metadata['Name'] - - @property - def _normalized_name(self): - """Return a normalized version of the name.""" - return Prepared.normalize(self.name) - - @property - def version(self): - """Return the 'Version' metadata for the distribution package.""" - return self.metadata['Version'] - - @property - def entry_points(self): - return EntryPoints._from_text_for(self.read_text('entry_points.txt'), self) - - @property - def files(self): - """Files in this distribution. - - :return: List of PackagePath for this distribution or None - - Result is `None` if the metadata file that enumerates files - (i.e. RECORD for dist-info or SOURCES.txt for egg-info) is - missing. - Result may be empty if the metadata exists but is empty. - """ - - def make_file(name, hash=None, size_str=None): - result = PackagePath(name) - result.hash = FileHash(hash) if hash else None - result.size = int(size_str) if size_str else None - result.dist = self - return result - - @pass_none - def make_files(lines): - return list(starmap(make_file, csv.reader(lines))) - - return make_files(self._read_files_distinfo() or self._read_files_egginfo()) - - def _read_files_distinfo(self): - """ - Read the lines of RECORD - """ - text = self.read_text('RECORD') - return text and text.splitlines() - - def _read_files_egginfo(self): - """ - SOURCES.txt might contain literal commas, so wrap each line - in quotes. - """ - text = self.read_text('SOURCES.txt') - return text and map('"{}"'.format, text.splitlines()) - - @property - def requires(self): - """Generated requirements specified for this Distribution""" - reqs = self._read_dist_info_reqs() or self._read_egg_info_reqs() - return reqs and list(reqs) - - def _read_dist_info_reqs(self): - return self.metadata.get_all('Requires-Dist') - - def _read_egg_info_reqs(self): - source = self.read_text('requires.txt') - return pass_none(self._deps_from_requires_text)(source) - - @classmethod - def _deps_from_requires_text(cls, source): - return cls._convert_egg_info_reqs_to_simple_reqs(Sectioned.read(source)) - - @staticmethod - def _convert_egg_info_reqs_to_simple_reqs(sections): - """ - Historically, setuptools would solicit and store 'extra' - requirements, including those with environment markers, - in separate sections. More modern tools expect each - dependency to be defined separately, with any relevant - extras and environment markers attached directly to that - requirement. This method converts the former to the - latter. See _test_deps_from_requires_text for an example. - """ - - def make_condition(name): - return name and f'extra == "{name}"' - - def quoted_marker(section): - section = section or '' - extra, sep, markers = section.partition(':') - if extra and markers: - markers = f'({markers})' - conditions = list(filter(None, [markers, make_condition(extra)])) - return '; ' + ' and '.join(conditions) if conditions else '' - - def url_req_space(req): - """ - PEP 508 requires a space between the url_spec and the quoted_marker. - Ref python/importlib_metadata#357. - """ - # '@' is uniquely indicative of a url_req. - return ' ' * ('@' in req) - - for section in sections: - space = url_req_space(section.value) - yield section.value + space + quoted_marker(section.name) - - -class DistributionFinder(MetaPathFinder): - """ - A MetaPathFinder capable of discovering installed distributions. - """ - - class Context: - """ - Keyword arguments presented by the caller to - ``distributions()`` or ``Distribution.discover()`` - to narrow the scope of a search for distributions - in all DistributionFinders. - - Each DistributionFinder may expect any parameters - and should attempt to honor the canonical - parameters defined below when appropriate. - """ - - name = None - """ - Specific name for which a distribution finder should match. - A name of ``None`` matches all distributions. - """ - - def __init__(self, **kwargs): - vars(self).update(kwargs) - - @property - def path(self): - """ - The sequence of directory path that a distribution finder - should search. - - Typically refers to Python installed package paths such as - "site-packages" directories and defaults to ``sys.path``. - """ - return vars(self).get('path', sys.path) - - @abc.abstractmethod - def find_distributions(self, context=Context()): - """ - Find distributions. - - Return an iterable of all Distribution instances capable of - loading the metadata for packages matching the ``context``, - a DistributionFinder.Context instance. - """ - - -class FastPath: - """ - Micro-optimized class for searching a path for - children. - - >>> FastPath('').children() - ['...'] - """ - - @functools.lru_cache() # type: ignore - def __new__(cls, root): - return super().__new__(cls) - - def __init__(self, root): - self.root = root - - def joinpath(self, child): - return pathlib.Path(self.root, child) - - def children(self): - with suppress(Exception): - return os.listdir(self.root or '.') - with suppress(Exception): - return self.zip_children() - return [] - - def zip_children(self): - zip_path = zipfile.Path(self.root) - names = zip_path.root.namelist() - self.joinpath = zip_path.joinpath - - return dict.fromkeys(child.split(posixpath.sep, 1)[0] for child in names) - - def search(self, name): - return self.lookup(self.mtime).search(name) - - @property - def mtime(self): - with suppress(OSError): - return os.stat(self.root).st_mtime - self.lookup.cache_clear() - - @method_cache - def lookup(self, mtime): - return Lookup(self) - - -class Lookup: - def __init__(self, path: FastPath): - base = os.path.basename(path.root).lower() - base_is_egg = base.endswith(".egg") - self.infos = FreezableDefaultDict(list) - self.eggs = FreezableDefaultDict(list) - - for child in path.children(): - low = child.lower() - if low.endswith((".dist-info", ".egg-info")): - # rpartition is faster than splitext and suitable for this purpose. - name = low.rpartition(".")[0].partition("-")[0] - normalized = Prepared.normalize(name) - self.infos[normalized].append(path.joinpath(child)) - elif base_is_egg and low == "egg-info": - name = base.rpartition(".")[0].partition("-")[0] - legacy_normalized = Prepared.legacy_normalize(name) - self.eggs[legacy_normalized].append(path.joinpath(child)) - - self.infos.freeze() - self.eggs.freeze() - - def search(self, prepared): - infos = ( - self.infos[prepared.normalized] - if prepared - else itertools.chain.from_iterable(self.infos.values()) - ) - eggs = ( - self.eggs[prepared.legacy_normalized] - if prepared - else itertools.chain.from_iterable(self.eggs.values()) - ) - return itertools.chain(infos, eggs) - - -class Prepared: - """ - A prepared search for metadata on a possibly-named package. - """ - - normalized = None - legacy_normalized = None - - def __init__(self, name): - self.name = name - if name is None: - return - self.normalized = self.normalize(name) - self.legacy_normalized = self.legacy_normalize(name) - - @staticmethod - def normalize(name): - """ - PEP 503 normalization plus dashes as underscores. - """ - return re.sub(r"[-_.]+", "-", name).lower().replace('-', '_') - - @staticmethod - def legacy_normalize(name): - """ - Normalize the package name as found in the convention in - older packaging tools versions and specs. - """ - return name.lower().replace('-', '_') - - def __bool__(self): - return bool(self.name) - - -class MetadataPathFinder(DistributionFinder): - @classmethod - def find_distributions(cls, context=DistributionFinder.Context()): - """ - Find distributions. - - Return an iterable of all Distribution instances capable of - loading the metadata for packages matching ``context.name`` - (or all names if ``None`` indicated) along the paths in the list - of directories ``context.path``. - """ - found = cls._search_paths(context.name, context.path) - return map(PathDistribution, found) - - @classmethod - def _search_paths(cls, name, paths): - """Find metadata directories in paths heuristically.""" - prepared = Prepared(name) - return itertools.chain.from_iterable( - path.search(prepared) for path in map(FastPath, paths) - ) - - def invalidate_caches(cls): - FastPath.__new__.cache_clear() - - -class PathDistribution(Distribution): - def __init__(self, path: SimplePath): - """Construct a distribution. - - :param path: SimplePath indicating the metadata directory. - """ - self._path = path - - def read_text(self, filename): - with suppress( - FileNotFoundError, - IsADirectoryError, - KeyError, - NotADirectoryError, - PermissionError, - ): - return self._path.joinpath(filename).read_text(encoding='utf-8') - - read_text.__doc__ = Distribution.read_text.__doc__ - - def locate_file(self, path): - return self._path.parent / path - - @property - def _normalized_name(self): - """ - Performance optimization: where possible, resolve the - normalized name from the file system path. - """ - stem = os.path.basename(str(self._path)) - return ( - pass_none(Prepared.normalize)(self._name_from_stem(stem)) - or super()._normalized_name - ) - - @staticmethod - def _name_from_stem(stem): - """ - >>> PathDistribution._name_from_stem('foo-3.0.egg-info') - 'foo' - >>> PathDistribution._name_from_stem('CherryPy-3.0.dist-info') - 'CherryPy' - >>> PathDistribution._name_from_stem('face.egg-info') - 'face' - >>> PathDistribution._name_from_stem('foo.bar') - """ - filename, ext = os.path.splitext(stem) - if ext not in ('.dist-info', '.egg-info'): - return - name, sep, rest = filename.partition('-') - return name - - -def distribution(distribution_name): - """Get the ``Distribution`` instance for the named package. - - :param distribution_name: The name of the distribution package as a string. - :return: A ``Distribution`` instance (or subclass thereof). - """ - return Distribution.from_name(distribution_name) - - -def distributions(**kwargs): - """Get all ``Distribution`` instances in the current environment. - - :return: An iterable of ``Distribution`` instances. - """ - return Distribution.discover(**kwargs) - - -def metadata(distribution_name) -> _meta.PackageMetadata: - """Get the metadata for the named package. - - :param distribution_name: The name of the distribution package to query. - :return: A PackageMetadata containing the parsed metadata. - """ - return Distribution.from_name(distribution_name).metadata - - -def version(distribution_name): - """Get the version string for the named package. - - :param distribution_name: The name of the distribution package to query. - :return: The version string for the package as defined in the package's - "Version" metadata key. - """ - return distribution(distribution_name).version - - -_unique = functools.partial( - unique_everseen, - key=operator.attrgetter('_normalized_name'), -) -""" -Wrapper for ``distributions`` to return unique distributions by name. -""" - - -def entry_points(**params) -> Union[EntryPoints, SelectableGroups]: - """Return EntryPoint objects for all installed packages. - - Pass selection parameters (group or name) to filter the - result to entry points matching those properties (see - EntryPoints.select()). - - For compatibility, returns ``SelectableGroups`` object unless - selection parameters are supplied. In the future, this function - will return ``EntryPoints`` instead of ``SelectableGroups`` - even when no selection parameters are supplied. - - For maximum future compatibility, pass selection parameters - or invoke ``.select`` with parameters on the result. - - :return: EntryPoints or SelectableGroups for all installed packages. - """ - eps = itertools.chain.from_iterable( - dist.entry_points for dist in _unique(distributions()) - ) - return SelectableGroups.load(eps).select(**params) - - -def files(distribution_name): - """Return a list of files for the named package. - - :param distribution_name: The name of the distribution package to query. - :return: List of files composing the distribution. - """ - return distribution(distribution_name).files - - -def requires(distribution_name): - """ - Return a list of requirements for the named package. - - :return: An iterator of requirements, suitable for - packaging.requirement.Requirement. - """ - return distribution(distribution_name).requires - - -def packages_distributions() -> Mapping[str, List[str]]: - """ - Return a mapping of top-level packages to their - distributions. - - >>> import collections.abc - >>> pkgs = packages_distributions() - >>> all(isinstance(dist, collections.abc.Sequence) for dist in pkgs.values()) - True - """ - pkg_to_dist = collections.defaultdict(list) - for dist in distributions(): - for pkg in _top_level_declared(dist) or _top_level_inferred(dist): - pkg_to_dist[pkg].append(dist.metadata['Name']) - return dict(pkg_to_dist) - - -def _top_level_declared(dist): - return (dist.read_text('top_level.txt') or '').split() - - -def _top_level_inferred(dist): - return { - f.parts[0] if len(f.parts) > 1 else f.with_suffix('').name - for f in always_iterable(dist.files) - if f.suffix == ".py" - } diff --git a/python/Lib/importlib/metadata/_adapters.py b/python/Lib/importlib/metadata/_adapters.py deleted file mode 100644 index d96abb2..0000000 --- a/python/Lib/importlib/metadata/_adapters.py +++ /dev/null @@ -1,68 +0,0 @@ -import re -import textwrap -import email.message - -from ._text import FoldedCase - - -class Message(email.message.Message): - multiple_use_keys = set( - map( - FoldedCase, - [ - 'Classifier', - 'Obsoletes-Dist', - 'Platform', - 'Project-URL', - 'Provides-Dist', - 'Provides-Extra', - 'Requires-Dist', - 'Requires-External', - 'Supported-Platform', - 'Dynamic', - ], - ) - ) - """ - Keys that may be indicated multiple times per PEP 566. - """ - - def __new__(cls, orig: email.message.Message): - res = super().__new__(cls) - vars(res).update(vars(orig)) - return res - - def __init__(self, *args, **kwargs): - self._headers = self._repair_headers() - - # suppress spurious error from mypy - def __iter__(self): - return super().__iter__() - - def _repair_headers(self): - def redent(value): - "Correct for RFC822 indentation" - if not value or '\n' not in value: - return value - return textwrap.dedent(' ' * 8 + value) - - headers = [(key, redent(value)) for key, value in vars(self)['_headers']] - if self._payload: - headers.append(('Description', self.get_payload())) - return headers - - @property - def json(self): - """ - Convert PackageMetadata to a JSON-compatible format - per PEP 0566. - """ - - def transform(key): - value = self.get_all(key) if key in self.multiple_use_keys else self[key] - if key == 'Keywords': - value = re.split(r'\s+', value) - tk = key.lower().replace('-', '_') - return tk, value - - return dict(map(transform, map(FoldedCase, self))) diff --git a/python/Lib/importlib/metadata/_collections.py b/python/Lib/importlib/metadata/_collections.py deleted file mode 100644 index 1dbf920..0000000 --- a/python/Lib/importlib/metadata/_collections.py +++ /dev/null @@ -1,30 +0,0 @@ -import collections - - -# from jaraco.collections 3.3 -class FreezableDefaultDict(collections.defaultdict): - """ - Often it is desirable to prevent the mutation of - a default dict after its initial construction, such - as to prevent mutation during iteration. - - >>> dd = FreezableDefaultDict(list) - >>> dd[0].append('1') - >>> dd.freeze() - >>> dd[1] - [] - >>> len(dd) - 1 - """ - - def __missing__(self, key): - return getattr(self, '_frozen', super().__missing__)(key) - - def freeze(self): - self._frozen = lambda key: self.default_factory() - - -class Pair(collections.namedtuple('Pair', 'name value')): - @classmethod - def parse(cls, text): - return cls(*map(str.strip, text.split("=", 1))) diff --git a/python/Lib/importlib/metadata/_functools.py b/python/Lib/importlib/metadata/_functools.py deleted file mode 100644 index 7268c33..0000000 --- a/python/Lib/importlib/metadata/_functools.py +++ /dev/null @@ -1,104 +0,0 @@ -import types -import functools - - -# from jaraco.functools 3.3 -def method_cache(method, cache_wrapper=None): - """ - Wrap lru_cache to support storing the cache data in the object instances. - - Abstracts the common paradigm where the method explicitly saves an - underscore-prefixed protected property on first call and returns that - subsequently. - - >>> class MyClass: - ... calls = 0 - ... - ... @method_cache - ... def method(self, value): - ... self.calls += 1 - ... return value - - >>> a = MyClass() - >>> a.method(3) - 3 - >>> for x in range(75): - ... res = a.method(x) - >>> a.calls - 75 - - Note that the apparent behavior will be exactly like that of lru_cache - except that the cache is stored on each instance, so values in one - instance will not flush values from another, and when an instance is - deleted, so are the cached values for that instance. - - >>> b = MyClass() - >>> for x in range(35): - ... res = b.method(x) - >>> b.calls - 35 - >>> a.method(0) - 0 - >>> a.calls - 75 - - Note that if method had been decorated with ``functools.lru_cache()``, - a.calls would have been 76 (due to the cached value of 0 having been - flushed by the 'b' instance). - - Clear the cache with ``.cache_clear()`` - - >>> a.method.cache_clear() - - Same for a method that hasn't yet been called. - - >>> c = MyClass() - >>> c.method.cache_clear() - - Another cache wrapper may be supplied: - - >>> cache = functools.lru_cache(maxsize=2) - >>> MyClass.method2 = method_cache(lambda self: 3, cache_wrapper=cache) - >>> a = MyClass() - >>> a.method2() - 3 - - Caution - do not subsequently wrap the method with another decorator, such - as ``@property``, which changes the semantics of the function. - - See also - http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/ - for another implementation and additional justification. - """ - cache_wrapper = cache_wrapper or functools.lru_cache() - - def wrapper(self, *args, **kwargs): - # it's the first call, replace the method with a cached, bound method - bound_method = types.MethodType(method, self) - cached_method = cache_wrapper(bound_method) - setattr(self, method.__name__, cached_method) - return cached_method(*args, **kwargs) - - # Support cache clear even before cache has been created. - wrapper.cache_clear = lambda: None - - return wrapper - - -# From jaraco.functools 3.3 -def pass_none(func): - """ - Wrap func so it's not called if its first param is None - - >>> print_text = pass_none(print) - >>> print_text('text') - text - >>> print_text(None) - """ - - @functools.wraps(func) - def wrapper(param, *args, **kwargs): - if param is not None: - return func(param, *args, **kwargs) - - return wrapper diff --git a/python/Lib/importlib/metadata/_itertools.py b/python/Lib/importlib/metadata/_itertools.py deleted file mode 100644 index b75748b..0000000 --- a/python/Lib/importlib/metadata/_itertools.py +++ /dev/null @@ -1,73 +0,0 @@ -from itertools import filterfalse - - -def unique_everseen(iterable, key=None): - "List unique elements, preserving order. Remember all elements ever seen." - # unique_everseen('AAAABBBCCDAABBB') --> A B C D - # unique_everseen('ABBCcAD', str.lower) --> A B C D - seen = set() - seen_add = seen.add - if key is None: - for element in filterfalse(seen.__contains__, iterable): - seen_add(element) - yield element - else: - for element in iterable: - k = key(element) - if k not in seen: - seen_add(k) - yield element - - -# copied from more_itertools 8.8 -def always_iterable(obj, base_type=(str, bytes)): - """If *obj* is iterable, return an iterator over its items:: - - >>> obj = (1, 2, 3) - >>> list(always_iterable(obj)) - [1, 2, 3] - - If *obj* is not iterable, return a one-item iterable containing *obj*:: - - >>> obj = 1 - >>> list(always_iterable(obj)) - [1] - - If *obj* is ``None``, return an empty iterable: - - >>> obj = None - >>> list(always_iterable(None)) - [] - - By default, binary and text strings are not considered iterable:: - - >>> obj = 'foo' - >>> list(always_iterable(obj)) - ['foo'] - - If *base_type* is set, objects for which ``isinstance(obj, base_type)`` - returns ``True`` won't be considered iterable. - - >>> obj = {'a': 1} - >>> list(always_iterable(obj)) # Iterate over the dict's keys - ['a'] - >>> list(always_iterable(obj, base_type=dict)) # Treat dicts as a unit - [{'a': 1}] - - Set *base_type* to ``None`` to avoid any special handling and treat objects - Python considers iterable as iterable: - - >>> obj = 'foo' - >>> list(always_iterable(obj, base_type=None)) - ['f', 'o', 'o'] - """ - if obj is None: - return iter(()) - - if (base_type is not None) and isinstance(obj, base_type): - return iter((obj,)) - - try: - return iter(obj) - except TypeError: - return iter((obj,)) diff --git a/python/Lib/importlib/metadata/_meta.py b/python/Lib/importlib/metadata/_meta.py deleted file mode 100644 index 3e62c7e..0000000 --- a/python/Lib/importlib/metadata/_meta.py +++ /dev/null @@ -1,47 +0,0 @@ -from typing import Any, Dict, Iterator, List, Protocol, TypeVar, Union - - -_T = TypeVar("_T") - - -class PackageMetadata(Protocol): - def __len__(self) -> int: - ... # pragma: no cover - - def __contains__(self, item: str) -> bool: - ... # pragma: no cover - - def __getitem__(self, key: str) -> str: - ... # pragma: no cover - - def __iter__(self) -> Iterator[str]: - ... # pragma: no cover - - def get_all(self, name: str, failobj: _T = ...) -> Union[List[Any], _T]: - """ - Return all values associated with a possibly multi-valued key. - """ - - @property - def json(self) -> Dict[str, Union[str, List[str]]]: - """ - A JSON-compatible form of the metadata. - """ - - -class SimplePath(Protocol): - """ - A minimal subset of pathlib.Path required by PathDistribution. - """ - - def joinpath(self) -> 'SimplePath': - ... # pragma: no cover - - def __truediv__(self) -> 'SimplePath': - ... # pragma: no cover - - def parent(self) -> 'SimplePath': - ... # pragma: no cover - - def read_text(self) -> str: - ... # pragma: no cover diff --git a/python/Lib/importlib/metadata/_text.py b/python/Lib/importlib/metadata/_text.py deleted file mode 100644 index 9c8ff90..0000000 --- a/python/Lib/importlib/metadata/_text.py +++ /dev/null @@ -1,99 +0,0 @@ -import re - -from ._functools import method_cache - - -# from jaraco.text 3.5 -class FoldedCase(str): - """ - A case insensitive string class; behaves just like str - except compares equal when the only variation is case. - - >>> s = FoldedCase('hello world') - - >>> s == 'Hello World' - True - - >>> 'Hello World' == s - True - - >>> s != 'Hello World' - False - - >>> s.index('O') - 4 - - >>> s.split('O') - ['hell', ' w', 'rld'] - - >>> sorted(map(FoldedCase, ['GAMMA', 'alpha', 'Beta'])) - ['alpha', 'Beta', 'GAMMA'] - - Sequence membership is straightforward. - - >>> "Hello World" in [s] - True - >>> s in ["Hello World"] - True - - You may test for set inclusion, but candidate and elements - must both be folded. - - >>> FoldedCase("Hello World") in {s} - True - >>> s in {FoldedCase("Hello World")} - True - - String inclusion works as long as the FoldedCase object - is on the right. - - >>> "hello" in FoldedCase("Hello World") - True - - But not if the FoldedCase object is on the left: - - >>> FoldedCase('hello') in 'Hello World' - False - - In that case, use in_: - - >>> FoldedCase('hello').in_('Hello World') - True - - >>> FoldedCase('hello') > FoldedCase('Hello') - False - """ - - def __lt__(self, other): - return self.lower() < other.lower() - - def __gt__(self, other): - return self.lower() > other.lower() - - def __eq__(self, other): - return self.lower() == other.lower() - - def __ne__(self, other): - return self.lower() != other.lower() - - def __hash__(self): - return hash(self.lower()) - - def __contains__(self, other): - return super().lower().__contains__(other.lower()) - - def in_(self, other): - "Does self appear in other?" - return self in FoldedCase(other) - - # cache lower since it's likely to be called frequently. - @method_cache - def lower(self): - return super().lower() - - def index(self, sub): - return self.lower().index(sub.lower()) - - def split(self, splitter=' ', maxsplit=0): - pattern = re.compile(re.escape(splitter), re.I) - return pattern.split(self, maxsplit) diff --git a/python/Lib/importlib/readers.py b/python/Lib/importlib/readers.py deleted file mode 100644 index a864be6..0000000 --- a/python/Lib/importlib/readers.py +++ /dev/null @@ -1,12 +0,0 @@ -""" -Compatibility shim for .resources.readers as found on Python 3.10. - -Consumers that can rely on Python 3.11 should use the other -module directly. -""" - -from .resources.readers import ( - FileReader, ZipReader, MultiplexedPath, NamespaceReader, -) - -__all__ = ['FileReader', 'ZipReader', 'MultiplexedPath', 'NamespaceReader'] diff --git a/python/Lib/importlib/resources/__init__.py b/python/Lib/importlib/resources/__init__.py deleted file mode 100644 index f8b5bd8..0000000 --- a/python/Lib/importlib/resources/__init__.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Read resources contained within a package.""" - -from ._common import ( - as_file, - files, - Package, -) - -from ._legacy import ( - contents, - open_binary, - read_binary, - open_text, - read_text, - is_resource, - path, - Resource, -) - -from .abc import ResourceReader - - -__all__ = [ - 'Package', - 'Resource', - 'ResourceReader', - 'as_file', - 'contents', - 'files', - 'is_resource', - 'open_binary', - 'open_text', - 'path', - 'read_binary', - 'read_text', -] diff --git a/python/Lib/importlib/resources/_adapters.py b/python/Lib/importlib/resources/_adapters.py deleted file mode 100644 index 5689377..0000000 --- a/python/Lib/importlib/resources/_adapters.py +++ /dev/null @@ -1,170 +0,0 @@ -from contextlib import suppress -from io import TextIOWrapper - -from . import abc - - -class SpecLoaderAdapter: - """ - Adapt a package spec to adapt the underlying loader. - """ - - def __init__(self, spec, adapter=lambda spec: spec.loader): - self.spec = spec - self.loader = adapter(spec) - - def __getattr__(self, name): - return getattr(self.spec, name) - - -class TraversableResourcesLoader: - """ - Adapt a loader to provide TraversableResources. - """ - - def __init__(self, spec): - self.spec = spec - - def get_resource_reader(self, name): - return CompatibilityFiles(self.spec)._native() - - -def _io_wrapper(file, mode='r', *args, **kwargs): - if mode == 'r': - return TextIOWrapper(file, *args, **kwargs) - elif mode == 'rb': - return file - raise ValueError( - "Invalid mode value '{}', only 'r' and 'rb' are supported".format(mode) - ) - - -class CompatibilityFiles: - """ - Adapter for an existing or non-existent resource reader - to provide a compatibility .files(). - """ - - class SpecPath(abc.Traversable): - """ - Path tied to a module spec. - Can be read and exposes the resource reader children. - """ - - def __init__(self, spec, reader): - self._spec = spec - self._reader = reader - - def iterdir(self): - if not self._reader: - return iter(()) - return iter( - CompatibilityFiles.ChildPath(self._reader, path) - for path in self._reader.contents() - ) - - def is_file(self): - return False - - is_dir = is_file - - def joinpath(self, other): - if not self._reader: - return CompatibilityFiles.OrphanPath(other) - return CompatibilityFiles.ChildPath(self._reader, other) - - @property - def name(self): - return self._spec.name - - def open(self, mode='r', *args, **kwargs): - return _io_wrapper(self._reader.open_resource(None), mode, *args, **kwargs) - - class ChildPath(abc.Traversable): - """ - Path tied to a resource reader child. - Can be read but doesn't expose any meaningful children. - """ - - def __init__(self, reader, name): - self._reader = reader - self._name = name - - def iterdir(self): - return iter(()) - - def is_file(self): - return self._reader.is_resource(self.name) - - def is_dir(self): - return not self.is_file() - - def joinpath(self, other): - return CompatibilityFiles.OrphanPath(self.name, other) - - @property - def name(self): - return self._name - - def open(self, mode='r', *args, **kwargs): - return _io_wrapper( - self._reader.open_resource(self.name), mode, *args, **kwargs - ) - - class OrphanPath(abc.Traversable): - """ - Orphan path, not tied to a module spec or resource reader. - Can't be read and doesn't expose any meaningful children. - """ - - def __init__(self, *path_parts): - if len(path_parts) < 1: - raise ValueError('Need at least one path part to construct a path') - self._path = path_parts - - def iterdir(self): - return iter(()) - - def is_file(self): - return False - - is_dir = is_file - - def joinpath(self, other): - return CompatibilityFiles.OrphanPath(*self._path, other) - - @property - def name(self): - return self._path[-1] - - def open(self, mode='r', *args, **kwargs): - raise FileNotFoundError("Can't open orphan path") - - def __init__(self, spec): - self.spec = spec - - @property - def _reader(self): - with suppress(AttributeError): - return self.spec.loader.get_resource_reader(self.spec.name) - - def _native(self): - """ - Return the native reader if it supports files(). - """ - reader = self._reader - return reader if hasattr(reader, 'files') else self - - def __getattr__(self, attr): - return getattr(self._reader, attr) - - def files(self): - return CompatibilityFiles.SpecPath(self.spec, self._reader) - - -def wrap_spec(package): - """ - Construct a package spec with traversable compatibility - on the spec/loader/reader. - """ - return SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader) diff --git a/python/Lib/importlib/resources/_common.py b/python/Lib/importlib/resources/_common.py deleted file mode 100644 index 721b2f4..0000000 --- a/python/Lib/importlib/resources/_common.py +++ /dev/null @@ -1,107 +0,0 @@ -import os -import pathlib -import tempfile -import functools -import contextlib -import types -import importlib - -from typing import Union, Optional -from .abc import ResourceReader, Traversable - -from ._adapters import wrap_spec - -Package = Union[types.ModuleType, str] - - -def files(package): - # type: (Package) -> Traversable - """ - Get a Traversable resource from a package - """ - return from_package(get_package(package)) - - -def get_resource_reader(package): - # type: (types.ModuleType) -> Optional[ResourceReader] - """ - Return the package's loader if it's a ResourceReader. - """ - # We can't use - # a issubclass() check here because apparently abc.'s __subclasscheck__() - # hook wants to create a weak reference to the object, but - # zipimport.zipimporter does not support weak references, resulting in a - # TypeError. That seems terrible. - spec = package.__spec__ - reader = getattr(spec.loader, 'get_resource_reader', None) # type: ignore - if reader is None: - return None - return reader(spec.name) # type: ignore - - -def resolve(cand): - # type: (Package) -> types.ModuleType - return cand if isinstance(cand, types.ModuleType) else importlib.import_module(cand) - - -def get_package(package): - # type: (Package) -> types.ModuleType - """Take a package name or module object and return the module. - - Raise an exception if the resolved module is not a package. - """ - resolved = resolve(package) - if wrap_spec(resolved).submodule_search_locations is None: - raise TypeError(f'{package!r} is not a package') - return resolved - - -def from_package(package): - """ - Return a Traversable object for the given package. - - """ - spec = wrap_spec(package) - reader = spec.loader.get_resource_reader(spec.name) - return reader.files() - - -@contextlib.contextmanager -def _tempfile(reader, suffix='', - # gh-93353: Keep a reference to call os.remove() in late Python - # finalization. - *, _os_remove=os.remove): - # Not using tempfile.NamedTemporaryFile as it leads to deeper 'try' - # blocks due to the need to close the temporary file to work on Windows - # properly. - fd, raw_path = tempfile.mkstemp(suffix=suffix) - try: - try: - os.write(fd, reader()) - finally: - os.close(fd) - del reader - yield pathlib.Path(raw_path) - finally: - try: - _os_remove(raw_path) - except FileNotFoundError: - pass - - -@functools.singledispatch -def as_file(path): - """ - Given a Traversable object, return that object as a - path on the local file system in a context manager. - """ - return _tempfile(path.read_bytes, suffix=path.name) - - -@as_file.register(pathlib.Path) -@contextlib.contextmanager -def _(path): - """ - Degenerate behavior for pathlib.Path objects. - """ - yield path diff --git a/python/Lib/importlib/resources/_itertools.py b/python/Lib/importlib/resources/_itertools.py deleted file mode 100644 index 65054de..0000000 --- a/python/Lib/importlib/resources/_itertools.py +++ /dev/null @@ -1,35 +0,0 @@ -from itertools import filterfalse - -from typing import ( - Callable, - Iterable, - Iterator, - Optional, - Set, - TypeVar, - Union, -) - -# Type and type variable definitions -_T = TypeVar('_T') -_U = TypeVar('_U') - - -def unique_everseen( - iterable: Iterable[_T], key: Optional[Callable[[_T], _U]] = None -) -> Iterator[_T]: - "List unique elements, preserving order. Remember all elements ever seen." - # unique_everseen('AAAABBBCCDAABBB') --> A B C D - # unique_everseen('ABBCcAD', str.lower) --> A B C D - seen: Set[Union[_T, _U]] = set() - seen_add = seen.add - if key is None: - for element in filterfalse(seen.__contains__, iterable): - seen_add(element) - yield element - else: - for element in iterable: - k = key(element) - if k not in seen: - seen_add(k) - yield element diff --git a/python/Lib/importlib/resources/_legacy.py b/python/Lib/importlib/resources/_legacy.py deleted file mode 100644 index fcbab94..0000000 --- a/python/Lib/importlib/resources/_legacy.py +++ /dev/null @@ -1,121 +0,0 @@ -import functools -import os -import pathlib -import types -import warnings - -from typing import Union, Iterable, ContextManager, BinaryIO, TextIO, Any - -from . import _common - -Package = Union[types.ModuleType, str] -Resource = str - - -def deprecated(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - warnings.warn( - f"{func.__name__} is deprecated. Use files() instead. " - "Refer to https://importlib-resources.readthedocs.io" - "/en/latest/using.html#migrating-from-legacy for migration advice.", - DeprecationWarning, - stacklevel=2, - ) - return func(*args, **kwargs) - - return wrapper - - -def normalize_path(path): - # type: (Any) -> str - """Normalize a path by ensuring it is a string. - - If the resulting string contains path separators, an exception is raised. - """ - str_path = str(path) - parent, file_name = os.path.split(str_path) - if parent: - raise ValueError(f'{path!r} must be only a file name') - return file_name - - -@deprecated -def open_binary(package: Package, resource: Resource) -> BinaryIO: - """Return a file-like object opened for binary reading of the resource.""" - return (_common.files(package) / normalize_path(resource)).open('rb') - - -@deprecated -def read_binary(package: Package, resource: Resource) -> bytes: - """Return the binary contents of the resource.""" - return (_common.files(package) / normalize_path(resource)).read_bytes() - - -@deprecated -def open_text( - package: Package, - resource: Resource, - encoding: str = 'utf-8', - errors: str = 'strict', -) -> TextIO: - """Return a file-like object opened for text reading of the resource.""" - return (_common.files(package) / normalize_path(resource)).open( - 'r', encoding=encoding, errors=errors - ) - - -@deprecated -def read_text( - package: Package, - resource: Resource, - encoding: str = 'utf-8', - errors: str = 'strict', -) -> str: - """Return the decoded string of the resource. - - The decoding-related arguments have the same semantics as those of - bytes.decode(). - """ - with open_text(package, resource, encoding, errors) as fp: - return fp.read() - - -@deprecated -def contents(package: Package) -> Iterable[str]: - """Return an iterable of entries in `package`. - - Note that not all entries are resources. Specifically, directories are - not considered resources. Use `is_resource()` on each entry returned here - to check if it is a resource or not. - """ - return [path.name for path in _common.files(package).iterdir()] - - -@deprecated -def is_resource(package: Package, name: str) -> bool: - """True if `name` is a resource inside `package`. - - Directories are *not* resources. - """ - resource = normalize_path(name) - return any( - traversable.name == resource and traversable.is_file() - for traversable in _common.files(package).iterdir() - ) - - -@deprecated -def path( - package: Package, - resource: Resource, -) -> ContextManager[pathlib.Path]: - """A context manager providing a file path object to the resource. - - If the resource does not already exist on its own on the file system, - a temporary file will be created. If the file was created, the file - will be deleted upon exiting the context manager (no exception is - raised if the file was deleted prior to the context manager - exiting). - """ - return _common.as_file(_common.files(package) / normalize_path(resource)) diff --git a/python/Lib/importlib/resources/abc.py b/python/Lib/importlib/resources/abc.py deleted file mode 100644 index f9e7a8e..0000000 --- a/python/Lib/importlib/resources/abc.py +++ /dev/null @@ -1,151 +0,0 @@ -import abc -import io -import os -from typing import Any, BinaryIO, Iterable, Iterator, NoReturn, Text, Optional -from typing import runtime_checkable, Protocol -from typing import Union - - -StrPath = Union[str, os.PathLike[str]] - -__all__ = ["ResourceReader", "Traversable", "TraversableResources"] - - -class ResourceReader(metaclass=abc.ABCMeta): - """Abstract base class for loaders to provide resource reading support.""" - - @abc.abstractmethod - def open_resource(self, resource: Text) -> BinaryIO: - """Return an opened, file-like object for binary reading. - - The 'resource' argument is expected to represent only a file name. - If the resource cannot be found, FileNotFoundError is raised. - """ - # This deliberately raises FileNotFoundError instead of - # NotImplementedError so that if this method is accidentally called, - # it'll still do the right thing. - raise FileNotFoundError - - @abc.abstractmethod - def resource_path(self, resource: Text) -> Text: - """Return the file system path to the specified resource. - - The 'resource' argument is expected to represent only a file name. - If the resource does not exist on the file system, raise - FileNotFoundError. - """ - # This deliberately raises FileNotFoundError instead of - # NotImplementedError so that if this method is accidentally called, - # it'll still do the right thing. - raise FileNotFoundError - - @abc.abstractmethod - def is_resource(self, path: Text) -> bool: - """Return True if the named 'path' is a resource. - - Files are resources, directories are not. - """ - raise FileNotFoundError - - @abc.abstractmethod - def contents(self) -> Iterable[str]: - """Return an iterable of entries in `package`.""" - raise FileNotFoundError - - -@runtime_checkable -class Traversable(Protocol): - """ - An object with a subset of pathlib.Path methods suitable for - traversing directories and opening files. - - Any exceptions that occur when accessing the backing resource - may propagate unaltered. - """ - - @abc.abstractmethod - def iterdir(self) -> Iterator["Traversable"]: - """ - Yield Traversable objects in self - """ - - def read_bytes(self) -> bytes: - """ - Read contents of self as bytes - """ - with self.open('rb') as strm: - return strm.read() - - def read_text(self, encoding: Optional[str] = None) -> str: - """ - Read contents of self as text - """ - with self.open(encoding=encoding) as strm: - return strm.read() - - @abc.abstractmethod - def is_dir(self) -> bool: - """ - Return True if self is a directory - """ - - @abc.abstractmethod - def is_file(self) -> bool: - """ - Return True if self is a file - """ - - @abc.abstractmethod - def joinpath(self, *descendants: StrPath) -> "Traversable": - """ - Return Traversable resolved with any descendants applied. - - Each descendant should be a path segment relative to self - and each may contain multiple levels separated by - ``posixpath.sep`` (``/``). - """ - - def __truediv__(self, child: StrPath) -> "Traversable": - """ - Return Traversable child in self - """ - return self.joinpath(child) - - @abc.abstractmethod - def open(self, mode='r', *args, **kwargs): - """ - mode may be 'r' or 'rb' to open as text or binary. Return a handle - suitable for reading (same as pathlib.Path.open). - - When opening as text, accepts encoding parameters such as those - accepted by io.TextIOWrapper. - """ - - @abc.abstractproperty - def name(self) -> str: - """ - The base name of this object without any parent references. - """ - - -class TraversableResources(ResourceReader): - """ - The required interface for providing traversable - resources. - """ - - @abc.abstractmethod - def files(self) -> "Traversable": - """Return a Traversable object for the loaded package.""" - - def open_resource(self, resource: StrPath) -> io.BufferedReader: - return self.files().joinpath(resource).open('rb') - - def resource_path(self, resource: Any) -> NoReturn: - raise FileNotFoundError(resource) - - def is_resource(self, path: StrPath) -> bool: - return self.files().joinpath(path).is_file() - - def contents(self) -> Iterator[str]: - return (item.name for item in self.files().iterdir()) diff --git a/python/Lib/importlib/resources/readers.py b/python/Lib/importlib/resources/readers.py deleted file mode 100644 index 06bda2b..0000000 --- a/python/Lib/importlib/resources/readers.py +++ /dev/null @@ -1,122 +0,0 @@ -import collections -import operator -import pathlib -import zipfile - -from . import abc - -from ._itertools import unique_everseen - - -def remove_duplicates(items): - return iter(collections.OrderedDict.fromkeys(items)) - - -class FileReader(abc.TraversableResources): - def __init__(self, loader): - self.path = pathlib.Path(loader.path).parent - - def resource_path(self, resource): - """ - Return the file system path to prevent - `resources.path()` from creating a temporary - copy. - """ - return str(self.path.joinpath(resource)) - - def files(self): - return self.path - - -class ZipReader(abc.TraversableResources): - def __init__(self, loader, module): - _, _, name = module.rpartition('.') - self.prefix = loader.prefix.replace('\\', '/') + name + '/' - self.archive = loader.archive - - def open_resource(self, resource): - try: - return super().open_resource(resource) - except KeyError as exc: - raise FileNotFoundError(exc.args[0]) - - def is_resource(self, path): - # workaround for `zipfile.Path.is_file` returning true - # for non-existent paths. - target = self.files().joinpath(path) - return target.is_file() and target.exists() - - def files(self): - return zipfile.Path(self.archive, self.prefix) - - -class MultiplexedPath(abc.Traversable): - """ - Given a series of Traversable objects, implement a merged - version of the interface across all objects. Useful for - namespace packages which may be multihomed at a single - name. - """ - - def __init__(self, *paths): - self._paths = list(map(pathlib.Path, remove_duplicates(paths))) - if not self._paths: - message = 'MultiplexedPath must contain at least one path' - raise FileNotFoundError(message) - if not all(path.is_dir() for path in self._paths): - raise NotADirectoryError('MultiplexedPath only supports directories') - - def iterdir(self): - files = (file for path in self._paths for file in path.iterdir()) - return unique_everseen(files, key=operator.attrgetter('name')) - - def read_bytes(self): - raise FileNotFoundError(f'{self} is not a file') - - def read_text(self, *args, **kwargs): - raise FileNotFoundError(f'{self} is not a file') - - def is_dir(self): - return True - - def is_file(self): - return False - - def joinpath(self, child): - # first try to find child in current paths - for file in self.iterdir(): - if file.name == child: - return file - # if it does not exist, construct it with the first path - return self._paths[0] / child - - __truediv__ = joinpath - - def open(self, *args, **kwargs): - raise FileNotFoundError(f'{self} is not a file') - - @property - def name(self): - return self._paths[0].name - - def __repr__(self): - paths = ', '.join(f"'{path}'" for path in self._paths) - return f'MultiplexedPath({paths})' - - -class NamespaceReader(abc.TraversableResources): - def __init__(self, namespace_path): - if 'NamespacePath' not in str(namespace_path): - raise ValueError('Invalid path') - self.path = MultiplexedPath(*list(namespace_path)) - - def resource_path(self, resource): - """ - Return the file system path to prevent - `resources.path()` from creating a temporary - copy. - """ - return str(self.path.joinpath(resource)) - - def files(self): - return self.path diff --git a/python/Lib/importlib/resources/simple.py b/python/Lib/importlib/resources/simple.py deleted file mode 100644 index 0c62388..0000000 --- a/python/Lib/importlib/resources/simple.py +++ /dev/null @@ -1,125 +0,0 @@ -""" -Interface adapters for low-level readers. -""" - -import abc -import io -import itertools -from typing import BinaryIO, List - -from .abc import Traversable, TraversableResources - - -class SimpleReader(abc.ABC): - """ - The minimum, low-level interface required from a resource - provider. - """ - - @abc.abstractproperty - def package(self): - # type: () -> str - """ - The name of the package for which this reader loads resources. - """ - - @abc.abstractmethod - def children(self): - # type: () -> List['SimpleReader'] - """ - Obtain an iterable of SimpleReader for available - child containers (e.g. directories). - """ - - @abc.abstractmethod - def resources(self): - # type: () -> List[str] - """ - Obtain available named resources for this virtual package. - """ - - @abc.abstractmethod - def open_binary(self, resource): - # type: (str) -> BinaryIO - """ - Obtain a File-like for a named resource. - """ - - @property - def name(self): - return self.package.split('.')[-1] - - -class ResourceHandle(Traversable): - """ - Handle to a named resource in a ResourceReader. - """ - - def __init__(self, parent, name): - # type: (ResourceContainer, str) -> None - self.parent = parent - self.name = name # type: ignore - - def is_file(self): - return True - - def is_dir(self): - return False - - def open(self, mode='r', *args, **kwargs): - stream = self.parent.reader.open_binary(self.name) - if 'b' not in mode: - stream = io.TextIOWrapper(*args, **kwargs) - return stream - - def joinpath(self, name): - raise RuntimeError("Cannot traverse into a resource") - - -class ResourceContainer(Traversable): - """ - Traversable container for a package's resources via its reader. - """ - - def __init__(self, reader): - # type: (SimpleReader) -> None - self.reader = reader - - def is_dir(self): - return True - - def is_file(self): - return False - - def iterdir(self): - files = (ResourceHandle(self, name) for name in self.reader.resources) - dirs = map(ResourceContainer, self.reader.children()) - return itertools.chain(files, dirs) - - def open(self, *args, **kwargs): - raise IsADirectoryError() - - @staticmethod - def _flatten(compound_names): - for name in compound_names: - yield from name.split('/') - - def joinpath(self, *descendants): - if not descendants: - return self - names = self._flatten(descendants) - target = next(names) - return next( - traversable for traversable in self.iterdir() if traversable.name == target - ).joinpath(*names) - - -class TraversableReader(TraversableResources, SimpleReader): - """ - A TraversableResources based on SimpleReader. Resource providers - may derive from this class to provide the TraversableResources - interface by supplying the SimpleReader interface. - """ - - def files(self): - return ResourceContainer(self) diff --git a/python/Lib/importlib/simple.py b/python/Lib/importlib/simple.py deleted file mode 100644 index 5d4d9fd..0000000 --- a/python/Lib/importlib/simple.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -Compatibility shim for .resources.simple as found on Python 3.10. - -Consumers that can rely on Python 3.11 should use the other -module directly. -""" - -from .resources.simple import ( - SimpleReader, ResourceHandle, ResourceContainer, TraversableReader, -) - -__all__ = [ - 'SimpleReader', 'ResourceHandle', 'ResourceContainer', 'TraversableReader', -] diff --git a/python/Lib/importlib/util.py b/python/Lib/importlib/util.py deleted file mode 100644 index 3d94f49..0000000 --- a/python/Lib/importlib/util.py +++ /dev/null @@ -1,302 +0,0 @@ -"""Utility code for constructing importers, etc.""" -from ._abc import Loader -from ._bootstrap import module_from_spec -from ._bootstrap import _resolve_name -from ._bootstrap import spec_from_loader -from ._bootstrap import _find_spec -from ._bootstrap_external import MAGIC_NUMBER -from ._bootstrap_external import _RAW_MAGIC_NUMBER -from ._bootstrap_external import cache_from_source -from ._bootstrap_external import decode_source -from ._bootstrap_external import source_from_cache -from ._bootstrap_external import spec_from_file_location - -from contextlib import contextmanager -import _imp -import functools -import sys -import types -import warnings - - -def source_hash(source_bytes): - "Return the hash of *source_bytes* as used in hash-based pyc files." - return _imp.source_hash(_RAW_MAGIC_NUMBER, source_bytes) - - -def resolve_name(name, package): - """Resolve a relative module name to an absolute one.""" - if not name.startswith('.'): - return name - elif not package: - raise ImportError(f'no package specified for {repr(name)} ' - '(required for relative module names)') - level = 0 - for character in name: - if character != '.': - break - level += 1 - return _resolve_name(name[level:], package, level) - - -def _find_spec_from_path(name, path=None): - """Return the spec for the specified module. - - First, sys.modules is checked to see if the module was already imported. If - so, then sys.modules[name].__spec__ is returned. If that happens to be - set to None, then ValueError is raised. If the module is not in - sys.modules, then sys.meta_path is searched for a suitable spec with the - value of 'path' given to the finders. None is returned if no spec could - be found. - - Dotted names do not have their parent packages implicitly imported. You will - most likely need to explicitly import all parent packages in the proper - order for a submodule to get the correct spec. - - """ - if name not in sys.modules: - return _find_spec(name, path) - else: - module = sys.modules[name] - if module is None: - return None - try: - spec = module.__spec__ - except AttributeError: - raise ValueError('{}.__spec__ is not set'.format(name)) from None - else: - if spec is None: - raise ValueError('{}.__spec__ is None'.format(name)) - return spec - - -def find_spec(name, package=None): - """Return the spec for the specified module. - - First, sys.modules is checked to see if the module was already imported. If - so, then sys.modules[name].__spec__ is returned. If that happens to be - set to None, then ValueError is raised. If the module is not in - sys.modules, then sys.meta_path is searched for a suitable spec with the - value of 'path' given to the finders. None is returned if no spec could - be found. - - If the name is for submodule (contains a dot), the parent module is - automatically imported. - - The name and package arguments work the same as importlib.import_module(). - In other words, relative module names (with leading dots) work. - - """ - fullname = resolve_name(name, package) if name.startswith('.') else name - if fullname not in sys.modules: - parent_name = fullname.rpartition('.')[0] - if parent_name: - parent = __import__(parent_name, fromlist=['__path__']) - try: - parent_path = parent.__path__ - except AttributeError as e: - raise ModuleNotFoundError( - f"__path__ attribute not found on {parent_name!r} " - f"while trying to find {fullname!r}", name=fullname) from e - else: - parent_path = None - return _find_spec(fullname, parent_path) - else: - module = sys.modules[fullname] - if module is None: - return None - try: - spec = module.__spec__ - except AttributeError: - raise ValueError('{}.__spec__ is not set'.format(name)) from None - else: - if spec is None: - raise ValueError('{}.__spec__ is None'.format(name)) - return spec - - -@contextmanager -def _module_to_load(name): - is_reload = name in sys.modules - - module = sys.modules.get(name) - if not is_reload: - # This must be done before open() is called as the 'io' module - # implicitly imports 'locale' and would otherwise trigger an - # infinite loop. - module = type(sys)(name) - # This must be done before putting the module in sys.modules - # (otherwise an optimization shortcut in import.c becomes wrong) - module.__initializing__ = True - sys.modules[name] = module - try: - yield module - except Exception: - if not is_reload: - try: - del sys.modules[name] - except KeyError: - pass - finally: - module.__initializing__ = False - - -def set_package(fxn): - """Set __package__ on the returned module. - - This function is deprecated. - - """ - @functools.wraps(fxn) - def set_package_wrapper(*args, **kwargs): - warnings.warn('The import system now takes care of this automatically; ' - 'this decorator is slated for removal in Python 3.12', - DeprecationWarning, stacklevel=2) - module = fxn(*args, **kwargs) - if getattr(module, '__package__', None) is None: - module.__package__ = module.__name__ - if not hasattr(module, '__path__'): - module.__package__ = module.__package__.rpartition('.')[0] - return module - return set_package_wrapper - - -def set_loader(fxn): - """Set __loader__ on the returned module. - - This function is deprecated. - - """ - @functools.wraps(fxn) - def set_loader_wrapper(self, *args, **kwargs): - warnings.warn('The import system now takes care of this automatically; ' - 'this decorator is slated for removal in Python 3.12', - DeprecationWarning, stacklevel=2) - module = fxn(self, *args, **kwargs) - if getattr(module, '__loader__', None) is None: - module.__loader__ = self - return module - return set_loader_wrapper - - -def module_for_loader(fxn): - """Decorator to handle selecting the proper module for loaders. - - The decorated function is passed the module to use instead of the module - name. The module passed in to the function is either from sys.modules if - it already exists or is a new module. If the module is new, then __name__ - is set the first argument to the method, __loader__ is set to self, and - __package__ is set accordingly (if self.is_package() is defined) will be set - before it is passed to the decorated function (if self.is_package() does - not work for the module it will be set post-load). - - If an exception is raised and the decorator created the module it is - subsequently removed from sys.modules. - - The decorator assumes that the decorated function takes the module name as - the second argument. - - """ - warnings.warn('The import system now takes care of this automatically; ' - 'this decorator is slated for removal in Python 3.12', - DeprecationWarning, stacklevel=2) - @functools.wraps(fxn) - def module_for_loader_wrapper(self, fullname, *args, **kwargs): - with _module_to_load(fullname) as module: - module.__loader__ = self - try: - is_package = self.is_package(fullname) - except (ImportError, AttributeError): - pass - else: - if is_package: - module.__package__ = fullname - else: - module.__package__ = fullname.rpartition('.')[0] - # If __package__ was not set above, __import__() will do it later. - return fxn(self, module, *args, **kwargs) - - return module_for_loader_wrapper - - -class _LazyModule(types.ModuleType): - - """A subclass of the module type which triggers loading upon attribute access.""" - - def __getattribute__(self, attr): - """Trigger the load of the module and return the attribute.""" - # All module metadata must be garnered from __spec__ in order to avoid - # using mutated values. - # Stop triggering this method. - self.__class__ = types.ModuleType - # Get the original name to make sure no object substitution occurred - # in sys.modules. - original_name = self.__spec__.name - # Figure out exactly what attributes were mutated between the creation - # of the module and now. - attrs_then = self.__spec__.loader_state['__dict__'] - attrs_now = self.__dict__ - attrs_updated = {} - for key, value in attrs_now.items(): - # Code that set the attribute may have kept a reference to the - # assigned object, making identity more important than equality. - if key not in attrs_then: - attrs_updated[key] = value - elif id(attrs_now[key]) != id(attrs_then[key]): - attrs_updated[key] = value - self.__spec__.loader.exec_module(self) - # If exec_module() was used directly there is no guarantee the module - # object was put into sys.modules. - if original_name in sys.modules: - if id(self) != id(sys.modules[original_name]): - raise ValueError(f"module object for {original_name!r} " - "substituted in sys.modules during a lazy " - "load") - # Update after loading since that's what would happen in an eager - # loading situation. - self.__dict__.update(attrs_updated) - return getattr(self, attr) - - def __delattr__(self, attr): - """Trigger the load and then perform the deletion.""" - # To trigger the load and raise an exception if the attribute - # doesn't exist. - self.__getattribute__(attr) - delattr(self, attr) - - -class LazyLoader(Loader): - - """A loader that creates a module which defers loading until attribute access.""" - - @staticmethod - def __check_eager_loader(loader): - if not hasattr(loader, 'exec_module'): - raise TypeError('loader must define exec_module()') - - @classmethod - def factory(cls, loader): - """Construct a callable which returns the eager loader made lazy.""" - cls.__check_eager_loader(loader) - return lambda *args, **kwargs: cls(loader(*args, **kwargs)) - - def __init__(self, loader): - self.__check_eager_loader(loader) - self.loader = loader - - def create_module(self, spec): - return self.loader.create_module(spec) - - def exec_module(self, module): - """Make the module load lazily.""" - module.__spec__.loader = self.loader - module.__loader__ = self.loader - # Don't need to worry about deep-copying as trying to set an attribute - # on an object would have triggered the load, - # e.g. ``module.__spec__.loader = None`` would trigger a load from - # trying to access module.__spec__. - loader_state = {} - loader_state['__dict__'] = module.__dict__.copy() - loader_state['__class__'] = module.__class__ - module.__spec__.loader_state = loader_state - module.__class__ = _LazyModule diff --git a/python/Lib/inspect.py b/python/Lib/inspect.py deleted file mode 100644 index 0fdba74..0000000 --- a/python/Lib/inspect.py +++ /dev/null @@ -1,3341 +0,0 @@ -"""Get useful information from live Python objects. - -This module encapsulates the interface provided by the internal special -attributes (co_*, im_*, tb_*, etc.) in a friendlier fashion. -It also provides some help for examining source code and class layout. - -Here are some of the useful functions provided by this module: - - ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(), - isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(), - isroutine() - check object types - getmembers() - get members of an object that satisfy a given condition - - getfile(), getsourcefile(), getsource() - find an object's source code - getdoc(), getcomments() - get documentation on an object - getmodule() - determine the module that an object came from - getclasstree() - arrange classes so as to represent their hierarchy - - getargvalues(), getcallargs() - get info about function arguments - getfullargspec() - same, with support for Python 3 features - formatargvalues() - format an argument spec - getouterframes(), getinnerframes() - get info about frames - currentframe() - get the current stack frame - stack(), trace() - get info about frames on the stack or in a traceback - - signature() - get a Signature object for the callable - - get_annotations() - safely compute an object's annotations -""" - -# This module is in the public domain. No warranties. - -__author__ = ('Ka-Ping Yee ', - 'Yury Selivanov ') - -__all__ = [ - "ArgInfo", - "Arguments", - "Attribute", - "BlockFinder", - "BoundArguments", - "CORO_CLOSED", - "CORO_CREATED", - "CORO_RUNNING", - "CORO_SUSPENDED", - "CO_ASYNC_GENERATOR", - "CO_COROUTINE", - "CO_GENERATOR", - "CO_ITERABLE_COROUTINE", - "CO_NESTED", - "CO_NEWLOCALS", - "CO_NOFREE", - "CO_OPTIMIZED", - "CO_VARARGS", - "CO_VARKEYWORDS", - "ClassFoundException", - "ClosureVars", - "EndOfBlock", - "FrameInfo", - "FullArgSpec", - "GEN_CLOSED", - "GEN_CREATED", - "GEN_RUNNING", - "GEN_SUSPENDED", - "Parameter", - "Signature", - "TPFLAGS_IS_ABSTRACT", - "Traceback", - "classify_class_attrs", - "cleandoc", - "currentframe", - "findsource", - "formatannotation", - "formatannotationrelativeto", - "formatargvalues", - "get_annotations", - "getabsfile", - "getargs", - "getargvalues", - "getattr_static", - "getblock", - "getcallargs", - "getclasstree", - "getclosurevars", - "getcomments", - "getcoroutinelocals", - "getcoroutinestate", - "getdoc", - "getfile", - "getframeinfo", - "getfullargspec", - "getgeneratorlocals", - "getgeneratorstate", - "getinnerframes", - "getlineno", - "getmembers", - "getmembers_static", - "getmodule", - "getmodulename", - "getmro", - "getouterframes", - "getsource", - "getsourcefile", - "getsourcelines", - "indentsize", - "isabstract", - "isasyncgen", - "isasyncgenfunction", - "isawaitable", - "isbuiltin", - "isclass", - "iscode", - "iscoroutine", - "iscoroutinefunction", - "isdatadescriptor", - "isframe", - "isfunction", - "isgenerator", - "isgeneratorfunction", - "isgetsetdescriptor", - "ismemberdescriptor", - "ismethod", - "ismethoddescriptor", - "ismethodwrapper", - "ismodule", - "isroutine", - "istraceback", - "signature", - "stack", - "trace", - "unwrap", - "walktree", -] - - -import abc -import ast -import dis -import collections.abc -import enum -import importlib.machinery -import itertools -import linecache -import os -import re -import sys -import tokenize -import token -import types -import functools -import builtins -from keyword import iskeyword -from operator import attrgetter -from collections import namedtuple, OrderedDict - -# Create constants for the compiler flags in Include/code.h -# We try to get them from dis to avoid duplication -mod_dict = globals() -for k, v in dis.COMPILER_FLAG_NAMES.items(): - mod_dict["CO_" + v] = k -del k, v, mod_dict - -# See Include/object.h -TPFLAGS_IS_ABSTRACT = 1 << 20 - - -def get_annotations(obj, *, globals=None, locals=None, eval_str=False): - """Compute the annotations dict for an object. - - obj may be a callable, class, or module. - Passing in an object of any other type raises TypeError. - - Returns a dict. get_annotations() returns a new dict every time - it's called; calling it twice on the same object will return two - different but equivalent dicts. - - This function handles several details for you: - - * If eval_str is true, values of type str will - be un-stringized using eval(). This is intended - for use with stringized annotations - ("from __future__ import annotations"). - * If obj doesn't have an annotations dict, returns an - empty dict. (Functions and methods always have an - annotations dict; classes, modules, and other types of - callables may not.) - * Ignores inherited annotations on classes. If a class - doesn't have its own annotations dict, returns an empty dict. - * All accesses to object members and dict values are done - using getattr() and dict.get() for safety. - * Always, always, always returns a freshly-created dict. - - eval_str controls whether or not values of type str are replaced - with the result of calling eval() on those values: - - * If eval_str is true, eval() is called on values of type str. - * If eval_str is false (the default), values of type str are unchanged. - - globals and locals are passed in to eval(); see the documentation - for eval() for more information. If either globals or locals is - None, this function may replace that value with a context-specific - default, contingent on type(obj): - - * If obj is a module, globals defaults to obj.__dict__. - * If obj is a class, globals defaults to - sys.modules[obj.__module__].__dict__ and locals - defaults to the obj class namespace. - * If obj is a callable, globals defaults to obj.__globals__, - although if obj is a wrapped function (using - functools.update_wrapper()) it is first unwrapped. - """ - if isinstance(obj, type): - # class - obj_dict = getattr(obj, '__dict__', None) - if obj_dict and hasattr(obj_dict, 'get'): - ann = obj_dict.get('__annotations__', None) - if isinstance(ann, types.GetSetDescriptorType): - ann = None - else: - ann = None - - obj_globals = None - module_name = getattr(obj, '__module__', None) - if module_name: - module = sys.modules.get(module_name, None) - if module: - obj_globals = getattr(module, '__dict__', None) - obj_locals = dict(vars(obj)) - unwrap = obj - elif isinstance(obj, types.ModuleType): - # module - ann = getattr(obj, '__annotations__', None) - obj_globals = getattr(obj, '__dict__') - obj_locals = None - unwrap = None - elif callable(obj): - # this includes types.Function, types.BuiltinFunctionType, - # types.BuiltinMethodType, functools.partial, functools.singledispatch, - # "class funclike" from Lib/test/test_inspect... on and on it goes. - ann = getattr(obj, '__annotations__', None) - obj_globals = getattr(obj, '__globals__', None) - obj_locals = None - unwrap = obj - else: - raise TypeError(f"{obj!r} is not a module, class, or callable.") - - if ann is None: - return {} - - if not isinstance(ann, dict): - raise ValueError(f"{obj!r}.__annotations__ is neither a dict nor None") - - if not ann: - return {} - - if not eval_str: - return dict(ann) - - if unwrap is not None: - while True: - if hasattr(unwrap, '__wrapped__'): - unwrap = unwrap.__wrapped__ - continue - if isinstance(unwrap, functools.partial): - unwrap = unwrap.func - continue - break - if hasattr(unwrap, "__globals__"): - obj_globals = unwrap.__globals__ - - if globals is None: - globals = obj_globals - if locals is None: - locals = obj_locals - - return_value = {key: - value if not isinstance(value, str) else eval(value, globals, locals) - for key, value in ann.items() } - return return_value - - -# ----------------------------------------------------------- type-checking -def ismodule(object): - """Return true if the object is a module. - - Module objects provide these attributes: - __cached__ pathname to byte compiled file - __doc__ documentation string - __file__ filename (missing for built-in modules)""" - return isinstance(object, types.ModuleType) - -def isclass(object): - """Return true if the object is a class. - - Class objects provide these attributes: - __doc__ documentation string - __module__ name of module in which this class was defined""" - return isinstance(object, type) - -def ismethod(object): - """Return true if the object is an instance method. - - Instance method objects provide these attributes: - __doc__ documentation string - __name__ name with which this method was defined - __func__ function object containing implementation of method - __self__ instance to which this method is bound""" - return isinstance(object, types.MethodType) - -def ismethoddescriptor(object): - """Return true if the object is a method descriptor. - - But not if ismethod() or isclass() or isfunction() are true. - - This is new in Python 2.2, and, for example, is true of int.__add__. - An object passing this test has a __get__ attribute but not a __set__ - attribute, but beyond that the set of attributes varies. __name__ is - usually sensible, and __doc__ often is. - - Methods implemented via descriptors that also pass one of the other - tests return false from the ismethoddescriptor() test, simply because - the other tests promise more -- you can, e.g., count on having the - __func__ attribute (etc) when an object passes ismethod().""" - if isclass(object) or ismethod(object) or isfunction(object): - # mutual exclusion - return False - tp = type(object) - return hasattr(tp, "__get__") and not hasattr(tp, "__set__") - -def isdatadescriptor(object): - """Return true if the object is a data descriptor. - - Data descriptors have a __set__ or a __delete__ attribute. Examples are - properties (defined in Python) and getsets and members (defined in C). - Typically, data descriptors will also have __name__ and __doc__ attributes - (properties, getsets, and members have both of these attributes), but this - is not guaranteed.""" - if isclass(object) or ismethod(object) or isfunction(object): - # mutual exclusion - return False - tp = type(object) - return hasattr(tp, "__set__") or hasattr(tp, "__delete__") - -if hasattr(types, 'MemberDescriptorType'): - # CPython and equivalent - def ismemberdescriptor(object): - """Return true if the object is a member descriptor. - - Member descriptors are specialized descriptors defined in extension - modules.""" - return isinstance(object, types.MemberDescriptorType) -else: - # Other implementations - def ismemberdescriptor(object): - """Return true if the object is a member descriptor. - - Member descriptors are specialized descriptors defined in extension - modules.""" - return False - -if hasattr(types, 'GetSetDescriptorType'): - # CPython and equivalent - def isgetsetdescriptor(object): - """Return true if the object is a getset descriptor. - - getset descriptors are specialized descriptors defined in extension - modules.""" - return isinstance(object, types.GetSetDescriptorType) -else: - # Other implementations - def isgetsetdescriptor(object): - """Return true if the object is a getset descriptor. - - getset descriptors are specialized descriptors defined in extension - modules.""" - return False - -def isfunction(object): - """Return true if the object is a user-defined function. - - Function objects provide these attributes: - __doc__ documentation string - __name__ name with which this function was defined - __code__ code object containing compiled function bytecode - __defaults__ tuple of any default values for arguments - __globals__ global namespace in which this function was defined - __annotations__ dict of parameter annotations - __kwdefaults__ dict of keyword only parameters with defaults""" - return isinstance(object, types.FunctionType) - -def _has_code_flag(f, flag): - """Return true if ``f`` is a function (or a method or functools.partial - wrapper wrapping a function) whose code object has the given ``flag`` - set in its flags.""" - while ismethod(f): - f = f.__func__ - f = functools._unwrap_partial(f) - if not (isfunction(f) or _signature_is_functionlike(f)): - return False - return bool(f.__code__.co_flags & flag) - -def isgeneratorfunction(obj): - """Return true if the object is a user-defined generator function. - - Generator function objects provide the same attributes as functions. - See help(isfunction) for a list of attributes.""" - return _has_code_flag(obj, CO_GENERATOR) - -def iscoroutinefunction(obj): - """Return true if the object is a coroutine function. - - Coroutine functions are defined with "async def" syntax. - """ - return _has_code_flag(obj, CO_COROUTINE) - -def isasyncgenfunction(obj): - """Return true if the object is an asynchronous generator function. - - Asynchronous generator functions are defined with "async def" - syntax and have "yield" expressions in their body. - """ - return _has_code_flag(obj, CO_ASYNC_GENERATOR) - -def isasyncgen(object): - """Return true if the object is an asynchronous generator.""" - return isinstance(object, types.AsyncGeneratorType) - -def isgenerator(object): - """Return true if the object is a generator. - - Generator objects provide these attributes: - __iter__ defined to support iteration over container - close raises a new GeneratorExit exception inside the - generator to terminate the iteration - gi_code code object - gi_frame frame object or possibly None once the generator has - been exhausted - gi_running set to 1 when generator is executing, 0 otherwise - next return the next item from the container - send resumes the generator and "sends" a value that becomes - the result of the current yield-expression - throw used to raise an exception inside the generator""" - return isinstance(object, types.GeneratorType) - -def iscoroutine(object): - """Return true if the object is a coroutine.""" - return isinstance(object, types.CoroutineType) - -def isawaitable(object): - """Return true if object can be passed to an ``await`` expression.""" - return (isinstance(object, types.CoroutineType) or - isinstance(object, types.GeneratorType) and - bool(object.gi_code.co_flags & CO_ITERABLE_COROUTINE) or - isinstance(object, collections.abc.Awaitable)) - -def istraceback(object): - """Return true if the object is a traceback. - - Traceback objects provide these attributes: - tb_frame frame object at this level - tb_lasti index of last attempted instruction in bytecode - tb_lineno current line number in Python source code - tb_next next inner traceback object (called by this level)""" - return isinstance(object, types.TracebackType) - -def isframe(object): - """Return true if the object is a frame object. - - Frame objects provide these attributes: - f_back next outer frame object (this frame's caller) - f_builtins built-in namespace seen by this frame - f_code code object being executed in this frame - f_globals global namespace seen by this frame - f_lasti index of last attempted instruction in bytecode - f_lineno current line number in Python source code - f_locals local namespace seen by this frame - f_trace tracing function for this frame, or None""" - return isinstance(object, types.FrameType) - -def iscode(object): - """Return true if the object is a code object. - - Code objects provide these attributes: - co_argcount number of arguments (not including *, ** args - or keyword only arguments) - co_code string of raw compiled bytecode - co_cellvars tuple of names of cell variables - co_consts tuple of constants used in the bytecode - co_filename name of file in which this code object was created - co_firstlineno number of first line in Python source code - co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg - | 16=nested | 32=generator | 64=nofree | 128=coroutine - | 256=iterable_coroutine | 512=async_generator - co_freevars tuple of names of free variables - co_posonlyargcount number of positional only arguments - co_kwonlyargcount number of keyword only arguments (not including ** arg) - co_lnotab encoded mapping of line numbers to bytecode indices - co_name name with which this code object was defined - co_names tuple of names other than arguments and function locals - co_nlocals number of local variables - co_stacksize virtual machine stack space required - co_varnames tuple of names of arguments and local variables""" - return isinstance(object, types.CodeType) - -def isbuiltin(object): - """Return true if the object is a built-in function or method. - - Built-in functions and methods provide these attributes: - __doc__ documentation string - __name__ original name of this function or method - __self__ instance to which a method is bound, or None""" - return isinstance(object, types.BuiltinFunctionType) - -def ismethodwrapper(object): - """Return true if the object is a method wrapper.""" - return isinstance(object, types.MethodWrapperType) - -def isroutine(object): - """Return true if the object is any kind of function or method.""" - return (isbuiltin(object) - or isfunction(object) - or ismethod(object) - or ismethoddescriptor(object) - or ismethodwrapper(object)) - -def isabstract(object): - """Return true if the object is an abstract base class (ABC).""" - if not isinstance(object, type): - return False - if object.__flags__ & TPFLAGS_IS_ABSTRACT: - return True - if not issubclass(type(object), abc.ABCMeta): - return False - if hasattr(object, '__abstractmethods__'): - # It looks like ABCMeta.__new__ has finished running; - # TPFLAGS_IS_ABSTRACT should have been accurate. - return False - # It looks like ABCMeta.__new__ has not finished running yet; we're - # probably in __init_subclass__. We'll look for abstractmethods manually. - for name, value in object.__dict__.items(): - if getattr(value, "__isabstractmethod__", False): - return True - for base in object.__bases__: - for name in getattr(base, "__abstractmethods__", ()): - value = getattr(object, name, None) - if getattr(value, "__isabstractmethod__", False): - return True - return False - -def _getmembers(object, predicate, getter): - results = [] - processed = set() - names = dir(object) - if isclass(object): - mro = (object,) + getmro(object) - # add any DynamicClassAttributes to the list of names if object is a class; - # this may result in duplicate entries if, for example, a virtual - # attribute with the same name as a DynamicClassAttribute exists - try: - for base in object.__bases__: - for k, v in base.__dict__.items(): - if isinstance(v, types.DynamicClassAttribute): - names.append(k) - except AttributeError: - pass - else: - mro = () - for key in names: - # First try to get the value via getattr. Some descriptors don't - # like calling their __get__ (see bug #1785), so fall back to - # looking in the __dict__. - try: - value = getter(object, key) - # handle the duplicate key - if key in processed: - raise AttributeError - except AttributeError: - for base in mro: - if key in base.__dict__: - value = base.__dict__[key] - break - else: - # could be a (currently) missing slot member, or a buggy - # __dir__; discard and move on - continue - if not predicate or predicate(value): - results.append((key, value)) - processed.add(key) - results.sort(key=lambda pair: pair[0]) - return results - -def getmembers(object, predicate=None): - """Return all members of an object as (name, value) pairs sorted by name. - Optionally, only return members that satisfy a given predicate.""" - return _getmembers(object, predicate, getattr) - -def getmembers_static(object, predicate=None): - """Return all members of an object as (name, value) pairs sorted by name - without triggering dynamic lookup via the descriptor protocol, - __getattr__ or __getattribute__. Optionally, only return members that - satisfy a given predicate. - - Note: this function may not be able to retrieve all members - that getmembers can fetch (like dynamically created attributes) - and may find members that getmembers can't (like descriptors - that raise AttributeError). It can also return descriptor objects - instead of instance members in some cases. - """ - return _getmembers(object, predicate, getattr_static) - -Attribute = namedtuple('Attribute', 'name kind defining_class object') - -def classify_class_attrs(cls): - """Return list of attribute-descriptor tuples. - - For each name in dir(cls), the return list contains a 4-tuple - with these elements: - - 0. The name (a string). - - 1. The kind of attribute this is, one of these strings: - 'class method' created via classmethod() - 'static method' created via staticmethod() - 'property' created via property() - 'method' any other flavor of method or descriptor - 'data' not a method - - 2. The class which defined this attribute (a class). - - 3. The object as obtained by calling getattr; if this fails, or if the - resulting object does not live anywhere in the class' mro (including - metaclasses) then the object is looked up in the defining class's - dict (found by walking the mro). - - If one of the items in dir(cls) is stored in the metaclass it will now - be discovered and not have None be listed as the class in which it was - defined. Any items whose home class cannot be discovered are skipped. - """ - - mro = getmro(cls) - metamro = getmro(type(cls)) # for attributes stored in the metaclass - metamro = tuple(cls for cls in metamro if cls not in (type, object)) - class_bases = (cls,) + mro - all_bases = class_bases + metamro - names = dir(cls) - # :dd any DynamicClassAttributes to the list of names; - # this may result in duplicate entries if, for example, a virtual - # attribute with the same name as a DynamicClassAttribute exists. - for base in mro: - for k, v in base.__dict__.items(): - if isinstance(v, types.DynamicClassAttribute) and v.fget is not None: - names.append(k) - result = [] - processed = set() - - for name in names: - # Get the object associated with the name, and where it was defined. - # Normal objects will be looked up with both getattr and directly in - # its class' dict (in case getattr fails [bug #1785], and also to look - # for a docstring). - # For DynamicClassAttributes on the second pass we only look in the - # class's dict. - # - # Getting an obj from the __dict__ sometimes reveals more than - # using getattr. Static and class methods are dramatic examples. - homecls = None - get_obj = None - dict_obj = None - if name not in processed: - try: - if name == '__dict__': - raise Exception("__dict__ is special, don't want the proxy") - get_obj = getattr(cls, name) - except Exception as exc: - pass - else: - homecls = getattr(get_obj, "__objclass__", homecls) - if homecls not in class_bases: - # if the resulting object does not live somewhere in the - # mro, drop it and search the mro manually - homecls = None - last_cls = None - # first look in the classes - for srch_cls in class_bases: - srch_obj = getattr(srch_cls, name, None) - if srch_obj is get_obj: - last_cls = srch_cls - # then check the metaclasses - for srch_cls in metamro: - try: - srch_obj = srch_cls.__getattr__(cls, name) - except AttributeError: - continue - if srch_obj is get_obj: - last_cls = srch_cls - if last_cls is not None: - homecls = last_cls - for base in all_bases: - if name in base.__dict__: - dict_obj = base.__dict__[name] - if homecls not in metamro: - homecls = base - break - if homecls is None: - # unable to locate the attribute anywhere, most likely due to - # buggy custom __dir__; discard and move on - continue - obj = get_obj if get_obj is not None else dict_obj - # Classify the object or its descriptor. - if isinstance(dict_obj, (staticmethod, types.BuiltinMethodType)): - kind = "static method" - obj = dict_obj - elif isinstance(dict_obj, (classmethod, types.ClassMethodDescriptorType)): - kind = "class method" - obj = dict_obj - elif isinstance(dict_obj, property): - kind = "property" - obj = dict_obj - elif isroutine(obj): - kind = "method" - else: - kind = "data" - result.append(Attribute(name, kind, homecls, obj)) - processed.add(name) - return result - -# ----------------------------------------------------------- class helpers - -def getmro(cls): - "Return tuple of base classes (including cls) in method resolution order." - return cls.__mro__ - -# -------------------------------------------------------- function helpers - -def unwrap(func, *, stop=None): - """Get the object wrapped by *func*. - - Follows the chain of :attr:`__wrapped__` attributes returning the last - object in the chain. - - *stop* is an optional callback accepting an object in the wrapper chain - as its sole argument that allows the unwrapping to be terminated early if - the callback returns a true value. If the callback never returns a true - value, the last object in the chain is returned as usual. For example, - :func:`signature` uses this to stop unwrapping if any object in the - chain has a ``__signature__`` attribute defined. - - :exc:`ValueError` is raised if a cycle is encountered. - - """ - if stop is None: - def _is_wrapper(f): - return hasattr(f, '__wrapped__') - else: - def _is_wrapper(f): - return hasattr(f, '__wrapped__') and not stop(f) - f = func # remember the original func for error reporting - # Memoise by id to tolerate non-hashable objects, but store objects to - # ensure they aren't destroyed, which would allow their IDs to be reused. - memo = {id(f): f} - recursion_limit = sys.getrecursionlimit() - while _is_wrapper(func): - func = func.__wrapped__ - id_func = id(func) - if (id_func in memo) or (len(memo) >= recursion_limit): - raise ValueError('wrapper loop when unwrapping {!r}'.format(f)) - memo[id_func] = func - return func - -# -------------------------------------------------- source code extraction -def indentsize(line): - """Return the indent size, in spaces, at the start of a line of text.""" - expline = line.expandtabs() - return len(expline) - len(expline.lstrip()) - -def _findclass(func): - cls = sys.modules.get(func.__module__) - if cls is None: - return None - for name in func.__qualname__.split('.')[:-1]: - cls = getattr(cls, name) - if not isclass(cls): - return None - return cls - -def _finddoc(obj): - if isclass(obj): - for base in obj.__mro__: - if base is not object: - try: - doc = base.__doc__ - except AttributeError: - continue - if doc is not None: - return doc - return None - - if ismethod(obj): - name = obj.__func__.__name__ - self = obj.__self__ - if (isclass(self) and - getattr(getattr(self, name, None), '__func__') is obj.__func__): - # classmethod - cls = self - else: - cls = self.__class__ - elif isfunction(obj): - name = obj.__name__ - cls = _findclass(obj) - if cls is None or getattr(cls, name) is not obj: - return None - elif isbuiltin(obj): - name = obj.__name__ - self = obj.__self__ - if (isclass(self) and - self.__qualname__ + '.' + name == obj.__qualname__): - # classmethod - cls = self - else: - cls = self.__class__ - # Should be tested before isdatadescriptor(). - elif isinstance(obj, property): - func = obj.fget - name = func.__name__ - cls = _findclass(func) - if cls is None or getattr(cls, name) is not obj: - return None - elif ismethoddescriptor(obj) or isdatadescriptor(obj): - name = obj.__name__ - cls = obj.__objclass__ - if getattr(cls, name) is not obj: - return None - if ismemberdescriptor(obj): - slots = getattr(cls, '__slots__', None) - if isinstance(slots, dict) and name in slots: - return slots[name] - else: - return None - for base in cls.__mro__: - try: - doc = getattr(base, name).__doc__ - except AttributeError: - continue - if doc is not None: - return doc - return None - -def getdoc(object): - """Get the documentation string for an object. - - All tabs are expanded to spaces. To clean up docstrings that are - indented to line up with blocks of code, any whitespace than can be - uniformly removed from the second line onwards is removed.""" - try: - doc = object.__doc__ - except AttributeError: - return None - if doc is None: - try: - doc = _finddoc(object) - except (AttributeError, TypeError): - return None - if not isinstance(doc, str): - return None - return cleandoc(doc) - -def cleandoc(doc): - """Clean up indentation from docstrings. - - Any whitespace that can be uniformly removed from the second line - onwards is removed.""" - try: - lines = doc.expandtabs().split('\n') - except UnicodeError: - return None - else: - # Find minimum indentation of any non-blank lines after first line. - margin = sys.maxsize - for line in lines[1:]: - content = len(line.lstrip()) - if content: - indent = len(line) - content - margin = min(margin, indent) - # Remove indentation. - if lines: - lines[0] = lines[0].lstrip() - if margin < sys.maxsize: - for i in range(1, len(lines)): lines[i] = lines[i][margin:] - # Remove any trailing or leading blank lines. - while lines and not lines[-1]: - lines.pop() - while lines and not lines[0]: - lines.pop(0) - return '\n'.join(lines) - -def getfile(object): - """Work out which source or compiled file an object was defined in.""" - if ismodule(object): - if getattr(object, '__file__', None): - return object.__file__ - raise TypeError('{!r} is a built-in module'.format(object)) - if isclass(object): - if hasattr(object, '__module__'): - module = sys.modules.get(object.__module__) - if getattr(module, '__file__', None): - return module.__file__ - if object.__module__ == '__main__': - raise OSError('source code not available') - raise TypeError('{!r} is a built-in class'.format(object)) - if ismethod(object): - object = object.__func__ - if isfunction(object): - object = object.__code__ - if istraceback(object): - object = object.tb_frame - if isframe(object): - object = object.f_code - if iscode(object): - return object.co_filename - raise TypeError('module, class, method, function, traceback, frame, or ' - 'code object was expected, got {}'.format( - type(object).__name__)) - -def getmodulename(path): - """Return the module name for a given file, or None.""" - fname = os.path.basename(path) - # Check for paths that look like an actual module file - suffixes = [(-len(suffix), suffix) - for suffix in importlib.machinery.all_suffixes()] - suffixes.sort() # try longest suffixes first, in case they overlap - for neglen, suffix in suffixes: - if fname.endswith(suffix): - return fname[:neglen] - return None - -def getsourcefile(object): - """Return the filename that can be used to locate an object's source. - Return None if no way can be identified to get the source. - """ - filename = getfile(object) - all_bytecode_suffixes = importlib.machinery.DEBUG_BYTECODE_SUFFIXES[:] - all_bytecode_suffixes += importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES[:] - if any(filename.endswith(s) for s in all_bytecode_suffixes): - filename = (os.path.splitext(filename)[0] + - importlib.machinery.SOURCE_SUFFIXES[0]) - elif any(filename.endswith(s) for s in - importlib.machinery.EXTENSION_SUFFIXES): - return None - if os.path.exists(filename): - return filename - # only return a non-existent filename if the module has a PEP 302 loader - module = getmodule(object, filename) - if getattr(module, '__loader__', None) is not None: - return filename - elif getattr(getattr(module, "__spec__", None), "loader", None) is not None: - return filename - # or it is in the linecache - elif filename in linecache.cache: - return filename - -def getabsfile(object, _filename=None): - """Return an absolute path to the source or compiled file for an object. - - The idea is for each object to have a unique origin, so this routine - normalizes the result as much as possible.""" - if _filename is None: - _filename = getsourcefile(object) or getfile(object) - return os.path.normcase(os.path.abspath(_filename)) - -modulesbyfile = {} -_filesbymodname = {} - -def getmodule(object, _filename=None): - """Return the module an object was defined in, or None if not found.""" - if ismodule(object): - return object - if hasattr(object, '__module__'): - return sys.modules.get(object.__module__) - # Try the filename to modulename cache - if _filename is not None and _filename in modulesbyfile: - return sys.modules.get(modulesbyfile[_filename]) - # Try the cache again with the absolute file name - try: - file = getabsfile(object, _filename) - except (TypeError, FileNotFoundError): - return None - if file in modulesbyfile: - return sys.modules.get(modulesbyfile[file]) - # Update the filename to module name cache and check yet again - # Copy sys.modules in order to cope with changes while iterating - for modname, module in sys.modules.copy().items(): - if ismodule(module) and hasattr(module, '__file__'): - f = module.__file__ - if f == _filesbymodname.get(modname, None): - # Have already mapped this module, so skip it - continue - _filesbymodname[modname] = f - f = getabsfile(module) - # Always map to the name the module knows itself by - modulesbyfile[f] = modulesbyfile[ - os.path.realpath(f)] = module.__name__ - if file in modulesbyfile: - return sys.modules.get(modulesbyfile[file]) - # Check the main module - main = sys.modules['__main__'] - if not hasattr(object, '__name__'): - return None - if hasattr(main, object.__name__): - mainobject = getattr(main, object.__name__) - if mainobject is object: - return main - # Check builtins - builtin = sys.modules['builtins'] - if hasattr(builtin, object.__name__): - builtinobject = getattr(builtin, object.__name__) - if builtinobject is object: - return builtin - - -class ClassFoundException(Exception): - pass - - -class _ClassFinder(ast.NodeVisitor): - - def __init__(self, qualname): - self.stack = [] - self.qualname = qualname - - def visit_FunctionDef(self, node): - self.stack.append(node.name) - self.stack.append('') - self.generic_visit(node) - self.stack.pop() - self.stack.pop() - - visit_AsyncFunctionDef = visit_FunctionDef - - def visit_ClassDef(self, node): - self.stack.append(node.name) - if self.qualname == '.'.join(self.stack): - # Return the decorator for the class if present - if node.decorator_list: - line_number = node.decorator_list[0].lineno - else: - line_number = node.lineno - - # decrement by one since lines starts with indexing by zero - line_number -= 1 - raise ClassFoundException(line_number) - self.generic_visit(node) - self.stack.pop() - - -def findsource(object): - """Return the entire source file and starting line number for an object. - - The argument may be a module, class, method, function, traceback, frame, - or code object. The source code is returned as a list of all the lines - in the file and the line number indexes a line in that list. An OSError - is raised if the source code cannot be retrieved.""" - - file = getsourcefile(object) - if file: - # Invalidate cache if needed. - linecache.checkcache(file) - else: - file = getfile(object) - # Allow filenames in form of "" to pass through. - # `doctest` monkeypatches `linecache` module to enable - # inspection, so let `linecache.getlines` to be called. - if not (file.startswith('<') and file.endswith('>')): - raise OSError('source code not available') - - module = getmodule(object, file) - if module: - lines = linecache.getlines(file, module.__dict__) - else: - lines = linecache.getlines(file) - if not lines: - raise OSError('could not get source code') - - if ismodule(object): - return lines, 0 - - if isclass(object): - qualname = object.__qualname__ - source = ''.join(lines) - tree = ast.parse(source) - class_finder = _ClassFinder(qualname) - try: - class_finder.visit(tree) - except ClassFoundException as e: - line_number = e.args[0] - return lines, line_number - else: - raise OSError('could not find class definition') - - if ismethod(object): - object = object.__func__ - if isfunction(object): - object = object.__code__ - if istraceback(object): - object = object.tb_frame - if isframe(object): - object = object.f_code - if iscode(object): - if not hasattr(object, 'co_firstlineno'): - raise OSError('could not find function definition') - lnum = object.co_firstlineno - 1 - pat = re.compile(r'^(\s*def\s)|(\s*async\s+def\s)|(.*(? 0: - try: - line = lines[lnum] - except IndexError: - raise OSError('lineno is out of bounds') - if pat.match(line): - break - lnum = lnum - 1 - return lines, lnum - raise OSError('could not find code object') - -def getcomments(object): - """Get lines of comments immediately preceding an object's source code. - - Returns None when source can't be found. - """ - try: - lines, lnum = findsource(object) - except (OSError, TypeError): - return None - - if ismodule(object): - # Look for a comment block at the top of the file. - start = 0 - if lines and lines[0][:2] == '#!': start = 1 - while start < len(lines) and lines[start].strip() in ('', '#'): - start = start + 1 - if start < len(lines) and lines[start][:1] == '#': - comments = [] - end = start - while end < len(lines) and lines[end][:1] == '#': - comments.append(lines[end].expandtabs()) - end = end + 1 - return ''.join(comments) - - # Look for a preceding block of comments at the same indentation. - elif lnum > 0: - indent = indentsize(lines[lnum]) - end = lnum - 1 - if end >= 0 and lines[end].lstrip()[:1] == '#' and \ - indentsize(lines[end]) == indent: - comments = [lines[end].expandtabs().lstrip()] - if end > 0: - end = end - 1 - comment = lines[end].expandtabs().lstrip() - while comment[:1] == '#' and indentsize(lines[end]) == indent: - comments[:0] = [comment] - end = end - 1 - if end < 0: break - comment = lines[end].expandtabs().lstrip() - while comments and comments[0].strip() == '#': - comments[:1] = [] - while comments and comments[-1].strip() == '#': - comments[-1:] = [] - return ''.join(comments) - -class EndOfBlock(Exception): pass - -class BlockFinder: - """Provide a tokeneater() method to detect the end of a code block.""" - def __init__(self): - self.indent = 0 - self.islambda = False - self.started = False - self.passline = False - self.indecorator = False - self.decoratorhasargs = False - self.last = 1 - self.body_col0 = None - - def tokeneater(self, type, token, srowcol, erowcol, line): - if not self.started and not self.indecorator: - # skip any decorators - if token == "@": - self.indecorator = True - # look for the first "def", "class" or "lambda" - elif token in ("def", "class", "lambda"): - if token == "lambda": - self.islambda = True - self.started = True - self.passline = True # skip to the end of the line - elif token == "(": - if self.indecorator: - self.decoratorhasargs = True - elif token == ")": - if self.indecorator: - self.indecorator = False - self.decoratorhasargs = False - elif type == tokenize.NEWLINE: - self.passline = False # stop skipping when a NEWLINE is seen - self.last = srowcol[0] - if self.islambda: # lambdas always end at the first NEWLINE - raise EndOfBlock - # hitting a NEWLINE when in a decorator without args - # ends the decorator - if self.indecorator and not self.decoratorhasargs: - self.indecorator = False - elif self.passline: - pass - elif type == tokenize.INDENT: - if self.body_col0 is None and self.started: - self.body_col0 = erowcol[1] - self.indent = self.indent + 1 - self.passline = True - elif type == tokenize.DEDENT: - self.indent = self.indent - 1 - # the end of matching indent/dedent pairs end a block - # (note that this only works for "def"/"class" blocks, - # not e.g. for "if: else:" or "try: finally:" blocks) - if self.indent <= 0: - raise EndOfBlock - elif type == tokenize.COMMENT: - if self.body_col0 is not None and srowcol[1] >= self.body_col0: - # Include comments if indented at least as much as the block - self.last = srowcol[0] - elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL): - # any other token on the same indentation level end the previous - # block as well, except the pseudo-tokens COMMENT and NL. - raise EndOfBlock - -def getblock(lines): - """Extract the block of code at the top of the given list of lines.""" - blockfinder = BlockFinder() - try: - tokens = tokenize.generate_tokens(iter(lines).__next__) - for _token in tokens: - blockfinder.tokeneater(*_token) - except (EndOfBlock, IndentationError): - pass - return lines[:blockfinder.last] - -def getsourcelines(object): - """Return a list of source lines and starting line number for an object. - - The argument may be a module, class, method, function, traceback, frame, - or code object. The source code is returned as a list of the lines - corresponding to the object and the line number indicates where in the - original source file the first line of code was found. An OSError is - raised if the source code cannot be retrieved.""" - object = unwrap(object) - lines, lnum = findsource(object) - - if istraceback(object): - object = object.tb_frame - - # for module or frame that corresponds to module, return all source lines - if (ismodule(object) or - (isframe(object) and object.f_code.co_name == "")): - return lines, 0 - else: - return getblock(lines[lnum:]), lnum + 1 - -def getsource(object): - """Return the text of the source code for an object. - - The argument may be a module, class, method, function, traceback, frame, - or code object. The source code is returned as a single string. An - OSError is raised if the source code cannot be retrieved.""" - lines, lnum = getsourcelines(object) - return ''.join(lines) - -# --------------------------------------------------- class tree extraction -def walktree(classes, children, parent): - """Recursive helper function for getclasstree().""" - results = [] - classes.sort(key=attrgetter('__module__', '__name__')) - for c in classes: - results.append((c, c.__bases__)) - if c in children: - results.append(walktree(children[c], children, c)) - return results - -def getclasstree(classes, unique=False): - """Arrange the given list of classes into a hierarchy of nested lists. - - Where a nested list appears, it contains classes derived from the class - whose entry immediately precedes the list. Each entry is a 2-tuple - containing a class and a tuple of its base classes. If the 'unique' - argument is true, exactly one entry appears in the returned structure - for each class in the given list. Otherwise, classes using multiple - inheritance and their descendants will appear multiple times.""" - children = {} - roots = [] - for c in classes: - if c.__bases__: - for parent in c.__bases__: - if parent not in children: - children[parent] = [] - if c not in children[parent]: - children[parent].append(c) - if unique and parent in classes: break - elif c not in roots: - roots.append(c) - for parent in children: - if parent not in classes: - roots.append(parent) - return walktree(roots, children, None) - -# ------------------------------------------------ argument list extraction -Arguments = namedtuple('Arguments', 'args, varargs, varkw') - -def getargs(co): - """Get information about the arguments accepted by a code object. - - Three things are returned: (args, varargs, varkw), where - 'args' is the list of argument names. Keyword-only arguments are - appended. 'varargs' and 'varkw' are the names of the * and ** - arguments or None.""" - if not iscode(co): - raise TypeError('{!r} is not a code object'.format(co)) - - names = co.co_varnames - nargs = co.co_argcount - nkwargs = co.co_kwonlyargcount - args = list(names[:nargs]) - kwonlyargs = list(names[nargs:nargs+nkwargs]) - step = 0 - - nargs += nkwargs - varargs = None - if co.co_flags & CO_VARARGS: - varargs = co.co_varnames[nargs] - nargs = nargs + 1 - varkw = None - if co.co_flags & CO_VARKEYWORDS: - varkw = co.co_varnames[nargs] - return Arguments(args + kwonlyargs, varargs, varkw) - - -FullArgSpec = namedtuple('FullArgSpec', - 'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations') - -def getfullargspec(func): - """Get the names and default values of a callable object's parameters. - - A tuple of seven things is returned: - (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations). - 'args' is a list of the parameter names. - 'varargs' and 'varkw' are the names of the * and ** parameters or None. - 'defaults' is an n-tuple of the default values of the last n parameters. - 'kwonlyargs' is a list of keyword-only parameter names. - 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults. - 'annotations' is a dictionary mapping parameter names to annotations. - - Notable differences from inspect.signature(): - - the "self" parameter is always reported, even for bound methods - - wrapper chains defined by __wrapped__ *not* unwrapped automatically - """ - try: - # Re: `skip_bound_arg=False` - # - # There is a notable difference in behaviour between getfullargspec - # and Signature: the former always returns 'self' parameter for bound - # methods, whereas the Signature always shows the actual calling - # signature of the passed object. - # - # To simulate this behaviour, we "unbind" bound methods, to trick - # inspect.signature to always return their first parameter ("self", - # usually) - - # Re: `follow_wrapper_chains=False` - # - # getfullargspec() historically ignored __wrapped__ attributes, - # so we ensure that remains the case in 3.3+ - - sig = _signature_from_callable(func, - follow_wrapper_chains=False, - skip_bound_arg=False, - sigcls=Signature, - eval_str=False) - except Exception as ex: - # Most of the times 'signature' will raise ValueError. - # But, it can also raise AttributeError, and, maybe something - # else. So to be fully backwards compatible, we catch all - # possible exceptions here, and reraise a TypeError. - raise TypeError('unsupported callable') from ex - - args = [] - varargs = None - varkw = None - posonlyargs = [] - kwonlyargs = [] - annotations = {} - defaults = () - kwdefaults = {} - - if sig.return_annotation is not sig.empty: - annotations['return'] = sig.return_annotation - - for param in sig.parameters.values(): - kind = param.kind - name = param.name - - if kind is _POSITIONAL_ONLY: - posonlyargs.append(name) - if param.default is not param.empty: - defaults += (param.default,) - elif kind is _POSITIONAL_OR_KEYWORD: - args.append(name) - if param.default is not param.empty: - defaults += (param.default,) - elif kind is _VAR_POSITIONAL: - varargs = name - elif kind is _KEYWORD_ONLY: - kwonlyargs.append(name) - if param.default is not param.empty: - kwdefaults[name] = param.default - elif kind is _VAR_KEYWORD: - varkw = name - - if param.annotation is not param.empty: - annotations[name] = param.annotation - - if not kwdefaults: - # compatibility with 'func.__kwdefaults__' - kwdefaults = None - - if not defaults: - # compatibility with 'func.__defaults__' - defaults = None - - return FullArgSpec(posonlyargs + args, varargs, varkw, defaults, - kwonlyargs, kwdefaults, annotations) - - -ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals') - -def getargvalues(frame): - """Get information about arguments passed into a particular frame. - - A tuple of four things is returned: (args, varargs, varkw, locals). - 'args' is a list of the argument names. - 'varargs' and 'varkw' are the names of the * and ** arguments or None. - 'locals' is the locals dictionary of the given frame.""" - args, varargs, varkw = getargs(frame.f_code) - return ArgInfo(args, varargs, varkw, frame.f_locals) - -def formatannotation(annotation, base_module=None): - if getattr(annotation, '__module__', None) == 'typing': - def repl(match): - text = match.group() - return text.removeprefix('typing.') - return re.sub(r'[\w\.]+', repl, repr(annotation)) - if isinstance(annotation, types.GenericAlias): - return str(annotation) - if isinstance(annotation, type): - if annotation.__module__ in ('builtins', base_module): - return annotation.__qualname__ - return annotation.__module__+'.'+annotation.__qualname__ - return repr(annotation) - -def formatannotationrelativeto(object): - module = getattr(object, '__module__', None) - def _formatannotation(annotation): - return formatannotation(annotation, module) - return _formatannotation - - -def formatargvalues(args, varargs, varkw, locals, - formatarg=str, - formatvarargs=lambda name: '*' + name, - formatvarkw=lambda name: '**' + name, - formatvalue=lambda value: '=' + repr(value)): - """Format an argument spec from the 4 values returned by getargvalues. - - The first four arguments are (args, varargs, varkw, locals). The - next four arguments are the corresponding optional formatting functions - that are called to turn names and values into strings. The ninth - argument is an optional function to format the sequence of arguments.""" - def convert(name, locals=locals, - formatarg=formatarg, formatvalue=formatvalue): - return formatarg(name) + formatvalue(locals[name]) - specs = [] - for i in range(len(args)): - specs.append(convert(args[i])) - if varargs: - specs.append(formatvarargs(varargs) + formatvalue(locals[varargs])) - if varkw: - specs.append(formatvarkw(varkw) + formatvalue(locals[varkw])) - return '(' + ', '.join(specs) + ')' - -def _missing_arguments(f_name, argnames, pos, values): - names = [repr(name) for name in argnames if name not in values] - missing = len(names) - if missing == 1: - s = names[0] - elif missing == 2: - s = "{} and {}".format(*names) - else: - tail = ", {} and {}".format(*names[-2:]) - del names[-2:] - s = ", ".join(names) + tail - raise TypeError("%s() missing %i required %s argument%s: %s" % - (f_name, missing, - "positional" if pos else "keyword-only", - "" if missing == 1 else "s", s)) - -def _too_many(f_name, args, kwonly, varargs, defcount, given, values): - atleast = len(args) - defcount - kwonly_given = len([arg for arg in kwonly if arg in values]) - if varargs: - plural = atleast != 1 - sig = "at least %d" % (atleast,) - elif defcount: - plural = True - sig = "from %d to %d" % (atleast, len(args)) - else: - plural = len(args) != 1 - sig = str(len(args)) - kwonly_sig = "" - if kwonly_given: - msg = " positional argument%s (and %d keyword-only argument%s)" - kwonly_sig = (msg % ("s" if given != 1 else "", kwonly_given, - "s" if kwonly_given != 1 else "")) - raise TypeError("%s() takes %s positional argument%s but %d%s %s given" % - (f_name, sig, "s" if plural else "", given, kwonly_sig, - "was" if given == 1 and not kwonly_given else "were")) - -def getcallargs(func, /, *positional, **named): - """Get the mapping of arguments to values. - - A dict is returned, with keys the function argument names (including the - names of the * and ** arguments, if any), and values the respective bound - values from 'positional' and 'named'.""" - spec = getfullargspec(func) - args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec - f_name = func.__name__ - arg2value = {} - - - if ismethod(func) and func.__self__ is not None: - # implicit 'self' (or 'cls' for classmethods) argument - positional = (func.__self__,) + positional - num_pos = len(positional) - num_args = len(args) - num_defaults = len(defaults) if defaults else 0 - - n = min(num_pos, num_args) - for i in range(n): - arg2value[args[i]] = positional[i] - if varargs: - arg2value[varargs] = tuple(positional[n:]) - possible_kwargs = set(args + kwonlyargs) - if varkw: - arg2value[varkw] = {} - for kw, value in named.items(): - if kw not in possible_kwargs: - if not varkw: - raise TypeError("%s() got an unexpected keyword argument %r" % - (f_name, kw)) - arg2value[varkw][kw] = value - continue - if kw in arg2value: - raise TypeError("%s() got multiple values for argument %r" % - (f_name, kw)) - arg2value[kw] = value - if num_pos > num_args and not varargs: - _too_many(f_name, args, kwonlyargs, varargs, num_defaults, - num_pos, arg2value) - if num_pos < num_args: - req = args[:num_args - num_defaults] - for arg in req: - if arg not in arg2value: - _missing_arguments(f_name, req, True, arg2value) - for i, arg in enumerate(args[num_args - num_defaults:]): - if arg not in arg2value: - arg2value[arg] = defaults[i] - missing = 0 - for kwarg in kwonlyargs: - if kwarg not in arg2value: - if kwonlydefaults and kwarg in kwonlydefaults: - arg2value[kwarg] = kwonlydefaults[kwarg] - else: - missing += 1 - if missing: - _missing_arguments(f_name, kwonlyargs, False, arg2value) - return arg2value - -ClosureVars = namedtuple('ClosureVars', 'nonlocals globals builtins unbound') - -def getclosurevars(func): - """ - Get the mapping of free variables to their current values. - - Returns a named tuple of dicts mapping the current nonlocal, global - and builtin references as seen by the body of the function. A final - set of unbound names that could not be resolved is also provided. - """ - - if ismethod(func): - func = func.__func__ - - if not isfunction(func): - raise TypeError("{!r} is not a Python function".format(func)) - - code = func.__code__ - # Nonlocal references are named in co_freevars and resolved - # by looking them up in __closure__ by positional index - if func.__closure__ is None: - nonlocal_vars = {} - else: - nonlocal_vars = { - var : cell.cell_contents - for var, cell in zip(code.co_freevars, func.__closure__) - } - - # Global and builtin references are named in co_names and resolved - # by looking them up in __globals__ or __builtins__ - global_ns = func.__globals__ - builtin_ns = global_ns.get("__builtins__", builtins.__dict__) - if ismodule(builtin_ns): - builtin_ns = builtin_ns.__dict__ - global_vars = {} - builtin_vars = {} - unbound_names = set() - for name in code.co_names: - if name in ("None", "True", "False"): - # Because these used to be builtins instead of keywords, they - # may still show up as name references. We ignore them. - continue - try: - global_vars[name] = global_ns[name] - except KeyError: - try: - builtin_vars[name] = builtin_ns[name] - except KeyError: - unbound_names.add(name) - - return ClosureVars(nonlocal_vars, global_vars, - builtin_vars, unbound_names) - -# -------------------------------------------------- stack frame extraction - -_Traceback = namedtuple('_Traceback', 'filename lineno function code_context index') - -class Traceback(_Traceback): - def __new__(cls, filename, lineno, function, code_context, index, *, positions=None): - instance = super().__new__(cls, filename, lineno, function, code_context, index) - instance.positions = positions - return instance - - def __repr__(self): - return ('Traceback(filename={!r}, lineno={!r}, function={!r}, ' - 'code_context={!r}, index={!r}, positions={!r})'.format( - self.filename, self.lineno, self.function, self.code_context, - self.index, self.positions)) - -def _get_code_position_from_tb(tb): - code, instruction_index = tb.tb_frame.f_code, tb.tb_lasti - return _get_code_position(code, instruction_index) - -def _get_code_position(code, instruction_index): - if instruction_index < 0: - return (None, None, None, None) - positions_gen = code.co_positions() - # The nth entry in code.co_positions() corresponds to instruction (2*n)th since Python 3.10+ - return next(itertools.islice(positions_gen, instruction_index // 2, None)) - -def getframeinfo(frame, context=1): - """Get information about a frame or traceback object. - - A tuple of five things is returned: the filename, the line number of - the current line, the function name, a list of lines of context from - the source code, and the index of the current line within that list. - The optional second argument specifies the number of lines of context - to return, which are centered around the current line.""" - if istraceback(frame): - positions = _get_code_position_from_tb(frame) - lineno = frame.tb_lineno - frame = frame.tb_frame - else: - lineno = frame.f_lineno - positions = _get_code_position(frame.f_code, frame.f_lasti) - - if positions[0] is None: - frame, *positions = (frame, lineno, *positions[1:]) - else: - frame, *positions = (frame, *positions) - - lineno = positions[0] - - if not isframe(frame): - raise TypeError('{!r} is not a frame or traceback object'.format(frame)) - - filename = getsourcefile(frame) or getfile(frame) - if context > 0: - start = lineno - 1 - context//2 - try: - lines, lnum = findsource(frame) - except OSError: - lines = index = None - else: - start = max(0, min(start, len(lines) - context)) - lines = lines[start:start+context] - index = lineno - 1 - start - else: - lines = index = None - - return Traceback(filename, lineno, frame.f_code.co_name, lines, - index, positions=dis.Positions(*positions)) - -def getlineno(frame): - """Get the line number from a frame object, allowing for optimization.""" - # FrameType.f_lineno is now a descriptor that grovels co_lnotab - return frame.f_lineno - -_FrameInfo = namedtuple('_FrameInfo', ('frame',) + Traceback._fields) -class FrameInfo(_FrameInfo): - def __new__(cls, frame, filename, lineno, function, code_context, index, *, positions=None): - instance = super().__new__(cls, frame, filename, lineno, function, code_context, index) - instance.positions = positions - return instance - - def __repr__(self): - return ('FrameInfo(frame={!r}, filename={!r}, lineno={!r}, function={!r}, ' - 'code_context={!r}, index={!r}, positions={!r})'.format( - self.frame, self.filename, self.lineno, self.function, - self.code_context, self.index, self.positions)) - -def getouterframes(frame, context=1): - """Get a list of records for a frame and all higher (calling) frames. - - Each record contains a frame object, filename, line number, function - name, a list of lines of context, and index within the context.""" - framelist = [] - while frame: - traceback_info = getframeinfo(frame, context) - frameinfo = (frame,) + traceback_info - framelist.append(FrameInfo(*frameinfo, positions=traceback_info.positions)) - frame = frame.f_back - return framelist - -def getinnerframes(tb, context=1): - """Get a list of records for a traceback's frame and all lower frames. - - Each record contains a frame object, filename, line number, function - name, a list of lines of context, and index within the context.""" - framelist = [] - while tb: - traceback_info = getframeinfo(tb, context) - frameinfo = (tb.tb_frame,) + traceback_info - framelist.append(FrameInfo(*frameinfo, positions=traceback_info.positions)) - tb = tb.tb_next - return framelist - -def currentframe(): - """Return the frame of the caller or None if this is not possible.""" - return sys._getframe(1) if hasattr(sys, "_getframe") else None - -def stack(context=1): - """Return a list of records for the stack above the caller's frame.""" - return getouterframes(sys._getframe(1), context) - -def trace(context=1): - """Return a list of records for the stack below the current exception.""" - return getinnerframes(sys.exc_info()[2], context) - - -# ------------------------------------------------ static version of getattr - -_sentinel = object() - -def _static_getmro(klass): - return type.__dict__['__mro__'].__get__(klass) - -def _check_instance(obj, attr): - instance_dict = {} - try: - instance_dict = object.__getattribute__(obj, "__dict__") - except AttributeError: - pass - return dict.get(instance_dict, attr, _sentinel) - - -def _check_class(klass, attr): - for entry in _static_getmro(klass): - if _shadowed_dict(type(entry)) is _sentinel: - try: - return entry.__dict__[attr] - except KeyError: - pass - return _sentinel - -def _is_type(obj): - try: - _static_getmro(obj) - except TypeError: - return False - return True - -def _shadowed_dict(klass): - dict_attr = type.__dict__["__dict__"] - for entry in _static_getmro(klass): - try: - class_dict = dict_attr.__get__(entry)["__dict__"] - except KeyError: - pass - else: - if not (type(class_dict) is types.GetSetDescriptorType and - class_dict.__name__ == "__dict__" and - class_dict.__objclass__ is entry): - return class_dict - return _sentinel - -def getattr_static(obj, attr, default=_sentinel): - """Retrieve attributes without triggering dynamic lookup via the - descriptor protocol, __getattr__ or __getattribute__. - - Note: this function may not be able to retrieve all attributes - that getattr can fetch (like dynamically created attributes) - and may find attributes that getattr can't (like descriptors - that raise AttributeError). It can also return descriptor objects - instead of instance members in some cases. See the - documentation for details. - """ - instance_result = _sentinel - if not _is_type(obj): - klass = type(obj) - dict_attr = _shadowed_dict(klass) - if (dict_attr is _sentinel or - type(dict_attr) is types.MemberDescriptorType): - instance_result = _check_instance(obj, attr) - else: - klass = obj - - klass_result = _check_class(klass, attr) - - if instance_result is not _sentinel and klass_result is not _sentinel: - if (_check_class(type(klass_result), '__get__') is not _sentinel and - _check_class(type(klass_result), '__set__') is not _sentinel): - return klass_result - - if instance_result is not _sentinel: - return instance_result - if klass_result is not _sentinel: - return klass_result - - if obj is klass: - # for types we check the metaclass too - for entry in _static_getmro(type(klass)): - if _shadowed_dict(type(entry)) is _sentinel: - try: - return entry.__dict__[attr] - except KeyError: - pass - if default is not _sentinel: - return default - raise AttributeError(attr) - - -# ------------------------------------------------ generator introspection - -GEN_CREATED = 'GEN_CREATED' -GEN_RUNNING = 'GEN_RUNNING' -GEN_SUSPENDED = 'GEN_SUSPENDED' -GEN_CLOSED = 'GEN_CLOSED' - -def getgeneratorstate(generator): - """Get current state of a generator-iterator. - - Possible states are: - GEN_CREATED: Waiting to start execution. - GEN_RUNNING: Currently being executed by the interpreter. - GEN_SUSPENDED: Currently suspended at a yield expression. - GEN_CLOSED: Execution has completed. - """ - if generator.gi_running: - return GEN_RUNNING - if generator.gi_suspended: - return GEN_SUSPENDED - if generator.gi_frame is None: - return GEN_CLOSED - return GEN_CREATED - - -def getgeneratorlocals(generator): - """ - Get the mapping of generator local variables to their current values. - - A dict is returned, with the keys the local variable names and values the - bound values.""" - - if not isgenerator(generator): - raise TypeError("{!r} is not a Python generator".format(generator)) - - frame = getattr(generator, "gi_frame", None) - if frame is not None: - return generator.gi_frame.f_locals - else: - return {} - - -# ------------------------------------------------ coroutine introspection - -CORO_CREATED = 'CORO_CREATED' -CORO_RUNNING = 'CORO_RUNNING' -CORO_SUSPENDED = 'CORO_SUSPENDED' -CORO_CLOSED = 'CORO_CLOSED' - -def getcoroutinestate(coroutine): - """Get current state of a coroutine object. - - Possible states are: - CORO_CREATED: Waiting to start execution. - CORO_RUNNING: Currently being executed by the interpreter. - CORO_SUSPENDED: Currently suspended at an await expression. - CORO_CLOSED: Execution has completed. - """ - if coroutine.cr_running: - return CORO_RUNNING - if coroutine.cr_suspended: - return CORO_SUSPENDED - if coroutine.cr_frame is None: - return CORO_CLOSED - return CORO_CREATED - - -def getcoroutinelocals(coroutine): - """ - Get the mapping of coroutine local variables to their current values. - - A dict is returned, with the keys the local variable names and values the - bound values.""" - frame = getattr(coroutine, "cr_frame", None) - if frame is not None: - return frame.f_locals - else: - return {} - - -############################################################################### -### Function Signature Object (PEP 362) -############################################################################### - - -_NonUserDefinedCallables = (types.WrapperDescriptorType, - types.MethodWrapperType, - types.ClassMethodDescriptorType, - types.BuiltinFunctionType) - - -def _signature_get_user_defined_method(cls, method_name): - """Private helper. Checks if ``cls`` has an attribute - named ``method_name`` and returns it only if it is a - pure python function. - """ - try: - meth = getattr(cls, method_name) - except AttributeError: - return - else: - if not isinstance(meth, _NonUserDefinedCallables): - # Once '__signature__' will be added to 'C'-level - # callables, this check won't be necessary - return meth - - -def _signature_get_partial(wrapped_sig, partial, extra_args=()): - """Private helper to calculate how 'wrapped_sig' signature will - look like after applying a 'functools.partial' object (or alike) - on it. - """ - - old_params = wrapped_sig.parameters - new_params = OrderedDict(old_params.items()) - - partial_args = partial.args or () - partial_keywords = partial.keywords or {} - - if extra_args: - partial_args = extra_args + partial_args - - try: - ba = wrapped_sig.bind_partial(*partial_args, **partial_keywords) - except TypeError as ex: - msg = 'partial object {!r} has incorrect arguments'.format(partial) - raise ValueError(msg) from ex - - - transform_to_kwonly = False - for param_name, param in old_params.items(): - try: - arg_value = ba.arguments[param_name] - except KeyError: - pass - else: - if param.kind is _POSITIONAL_ONLY: - # If positional-only parameter is bound by partial, - # it effectively disappears from the signature - new_params.pop(param_name) - continue - - if param.kind is _POSITIONAL_OR_KEYWORD: - if param_name in partial_keywords: - # This means that this parameter, and all parameters - # after it should be keyword-only (and var-positional - # should be removed). Here's why. Consider the following - # function: - # foo(a, b, *args, c): - # pass - # - # "partial(foo, a='spam')" will have the following - # signature: "(*, a='spam', b, c)". Because attempting - # to call that partial with "(10, 20)" arguments will - # raise a TypeError, saying that "a" argument received - # multiple values. - transform_to_kwonly = True - # Set the new default value - new_params[param_name] = param.replace(default=arg_value) - else: - # was passed as a positional argument - new_params.pop(param.name) - continue - - if param.kind is _KEYWORD_ONLY: - # Set the new default value - new_params[param_name] = param.replace(default=arg_value) - - if transform_to_kwonly: - assert param.kind is not _POSITIONAL_ONLY - - if param.kind is _POSITIONAL_OR_KEYWORD: - new_param = new_params[param_name].replace(kind=_KEYWORD_ONLY) - new_params[param_name] = new_param - new_params.move_to_end(param_name) - elif param.kind in (_KEYWORD_ONLY, _VAR_KEYWORD): - new_params.move_to_end(param_name) - elif param.kind is _VAR_POSITIONAL: - new_params.pop(param.name) - - return wrapped_sig.replace(parameters=new_params.values()) - - -def _signature_bound_method(sig): - """Private helper to transform signatures for unbound - functions to bound methods. - """ - - params = tuple(sig.parameters.values()) - - if not params or params[0].kind in (_VAR_KEYWORD, _KEYWORD_ONLY): - raise ValueError('invalid method signature') - - kind = params[0].kind - if kind in (_POSITIONAL_OR_KEYWORD, _POSITIONAL_ONLY): - # Drop first parameter: - # '(p1, p2[, ...])' -> '(p2[, ...])' - params = params[1:] - else: - if kind is not _VAR_POSITIONAL: - # Unless we add a new parameter type we never - # get here - raise ValueError('invalid argument type') - # It's a var-positional parameter. - # Do nothing. '(*args[, ...])' -> '(*args[, ...])' - - return sig.replace(parameters=params) - - -def _signature_is_builtin(obj): - """Private helper to test if `obj` is a callable that might - support Argument Clinic's __text_signature__ protocol. - """ - return (isbuiltin(obj) or - ismethoddescriptor(obj) or - isinstance(obj, _NonUserDefinedCallables) or - # Can't test 'isinstance(type)' here, as it would - # also be True for regular python classes - obj in (type, object)) - - -def _signature_is_functionlike(obj): - """Private helper to test if `obj` is a duck type of FunctionType. - A good example of such objects are functions compiled with - Cython, which have all attributes that a pure Python function - would have, but have their code statically compiled. - """ - - if not callable(obj) or isclass(obj): - # All function-like objects are obviously callables, - # and not classes. - return False - - name = getattr(obj, '__name__', None) - code = getattr(obj, '__code__', None) - defaults = getattr(obj, '__defaults__', _void) # Important to use _void ... - kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here - annotations = getattr(obj, '__annotations__', None) - - return (isinstance(code, types.CodeType) and - isinstance(name, str) and - (defaults is None or isinstance(defaults, tuple)) and - (kwdefaults is None or isinstance(kwdefaults, dict)) and - (isinstance(annotations, (dict)) or annotations is None) ) - - -def _signature_strip_non_python_syntax(signature): - """ - Private helper function. Takes a signature in Argument Clinic's - extended signature format. - - Returns a tuple of three things: - * that signature re-rendered in standard Python syntax, - * the index of the "self" parameter (generally 0), or None if - the function does not have a "self" parameter, and - * the index of the last "positional only" parameter, - or None if the signature has no positional-only parameters. - """ - - if not signature: - return signature, None, None - - self_parameter = None - last_positional_only = None - - lines = [l.encode('ascii') for l in signature.split('\n')] - generator = iter(lines).__next__ - token_stream = tokenize.tokenize(generator) - - delayed_comma = False - skip_next_comma = False - text = [] - add = text.append - - current_parameter = 0 - OP = token.OP - ERRORTOKEN = token.ERRORTOKEN - - # token stream always starts with ENCODING token, skip it - t = next(token_stream) - assert t.type == tokenize.ENCODING - - for t in token_stream: - type, string = t.type, t.string - - if type == OP: - if string == ',': - if skip_next_comma: - skip_next_comma = False - else: - assert not delayed_comma - delayed_comma = True - current_parameter += 1 - continue - - if string == '/': - assert not skip_next_comma - assert last_positional_only is None - skip_next_comma = True - last_positional_only = current_parameter - 1 - continue - - if (type == ERRORTOKEN) and (string == '$'): - assert self_parameter is None - self_parameter = current_parameter - continue - - if delayed_comma: - delayed_comma = False - if not ((type == OP) and (string == ')')): - add(', ') - add(string) - if (string == ','): - add(' ') - clean_signature = ''.join(text) - return clean_signature, self_parameter, last_positional_only - - -def _signature_fromstr(cls, obj, s, skip_bound_arg=True): - """Private helper to parse content of '__text_signature__' - and return a Signature based on it. - """ - Parameter = cls._parameter_cls - - clean_signature, self_parameter, last_positional_only = \ - _signature_strip_non_python_syntax(s) - - program = "def foo" + clean_signature + ": pass" - - try: - module = ast.parse(program) - except SyntaxError: - module = None - - if not isinstance(module, ast.Module): - raise ValueError("{!r} builtin has invalid signature".format(obj)) - - f = module.body[0] - - parameters = [] - empty = Parameter.empty - invalid = object() - - module = None - module_dict = {} - module_name = getattr(obj, '__module__', None) - if module_name: - module = sys.modules.get(module_name, None) - if module: - module_dict = module.__dict__ - sys_module_dict = sys.modules.copy() - - def parse_name(node): - assert isinstance(node, ast.arg) - if node.annotation is not None: - raise ValueError("Annotations are not currently supported") - return node.arg - - def wrap_value(s): - try: - value = eval(s, module_dict) - except NameError: - try: - value = eval(s, sys_module_dict) - except NameError: - raise RuntimeError() - - if isinstance(value, (str, int, float, bytes, bool, type(None))): - return ast.Constant(value) - raise RuntimeError() - - class RewriteSymbolics(ast.NodeTransformer): - def visit_Attribute(self, node): - a = [] - n = node - while isinstance(n, ast.Attribute): - a.append(n.attr) - n = n.value - if not isinstance(n, ast.Name): - raise RuntimeError() - a.append(n.id) - value = ".".join(reversed(a)) - return wrap_value(value) - - def visit_Name(self, node): - if not isinstance(node.ctx, ast.Load): - raise ValueError() - return wrap_value(node.id) - - def p(name_node, default_node, default=empty): - name = parse_name(name_node) - if name is invalid: - return None - if default_node and default_node is not _empty: - try: - default_node = RewriteSymbolics().visit(default_node) - o = ast.literal_eval(default_node) - except ValueError: - o = invalid - if o is invalid: - return None - default = o if o is not invalid else default - parameters.append(Parameter(name, kind, default=default, annotation=empty)) - - # non-keyword-only parameters - args = reversed(f.args.args) - defaults = reversed(f.args.defaults) - iter = itertools.zip_longest(args, defaults, fillvalue=None) - if last_positional_only is not None: - kind = Parameter.POSITIONAL_ONLY - else: - kind = Parameter.POSITIONAL_OR_KEYWORD - for i, (name, default) in enumerate(reversed(list(iter))): - p(name, default) - if i == last_positional_only: - kind = Parameter.POSITIONAL_OR_KEYWORD - - # *args - if f.args.vararg: - kind = Parameter.VAR_POSITIONAL - p(f.args.vararg, empty) - - # keyword-only arguments - kind = Parameter.KEYWORD_ONLY - for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults): - p(name, default) - - # **kwargs - if f.args.kwarg: - kind = Parameter.VAR_KEYWORD - p(f.args.kwarg, empty) - - if self_parameter is not None: - # Possibly strip the bound argument: - # - We *always* strip first bound argument if - # it is a module. - # - We don't strip first bound argument if - # skip_bound_arg is False. - assert parameters - _self = getattr(obj, '__self__', None) - self_isbound = _self is not None - self_ismodule = ismodule(_self) - if self_isbound and (self_ismodule or skip_bound_arg): - parameters.pop(0) - else: - # for builtins, self parameter is always positional-only! - p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY) - parameters[0] = p - - return cls(parameters, return_annotation=cls.empty) - - -def _signature_from_builtin(cls, func, skip_bound_arg=True): - """Private helper function to get signature for - builtin callables. - """ - - if not _signature_is_builtin(func): - raise TypeError("{!r} is not a Python builtin " - "function".format(func)) - - s = getattr(func, "__text_signature__", None) - if not s: - raise ValueError("no signature found for builtin {!r}".format(func)) - - return _signature_fromstr(cls, func, s, skip_bound_arg) - - -def _signature_from_function(cls, func, skip_bound_arg=True, - globals=None, locals=None, eval_str=False): - """Private helper: constructs Signature for the given python function.""" - - is_duck_function = False - if not isfunction(func): - if _signature_is_functionlike(func): - is_duck_function = True - else: - # If it's not a pure Python function, and not a duck type - # of pure function: - raise TypeError('{!r} is not a Python function'.format(func)) - - s = getattr(func, "__text_signature__", None) - if s: - return _signature_fromstr(cls, func, s, skip_bound_arg) - - Parameter = cls._parameter_cls - - # Parameter information. - func_code = func.__code__ - pos_count = func_code.co_argcount - arg_names = func_code.co_varnames - posonly_count = func_code.co_posonlyargcount - positional = arg_names[:pos_count] - keyword_only_count = func_code.co_kwonlyargcount - keyword_only = arg_names[pos_count:pos_count + keyword_only_count] - annotations = get_annotations(func, globals=globals, locals=locals, eval_str=eval_str) - defaults = func.__defaults__ - kwdefaults = func.__kwdefaults__ - - if defaults: - pos_default_count = len(defaults) - else: - pos_default_count = 0 - - parameters = [] - - non_default_count = pos_count - pos_default_count - posonly_left = posonly_count - - # Non-keyword-only parameters w/o defaults. - for name in positional[:non_default_count]: - kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD - annotation = annotations.get(name, _empty) - parameters.append(Parameter(name, annotation=annotation, - kind=kind)) - if posonly_left: - posonly_left -= 1 - - # ... w/ defaults. - for offset, name in enumerate(positional[non_default_count:]): - kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD - annotation = annotations.get(name, _empty) - parameters.append(Parameter(name, annotation=annotation, - kind=kind, - default=defaults[offset])) - if posonly_left: - posonly_left -= 1 - - # *args - if func_code.co_flags & CO_VARARGS: - name = arg_names[pos_count + keyword_only_count] - annotation = annotations.get(name, _empty) - parameters.append(Parameter(name, annotation=annotation, - kind=_VAR_POSITIONAL)) - - # Keyword-only parameters. - for name in keyword_only: - default = _empty - if kwdefaults is not None: - default = kwdefaults.get(name, _empty) - - annotation = annotations.get(name, _empty) - parameters.append(Parameter(name, annotation=annotation, - kind=_KEYWORD_ONLY, - default=default)) - # **kwargs - if func_code.co_flags & CO_VARKEYWORDS: - index = pos_count + keyword_only_count - if func_code.co_flags & CO_VARARGS: - index += 1 - - name = arg_names[index] - annotation = annotations.get(name, _empty) - parameters.append(Parameter(name, annotation=annotation, - kind=_VAR_KEYWORD)) - - # Is 'func' is a pure Python function - don't validate the - # parameters list (for correct order and defaults), it should be OK. - return cls(parameters, - return_annotation=annotations.get('return', _empty), - __validate_parameters__=is_duck_function) - - -def _signature_from_callable(obj, *, - follow_wrapper_chains=True, - skip_bound_arg=True, - globals=None, - locals=None, - eval_str=False, - sigcls): - - """Private helper function to get signature for arbitrary - callable objects. - """ - - _get_signature_of = functools.partial(_signature_from_callable, - follow_wrapper_chains=follow_wrapper_chains, - skip_bound_arg=skip_bound_arg, - globals=globals, - locals=locals, - sigcls=sigcls, - eval_str=eval_str) - - if not callable(obj): - raise TypeError('{!r} is not a callable object'.format(obj)) - - if isinstance(obj, types.MethodType): - # In this case we skip the first parameter of the underlying - # function (usually `self` or `cls`). - sig = _get_signature_of(obj.__func__) - - if skip_bound_arg: - return _signature_bound_method(sig) - else: - return sig - - # Was this function wrapped by a decorator? - if follow_wrapper_chains: - # Unwrap until we find an explicit signature or a MethodType (which will be - # handled explicitly below). - obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__") - or isinstance(f, types.MethodType))) - if isinstance(obj, types.MethodType): - # If the unwrapped object is a *method*, we might want to - # skip its first parameter (self). - # See test_signature_wrapped_bound_method for details. - return _get_signature_of(obj) - - try: - sig = obj.__signature__ - except AttributeError: - pass - else: - if sig is not None: - if not isinstance(sig, Signature): - raise TypeError( - 'unexpected object {!r} in __signature__ ' - 'attribute'.format(sig)) - return sig - - try: - partialmethod = obj._partialmethod - except AttributeError: - pass - else: - if isinstance(partialmethod, functools.partialmethod): - # Unbound partialmethod (see functools.partialmethod) - # This means, that we need to calculate the signature - # as if it's a regular partial object, but taking into - # account that the first positional argument - # (usually `self`, or `cls`) will not be passed - # automatically (as for boundmethods) - - wrapped_sig = _get_signature_of(partialmethod.func) - - sig = _signature_get_partial(wrapped_sig, partialmethod, (None,)) - first_wrapped_param = tuple(wrapped_sig.parameters.values())[0] - if first_wrapped_param.kind is Parameter.VAR_POSITIONAL: - # First argument of the wrapped callable is `*args`, as in - # `partialmethod(lambda *args)`. - return sig - else: - sig_params = tuple(sig.parameters.values()) - assert (not sig_params or - first_wrapped_param is not sig_params[0]) - new_params = (first_wrapped_param,) + sig_params - return sig.replace(parameters=new_params) - - if isfunction(obj) or _signature_is_functionlike(obj): - # If it's a pure Python function, or an object that is duck type - # of a Python function (Cython functions, for instance), then: - return _signature_from_function(sigcls, obj, - skip_bound_arg=skip_bound_arg, - globals=globals, locals=locals, eval_str=eval_str) - - if _signature_is_builtin(obj): - return _signature_from_builtin(sigcls, obj, - skip_bound_arg=skip_bound_arg) - - if isinstance(obj, functools.partial): - wrapped_sig = _get_signature_of(obj.func) - return _signature_get_partial(wrapped_sig, obj) - - sig = None - if isinstance(obj, type): - # obj is a class or a metaclass - - # First, let's see if it has an overloaded __call__ defined - # in its metaclass - call = _signature_get_user_defined_method(type(obj), '__call__') - if call is not None: - sig = _get_signature_of(call) - else: - factory_method = None - new = _signature_get_user_defined_method(obj, '__new__') - init = _signature_get_user_defined_method(obj, '__init__') - # Now we check if the 'obj' class has an own '__new__' method - if '__new__' in obj.__dict__: - factory_method = new - # or an own '__init__' method - elif '__init__' in obj.__dict__: - factory_method = init - # If not, we take inherited '__new__' or '__init__', if present - elif new is not None: - factory_method = new - elif init is not None: - factory_method = init - - if factory_method is not None: - sig = _get_signature_of(factory_method) - - if sig is None: - # At this point we know, that `obj` is a class, with no user- - # defined '__init__', '__new__', or class-level '__call__' - - for base in obj.__mro__[:-1]: - # Since '__text_signature__' is implemented as a - # descriptor that extracts text signature from the - # class docstring, if 'obj' is derived from a builtin - # class, its own '__text_signature__' may be 'None'. - # Therefore, we go through the MRO (except the last - # class in there, which is 'object') to find the first - # class with non-empty text signature. - try: - text_sig = base.__text_signature__ - except AttributeError: - pass - else: - if text_sig: - # If 'base' class has a __text_signature__ attribute: - # return a signature based on it - return _signature_fromstr(sigcls, base, text_sig) - - # No '__text_signature__' was found for the 'obj' class. - # Last option is to check if its '__init__' is - # object.__init__ or type.__init__. - if type not in obj.__mro__: - # We have a class (not metaclass), but no user-defined - # __init__ or __new__ for it - if (obj.__init__ is object.__init__ and - obj.__new__ is object.__new__): - # Return a signature of 'object' builtin. - return sigcls.from_callable(object) - else: - raise ValueError( - 'no signature found for builtin type {!r}'.format(obj)) - - elif not isinstance(obj, _NonUserDefinedCallables): - # An object with __call__ - # We also check that the 'obj' is not an instance of - # types.WrapperDescriptorType or types.MethodWrapperType to avoid - # infinite recursion (and even potential segfault) - call = _signature_get_user_defined_method(type(obj), '__call__') - if call is not None: - try: - sig = _get_signature_of(call) - except ValueError as ex: - msg = 'no signature found for {!r}'.format(obj) - raise ValueError(msg) from ex - - if sig is not None: - # For classes and objects we skip the first parameter of their - # __call__, __new__, or __init__ methods - if skip_bound_arg: - return _signature_bound_method(sig) - else: - return sig - - if isinstance(obj, types.BuiltinFunctionType): - # Raise a nicer error message for builtins - msg = 'no signature found for builtin function {!r}'.format(obj) - raise ValueError(msg) - - raise ValueError('callable {!r} is not supported by signature'.format(obj)) - - -class _void: - """A private marker - used in Parameter & Signature.""" - - -class _empty: - """Marker object for Signature.empty and Parameter.empty.""" - - -class _ParameterKind(enum.IntEnum): - POSITIONAL_ONLY = 'positional-only' - POSITIONAL_OR_KEYWORD = 'positional or keyword' - VAR_POSITIONAL = 'variadic positional' - KEYWORD_ONLY = 'keyword-only' - VAR_KEYWORD = 'variadic keyword' - - def __new__(cls, description): - value = len(cls.__members__) - member = int.__new__(cls, value) - member._value_ = value - member.description = description - return member - - def __str__(self): - return self.name - -_POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY -_POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD -_VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL -_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY -_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD - - -class Parameter: - """Represents a parameter in a function signature. - - Has the following public attributes: - - * name : str - The name of the parameter as a string. - * default : object - The default value for the parameter if specified. If the - parameter has no default value, this attribute is set to - `Parameter.empty`. - * annotation - The annotation for the parameter if specified. If the - parameter has no annotation, this attribute is set to - `Parameter.empty`. - * kind : str - Describes how argument values are bound to the parameter. - Possible values: `Parameter.POSITIONAL_ONLY`, - `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`, - `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`. - """ - - __slots__ = ('_name', '_kind', '_default', '_annotation') - - POSITIONAL_ONLY = _POSITIONAL_ONLY - POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD - VAR_POSITIONAL = _VAR_POSITIONAL - KEYWORD_ONLY = _KEYWORD_ONLY - VAR_KEYWORD = _VAR_KEYWORD - - empty = _empty - - def __init__(self, name, kind, *, default=_empty, annotation=_empty): - try: - self._kind = _ParameterKind(kind) - except ValueError: - raise ValueError(f'value {kind!r} is not a valid Parameter.kind') - if default is not _empty: - if self._kind in (_VAR_POSITIONAL, _VAR_KEYWORD): - msg = '{} parameters cannot have default values' - msg = msg.format(self._kind.description) - raise ValueError(msg) - self._default = default - self._annotation = annotation - - if name is _empty: - raise ValueError('name is a required attribute for Parameter') - - if not isinstance(name, str): - msg = 'name must be a str, not a {}'.format(type(name).__name__) - raise TypeError(msg) - - if name[0] == '.' and name[1:].isdigit(): - # These are implicit arguments generated by comprehensions. In - # order to provide a friendlier interface to users, we recast - # their name as "implicitN" and treat them as positional-only. - # See issue 19611. - if self._kind != _POSITIONAL_OR_KEYWORD: - msg = ( - 'implicit arguments must be passed as ' - 'positional or keyword arguments, not {}' - ) - msg = msg.format(self._kind.description) - raise ValueError(msg) - self._kind = _POSITIONAL_ONLY - name = 'implicit{}'.format(name[1:]) - - # It's possible for C functions to have a positional-only parameter - # where the name is a keyword, so for compatibility we'll allow it. - is_keyword = iskeyword(name) and self._kind is not _POSITIONAL_ONLY - if is_keyword or not name.isidentifier(): - raise ValueError('{!r} is not a valid parameter name'.format(name)) - - self._name = name - - def __reduce__(self): - return (type(self), - (self._name, self._kind), - {'_default': self._default, - '_annotation': self._annotation}) - - def __setstate__(self, state): - self._default = state['_default'] - self._annotation = state['_annotation'] - - @property - def name(self): - return self._name - - @property - def default(self): - return self._default - - @property - def annotation(self): - return self._annotation - - @property - def kind(self): - return self._kind - - def replace(self, *, name=_void, kind=_void, - annotation=_void, default=_void): - """Creates a customized copy of the Parameter.""" - - if name is _void: - name = self._name - - if kind is _void: - kind = self._kind - - if annotation is _void: - annotation = self._annotation - - if default is _void: - default = self._default - - return type(self)(name, kind, default=default, annotation=annotation) - - def __str__(self): - kind = self.kind - formatted = self._name - - # Add annotation and default value - if self._annotation is not _empty: - formatted = '{}: {}'.format(formatted, - formatannotation(self._annotation)) - - if self._default is not _empty: - if self._annotation is not _empty: - formatted = '{} = {}'.format(formatted, repr(self._default)) - else: - formatted = '{}={}'.format(formatted, repr(self._default)) - - if kind == _VAR_POSITIONAL: - formatted = '*' + formatted - elif kind == _VAR_KEYWORD: - formatted = '**' + formatted - - return formatted - - def __repr__(self): - return '<{} "{}">'.format(self.__class__.__name__, self) - - def __hash__(self): - return hash((self.name, self.kind, self.annotation, self.default)) - - def __eq__(self, other): - if self is other: - return True - if not isinstance(other, Parameter): - return NotImplemented - return (self._name == other._name and - self._kind == other._kind and - self._default == other._default and - self._annotation == other._annotation) - - -class BoundArguments: - """Result of `Signature.bind` call. Holds the mapping of arguments - to the function's parameters. - - Has the following public attributes: - - * arguments : dict - An ordered mutable mapping of parameters' names to arguments' values. - Does not contain arguments' default values. - * signature : Signature - The Signature object that created this instance. - * args : tuple - Tuple of positional arguments values. - * kwargs : dict - Dict of keyword arguments values. - """ - - __slots__ = ('arguments', '_signature', '__weakref__') - - def __init__(self, signature, arguments): - self.arguments = arguments - self._signature = signature - - @property - def signature(self): - return self._signature - - @property - def args(self): - args = [] - for param_name, param in self._signature.parameters.items(): - if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY): - break - - try: - arg = self.arguments[param_name] - except KeyError: - # We're done here. Other arguments - # will be mapped in 'BoundArguments.kwargs' - break - else: - if param.kind == _VAR_POSITIONAL: - # *args - args.extend(arg) - else: - # plain argument - args.append(arg) - - return tuple(args) - - @property - def kwargs(self): - kwargs = {} - kwargs_started = False - for param_name, param in self._signature.parameters.items(): - if not kwargs_started: - if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY): - kwargs_started = True - else: - if param_name not in self.arguments: - kwargs_started = True - continue - - if not kwargs_started: - continue - - try: - arg = self.arguments[param_name] - except KeyError: - pass - else: - if param.kind == _VAR_KEYWORD: - # **kwargs - kwargs.update(arg) - else: - # plain keyword argument - kwargs[param_name] = arg - - return kwargs - - def apply_defaults(self): - """Set default values for missing arguments. - - For variable-positional arguments (*args) the default is an - empty tuple. - - For variable-keyword arguments (**kwargs) the default is an - empty dict. - """ - arguments = self.arguments - new_arguments = [] - for name, param in self._signature.parameters.items(): - try: - new_arguments.append((name, arguments[name])) - except KeyError: - if param.default is not _empty: - val = param.default - elif param.kind is _VAR_POSITIONAL: - val = () - elif param.kind is _VAR_KEYWORD: - val = {} - else: - # This BoundArguments was likely produced by - # Signature.bind_partial(). - continue - new_arguments.append((name, val)) - self.arguments = dict(new_arguments) - - def __eq__(self, other): - if self is other: - return True - if not isinstance(other, BoundArguments): - return NotImplemented - return (self.signature == other.signature and - self.arguments == other.arguments) - - def __setstate__(self, state): - self._signature = state['_signature'] - self.arguments = state['arguments'] - - def __getstate__(self): - return {'_signature': self._signature, 'arguments': self.arguments} - - def __repr__(self): - args = [] - for arg, value in self.arguments.items(): - args.append('{}={!r}'.format(arg, value)) - return '<{} ({})>'.format(self.__class__.__name__, ', '.join(args)) - - -class Signature: - """A Signature object represents the overall signature of a function. - It stores a Parameter object for each parameter accepted by the - function, as well as information specific to the function itself. - - A Signature object has the following public attributes and methods: - - * parameters : OrderedDict - An ordered mapping of parameters' names to the corresponding - Parameter objects (keyword-only arguments are in the same order - as listed in `code.co_varnames`). - * return_annotation : object - The annotation for the return type of the function if specified. - If the function has no annotation for its return type, this - attribute is set to `Signature.empty`. - * bind(*args, **kwargs) -> BoundArguments - Creates a mapping from positional and keyword arguments to - parameters. - * bind_partial(*args, **kwargs) -> BoundArguments - Creates a partial mapping from positional and keyword arguments - to parameters (simulating 'functools.partial' behavior.) - """ - - __slots__ = ('_return_annotation', '_parameters') - - _parameter_cls = Parameter - _bound_arguments_cls = BoundArguments - - empty = _empty - - def __init__(self, parameters=None, *, return_annotation=_empty, - __validate_parameters__=True): - """Constructs Signature from the given list of Parameter - objects and 'return_annotation'. All arguments are optional. - """ - - if parameters is None: - params = OrderedDict() - else: - if __validate_parameters__: - params = OrderedDict() - top_kind = _POSITIONAL_ONLY - kind_defaults = False - - for param in parameters: - kind = param.kind - name = param.name - - if kind < top_kind: - msg = ( - 'wrong parameter order: {} parameter before {} ' - 'parameter' - ) - msg = msg.format(top_kind.description, - kind.description) - raise ValueError(msg) - elif kind > top_kind: - kind_defaults = False - top_kind = kind - - if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD): - if param.default is _empty: - if kind_defaults: - # No default for this parameter, but the - # previous parameter of the same kind had - # a default - msg = 'non-default argument follows default ' \ - 'argument' - raise ValueError(msg) - else: - # There is a default for this parameter. - kind_defaults = True - - if name in params: - msg = 'duplicate parameter name: {!r}'.format(name) - raise ValueError(msg) - - params[name] = param - else: - params = OrderedDict((param.name, param) for param in parameters) - - self._parameters = types.MappingProxyType(params) - self._return_annotation = return_annotation - - @classmethod - def from_callable(cls, obj, *, - follow_wrapped=True, globals=None, locals=None, eval_str=False): - """Constructs Signature for the given callable object.""" - return _signature_from_callable(obj, sigcls=cls, - follow_wrapper_chains=follow_wrapped, - globals=globals, locals=locals, eval_str=eval_str) - - @property - def parameters(self): - return self._parameters - - @property - def return_annotation(self): - return self._return_annotation - - def replace(self, *, parameters=_void, return_annotation=_void): - """Creates a customized copy of the Signature. - Pass 'parameters' and/or 'return_annotation' arguments - to override them in the new copy. - """ - - if parameters is _void: - parameters = self.parameters.values() - - if return_annotation is _void: - return_annotation = self._return_annotation - - return type(self)(parameters, - return_annotation=return_annotation) - - def _hash_basis(self): - params = tuple(param for param in self.parameters.values() - if param.kind != _KEYWORD_ONLY) - - kwo_params = {param.name: param for param in self.parameters.values() - if param.kind == _KEYWORD_ONLY} - - return params, kwo_params, self.return_annotation - - def __hash__(self): - params, kwo_params, return_annotation = self._hash_basis() - kwo_params = frozenset(kwo_params.values()) - return hash((params, kwo_params, return_annotation)) - - def __eq__(self, other): - if self is other: - return True - if not isinstance(other, Signature): - return NotImplemented - return self._hash_basis() == other._hash_basis() - - def _bind(self, args, kwargs, *, partial=False): - """Private method. Don't use directly.""" - - arguments = {} - - parameters = iter(self.parameters.values()) - parameters_ex = () - arg_vals = iter(args) - - while True: - # Let's iterate through the positional arguments and corresponding - # parameters - try: - arg_val = next(arg_vals) - except StopIteration: - # No more positional arguments - try: - param = next(parameters) - except StopIteration: - # No more parameters. That's it. Just need to check that - # we have no `kwargs` after this while loop - break - else: - if param.kind == _VAR_POSITIONAL: - # That's OK, just empty *args. Let's start parsing - # kwargs - break - elif param.name in kwargs: - if param.kind == _POSITIONAL_ONLY: - msg = '{arg!r} parameter is positional only, ' \ - 'but was passed as a keyword' - msg = msg.format(arg=param.name) - raise TypeError(msg) from None - parameters_ex = (param,) - break - elif (param.kind == _VAR_KEYWORD or - param.default is not _empty): - # That's fine too - we have a default value for this - # parameter. So, lets start parsing `kwargs`, starting - # with the current parameter - parameters_ex = (param,) - break - else: - # No default, not VAR_KEYWORD, not VAR_POSITIONAL, - # not in `kwargs` - if partial: - parameters_ex = (param,) - break - else: - msg = 'missing a required argument: {arg!r}' - msg = msg.format(arg=param.name) - raise TypeError(msg) from None - else: - # We have a positional argument to process - try: - param = next(parameters) - except StopIteration: - raise TypeError('too many positional arguments') from None - else: - if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY): - # Looks like we have no parameter for this positional - # argument - raise TypeError( - 'too many positional arguments') from None - - if param.kind == _VAR_POSITIONAL: - # We have an '*args'-like argument, let's fill it with - # all positional arguments we have left and move on to - # the next phase - values = [arg_val] - values.extend(arg_vals) - arguments[param.name] = tuple(values) - break - - if param.name in kwargs and param.kind != _POSITIONAL_ONLY: - raise TypeError( - 'multiple values for argument {arg!r}'.format( - arg=param.name)) from None - - arguments[param.name] = arg_val - - # Now, we iterate through the remaining parameters to process - # keyword arguments - kwargs_param = None - for param in itertools.chain(parameters_ex, parameters): - if param.kind == _VAR_KEYWORD: - # Memorize that we have a '**kwargs'-like parameter - kwargs_param = param - continue - - if param.kind == _VAR_POSITIONAL: - # Named arguments don't refer to '*args'-like parameters. - # We only arrive here if the positional arguments ended - # before reaching the last parameter before *args. - continue - - param_name = param.name - try: - arg_val = kwargs.pop(param_name) - except KeyError: - # We have no value for this parameter. It's fine though, - # if it has a default value, or it is an '*args'-like - # parameter, left alone by the processing of positional - # arguments. - if (not partial and param.kind != _VAR_POSITIONAL and - param.default is _empty): - raise TypeError('missing a required argument: {arg!r}'. \ - format(arg=param_name)) from None - - else: - if param.kind == _POSITIONAL_ONLY: - # This should never happen in case of a properly built - # Signature object (but let's have this check here - # to ensure correct behaviour just in case) - raise TypeError('{arg!r} parameter is positional only, ' - 'but was passed as a keyword'. \ - format(arg=param.name)) - - arguments[param_name] = arg_val - - if kwargs: - if kwargs_param is not None: - # Process our '**kwargs'-like parameter - arguments[kwargs_param.name] = kwargs - else: - raise TypeError( - 'got an unexpected keyword argument {arg!r}'.format( - arg=next(iter(kwargs)))) - - return self._bound_arguments_cls(self, arguments) - - def bind(self, /, *args, **kwargs): - """Get a BoundArguments object, that maps the passed `args` - and `kwargs` to the function's signature. Raises `TypeError` - if the passed arguments can not be bound. - """ - return self._bind(args, kwargs) - - def bind_partial(self, /, *args, **kwargs): - """Get a BoundArguments object, that partially maps the - passed `args` and `kwargs` to the function's signature. - Raises `TypeError` if the passed arguments can not be bound. - """ - return self._bind(args, kwargs, partial=True) - - def __reduce__(self): - return (type(self), - (tuple(self._parameters.values()),), - {'_return_annotation': self._return_annotation}) - - def __setstate__(self, state): - self._return_annotation = state['_return_annotation'] - - def __repr__(self): - return '<{} {}>'.format(self.__class__.__name__, self) - - def __str__(self): - result = [] - render_pos_only_separator = False - render_kw_only_separator = True - for param in self.parameters.values(): - formatted = str(param) - - kind = param.kind - - if kind == _POSITIONAL_ONLY: - render_pos_only_separator = True - elif render_pos_only_separator: - # It's not a positional-only parameter, and the flag - # is set to 'True' (there were pos-only params before.) - result.append('/') - render_pos_only_separator = False - - if kind == _VAR_POSITIONAL: - # OK, we have an '*args'-like parameter, so we won't need - # a '*' to separate keyword-only arguments - render_kw_only_separator = False - elif kind == _KEYWORD_ONLY and render_kw_only_separator: - # We have a keyword-only parameter to render and we haven't - # rendered an '*args'-like parameter before, so add a '*' - # separator to the parameters list ("foo(arg1, *, arg2)" case) - result.append('*') - # This condition should be only triggered once, so - # reset the flag - render_kw_only_separator = False - - result.append(formatted) - - if render_pos_only_separator: - # There were only positional-only parameters, hence the - # flag was not reset to 'False' - result.append('/') - - rendered = '({})'.format(', '.join(result)) - - if self.return_annotation is not _empty: - anno = formatannotation(self.return_annotation) - rendered += ' -> {}'.format(anno) - - return rendered - - -def signature(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=False): - """Get a signature object for the passed callable.""" - return Signature.from_callable(obj, follow_wrapped=follow_wrapped, - globals=globals, locals=locals, eval_str=eval_str) - - -def _main(): - """ Logic for inspecting an object given at command line """ - import argparse - import importlib - - parser = argparse.ArgumentParser() - parser.add_argument( - 'object', - help="The object to be analysed. " - "It supports the 'module:qualname' syntax") - parser.add_argument( - '-d', '--details', action='store_true', - help='Display info about the module rather than its source code') - - args = parser.parse_args() - - target = args.object - mod_name, has_attrs, attrs = target.partition(":") - try: - obj = module = importlib.import_module(mod_name) - except Exception as exc: - msg = "Failed to import {} ({}: {})".format(mod_name, - type(exc).__name__, - exc) - print(msg, file=sys.stderr) - sys.exit(2) - - if has_attrs: - parts = attrs.split(".") - obj = module - for part in parts: - obj = getattr(obj, part) - - if module.__name__ in sys.builtin_module_names: - print("Can't get info for builtin modules.", file=sys.stderr) - sys.exit(1) - - if args.details: - print('Target: {}'.format(target)) - print('Origin: {}'.format(getsourcefile(module))) - print('Cached: {}'.format(module.__cached__)) - if obj is module: - print('Loader: {}'.format(repr(module.__loader__))) - if hasattr(module, '__path__'): - print('Submodule search path: {}'.format(module.__path__)) - else: - try: - __, lineno = findsource(obj) - except Exception: - pass - else: - print('Line: {}'.format(lineno)) - - print('\n') - else: - print(getsource(obj)) - - -if __name__ == "__main__": - _main() diff --git a/python/Lib/io.py b/python/Lib/io.py deleted file mode 100644 index 651ddab..0000000 --- a/python/Lib/io.py +++ /dev/null @@ -1,114 +0,0 @@ -"""The io module provides the Python interfaces to stream handling. The -builtin open function is defined in this module. - -At the top of the I/O hierarchy is the abstract base class IOBase. It -defines the basic interface to a stream. Note, however, that there is no -separation between reading and writing to streams; implementations are -allowed to raise an OSError if they do not support a given operation. - -Extending IOBase is RawIOBase which deals simply with the reading and -writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide -an interface to OS files. - -BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its -subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer -streams that are readable, writable, and both respectively. -BufferedRandom provides a buffered interface to random access -streams. BytesIO is a simple stream of in-memory bytes. - -Another IOBase subclass, TextIOBase, deals with the encoding and decoding -of streams into text. TextIOWrapper, which extends it, is a buffered text -interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO -is an in-memory stream for text. - -Argument names are not part of the specification, and only the arguments -of open() are intended to be used as keyword arguments. - -data: - -DEFAULT_BUFFER_SIZE - - An int containing the default buffer size used by the module's buffered - I/O classes. open() uses the file's blksize (as obtained by os.stat) if - possible. -""" -# New I/O library conforming to PEP 3116. - -__author__ = ("Guido van Rossum , " - "Mike Verdone , " - "Mark Russell , " - "Antoine Pitrou , " - "Amaury Forgeot d'Arc , " - "Benjamin Peterson ") - -__all__ = ["BlockingIOError", "open", "open_code", "IOBase", "RawIOBase", - "FileIO", "BytesIO", "StringIO", "BufferedIOBase", - "BufferedReader", "BufferedWriter", "BufferedRWPair", - "BufferedRandom", "TextIOBase", "TextIOWrapper", - "UnsupportedOperation", "SEEK_SET", "SEEK_CUR", "SEEK_END"] - - -import _io -import abc - -from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation, - open, open_code, FileIO, BytesIO, StringIO, BufferedReader, - BufferedWriter, BufferedRWPair, BufferedRandom, - IncrementalNewlineDecoder, text_encoding, TextIOWrapper) - - -def __getattr__(name): - if name == "OpenWrapper": - # bpo-43680: Until Python 3.9, _pyio.open was not a static method and - # builtins.open was set to OpenWrapper to not become a bound method - # when set to a class variable. _io.open is a built-in function whereas - # _pyio.open is a Python function. In Python 3.10, _pyio.open() is now - # a static method, and builtins.open() is now io.open(). - import warnings - warnings.warn('OpenWrapper is deprecated, use open instead', - DeprecationWarning, stacklevel=2) - global OpenWrapper - OpenWrapper = open - return OpenWrapper - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") - - -# Pretend this exception was created here. -UnsupportedOperation.__module__ = "io" - -# for seek() -SEEK_SET = 0 -SEEK_CUR = 1 -SEEK_END = 2 - -# Declaring ABCs in C is tricky so we do it here. -# Method descriptions and default implementations are inherited from the C -# version however. -class IOBase(_io._IOBase, metaclass=abc.ABCMeta): - __doc__ = _io._IOBase.__doc__ - -class RawIOBase(_io._RawIOBase, IOBase): - __doc__ = _io._RawIOBase.__doc__ - -class BufferedIOBase(_io._BufferedIOBase, IOBase): - __doc__ = _io._BufferedIOBase.__doc__ - -class TextIOBase(_io._TextIOBase, IOBase): - __doc__ = _io._TextIOBase.__doc__ - -RawIOBase.register(FileIO) - -for klass in (BytesIO, BufferedReader, BufferedWriter, BufferedRandom, - BufferedRWPair): - BufferedIOBase.register(klass) - -for klass in (StringIO, TextIOWrapper): - TextIOBase.register(klass) -del klass - -try: - from _io import _WindowsConsoleIO -except ImportError: - pass -else: - RawIOBase.register(_WindowsConsoleIO) diff --git a/python/Lib/ipaddress.py b/python/Lib/ipaddress.py deleted file mode 100644 index e39d4ee..0000000 --- a/python/Lib/ipaddress.py +++ /dev/null @@ -1,2299 +0,0 @@ -# Copyright 2007 Google Inc. -# Licensed to PSF under a Contributor Agreement. - -"""A fast, lightweight IPv4/IPv6 manipulation library in Python. - -This library is used to create/poke/manipulate IPv4 and IPv6 addresses -and networks. - -""" - -__version__ = '1.0' - - -import functools - -IPV4LENGTH = 32 -IPV6LENGTH = 128 - - -class AddressValueError(ValueError): - """A Value Error related to the address.""" - - -class NetmaskValueError(ValueError): - """A Value Error related to the netmask.""" - - -def ip_address(address): - """Take an IP string/int and return an object of the correct type. - - Args: - address: A string or integer, the IP address. Either IPv4 or - IPv6 addresses may be supplied; integers less than 2**32 will - be considered to be IPv4 by default. - - Returns: - An IPv4Address or IPv6Address object. - - Raises: - ValueError: if the *address* passed isn't either a v4 or a v6 - address - - """ - try: - return IPv4Address(address) - except (AddressValueError, NetmaskValueError): - pass - - try: - return IPv6Address(address) - except (AddressValueError, NetmaskValueError): - pass - - raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address') - - -def ip_network(address, strict=True): - """Take an IP string/int and return an object of the correct type. - - Args: - address: A string or integer, the IP network. Either IPv4 or - IPv6 networks may be supplied; integers less than 2**32 will - be considered to be IPv4 by default. - - Returns: - An IPv4Network or IPv6Network object. - - Raises: - ValueError: if the string passed isn't either a v4 or a v6 - address. Or if the network has host bits set. - - """ - try: - return IPv4Network(address, strict) - except (AddressValueError, NetmaskValueError): - pass - - try: - return IPv6Network(address, strict) - except (AddressValueError, NetmaskValueError): - pass - - raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 network') - - -def ip_interface(address): - """Take an IP string/int and return an object of the correct type. - - Args: - address: A string or integer, the IP address. Either IPv4 or - IPv6 addresses may be supplied; integers less than 2**32 will - be considered to be IPv4 by default. - - Returns: - An IPv4Interface or IPv6Interface object. - - Raises: - ValueError: if the string passed isn't either a v4 or a v6 - address. - - Notes: - The IPv?Interface classes describe an Address on a particular - Network, so they're basically a combination of both the Address - and Network classes. - - """ - try: - return IPv4Interface(address) - except (AddressValueError, NetmaskValueError): - pass - - try: - return IPv6Interface(address) - except (AddressValueError, NetmaskValueError): - pass - - raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 interface') - - -def v4_int_to_packed(address): - """Represent an address as 4 packed bytes in network (big-endian) order. - - Args: - address: An integer representation of an IPv4 IP address. - - Returns: - The integer address packed as 4 bytes in network (big-endian) order. - - Raises: - ValueError: If the integer is negative or too large to be an - IPv4 IP address. - - """ - try: - return address.to_bytes(4) # big endian - except OverflowError: - raise ValueError("Address negative or too large for IPv4") - - -def v6_int_to_packed(address): - """Represent an address as 16 packed bytes in network (big-endian) order. - - Args: - address: An integer representation of an IPv6 IP address. - - Returns: - The integer address packed as 16 bytes in network (big-endian) order. - - """ - try: - return address.to_bytes(16) # big endian - except OverflowError: - raise ValueError("Address negative or too large for IPv6") - - -def _split_optional_netmask(address): - """Helper to split the netmask and raise AddressValueError if needed""" - addr = str(address).split('/') - if len(addr) > 2: - raise AddressValueError(f"Only one '/' permitted in {address!r}") - return addr - - -def _find_address_range(addresses): - """Find a sequence of sorted deduplicated IPv#Address. - - Args: - addresses: a list of IPv#Address objects. - - Yields: - A tuple containing the first and last IP addresses in the sequence. - - """ - it = iter(addresses) - first = last = next(it) - for ip in it: - if ip._ip != last._ip + 1: - yield first, last - first = ip - last = ip - yield first, last - - -def _count_righthand_zero_bits(number, bits): - """Count the number of zero bits on the right hand side. - - Args: - number: an integer. - bits: maximum number of bits to count. - - Returns: - The number of zero bits on the right hand side of the number. - - """ - if number == 0: - return bits - return min(bits, (~number & (number-1)).bit_length()) - - -def summarize_address_range(first, last): - """Summarize a network range given the first and last IP addresses. - - Example: - >>> list(summarize_address_range(IPv4Address('192.0.2.0'), - ... IPv4Address('192.0.2.130'))) - ... #doctest: +NORMALIZE_WHITESPACE - [IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'), - IPv4Network('192.0.2.130/32')] - - Args: - first: the first IPv4Address or IPv6Address in the range. - last: the last IPv4Address or IPv6Address in the range. - - Returns: - An iterator of the summarized IPv(4|6) network objects. - - Raise: - TypeError: - If the first and last objects are not IP addresses. - If the first and last objects are not the same version. - ValueError: - If the last object is not greater than the first. - If the version of the first address is not 4 or 6. - - """ - if (not (isinstance(first, _BaseAddress) and - isinstance(last, _BaseAddress))): - raise TypeError('first and last must be IP addresses, not networks') - if first.version != last.version: - raise TypeError("%s and %s are not of the same version" % ( - first, last)) - if first > last: - raise ValueError('last IP address must be greater than first') - - if first.version == 4: - ip = IPv4Network - elif first.version == 6: - ip = IPv6Network - else: - raise ValueError('unknown IP version') - - ip_bits = first._max_prefixlen - first_int = first._ip - last_int = last._ip - while first_int <= last_int: - nbits = min(_count_righthand_zero_bits(first_int, ip_bits), - (last_int - first_int + 1).bit_length() - 1) - net = ip((first_int, ip_bits - nbits)) - yield net - first_int += 1 << nbits - if first_int - 1 == ip._ALL_ONES: - break - - -def _collapse_addresses_internal(addresses): - """Loops through the addresses, collapsing concurrent netblocks. - - Example: - - ip1 = IPv4Network('192.0.2.0/26') - ip2 = IPv4Network('192.0.2.64/26') - ip3 = IPv4Network('192.0.2.128/26') - ip4 = IPv4Network('192.0.2.192/26') - - _collapse_addresses_internal([ip1, ip2, ip3, ip4]) -> - [IPv4Network('192.0.2.0/24')] - - This shouldn't be called directly; it is called via - collapse_addresses([]). - - Args: - addresses: A list of IPv4Network's or IPv6Network's - - Returns: - A list of IPv4Network's or IPv6Network's depending on what we were - passed. - - """ - # First merge - to_merge = list(addresses) - subnets = {} - while to_merge: - net = to_merge.pop() - supernet = net.supernet() - existing = subnets.get(supernet) - if existing is None: - subnets[supernet] = net - elif existing != net: - # Merge consecutive subnets - del subnets[supernet] - to_merge.append(supernet) - # Then iterate over resulting networks, skipping subsumed subnets - last = None - for net in sorted(subnets.values()): - if last is not None: - # Since they are sorted, last.network_address <= net.network_address - # is a given. - if last.broadcast_address >= net.broadcast_address: - continue - yield net - last = net - - -def collapse_addresses(addresses): - """Collapse a list of IP objects. - - Example: - collapse_addresses([IPv4Network('192.0.2.0/25'), - IPv4Network('192.0.2.128/25')]) -> - [IPv4Network('192.0.2.0/24')] - - Args: - addresses: An iterator of IPv4Network or IPv6Network objects. - - Returns: - An iterator of the collapsed IPv(4|6)Network objects. - - Raises: - TypeError: If passed a list of mixed version objects. - - """ - addrs = [] - ips = [] - nets = [] - - # split IP addresses and networks - for ip in addresses: - if isinstance(ip, _BaseAddress): - if ips and ips[-1]._version != ip._version: - raise TypeError("%s and %s are not of the same version" % ( - ip, ips[-1])) - ips.append(ip) - elif ip._prefixlen == ip._max_prefixlen: - if ips and ips[-1]._version != ip._version: - raise TypeError("%s and %s are not of the same version" % ( - ip, ips[-1])) - try: - ips.append(ip.ip) - except AttributeError: - ips.append(ip.network_address) - else: - if nets and nets[-1]._version != ip._version: - raise TypeError("%s and %s are not of the same version" % ( - ip, nets[-1])) - nets.append(ip) - - # sort and dedup - ips = sorted(set(ips)) - - # find consecutive address ranges in the sorted sequence and summarize them - if ips: - for first, last in _find_address_range(ips): - addrs.extend(summarize_address_range(first, last)) - - return _collapse_addresses_internal(addrs + nets) - - -def get_mixed_type_key(obj): - """Return a key suitable for sorting between networks and addresses. - - Address and Network objects are not sortable by default; they're - fundamentally different so the expression - - IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24') - - doesn't make any sense. There are some times however, where you may wish - to have ipaddress sort these for you anyway. If you need to do this, you - can use this function as the key= argument to sorted(). - - Args: - obj: either a Network or Address object. - Returns: - appropriate key. - - """ - if isinstance(obj, _BaseNetwork): - return obj._get_networks_key() - elif isinstance(obj, _BaseAddress): - return obj._get_address_key() - return NotImplemented - - -class _IPAddressBase: - - """The mother class.""" - - __slots__ = () - - @property - def exploded(self): - """Return the longhand version of the IP address as a string.""" - return self._explode_shorthand_ip_string() - - @property - def compressed(self): - """Return the shorthand version of the IP address as a string.""" - return str(self) - - @property - def reverse_pointer(self): - """The name of the reverse DNS pointer for the IP address, e.g.: - >>> ipaddress.ip_address("127.0.0.1").reverse_pointer - '1.0.0.127.in-addr.arpa' - >>> ipaddress.ip_address("2001:db8::1").reverse_pointer - '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' - - """ - return self._reverse_pointer() - - @property - def version(self): - msg = '%200s has no version specified' % (type(self),) - raise NotImplementedError(msg) - - def _check_int_address(self, address): - if address < 0: - msg = "%d (< 0) is not permitted as an IPv%d address" - raise AddressValueError(msg % (address, self._version)) - if address > self._ALL_ONES: - msg = "%d (>= 2**%d) is not permitted as an IPv%d address" - raise AddressValueError(msg % (address, self._max_prefixlen, - self._version)) - - def _check_packed_address(self, address, expected_len): - address_len = len(address) - if address_len != expected_len: - msg = "%r (len %d != %d) is not permitted as an IPv%d address" - raise AddressValueError(msg % (address, address_len, - expected_len, self._version)) - - @classmethod - def _ip_int_from_prefix(cls, prefixlen): - """Turn the prefix length into a bitwise netmask - - Args: - prefixlen: An integer, the prefix length. - - Returns: - An integer. - - """ - return cls._ALL_ONES ^ (cls._ALL_ONES >> prefixlen) - - @classmethod - def _prefix_from_ip_int(cls, ip_int): - """Return prefix length from the bitwise netmask. - - Args: - ip_int: An integer, the netmask in expanded bitwise format - - Returns: - An integer, the prefix length. - - Raises: - ValueError: If the input intermingles zeroes & ones - """ - trailing_zeroes = _count_righthand_zero_bits(ip_int, - cls._max_prefixlen) - prefixlen = cls._max_prefixlen - trailing_zeroes - leading_ones = ip_int >> trailing_zeroes - all_ones = (1 << prefixlen) - 1 - if leading_ones != all_ones: - byteslen = cls._max_prefixlen // 8 - details = ip_int.to_bytes(byteslen, 'big') - msg = 'Netmask pattern %r mixes zeroes & ones' - raise ValueError(msg % details) - return prefixlen - - @classmethod - def _report_invalid_netmask(cls, netmask_str): - msg = '%r is not a valid netmask' % netmask_str - raise NetmaskValueError(msg) from None - - @classmethod - def _prefix_from_prefix_string(cls, prefixlen_str): - """Return prefix length from a numeric string - - Args: - prefixlen_str: The string to be converted - - Returns: - An integer, the prefix length. - - Raises: - NetmaskValueError: If the input is not a valid netmask - """ - # int allows a leading +/- as well as surrounding whitespace, - # so we ensure that isn't the case - if not (prefixlen_str.isascii() and prefixlen_str.isdigit()): - cls._report_invalid_netmask(prefixlen_str) - try: - prefixlen = int(prefixlen_str) - except ValueError: - cls._report_invalid_netmask(prefixlen_str) - if not (0 <= prefixlen <= cls._max_prefixlen): - cls._report_invalid_netmask(prefixlen_str) - return prefixlen - - @classmethod - def _prefix_from_ip_string(cls, ip_str): - """Turn a netmask/hostmask string into a prefix length - - Args: - ip_str: The netmask/hostmask to be converted - - Returns: - An integer, the prefix length. - - Raises: - NetmaskValueError: If the input is not a valid netmask/hostmask - """ - # Parse the netmask/hostmask like an IP address. - try: - ip_int = cls._ip_int_from_string(ip_str) - except AddressValueError: - cls._report_invalid_netmask(ip_str) - - # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). - # Note that the two ambiguous cases (all-ones and all-zeroes) are - # treated as netmasks. - try: - return cls._prefix_from_ip_int(ip_int) - except ValueError: - pass - - # Invert the bits, and try matching a /0+1+/ hostmask instead. - ip_int ^= cls._ALL_ONES - try: - return cls._prefix_from_ip_int(ip_int) - except ValueError: - cls._report_invalid_netmask(ip_str) - - @classmethod - def _split_addr_prefix(cls, address): - """Helper function to parse address of Network/Interface. - - Arg: - address: Argument of Network/Interface. - - Returns: - (addr, prefix) tuple. - """ - # a packed address or integer - if isinstance(address, (bytes, int)): - return address, cls._max_prefixlen - - if not isinstance(address, tuple): - # Assume input argument to be string or any object representation - # which converts into a formatted IP prefix string. - address = _split_optional_netmask(address) - - # Constructing from a tuple (addr, [mask]) - if len(address) > 1: - return address - return address[0], cls._max_prefixlen - - def __reduce__(self): - return self.__class__, (str(self),) - - -_address_fmt_re = None - -@functools.total_ordering -class _BaseAddress(_IPAddressBase): - - """A generic IP object. - - This IP class contains the version independent methods which are - used by single IP addresses. - """ - - __slots__ = () - - def __int__(self): - return self._ip - - def __eq__(self, other): - try: - return (self._ip == other._ip - and self._version == other._version) - except AttributeError: - return NotImplemented - - def __lt__(self, other): - if not isinstance(other, _BaseAddress): - return NotImplemented - if self._version != other._version: - raise TypeError('%s and %s are not of the same version' % ( - self, other)) - if self._ip != other._ip: - return self._ip < other._ip - return False - - # Shorthand for Integer addition and subtraction. This is not - # meant to ever support addition/subtraction of addresses. - def __add__(self, other): - if not isinstance(other, int): - return NotImplemented - return self.__class__(int(self) + other) - - def __sub__(self, other): - if not isinstance(other, int): - return NotImplemented - return self.__class__(int(self) - other) - - def __repr__(self): - return '%s(%r)' % (self.__class__.__name__, str(self)) - - def __str__(self): - return str(self._string_from_ip_int(self._ip)) - - def __hash__(self): - return hash(hex(int(self._ip))) - - def _get_address_key(self): - return (self._version, self) - - def __reduce__(self): - return self.__class__, (self._ip,) - - def __format__(self, fmt): - """Returns an IP address as a formatted string. - - Supported presentation types are: - 's': returns the IP address as a string (default) - 'b': converts to binary and returns a zero-padded string - 'X' or 'x': converts to upper- or lower-case hex and returns a zero-padded string - 'n': the same as 'b' for IPv4 and 'x' for IPv6 - - For binary and hex presentation types, the alternate form specifier - '#' and the grouping option '_' are supported. - """ - - # Support string formatting - if not fmt or fmt[-1] == 's': - return format(str(self), fmt) - - # From here on down, support for 'bnXx' - global _address_fmt_re - if _address_fmt_re is None: - import re - _address_fmt_re = re.compile('(#?)(_?)([xbnX])') - - m = _address_fmt_re.fullmatch(fmt) - if not m: - return super().__format__(fmt) - - alternate, grouping, fmt_base = m.groups() - - # Set some defaults - if fmt_base == 'n': - if self._version == 4: - fmt_base = 'b' # Binary is default for ipv4 - else: - fmt_base = 'x' # Hex is default for ipv6 - - if fmt_base == 'b': - padlen = self._max_prefixlen - else: - padlen = self._max_prefixlen // 4 - - if grouping: - padlen += padlen // 4 - 1 - - if alternate: - padlen += 2 # 0b or 0x - - return format(int(self), f'{alternate}0{padlen}{grouping}{fmt_base}') - - -@functools.total_ordering -class _BaseNetwork(_IPAddressBase): - """A generic IP network object. - - This IP class contains the version independent methods which are - used by networks. - """ - - def __repr__(self): - return '%s(%r)' % (self.__class__.__name__, str(self)) - - def __str__(self): - return '%s/%d' % (self.network_address, self.prefixlen) - - def hosts(self): - """Generate Iterator over usable hosts in a network. - - This is like __iter__ except it doesn't return the network - or broadcast addresses. - - """ - network = int(self.network_address) - broadcast = int(self.broadcast_address) - for x in range(network + 1, broadcast): - yield self._address_class(x) - - def __iter__(self): - network = int(self.network_address) - broadcast = int(self.broadcast_address) - for x in range(network, broadcast + 1): - yield self._address_class(x) - - def __getitem__(self, n): - network = int(self.network_address) - broadcast = int(self.broadcast_address) - if n >= 0: - if network + n > broadcast: - raise IndexError('address out of range') - return self._address_class(network + n) - else: - n += 1 - if broadcast + n < network: - raise IndexError('address out of range') - return self._address_class(broadcast + n) - - def __lt__(self, other): - if not isinstance(other, _BaseNetwork): - return NotImplemented - if self._version != other._version: - raise TypeError('%s and %s are not of the same version' % ( - self, other)) - if self.network_address != other.network_address: - return self.network_address < other.network_address - if self.netmask != other.netmask: - return self.netmask < other.netmask - return False - - def __eq__(self, other): - try: - return (self._version == other._version and - self.network_address == other.network_address and - int(self.netmask) == int(other.netmask)) - except AttributeError: - return NotImplemented - - def __hash__(self): - return hash(int(self.network_address) ^ int(self.netmask)) - - def __contains__(self, other): - # always false if one is v4 and the other is v6. - if self._version != other._version: - return False - # dealing with another network. - if isinstance(other, _BaseNetwork): - return False - # dealing with another address - else: - # address - return other._ip & self.netmask._ip == self.network_address._ip - - def overlaps(self, other): - """Tell if self is partly contained in other.""" - return self.network_address in other or ( - self.broadcast_address in other or ( - other.network_address in self or ( - other.broadcast_address in self))) - - @functools.cached_property - def broadcast_address(self): - return self._address_class(int(self.network_address) | - int(self.hostmask)) - - @functools.cached_property - def hostmask(self): - return self._address_class(int(self.netmask) ^ self._ALL_ONES) - - @property - def with_prefixlen(self): - return '%s/%d' % (self.network_address, self._prefixlen) - - @property - def with_netmask(self): - return '%s/%s' % (self.network_address, self.netmask) - - @property - def with_hostmask(self): - return '%s/%s' % (self.network_address, self.hostmask) - - @property - def num_addresses(self): - """Number of hosts in the current subnet.""" - return int(self.broadcast_address) - int(self.network_address) + 1 - - @property - def _address_class(self): - # Returning bare address objects (rather than interfaces) allows for - # more consistent behaviour across the network address, broadcast - # address and individual host addresses. - msg = '%200s has no associated address class' % (type(self),) - raise NotImplementedError(msg) - - @property - def prefixlen(self): - return self._prefixlen - - def address_exclude(self, other): - """Remove an address from a larger block. - - For example: - - addr1 = ip_network('192.0.2.0/28') - addr2 = ip_network('192.0.2.1/32') - list(addr1.address_exclude(addr2)) = - [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'), - IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')] - - or IPv6: - - addr1 = ip_network('2001:db8::1/32') - addr2 = ip_network('2001:db8::1/128') - list(addr1.address_exclude(addr2)) = - [ip_network('2001:db8::1/128'), - ip_network('2001:db8::2/127'), - ip_network('2001:db8::4/126'), - ip_network('2001:db8::8/125'), - ... - ip_network('2001:db8:8000::/33')] - - Args: - other: An IPv4Network or IPv6Network object of the same type. - - Returns: - An iterator of the IPv(4|6)Network objects which is self - minus other. - - Raises: - TypeError: If self and other are of differing address - versions, or if other is not a network object. - ValueError: If other is not completely contained by self. - - """ - if not self._version == other._version: - raise TypeError("%s and %s are not of the same version" % ( - self, other)) - - if not isinstance(other, _BaseNetwork): - raise TypeError("%s is not a network object" % other) - - if not other.subnet_of(self): - raise ValueError('%s not contained in %s' % (other, self)) - if other == self: - return - - # Make sure we're comparing the network of other. - other = other.__class__('%s/%s' % (other.network_address, - other.prefixlen)) - - s1, s2 = self.subnets() - while s1 != other and s2 != other: - if other.subnet_of(s1): - yield s2 - s1, s2 = s1.subnets() - elif other.subnet_of(s2): - yield s1 - s1, s2 = s2.subnets() - else: - # If we got here, there's a bug somewhere. - raise AssertionError('Error performing exclusion: ' - 's1: %s s2: %s other: %s' % - (s1, s2, other)) - if s1 == other: - yield s2 - elif s2 == other: - yield s1 - else: - # If we got here, there's a bug somewhere. - raise AssertionError('Error performing exclusion: ' - 's1: %s s2: %s other: %s' % - (s1, s2, other)) - - def compare_networks(self, other): - """Compare two IP objects. - - This is only concerned about the comparison of the integer - representation of the network addresses. This means that the - host bits aren't considered at all in this method. If you want - to compare host bits, you can easily enough do a - 'HostA._ip < HostB._ip' - - Args: - other: An IP object. - - Returns: - If the IP versions of self and other are the same, returns: - - -1 if self < other: - eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25') - IPv6Network('2001:db8::1000/124') < - IPv6Network('2001:db8::2000/124') - 0 if self == other - eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24') - IPv6Network('2001:db8::1000/124') == - IPv6Network('2001:db8::1000/124') - 1 if self > other - eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25') - IPv6Network('2001:db8::2000/124') > - IPv6Network('2001:db8::1000/124') - - Raises: - TypeError if the IP versions are different. - - """ - # does this need to raise a ValueError? - if self._version != other._version: - raise TypeError('%s and %s are not of the same type' % ( - self, other)) - # self._version == other._version below here: - if self.network_address < other.network_address: - return -1 - if self.network_address > other.network_address: - return 1 - # self.network_address == other.network_address below here: - if self.netmask < other.netmask: - return -1 - if self.netmask > other.netmask: - return 1 - return 0 - - def _get_networks_key(self): - """Network-only key function. - - Returns an object that identifies this address' network and - netmask. This function is a suitable "key" argument for sorted() - and list.sort(). - - """ - return (self._version, self.network_address, self.netmask) - - def subnets(self, prefixlen_diff=1, new_prefix=None): - """The subnets which join to make the current subnet. - - In the case that self contains only one IP - (self._prefixlen == 32 for IPv4 or self._prefixlen == 128 - for IPv6), yield an iterator with just ourself. - - Args: - prefixlen_diff: An integer, the amount the prefix length - should be increased by. This should not be set if - new_prefix is also set. - new_prefix: The desired new prefix length. This must be a - larger number (smaller prefix) than the existing prefix. - This should not be set if prefixlen_diff is also set. - - Returns: - An iterator of IPv(4|6) objects. - - Raises: - ValueError: The prefixlen_diff is too small or too large. - OR - prefixlen_diff and new_prefix are both set or new_prefix - is a smaller number than the current prefix (smaller - number means a larger network) - - """ - if self._prefixlen == self._max_prefixlen: - yield self - return - - if new_prefix is not None: - if new_prefix < self._prefixlen: - raise ValueError('new prefix must be longer') - if prefixlen_diff != 1: - raise ValueError('cannot set prefixlen_diff and new_prefix') - prefixlen_diff = new_prefix - self._prefixlen - - if prefixlen_diff < 0: - raise ValueError('prefix length diff must be > 0') - new_prefixlen = self._prefixlen + prefixlen_diff - - if new_prefixlen > self._max_prefixlen: - raise ValueError( - 'prefix length diff %d is invalid for netblock %s' % ( - new_prefixlen, self)) - - start = int(self.network_address) - end = int(self.broadcast_address) + 1 - step = (int(self.hostmask) + 1) >> prefixlen_diff - for new_addr in range(start, end, step): - current = self.__class__((new_addr, new_prefixlen)) - yield current - - def supernet(self, prefixlen_diff=1, new_prefix=None): - """The supernet containing the current network. - - Args: - prefixlen_diff: An integer, the amount the prefix length of - the network should be decreased by. For example, given a - /24 network and a prefixlen_diff of 3, a supernet with a - /21 netmask is returned. - - Returns: - An IPv4 network object. - - Raises: - ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have - a negative prefix length. - OR - If prefixlen_diff and new_prefix are both set or new_prefix is a - larger number than the current prefix (larger number means a - smaller network) - - """ - if self._prefixlen == 0: - return self - - if new_prefix is not None: - if new_prefix > self._prefixlen: - raise ValueError('new prefix must be shorter') - if prefixlen_diff != 1: - raise ValueError('cannot set prefixlen_diff and new_prefix') - prefixlen_diff = self._prefixlen - new_prefix - - new_prefixlen = self.prefixlen - prefixlen_diff - if new_prefixlen < 0: - raise ValueError( - 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % - (self.prefixlen, prefixlen_diff)) - return self.__class__(( - int(self.network_address) & (int(self.netmask) << prefixlen_diff), - new_prefixlen - )) - - @property - def is_multicast(self): - """Test if the address is reserved for multicast use. - - Returns: - A boolean, True if the address is a multicast address. - See RFC 2373 2.7 for details. - - """ - return (self.network_address.is_multicast and - self.broadcast_address.is_multicast) - - @staticmethod - def _is_subnet_of(a, b): - try: - # Always false if one is v4 and the other is v6. - if a._version != b._version: - raise TypeError(f"{a} and {b} are not of the same version") - return (b.network_address <= a.network_address and - b.broadcast_address >= a.broadcast_address) - except AttributeError: - raise TypeError(f"Unable to test subnet containment " - f"between {a} and {b}") - - def subnet_of(self, other): - """Return True if this network is a subnet of other.""" - return self._is_subnet_of(self, other) - - def supernet_of(self, other): - """Return True if this network is a supernet of other.""" - return self._is_subnet_of(other, self) - - @property - def is_reserved(self): - """Test if the address is otherwise IETF reserved. - - Returns: - A boolean, True if the address is within one of the - reserved IPv6 Network ranges. - - """ - return (self.network_address.is_reserved and - self.broadcast_address.is_reserved) - - @property - def is_link_local(self): - """Test if the address is reserved for link-local. - - Returns: - A boolean, True if the address is reserved per RFC 4291. - - """ - return (self.network_address.is_link_local and - self.broadcast_address.is_link_local) - - @property - def is_private(self): - """Test if this network belongs to a private range. - - Returns: - A boolean, True if the network is reserved per - iana-ipv4-special-registry or iana-ipv6-special-registry. - - """ - return any(self.network_address in priv_network and - self.broadcast_address in priv_network - for priv_network in self._constants._private_networks) - - @property - def is_global(self): - """Test if this address is allocated for public networks. - - Returns: - A boolean, True if the address is not reserved per - iana-ipv4-special-registry or iana-ipv6-special-registry. - - """ - return not self.is_private - - @property - def is_unspecified(self): - """Test if the address is unspecified. - - Returns: - A boolean, True if this is the unspecified address as defined in - RFC 2373 2.5.2. - - """ - return (self.network_address.is_unspecified and - self.broadcast_address.is_unspecified) - - @property - def is_loopback(self): - """Test if the address is a loopback address. - - Returns: - A boolean, True if the address is a loopback address as defined in - RFC 2373 2.5.3. - - """ - return (self.network_address.is_loopback and - self.broadcast_address.is_loopback) - - -class _BaseConstants: - - _private_networks = [] - - -_BaseNetwork._constants = _BaseConstants - - -class _BaseV4: - - """Base IPv4 object. - - The following methods are used by IPv4 objects in both single IP - addresses and networks. - - """ - - __slots__ = () - _version = 4 - # Equivalent to 255.255.255.255 or 32 bits of 1's. - _ALL_ONES = (2**IPV4LENGTH) - 1 - - _max_prefixlen = IPV4LENGTH - # There are only a handful of valid v4 netmasks, so we cache them all - # when constructed (see _make_netmask()). - _netmask_cache = {} - - def _explode_shorthand_ip_string(self): - return str(self) - - @classmethod - def _make_netmask(cls, arg): - """Make a (netmask, prefix_len) tuple from the given argument. - - Argument can be: - - an integer (the prefix length) - - a string representing the prefix length (e.g. "24") - - a string representing the prefix netmask (e.g. "255.255.255.0") - """ - if arg not in cls._netmask_cache: - if isinstance(arg, int): - prefixlen = arg - if not (0 <= prefixlen <= cls._max_prefixlen): - cls._report_invalid_netmask(prefixlen) - else: - try: - # Check for a netmask in prefix length form - prefixlen = cls._prefix_from_prefix_string(arg) - except NetmaskValueError: - # Check for a netmask or hostmask in dotted-quad form. - # This may raise NetmaskValueError. - prefixlen = cls._prefix_from_ip_string(arg) - netmask = IPv4Address(cls._ip_int_from_prefix(prefixlen)) - cls._netmask_cache[arg] = netmask, prefixlen - return cls._netmask_cache[arg] - - @classmethod - def _ip_int_from_string(cls, ip_str): - """Turn the given IP string into an integer for comparison. - - Args: - ip_str: A string, the IP ip_str. - - Returns: - The IP ip_str as an integer. - - Raises: - AddressValueError: if ip_str isn't a valid IPv4 Address. - - """ - if not ip_str: - raise AddressValueError('Address cannot be empty') - - octets = ip_str.split('.') - if len(octets) != 4: - raise AddressValueError("Expected 4 octets in %r" % ip_str) - - try: - return int.from_bytes(map(cls._parse_octet, octets), 'big') - except ValueError as exc: - raise AddressValueError("%s in %r" % (exc, ip_str)) from None - - @classmethod - def _parse_octet(cls, octet_str): - """Convert a decimal octet into an integer. - - Args: - octet_str: A string, the number to parse. - - Returns: - The octet as an integer. - - Raises: - ValueError: if the octet isn't strictly a decimal from [0..255]. - - """ - if not octet_str: - raise ValueError("Empty octet not permitted") - # Reject non-ASCII digits. - if not (octet_str.isascii() and octet_str.isdigit()): - msg = "Only decimal digits permitted in %r" - raise ValueError(msg % octet_str) - # We do the length check second, since the invalid character error - # is likely to be more informative for the user - if len(octet_str) > 3: - msg = "At most 3 characters permitted in %r" - raise ValueError(msg % octet_str) - # Handle leading zeros as strict as glibc's inet_pton() - # See security bug bpo-36384 - if octet_str != '0' and octet_str[0] == '0': - msg = "Leading zeros are not permitted in %r" - raise ValueError(msg % octet_str) - # Convert to integer (we know digits are legal) - octet_int = int(octet_str, 10) - if octet_int > 255: - raise ValueError("Octet %d (> 255) not permitted" % octet_int) - return octet_int - - @classmethod - def _string_from_ip_int(cls, ip_int): - """Turns a 32-bit integer into dotted decimal notation. - - Args: - ip_int: An integer, the IP address. - - Returns: - The IP address as a string in dotted decimal notation. - - """ - return '.'.join(map(str, ip_int.to_bytes(4, 'big'))) - - def _reverse_pointer(self): - """Return the reverse DNS pointer name for the IPv4 address. - - This implements the method described in RFC1035 3.5. - - """ - reverse_octets = str(self).split('.')[::-1] - return '.'.join(reverse_octets) + '.in-addr.arpa' - - @property - def max_prefixlen(self): - return self._max_prefixlen - - @property - def version(self): - return self._version - - -class IPv4Address(_BaseV4, _BaseAddress): - - """Represent and manipulate single IPv4 Addresses.""" - - __slots__ = ('_ip', '__weakref__') - - def __init__(self, address): - - """ - Args: - address: A string or integer representing the IP - - Additionally, an integer can be passed, so - IPv4Address('192.0.2.1') == IPv4Address(3221225985). - or, more generally - IPv4Address(int(IPv4Address('192.0.2.1'))) == - IPv4Address('192.0.2.1') - - Raises: - AddressValueError: If ipaddress isn't a valid IPv4 address. - - """ - # Efficient constructor from integer. - if isinstance(address, int): - self._check_int_address(address) - self._ip = address - return - - # Constructing from a packed address - if isinstance(address, bytes): - self._check_packed_address(address, 4) - self._ip = int.from_bytes(address) # big endian - return - - # Assume input argument to be string or any object representation - # which converts into a formatted IP string. - addr_str = str(address) - if '/' in addr_str: - raise AddressValueError(f"Unexpected '/' in {address!r}") - self._ip = self._ip_int_from_string(addr_str) - - @property - def packed(self): - """The binary representation of this address.""" - return v4_int_to_packed(self._ip) - - @property - def is_reserved(self): - """Test if the address is otherwise IETF reserved. - - Returns: - A boolean, True if the address is within the - reserved IPv4 Network range. - - """ - return self in self._constants._reserved_network - - @property - @functools.lru_cache() - def is_private(self): - """Test if this address is allocated for private networks. - - Returns: - A boolean, True if the address is reserved per - iana-ipv4-special-registry. - - """ - return any(self in net for net in self._constants._private_networks) - - @property - @functools.lru_cache() - def is_global(self): - return self not in self._constants._public_network and not self.is_private - - @property - def is_multicast(self): - """Test if the address is reserved for multicast use. - - Returns: - A boolean, True if the address is multicast. - See RFC 3171 for details. - - """ - return self in self._constants._multicast_network - - @property - def is_unspecified(self): - """Test if the address is unspecified. - - Returns: - A boolean, True if this is the unspecified address as defined in - RFC 5735 3. - - """ - return self == self._constants._unspecified_address - - @property - def is_loopback(self): - """Test if the address is a loopback address. - - Returns: - A boolean, True if the address is a loopback per RFC 3330. - - """ - return self in self._constants._loopback_network - - @property - def is_link_local(self): - """Test if the address is reserved for link-local. - - Returns: - A boolean, True if the address is link-local per RFC 3927. - - """ - return self in self._constants._linklocal_network - - -class IPv4Interface(IPv4Address): - - def __init__(self, address): - addr, mask = self._split_addr_prefix(address) - - IPv4Address.__init__(self, addr) - self.network = IPv4Network((addr, mask), strict=False) - self.netmask = self.network.netmask - self._prefixlen = self.network._prefixlen - - @functools.cached_property - def hostmask(self): - return self.network.hostmask - - def __str__(self): - return '%s/%d' % (self._string_from_ip_int(self._ip), - self._prefixlen) - - def __eq__(self, other): - address_equal = IPv4Address.__eq__(self, other) - if address_equal is NotImplemented or not address_equal: - return address_equal - try: - return self.network == other.network - except AttributeError: - # An interface with an associated network is NOT the - # same as an unassociated address. That's why the hash - # takes the extra info into account. - return False - - def __lt__(self, other): - address_less = IPv4Address.__lt__(self, other) - if address_less is NotImplemented: - return NotImplemented - try: - return (self.network < other.network or - self.network == other.network and address_less) - except AttributeError: - # We *do* allow addresses and interfaces to be sorted. The - # unassociated address is considered less than all interfaces. - return False - - def __hash__(self): - return hash((self._ip, self._prefixlen, int(self.network.network_address))) - - __reduce__ = _IPAddressBase.__reduce__ - - @property - def ip(self): - return IPv4Address(self._ip) - - @property - def with_prefixlen(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self._prefixlen) - - @property - def with_netmask(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self.netmask) - - @property - def with_hostmask(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self.hostmask) - - -class IPv4Network(_BaseV4, _BaseNetwork): - - """This class represents and manipulates 32-bit IPv4 network + addresses.. - - Attributes: [examples for IPv4Network('192.0.2.0/27')] - .network_address: IPv4Address('192.0.2.0') - .hostmask: IPv4Address('0.0.0.31') - .broadcast_address: IPv4Address('192.0.2.32') - .netmask: IPv4Address('255.255.255.224') - .prefixlen: 27 - - """ - # Class to use when creating address objects - _address_class = IPv4Address - - def __init__(self, address, strict=True): - """Instantiate a new IPv4 network object. - - Args: - address: A string or integer representing the IP [& network]. - '192.0.2.0/24' - '192.0.2.0/255.255.255.0' - '192.0.2.0/0.0.0.255' - are all functionally the same in IPv4. Similarly, - '192.0.2.1' - '192.0.2.1/255.255.255.255' - '192.0.2.1/32' - are also functionally equivalent. That is to say, failing to - provide a subnetmask will create an object with a mask of /32. - - If the mask (portion after the / in the argument) is given in - dotted quad form, it is treated as a netmask if it starts with a - non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it - starts with a zero field (e.g. 0.255.255.255 == /8), with the - single exception of an all-zero mask which is treated as a - netmask == /0. If no mask is given, a default of /32 is used. - - Additionally, an integer can be passed, so - IPv4Network('192.0.2.1') == IPv4Network(3221225985) - or, more generally - IPv4Interface(int(IPv4Interface('192.0.2.1'))) == - IPv4Interface('192.0.2.1') - - Raises: - AddressValueError: If ipaddress isn't a valid IPv4 address. - NetmaskValueError: If the netmask isn't valid for - an IPv4 address. - ValueError: If strict is True and a network address is not - supplied. - """ - addr, mask = self._split_addr_prefix(address) - - self.network_address = IPv4Address(addr) - self.netmask, self._prefixlen = self._make_netmask(mask) - packed = int(self.network_address) - if packed & int(self.netmask) != packed: - if strict: - raise ValueError('%s has host bits set' % self) - else: - self.network_address = IPv4Address(packed & - int(self.netmask)) - - if self._prefixlen == (self._max_prefixlen - 1): - self.hosts = self.__iter__ - elif self._prefixlen == (self._max_prefixlen): - self.hosts = lambda: [IPv4Address(addr)] - - @property - @functools.lru_cache() - def is_global(self): - """Test if this address is allocated for public networks. - - Returns: - A boolean, True if the address is not reserved per - iana-ipv4-special-registry. - - """ - return (not (self.network_address in IPv4Network('100.64.0.0/10') and - self.broadcast_address in IPv4Network('100.64.0.0/10')) and - not self.is_private) - - -class _IPv4Constants: - _linklocal_network = IPv4Network('169.254.0.0/16') - - _loopback_network = IPv4Network('127.0.0.0/8') - - _multicast_network = IPv4Network('224.0.0.0/4') - - _public_network = IPv4Network('100.64.0.0/10') - - _private_networks = [ - IPv4Network('0.0.0.0/8'), - IPv4Network('10.0.0.0/8'), - IPv4Network('127.0.0.0/8'), - IPv4Network('169.254.0.0/16'), - IPv4Network('172.16.0.0/12'), - IPv4Network('192.0.0.0/29'), - IPv4Network('192.0.0.170/31'), - IPv4Network('192.0.2.0/24'), - IPv4Network('192.168.0.0/16'), - IPv4Network('198.18.0.0/15'), - IPv4Network('198.51.100.0/24'), - IPv4Network('203.0.113.0/24'), - IPv4Network('240.0.0.0/4'), - IPv4Network('255.255.255.255/32'), - ] - - _reserved_network = IPv4Network('240.0.0.0/4') - - _unspecified_address = IPv4Address('0.0.0.0') - - -IPv4Address._constants = _IPv4Constants -IPv4Network._constants = _IPv4Constants - - -class _BaseV6: - - """Base IPv6 object. - - The following methods are used by IPv6 objects in both single IP - addresses and networks. - - """ - - __slots__ = () - _version = 6 - _ALL_ONES = (2**IPV6LENGTH) - 1 - _HEXTET_COUNT = 8 - _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') - _max_prefixlen = IPV6LENGTH - - # There are only a bunch of valid v6 netmasks, so we cache them all - # when constructed (see _make_netmask()). - _netmask_cache = {} - - @classmethod - def _make_netmask(cls, arg): - """Make a (netmask, prefix_len) tuple from the given argument. - - Argument can be: - - an integer (the prefix length) - - a string representing the prefix length (e.g. "24") - - a string representing the prefix netmask (e.g. "255.255.255.0") - """ - if arg not in cls._netmask_cache: - if isinstance(arg, int): - prefixlen = arg - if not (0 <= prefixlen <= cls._max_prefixlen): - cls._report_invalid_netmask(prefixlen) - else: - prefixlen = cls._prefix_from_prefix_string(arg) - netmask = IPv6Address(cls._ip_int_from_prefix(prefixlen)) - cls._netmask_cache[arg] = netmask, prefixlen - return cls._netmask_cache[arg] - - @classmethod - def _ip_int_from_string(cls, ip_str): - """Turn an IPv6 ip_str into an integer. - - Args: - ip_str: A string, the IPv6 ip_str. - - Returns: - An int, the IPv6 address - - Raises: - AddressValueError: if ip_str isn't a valid IPv6 Address. - - """ - if not ip_str: - raise AddressValueError('Address cannot be empty') - - parts = ip_str.split(':') - - # An IPv6 address needs at least 2 colons (3 parts). - _min_parts = 3 - if len(parts) < _min_parts: - msg = "At least %d parts expected in %r" % (_min_parts, ip_str) - raise AddressValueError(msg) - - # If the address has an IPv4-style suffix, convert it to hexadecimal. - if '.' in parts[-1]: - try: - ipv4_int = IPv4Address(parts.pop())._ip - except AddressValueError as exc: - raise AddressValueError("%s in %r" % (exc, ip_str)) from None - parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF)) - parts.append('%x' % (ipv4_int & 0xFFFF)) - - # An IPv6 address can't have more than 8 colons (9 parts). - # The extra colon comes from using the "::" notation for a single - # leading or trailing zero part. - _max_parts = cls._HEXTET_COUNT + 1 - if len(parts) > _max_parts: - msg = "At most %d colons permitted in %r" % (_max_parts-1, ip_str) - raise AddressValueError(msg) - - # Disregarding the endpoints, find '::' with nothing in between. - # This indicates that a run of zeroes has been skipped. - skip_index = None - for i in range(1, len(parts) - 1): - if not parts[i]: - if skip_index is not None: - # Can't have more than one '::' - msg = "At most one '::' permitted in %r" % ip_str - raise AddressValueError(msg) - skip_index = i - - # parts_hi is the number of parts to copy from above/before the '::' - # parts_lo is the number of parts to copy from below/after the '::' - if skip_index is not None: - # If we found a '::', then check if it also covers the endpoints. - parts_hi = skip_index - parts_lo = len(parts) - skip_index - 1 - if not parts[0]: - parts_hi -= 1 - if parts_hi: - msg = "Leading ':' only permitted as part of '::' in %r" - raise AddressValueError(msg % ip_str) # ^: requires ^:: - if not parts[-1]: - parts_lo -= 1 - if parts_lo: - msg = "Trailing ':' only permitted as part of '::' in %r" - raise AddressValueError(msg % ip_str) # :$ requires ::$ - parts_skipped = cls._HEXTET_COUNT - (parts_hi + parts_lo) - if parts_skipped < 1: - msg = "Expected at most %d other parts with '::' in %r" - raise AddressValueError(msg % (cls._HEXTET_COUNT-1, ip_str)) - else: - # Otherwise, allocate the entire address to parts_hi. The - # endpoints could still be empty, but _parse_hextet() will check - # for that. - if len(parts) != cls._HEXTET_COUNT: - msg = "Exactly %d parts expected without '::' in %r" - raise AddressValueError(msg % (cls._HEXTET_COUNT, ip_str)) - if not parts[0]: - msg = "Leading ':' only permitted as part of '::' in %r" - raise AddressValueError(msg % ip_str) # ^: requires ^:: - if not parts[-1]: - msg = "Trailing ':' only permitted as part of '::' in %r" - raise AddressValueError(msg % ip_str) # :$ requires ::$ - parts_hi = len(parts) - parts_lo = 0 - parts_skipped = 0 - - try: - # Now, parse the hextets into a 128-bit integer. - ip_int = 0 - for i in range(parts_hi): - ip_int <<= 16 - ip_int |= cls._parse_hextet(parts[i]) - ip_int <<= 16 * parts_skipped - for i in range(-parts_lo, 0): - ip_int <<= 16 - ip_int |= cls._parse_hextet(parts[i]) - return ip_int - except ValueError as exc: - raise AddressValueError("%s in %r" % (exc, ip_str)) from None - - @classmethod - def _parse_hextet(cls, hextet_str): - """Convert an IPv6 hextet string into an integer. - - Args: - hextet_str: A string, the number to parse. - - Returns: - The hextet as an integer. - - Raises: - ValueError: if the input isn't strictly a hex number from - [0..FFFF]. - - """ - # Reject non-ASCII digits. - if not cls._HEX_DIGITS.issuperset(hextet_str): - raise ValueError("Only hex digits permitted in %r" % hextet_str) - # We do the length check second, since the invalid character error - # is likely to be more informative for the user - if len(hextet_str) > 4: - msg = "At most 4 characters permitted in %r" - raise ValueError(msg % hextet_str) - # Length check means we can skip checking the integer value - return int(hextet_str, 16) - - @classmethod - def _compress_hextets(cls, hextets): - """Compresses a list of hextets. - - Compresses a list of strings, replacing the longest continuous - sequence of "0" in the list with "" and adding empty strings at - the beginning or at the end of the string such that subsequently - calling ":".join(hextets) will produce the compressed version of - the IPv6 address. - - Args: - hextets: A list of strings, the hextets to compress. - - Returns: - A list of strings. - - """ - best_doublecolon_start = -1 - best_doublecolon_len = 0 - doublecolon_start = -1 - doublecolon_len = 0 - for index, hextet in enumerate(hextets): - if hextet == '0': - doublecolon_len += 1 - if doublecolon_start == -1: - # Start of a sequence of zeros. - doublecolon_start = index - if doublecolon_len > best_doublecolon_len: - # This is the longest sequence of zeros so far. - best_doublecolon_len = doublecolon_len - best_doublecolon_start = doublecolon_start - else: - doublecolon_len = 0 - doublecolon_start = -1 - - if best_doublecolon_len > 1: - best_doublecolon_end = (best_doublecolon_start + - best_doublecolon_len) - # For zeros at the end of the address. - if best_doublecolon_end == len(hextets): - hextets += [''] - hextets[best_doublecolon_start:best_doublecolon_end] = [''] - # For zeros at the beginning of the address. - if best_doublecolon_start == 0: - hextets = [''] + hextets - - return hextets - - @classmethod - def _string_from_ip_int(cls, ip_int=None): - """Turns a 128-bit integer into hexadecimal notation. - - Args: - ip_int: An integer, the IP address. - - Returns: - A string, the hexadecimal representation of the address. - - Raises: - ValueError: The address is bigger than 128 bits of all ones. - - """ - if ip_int is None: - ip_int = int(cls._ip) - - if ip_int > cls._ALL_ONES: - raise ValueError('IPv6 address is too large') - - hex_str = '%032x' % ip_int - hextets = ['%x' % int(hex_str[x:x+4], 16) for x in range(0, 32, 4)] - - hextets = cls._compress_hextets(hextets) - return ':'.join(hextets) - - def _explode_shorthand_ip_string(self): - """Expand a shortened IPv6 address. - - Args: - ip_str: A string, the IPv6 address. - - Returns: - A string, the expanded IPv6 address. - - """ - if isinstance(self, IPv6Network): - ip_str = str(self.network_address) - elif isinstance(self, IPv6Interface): - ip_str = str(self.ip) - else: - ip_str = str(self) - - ip_int = self._ip_int_from_string(ip_str) - hex_str = '%032x' % ip_int - parts = [hex_str[x:x+4] for x in range(0, 32, 4)] - if isinstance(self, (_BaseNetwork, IPv6Interface)): - return '%s/%d' % (':'.join(parts), self._prefixlen) - return ':'.join(parts) - - def _reverse_pointer(self): - """Return the reverse DNS pointer name for the IPv6 address. - - This implements the method described in RFC3596 2.5. - - """ - reverse_chars = self.exploded[::-1].replace(':', '') - return '.'.join(reverse_chars) + '.ip6.arpa' - - @staticmethod - def _split_scope_id(ip_str): - """Helper function to parse IPv6 string address with scope id. - - See RFC 4007 for details. - - Args: - ip_str: A string, the IPv6 address. - - Returns: - (addr, scope_id) tuple. - - """ - addr, sep, scope_id = ip_str.partition('%') - if not sep: - scope_id = None - elif not scope_id or '%' in scope_id: - raise AddressValueError('Invalid IPv6 address: "%r"' % ip_str) - return addr, scope_id - - @property - def max_prefixlen(self): - return self._max_prefixlen - - @property - def version(self): - return self._version - - -class IPv6Address(_BaseV6, _BaseAddress): - - """Represent and manipulate single IPv6 Addresses.""" - - __slots__ = ('_ip', '_scope_id', '__weakref__') - - def __init__(self, address): - """Instantiate a new IPv6 address object. - - Args: - address: A string or integer representing the IP - - Additionally, an integer can be passed, so - IPv6Address('2001:db8::') == - IPv6Address(42540766411282592856903984951653826560) - or, more generally - IPv6Address(int(IPv6Address('2001:db8::'))) == - IPv6Address('2001:db8::') - - Raises: - AddressValueError: If address isn't a valid IPv6 address. - - """ - # Efficient constructor from integer. - if isinstance(address, int): - self._check_int_address(address) - self._ip = address - self._scope_id = None - return - - # Constructing from a packed address - if isinstance(address, bytes): - self._check_packed_address(address, 16) - self._ip = int.from_bytes(address, 'big') - self._scope_id = None - return - - # Assume input argument to be string or any object representation - # which converts into a formatted IP string. - addr_str = str(address) - if '/' in addr_str: - raise AddressValueError(f"Unexpected '/' in {address!r}") - addr_str, self._scope_id = self._split_scope_id(addr_str) - - self._ip = self._ip_int_from_string(addr_str) - - def __str__(self): - ip_str = super().__str__() - return ip_str + '%' + self._scope_id if self._scope_id else ip_str - - def __hash__(self): - return hash((self._ip, self._scope_id)) - - def __eq__(self, other): - address_equal = super().__eq__(other) - if address_equal is NotImplemented: - return NotImplemented - if not address_equal: - return False - return self._scope_id == getattr(other, '_scope_id', None) - - @property - def scope_id(self): - """Identifier of a particular zone of the address's scope. - - See RFC 4007 for details. - - Returns: - A string identifying the zone of the address if specified, else None. - - """ - return self._scope_id - - @property - def packed(self): - """The binary representation of this address.""" - return v6_int_to_packed(self._ip) - - @property - def is_multicast(self): - """Test if the address is reserved for multicast use. - - Returns: - A boolean, True if the address is a multicast address. - See RFC 2373 2.7 for details. - - """ - return self in self._constants._multicast_network - - @property - def is_reserved(self): - """Test if the address is otherwise IETF reserved. - - Returns: - A boolean, True if the address is within one of the - reserved IPv6 Network ranges. - - """ - return any(self in x for x in self._constants._reserved_networks) - - @property - def is_link_local(self): - """Test if the address is reserved for link-local. - - Returns: - A boolean, True if the address is reserved per RFC 4291. - - """ - return self in self._constants._linklocal_network - - @property - def is_site_local(self): - """Test if the address is reserved for site-local. - - Note that the site-local address space has been deprecated by RFC 3879. - Use is_private to test if this address is in the space of unique local - addresses as defined by RFC 4193. - - Returns: - A boolean, True if the address is reserved per RFC 3513 2.5.6. - - """ - return self in self._constants._sitelocal_network - - @property - @functools.lru_cache() - def is_private(self): - """Test if this address is allocated for private networks. - - Returns: - A boolean, True if the address is reserved per - iana-ipv6-special-registry, or is ipv4_mapped and is - reserved in the iana-ipv4-special-registry. - - """ - ipv4_mapped = self.ipv4_mapped - if ipv4_mapped is not None: - return ipv4_mapped.is_private - return any(self in net for net in self._constants._private_networks) - - @property - def is_global(self): - """Test if this address is allocated for public networks. - - Returns: - A boolean, true if the address is not reserved per - iana-ipv6-special-registry. - - """ - return not self.is_private - - @property - def is_unspecified(self): - """Test if the address is unspecified. - - Returns: - A boolean, True if this is the unspecified address as defined in - RFC 2373 2.5.2. - - """ - return self._ip == 0 - - @property - def is_loopback(self): - """Test if the address is a loopback address. - - Returns: - A boolean, True if the address is a loopback address as defined in - RFC 2373 2.5.3. - - """ - return self._ip == 1 - - @property - def ipv4_mapped(self): - """Return the IPv4 mapped address. - - Returns: - If the IPv6 address is a v4 mapped address, return the - IPv4 mapped address. Return None otherwise. - - """ - if (self._ip >> 32) != 0xFFFF: - return None - return IPv4Address(self._ip & 0xFFFFFFFF) - - @property - def teredo(self): - """Tuple of embedded teredo IPs. - - Returns: - Tuple of the (server, client) IPs or None if the address - doesn't appear to be a teredo address (doesn't start with - 2001::/32) - - """ - if (self._ip >> 96) != 0x20010000: - return None - return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF), - IPv4Address(~self._ip & 0xFFFFFFFF)) - - @property - def sixtofour(self): - """Return the IPv4 6to4 embedded address. - - Returns: - The IPv4 6to4-embedded address if present or None if the - address doesn't appear to contain a 6to4 embedded address. - - """ - if (self._ip >> 112) != 0x2002: - return None - return IPv4Address((self._ip >> 80) & 0xFFFFFFFF) - - -class IPv6Interface(IPv6Address): - - def __init__(self, address): - addr, mask = self._split_addr_prefix(address) - - IPv6Address.__init__(self, addr) - self.network = IPv6Network((addr, mask), strict=False) - self.netmask = self.network.netmask - self._prefixlen = self.network._prefixlen - - @functools.cached_property - def hostmask(self): - return self.network.hostmask - - def __str__(self): - return '%s/%d' % (super().__str__(), - self._prefixlen) - - def __eq__(self, other): - address_equal = IPv6Address.__eq__(self, other) - if address_equal is NotImplemented or not address_equal: - return address_equal - try: - return self.network == other.network - except AttributeError: - # An interface with an associated network is NOT the - # same as an unassociated address. That's why the hash - # takes the extra info into account. - return False - - def __lt__(self, other): - address_less = IPv6Address.__lt__(self, other) - if address_less is NotImplemented: - return address_less - try: - return (self.network < other.network or - self.network == other.network and address_less) - except AttributeError: - # We *do* allow addresses and interfaces to be sorted. The - # unassociated address is considered less than all interfaces. - return False - - def __hash__(self): - return hash((self._ip, self._prefixlen, int(self.network.network_address))) - - __reduce__ = _IPAddressBase.__reduce__ - - @property - def ip(self): - return IPv6Address(self._ip) - - @property - def with_prefixlen(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self._prefixlen) - - @property - def with_netmask(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self.netmask) - - @property - def with_hostmask(self): - return '%s/%s' % (self._string_from_ip_int(self._ip), - self.hostmask) - - @property - def is_unspecified(self): - return self._ip == 0 and self.network.is_unspecified - - @property - def is_loopback(self): - return self._ip == 1 and self.network.is_loopback - - -class IPv6Network(_BaseV6, _BaseNetwork): - - """This class represents and manipulates 128-bit IPv6 networks. - - Attributes: [examples for IPv6('2001:db8::1000/124')] - .network_address: IPv6Address('2001:db8::1000') - .hostmask: IPv6Address('::f') - .broadcast_address: IPv6Address('2001:db8::100f') - .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0') - .prefixlen: 124 - - """ - - # Class to use when creating address objects - _address_class = IPv6Address - - def __init__(self, address, strict=True): - """Instantiate a new IPv6 Network object. - - Args: - address: A string or integer representing the IPv6 network or the - IP and prefix/netmask. - '2001:db8::/128' - '2001:db8:0000:0000:0000:0000:0000:0000/128' - '2001:db8::' - are all functionally the same in IPv6. That is to say, - failing to provide a subnetmask will create an object with - a mask of /128. - - Additionally, an integer can be passed, so - IPv6Network('2001:db8::') == - IPv6Network(42540766411282592856903984951653826560) - or, more generally - IPv6Network(int(IPv6Network('2001:db8::'))) == - IPv6Network('2001:db8::') - - strict: A boolean. If true, ensure that we have been passed - A true network address, eg, 2001:db8::1000/124 and not an - IP address on a network, eg, 2001:db8::1/124. - - Raises: - AddressValueError: If address isn't a valid IPv6 address. - NetmaskValueError: If the netmask isn't valid for - an IPv6 address. - ValueError: If strict was True and a network address was not - supplied. - """ - addr, mask = self._split_addr_prefix(address) - - self.network_address = IPv6Address(addr) - self.netmask, self._prefixlen = self._make_netmask(mask) - packed = int(self.network_address) - if packed & int(self.netmask) != packed: - if strict: - raise ValueError('%s has host bits set' % self) - else: - self.network_address = IPv6Address(packed & - int(self.netmask)) - - if self._prefixlen == (self._max_prefixlen - 1): - self.hosts = self.__iter__ - elif self._prefixlen == self._max_prefixlen: - self.hosts = lambda: [IPv6Address(addr)] - - def hosts(self): - """Generate Iterator over usable hosts in a network. - - This is like __iter__ except it doesn't return the - Subnet-Router anycast address. - - """ - network = int(self.network_address) - broadcast = int(self.broadcast_address) - for x in range(network + 1, broadcast + 1): - yield self._address_class(x) - - @property - def is_site_local(self): - """Test if the address is reserved for site-local. - - Note that the site-local address space has been deprecated by RFC 3879. - Use is_private to test if this address is in the space of unique local - addresses as defined by RFC 4193. - - Returns: - A boolean, True if the address is reserved per RFC 3513 2.5.6. - - """ - return (self.network_address.is_site_local and - self.broadcast_address.is_site_local) - - -class _IPv6Constants: - - _linklocal_network = IPv6Network('fe80::/10') - - _multicast_network = IPv6Network('ff00::/8') - - _private_networks = [ - IPv6Network('::1/128'), - IPv6Network('::/128'), - IPv6Network('::ffff:0:0/96'), - IPv6Network('100::/64'), - IPv6Network('2001::/23'), - IPv6Network('2001:2::/48'), - IPv6Network('2001:db8::/32'), - IPv6Network('2001:10::/28'), - IPv6Network('fc00::/7'), - IPv6Network('fe80::/10'), - ] - - _reserved_networks = [ - IPv6Network('::/8'), IPv6Network('100::/8'), - IPv6Network('200::/7'), IPv6Network('400::/6'), - IPv6Network('800::/5'), IPv6Network('1000::/4'), - IPv6Network('4000::/3'), IPv6Network('6000::/3'), - IPv6Network('8000::/3'), IPv6Network('A000::/3'), - IPv6Network('C000::/3'), IPv6Network('E000::/4'), - IPv6Network('F000::/5'), IPv6Network('F800::/6'), - IPv6Network('FE00::/9'), - ] - - _sitelocal_network = IPv6Network('fec0::/10') - - -IPv6Address._constants = _IPv6Constants -IPv6Network._constants = _IPv6Constants diff --git a/python/Lib/json/__init__.py b/python/Lib/json/__init__.py deleted file mode 100644 index 4aa14c4..0000000 --- a/python/Lib/json/__init__.py +++ /dev/null @@ -1,359 +0,0 @@ -r"""JSON (JavaScript Object Notation) is a subset of -JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data -interchange format. - -:mod:`json` exposes an API familiar to users of the standard library -:mod:`marshal` and :mod:`pickle` modules. It is derived from a -version of the externally maintained simplejson library. - -Encoding basic Python object hierarchies:: - - >>> import json - >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) - '["foo", {"bar": ["baz", null, 1.0, 2]}]' - >>> print(json.dumps("\"foo\bar")) - "\"foo\bar" - >>> print(json.dumps('\u1234')) - "\u1234" - >>> print(json.dumps('\\')) - "\\" - >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)) - {"a": 0, "b": 0, "c": 0} - >>> from io import StringIO - >>> io = StringIO() - >>> json.dump(['streaming API'], io) - >>> io.getvalue() - '["streaming API"]' - -Compact encoding:: - - >>> import json - >>> mydict = {'4': 5, '6': 7} - >>> json.dumps([1,2,3,mydict], separators=(',', ':')) - '[1,2,3,{"4":5,"6":7}]' - -Pretty printing:: - - >>> import json - >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)) - { - "4": 5, - "6": 7 - } - -Decoding JSON:: - - >>> import json - >>> obj = ['foo', {'bar': ['baz', None, 1.0, 2]}] - >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj - True - >>> json.loads('"\\"foo\\bar"') == '"foo\x08ar' - True - >>> from io import StringIO - >>> io = StringIO('["streaming API"]') - >>> json.load(io)[0] == 'streaming API' - True - -Specializing JSON object decoding:: - - >>> import json - >>> def as_complex(dct): - ... if '__complex__' in dct: - ... return complex(dct['real'], dct['imag']) - ... return dct - ... - >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', - ... object_hook=as_complex) - (1+2j) - >>> from decimal import Decimal - >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') - True - -Specializing JSON object encoding:: - - >>> import json - >>> def encode_complex(obj): - ... if isinstance(obj, complex): - ... return [obj.real, obj.imag] - ... raise TypeError(f'Object of type {obj.__class__.__name__} ' - ... f'is not JSON serializable') - ... - >>> json.dumps(2 + 1j, default=encode_complex) - '[2.0, 1.0]' - >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) - '[2.0, 1.0]' - >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) - '[2.0, 1.0]' - - -Using json.tool from the shell to validate and pretty-print:: - - $ echo '{"json":"obj"}' | python -m json.tool - { - "json": "obj" - } - $ echo '{ 1.2:3.4}' | python -m json.tool - Expecting property name enclosed in double quotes: line 1 column 3 (char 2) -""" -__version__ = '2.0.9' -__all__ = [ - 'dump', 'dumps', 'load', 'loads', - 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', -] - -__author__ = 'Bob Ippolito ' - -from .decoder import JSONDecoder, JSONDecodeError -from .encoder import JSONEncoder -import codecs - -_default_encoder = JSONEncoder( - skipkeys=False, - ensure_ascii=True, - check_circular=True, - allow_nan=True, - indent=None, - separators=None, - default=None, -) - -def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, - allow_nan=True, cls=None, indent=None, separators=None, - default=None, sort_keys=False, **kw): - """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a - ``.write()``-supporting file-like object). - - If ``skipkeys`` is true then ``dict`` keys that are not basic types - (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped - instead of raising a ``TypeError``. - - If ``ensure_ascii`` is false, then the strings written to ``fp`` can - contain non-ASCII characters if they appear in strings contained in - ``obj``. Otherwise, all such characters are escaped in JSON strings. - - If ``check_circular`` is false, then the circular reference check - for container types will be skipped and a circular reference will - result in an ``RecursionError`` (or worse). - - If ``allow_nan`` is false, then it will be a ``ValueError`` to - serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) - in strict compliance of the JSON specification, instead of using the - JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). - - If ``indent`` is a non-negative integer, then JSON array elements and - object members will be pretty-printed with that indent level. An indent - level of 0 will only insert newlines. ``None`` is the most compact - representation. - - If specified, ``separators`` should be an ``(item_separator, key_separator)`` - tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and - ``(',', ': ')`` otherwise. To get the most compact JSON representation, - you should specify ``(',', ':')`` to eliminate whitespace. - - ``default(obj)`` is a function that should return a serializable version - of obj or raise TypeError. The default simply raises TypeError. - - If *sort_keys* is true (default: ``False``), then the output of - dictionaries will be sorted by key. - - To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the - ``.default()`` method to serialize additional types), specify it with - the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. - - """ - # cached encoder - if (not skipkeys and ensure_ascii and - check_circular and allow_nan and - cls is None and indent is None and separators is None and - default is None and not sort_keys and not kw): - iterable = _default_encoder.iterencode(obj) - else: - if cls is None: - cls = JSONEncoder - iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, - check_circular=check_circular, allow_nan=allow_nan, indent=indent, - separators=separators, - default=default, sort_keys=sort_keys, **kw).iterencode(obj) - # could accelerate with writelines in some versions of Python, at - # a debuggability cost - for chunk in iterable: - fp.write(chunk) - - -def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, - allow_nan=True, cls=None, indent=None, separators=None, - default=None, sort_keys=False, **kw): - """Serialize ``obj`` to a JSON formatted ``str``. - - If ``skipkeys`` is true then ``dict`` keys that are not basic types - (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped - instead of raising a ``TypeError``. - - If ``ensure_ascii`` is false, then the return value can contain non-ASCII - characters if they appear in strings contained in ``obj``. Otherwise, all - such characters are escaped in JSON strings. - - If ``check_circular`` is false, then the circular reference check - for container types will be skipped and a circular reference will - result in an ``RecursionError`` (or worse). - - If ``allow_nan`` is false, then it will be a ``ValueError`` to - serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in - strict compliance of the JSON specification, instead of using the - JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). - - If ``indent`` is a non-negative integer, then JSON array elements and - object members will be pretty-printed with that indent level. An indent - level of 0 will only insert newlines. ``None`` is the most compact - representation. - - If specified, ``separators`` should be an ``(item_separator, key_separator)`` - tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and - ``(',', ': ')`` otherwise. To get the most compact JSON representation, - you should specify ``(',', ':')`` to eliminate whitespace. - - ``default(obj)`` is a function that should return a serializable version - of obj or raise TypeError. The default simply raises TypeError. - - If *sort_keys* is true (default: ``False``), then the output of - dictionaries will be sorted by key. - - To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the - ``.default()`` method to serialize additional types), specify it with - the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. - - """ - # cached encoder - if (not skipkeys and ensure_ascii and - check_circular and allow_nan and - cls is None and indent is None and separators is None and - default is None and not sort_keys and not kw): - return _default_encoder.encode(obj) - if cls is None: - cls = JSONEncoder - return cls( - skipkeys=skipkeys, ensure_ascii=ensure_ascii, - check_circular=check_circular, allow_nan=allow_nan, indent=indent, - separators=separators, default=default, sort_keys=sort_keys, - **kw).encode(obj) - - -_default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None) - - -def detect_encoding(b): - bstartswith = b.startswith - if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)): - return 'utf-32' - if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)): - return 'utf-16' - if bstartswith(codecs.BOM_UTF8): - return 'utf-8-sig' - - if len(b) >= 4: - if not b[0]: - # 00 00 -- -- - utf-32-be - # 00 XX -- -- - utf-16-be - return 'utf-16-be' if b[1] else 'utf-32-be' - if not b[1]: - # XX 00 00 00 - utf-32-le - # XX 00 00 XX - utf-16-le - # XX 00 XX -- - utf-16-le - return 'utf-16-le' if b[2] or b[3] else 'utf-32-le' - elif len(b) == 2: - if not b[0]: - # 00 XX - utf-16-be - return 'utf-16-be' - if not b[1]: - # XX 00 - utf-16-le - return 'utf-16-le' - # default - return 'utf-8' - - -def load(fp, *, cls=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): - """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing - a JSON document) to a Python object. - - ``object_hook`` is an optional function that will be called with the - result of any object literal decode (a ``dict``). The return value of - ``object_hook`` will be used instead of the ``dict``. This feature - can be used to implement custom decoders (e.g. JSON-RPC class hinting). - - ``object_pairs_hook`` is an optional function that will be called with the - result of any object literal decoded with an ordered list of pairs. The - return value of ``object_pairs_hook`` will be used instead of the ``dict``. - This feature can be used to implement custom decoders. If ``object_hook`` - is also defined, the ``object_pairs_hook`` takes priority. - - To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` - kwarg; otherwise ``JSONDecoder`` is used. - """ - return loads(fp.read(), - cls=cls, object_hook=object_hook, - parse_float=parse_float, parse_int=parse_int, - parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) - - -def loads(s, *, cls=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): - """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance - containing a JSON document) to a Python object. - - ``object_hook`` is an optional function that will be called with the - result of any object literal decode (a ``dict``). The return value of - ``object_hook`` will be used instead of the ``dict``. This feature - can be used to implement custom decoders (e.g. JSON-RPC class hinting). - - ``object_pairs_hook`` is an optional function that will be called with the - result of any object literal decoded with an ordered list of pairs. The - return value of ``object_pairs_hook`` will be used instead of the ``dict``. - This feature can be used to implement custom decoders. If ``object_hook`` - is also defined, the ``object_pairs_hook`` takes priority. - - ``parse_float``, if specified, will be called with the string - of every JSON float to be decoded. By default this is equivalent to - float(num_str). This can be used to use another datatype or parser - for JSON floats (e.g. decimal.Decimal). - - ``parse_int``, if specified, will be called with the string - of every JSON int to be decoded. By default this is equivalent to - int(num_str). This can be used to use another datatype or parser - for JSON integers (e.g. float). - - ``parse_constant``, if specified, will be called with one of the - following strings: -Infinity, Infinity, NaN. - This can be used to raise an exception if invalid JSON numbers - are encountered. - - To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` - kwarg; otherwise ``JSONDecoder`` is used. - """ - if isinstance(s, str): - if s.startswith('\ufeff'): - raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", - s, 0) - else: - if not isinstance(s, (bytes, bytearray)): - raise TypeError(f'the JSON object must be str, bytes or bytearray, ' - f'not {s.__class__.__name__}') - s = s.decode(detect_encoding(s), 'surrogatepass') - - if (cls is None and object_hook is None and - parse_int is None and parse_float is None and - parse_constant is None and object_pairs_hook is None and not kw): - return _default_decoder.decode(s) - if cls is None: - cls = JSONDecoder - if object_hook is not None: - kw['object_hook'] = object_hook - if object_pairs_hook is not None: - kw['object_pairs_hook'] = object_pairs_hook - if parse_float is not None: - kw['parse_float'] = parse_float - if parse_int is not None: - kw['parse_int'] = parse_int - if parse_constant is not None: - kw['parse_constant'] = parse_constant - return cls(**kw).decode(s) diff --git a/python/Lib/json/decoder.py b/python/Lib/json/decoder.py deleted file mode 100644 index d66a24c..0000000 --- a/python/Lib/json/decoder.py +++ /dev/null @@ -1,356 +0,0 @@ -"""Implementation of JSONDecoder -""" -import re - -from json import scanner -try: - from _json import scanstring as c_scanstring -except ImportError: - c_scanstring = None - -__all__ = ['JSONDecoder', 'JSONDecodeError'] - -FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL - -NaN = float('nan') -PosInf = float('inf') -NegInf = float('-inf') - - -class JSONDecodeError(ValueError): - """Subclass of ValueError with the following additional properties: - - msg: The unformatted error message - doc: The JSON document being parsed - pos: The start index of doc where parsing failed - lineno: The line corresponding to pos - colno: The column corresponding to pos - - """ - # Note that this exception is used from _json - def __init__(self, msg, doc, pos): - lineno = doc.count('\n', 0, pos) + 1 - colno = pos - doc.rfind('\n', 0, pos) - errmsg = '%s: line %d column %d (char %d)' % (msg, lineno, colno, pos) - ValueError.__init__(self, errmsg) - self.msg = msg - self.doc = doc - self.pos = pos - self.lineno = lineno - self.colno = colno - - def __reduce__(self): - return self.__class__, (self.msg, self.doc, self.pos) - - -_CONSTANTS = { - '-Infinity': NegInf, - 'Infinity': PosInf, - 'NaN': NaN, -} - - -STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS) -BACKSLASH = { - '"': '"', '\\': '\\', '/': '/', - 'b': '\b', 'f': '\f', 'n': '\n', 'r': '\r', 't': '\t', -} - -def _decode_uXXXX(s, pos): - esc = s[pos + 1:pos + 5] - if len(esc) == 4 and esc[1] not in 'xX': - try: - return int(esc, 16) - except ValueError: - pass - msg = "Invalid \\uXXXX escape" - raise JSONDecodeError(msg, s, pos) - -def py_scanstring(s, end, strict=True, - _b=BACKSLASH, _m=STRINGCHUNK.match): - """Scan the string s for a JSON string. End is the index of the - character in s after the quote that started the JSON string. - Unescapes all valid JSON string escape sequences and raises ValueError - on attempt to decode an invalid string. If strict is False then literal - control characters are allowed in the string. - - Returns a tuple of the decoded string and the index of the character in s - after the end quote.""" - chunks = [] - _append = chunks.append - begin = end - 1 - while 1: - chunk = _m(s, end) - if chunk is None: - raise JSONDecodeError("Unterminated string starting at", s, begin) - end = chunk.end() - content, terminator = chunk.groups() - # Content is contains zero or more unescaped string characters - if content: - _append(content) - # Terminator is the end of string, a literal control character, - # or a backslash denoting that an escape sequence follows - if terminator == '"': - break - elif terminator != '\\': - if strict: - #msg = "Invalid control character %r at" % (terminator,) - msg = "Invalid control character {0!r} at".format(terminator) - raise JSONDecodeError(msg, s, end) - else: - _append(terminator) - continue - try: - esc = s[end] - except IndexError: - raise JSONDecodeError("Unterminated string starting at", - s, begin) from None - # If not a unicode escape sequence, must be in the lookup table - if esc != 'u': - try: - char = _b[esc] - except KeyError: - msg = "Invalid \\escape: {0!r}".format(esc) - raise JSONDecodeError(msg, s, end) - end += 1 - else: - uni = _decode_uXXXX(s, end) - end += 5 - if 0xd800 <= uni <= 0xdbff and s[end:end + 2] == '\\u': - uni2 = _decode_uXXXX(s, end + 1) - if 0xdc00 <= uni2 <= 0xdfff: - uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00)) - end += 6 - char = chr(uni) - _append(char) - return ''.join(chunks), end - - -# Use speedup if available -scanstring = c_scanstring or py_scanstring - -WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS) -WHITESPACE_STR = ' \t\n\r' - - -def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook, - memo=None, _w=WHITESPACE.match, _ws=WHITESPACE_STR): - s, end = s_and_end - pairs = [] - pairs_append = pairs.append - # Backwards compatibility - if memo is None: - memo = {} - memo_get = memo.setdefault - # Use a slice to prevent IndexError from being raised, the following - # check will raise a more specific ValueError if the string is empty - nextchar = s[end:end + 1] - # Normally we expect nextchar == '"' - if nextchar != '"': - if nextchar in _ws: - end = _w(s, end).end() - nextchar = s[end:end + 1] - # Trivial empty object - if nextchar == '}': - if object_pairs_hook is not None: - result = object_pairs_hook(pairs) - return result, end + 1 - pairs = {} - if object_hook is not None: - pairs = object_hook(pairs) - return pairs, end + 1 - elif nextchar != '"': - raise JSONDecodeError( - "Expecting property name enclosed in double quotes", s, end) - end += 1 - while True: - key, end = scanstring(s, end, strict) - key = memo_get(key, key) - # To skip some function call overhead we optimize the fast paths where - # the JSON key separator is ": " or just ":". - if s[end:end + 1] != ':': - end = _w(s, end).end() - if s[end:end + 1] != ':': - raise JSONDecodeError("Expecting ':' delimiter", s, end) - end += 1 - - try: - if s[end] in _ws: - end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() - except IndexError: - pass - - try: - value, end = scan_once(s, end) - except StopIteration as err: - raise JSONDecodeError("Expecting value", s, err.value) from None - pairs_append((key, value)) - try: - nextchar = s[end] - if nextchar in _ws: - end = _w(s, end + 1).end() - nextchar = s[end] - except IndexError: - nextchar = '' - end += 1 - - if nextchar == '}': - break - elif nextchar != ',': - raise JSONDecodeError("Expecting ',' delimiter", s, end - 1) - end = _w(s, end).end() - nextchar = s[end:end + 1] - end += 1 - if nextchar != '"': - raise JSONDecodeError( - "Expecting property name enclosed in double quotes", s, end - 1) - if object_pairs_hook is not None: - result = object_pairs_hook(pairs) - return result, end - pairs = dict(pairs) - if object_hook is not None: - pairs = object_hook(pairs) - return pairs, end - -def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): - s, end = s_and_end - values = [] - nextchar = s[end:end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() - nextchar = s[end:end + 1] - # Look-ahead for trivial empty array - if nextchar == ']': - return values, end + 1 - _append = values.append - while True: - try: - value, end = scan_once(s, end) - except StopIteration as err: - raise JSONDecodeError("Expecting value", s, err.value) from None - _append(value) - nextchar = s[end:end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() - nextchar = s[end:end + 1] - end += 1 - if nextchar == ']': - break - elif nextchar != ',': - raise JSONDecodeError("Expecting ',' delimiter", s, end - 1) - try: - if s[end] in _ws: - end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() - except IndexError: - pass - - return values, end - - -class JSONDecoder(object): - """Simple JSON decoder - - Performs the following translations in decoding by default: - - +---------------+-------------------+ - | JSON | Python | - +===============+===================+ - | object | dict | - +---------------+-------------------+ - | array | list | - +---------------+-------------------+ - | string | str | - +---------------+-------------------+ - | number (int) | int | - +---------------+-------------------+ - | number (real) | float | - +---------------+-------------------+ - | true | True | - +---------------+-------------------+ - | false | False | - +---------------+-------------------+ - | null | None | - +---------------+-------------------+ - - It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as - their corresponding ``float`` values, which is outside the JSON spec. - - """ - - def __init__(self, *, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, strict=True, - object_pairs_hook=None): - """``object_hook``, if specified, will be called with the result - of every JSON object decoded and its return value will be used in - place of the given ``dict``. This can be used to provide custom - deserializations (e.g. to support JSON-RPC class hinting). - - ``object_pairs_hook``, if specified will be called with the result of - every JSON object decoded with an ordered list of pairs. The return - value of ``object_pairs_hook`` will be used instead of the ``dict``. - This feature can be used to implement custom decoders. - If ``object_hook`` is also defined, the ``object_pairs_hook`` takes - priority. - - ``parse_float``, if specified, will be called with the string - of every JSON float to be decoded. By default this is equivalent to - float(num_str). This can be used to use another datatype or parser - for JSON floats (e.g. decimal.Decimal). - - ``parse_int``, if specified, will be called with the string - of every JSON int to be decoded. By default this is equivalent to - int(num_str). This can be used to use another datatype or parser - for JSON integers (e.g. float). - - ``parse_constant``, if specified, will be called with one of the - following strings: -Infinity, Infinity, NaN. - This can be used to raise an exception if invalid JSON numbers - are encountered. - - If ``strict`` is false (true is the default), then control - characters will be allowed inside strings. Control characters in - this context are those with character codes in the 0-31 range, - including ``'\\t'`` (tab), ``'\\n'``, ``'\\r'`` and ``'\\0'``. - """ - self.object_hook = object_hook - self.parse_float = parse_float or float - self.parse_int = parse_int or int - self.parse_constant = parse_constant or _CONSTANTS.__getitem__ - self.strict = strict - self.object_pairs_hook = object_pairs_hook - self.parse_object = JSONObject - self.parse_array = JSONArray - self.parse_string = scanstring - self.memo = {} - self.scan_once = scanner.make_scanner(self) - - - def decode(self, s, _w=WHITESPACE.match): - """Return the Python representation of ``s`` (a ``str`` instance - containing a JSON document). - - """ - obj, end = self.raw_decode(s, idx=_w(s, 0).end()) - end = _w(s, end).end() - if end != len(s): - raise JSONDecodeError("Extra data", s, end) - return obj - - def raw_decode(self, s, idx=0): - """Decode a JSON document from ``s`` (a ``str`` beginning with - a JSON document) and return a 2-tuple of the Python - representation and the index in ``s`` where the document ended. - - This can be used to decode a JSON document from a string that may - have extraneous data at the end. - - """ - try: - obj, end = self.scan_once(s, idx) - except StopIteration as err: - raise JSONDecodeError("Expecting value", s, err.value) from None - return obj, end diff --git a/python/Lib/json/encoder.py b/python/Lib/json/encoder.py deleted file mode 100644 index 21ed6a2..0000000 --- a/python/Lib/json/encoder.py +++ /dev/null @@ -1,443 +0,0 @@ -"""Implementation of JSONEncoder -""" -import re - -try: - from _json import encode_basestring_ascii as c_encode_basestring_ascii -except ImportError: - c_encode_basestring_ascii = None -try: - from _json import encode_basestring as c_encode_basestring -except ImportError: - c_encode_basestring = None -try: - from _json import make_encoder as c_make_encoder -except ImportError: - c_make_encoder = None - -ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]') -ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])') -HAS_UTF8 = re.compile(b'[\x80-\xff]') -ESCAPE_DCT = { - '\\': '\\\\', - '"': '\\"', - '\b': '\\b', - '\f': '\\f', - '\n': '\\n', - '\r': '\\r', - '\t': '\\t', -} -for i in range(0x20): - ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i)) - #ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,)) -del i - -INFINITY = float('inf') - -def py_encode_basestring(s): - """Return a JSON representation of a Python string - - """ - def replace(match): - return ESCAPE_DCT[match.group(0)] - return '"' + ESCAPE.sub(replace, s) + '"' - - -encode_basestring = (c_encode_basestring or py_encode_basestring) - - -def py_encode_basestring_ascii(s): - """Return an ASCII-only JSON representation of a Python string - - """ - def replace(match): - s = match.group(0) - try: - return ESCAPE_DCT[s] - except KeyError: - n = ord(s) - if n < 0x10000: - return '\\u{0:04x}'.format(n) - #return '\\u%04x' % (n,) - else: - # surrogate pair - n -= 0x10000 - s1 = 0xd800 | ((n >> 10) & 0x3ff) - s2 = 0xdc00 | (n & 0x3ff) - return '\\u{0:04x}\\u{1:04x}'.format(s1, s2) - return '"' + ESCAPE_ASCII.sub(replace, s) + '"' - - -encode_basestring_ascii = ( - c_encode_basestring_ascii or py_encode_basestring_ascii) - -class JSONEncoder(object): - """Extensible JSON encoder for Python data structures. - - Supports the following objects and types by default: - - +-------------------+---------------+ - | Python | JSON | - +===================+===============+ - | dict | object | - +-------------------+---------------+ - | list, tuple | array | - +-------------------+---------------+ - | str | string | - +-------------------+---------------+ - | int, float | number | - +-------------------+---------------+ - | True | true | - +-------------------+---------------+ - | False | false | - +-------------------+---------------+ - | None | null | - +-------------------+---------------+ - - To extend this to recognize other objects, subclass and implement a - ``.default()`` method with another method that returns a serializable - object for ``o`` if possible, otherwise it should call the superclass - implementation (to raise ``TypeError``). - - """ - item_separator = ', ' - key_separator = ': ' - def __init__(self, *, skipkeys=False, ensure_ascii=True, - check_circular=True, allow_nan=True, sort_keys=False, - indent=None, separators=None, default=None): - """Constructor for JSONEncoder, with sensible defaults. - - If skipkeys is false, then it is a TypeError to attempt - encoding of keys that are not str, int, float or None. If - skipkeys is True, such items are simply skipped. - - If ensure_ascii is true, the output is guaranteed to be str - objects with all incoming non-ASCII characters escaped. If - ensure_ascii is false, the output can contain non-ASCII characters. - - If check_circular is true, then lists, dicts, and custom encoded - objects will be checked for circular references during encoding to - prevent an infinite recursion (which would cause an RecursionError). - Otherwise, no such check takes place. - - If allow_nan is true, then NaN, Infinity, and -Infinity will be - encoded as such. This behavior is not JSON specification compliant, - but is consistent with most JavaScript based encoders and decoders. - Otherwise, it will be a ValueError to encode such floats. - - If sort_keys is true, then the output of dictionaries will be - sorted by key; this is useful for regression tests to ensure - that JSON serializations can be compared on a day-to-day basis. - - If indent is a non-negative integer, then JSON array - elements and object members will be pretty-printed with that - indent level. An indent level of 0 will only insert newlines. - None is the most compact representation. - - If specified, separators should be an (item_separator, key_separator) - tuple. The default is (', ', ': ') if *indent* is ``None`` and - (',', ': ') otherwise. To get the most compact JSON representation, - you should specify (',', ':') to eliminate whitespace. - - If specified, default is a function that gets called for objects - that can't otherwise be serialized. It should return a JSON encodable - version of the object or raise a ``TypeError``. - - """ - - self.skipkeys = skipkeys - self.ensure_ascii = ensure_ascii - self.check_circular = check_circular - self.allow_nan = allow_nan - self.sort_keys = sort_keys - self.indent = indent - if separators is not None: - self.item_separator, self.key_separator = separators - elif indent is not None: - self.item_separator = ',' - if default is not None: - self.default = default - - def default(self, o): - """Implement this method in a subclass such that it returns - a serializable object for ``o``, or calls the base implementation - (to raise a ``TypeError``). - - For example, to support arbitrary iterators, you could - implement default like this:: - - def default(self, o): - try: - iterable = iter(o) - except TypeError: - pass - else: - return list(iterable) - # Let the base class default method raise the TypeError - return JSONEncoder.default(self, o) - - """ - raise TypeError(f'Object of type {o.__class__.__name__} ' - f'is not JSON serializable') - - def encode(self, o): - """Return a JSON string representation of a Python data structure. - - >>> from json.encoder import JSONEncoder - >>> JSONEncoder().encode({"foo": ["bar", "baz"]}) - '{"foo": ["bar", "baz"]}' - - """ - # This is for extremely simple cases and benchmarks. - if isinstance(o, str): - if self.ensure_ascii: - return encode_basestring_ascii(o) - else: - return encode_basestring(o) - # This doesn't pass the iterator directly to ''.join() because the - # exceptions aren't as detailed. The list call should be roughly - # equivalent to the PySequence_Fast that ''.join() would do. - chunks = self.iterencode(o, _one_shot=True) - if not isinstance(chunks, (list, tuple)): - chunks = list(chunks) - return ''.join(chunks) - - def iterencode(self, o, _one_shot=False): - """Encode the given object and yield each string - representation as available. - - For example:: - - for chunk in JSONEncoder().iterencode(bigobject): - mysocket.write(chunk) - - """ - if self.check_circular: - markers = {} - else: - markers = None - if self.ensure_ascii: - _encoder = encode_basestring_ascii - else: - _encoder = encode_basestring - - def floatstr(o, allow_nan=self.allow_nan, - _repr=float.__repr__, _inf=INFINITY, _neginf=-INFINITY): - # Check for specials. Note that this type of test is processor - # and/or platform-specific, so do tests which don't depend on the - # internals. - - if o != o: - text = 'NaN' - elif o == _inf: - text = 'Infinity' - elif o == _neginf: - text = '-Infinity' - else: - return _repr(o) - - if not allow_nan: - raise ValueError( - "Out of range float values are not JSON compliant: " + - repr(o)) - - return text - - - if (_one_shot and c_make_encoder is not None - and self.indent is None): - _iterencode = c_make_encoder( - markers, self.default, _encoder, self.indent, - self.key_separator, self.item_separator, self.sort_keys, - self.skipkeys, self.allow_nan) - else: - _iterencode = _make_iterencode( - markers, self.default, _encoder, self.indent, floatstr, - self.key_separator, self.item_separator, self.sort_keys, - self.skipkeys, _one_shot) - return _iterencode(o, 0) - -def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, - _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot, - ## HACK: hand-optimized bytecode; turn globals into locals - ValueError=ValueError, - dict=dict, - float=float, - id=id, - int=int, - isinstance=isinstance, - list=list, - str=str, - tuple=tuple, - _intstr=int.__repr__, - ): - - if _indent is not None and not isinstance(_indent, str): - _indent = ' ' * _indent - - def _iterencode_list(lst, _current_indent_level): - if not lst: - yield '[]' - return - if markers is not None: - markerid = id(lst) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = lst - buf = '[' - if _indent is not None: - _current_indent_level += 1 - newline_indent = '\n' + _indent * _current_indent_level - separator = _item_separator + newline_indent - buf += newline_indent - else: - newline_indent = None - separator = _item_separator - first = True - for value in lst: - if first: - first = False - else: - buf = separator - if isinstance(value, str): - yield buf + _encoder(value) - elif value is None: - yield buf + 'null' - elif value is True: - yield buf + 'true' - elif value is False: - yield buf + 'false' - elif isinstance(value, int): - # Subclasses of int/float may override __repr__, but we still - # want to encode them as integers/floats in JSON. One example - # within the standard library is IntEnum. - yield buf + _intstr(value) - elif isinstance(value, float): - # see comment above for int - yield buf + _floatstr(value) - else: - yield buf - if isinstance(value, (list, tuple)): - chunks = _iterencode_list(value, _current_indent_level) - elif isinstance(value, dict): - chunks = _iterencode_dict(value, _current_indent_level) - else: - chunks = _iterencode(value, _current_indent_level) - yield from chunks - if newline_indent is not None: - _current_indent_level -= 1 - yield '\n' + _indent * _current_indent_level - yield ']' - if markers is not None: - del markers[markerid] - - def _iterencode_dict(dct, _current_indent_level): - if not dct: - yield '{}' - return - if markers is not None: - markerid = id(dct) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = dct - yield '{' - if _indent is not None: - _current_indent_level += 1 - newline_indent = '\n' + _indent * _current_indent_level - item_separator = _item_separator + newline_indent - yield newline_indent - else: - newline_indent = None - item_separator = _item_separator - first = True - if _sort_keys: - items = sorted(dct.items()) - else: - items = dct.items() - for key, value in items: - if isinstance(key, str): - pass - # JavaScript is weakly typed for these, so it makes sense to - # also allow them. Many encoders seem to do something like this. - elif isinstance(key, float): - # see comment for int/float in _make_iterencode - key = _floatstr(key) - elif key is True: - key = 'true' - elif key is False: - key = 'false' - elif key is None: - key = 'null' - elif isinstance(key, int): - # see comment for int/float in _make_iterencode - key = _intstr(key) - elif _skipkeys: - continue - else: - raise TypeError(f'keys must be str, int, float, bool or None, ' - f'not {key.__class__.__name__}') - if first: - first = False - else: - yield item_separator - yield _encoder(key) - yield _key_separator - if isinstance(value, str): - yield _encoder(value) - elif value is None: - yield 'null' - elif value is True: - yield 'true' - elif value is False: - yield 'false' - elif isinstance(value, int): - # see comment for int/float in _make_iterencode - yield _intstr(value) - elif isinstance(value, float): - # see comment for int/float in _make_iterencode - yield _floatstr(value) - else: - if isinstance(value, (list, tuple)): - chunks = _iterencode_list(value, _current_indent_level) - elif isinstance(value, dict): - chunks = _iterencode_dict(value, _current_indent_level) - else: - chunks = _iterencode(value, _current_indent_level) - yield from chunks - if newline_indent is not None: - _current_indent_level -= 1 - yield '\n' + _indent * _current_indent_level - yield '}' - if markers is not None: - del markers[markerid] - - def _iterencode(o, _current_indent_level): - if isinstance(o, str): - yield _encoder(o) - elif o is None: - yield 'null' - elif o is True: - yield 'true' - elif o is False: - yield 'false' - elif isinstance(o, int): - # see comment for int/float in _make_iterencode - yield _intstr(o) - elif isinstance(o, float): - # see comment for int/float in _make_iterencode - yield _floatstr(o) - elif isinstance(o, (list, tuple)): - yield from _iterencode_list(o, _current_indent_level) - elif isinstance(o, dict): - yield from _iterencode_dict(o, _current_indent_level) - else: - if markers is not None: - markerid = id(o) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = o - o = _default(o) - yield from _iterencode(o, _current_indent_level) - if markers is not None: - del markers[markerid] - return _iterencode diff --git a/python/Lib/json/scanner.py b/python/Lib/json/scanner.py deleted file mode 100644 index 4b52237..0000000 --- a/python/Lib/json/scanner.py +++ /dev/null @@ -1,73 +0,0 @@ -"""JSON token scanner -""" -import re -try: - from _json import make_scanner as c_make_scanner -except ImportError: - c_make_scanner = None - -__all__ = ['make_scanner'] - -NUMBER_RE = re.compile( - r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?', - (re.VERBOSE | re.MULTILINE | re.DOTALL)) - -def py_make_scanner(context): - parse_object = context.parse_object - parse_array = context.parse_array - parse_string = context.parse_string - match_number = NUMBER_RE.match - strict = context.strict - parse_float = context.parse_float - parse_int = context.parse_int - parse_constant = context.parse_constant - object_hook = context.object_hook - object_pairs_hook = context.object_pairs_hook - memo = context.memo - - def _scan_once(string, idx): - try: - nextchar = string[idx] - except IndexError: - raise StopIteration(idx) from None - - if nextchar == '"': - return parse_string(string, idx + 1, strict) - elif nextchar == '{': - return parse_object((string, idx + 1), strict, - _scan_once, object_hook, object_pairs_hook, memo) - elif nextchar == '[': - return parse_array((string, idx + 1), _scan_once) - elif nextchar == 'n' and string[idx:idx + 4] == 'null': - return None, idx + 4 - elif nextchar == 't' and string[idx:idx + 4] == 'true': - return True, idx + 4 - elif nextchar == 'f' and string[idx:idx + 5] == 'false': - return False, idx + 5 - - m = match_number(string, idx) - if m is not None: - integer, frac, exp = m.groups() - if frac or exp: - res = parse_float(integer + (frac or '') + (exp or '')) - else: - res = parse_int(integer) - return res, m.end() - elif nextchar == 'N' and string[idx:idx + 3] == 'NaN': - return parse_constant('NaN'), idx + 3 - elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity': - return parse_constant('Infinity'), idx + 8 - elif nextchar == '-' and string[idx:idx + 9] == '-Infinity': - return parse_constant('-Infinity'), idx + 9 - else: - raise StopIteration(idx) - - def scan_once(string, idx): - try: - return _scan_once(string, idx) - finally: - memo.clear() - - return scan_once - -make_scanner = c_make_scanner or py_make_scanner diff --git a/python/Lib/json/tool.py b/python/Lib/json/tool.py deleted file mode 100644 index a036050..0000000 --- a/python/Lib/json/tool.py +++ /dev/null @@ -1,85 +0,0 @@ -r"""Command-line tool to validate and pretty-print JSON - -Usage:: - - $ echo '{"json":"obj"}' | python -m json.tool - { - "json": "obj" - } - $ echo '{ 1.2:3.4}' | python -m json.tool - Expecting property name enclosed in double quotes: line 1 column 3 (char 2) - -""" -import argparse -import json -import sys -from pathlib import Path - - -def main(): - prog = 'python -m json.tool' - description = ('A simple command line interface for json module ' - 'to validate and pretty-print JSON objects.') - parser = argparse.ArgumentParser(prog=prog, description=description) - parser.add_argument('infile', nargs='?', - type=argparse.FileType(encoding="utf-8"), - help='a JSON file to be validated or pretty-printed', - default=sys.stdin) - parser.add_argument('outfile', nargs='?', - type=Path, - help='write the output of infile to outfile', - default=None) - parser.add_argument('--sort-keys', action='store_true', default=False, - help='sort the output of dictionaries alphabetically by key') - parser.add_argument('--no-ensure-ascii', dest='ensure_ascii', action='store_false', - help='disable escaping of non-ASCII characters') - parser.add_argument('--json-lines', action='store_true', default=False, - help='parse input using the JSON Lines format. ' - 'Use with --no-indent or --compact to produce valid JSON Lines output.') - group = parser.add_mutually_exclusive_group() - group.add_argument('--indent', default=4, type=int, - help='separate items with newlines and use this number ' - 'of spaces for indentation') - group.add_argument('--tab', action='store_const', dest='indent', - const='\t', help='separate items with newlines and use ' - 'tabs for indentation') - group.add_argument('--no-indent', action='store_const', dest='indent', - const=None, - help='separate items with spaces rather than newlines') - group.add_argument('--compact', action='store_true', - help='suppress all whitespace separation (most compact)') - options = parser.parse_args() - - dump_args = { - 'sort_keys': options.sort_keys, - 'indent': options.indent, - 'ensure_ascii': options.ensure_ascii, - } - if options.compact: - dump_args['indent'] = None - dump_args['separators'] = ',', ':' - - with options.infile as infile: - try: - if options.json_lines: - objs = (json.loads(line) for line in infile) - else: - objs = (json.load(infile),) - - if options.outfile is None: - out = sys.stdout - else: - out = options.outfile.open('w', encoding='utf-8') - with out as outfile: - for obj in objs: - json.dump(obj, outfile, **dump_args) - outfile.write('\n') - except ValueError as e: - raise SystemExit(e) - - -if __name__ == '__main__': - try: - main() - except BrokenPipeError as exc: - sys.exit(exc.errno) diff --git a/python/Lib/keyword.py b/python/Lib/keyword.py deleted file mode 100644 index eab8204..0000000 --- a/python/Lib/keyword.py +++ /dev/null @@ -1,63 +0,0 @@ -"""Keywords (from "Grammar/python.gram") - -This file is automatically generated; please don't muck it up! - -To update the symbols in this file, 'cd' to the top directory of -the python source tree and run: - - PYTHONPATH=Tools/peg_generator python3 -m pegen.keywordgen \ - Grammar/python.gram \ - Grammar/Tokens \ - Lib/keyword.py - -Alternatively, you can run 'make regen-keyword'. -""" - -__all__ = ["iskeyword", "issoftkeyword", "kwlist", "softkwlist"] - -kwlist = [ - 'False', - 'None', - 'True', - 'and', - 'as', - 'assert', - 'async', - 'await', - 'break', - 'class', - 'continue', - 'def', - 'del', - 'elif', - 'else', - 'except', - 'finally', - 'for', - 'from', - 'global', - 'if', - 'import', - 'in', - 'is', - 'lambda', - 'nonlocal', - 'not', - 'or', - 'pass', - 'raise', - 'return', - 'try', - 'while', - 'with', - 'yield' -] - -softkwlist = [ - '_', - 'case', - 'match' -] - -iskeyword = frozenset(kwlist).__contains__ -issoftkeyword = frozenset(softkwlist).__contains__ diff --git a/python/Lib/linecache.py b/python/Lib/linecache.py deleted file mode 100644 index 1a9380d..0000000 --- a/python/Lib/linecache.py +++ /dev/null @@ -1,182 +0,0 @@ -"""Cache lines from Python source files. - -This is intended to read lines from modules imported -- hence if a filename -is not found, it will look down the module search path for a file by -that name. -""" - -import functools -import sys -import os -import tokenize - -__all__ = ["getline", "clearcache", "checkcache", "lazycache"] - - -# The cache. Maps filenames to either a thunk which will provide source code, -# or a tuple (size, mtime, lines, fullname) once loaded. -cache = {} - - -def clearcache(): - """Clear the cache entirely.""" - cache.clear() - - -def getline(filename, lineno, module_globals=None): - """Get a line for a Python source file from the cache. - Update the cache if it doesn't contain an entry for this file already.""" - - lines = getlines(filename, module_globals) - if 1 <= lineno <= len(lines): - return lines[lineno - 1] - return '' - - -def getlines(filename, module_globals=None): - """Get the lines for a Python source file from the cache. - Update the cache if it doesn't contain an entry for this file already.""" - - if filename in cache: - entry = cache[filename] - if len(entry) != 1: - return cache[filename][2] - - try: - return updatecache(filename, module_globals) - except MemoryError: - clearcache() - return [] - - -def checkcache(filename=None): - """Discard cache entries that are out of date. - (This is not checked upon each call!)""" - - if filename is None: - filenames = list(cache.keys()) - elif filename in cache: - filenames = [filename] - else: - return - - for filename in filenames: - entry = cache[filename] - if len(entry) == 1: - # lazy cache entry, leave it lazy. - continue - size, mtime, lines, fullname = entry - if mtime is None: - continue # no-op for files loaded via a __loader__ - try: - stat = os.stat(fullname) - except OSError: - cache.pop(filename, None) - continue - if size != stat.st_size or mtime != stat.st_mtime: - cache.pop(filename, None) - - -def updatecache(filename, module_globals=None): - """Update a cache entry and return its list of lines. - If something's wrong, print a message, discard the cache entry, - and return an empty list.""" - - if filename in cache: - if len(cache[filename]) != 1: - cache.pop(filename, None) - if not filename or (filename.startswith('<') and filename.endswith('>')): - return [] - - fullname = filename - try: - stat = os.stat(fullname) - except OSError: - basename = filename - - # Realise a lazy loader based lookup if there is one - # otherwise try to lookup right now. - if lazycache(filename, module_globals): - try: - data = cache[filename][0]() - except (ImportError, OSError): - pass - else: - if data is None: - # No luck, the PEP302 loader cannot find the source - # for this module. - return [] - cache[filename] = ( - len(data), - None, - [line + '\n' for line in data.splitlines()], - fullname - ) - return cache[filename][2] - - # Try looking through the module search path, which is only useful - # when handling a relative filename. - if os.path.isabs(filename): - return [] - - for dirname in sys.path: - try: - fullname = os.path.join(dirname, basename) - except (TypeError, AttributeError): - # Not sufficiently string-like to do anything useful with. - continue - try: - stat = os.stat(fullname) - break - except OSError: - pass - else: - return [] - try: - with tokenize.open(fullname) as fp: - lines = fp.readlines() - except (OSError, UnicodeDecodeError, SyntaxError): - return [] - if lines and not lines[-1].endswith('\n'): - lines[-1] += '\n' - size, mtime = stat.st_size, stat.st_mtime - cache[filename] = size, mtime, lines, fullname - return lines - - -def lazycache(filename, module_globals): - """Seed the cache for filename with module_globals. - - The module loader will be asked for the source only when getlines is - called, not immediately. - - If there is an entry in the cache already, it is not altered. - - :return: True if a lazy load is registered in the cache, - otherwise False. To register such a load a module loader with a - get_source method must be found, the filename must be a cacheable - filename, and the filename must not be already cached. - """ - if filename in cache: - if len(cache[filename]) == 1: - return True - else: - return False - if not filename or (filename.startswith('<') and filename.endswith('>')): - return False - # Try for a __loader__, if available - if module_globals and '__name__' in module_globals: - name = module_globals['__name__'] - if (loader := module_globals.get('__loader__')) is None: - if spec := module_globals.get('__spec__'): - try: - loader = spec.loader - except AttributeError: - pass - get_source = getattr(loader, 'get_source', None) - - if name and get_source: - get_lines = functools.partial(get_source, name) - cache[filename] = (get_lines,) - return True - return False diff --git a/python/Lib/locale.py b/python/Lib/locale.py deleted file mode 100644 index 22b5f11..0000000 --- a/python/Lib/locale.py +++ /dev/null @@ -1,1789 +0,0 @@ -"""Locale support module. - -The module provides low-level access to the C lib's locale APIs and adds high -level number formatting APIs as well as a locale aliasing engine to complement -these. - -The aliasing engine includes support for many commonly used locale names and -maps them to values suitable for passing to the C lib's setlocale() function. It -also includes default encodings for all supported locale names. - -""" - -import sys -import encodings -import encodings.aliases -import re -import _collections_abc -from builtins import str as _builtin_str -import functools - -# Try importing the _locale module. -# -# If this fails, fall back on a basic 'C' locale emulation. - -# Yuck: LC_MESSAGES is non-standard: can't tell whether it exists before -# trying the import. So __all__ is also fiddled at the end of the file. -__all__ = ["getlocale", "getdefaultlocale", "getpreferredencoding", "Error", - "setlocale", "resetlocale", "localeconv", "strcoll", "strxfrm", - "str", "atof", "atoi", "format", "format_string", "currency", - "normalize", "LC_CTYPE", "LC_COLLATE", "LC_TIME", "LC_MONETARY", - "LC_NUMERIC", "LC_ALL", "CHAR_MAX", "getencoding"] - -def _strcoll(a,b): - """ strcoll(string,string) -> int. - Compares two strings according to the locale. - """ - return (a > b) - (a < b) - -def _strxfrm(s): - """ strxfrm(string) -> string. - Returns a string that behaves for cmp locale-aware. - """ - return s - -try: - - from _locale import * - -except ImportError: - - # Locale emulation - - CHAR_MAX = 127 - LC_ALL = 6 - LC_COLLATE = 3 - LC_CTYPE = 0 - LC_MESSAGES = 5 - LC_MONETARY = 4 - LC_NUMERIC = 1 - LC_TIME = 2 - Error = ValueError - - def localeconv(): - """ localeconv() -> dict. - Returns numeric and monetary locale-specific parameters. - """ - # 'C' locale default values - return {'grouping': [127], - 'currency_symbol': '', - 'n_sign_posn': 127, - 'p_cs_precedes': 127, - 'n_cs_precedes': 127, - 'mon_grouping': [], - 'n_sep_by_space': 127, - 'decimal_point': '.', - 'negative_sign': '', - 'positive_sign': '', - 'p_sep_by_space': 127, - 'int_curr_symbol': '', - 'p_sign_posn': 127, - 'thousands_sep': '', - 'mon_thousands_sep': '', - 'frac_digits': 127, - 'mon_decimal_point': '', - 'int_frac_digits': 127} - - def setlocale(category, value=None): - """ setlocale(integer,string=None) -> string. - Activates/queries locale processing. - """ - if value not in (None, '', 'C'): - raise Error('_locale emulation only supports "C" locale') - return 'C' - -# These may or may not exist in _locale, so be sure to set them. -if 'strxfrm' not in globals(): - strxfrm = _strxfrm -if 'strcoll' not in globals(): - strcoll = _strcoll - - -_localeconv = localeconv - -# With this dict, you can override some items of localeconv's return value. -# This is useful for testing purposes. -_override_localeconv = {} - -@functools.wraps(_localeconv) -def localeconv(): - d = _localeconv() - if _override_localeconv: - d.update(_override_localeconv) - return d - - -### Number formatting APIs - -# Author: Martin von Loewis -# improved by Georg Brandl - -# Iterate over grouping intervals -def _grouping_intervals(grouping): - last_interval = None - for interval in grouping: - # if grouping is -1, we are done - if interval == CHAR_MAX: - return - # 0: re-use last group ad infinitum - if interval == 0: - if last_interval is None: - raise ValueError("invalid grouping") - while True: - yield last_interval - yield interval - last_interval = interval - -#perform the grouping from right to left -def _group(s, monetary=False): - conv = localeconv() - thousands_sep = conv[monetary and 'mon_thousands_sep' or 'thousands_sep'] - grouping = conv[monetary and 'mon_grouping' or 'grouping'] - if not grouping: - return (s, 0) - if s[-1] == ' ': - stripped = s.rstrip() - right_spaces = s[len(stripped):] - s = stripped - else: - right_spaces = '' - left_spaces = '' - groups = [] - for interval in _grouping_intervals(grouping): - if not s or s[-1] not in "0123456789": - # only non-digit characters remain (sign, spaces) - left_spaces = s - s = '' - break - groups.append(s[-interval:]) - s = s[:-interval] - if s: - groups.append(s) - groups.reverse() - return ( - left_spaces + thousands_sep.join(groups) + right_spaces, - len(thousands_sep) * (len(groups) - 1) - ) - -# Strip a given amount of excess padding from the given string -def _strip_padding(s, amount): - lpos = 0 - while amount and s[lpos] == ' ': - lpos += 1 - amount -= 1 - rpos = len(s) - 1 - while amount and s[rpos] == ' ': - rpos -= 1 - amount -= 1 - return s[lpos:rpos+1] - -_percent_re = re.compile(r'%(?:\((?P.*?)\))?' - r'(?P[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]') - -def _format(percent, value, grouping=False, monetary=False, *additional): - if additional: - formatted = percent % ((value,) + additional) - else: - formatted = percent % value - if percent[-1] in 'eEfFgGdiu': - formatted = _localize(formatted, grouping, monetary) - return formatted - -# Transform formatted as locale number according to the locale settings -def _localize(formatted, grouping=False, monetary=False): - # floats and decimal ints need special action! - if '.' in formatted: - seps = 0 - parts = formatted.split('.') - if grouping: - parts[0], seps = _group(parts[0], monetary=monetary) - decimal_point = localeconv()[monetary and 'mon_decimal_point' - or 'decimal_point'] - formatted = decimal_point.join(parts) - if seps: - formatted = _strip_padding(formatted, seps) - else: - seps = 0 - if grouping: - formatted, seps = _group(formatted, monetary=monetary) - if seps: - formatted = _strip_padding(formatted, seps) - return formatted - -def format_string(f, val, grouping=False, monetary=False): - """Formats a string in the same way that the % formatting would use, - but takes the current locale into account. - - Grouping is applied if the third parameter is true. - Conversion uses monetary thousands separator and grouping strings if - forth parameter monetary is true.""" - percents = list(_percent_re.finditer(f)) - new_f = _percent_re.sub('%s', f) - - if isinstance(val, _collections_abc.Mapping): - new_val = [] - for perc in percents: - if perc.group()[-1]=='%': - new_val.append('%') - else: - new_val.append(_format(perc.group(), val, grouping, monetary)) - else: - if not isinstance(val, tuple): - val = (val,) - new_val = [] - i = 0 - for perc in percents: - if perc.group()[-1]=='%': - new_val.append('%') - else: - starcount = perc.group('modifiers').count('*') - new_val.append(_format(perc.group(), - val[i], - grouping, - monetary, - *val[i+1:i+1+starcount])) - i += (1 + starcount) - val = tuple(new_val) - - return new_f % val - -def format(percent, value, grouping=False, monetary=False, *additional): - """Deprecated, use format_string instead.""" - import warnings - warnings.warn( - "This method will be removed in a future version of Python. " - "Use 'locale.format_string()' instead.", - DeprecationWarning, stacklevel=2 - ) - - match = _percent_re.match(percent) - if not match or len(match.group())!= len(percent): - raise ValueError(("format() must be given exactly one %%char " - "format specifier, %s not valid") % repr(percent)) - return _format(percent, value, grouping, monetary, *additional) - -def currency(val, symbol=True, grouping=False, international=False): - """Formats val according to the currency settings - in the current locale.""" - conv = localeconv() - - # check for illegal values - digits = conv[international and 'int_frac_digits' or 'frac_digits'] - if digits == 127: - raise ValueError("Currency formatting is not possible using " - "the 'C' locale.") - - s = _localize(f'{abs(val):.{digits}f}', grouping, monetary=True) - # '<' and '>' are markers if the sign must be inserted between symbol and value - s = '<' + s + '>' - - if symbol: - smb = conv[international and 'int_curr_symbol' or 'currency_symbol'] - precedes = conv[val<0 and 'n_cs_precedes' or 'p_cs_precedes'] - separated = conv[val<0 and 'n_sep_by_space' or 'p_sep_by_space'] - - if precedes: - s = smb + (separated and ' ' or '') + s - else: - if international and smb[-1] == ' ': - smb = smb[:-1] - s = s + (separated and ' ' or '') + smb - - sign_pos = conv[val<0 and 'n_sign_posn' or 'p_sign_posn'] - sign = conv[val<0 and 'negative_sign' or 'positive_sign'] - - if sign_pos == 0: - s = '(' + s + ')' - elif sign_pos == 1: - s = sign + s - elif sign_pos == 2: - s = s + sign - elif sign_pos == 3: - s = s.replace('<', sign) - elif sign_pos == 4: - s = s.replace('>', sign) - else: - # the default if nothing specified; - # this should be the most fitting sign position - s = sign + s - - return s.replace('<', '').replace('>', '') - -def str(val): - """Convert float to string, taking the locale into account.""" - return _format("%.12g", val) - -def delocalize(string): - "Parses a string as a normalized number according to the locale settings." - - conv = localeconv() - - #First, get rid of the grouping - ts = conv['thousands_sep'] - if ts: - string = string.replace(ts, '') - - #next, replace the decimal point with a dot - dd = conv['decimal_point'] - if dd: - string = string.replace(dd, '.') - return string - -def localize(string, grouping=False, monetary=False): - """Parses a string as locale number according to the locale settings.""" - return _localize(string, grouping, monetary) - -def atof(string, func=float): - "Parses a string as a float according to the locale settings." - return func(delocalize(string)) - -def atoi(string): - "Converts a string to an integer according to the locale settings." - return int(delocalize(string)) - -def _test(): - setlocale(LC_ALL, "") - #do grouping - s1 = format_string("%d", 123456789,1) - print(s1, "is", atoi(s1)) - #standard formatting - s1 = str(3.14) - print(s1, "is", atof(s1)) - -### Locale name aliasing engine - -# Author: Marc-Andre Lemburg, mal@lemburg.com -# Various tweaks by Fredrik Lundh - -# store away the low-level version of setlocale (it's -# overridden below) -_setlocale = setlocale - -def _replace_encoding(code, encoding): - if '.' in code: - langname = code[:code.index('.')] - else: - langname = code - # Convert the encoding to a C lib compatible encoding string - norm_encoding = encodings.normalize_encoding(encoding) - #print('norm encoding: %r' % norm_encoding) - norm_encoding = encodings.aliases.aliases.get(norm_encoding.lower(), - norm_encoding) - #print('aliased encoding: %r' % norm_encoding) - encoding = norm_encoding - norm_encoding = norm_encoding.lower() - if norm_encoding in locale_encoding_alias: - encoding = locale_encoding_alias[norm_encoding] - else: - norm_encoding = norm_encoding.replace('_', '') - norm_encoding = norm_encoding.replace('-', '') - if norm_encoding in locale_encoding_alias: - encoding = locale_encoding_alias[norm_encoding] - #print('found encoding %r' % encoding) - return langname + '.' + encoding - -def _append_modifier(code, modifier): - if modifier == 'euro': - if '.' not in code: - return code + '.ISO8859-15' - _, _, encoding = code.partition('.') - if encoding in ('ISO8859-15', 'UTF-8'): - return code - if encoding == 'ISO8859-1': - return _replace_encoding(code, 'ISO8859-15') - return code + '@' + modifier - -def normalize(localename): - - """ Returns a normalized locale code for the given locale - name. - - The returned locale code is formatted for use with - setlocale(). - - If normalization fails, the original name is returned - unchanged. - - If the given encoding is not known, the function defaults to - the default encoding for the locale code just like setlocale() - does. - - """ - # Normalize the locale name and extract the encoding and modifier - code = localename.lower() - if ':' in code: - # ':' is sometimes used as encoding delimiter. - code = code.replace(':', '.') - if '@' in code: - code, modifier = code.split('@', 1) - else: - modifier = '' - if '.' in code: - langname, encoding = code.split('.')[:2] - else: - langname = code - encoding = '' - - # First lookup: fullname (possibly with encoding and modifier) - lang_enc = langname - if encoding: - norm_encoding = encoding.replace('-', '') - norm_encoding = norm_encoding.replace('_', '') - lang_enc += '.' + norm_encoding - lookup_name = lang_enc - if modifier: - lookup_name += '@' + modifier - code = locale_alias.get(lookup_name, None) - if code is not None: - return code - #print('first lookup failed') - - if modifier: - # Second try: fullname without modifier (possibly with encoding) - code = locale_alias.get(lang_enc, None) - if code is not None: - #print('lookup without modifier succeeded') - if '@' not in code: - return _append_modifier(code, modifier) - if code.split('@', 1)[1].lower() == modifier: - return code - #print('second lookup failed') - - if encoding: - # Third try: langname (without encoding, possibly with modifier) - lookup_name = langname - if modifier: - lookup_name += '@' + modifier - code = locale_alias.get(lookup_name, None) - if code is not None: - #print('lookup without encoding succeeded') - if '@' not in code: - return _replace_encoding(code, encoding) - code, modifier = code.split('@', 1) - return _replace_encoding(code, encoding) + '@' + modifier - - if modifier: - # Fourth try: langname (without encoding and modifier) - code = locale_alias.get(langname, None) - if code is not None: - #print('lookup without modifier and encoding succeeded') - if '@' not in code: - code = _replace_encoding(code, encoding) - return _append_modifier(code, modifier) - code, defmod = code.split('@', 1) - if defmod.lower() == modifier: - return _replace_encoding(code, encoding) + '@' + defmod - - return localename - -def _parse_localename(localename): - - """ Parses the locale code for localename and returns the - result as tuple (language code, encoding). - - The localename is normalized and passed through the locale - alias engine. A ValueError is raised in case the locale name - cannot be parsed. - - The language code corresponds to RFC 1766. code and encoding - can be None in case the values cannot be determined or are - unknown to this implementation. - - """ - code = normalize(localename) - if '@' in code: - # Deal with locale modifiers - code, modifier = code.split('@', 1) - if modifier == 'euro' and '.' not in code: - # Assume Latin-9 for @euro locales. This is bogus, - # since some systems may use other encodings for these - # locales. Also, we ignore other modifiers. - return code, 'iso-8859-15' - - if '.' in code: - return tuple(code.split('.')[:2]) - elif code == 'C': - return None, None - elif code == 'UTF-8': - # On macOS "LC_CTYPE=UTF-8" is a valid locale setting - # for getting UTF-8 handling for text. - return None, 'UTF-8' - raise ValueError('unknown locale: %s' % localename) - -def _build_localename(localetuple): - - """ Builds a locale code from the given tuple (language code, - encoding). - - No aliasing or normalizing takes place. - - """ - try: - language, encoding = localetuple - - if language is None: - language = 'C' - if encoding is None: - return language - else: - return language + '.' + encoding - except (TypeError, ValueError): - raise TypeError('Locale must be None, a string, or an iterable of ' - 'two strings -- language code, encoding.') from None - -def getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): - - """ Tries to determine the default locale settings and returns - them as tuple (language code, encoding). - - According to POSIX, a program which has not called - setlocale(LC_ALL, "") runs using the portable 'C' locale. - Calling setlocale(LC_ALL, "") lets it use the default locale as - defined by the LANG variable. Since we don't want to interfere - with the current locale setting we thus emulate the behavior - in the way described above. - - To maintain compatibility with other platforms, not only the - LANG variable is tested, but a list of variables given as - envvars parameter. The first found to be defined will be - used. envvars defaults to the search path used in GNU gettext; - it must always contain the variable name 'LANG'. - - Except for the code 'C', the language code corresponds to RFC - 1766. code and encoding can be None in case the values cannot - be determined. - - """ - - import warnings - warnings.warn( - "Use setlocale(), getencoding() and getlocale() instead", - DeprecationWarning, stacklevel=2 - ) - - try: - # check if it's supported by the _locale module - import _locale - code, encoding = _locale._getdefaultlocale() - except (ImportError, AttributeError): - pass - else: - # make sure the code/encoding values are valid - if sys.platform == "win32" and code and code[:2] == "0x": - # map windows language identifier to language name - code = windows_locale.get(int(code, 0)) - # ...add other platform-specific processing here, if - # necessary... - return code, encoding - - # fall back on POSIX behaviour - import os - lookup = os.environ.get - for variable in envvars: - localename = lookup(variable,None) - if localename: - if variable == 'LANGUAGE': - localename = localename.split(':')[0] - break - else: - localename = 'C' - return _parse_localename(localename) - - -def getlocale(category=LC_CTYPE): - - """ Returns the current setting for the given locale category as - tuple (language code, encoding). - - category may be one of the LC_* value except LC_ALL. It - defaults to LC_CTYPE. - - Except for the code 'C', the language code corresponds to RFC - 1766. code and encoding can be None in case the values cannot - be determined. - - """ - localename = _setlocale(category) - if category == LC_ALL and ';' in localename: - raise TypeError('category LC_ALL is not supported') - return _parse_localename(localename) - -def setlocale(category, locale=None): - - """ Set the locale for the given category. The locale can be - a string, an iterable of two strings (language code and encoding), - or None. - - Iterables are converted to strings using the locale aliasing - engine. Locale strings are passed directly to the C lib. - - category may be given as one of the LC_* values. - - """ - if locale and not isinstance(locale, _builtin_str): - # convert to string - locale = normalize(_build_localename(locale)) - return _setlocale(category, locale) - -def resetlocale(category=LC_ALL): - - """ Sets the locale for category to the default setting. - - The default setting is determined by calling - getdefaultlocale(). category defaults to LC_ALL. - - """ - import warnings - warnings.warn( - 'Use locale.setlocale(locale.LC_ALL, "") instead', - DeprecationWarning, stacklevel=2 - ) - - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=DeprecationWarning) - loc = getdefaultlocale() - - _setlocale(category, _build_localename(loc)) - - -try: - from _locale import getencoding -except ImportError: - def getencoding(): - if hasattr(sys, 'getandroidapilevel'): - # On Android langinfo.h and CODESET are missing, and UTF-8 is - # always used in mbstowcs() and wcstombs(). - return 'utf-8' - encoding = getdefaultlocale()[1] - if encoding is None: - # LANG not set, default to UTF-8 - encoding = 'utf-8' - return encoding - -try: - CODESET -except NameError: - def getpreferredencoding(do_setlocale=True): - """Return the charset that the user is likely using.""" - if sys.flags.warn_default_encoding: - import warnings - warnings.warn( - "UTF-8 Mode affects locale.getpreferredencoding(). Consider locale.getencoding() instead.", - EncodingWarning, 2) - if sys.flags.utf8_mode: - return 'utf-8' - return getencoding() -else: - # On Unix, if CODESET is available, use that. - def getpreferredencoding(do_setlocale=True): - """Return the charset that the user is likely using, - according to the system configuration.""" - - if sys.flags.warn_default_encoding: - import warnings - warnings.warn( - "UTF-8 Mode affects locale.getpreferredencoding(). Consider locale.getencoding() instead.", - EncodingWarning, 2) - if sys.flags.utf8_mode: - return 'utf-8' - - if not do_setlocale: - return getencoding() - - old_loc = setlocale(LC_CTYPE) - try: - try: - setlocale(LC_CTYPE, "") - except Error: - pass - return getencoding() - finally: - setlocale(LC_CTYPE, old_loc) - - -### Database -# -# The following data was extracted from the locale.alias file which -# comes with X11 and then hand edited removing the explicit encoding -# definitions and adding some more aliases. The file is usually -# available as /usr/lib/X11/locale/locale.alias. -# - -# -# The local_encoding_alias table maps lowercase encoding alias names -# to C locale encoding names (case-sensitive). Note that normalize() -# first looks up the encoding in the encodings.aliases dictionary and -# then applies this mapping to find the correct C lib name for the -# encoding. -# -locale_encoding_alias = { - - # Mappings for non-standard encoding names used in locale names - '437': 'C', - 'c': 'C', - 'en': 'ISO8859-1', - 'jis': 'JIS7', - 'jis7': 'JIS7', - 'ajec': 'eucJP', - 'koi8c': 'KOI8-C', - 'microsoftcp1251': 'CP1251', - 'microsoftcp1255': 'CP1255', - 'microsoftcp1256': 'CP1256', - '88591': 'ISO8859-1', - '88592': 'ISO8859-2', - '88595': 'ISO8859-5', - '885915': 'ISO8859-15', - - # Mappings from Python codec names to C lib encoding names - 'ascii': 'ISO8859-1', - 'latin_1': 'ISO8859-1', - 'iso8859_1': 'ISO8859-1', - 'iso8859_10': 'ISO8859-10', - 'iso8859_11': 'ISO8859-11', - 'iso8859_13': 'ISO8859-13', - 'iso8859_14': 'ISO8859-14', - 'iso8859_15': 'ISO8859-15', - 'iso8859_16': 'ISO8859-16', - 'iso8859_2': 'ISO8859-2', - 'iso8859_3': 'ISO8859-3', - 'iso8859_4': 'ISO8859-4', - 'iso8859_5': 'ISO8859-5', - 'iso8859_6': 'ISO8859-6', - 'iso8859_7': 'ISO8859-7', - 'iso8859_8': 'ISO8859-8', - 'iso8859_9': 'ISO8859-9', - 'iso2022_jp': 'JIS7', - 'shift_jis': 'SJIS', - 'tactis': 'TACTIS', - 'euc_jp': 'eucJP', - 'euc_kr': 'eucKR', - 'utf_8': 'UTF-8', - 'koi8_r': 'KOI8-R', - 'koi8_t': 'KOI8-T', - 'koi8_u': 'KOI8-U', - 'kz1048': 'RK1048', - 'cp1251': 'CP1251', - 'cp1255': 'CP1255', - 'cp1256': 'CP1256', - - # XXX This list is still incomplete. If you know more - # mappings, please file a bug report. Thanks. -} - -for k, v in sorted(locale_encoding_alias.items()): - k = k.replace('_', '') - locale_encoding_alias.setdefault(k, v) -del k, v - -# -# The locale_alias table maps lowercase alias names to C locale names -# (case-sensitive). Encodings are always separated from the locale -# name using a dot ('.'); they should only be given in case the -# language name is needed to interpret the given encoding alias -# correctly (CJK codes often have this need). -# -# Note that the normalize() function which uses this tables -# removes '_' and '-' characters from the encoding part of the -# locale name before doing the lookup. This saves a lot of -# space in the table. -# -# MAL 2004-12-10: -# Updated alias mapping to most recent locale.alias file -# from X.org distribution using makelocalealias.py. -# -# These are the differences compared to the old mapping (Python 2.4 -# and older): -# -# updated 'bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' -# updated 'bg_bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' -# updated 'bulgarian' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' -# updated 'cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2' -# updated 'cz_cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2' -# updated 'czech' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2' -# updated 'dutch' -> 'nl_BE.ISO8859-1' to 'nl_NL.ISO8859-1' -# updated 'et' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15' -# updated 'et_ee' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15' -# updated 'fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15' -# updated 'fi_fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15' -# updated 'iw' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' -# updated 'iw_il' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' -# updated 'japanese' -> 'ja_JP.SJIS' to 'ja_JP.eucJP' -# updated 'lt' -> 'lt_LT.ISO8859-4' to 'lt_LT.ISO8859-13' -# updated 'lv' -> 'lv_LV.ISO8859-4' to 'lv_LV.ISO8859-13' -# updated 'sl' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2' -# updated 'slovene' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2' -# updated 'th_th' -> 'th_TH.TACTIS' to 'th_TH.ISO8859-11' -# updated 'zh_cn' -> 'zh_CN.eucCN' to 'zh_CN.gb2312' -# updated 'zh_cn.big5' -> 'zh_TW.eucTW' to 'zh_TW.big5' -# updated 'zh_tw' -> 'zh_TW.eucTW' to 'zh_TW.big5' -# -# MAL 2008-05-30: -# Updated alias mapping to most recent locale.alias file -# from X.org distribution using makelocalealias.py. -# -# These are the differences compared to the old mapping (Python 2.5 -# and older): -# -# updated 'cs_cs.iso88592' -> 'cs_CZ.ISO8859-2' to 'cs_CS.ISO8859-2' -# updated 'serbocroatian' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' -# updated 'sh' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' -# updated 'sh_hr.iso88592' -> 'sh_HR.ISO8859-2' to 'hr_HR.ISO8859-2' -# updated 'sh_sp' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' -# updated 'sh_yu' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' -# updated 'sp' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5' -# updated 'sp_yu' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5' -# updated 'sr' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' -# updated 'sr@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' -# updated 'sr_sp' -> 'sr_SP.ISO8859-2' to 'sr_CS.ISO8859-2' -# updated 'sr_yu' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' -# updated 'sr_yu.cp1251@cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251' -# updated 'sr_yu.iso88592' -> 'sr_YU.ISO8859-2' to 'sr_CS.ISO8859-2' -# updated 'sr_yu.iso88595' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' -# updated 'sr_yu.iso88595@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' -# updated 'sr_yu.microsoftcp1251@cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251' -# updated 'sr_yu.utf8@cyrillic' -> 'sr_YU.UTF-8' to 'sr_CS.UTF-8' -# updated 'sr_yu@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' -# -# AP 2010-04-12: -# Updated alias mapping to most recent locale.alias file -# from X.org distribution using makelocalealias.py. -# -# These are the differences compared to the old mapping (Python 2.6.5 -# and older): -# -# updated 'ru' -> 'ru_RU.ISO8859-5' to 'ru_RU.UTF-8' -# updated 'ru_ru' -> 'ru_RU.ISO8859-5' to 'ru_RU.UTF-8' -# updated 'serbocroatian' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' -# updated 'sh' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' -# updated 'sh_yu' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' -# updated 'sr' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' -# updated 'sr@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' -# updated 'sr@latn' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' -# updated 'sr_cs.utf8@latn' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8@latin' -# updated 'sr_cs@latn' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' -# updated 'sr_yu' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8@latin' -# updated 'sr_yu.utf8@cyrillic' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8' -# updated 'sr_yu@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' -# -# SS 2013-12-20: -# Updated alias mapping to most recent locale.alias file -# from X.org distribution using makelocalealias.py. -# -# These are the differences compared to the old mapping (Python 3.3.3 -# and older): -# -# updated 'a3' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' -# updated 'a3_az' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' -# updated 'a3_az.koi8c' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' -# updated 'cs_cs.iso88592' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2' -# updated 'hebrew' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' -# updated 'hebrew.iso88598' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' -# updated 'sd' -> 'sd_IN@devanagari.UTF-8' to 'sd_IN.UTF-8' -# updated 'sr@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' -# updated 'sr_cs' -> 'sr_RS.UTF-8' to 'sr_CS.UTF-8' -# updated 'sr_cs.utf8@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' -# updated 'sr_cs@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' -# -# SS 2014-10-01: -# Updated alias mapping with glibc 2.19 supported locales. -# -# SS 2018-05-05: -# Updated alias mapping with glibc 2.27 supported locales. -# -# These are the differences compared to the old mapping (Python 3.6.5 -# and older): -# -# updated 'ca_es@valencia' -> 'ca_ES.ISO8859-15@valencia' to 'ca_ES.UTF-8@valencia' -# updated 'kk_kz' -> 'kk_KZ.RK1048' to 'kk_KZ.ptcp154' -# updated 'russian' -> 'ru_RU.ISO8859-5' to 'ru_RU.KOI8-R' - -locale_alias = { - 'a3': 'az_AZ.KOI8-C', - 'a3_az': 'az_AZ.KOI8-C', - 'a3_az.koic': 'az_AZ.KOI8-C', - 'aa_dj': 'aa_DJ.ISO8859-1', - 'aa_er': 'aa_ER.UTF-8', - 'aa_et': 'aa_ET.UTF-8', - 'af': 'af_ZA.ISO8859-1', - 'af_za': 'af_ZA.ISO8859-1', - 'agr_pe': 'agr_PE.UTF-8', - 'ak_gh': 'ak_GH.UTF-8', - 'am': 'am_ET.UTF-8', - 'am_et': 'am_ET.UTF-8', - 'american': 'en_US.ISO8859-1', - 'an_es': 'an_ES.ISO8859-15', - 'anp_in': 'anp_IN.UTF-8', - 'ar': 'ar_AA.ISO8859-6', - 'ar_aa': 'ar_AA.ISO8859-6', - 'ar_ae': 'ar_AE.ISO8859-6', - 'ar_bh': 'ar_BH.ISO8859-6', - 'ar_dz': 'ar_DZ.ISO8859-6', - 'ar_eg': 'ar_EG.ISO8859-6', - 'ar_in': 'ar_IN.UTF-8', - 'ar_iq': 'ar_IQ.ISO8859-6', - 'ar_jo': 'ar_JO.ISO8859-6', - 'ar_kw': 'ar_KW.ISO8859-6', - 'ar_lb': 'ar_LB.ISO8859-6', - 'ar_ly': 'ar_LY.ISO8859-6', - 'ar_ma': 'ar_MA.ISO8859-6', - 'ar_om': 'ar_OM.ISO8859-6', - 'ar_qa': 'ar_QA.ISO8859-6', - 'ar_sa': 'ar_SA.ISO8859-6', - 'ar_sd': 'ar_SD.ISO8859-6', - 'ar_ss': 'ar_SS.UTF-8', - 'ar_sy': 'ar_SY.ISO8859-6', - 'ar_tn': 'ar_TN.ISO8859-6', - 'ar_ye': 'ar_YE.ISO8859-6', - 'arabic': 'ar_AA.ISO8859-6', - 'as': 'as_IN.UTF-8', - 'as_in': 'as_IN.UTF-8', - 'ast_es': 'ast_ES.ISO8859-15', - 'ayc_pe': 'ayc_PE.UTF-8', - 'az': 'az_AZ.ISO8859-9E', - 'az_az': 'az_AZ.ISO8859-9E', - 'az_az.iso88599e': 'az_AZ.ISO8859-9E', - 'az_ir': 'az_IR.UTF-8', - 'be': 'be_BY.CP1251', - 'be@latin': 'be_BY.UTF-8@latin', - 'be_bg.utf8': 'bg_BG.UTF-8', - 'be_by': 'be_BY.CP1251', - 'be_by@latin': 'be_BY.UTF-8@latin', - 'bem_zm': 'bem_ZM.UTF-8', - 'ber_dz': 'ber_DZ.UTF-8', - 'ber_ma': 'ber_MA.UTF-8', - 'bg': 'bg_BG.CP1251', - 'bg_bg': 'bg_BG.CP1251', - 'bhb_in.utf8': 'bhb_IN.UTF-8', - 'bho_in': 'bho_IN.UTF-8', - 'bho_np': 'bho_NP.UTF-8', - 'bi_vu': 'bi_VU.UTF-8', - 'bn_bd': 'bn_BD.UTF-8', - 'bn_in': 'bn_IN.UTF-8', - 'bo_cn': 'bo_CN.UTF-8', - 'bo_in': 'bo_IN.UTF-8', - 'bokmal': 'nb_NO.ISO8859-1', - 'bokm\xe5l': 'nb_NO.ISO8859-1', - 'br': 'br_FR.ISO8859-1', - 'br_fr': 'br_FR.ISO8859-1', - 'brx_in': 'brx_IN.UTF-8', - 'bs': 'bs_BA.ISO8859-2', - 'bs_ba': 'bs_BA.ISO8859-2', - 'bulgarian': 'bg_BG.CP1251', - 'byn_er': 'byn_ER.UTF-8', - 'c': 'C', - 'c-french': 'fr_CA.ISO8859-1', - 'c.ascii': 'C', - 'c.en': 'C', - 'c.iso88591': 'en_US.ISO8859-1', - 'c.utf8': 'en_US.UTF-8', - 'c_c': 'C', - 'c_c.c': 'C', - 'ca': 'ca_ES.ISO8859-1', - 'ca_ad': 'ca_AD.ISO8859-1', - 'ca_es': 'ca_ES.ISO8859-1', - 'ca_es@valencia': 'ca_ES.UTF-8@valencia', - 'ca_fr': 'ca_FR.ISO8859-1', - 'ca_it': 'ca_IT.ISO8859-1', - 'catalan': 'ca_ES.ISO8859-1', - 'ce_ru': 'ce_RU.UTF-8', - 'cextend': 'en_US.ISO8859-1', - 'chinese-s': 'zh_CN.eucCN', - 'chinese-t': 'zh_TW.eucTW', - 'chr_us': 'chr_US.UTF-8', - 'ckb_iq': 'ckb_IQ.UTF-8', - 'cmn_tw': 'cmn_TW.UTF-8', - 'crh_ua': 'crh_UA.UTF-8', - 'croatian': 'hr_HR.ISO8859-2', - 'cs': 'cs_CZ.ISO8859-2', - 'cs_cs': 'cs_CZ.ISO8859-2', - 'cs_cz': 'cs_CZ.ISO8859-2', - 'csb_pl': 'csb_PL.UTF-8', - 'cv_ru': 'cv_RU.UTF-8', - 'cy': 'cy_GB.ISO8859-1', - 'cy_gb': 'cy_GB.ISO8859-1', - 'cz': 'cs_CZ.ISO8859-2', - 'cz_cz': 'cs_CZ.ISO8859-2', - 'czech': 'cs_CZ.ISO8859-2', - 'da': 'da_DK.ISO8859-1', - 'da_dk': 'da_DK.ISO8859-1', - 'danish': 'da_DK.ISO8859-1', - 'dansk': 'da_DK.ISO8859-1', - 'de': 'de_DE.ISO8859-1', - 'de_at': 'de_AT.ISO8859-1', - 'de_be': 'de_BE.ISO8859-1', - 'de_ch': 'de_CH.ISO8859-1', - 'de_de': 'de_DE.ISO8859-1', - 'de_it': 'de_IT.ISO8859-1', - 'de_li.utf8': 'de_LI.UTF-8', - 'de_lu': 'de_LU.ISO8859-1', - 'deutsch': 'de_DE.ISO8859-1', - 'doi_in': 'doi_IN.UTF-8', - 'dutch': 'nl_NL.ISO8859-1', - 'dutch.iso88591': 'nl_BE.ISO8859-1', - 'dv_mv': 'dv_MV.UTF-8', - 'dz_bt': 'dz_BT.UTF-8', - 'ee': 'ee_EE.ISO8859-4', - 'ee_ee': 'ee_EE.ISO8859-4', - 'eesti': 'et_EE.ISO8859-1', - 'el': 'el_GR.ISO8859-7', - 'el_cy': 'el_CY.ISO8859-7', - 'el_gr': 'el_GR.ISO8859-7', - 'el_gr@euro': 'el_GR.ISO8859-15', - 'en': 'en_US.ISO8859-1', - 'en_ag': 'en_AG.UTF-8', - 'en_au': 'en_AU.ISO8859-1', - 'en_be': 'en_BE.ISO8859-1', - 'en_bw': 'en_BW.ISO8859-1', - 'en_ca': 'en_CA.ISO8859-1', - 'en_dk': 'en_DK.ISO8859-1', - 'en_dl.utf8': 'en_DL.UTF-8', - 'en_gb': 'en_GB.ISO8859-1', - 'en_hk': 'en_HK.ISO8859-1', - 'en_ie': 'en_IE.ISO8859-1', - 'en_il': 'en_IL.UTF-8', - 'en_in': 'en_IN.ISO8859-1', - 'en_ng': 'en_NG.UTF-8', - 'en_nz': 'en_NZ.ISO8859-1', - 'en_ph': 'en_PH.ISO8859-1', - 'en_sc.utf8': 'en_SC.UTF-8', - 'en_sg': 'en_SG.ISO8859-1', - 'en_uk': 'en_GB.ISO8859-1', - 'en_us': 'en_US.ISO8859-1', - 'en_us@euro@euro': 'en_US.ISO8859-15', - 'en_za': 'en_ZA.ISO8859-1', - 'en_zm': 'en_ZM.UTF-8', - 'en_zw': 'en_ZW.ISO8859-1', - 'en_zw.utf8': 'en_ZS.UTF-8', - 'eng_gb': 'en_GB.ISO8859-1', - 'english': 'en_EN.ISO8859-1', - 'english.iso88591': 'en_US.ISO8859-1', - 'english_uk': 'en_GB.ISO8859-1', - 'english_united-states': 'en_US.ISO8859-1', - 'english_united-states.437': 'C', - 'english_us': 'en_US.ISO8859-1', - 'eo': 'eo_XX.ISO8859-3', - 'eo.utf8': 'eo.UTF-8', - 'eo_eo': 'eo_EO.ISO8859-3', - 'eo_us.utf8': 'eo_US.UTF-8', - 'eo_xx': 'eo_XX.ISO8859-3', - 'es': 'es_ES.ISO8859-1', - 'es_ar': 'es_AR.ISO8859-1', - 'es_bo': 'es_BO.ISO8859-1', - 'es_cl': 'es_CL.ISO8859-1', - 'es_co': 'es_CO.ISO8859-1', - 'es_cr': 'es_CR.ISO8859-1', - 'es_cu': 'es_CU.UTF-8', - 'es_do': 'es_DO.ISO8859-1', - 'es_ec': 'es_EC.ISO8859-1', - 'es_es': 'es_ES.ISO8859-1', - 'es_gt': 'es_GT.ISO8859-1', - 'es_hn': 'es_HN.ISO8859-1', - 'es_mx': 'es_MX.ISO8859-1', - 'es_ni': 'es_NI.ISO8859-1', - 'es_pa': 'es_PA.ISO8859-1', - 'es_pe': 'es_PE.ISO8859-1', - 'es_pr': 'es_PR.ISO8859-1', - 'es_py': 'es_PY.ISO8859-1', - 'es_sv': 'es_SV.ISO8859-1', - 'es_us': 'es_US.ISO8859-1', - 'es_uy': 'es_UY.ISO8859-1', - 'es_ve': 'es_VE.ISO8859-1', - 'estonian': 'et_EE.ISO8859-1', - 'et': 'et_EE.ISO8859-15', - 'et_ee': 'et_EE.ISO8859-15', - 'eu': 'eu_ES.ISO8859-1', - 'eu_es': 'eu_ES.ISO8859-1', - 'eu_fr': 'eu_FR.ISO8859-1', - 'fa': 'fa_IR.UTF-8', - 'fa_ir': 'fa_IR.UTF-8', - 'fa_ir.isiri3342': 'fa_IR.ISIRI-3342', - 'ff_sn': 'ff_SN.UTF-8', - 'fi': 'fi_FI.ISO8859-15', - 'fi_fi': 'fi_FI.ISO8859-15', - 'fil_ph': 'fil_PH.UTF-8', - 'finnish': 'fi_FI.ISO8859-1', - 'fo': 'fo_FO.ISO8859-1', - 'fo_fo': 'fo_FO.ISO8859-1', - 'fr': 'fr_FR.ISO8859-1', - 'fr_be': 'fr_BE.ISO8859-1', - 'fr_ca': 'fr_CA.ISO8859-1', - 'fr_ch': 'fr_CH.ISO8859-1', - 'fr_fr': 'fr_FR.ISO8859-1', - 'fr_lu': 'fr_LU.ISO8859-1', - 'fran\xe7ais': 'fr_FR.ISO8859-1', - 'fre_fr': 'fr_FR.ISO8859-1', - 'french': 'fr_FR.ISO8859-1', - 'french.iso88591': 'fr_CH.ISO8859-1', - 'french_france': 'fr_FR.ISO8859-1', - 'fur_it': 'fur_IT.UTF-8', - 'fy_de': 'fy_DE.UTF-8', - 'fy_nl': 'fy_NL.UTF-8', - 'ga': 'ga_IE.ISO8859-1', - 'ga_ie': 'ga_IE.ISO8859-1', - 'galego': 'gl_ES.ISO8859-1', - 'galician': 'gl_ES.ISO8859-1', - 'gd': 'gd_GB.ISO8859-1', - 'gd_gb': 'gd_GB.ISO8859-1', - 'ger_de': 'de_DE.ISO8859-1', - 'german': 'de_DE.ISO8859-1', - 'german.iso88591': 'de_CH.ISO8859-1', - 'german_germany': 'de_DE.ISO8859-1', - 'gez_er': 'gez_ER.UTF-8', - 'gez_et': 'gez_ET.UTF-8', - 'gl': 'gl_ES.ISO8859-1', - 'gl_es': 'gl_ES.ISO8859-1', - 'greek': 'el_GR.ISO8859-7', - 'gu_in': 'gu_IN.UTF-8', - 'gv': 'gv_GB.ISO8859-1', - 'gv_gb': 'gv_GB.ISO8859-1', - 'ha_ng': 'ha_NG.UTF-8', - 'hak_tw': 'hak_TW.UTF-8', - 'he': 'he_IL.ISO8859-8', - 'he_il': 'he_IL.ISO8859-8', - 'hebrew': 'he_IL.ISO8859-8', - 'hi': 'hi_IN.ISCII-DEV', - 'hi_in': 'hi_IN.ISCII-DEV', - 'hi_in.isciidev': 'hi_IN.ISCII-DEV', - 'hif_fj': 'hif_FJ.UTF-8', - 'hne': 'hne_IN.UTF-8', - 'hne_in': 'hne_IN.UTF-8', - 'hr': 'hr_HR.ISO8859-2', - 'hr_hr': 'hr_HR.ISO8859-2', - 'hrvatski': 'hr_HR.ISO8859-2', - 'hsb_de': 'hsb_DE.ISO8859-2', - 'ht_ht': 'ht_HT.UTF-8', - 'hu': 'hu_HU.ISO8859-2', - 'hu_hu': 'hu_HU.ISO8859-2', - 'hungarian': 'hu_HU.ISO8859-2', - 'hy_am': 'hy_AM.UTF-8', - 'hy_am.armscii8': 'hy_AM.ARMSCII_8', - 'ia': 'ia.UTF-8', - 'ia_fr': 'ia_FR.UTF-8', - 'icelandic': 'is_IS.ISO8859-1', - 'id': 'id_ID.ISO8859-1', - 'id_id': 'id_ID.ISO8859-1', - 'ig_ng': 'ig_NG.UTF-8', - 'ik_ca': 'ik_CA.UTF-8', - 'in': 'id_ID.ISO8859-1', - 'in_id': 'id_ID.ISO8859-1', - 'is': 'is_IS.ISO8859-1', - 'is_is': 'is_IS.ISO8859-1', - 'iso-8859-1': 'en_US.ISO8859-1', - 'iso-8859-15': 'en_US.ISO8859-15', - 'iso8859-1': 'en_US.ISO8859-1', - 'iso8859-15': 'en_US.ISO8859-15', - 'iso_8859_1': 'en_US.ISO8859-1', - 'iso_8859_15': 'en_US.ISO8859-15', - 'it': 'it_IT.ISO8859-1', - 'it_ch': 'it_CH.ISO8859-1', - 'it_it': 'it_IT.ISO8859-1', - 'italian': 'it_IT.ISO8859-1', - 'iu': 'iu_CA.NUNACOM-8', - 'iu_ca': 'iu_CA.NUNACOM-8', - 'iu_ca.nunacom8': 'iu_CA.NUNACOM-8', - 'iw': 'he_IL.ISO8859-8', - 'iw_il': 'he_IL.ISO8859-8', - 'iw_il.utf8': 'iw_IL.UTF-8', - 'ja': 'ja_JP.eucJP', - 'ja_jp': 'ja_JP.eucJP', - 'ja_jp.euc': 'ja_JP.eucJP', - 'ja_jp.mscode': 'ja_JP.SJIS', - 'ja_jp.pck': 'ja_JP.SJIS', - 'japan': 'ja_JP.eucJP', - 'japanese': 'ja_JP.eucJP', - 'japanese-euc': 'ja_JP.eucJP', - 'japanese.euc': 'ja_JP.eucJP', - 'jp_jp': 'ja_JP.eucJP', - 'ka': 'ka_GE.GEORGIAN-ACADEMY', - 'ka_ge': 'ka_GE.GEORGIAN-ACADEMY', - 'ka_ge.georgianacademy': 'ka_GE.GEORGIAN-ACADEMY', - 'ka_ge.georgianps': 'ka_GE.GEORGIAN-PS', - 'ka_ge.georgianrs': 'ka_GE.GEORGIAN-ACADEMY', - 'kab_dz': 'kab_DZ.UTF-8', - 'kk_kz': 'kk_KZ.ptcp154', - 'kl': 'kl_GL.ISO8859-1', - 'kl_gl': 'kl_GL.ISO8859-1', - 'km_kh': 'km_KH.UTF-8', - 'kn': 'kn_IN.UTF-8', - 'kn_in': 'kn_IN.UTF-8', - 'ko': 'ko_KR.eucKR', - 'ko_kr': 'ko_KR.eucKR', - 'ko_kr.euc': 'ko_KR.eucKR', - 'kok_in': 'kok_IN.UTF-8', - 'korean': 'ko_KR.eucKR', - 'korean.euc': 'ko_KR.eucKR', - 'ks': 'ks_IN.UTF-8', - 'ks_in': 'ks_IN.UTF-8', - 'ks_in@devanagari.utf8': 'ks_IN.UTF-8@devanagari', - 'ku_tr': 'ku_TR.ISO8859-9', - 'kw': 'kw_GB.ISO8859-1', - 'kw_gb': 'kw_GB.ISO8859-1', - 'ky': 'ky_KG.UTF-8', - 'ky_kg': 'ky_KG.UTF-8', - 'lb_lu': 'lb_LU.UTF-8', - 'lg_ug': 'lg_UG.ISO8859-10', - 'li_be': 'li_BE.UTF-8', - 'li_nl': 'li_NL.UTF-8', - 'lij_it': 'lij_IT.UTF-8', - 'lithuanian': 'lt_LT.ISO8859-13', - 'ln_cd': 'ln_CD.UTF-8', - 'lo': 'lo_LA.MULELAO-1', - 'lo_la': 'lo_LA.MULELAO-1', - 'lo_la.cp1133': 'lo_LA.IBM-CP1133', - 'lo_la.ibmcp1133': 'lo_LA.IBM-CP1133', - 'lo_la.mulelao1': 'lo_LA.MULELAO-1', - 'lt': 'lt_LT.ISO8859-13', - 'lt_lt': 'lt_LT.ISO8859-13', - 'lv': 'lv_LV.ISO8859-13', - 'lv_lv': 'lv_LV.ISO8859-13', - 'lzh_tw': 'lzh_TW.UTF-8', - 'mag_in': 'mag_IN.UTF-8', - 'mai': 'mai_IN.UTF-8', - 'mai_in': 'mai_IN.UTF-8', - 'mai_np': 'mai_NP.UTF-8', - 'mfe_mu': 'mfe_MU.UTF-8', - 'mg_mg': 'mg_MG.ISO8859-15', - 'mhr_ru': 'mhr_RU.UTF-8', - 'mi': 'mi_NZ.ISO8859-1', - 'mi_nz': 'mi_NZ.ISO8859-1', - 'miq_ni': 'miq_NI.UTF-8', - 'mjw_in': 'mjw_IN.UTF-8', - 'mk': 'mk_MK.ISO8859-5', - 'mk_mk': 'mk_MK.ISO8859-5', - 'ml': 'ml_IN.UTF-8', - 'ml_in': 'ml_IN.UTF-8', - 'mn_mn': 'mn_MN.UTF-8', - 'mni_in': 'mni_IN.UTF-8', - 'mr': 'mr_IN.UTF-8', - 'mr_in': 'mr_IN.UTF-8', - 'ms': 'ms_MY.ISO8859-1', - 'ms_my': 'ms_MY.ISO8859-1', - 'mt': 'mt_MT.ISO8859-3', - 'mt_mt': 'mt_MT.ISO8859-3', - 'my_mm': 'my_MM.UTF-8', - 'nan_tw': 'nan_TW.UTF-8', - 'nb': 'nb_NO.ISO8859-1', - 'nb_no': 'nb_NO.ISO8859-1', - 'nds_de': 'nds_DE.UTF-8', - 'nds_nl': 'nds_NL.UTF-8', - 'ne_np': 'ne_NP.UTF-8', - 'nhn_mx': 'nhn_MX.UTF-8', - 'niu_nu': 'niu_NU.UTF-8', - 'niu_nz': 'niu_NZ.UTF-8', - 'nl': 'nl_NL.ISO8859-1', - 'nl_aw': 'nl_AW.UTF-8', - 'nl_be': 'nl_BE.ISO8859-1', - 'nl_nl': 'nl_NL.ISO8859-1', - 'nn': 'nn_NO.ISO8859-1', - 'nn_no': 'nn_NO.ISO8859-1', - 'no': 'no_NO.ISO8859-1', - 'no@nynorsk': 'ny_NO.ISO8859-1', - 'no_no': 'no_NO.ISO8859-1', - 'no_no.iso88591@bokmal': 'no_NO.ISO8859-1', - 'no_no.iso88591@nynorsk': 'no_NO.ISO8859-1', - 'norwegian': 'no_NO.ISO8859-1', - 'nr': 'nr_ZA.ISO8859-1', - 'nr_za': 'nr_ZA.ISO8859-1', - 'nso': 'nso_ZA.ISO8859-15', - 'nso_za': 'nso_ZA.ISO8859-15', - 'ny': 'ny_NO.ISO8859-1', - 'ny_no': 'ny_NO.ISO8859-1', - 'nynorsk': 'nn_NO.ISO8859-1', - 'oc': 'oc_FR.ISO8859-1', - 'oc_fr': 'oc_FR.ISO8859-1', - 'om_et': 'om_ET.UTF-8', - 'om_ke': 'om_KE.ISO8859-1', - 'or': 'or_IN.UTF-8', - 'or_in': 'or_IN.UTF-8', - 'os_ru': 'os_RU.UTF-8', - 'pa': 'pa_IN.UTF-8', - 'pa_in': 'pa_IN.UTF-8', - 'pa_pk': 'pa_PK.UTF-8', - 'pap_an': 'pap_AN.UTF-8', - 'pap_aw': 'pap_AW.UTF-8', - 'pap_cw': 'pap_CW.UTF-8', - 'pd': 'pd_US.ISO8859-1', - 'pd_de': 'pd_DE.ISO8859-1', - 'pd_us': 'pd_US.ISO8859-1', - 'ph': 'ph_PH.ISO8859-1', - 'ph_ph': 'ph_PH.ISO8859-1', - 'pl': 'pl_PL.ISO8859-2', - 'pl_pl': 'pl_PL.ISO8859-2', - 'polish': 'pl_PL.ISO8859-2', - 'portuguese': 'pt_PT.ISO8859-1', - 'portuguese_brazil': 'pt_BR.ISO8859-1', - 'posix': 'C', - 'posix-utf2': 'C', - 'pp': 'pp_AN.ISO8859-1', - 'pp_an': 'pp_AN.ISO8859-1', - 'ps_af': 'ps_AF.UTF-8', - 'pt': 'pt_PT.ISO8859-1', - 'pt_br': 'pt_BR.ISO8859-1', - 'pt_pt': 'pt_PT.ISO8859-1', - 'quz_pe': 'quz_PE.UTF-8', - 'raj_in': 'raj_IN.UTF-8', - 'ro': 'ro_RO.ISO8859-2', - 'ro_ro': 'ro_RO.ISO8859-2', - 'romanian': 'ro_RO.ISO8859-2', - 'ru': 'ru_RU.UTF-8', - 'ru_ru': 'ru_RU.UTF-8', - 'ru_ua': 'ru_UA.KOI8-U', - 'rumanian': 'ro_RO.ISO8859-2', - 'russian': 'ru_RU.KOI8-R', - 'rw': 'rw_RW.ISO8859-1', - 'rw_rw': 'rw_RW.ISO8859-1', - 'sa_in': 'sa_IN.UTF-8', - 'sat_in': 'sat_IN.UTF-8', - 'sc_it': 'sc_IT.UTF-8', - 'sd': 'sd_IN.UTF-8', - 'sd_in': 'sd_IN.UTF-8', - 'sd_in@devanagari.utf8': 'sd_IN.UTF-8@devanagari', - 'sd_pk': 'sd_PK.UTF-8', - 'se_no': 'se_NO.UTF-8', - 'serbocroatian': 'sr_RS.UTF-8@latin', - 'sgs_lt': 'sgs_LT.UTF-8', - 'sh': 'sr_RS.UTF-8@latin', - 'sh_ba.iso88592@bosnia': 'sr_CS.ISO8859-2', - 'sh_hr': 'sh_HR.ISO8859-2', - 'sh_hr.iso88592': 'hr_HR.ISO8859-2', - 'sh_sp': 'sr_CS.ISO8859-2', - 'sh_yu': 'sr_RS.UTF-8@latin', - 'shn_mm': 'shn_MM.UTF-8', - 'shs_ca': 'shs_CA.UTF-8', - 'si': 'si_LK.UTF-8', - 'si_lk': 'si_LK.UTF-8', - 'sid_et': 'sid_ET.UTF-8', - 'sinhala': 'si_LK.UTF-8', - 'sk': 'sk_SK.ISO8859-2', - 'sk_sk': 'sk_SK.ISO8859-2', - 'sl': 'sl_SI.ISO8859-2', - 'sl_cs': 'sl_CS.ISO8859-2', - 'sl_si': 'sl_SI.ISO8859-2', - 'slovak': 'sk_SK.ISO8859-2', - 'slovene': 'sl_SI.ISO8859-2', - 'slovenian': 'sl_SI.ISO8859-2', - 'sm_ws': 'sm_WS.UTF-8', - 'so_dj': 'so_DJ.ISO8859-1', - 'so_et': 'so_ET.UTF-8', - 'so_ke': 'so_KE.ISO8859-1', - 'so_so': 'so_SO.ISO8859-1', - 'sp': 'sr_CS.ISO8859-5', - 'sp_yu': 'sr_CS.ISO8859-5', - 'spanish': 'es_ES.ISO8859-1', - 'spanish_spain': 'es_ES.ISO8859-1', - 'sq': 'sq_AL.ISO8859-2', - 'sq_al': 'sq_AL.ISO8859-2', - 'sq_mk': 'sq_MK.UTF-8', - 'sr': 'sr_RS.UTF-8', - 'sr@cyrillic': 'sr_RS.UTF-8', - 'sr@latn': 'sr_CS.UTF-8@latin', - 'sr_cs': 'sr_CS.UTF-8', - 'sr_cs.iso88592@latn': 'sr_CS.ISO8859-2', - 'sr_cs@latn': 'sr_CS.UTF-8@latin', - 'sr_me': 'sr_ME.UTF-8', - 'sr_rs': 'sr_RS.UTF-8', - 'sr_rs@latn': 'sr_RS.UTF-8@latin', - 'sr_sp': 'sr_CS.ISO8859-2', - 'sr_yu': 'sr_RS.UTF-8@latin', - 'sr_yu.cp1251@cyrillic': 'sr_CS.CP1251', - 'sr_yu.iso88592': 'sr_CS.ISO8859-2', - 'sr_yu.iso88595': 'sr_CS.ISO8859-5', - 'sr_yu.iso88595@cyrillic': 'sr_CS.ISO8859-5', - 'sr_yu.microsoftcp1251@cyrillic': 'sr_CS.CP1251', - 'sr_yu.utf8': 'sr_RS.UTF-8', - 'sr_yu.utf8@cyrillic': 'sr_RS.UTF-8', - 'sr_yu@cyrillic': 'sr_RS.UTF-8', - 'ss': 'ss_ZA.ISO8859-1', - 'ss_za': 'ss_ZA.ISO8859-1', - 'st': 'st_ZA.ISO8859-1', - 'st_za': 'st_ZA.ISO8859-1', - 'sv': 'sv_SE.ISO8859-1', - 'sv_fi': 'sv_FI.ISO8859-1', - 'sv_se': 'sv_SE.ISO8859-1', - 'sw_ke': 'sw_KE.UTF-8', - 'sw_tz': 'sw_TZ.UTF-8', - 'swedish': 'sv_SE.ISO8859-1', - 'szl_pl': 'szl_PL.UTF-8', - 'ta': 'ta_IN.TSCII-0', - 'ta_in': 'ta_IN.TSCII-0', - 'ta_in.tscii': 'ta_IN.TSCII-0', - 'ta_in.tscii0': 'ta_IN.TSCII-0', - 'ta_lk': 'ta_LK.UTF-8', - 'tcy_in.utf8': 'tcy_IN.UTF-8', - 'te': 'te_IN.UTF-8', - 'te_in': 'te_IN.UTF-8', - 'tg': 'tg_TJ.KOI8-C', - 'tg_tj': 'tg_TJ.KOI8-C', - 'th': 'th_TH.ISO8859-11', - 'th_th': 'th_TH.ISO8859-11', - 'th_th.tactis': 'th_TH.TIS620', - 'th_th.tis620': 'th_TH.TIS620', - 'thai': 'th_TH.ISO8859-11', - 'the_np': 'the_NP.UTF-8', - 'ti_er': 'ti_ER.UTF-8', - 'ti_et': 'ti_ET.UTF-8', - 'tig_er': 'tig_ER.UTF-8', - 'tk_tm': 'tk_TM.UTF-8', - 'tl': 'tl_PH.ISO8859-1', - 'tl_ph': 'tl_PH.ISO8859-1', - 'tn': 'tn_ZA.ISO8859-15', - 'tn_za': 'tn_ZA.ISO8859-15', - 'to_to': 'to_TO.UTF-8', - 'tpi_pg': 'tpi_PG.UTF-8', - 'tr': 'tr_TR.ISO8859-9', - 'tr_cy': 'tr_CY.ISO8859-9', - 'tr_tr': 'tr_TR.ISO8859-9', - 'ts': 'ts_ZA.ISO8859-1', - 'ts_za': 'ts_ZA.ISO8859-1', - 'tt': 'tt_RU.TATAR-CYR', - 'tt_ru': 'tt_RU.TATAR-CYR', - 'tt_ru.tatarcyr': 'tt_RU.TATAR-CYR', - 'tt_ru@iqtelif': 'tt_RU.UTF-8@iqtelif', - 'turkish': 'tr_TR.ISO8859-9', - 'ug_cn': 'ug_CN.UTF-8', - 'uk': 'uk_UA.KOI8-U', - 'uk_ua': 'uk_UA.KOI8-U', - 'univ': 'en_US.utf', - 'universal': 'en_US.utf', - 'universal.utf8@ucs4': 'en_US.UTF-8', - 'unm_us': 'unm_US.UTF-8', - 'ur': 'ur_PK.CP1256', - 'ur_in': 'ur_IN.UTF-8', - 'ur_pk': 'ur_PK.CP1256', - 'uz': 'uz_UZ.UTF-8', - 'uz_uz': 'uz_UZ.UTF-8', - 'uz_uz@cyrillic': 'uz_UZ.UTF-8', - 've': 've_ZA.UTF-8', - 've_za': 've_ZA.UTF-8', - 'vi': 'vi_VN.TCVN', - 'vi_vn': 'vi_VN.TCVN', - 'vi_vn.tcvn': 'vi_VN.TCVN', - 'vi_vn.tcvn5712': 'vi_VN.TCVN', - 'vi_vn.viscii': 'vi_VN.VISCII', - 'vi_vn.viscii111': 'vi_VN.VISCII', - 'wa': 'wa_BE.ISO8859-1', - 'wa_be': 'wa_BE.ISO8859-1', - 'wae_ch': 'wae_CH.UTF-8', - 'wal_et': 'wal_ET.UTF-8', - 'wo_sn': 'wo_SN.UTF-8', - 'xh': 'xh_ZA.ISO8859-1', - 'xh_za': 'xh_ZA.ISO8859-1', - 'yi': 'yi_US.CP1255', - 'yi_us': 'yi_US.CP1255', - 'yo_ng': 'yo_NG.UTF-8', - 'yue_hk': 'yue_HK.UTF-8', - 'yuw_pg': 'yuw_PG.UTF-8', - 'zh': 'zh_CN.eucCN', - 'zh_cn': 'zh_CN.gb2312', - 'zh_cn.big5': 'zh_TW.big5', - 'zh_cn.euc': 'zh_CN.eucCN', - 'zh_hk': 'zh_HK.big5hkscs', - 'zh_hk.big5hk': 'zh_HK.big5hkscs', - 'zh_sg': 'zh_SG.GB2312', - 'zh_sg.gbk': 'zh_SG.GBK', - 'zh_tw': 'zh_TW.big5', - 'zh_tw.euc': 'zh_TW.eucTW', - 'zh_tw.euctw': 'zh_TW.eucTW', - 'zu': 'zu_ZA.ISO8859-1', - 'zu_za': 'zu_ZA.ISO8859-1', -} - -# -# This maps Windows language identifiers to locale strings. -# -# This list has been updated from -# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_238z.asp -# to include every locale up to Windows Vista. -# -# NOTE: this mapping is incomplete. If your language is missing, please -# submit a bug report to the Python bug tracker at http://bugs.python.org/ -# Make sure you include the missing language identifier and the suggested -# locale code. -# - -windows_locale = { - 0x0436: "af_ZA", # Afrikaans - 0x041c: "sq_AL", # Albanian - 0x0484: "gsw_FR",# Alsatian - France - 0x045e: "am_ET", # Amharic - Ethiopia - 0x0401: "ar_SA", # Arabic - Saudi Arabia - 0x0801: "ar_IQ", # Arabic - Iraq - 0x0c01: "ar_EG", # Arabic - Egypt - 0x1001: "ar_LY", # Arabic - Libya - 0x1401: "ar_DZ", # Arabic - Algeria - 0x1801: "ar_MA", # Arabic - Morocco - 0x1c01: "ar_TN", # Arabic - Tunisia - 0x2001: "ar_OM", # Arabic - Oman - 0x2401: "ar_YE", # Arabic - Yemen - 0x2801: "ar_SY", # Arabic - Syria - 0x2c01: "ar_JO", # Arabic - Jordan - 0x3001: "ar_LB", # Arabic - Lebanon - 0x3401: "ar_KW", # Arabic - Kuwait - 0x3801: "ar_AE", # Arabic - United Arab Emirates - 0x3c01: "ar_BH", # Arabic - Bahrain - 0x4001: "ar_QA", # Arabic - Qatar - 0x042b: "hy_AM", # Armenian - 0x044d: "as_IN", # Assamese - India - 0x042c: "az_AZ", # Azeri - Latin - 0x082c: "az_AZ", # Azeri - Cyrillic - 0x046d: "ba_RU", # Bashkir - 0x042d: "eu_ES", # Basque - Russia - 0x0423: "be_BY", # Belarusian - 0x0445: "bn_IN", # Begali - 0x201a: "bs_BA", # Bosnian - Cyrillic - 0x141a: "bs_BA", # Bosnian - Latin - 0x047e: "br_FR", # Breton - France - 0x0402: "bg_BG", # Bulgarian -# 0x0455: "my_MM", # Burmese - Not supported - 0x0403: "ca_ES", # Catalan - 0x0004: "zh_CHS",# Chinese - Simplified - 0x0404: "zh_TW", # Chinese - Taiwan - 0x0804: "zh_CN", # Chinese - PRC - 0x0c04: "zh_HK", # Chinese - Hong Kong S.A.R. - 0x1004: "zh_SG", # Chinese - Singapore - 0x1404: "zh_MO", # Chinese - Macao S.A.R. - 0x7c04: "zh_CHT",# Chinese - Traditional - 0x0483: "co_FR", # Corsican - France - 0x041a: "hr_HR", # Croatian - 0x101a: "hr_BA", # Croatian - Bosnia - 0x0405: "cs_CZ", # Czech - 0x0406: "da_DK", # Danish - 0x048c: "gbz_AF",# Dari - Afghanistan - 0x0465: "div_MV",# Divehi - Maldives - 0x0413: "nl_NL", # Dutch - The Netherlands - 0x0813: "nl_BE", # Dutch - Belgium - 0x0409: "en_US", # English - United States - 0x0809: "en_GB", # English - United Kingdom - 0x0c09: "en_AU", # English - Australia - 0x1009: "en_CA", # English - Canada - 0x1409: "en_NZ", # English - New Zealand - 0x1809: "en_IE", # English - Ireland - 0x1c09: "en_ZA", # English - South Africa - 0x2009: "en_JA", # English - Jamaica - 0x2409: "en_CB", # English - Caribbean - 0x2809: "en_BZ", # English - Belize - 0x2c09: "en_TT", # English - Trinidad - 0x3009: "en_ZW", # English - Zimbabwe - 0x3409: "en_PH", # English - Philippines - 0x4009: "en_IN", # English - India - 0x4409: "en_MY", # English - Malaysia - 0x4809: "en_IN", # English - Singapore - 0x0425: "et_EE", # Estonian - 0x0438: "fo_FO", # Faroese - 0x0464: "fil_PH",# Filipino - 0x040b: "fi_FI", # Finnish - 0x040c: "fr_FR", # French - France - 0x080c: "fr_BE", # French - Belgium - 0x0c0c: "fr_CA", # French - Canada - 0x100c: "fr_CH", # French - Switzerland - 0x140c: "fr_LU", # French - Luxembourg - 0x180c: "fr_MC", # French - Monaco - 0x0462: "fy_NL", # Frisian - Netherlands - 0x0456: "gl_ES", # Galician - 0x0437: "ka_GE", # Georgian - 0x0407: "de_DE", # German - Germany - 0x0807: "de_CH", # German - Switzerland - 0x0c07: "de_AT", # German - Austria - 0x1007: "de_LU", # German - Luxembourg - 0x1407: "de_LI", # German - Liechtenstein - 0x0408: "el_GR", # Greek - 0x046f: "kl_GL", # Greenlandic - Greenland - 0x0447: "gu_IN", # Gujarati - 0x0468: "ha_NG", # Hausa - Latin - 0x040d: "he_IL", # Hebrew - 0x0439: "hi_IN", # Hindi - 0x040e: "hu_HU", # Hungarian - 0x040f: "is_IS", # Icelandic - 0x0421: "id_ID", # Indonesian - 0x045d: "iu_CA", # Inuktitut - Syllabics - 0x085d: "iu_CA", # Inuktitut - Latin - 0x083c: "ga_IE", # Irish - Ireland - 0x0410: "it_IT", # Italian - Italy - 0x0810: "it_CH", # Italian - Switzerland - 0x0411: "ja_JP", # Japanese - 0x044b: "kn_IN", # Kannada - India - 0x043f: "kk_KZ", # Kazakh - 0x0453: "kh_KH", # Khmer - Cambodia - 0x0486: "qut_GT",# K'iche - Guatemala - 0x0487: "rw_RW", # Kinyarwanda - Rwanda - 0x0457: "kok_IN",# Konkani - 0x0412: "ko_KR", # Korean - 0x0440: "ky_KG", # Kyrgyz - 0x0454: "lo_LA", # Lao - Lao PDR - 0x0426: "lv_LV", # Latvian - 0x0427: "lt_LT", # Lithuanian - 0x082e: "dsb_DE",# Lower Sorbian - Germany - 0x046e: "lb_LU", # Luxembourgish - 0x042f: "mk_MK", # FYROM Macedonian - 0x043e: "ms_MY", # Malay - Malaysia - 0x083e: "ms_BN", # Malay - Brunei Darussalam - 0x044c: "ml_IN", # Malayalam - India - 0x043a: "mt_MT", # Maltese - 0x0481: "mi_NZ", # Maori - 0x047a: "arn_CL",# Mapudungun - 0x044e: "mr_IN", # Marathi - 0x047c: "moh_CA",# Mohawk - Canada - 0x0450: "mn_MN", # Mongolian - Cyrillic - 0x0850: "mn_CN", # Mongolian - PRC - 0x0461: "ne_NP", # Nepali - 0x0414: "nb_NO", # Norwegian - Bokmal - 0x0814: "nn_NO", # Norwegian - Nynorsk - 0x0482: "oc_FR", # Occitan - France - 0x0448: "or_IN", # Oriya - India - 0x0463: "ps_AF", # Pashto - Afghanistan - 0x0429: "fa_IR", # Persian - 0x0415: "pl_PL", # Polish - 0x0416: "pt_BR", # Portuguese - Brazil - 0x0816: "pt_PT", # Portuguese - Portugal - 0x0446: "pa_IN", # Punjabi - 0x046b: "quz_BO",# Quechua (Bolivia) - 0x086b: "quz_EC",# Quechua (Ecuador) - 0x0c6b: "quz_PE",# Quechua (Peru) - 0x0418: "ro_RO", # Romanian - Romania - 0x0417: "rm_CH", # Romansh - 0x0419: "ru_RU", # Russian - 0x243b: "smn_FI",# Sami Finland - 0x103b: "smj_NO",# Sami Norway - 0x143b: "smj_SE",# Sami Sweden - 0x043b: "se_NO", # Sami Northern Norway - 0x083b: "se_SE", # Sami Northern Sweden - 0x0c3b: "se_FI", # Sami Northern Finland - 0x203b: "sms_FI",# Sami Skolt - 0x183b: "sma_NO",# Sami Southern Norway - 0x1c3b: "sma_SE",# Sami Southern Sweden - 0x044f: "sa_IN", # Sanskrit - 0x0c1a: "sr_SP", # Serbian - Cyrillic - 0x1c1a: "sr_BA", # Serbian - Bosnia Cyrillic - 0x081a: "sr_SP", # Serbian - Latin - 0x181a: "sr_BA", # Serbian - Bosnia Latin - 0x045b: "si_LK", # Sinhala - Sri Lanka - 0x046c: "ns_ZA", # Northern Sotho - 0x0432: "tn_ZA", # Setswana - Southern Africa - 0x041b: "sk_SK", # Slovak - 0x0424: "sl_SI", # Slovenian - 0x040a: "es_ES", # Spanish - Spain - 0x080a: "es_MX", # Spanish - Mexico - 0x0c0a: "es_ES", # Spanish - Spain (Modern) - 0x100a: "es_GT", # Spanish - Guatemala - 0x140a: "es_CR", # Spanish - Costa Rica - 0x180a: "es_PA", # Spanish - Panama - 0x1c0a: "es_DO", # Spanish - Dominican Republic - 0x200a: "es_VE", # Spanish - Venezuela - 0x240a: "es_CO", # Spanish - Colombia - 0x280a: "es_PE", # Spanish - Peru - 0x2c0a: "es_AR", # Spanish - Argentina - 0x300a: "es_EC", # Spanish - Ecuador - 0x340a: "es_CL", # Spanish - Chile - 0x380a: "es_UR", # Spanish - Uruguay - 0x3c0a: "es_PY", # Spanish - Paraguay - 0x400a: "es_BO", # Spanish - Bolivia - 0x440a: "es_SV", # Spanish - El Salvador - 0x480a: "es_HN", # Spanish - Honduras - 0x4c0a: "es_NI", # Spanish - Nicaragua - 0x500a: "es_PR", # Spanish - Puerto Rico - 0x540a: "es_US", # Spanish - United States -# 0x0430: "", # Sutu - Not supported - 0x0441: "sw_KE", # Swahili - 0x041d: "sv_SE", # Swedish - Sweden - 0x081d: "sv_FI", # Swedish - Finland - 0x045a: "syr_SY",# Syriac - 0x0428: "tg_TJ", # Tajik - Cyrillic - 0x085f: "tmz_DZ",# Tamazight - Latin - 0x0449: "ta_IN", # Tamil - 0x0444: "tt_RU", # Tatar - 0x044a: "te_IN", # Telugu - 0x041e: "th_TH", # Thai - 0x0851: "bo_BT", # Tibetan - Bhutan - 0x0451: "bo_CN", # Tibetan - PRC - 0x041f: "tr_TR", # Turkish - 0x0442: "tk_TM", # Turkmen - Cyrillic - 0x0480: "ug_CN", # Uighur - Arabic - 0x0422: "uk_UA", # Ukrainian - 0x042e: "wen_DE",# Upper Sorbian - Germany - 0x0420: "ur_PK", # Urdu - 0x0820: "ur_IN", # Urdu - India - 0x0443: "uz_UZ", # Uzbek - Latin - 0x0843: "uz_UZ", # Uzbek - Cyrillic - 0x042a: "vi_VN", # Vietnamese - 0x0452: "cy_GB", # Welsh - 0x0488: "wo_SN", # Wolof - Senegal - 0x0434: "xh_ZA", # Xhosa - South Africa - 0x0485: "sah_RU",# Yakut - Cyrillic - 0x0478: "ii_CN", # Yi - PRC - 0x046a: "yo_NG", # Yoruba - Nigeria - 0x0435: "zu_ZA", # Zulu -} - -def _print_locale(): - - """ Test function. - """ - categories = {} - def _init_categories(categories=categories): - for k,v in globals().items(): - if k[:3] == 'LC_': - categories[k] = v - _init_categories() - del categories['LC_ALL'] - - print('Locale defaults as determined by getdefaultlocale():') - print('-'*72) - lang, enc = getdefaultlocale() - print('Language: ', lang or '(undefined)') - print('Encoding: ', enc or '(undefined)') - print() - - print('Locale settings on startup:') - print('-'*72) - for name,category in categories.items(): - print(name, '...') - lang, enc = getlocale(category) - print(' Language: ', lang or '(undefined)') - print(' Encoding: ', enc or '(undefined)') - print() - - print() - print('Locale settings after calling resetlocale():') - print('-'*72) - resetlocale() - for name,category in categories.items(): - print(name, '...') - lang, enc = getlocale(category) - print(' Language: ', lang or '(undefined)') - print(' Encoding: ', enc or '(undefined)') - print() - - try: - setlocale(LC_ALL, "") - except: - print('NOTE:') - print('setlocale(LC_ALL, "") does not support the default locale') - print('given in the OS environment variables.') - else: - print() - print('Locale settings after calling setlocale(LC_ALL, ""):') - print('-'*72) - for name,category in categories.items(): - print(name, '...') - lang, enc = getlocale(category) - print(' Language: ', lang or '(undefined)') - print(' Encoding: ', enc or '(undefined)') - print() - -### - -try: - LC_MESSAGES -except NameError: - pass -else: - __all__.append("LC_MESSAGES") - -if __name__=='__main__': - print('Locale aliasing:') - print() - _print_locale() - print() - print('Number formatting:') - print() - _test() diff --git a/python/Lib/logging/__init__.py b/python/Lib/logging/__init__.py deleted file mode 100644 index b098187..0000000 --- a/python/Lib/logging/__init__.py +++ /dev/null @@ -1,2273 +0,0 @@ -# Copyright 2001-2019 by Vinay Sajip. All Rights Reserved. -# -# Permission to use, copy, modify, and distribute this software and its -# documentation for any purpose and without fee is hereby granted, -# provided that the above copyright notice appear in all copies and that -# both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of Vinay Sajip -# not be used in advertising or publicity pertaining to distribution -# of the software without specific, written prior permission. -# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL -# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER -# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -""" -Logging package for Python. Based on PEP 282 and comments thereto in -comp.lang.python. - -Copyright (C) 2001-2019 Vinay Sajip. All Rights Reserved. - -To use, simply 'import logging' and log away! -""" - -import sys, os, time, io, re, traceback, warnings, weakref, collections.abc - -from types import GenericAlias -from string import Template -from string import Formatter as StrFormatter - - -__all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', - 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', - 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', - 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', - 'captureWarnings', 'critical', 'debug', 'disable', 'error', - 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', - 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown', - 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory', - 'lastResort', 'raiseExceptions', 'getLevelNamesMapping'] - -import threading - -__author__ = "Vinay Sajip " -__status__ = "production" -# The following module attributes are no longer updated. -__version__ = "0.5.1.2" -__date__ = "07 February 2010" - -#--------------------------------------------------------------------------- -# Miscellaneous module data -#--------------------------------------------------------------------------- - -# -#_startTime is used as the base when calculating the relative time of events -# -_startTime = time.time() - -# -#raiseExceptions is used to see if exceptions during handling should be -#propagated -# -raiseExceptions = True - -# -# If you don't want threading information in the log, set this to zero -# -logThreads = True - -# -# If you don't want multiprocessing information in the log, set this to zero -# -logMultiprocessing = True - -# -# If you don't want process information in the log, set this to zero -# -logProcesses = True - -#--------------------------------------------------------------------------- -# Level related stuff -#--------------------------------------------------------------------------- -# -# Default levels and level names, these can be replaced with any positive set -# of values having corresponding names. There is a pseudo-level, NOTSET, which -# is only really there as a lower limit for user-defined levels. Handlers and -# loggers are initialized with NOTSET so that they will log all messages, even -# at user-defined levels. -# - -CRITICAL = 50 -FATAL = CRITICAL -ERROR = 40 -WARNING = 30 -WARN = WARNING -INFO = 20 -DEBUG = 10 -NOTSET = 0 - -_levelToName = { - CRITICAL: 'CRITICAL', - ERROR: 'ERROR', - WARNING: 'WARNING', - INFO: 'INFO', - DEBUG: 'DEBUG', - NOTSET: 'NOTSET', -} -_nameToLevel = { - 'CRITICAL': CRITICAL, - 'FATAL': FATAL, - 'ERROR': ERROR, - 'WARN': WARNING, - 'WARNING': WARNING, - 'INFO': INFO, - 'DEBUG': DEBUG, - 'NOTSET': NOTSET, -} - -def getLevelNamesMapping(): - return _nameToLevel.copy() - -def getLevelName(level): - """ - Return the textual or numeric representation of logging level 'level'. - - If the level is one of the predefined levels (CRITICAL, ERROR, WARNING, - INFO, DEBUG) then you get the corresponding string. If you have - associated levels with names using addLevelName then the name you have - associated with 'level' is returned. - - If a numeric value corresponding to one of the defined levels is passed - in, the corresponding string representation is returned. - - If a string representation of the level is passed in, the corresponding - numeric value is returned. - - If no matching numeric or string value is passed in, the string - 'Level %s' % level is returned. - """ - # See Issues #22386, #27937 and #29220 for why it's this way - result = _levelToName.get(level) - if result is not None: - return result - result = _nameToLevel.get(level) - if result is not None: - return result - return "Level %s" % level - -def addLevelName(level, levelName): - """ - Associate 'levelName' with 'level'. - - This is used when converting levels to text during message formatting. - """ - _acquireLock() - try: #unlikely to cause an exception, but you never know... - _levelToName[level] = levelName - _nameToLevel[levelName] = level - finally: - _releaseLock() - -if hasattr(sys, "_getframe"): - currentframe = lambda: sys._getframe(1) -else: #pragma: no cover - def currentframe(): - """Return the frame object for the caller's stack frame.""" - try: - raise Exception - except Exception: - return sys.exc_info()[2].tb_frame.f_back - -# -# _srcfile is used when walking the stack to check when we've got the first -# caller stack frame, by skipping frames whose filename is that of this -# module's source. It therefore should contain the filename of this module's -# source file. -# -# Ordinarily we would use __file__ for this, but frozen modules don't always -# have __file__ set, for some reason (see Issue #21736). Thus, we get the -# filename from a handy code object from a function defined in this module. -# (There's no particular reason for picking addLevelName.) -# - -_srcfile = os.path.normcase(addLevelName.__code__.co_filename) - -# _srcfile is only used in conjunction with sys._getframe(). -# Setting _srcfile to None will prevent findCaller() from being called. This -# way, you can avoid the overhead of fetching caller information. - -# The following is based on warnings._is_internal_frame. It makes sure that -# frames of the import mechanism are skipped when logging at module level and -# using a stacklevel value greater than one. -def _is_internal_frame(frame): - """Signal whether the frame is a CPython or logging module internal.""" - filename = os.path.normcase(frame.f_code.co_filename) - return filename == _srcfile or ( - "importlib" in filename and "_bootstrap" in filename - ) - - -def _checkLevel(level): - if isinstance(level, int): - rv = level - elif str(level) == level: - if level not in _nameToLevel: - raise ValueError("Unknown level: %r" % level) - rv = _nameToLevel[level] - else: - raise TypeError("Level not an integer or a valid string: %r" - % (level,)) - return rv - -#--------------------------------------------------------------------------- -# Thread-related stuff -#--------------------------------------------------------------------------- - -# -#_lock is used to serialize access to shared data structures in this module. -#This needs to be an RLock because fileConfig() creates and configures -#Handlers, and so might arbitrary user threads. Since Handler code updates the -#shared dictionary _handlers, it needs to acquire the lock. But if configuring, -#the lock would already have been acquired - so we need an RLock. -#The same argument applies to Loggers and Manager.loggerDict. -# -_lock = threading.RLock() - -def _acquireLock(): - """ - Acquire the module-level lock for serializing access to shared data. - - This should be released with _releaseLock(). - """ - if _lock: - _lock.acquire() - -def _releaseLock(): - """ - Release the module-level lock acquired by calling _acquireLock(). - """ - if _lock: - _lock.release() - - -# Prevent a held logging lock from blocking a child from logging. - -if not hasattr(os, 'register_at_fork'): # Windows and friends. - def _register_at_fork_reinit_lock(instance): - pass # no-op when os.register_at_fork does not exist. -else: - # A collection of instances with a _at_fork_reinit method (logging.Handler) - # to be called in the child after forking. The weakref avoids us keeping - # discarded Handler instances alive. - _at_fork_reinit_lock_weakset = weakref.WeakSet() - - def _register_at_fork_reinit_lock(instance): - _acquireLock() - try: - _at_fork_reinit_lock_weakset.add(instance) - finally: - _releaseLock() - - def _after_at_fork_child_reinit_locks(): - for handler in _at_fork_reinit_lock_weakset: - handler._at_fork_reinit() - - # _acquireLock() was called in the parent before forking. - # The lock is reinitialized to unlocked state. - _lock._at_fork_reinit() - - os.register_at_fork(before=_acquireLock, - after_in_child=_after_at_fork_child_reinit_locks, - after_in_parent=_releaseLock) - - -#--------------------------------------------------------------------------- -# The logging record -#--------------------------------------------------------------------------- - -class LogRecord(object): - """ - A LogRecord instance represents an event being logged. - - LogRecord instances are created every time something is logged. They - contain all the information pertinent to the event being logged. The - main information passed in is in msg and args, which are combined - using str(msg) % args to create the message field of the record. The - record also includes information such as when the record was created, - the source line where the logging call was made, and any exception - information to be logged. - """ - def __init__(self, name, level, pathname, lineno, - msg, args, exc_info, func=None, sinfo=None, **kwargs): - """ - Initialize a logging record with interesting information. - """ - ct = time.time() - self.name = name - self.msg = msg - # - # The following statement allows passing of a dictionary as a sole - # argument, so that you can do something like - # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2}) - # Suggested by Stefan Behnel. - # Note that without the test for args[0], we get a problem because - # during formatting, we test to see if the arg is present using - # 'if self.args:'. If the event being logged is e.g. 'Value is %d' - # and if the passed arg fails 'if self.args:' then no formatting - # is done. For example, logger.warning('Value is %d', 0) would log - # 'Value is %d' instead of 'Value is 0'. - # For the use case of passing a dictionary, this should not be a - # problem. - # Issue #21172: a request was made to relax the isinstance check - # to hasattr(args[0], '__getitem__'). However, the docs on string - # formatting still seem to suggest a mapping object is required. - # Thus, while not removing the isinstance check, it does now look - # for collections.abc.Mapping rather than, as before, dict. - if (args and len(args) == 1 and isinstance(args[0], collections.abc.Mapping) - and args[0]): - args = args[0] - self.args = args - self.levelname = getLevelName(level) - self.levelno = level - self.pathname = pathname - try: - self.filename = os.path.basename(pathname) - self.module = os.path.splitext(self.filename)[0] - except (TypeError, ValueError, AttributeError): - self.filename = pathname - self.module = "Unknown module" - self.exc_info = exc_info - self.exc_text = None # used to cache the traceback text - self.stack_info = sinfo - self.lineno = lineno - self.funcName = func - self.created = ct - self.msecs = int((ct - int(ct)) * 1000) + 0.0 # see gh-89047 - self.relativeCreated = (self.created - _startTime) * 1000 - if logThreads: - self.thread = threading.get_ident() - self.threadName = threading.current_thread().name - else: # pragma: no cover - self.thread = None - self.threadName = None - if not logMultiprocessing: # pragma: no cover - self.processName = None - else: - self.processName = 'MainProcess' - mp = sys.modules.get('multiprocessing') - if mp is not None: - # Errors may occur if multiprocessing has not finished loading - # yet - e.g. if a custom import hook causes third-party code - # to run when multiprocessing calls import. See issue 8200 - # for an example - try: - self.processName = mp.current_process().name - except Exception: #pragma: no cover - pass - if logProcesses and hasattr(os, 'getpid'): - self.process = os.getpid() - else: - self.process = None - - def __repr__(self): - return ''%(self.name, self.levelno, - self.pathname, self.lineno, self.msg) - - def getMessage(self): - """ - Return the message for this LogRecord. - - Return the message for this LogRecord after merging any user-supplied - arguments with the message. - """ - msg = str(self.msg) - if self.args: - msg = msg % self.args - return msg - -# -# Determine which class to use when instantiating log records. -# -_logRecordFactory = LogRecord - -def setLogRecordFactory(factory): - """ - Set the factory to be used when instantiating a log record. - - :param factory: A callable which will be called to instantiate - a log record. - """ - global _logRecordFactory - _logRecordFactory = factory - -def getLogRecordFactory(): - """ - Return the factory to be used when instantiating a log record. - """ - - return _logRecordFactory - -def makeLogRecord(dict): - """ - Make a LogRecord whose attributes are defined by the specified dictionary, - This function is useful for converting a logging event received over - a socket connection (which is sent as a dictionary) into a LogRecord - instance. - """ - rv = _logRecordFactory(None, None, "", 0, "", (), None, None) - rv.__dict__.update(dict) - return rv - - -#--------------------------------------------------------------------------- -# Formatter classes and functions -#--------------------------------------------------------------------------- -_str_formatter = StrFormatter() -del StrFormatter - - -class PercentStyle(object): - - default_format = '%(message)s' - asctime_format = '%(asctime)s' - asctime_search = '%(asctime)' - validation_pattern = re.compile(r'%\(\w+\)[#0+ -]*(\*|\d+)?(\.(\*|\d+))?[diouxefgcrsa%]', re.I) - - def __init__(self, fmt, *, defaults=None): - self._fmt = fmt or self.default_format - self._defaults = defaults - - def usesTime(self): - return self._fmt.find(self.asctime_search) >= 0 - - def validate(self): - """Validate the input format, ensure it matches the correct style""" - if not self.validation_pattern.search(self._fmt): - raise ValueError("Invalid format '%s' for '%s' style" % (self._fmt, self.default_format[0])) - - def _format(self, record): - if defaults := self._defaults: - values = defaults | record.__dict__ - else: - values = record.__dict__ - return self._fmt % values - - def format(self, record): - try: - return self._format(record) - except KeyError as e: - raise ValueError('Formatting field not found in record: %s' % e) - - -class StrFormatStyle(PercentStyle): - default_format = '{message}' - asctime_format = '{asctime}' - asctime_search = '{asctime' - - fmt_spec = re.compile(r'^(.?[<>=^])?[+ -]?#?0?(\d+|{\w+})?[,_]?(\.(\d+|{\w+}))?[bcdefgnosx%]?$', re.I) - field_spec = re.compile(r'^(\d+|\w+)(\.\w+|\[[^]]+\])*$') - - def _format(self, record): - if defaults := self._defaults: - values = defaults | record.__dict__ - else: - values = record.__dict__ - return self._fmt.format(**values) - - def validate(self): - """Validate the input format, ensure it is the correct string formatting style""" - fields = set() - try: - for _, fieldname, spec, conversion in _str_formatter.parse(self._fmt): - if fieldname: - if not self.field_spec.match(fieldname): - raise ValueError('invalid field name/expression: %r' % fieldname) - fields.add(fieldname) - if conversion and conversion not in 'rsa': - raise ValueError('invalid conversion: %r' % conversion) - if spec and not self.fmt_spec.match(spec): - raise ValueError('bad specifier: %r' % spec) - except ValueError as e: - raise ValueError('invalid format: %s' % e) - if not fields: - raise ValueError('invalid format: no fields') - - -class StringTemplateStyle(PercentStyle): - default_format = '${message}' - asctime_format = '${asctime}' - asctime_search = '${asctime}' - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._tpl = Template(self._fmt) - - def usesTime(self): - fmt = self._fmt - return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_search) >= 0 - - def validate(self): - pattern = Template.pattern - fields = set() - for m in pattern.finditer(self._fmt): - d = m.groupdict() - if d['named']: - fields.add(d['named']) - elif d['braced']: - fields.add(d['braced']) - elif m.group(0) == '$': - raise ValueError('invalid format: bare \'$\' not allowed') - if not fields: - raise ValueError('invalid format: no fields') - - def _format(self, record): - if defaults := self._defaults: - values = defaults | record.__dict__ - else: - values = record.__dict__ - return self._tpl.substitute(**values) - - -BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" - -_STYLES = { - '%': (PercentStyle, BASIC_FORMAT), - '{': (StrFormatStyle, '{levelname}:{name}:{message}'), - '$': (StringTemplateStyle, '${levelname}:${name}:${message}'), -} - -class Formatter(object): - """ - Formatter instances are used to convert a LogRecord to text. - - Formatters need to know how a LogRecord is constructed. They are - responsible for converting a LogRecord to (usually) a string which can - be interpreted by either a human or an external system. The base Formatter - allows a formatting string to be specified. If none is supplied, the - style-dependent default value, "%(message)s", "{message}", or - "${message}", is used. - - The Formatter can be initialized with a format string which makes use of - knowledge of the LogRecord attributes - e.g. the default value mentioned - above makes use of the fact that the user's message and arguments are pre- - formatted into a LogRecord's message attribute. Currently, the useful - attributes in a LogRecord are described by: - - %(name)s Name of the logger (logging channel) - %(levelno)s Numeric logging level for the message (DEBUG, INFO, - WARNING, ERROR, CRITICAL) - %(levelname)s Text logging level for the message ("DEBUG", "INFO", - "WARNING", "ERROR", "CRITICAL") - %(pathname)s Full pathname of the source file where the logging - call was issued (if available) - %(filename)s Filename portion of pathname - %(module)s Module (name portion of filename) - %(lineno)d Source line number where the logging call was issued - (if available) - %(funcName)s Function name - %(created)f Time when the LogRecord was created (time.time() - return value) - %(asctime)s Textual time when the LogRecord was created - %(msecs)d Millisecond portion of the creation time - %(relativeCreated)d Time in milliseconds when the LogRecord was created, - relative to the time the logging module was loaded - (typically at application startup time) - %(thread)d Thread ID (if available) - %(threadName)s Thread name (if available) - %(process)d Process ID (if available) - %(message)s The result of record.getMessage(), computed just as - the record is emitted - """ - - converter = time.localtime - - def __init__(self, fmt=None, datefmt=None, style='%', validate=True, *, - defaults=None): - """ - Initialize the formatter with specified format strings. - - Initialize the formatter either with the specified format string, or a - default as described above. Allow for specialized date formatting with - the optional datefmt argument. If datefmt is omitted, you get an - ISO8601-like (or RFC 3339-like) format. - - Use a style parameter of '%', '{' or '$' to specify that you want to - use one of %-formatting, :meth:`str.format` (``{}``) formatting or - :class:`string.Template` formatting in your format string. - - .. versionchanged:: 3.2 - Added the ``style`` parameter. - """ - if style not in _STYLES: - raise ValueError('Style must be one of: %s' % ','.join( - _STYLES.keys())) - self._style = _STYLES[style][0](fmt, defaults=defaults) - if validate: - self._style.validate() - - self._fmt = self._style._fmt - self.datefmt = datefmt - - default_time_format = '%Y-%m-%d %H:%M:%S' - default_msec_format = '%s,%03d' - - def formatTime(self, record, datefmt=None): - """ - Return the creation time of the specified LogRecord as formatted text. - - This method should be called from format() by a formatter which - wants to make use of a formatted time. This method can be overridden - in formatters to provide for any specific requirement, but the - basic behaviour is as follows: if datefmt (a string) is specified, - it is used with time.strftime() to format the creation time of the - record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. - The resulting string is returned. This function uses a user-configurable - function to convert the creation time to a tuple. By default, - time.localtime() is used; to change this for a particular formatter - instance, set the 'converter' attribute to a function with the same - signature as time.localtime() or time.gmtime(). To change it for all - formatters, for example if you want all logging times to be shown in GMT, - set the 'converter' attribute in the Formatter class. - """ - ct = self.converter(record.created) - if datefmt: - s = time.strftime(datefmt, ct) - else: - s = time.strftime(self.default_time_format, ct) - if self.default_msec_format: - s = self.default_msec_format % (s, record.msecs) - return s - - def formatException(self, ei): - """ - Format and return the specified exception information as a string. - - This default implementation just uses - traceback.print_exception() - """ - sio = io.StringIO() - tb = ei[2] - # See issues #9427, #1553375. Commented out for now. - #if getattr(self, 'fullstack', False): - # traceback.print_stack(tb.tb_frame.f_back, file=sio) - traceback.print_exception(ei[0], ei[1], tb, None, sio) - s = sio.getvalue() - sio.close() - if s[-1:] == "\n": - s = s[:-1] - return s - - def usesTime(self): - """ - Check if the format uses the creation time of the record. - """ - return self._style.usesTime() - - def formatMessage(self, record): - return self._style.format(record) - - def formatStack(self, stack_info): - """ - This method is provided as an extension point for specialized - formatting of stack information. - - The input data is a string as returned from a call to - :func:`traceback.print_stack`, but with the last trailing newline - removed. - - The base implementation just returns the value passed in. - """ - return stack_info - - def format(self, record): - """ - Format the specified record as text. - - The record's attribute dictionary is used as the operand to a - string formatting operation which yields the returned string. - Before formatting the dictionary, a couple of preparatory steps - are carried out. The message attribute of the record is computed - using LogRecord.getMessage(). If the formatting string uses the - time (as determined by a call to usesTime(), formatTime() is - called to format the event time. If there is exception information, - it is formatted using formatException() and appended to the message. - """ - record.message = record.getMessage() - if self.usesTime(): - record.asctime = self.formatTime(record, self.datefmt) - s = self.formatMessage(record) - if record.exc_info: - # Cache the traceback text to avoid converting it multiple times - # (it's constant anyway) - if not record.exc_text: - record.exc_text = self.formatException(record.exc_info) - if record.exc_text: - if s[-1:] != "\n": - s = s + "\n" - s = s + record.exc_text - if record.stack_info: - if s[-1:] != "\n": - s = s + "\n" - s = s + self.formatStack(record.stack_info) - return s - -# -# The default formatter to use when no other is specified -# -_defaultFormatter = Formatter() - -class BufferingFormatter(object): - """ - A formatter suitable for formatting a number of records. - """ - def __init__(self, linefmt=None): - """ - Optionally specify a formatter which will be used to format each - individual record. - """ - if linefmt: - self.linefmt = linefmt - else: - self.linefmt = _defaultFormatter - - def formatHeader(self, records): - """ - Return the header string for the specified records. - """ - return "" - - def formatFooter(self, records): - """ - Return the footer string for the specified records. - """ - return "" - - def format(self, records): - """ - Format the specified records and return the result as a string. - """ - rv = "" - if len(records) > 0: - rv = rv + self.formatHeader(records) - for record in records: - rv = rv + self.linefmt.format(record) - rv = rv + self.formatFooter(records) - return rv - -#--------------------------------------------------------------------------- -# Filter classes and functions -#--------------------------------------------------------------------------- - -class Filter(object): - """ - Filter instances are used to perform arbitrary filtering of LogRecords. - - Loggers and Handlers can optionally use Filter instances to filter - records as desired. The base filter class only allows events which are - below a certain point in the logger hierarchy. For example, a filter - initialized with "A.B" will allow events logged by loggers "A.B", - "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If - initialized with the empty string, all events are passed. - """ - def __init__(self, name=''): - """ - Initialize a filter. - - Initialize with the name of the logger which, together with its - children, will have its events allowed through the filter. If no - name is specified, allow every event. - """ - self.name = name - self.nlen = len(name) - - def filter(self, record): - """ - Determine if the specified record is to be logged. - - Returns True if the record should be logged, or False otherwise. - If deemed appropriate, the record may be modified in-place. - """ - if self.nlen == 0: - return True - elif self.name == record.name: - return True - elif record.name.find(self.name, 0, self.nlen) != 0: - return False - return (record.name[self.nlen] == ".") - -class Filterer(object): - """ - A base class for loggers and handlers which allows them to share - common code. - """ - def __init__(self): - """ - Initialize the list of filters to be an empty list. - """ - self.filters = [] - - def addFilter(self, filter): - """ - Add the specified filter to this handler. - """ - if not (filter in self.filters): - self.filters.append(filter) - - def removeFilter(self, filter): - """ - Remove the specified filter from this handler. - """ - if filter in self.filters: - self.filters.remove(filter) - - def filter(self, record): - """ - Determine if a record is loggable by consulting all the filters. - - The default is to allow the record to be logged; any filter can veto - this and the record is then dropped. Returns a zero value if a record - is to be dropped, else non-zero. - - .. versionchanged:: 3.2 - - Allow filters to be just callables. - """ - rv = True - for f in self.filters: - if hasattr(f, 'filter'): - result = f.filter(record) - else: - result = f(record) # assume callable - will raise if not - if not result: - rv = False - break - return rv - -#--------------------------------------------------------------------------- -# Handler classes and functions -#--------------------------------------------------------------------------- - -_handlers = weakref.WeakValueDictionary() #map of handler names to handlers -_handlerList = [] # added to allow handlers to be removed in reverse of order initialized - -def _removeHandlerRef(wr): - """ - Remove a handler reference from the internal cleanup list. - """ - # This function can be called during module teardown, when globals are - # set to None. It can also be called from another thread. So we need to - # pre-emptively grab the necessary globals and check if they're None, - # to prevent race conditions and failures during interpreter shutdown. - acquire, release, handlers = _acquireLock, _releaseLock, _handlerList - if acquire and release and handlers: - acquire() - try: - handlers.remove(wr) - except ValueError: - pass - finally: - release() - -def _addHandlerRef(handler): - """ - Add a handler to the internal cleanup list using a weak reference. - """ - _acquireLock() - try: - _handlerList.append(weakref.ref(handler, _removeHandlerRef)) - finally: - _releaseLock() - -class Handler(Filterer): - """ - Handler instances dispatch logging events to specific destinations. - - The base handler class. Acts as a placeholder which defines the Handler - interface. Handlers can optionally use Formatter instances to format - records as desired. By default, no formatter is specified; in this case, - the 'raw' message as determined by record.message is logged. - """ - def __init__(self, level=NOTSET): - """ - Initializes the instance - basically setting the formatter to None - and the filter list to empty. - """ - Filterer.__init__(self) - self._name = None - self.level = _checkLevel(level) - self.formatter = None - self._closed = False - # Add the handler to the global _handlerList (for cleanup on shutdown) - _addHandlerRef(self) - self.createLock() - - def get_name(self): - return self._name - - def set_name(self, name): - _acquireLock() - try: - if self._name in _handlers: - del _handlers[self._name] - self._name = name - if name: - _handlers[name] = self - finally: - _releaseLock() - - name = property(get_name, set_name) - - def createLock(self): - """ - Acquire a thread lock for serializing access to the underlying I/O. - """ - self.lock = threading.RLock() - _register_at_fork_reinit_lock(self) - - def _at_fork_reinit(self): - self.lock._at_fork_reinit() - - def acquire(self): - """ - Acquire the I/O thread lock. - """ - if self.lock: - self.lock.acquire() - - def release(self): - """ - Release the I/O thread lock. - """ - if self.lock: - self.lock.release() - - def setLevel(self, level): - """ - Set the logging level of this handler. level must be an int or a str. - """ - self.level = _checkLevel(level) - - def format(self, record): - """ - Format the specified record. - - If a formatter is set, use it. Otherwise, use the default formatter - for the module. - """ - if self.formatter: - fmt = self.formatter - else: - fmt = _defaultFormatter - return fmt.format(record) - - def emit(self, record): - """ - Do whatever it takes to actually log the specified logging record. - - This version is intended to be implemented by subclasses and so - raises a NotImplementedError. - """ - raise NotImplementedError('emit must be implemented ' - 'by Handler subclasses') - - def handle(self, record): - """ - Conditionally emit the specified logging record. - - Emission depends on filters which may have been added to the handler. - Wrap the actual emission of the record with acquisition/release of - the I/O thread lock. Returns whether the filter passed the record for - emission. - """ - rv = self.filter(record) - if rv: - self.acquire() - try: - self.emit(record) - finally: - self.release() - return rv - - def setFormatter(self, fmt): - """ - Set the formatter for this handler. - """ - self.formatter = fmt - - def flush(self): - """ - Ensure all logging output has been flushed. - - This version does nothing and is intended to be implemented by - subclasses. - """ - pass - - def close(self): - """ - Tidy up any resources used by the handler. - - This version removes the handler from an internal map of handlers, - _handlers, which is used for handler lookup by name. Subclasses - should ensure that this gets called from overridden close() - methods. - """ - #get the module data lock, as we're updating a shared structure. - _acquireLock() - try: #unlikely to raise an exception, but you never know... - self._closed = True - if self._name and self._name in _handlers: - del _handlers[self._name] - finally: - _releaseLock() - - def handleError(self, record): - """ - Handle errors which occur during an emit() call. - - This method should be called from handlers when an exception is - encountered during an emit() call. If raiseExceptions is false, - exceptions get silently ignored. This is what is mostly wanted - for a logging system - most users will not care about errors in - the logging system, they are more interested in application errors. - You could, however, replace this with a custom handler if you wish. - The record which was being processed is passed in to this method. - """ - if raiseExceptions and sys.stderr: # see issue 13807 - t, v, tb = sys.exc_info() - try: - sys.stderr.write('--- Logging error ---\n') - traceback.print_exception(t, v, tb, None, sys.stderr) - sys.stderr.write('Call stack:\n') - # Walk the stack frame up until we're out of logging, - # so as to print the calling context. - frame = tb.tb_frame - while (frame and os.path.dirname(frame.f_code.co_filename) == - __path__[0]): - frame = frame.f_back - if frame: - traceback.print_stack(frame, file=sys.stderr) - else: - # couldn't find the right stack frame, for some reason - sys.stderr.write('Logged from file %s, line %s\n' % ( - record.filename, record.lineno)) - # Issue 18671: output logging message and arguments - try: - sys.stderr.write('Message: %r\n' - 'Arguments: %s\n' % (record.msg, - record.args)) - except RecursionError: # See issue 36272 - raise - except Exception: - sys.stderr.write('Unable to print the message and arguments' - ' - possible formatting error.\nUse the' - ' traceback above to help find the error.\n' - ) - except OSError: #pragma: no cover - pass # see issue 5971 - finally: - del t, v, tb - - def __repr__(self): - level = getLevelName(self.level) - return '<%s (%s)>' % (self.__class__.__name__, level) - -class StreamHandler(Handler): - """ - A handler class which writes logging records, appropriately formatted, - to a stream. Note that this class does not close the stream, as - sys.stdout or sys.stderr may be used. - """ - - terminator = '\n' - - def __init__(self, stream=None): - """ - Initialize the handler. - - If stream is not specified, sys.stderr is used. - """ - Handler.__init__(self) - if stream is None: - stream = sys.stderr - self.stream = stream - - def flush(self): - """ - Flushes the stream. - """ - self.acquire() - try: - if self.stream and hasattr(self.stream, "flush"): - self.stream.flush() - finally: - self.release() - - def emit(self, record): - """ - Emit a record. - - If a formatter is specified, it is used to format the record. - The record is then written to the stream with a trailing newline. If - exception information is present, it is formatted using - traceback.print_exception and appended to the stream. If the stream - has an 'encoding' attribute, it is used to determine how to do the - output to the stream. - """ - try: - msg = self.format(record) - stream = self.stream - # issue 35046: merged two stream.writes into one. - stream.write(msg + self.terminator) - self.flush() - except RecursionError: # See issue 36272 - raise - except Exception: - self.handleError(record) - - def setStream(self, stream): - """ - Sets the StreamHandler's stream to the specified value, - if it is different. - - Returns the old stream, if the stream was changed, or None - if it wasn't. - """ - if stream is self.stream: - result = None - else: - result = self.stream - self.acquire() - try: - self.flush() - self.stream = stream - finally: - self.release() - return result - - def __repr__(self): - level = getLevelName(self.level) - name = getattr(self.stream, 'name', '') - # bpo-36015: name can be an int - name = str(name) - if name: - name += ' ' - return '<%s %s(%s)>' % (self.__class__.__name__, name, level) - - __class_getitem__ = classmethod(GenericAlias) - - -class FileHandler(StreamHandler): - """ - A handler class which writes formatted logging records to disk files. - """ - def __init__(self, filename, mode='a', encoding=None, delay=False, errors=None): - """ - Open the specified file and use it as the stream for logging. - """ - # Issue #27493: add support for Path objects to be passed in - filename = os.fspath(filename) - #keep the absolute path, otherwise derived classes which use this - #may come a cropper when the current directory changes - self.baseFilename = os.path.abspath(filename) - self.mode = mode - self.encoding = encoding - if "b" not in mode: - self.encoding = io.text_encoding(encoding) - self.errors = errors - self.delay = delay - # bpo-26789: FileHandler keeps a reference to the builtin open() - # function to be able to open or reopen the file during Python - # finalization. - self._builtin_open = open - if delay: - #We don't open the stream, but we still need to call the - #Handler constructor to set level, formatter, lock etc. - Handler.__init__(self) - self.stream = None - else: - StreamHandler.__init__(self, self._open()) - - def close(self): - """ - Closes the stream. - """ - self.acquire() - try: - try: - if self.stream: - try: - self.flush() - finally: - stream = self.stream - self.stream = None - if hasattr(stream, "close"): - stream.close() - finally: - # Issue #19523: call unconditionally to - # prevent a handler leak when delay is set - # Also see Issue #42378: we also rely on - # self._closed being set to True there - StreamHandler.close(self) - finally: - self.release() - - def _open(self): - """ - Open the current base file with the (original) mode and encoding. - Return the resulting stream. - """ - open_func = self._builtin_open - return open_func(self.baseFilename, self.mode, - encoding=self.encoding, errors=self.errors) - - def emit(self, record): - """ - Emit a record. - - If the stream was not opened because 'delay' was specified in the - constructor, open it before calling the superclass's emit. - - If stream is not open, current mode is 'w' and `_closed=True`, record - will not be emitted (see Issue #42378). - """ - if self.stream is None: - if self.mode != 'w' or not self._closed: - self.stream = self._open() - if self.stream: - StreamHandler.emit(self, record) - - def __repr__(self): - level = getLevelName(self.level) - return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level) - - -class _StderrHandler(StreamHandler): - """ - This class is like a StreamHandler using sys.stderr, but always uses - whatever sys.stderr is currently set to rather than the value of - sys.stderr at handler construction time. - """ - def __init__(self, level=NOTSET): - """ - Initialize the handler. - """ - Handler.__init__(self, level) - - @property - def stream(self): - return sys.stderr - - -_defaultLastResort = _StderrHandler(WARNING) -lastResort = _defaultLastResort - -#--------------------------------------------------------------------------- -# Manager classes and functions -#--------------------------------------------------------------------------- - -class PlaceHolder(object): - """ - PlaceHolder instances are used in the Manager logger hierarchy to take - the place of nodes for which no loggers have been defined. This class is - intended for internal use only and not as part of the public API. - """ - def __init__(self, alogger): - """ - Initialize with the specified logger being a child of this placeholder. - """ - self.loggerMap = { alogger : None } - - def append(self, alogger): - """ - Add the specified logger as a child of this placeholder. - """ - if alogger not in self.loggerMap: - self.loggerMap[alogger] = None - -# -# Determine which class to use when instantiating loggers. -# - -def setLoggerClass(klass): - """ - Set the class to be used when instantiating a logger. The class should - define __init__() such that only a name argument is required, and the - __init__() should call Logger.__init__() - """ - if klass != Logger: - if not issubclass(klass, Logger): - raise TypeError("logger not derived from logging.Logger: " - + klass.__name__) - global _loggerClass - _loggerClass = klass - -def getLoggerClass(): - """ - Return the class to be used when instantiating a logger. - """ - return _loggerClass - -class Manager(object): - """ - There is [under normal circumstances] just one Manager instance, which - holds the hierarchy of loggers. - """ - def __init__(self, rootnode): - """ - Initialize the manager with the root node of the logger hierarchy. - """ - self.root = rootnode - self.disable = 0 - self.emittedNoHandlerWarning = False - self.loggerDict = {} - self.loggerClass = None - self.logRecordFactory = None - - @property - def disable(self): - return self._disable - - @disable.setter - def disable(self, value): - self._disable = _checkLevel(value) - - def getLogger(self, name): - """ - Get a logger with the specified name (channel name), creating it - if it doesn't yet exist. This name is a dot-separated hierarchical - name, such as "a", "a.b", "a.b.c" or similar. - - If a PlaceHolder existed for the specified name [i.e. the logger - didn't exist but a child of it did], replace it with the created - logger and fix up the parent/child references which pointed to the - placeholder to now point to the logger. - """ - rv = None - if not isinstance(name, str): - raise TypeError('A logger name must be a string') - _acquireLock() - try: - if name in self.loggerDict: - rv = self.loggerDict[name] - if isinstance(rv, PlaceHolder): - ph = rv - rv = (self.loggerClass or _loggerClass)(name) - rv.manager = self - self.loggerDict[name] = rv - self._fixupChildren(ph, rv) - self._fixupParents(rv) - else: - rv = (self.loggerClass or _loggerClass)(name) - rv.manager = self - self.loggerDict[name] = rv - self._fixupParents(rv) - finally: - _releaseLock() - return rv - - def setLoggerClass(self, klass): - """ - Set the class to be used when instantiating a logger with this Manager. - """ - if klass != Logger: - if not issubclass(klass, Logger): - raise TypeError("logger not derived from logging.Logger: " - + klass.__name__) - self.loggerClass = klass - - def setLogRecordFactory(self, factory): - """ - Set the factory to be used when instantiating a log record with this - Manager. - """ - self.logRecordFactory = factory - - def _fixupParents(self, alogger): - """ - Ensure that there are either loggers or placeholders all the way - from the specified logger to the root of the logger hierarchy. - """ - name = alogger.name - i = name.rfind(".") - rv = None - while (i > 0) and not rv: - substr = name[:i] - if substr not in self.loggerDict: - self.loggerDict[substr] = PlaceHolder(alogger) - else: - obj = self.loggerDict[substr] - if isinstance(obj, Logger): - rv = obj - else: - assert isinstance(obj, PlaceHolder) - obj.append(alogger) - i = name.rfind(".", 0, i - 1) - if not rv: - rv = self.root - alogger.parent = rv - - def _fixupChildren(self, ph, alogger): - """ - Ensure that children of the placeholder ph are connected to the - specified logger. - """ - name = alogger.name - namelen = len(name) - for c in ph.loggerMap.keys(): - #The if means ... if not c.parent.name.startswith(nm) - if c.parent.name[:namelen] != name: - alogger.parent = c.parent - c.parent = alogger - - def _clear_cache(self): - """ - Clear the cache for all loggers in loggerDict - Called when level changes are made - """ - - _acquireLock() - for logger in self.loggerDict.values(): - if isinstance(logger, Logger): - logger._cache.clear() - self.root._cache.clear() - _releaseLock() - -#--------------------------------------------------------------------------- -# Logger classes and functions -#--------------------------------------------------------------------------- - -class Logger(Filterer): - """ - Instances of the Logger class represent a single logging channel. A - "logging channel" indicates an area of an application. Exactly how an - "area" is defined is up to the application developer. Since an - application can have any number of areas, logging channels are identified - by a unique string. Application areas can be nested (e.g. an area - of "input processing" might include sub-areas "read CSV files", "read - XLS files" and "read Gnumeric files"). To cater for this natural nesting, - channel names are organized into a namespace hierarchy where levels are - separated by periods, much like the Java or Python package namespace. So - in the instance given above, channel names might be "input" for the upper - level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. - There is no arbitrary limit to the depth of nesting. - """ - def __init__(self, name, level=NOTSET): - """ - Initialize the logger with a name and an optional level. - """ - Filterer.__init__(self) - self.name = name - self.level = _checkLevel(level) - self.parent = None - self.propagate = True - self.handlers = [] - self.disabled = False - self._cache = {} - - def setLevel(self, level): - """ - Set the logging level of this logger. level must be an int or a str. - """ - self.level = _checkLevel(level) - self.manager._clear_cache() - - def debug(self, msg, *args, **kwargs): - """ - Log 'msg % args' with severity 'DEBUG'. - - To pass exception information, use the keyword argument exc_info with - a true value, e.g. - - logger.debug("Houston, we have a %s", "thorny problem", exc_info=1) - """ - if self.isEnabledFor(DEBUG): - self._log(DEBUG, msg, args, **kwargs) - - def info(self, msg, *args, **kwargs): - """ - Log 'msg % args' with severity 'INFO'. - - To pass exception information, use the keyword argument exc_info with - a true value, e.g. - - logger.info("Houston, we have a %s", "interesting problem", exc_info=1) - """ - if self.isEnabledFor(INFO): - self._log(INFO, msg, args, **kwargs) - - def warning(self, msg, *args, **kwargs): - """ - Log 'msg % args' with severity 'WARNING'. - - To pass exception information, use the keyword argument exc_info with - a true value, e.g. - - logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1) - """ - if self.isEnabledFor(WARNING): - self._log(WARNING, msg, args, **kwargs) - - def warn(self, msg, *args, **kwargs): - warnings.warn("The 'warn' method is deprecated, " - "use 'warning' instead", DeprecationWarning, 2) - self.warning(msg, *args, **kwargs) - - def error(self, msg, *args, **kwargs): - """ - Log 'msg % args' with severity 'ERROR'. - - To pass exception information, use the keyword argument exc_info with - a true value, e.g. - - logger.error("Houston, we have a %s", "major problem", exc_info=1) - """ - if self.isEnabledFor(ERROR): - self._log(ERROR, msg, args, **kwargs) - - def exception(self, msg, *args, exc_info=True, **kwargs): - """ - Convenience method for logging an ERROR with exception information. - """ - self.error(msg, *args, exc_info=exc_info, **kwargs) - - def critical(self, msg, *args, **kwargs): - """ - Log 'msg % args' with severity 'CRITICAL'. - - To pass exception information, use the keyword argument exc_info with - a true value, e.g. - - logger.critical("Houston, we have a %s", "major disaster", exc_info=1) - """ - if self.isEnabledFor(CRITICAL): - self._log(CRITICAL, msg, args, **kwargs) - - def fatal(self, msg, *args, **kwargs): - """ - Don't use this method, use critical() instead. - """ - self.critical(msg, *args, **kwargs) - - def log(self, level, msg, *args, **kwargs): - """ - Log 'msg % args' with the integer severity 'level'. - - To pass exception information, use the keyword argument exc_info with - a true value, e.g. - - logger.log(level, "We have a %s", "mysterious problem", exc_info=1) - """ - if not isinstance(level, int): - if raiseExceptions: - raise TypeError("level must be an integer") - else: - return - if self.isEnabledFor(level): - self._log(level, msg, args, **kwargs) - - def findCaller(self, stack_info=False, stacklevel=1): - """ - Find the stack frame of the caller so that we can note the source - file name, line number and function name. - """ - f = currentframe() - #On some versions of IronPython, currentframe() returns None if - #IronPython isn't run with -X:Frames. - if f is None: - return "(unknown file)", 0, "(unknown function)", None - while stacklevel > 0: - next_f = f.f_back - if next_f is None: - ## We've got options here. - ## If we want to use the last (deepest) frame: - break - ## If we want to mimic the warnings module: - #return ("sys", 1, "(unknown function)", None) - ## If we want to be pedantic: - #raise ValueError("call stack is not deep enough") - f = next_f - if not _is_internal_frame(f): - stacklevel -= 1 - co = f.f_code - sinfo = None - if stack_info: - with io.StringIO() as sio: - sio.write("Stack (most recent call last):\n") - traceback.print_stack(f, file=sio) - sinfo = sio.getvalue() - if sinfo[-1] == '\n': - sinfo = sinfo[:-1] - return co.co_filename, f.f_lineno, co.co_name, sinfo - - def makeRecord(self, name, level, fn, lno, msg, args, exc_info, - func=None, extra=None, sinfo=None): - """ - A factory method which can be overridden in subclasses to create - specialized LogRecords. - """ - rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func, - sinfo) - if extra is not None: - for key in extra: - if (key in ["message", "asctime"]) or (key in rv.__dict__): - raise KeyError("Attempt to overwrite %r in LogRecord" % key) - rv.__dict__[key] = extra[key] - return rv - - def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, - stacklevel=1): - """ - Low-level logging routine which creates a LogRecord and then calls - all the handlers of this logger to handle the record. - """ - sinfo = None - if _srcfile: - #IronPython doesn't track Python frames, so findCaller raises an - #exception on some versions of IronPython. We trap it here so that - #IronPython can use logging. - try: - fn, lno, func, sinfo = self.findCaller(stack_info, stacklevel) - except ValueError: # pragma: no cover - fn, lno, func = "(unknown file)", 0, "(unknown function)" - else: # pragma: no cover - fn, lno, func = "(unknown file)", 0, "(unknown function)" - if exc_info: - if isinstance(exc_info, BaseException): - exc_info = (type(exc_info), exc_info, exc_info.__traceback__) - elif not isinstance(exc_info, tuple): - exc_info = sys.exc_info() - record = self.makeRecord(self.name, level, fn, lno, msg, args, - exc_info, func, extra, sinfo) - self.handle(record) - - def handle(self, record): - """ - Call the handlers for the specified record. - - This method is used for unpickled records received from a socket, as - well as those created locally. Logger-level filtering is applied. - """ - if (not self.disabled) and self.filter(record): - self.callHandlers(record) - - def addHandler(self, hdlr): - """ - Add the specified handler to this logger. - """ - _acquireLock() - try: - if not (hdlr in self.handlers): - self.handlers.append(hdlr) - finally: - _releaseLock() - - def removeHandler(self, hdlr): - """ - Remove the specified handler from this logger. - """ - _acquireLock() - try: - if hdlr in self.handlers: - self.handlers.remove(hdlr) - finally: - _releaseLock() - - def hasHandlers(self): - """ - See if this logger has any handlers configured. - - Loop through all handlers for this logger and its parents in the - logger hierarchy. Return True if a handler was found, else False. - Stop searching up the hierarchy whenever a logger with the "propagate" - attribute set to zero is found - that will be the last logger which - is checked for the existence of handlers. - """ - c = self - rv = False - while c: - if c.handlers: - rv = True - break - if not c.propagate: - break - else: - c = c.parent - return rv - - def callHandlers(self, record): - """ - Pass a record to all relevant handlers. - - Loop through all handlers for this logger and its parents in the - logger hierarchy. If no handler was found, output a one-off error - message to sys.stderr. Stop searching up the hierarchy whenever a - logger with the "propagate" attribute set to zero is found - that - will be the last logger whose handlers are called. - """ - c = self - found = 0 - while c: - for hdlr in c.handlers: - found = found + 1 - if record.levelno >= hdlr.level: - hdlr.handle(record) - if not c.propagate: - c = None #break out - else: - c = c.parent - if (found == 0): - if lastResort: - if record.levelno >= lastResort.level: - lastResort.handle(record) - elif raiseExceptions and not self.manager.emittedNoHandlerWarning: - sys.stderr.write("No handlers could be found for logger" - " \"%s\"\n" % self.name) - self.manager.emittedNoHandlerWarning = True - - def getEffectiveLevel(self): - """ - Get the effective level for this logger. - - Loop through this logger and its parents in the logger hierarchy, - looking for a non-zero logging level. Return the first one found. - """ - logger = self - while logger: - if logger.level: - return logger.level - logger = logger.parent - return NOTSET - - def isEnabledFor(self, level): - """ - Is this logger enabled for level 'level'? - """ - if self.disabled: - return False - - try: - return self._cache[level] - except KeyError: - _acquireLock() - try: - if self.manager.disable >= level: - is_enabled = self._cache[level] = False - else: - is_enabled = self._cache[level] = ( - level >= self.getEffectiveLevel() - ) - finally: - _releaseLock() - return is_enabled - - def getChild(self, suffix): - """ - Get a logger which is a descendant to this one. - - This is a convenience method, such that - - logging.getLogger('abc').getChild('def.ghi') - - is the same as - - logging.getLogger('abc.def.ghi') - - It's useful, for example, when the parent logger is named using - __name__ rather than a literal string. - """ - if self.root is not self: - suffix = '.'.join((self.name, suffix)) - return self.manager.getLogger(suffix) - - def __repr__(self): - level = getLevelName(self.getEffectiveLevel()) - return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level) - - def __reduce__(self): - if getLogger(self.name) is not self: - import pickle - raise pickle.PicklingError('logger cannot be pickled') - return getLogger, (self.name,) - - -class RootLogger(Logger): - """ - A root logger is not that different to any other logger, except that - it must have a logging level and there is only one instance of it in - the hierarchy. - """ - def __init__(self, level): - """ - Initialize the logger with the name "root". - """ - Logger.__init__(self, "root", level) - - def __reduce__(self): - return getLogger, () - -_loggerClass = Logger - -class LoggerAdapter(object): - """ - An adapter for loggers which makes it easier to specify contextual - information in logging output. - """ - - def __init__(self, logger, extra=None): - """ - Initialize the adapter with a logger and a dict-like object which - provides contextual information. This constructor signature allows - easy stacking of LoggerAdapters, if so desired. - - You can effectively pass keyword arguments as shown in the - following example: - - adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) - """ - self.logger = logger - self.extra = extra - - def process(self, msg, kwargs): - """ - Process the logging message and keyword arguments passed in to - a logging call to insert contextual information. You can either - manipulate the message itself, the keyword args or both. Return - the message and kwargs modified (or not) to suit your needs. - - Normally, you'll only need to override this one method in a - LoggerAdapter subclass for your specific needs. - """ - kwargs["extra"] = self.extra - return msg, kwargs - - # - # Boilerplate convenience methods - # - def debug(self, msg, *args, **kwargs): - """ - Delegate a debug call to the underlying logger. - """ - self.log(DEBUG, msg, *args, **kwargs) - - def info(self, msg, *args, **kwargs): - """ - Delegate an info call to the underlying logger. - """ - self.log(INFO, msg, *args, **kwargs) - - def warning(self, msg, *args, **kwargs): - """ - Delegate a warning call to the underlying logger. - """ - self.log(WARNING, msg, *args, **kwargs) - - def warn(self, msg, *args, **kwargs): - warnings.warn("The 'warn' method is deprecated, " - "use 'warning' instead", DeprecationWarning, 2) - self.warning(msg, *args, **kwargs) - - def error(self, msg, *args, **kwargs): - """ - Delegate an error call to the underlying logger. - """ - self.log(ERROR, msg, *args, **kwargs) - - def exception(self, msg, *args, exc_info=True, **kwargs): - """ - Delegate an exception call to the underlying logger. - """ - self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs) - - def critical(self, msg, *args, **kwargs): - """ - Delegate a critical call to the underlying logger. - """ - self.log(CRITICAL, msg, *args, **kwargs) - - def log(self, level, msg, *args, **kwargs): - """ - Delegate a log call to the underlying logger, after adding - contextual information from this adapter instance. - """ - if self.isEnabledFor(level): - msg, kwargs = self.process(msg, kwargs) - self.logger.log(level, msg, *args, **kwargs) - - def isEnabledFor(self, level): - """ - Is this logger enabled for level 'level'? - """ - return self.logger.isEnabledFor(level) - - def setLevel(self, level): - """ - Set the specified level on the underlying logger. - """ - self.logger.setLevel(level) - - def getEffectiveLevel(self): - """ - Get the effective level for the underlying logger. - """ - return self.logger.getEffectiveLevel() - - def hasHandlers(self): - """ - See if the underlying logger has any handlers. - """ - return self.logger.hasHandlers() - - def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): - """ - Low-level log implementation, proxied to allow nested logger adapters. - """ - return self.logger._log( - level, - msg, - args, - exc_info=exc_info, - extra=extra, - stack_info=stack_info, - ) - - @property - def manager(self): - return self.logger.manager - - @manager.setter - def manager(self, value): - self.logger.manager = value - - @property - def name(self): - return self.logger.name - - def __repr__(self): - logger = self.logger - level = getLevelName(logger.getEffectiveLevel()) - return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level) - - __class_getitem__ = classmethod(GenericAlias) - -root = RootLogger(WARNING) -Logger.root = root -Logger.manager = Manager(Logger.root) - -#--------------------------------------------------------------------------- -# Configuration classes and functions -#--------------------------------------------------------------------------- - -def basicConfig(**kwargs): - """ - Do basic configuration for the logging system. - - This function does nothing if the root logger already has handlers - configured, unless the keyword argument *force* is set to ``True``. - It is a convenience method intended for use by simple scripts - to do one-shot configuration of the logging package. - - The default behaviour is to create a StreamHandler which writes to - sys.stderr, set a formatter using the BASIC_FORMAT format string, and - add the handler to the root logger. - - A number of optional keyword arguments may be specified, which can alter - the default behaviour. - - filename Specifies that a FileHandler be created, using the specified - filename, rather than a StreamHandler. - filemode Specifies the mode to open the file, if filename is specified - (if filemode is unspecified, it defaults to 'a'). - format Use the specified format string for the handler. - datefmt Use the specified date/time format. - style If a format string is specified, use this to specify the - type of format string (possible values '%', '{', '$', for - %-formatting, :meth:`str.format` and :class:`string.Template` - - defaults to '%'). - level Set the root logger level to the specified level. - stream Use the specified stream to initialize the StreamHandler. Note - that this argument is incompatible with 'filename' - if both - are present, 'stream' is ignored. - handlers If specified, this should be an iterable of already created - handlers, which will be added to the root handler. Any handler - in the list which does not have a formatter assigned will be - assigned the formatter created in this function. - force If this keyword is specified as true, any existing handlers - attached to the root logger are removed and closed, before - carrying out the configuration as specified by the other - arguments. - encoding If specified together with a filename, this encoding is passed to - the created FileHandler, causing it to be used when the file is - opened. - errors If specified together with a filename, this value is passed to the - created FileHandler, causing it to be used when the file is - opened in text mode. If not specified, the default value is - `backslashreplace`. - - Note that you could specify a stream created using open(filename, mode) - rather than passing the filename and mode in. However, it should be - remembered that StreamHandler does not close its stream (since it may be - using sys.stdout or sys.stderr), whereas FileHandler closes its stream - when the handler is closed. - - .. versionchanged:: 3.2 - Added the ``style`` parameter. - - .. versionchanged:: 3.3 - Added the ``handlers`` parameter. A ``ValueError`` is now thrown for - incompatible arguments (e.g. ``handlers`` specified together with - ``filename``/``filemode``, or ``filename``/``filemode`` specified - together with ``stream``, or ``handlers`` specified together with - ``stream``. - - .. versionchanged:: 3.8 - Added the ``force`` parameter. - - .. versionchanged:: 3.9 - Added the ``encoding`` and ``errors`` parameters. - """ - # Add thread safety in case someone mistakenly calls - # basicConfig() from multiple threads - _acquireLock() - try: - force = kwargs.pop('force', False) - encoding = kwargs.pop('encoding', None) - errors = kwargs.pop('errors', 'backslashreplace') - if force: - for h in root.handlers[:]: - root.removeHandler(h) - h.close() - if len(root.handlers) == 0: - handlers = kwargs.pop("handlers", None) - if handlers is None: - if "stream" in kwargs and "filename" in kwargs: - raise ValueError("'stream' and 'filename' should not be " - "specified together") - else: - if "stream" in kwargs or "filename" in kwargs: - raise ValueError("'stream' or 'filename' should not be " - "specified together with 'handlers'") - if handlers is None: - filename = kwargs.pop("filename", None) - mode = kwargs.pop("filemode", 'a') - if filename: - if 'b' in mode: - errors = None - else: - encoding = io.text_encoding(encoding) - h = FileHandler(filename, mode, - encoding=encoding, errors=errors) - else: - stream = kwargs.pop("stream", None) - h = StreamHandler(stream) - handlers = [h] - dfs = kwargs.pop("datefmt", None) - style = kwargs.pop("style", '%') - if style not in _STYLES: - raise ValueError('Style must be one of: %s' % ','.join( - _STYLES.keys())) - fs = kwargs.pop("format", _STYLES[style][1]) - fmt = Formatter(fs, dfs, style) - for h in handlers: - if h.formatter is None: - h.setFormatter(fmt) - root.addHandler(h) - level = kwargs.pop("level", None) - if level is not None: - root.setLevel(level) - if kwargs: - keys = ', '.join(kwargs.keys()) - raise ValueError('Unrecognised argument(s): %s' % keys) - finally: - _releaseLock() - -#--------------------------------------------------------------------------- -# Utility functions at module level. -# Basically delegate everything to the root logger. -#--------------------------------------------------------------------------- - -def getLogger(name=None): - """ - Return a logger with the specified name, creating it if necessary. - - If no name is specified, return the root logger. - """ - if not name or isinstance(name, str) and name == root.name: - return root - return Logger.manager.getLogger(name) - -def critical(msg, *args, **kwargs): - """ - Log a message with severity 'CRITICAL' on the root logger. If the logger - has no handlers, call basicConfig() to add a console handler with a - pre-defined format. - """ - if len(root.handlers) == 0: - basicConfig() - root.critical(msg, *args, **kwargs) - -def fatal(msg, *args, **kwargs): - """ - Don't use this function, use critical() instead. - """ - critical(msg, *args, **kwargs) - -def error(msg, *args, **kwargs): - """ - Log a message with severity 'ERROR' on the root logger. If the logger has - no handlers, call basicConfig() to add a console handler with a pre-defined - format. - """ - if len(root.handlers) == 0: - basicConfig() - root.error(msg, *args, **kwargs) - -def exception(msg, *args, exc_info=True, **kwargs): - """ - Log a message with severity 'ERROR' on the root logger, with exception - information. If the logger has no handlers, basicConfig() is called to add - a console handler with a pre-defined format. - """ - error(msg, *args, exc_info=exc_info, **kwargs) - -def warning(msg, *args, **kwargs): - """ - Log a message with severity 'WARNING' on the root logger. If the logger has - no handlers, call basicConfig() to add a console handler with a pre-defined - format. - """ - if len(root.handlers) == 0: - basicConfig() - root.warning(msg, *args, **kwargs) - -def warn(msg, *args, **kwargs): - warnings.warn("The 'warn' function is deprecated, " - "use 'warning' instead", DeprecationWarning, 2) - warning(msg, *args, **kwargs) - -def info(msg, *args, **kwargs): - """ - Log a message with severity 'INFO' on the root logger. If the logger has - no handlers, call basicConfig() to add a console handler with a pre-defined - format. - """ - if len(root.handlers) == 0: - basicConfig() - root.info(msg, *args, **kwargs) - -def debug(msg, *args, **kwargs): - """ - Log a message with severity 'DEBUG' on the root logger. If the logger has - no handlers, call basicConfig() to add a console handler with a pre-defined - format. - """ - if len(root.handlers) == 0: - basicConfig() - root.debug(msg, *args, **kwargs) - -def log(level, msg, *args, **kwargs): - """ - Log 'msg % args' with the integer severity 'level' on the root logger. If - the logger has no handlers, call basicConfig() to add a console handler - with a pre-defined format. - """ - if len(root.handlers) == 0: - basicConfig() - root.log(level, msg, *args, **kwargs) - -def disable(level=CRITICAL): - """ - Disable all logging calls of severity 'level' and below. - """ - root.manager.disable = level - root.manager._clear_cache() - -def shutdown(handlerList=_handlerList): - """ - Perform any cleanup actions in the logging system (e.g. flushing - buffers). - - Should be called at application exit. - """ - for wr in reversed(handlerList[:]): - #errors might occur, for example, if files are locked - #we just ignore them if raiseExceptions is not set - try: - h = wr() - if h: - try: - h.acquire() - h.flush() - h.close() - except (OSError, ValueError): - # Ignore errors which might be caused - # because handlers have been closed but - # references to them are still around at - # application exit. - pass - finally: - h.release() - except: # ignore everything, as we're shutting down - if raiseExceptions: - raise - #else, swallow - -#Let's try and shutdown automatically on application exit... -import atexit -atexit.register(shutdown) - -# Null handler - -class NullHandler(Handler): - """ - This handler does nothing. It's intended to be used to avoid the - "No handlers could be found for logger XXX" one-off warning. This is - important for library code, which may contain code to log events. If a user - of the library does not configure logging, the one-off warning might be - produced; to avoid this, the library developer simply needs to instantiate - a NullHandler and add it to the top-level logger of the library module or - package. - """ - def handle(self, record): - """Stub.""" - - def emit(self, record): - """Stub.""" - - def createLock(self): - self.lock = None - - def _at_fork_reinit(self): - pass - -# Warnings integration - -_warnings_showwarning = None - -def _showwarning(message, category, filename, lineno, file=None, line=None): - """ - Implementation of showwarnings which redirects to logging, which will first - check to see if the file parameter is None. If a file is specified, it will - delegate to the original warnings implementation of showwarning. Otherwise, - it will call warnings.formatwarning and will log the resulting string to a - warnings logger named "py.warnings" with level logging.WARNING. - """ - if file is not None: - if _warnings_showwarning is not None: - _warnings_showwarning(message, category, filename, lineno, file, line) - else: - s = warnings.formatwarning(message, category, filename, lineno, line) - logger = getLogger("py.warnings") - if not logger.handlers: - logger.addHandler(NullHandler()) - # bpo-46557: Log str(s) as msg instead of logger.warning("%s", s) - # since some log aggregation tools group logs by the msg arg - logger.warning(str(s)) - -def captureWarnings(capture): - """ - If capture is true, redirect all warnings to the logging package. - If capture is False, ensure that warnings are not redirected to logging - but to their original destinations. - """ - global _warnings_showwarning - if capture: - if _warnings_showwarning is None: - _warnings_showwarning = warnings.showwarning - warnings.showwarning = _showwarning - else: - if _warnings_showwarning is not None: - warnings.showwarning = _warnings_showwarning - _warnings_showwarning = None diff --git a/python/Lib/logging/config.py b/python/Lib/logging/config.py deleted file mode 100644 index 4a00f81..0000000 --- a/python/Lib/logging/config.py +++ /dev/null @@ -1,948 +0,0 @@ -# Copyright 2001-2019 by Vinay Sajip. All Rights Reserved. -# -# Permission to use, copy, modify, and distribute this software and its -# documentation for any purpose and without fee is hereby granted, -# provided that the above copyright notice appear in all copies and that -# both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of Vinay Sajip -# not be used in advertising or publicity pertaining to distribution -# of the software without specific, written prior permission. -# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL -# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER -# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -""" -Configuration functions for the logging package for Python. The core package -is based on PEP 282 and comments thereto in comp.lang.python, and influenced -by Apache's log4j system. - -Copyright (C) 2001-2019 Vinay Sajip. All Rights Reserved. - -To use, simply 'import logging' and log away! -""" - -import errno -import io -import logging -import logging.handlers -import re -import struct -import threading -import traceback - -from socketserver import ThreadingTCPServer, StreamRequestHandler - - -DEFAULT_LOGGING_CONFIG_PORT = 9030 - -RESET_ERROR = errno.ECONNRESET - -# -# The following code implements a socket listener for on-the-fly -# reconfiguration of logging. -# -# _listener holds the server object doing the listening -_listener = None - -def fileConfig(fname, defaults=None, disable_existing_loggers=True, encoding=None): - """ - Read the logging configuration from a ConfigParser-format file. - - This can be called several times from an application, allowing an end user - the ability to select from various pre-canned configurations (if the - developer provides a mechanism to present the choices and load the chosen - configuration). - """ - import configparser - - if isinstance(fname, configparser.RawConfigParser): - cp = fname - else: - cp = configparser.ConfigParser(defaults) - if hasattr(fname, 'readline'): - cp.read_file(fname) - else: - encoding = io.text_encoding(encoding) - cp.read(fname, encoding=encoding) - - formatters = _create_formatters(cp) - - # critical section - logging._acquireLock() - try: - _clearExistingHandlers() - - # Handlers add themselves to logging._handlers - handlers = _install_handlers(cp, formatters) - _install_loggers(cp, handlers, disable_existing_loggers) - finally: - logging._releaseLock() - - -def _resolve(name): - """Resolve a dotted name to a global object.""" - name = name.split('.') - used = name.pop(0) - found = __import__(used) - for n in name: - used = used + '.' + n - try: - found = getattr(found, n) - except AttributeError: - __import__(used) - found = getattr(found, n) - return found - -def _strip_spaces(alist): - return map(str.strip, alist) - -def _create_formatters(cp): - """Create and return formatters""" - flist = cp["formatters"]["keys"] - if not len(flist): - return {} - flist = flist.split(",") - flist = _strip_spaces(flist) - formatters = {} - for form in flist: - sectname = "formatter_%s" % form - fs = cp.get(sectname, "format", raw=True, fallback=None) - dfs = cp.get(sectname, "datefmt", raw=True, fallback=None) - stl = cp.get(sectname, "style", raw=True, fallback='%') - c = logging.Formatter - class_name = cp[sectname].get("class") - if class_name: - c = _resolve(class_name) - f = c(fs, dfs, stl) - formatters[form] = f - return formatters - - -def _install_handlers(cp, formatters): - """Install and return handlers""" - hlist = cp["handlers"]["keys"] - if not len(hlist): - return {} - hlist = hlist.split(",") - hlist = _strip_spaces(hlist) - handlers = {} - fixups = [] #for inter-handler references - for hand in hlist: - section = cp["handler_%s" % hand] - klass = section["class"] - fmt = section.get("formatter", "") - try: - klass = eval(klass, vars(logging)) - except (AttributeError, NameError): - klass = _resolve(klass) - args = section.get("args", '()') - args = eval(args, vars(logging)) - kwargs = section.get("kwargs", '{}') - kwargs = eval(kwargs, vars(logging)) - h = klass(*args, **kwargs) - h.name = hand - if "level" in section: - level = section["level"] - h.setLevel(level) - if len(fmt): - h.setFormatter(formatters[fmt]) - if issubclass(klass, logging.handlers.MemoryHandler): - target = section.get("target", "") - if len(target): #the target handler may not be loaded yet, so keep for later... - fixups.append((h, target)) - handlers[hand] = h - #now all handlers are loaded, fixup inter-handler references... - for h, t in fixups: - h.setTarget(handlers[t]) - return handlers - -def _handle_existing_loggers(existing, child_loggers, disable_existing): - """ - When (re)configuring logging, handle loggers which were in the previous - configuration but are not in the new configuration. There's no point - deleting them as other threads may continue to hold references to them; - and by disabling them, you stop them doing any logging. - - However, don't disable children of named loggers, as that's probably not - what was intended by the user. Also, allow existing loggers to NOT be - disabled if disable_existing is false. - """ - root = logging.root - for log in existing: - logger = root.manager.loggerDict[log] - if log in child_loggers: - if not isinstance(logger, logging.PlaceHolder): - logger.setLevel(logging.NOTSET) - logger.handlers = [] - logger.propagate = True - else: - logger.disabled = disable_existing - -def _install_loggers(cp, handlers, disable_existing): - """Create and install loggers""" - - # configure the root first - llist = cp["loggers"]["keys"] - llist = llist.split(",") - llist = list(_strip_spaces(llist)) - llist.remove("root") - section = cp["logger_root"] - root = logging.root - log = root - if "level" in section: - level = section["level"] - log.setLevel(level) - for h in root.handlers[:]: - root.removeHandler(h) - hlist = section["handlers"] - if len(hlist): - hlist = hlist.split(",") - hlist = _strip_spaces(hlist) - for hand in hlist: - log.addHandler(handlers[hand]) - - #and now the others... - #we don't want to lose the existing loggers, - #since other threads may have pointers to them. - #existing is set to contain all existing loggers, - #and as we go through the new configuration we - #remove any which are configured. At the end, - #what's left in existing is the set of loggers - #which were in the previous configuration but - #which are not in the new configuration. - existing = list(root.manager.loggerDict.keys()) - #The list needs to be sorted so that we can - #avoid disabling child loggers of explicitly - #named loggers. With a sorted list it is easier - #to find the child loggers. - existing.sort() - #We'll keep the list of existing loggers - #which are children of named loggers here... - child_loggers = [] - #now set up the new ones... - for log in llist: - section = cp["logger_%s" % log] - qn = section["qualname"] - propagate = section.getint("propagate", fallback=1) - logger = logging.getLogger(qn) - if qn in existing: - i = existing.index(qn) + 1 # start with the entry after qn - prefixed = qn + "." - pflen = len(prefixed) - num_existing = len(existing) - while i < num_existing: - if existing[i][:pflen] == prefixed: - child_loggers.append(existing[i]) - i += 1 - existing.remove(qn) - if "level" in section: - level = section["level"] - logger.setLevel(level) - for h in logger.handlers[:]: - logger.removeHandler(h) - logger.propagate = propagate - logger.disabled = 0 - hlist = section["handlers"] - if len(hlist): - hlist = hlist.split(",") - hlist = _strip_spaces(hlist) - for hand in hlist: - logger.addHandler(handlers[hand]) - - #Disable any old loggers. There's no point deleting - #them as other threads may continue to hold references - #and by disabling them, you stop them doing any logging. - #However, don't disable children of named loggers, as that's - #probably not what was intended by the user. - #for log in existing: - # logger = root.manager.loggerDict[log] - # if log in child_loggers: - # logger.level = logging.NOTSET - # logger.handlers = [] - # logger.propagate = 1 - # elif disable_existing_loggers: - # logger.disabled = 1 - _handle_existing_loggers(existing, child_loggers, disable_existing) - - -def _clearExistingHandlers(): - """Clear and close existing handlers""" - logging._handlers.clear() - logging.shutdown(logging._handlerList[:]) - del logging._handlerList[:] - - -IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) - - -def valid_ident(s): - m = IDENTIFIER.match(s) - if not m: - raise ValueError('Not a valid Python identifier: %r' % s) - return True - - -class ConvertingMixin(object): - """For ConvertingXXX's, this mixin class provides common functions""" - - def convert_with_key(self, key, value, replace=True): - result = self.configurator.convert(value) - #If the converted value is different, save for next time - if value is not result: - if replace: - self[key] = result - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result - - def convert(self, value): - result = self.configurator.convert(value) - if value is not result: - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - return result - - -# The ConvertingXXX classes are wrappers around standard Python containers, -# and they serve to convert any suitable values in the container. The -# conversion converts base dicts, lists and tuples to their wrapped -# equivalents, whereas strings which match a conversion format are converted -# appropriately. -# -# Each wrapper should have a configurator attribute holding the actual -# configurator to use for conversion. - -class ConvertingDict(dict, ConvertingMixin): - """A converting dictionary wrapper.""" - - def __getitem__(self, key): - value = dict.__getitem__(self, key) - return self.convert_with_key(key, value) - - def get(self, key, default=None): - value = dict.get(self, key, default) - return self.convert_with_key(key, value) - - def pop(self, key, default=None): - value = dict.pop(self, key, default) - return self.convert_with_key(key, value, replace=False) - -class ConvertingList(list, ConvertingMixin): - """A converting list wrapper.""" - def __getitem__(self, key): - value = list.__getitem__(self, key) - return self.convert_with_key(key, value) - - def pop(self, idx=-1): - value = list.pop(self, idx) - return self.convert(value) - -class ConvertingTuple(tuple, ConvertingMixin): - """A converting tuple wrapper.""" - def __getitem__(self, key): - value = tuple.__getitem__(self, key) - # Can't replace a tuple entry. - return self.convert_with_key(key, value, replace=False) - -class BaseConfigurator(object): - """ - The configurator base class which defines some useful defaults. - """ - - CONVERT_PATTERN = re.compile(r'^(?P[a-z]+)://(?P.*)$') - - WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') - DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') - INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') - DIGIT_PATTERN = re.compile(r'^\d+$') - - value_converters = { - 'ext' : 'ext_convert', - 'cfg' : 'cfg_convert', - } - - # We might want to use a different one, e.g. importlib - importer = staticmethod(__import__) - - def __init__(self, config): - self.config = ConvertingDict(config) - self.config.configurator = self - - def resolve(self, s): - """ - Resolve strings to objects using standard import and attribute - syntax. - """ - name = s.split('.') - used = name.pop(0) - try: - found = self.importer(used) - for frag in name: - used += '.' + frag - try: - found = getattr(found, frag) - except AttributeError: - self.importer(used) - found = getattr(found, frag) - return found - except ImportError as e: - v = ValueError('Cannot resolve %r: %s' % (s, e)) - raise v from e - - def ext_convert(self, value): - """Default converter for the ext:// protocol.""" - return self.resolve(value) - - def cfg_convert(self, value): - """Default converter for the cfg:// protocol.""" - rest = value - m = self.WORD_PATTERN.match(rest) - if m is None: - raise ValueError("Unable to convert %r" % value) - else: - rest = rest[m.end():] - d = self.config[m.groups()[0]] - #print d, rest - while rest: - m = self.DOT_PATTERN.match(rest) - if m: - d = d[m.groups()[0]] - else: - m = self.INDEX_PATTERN.match(rest) - if m: - idx = m.groups()[0] - if not self.DIGIT_PATTERN.match(idx): - d = d[idx] - else: - try: - n = int(idx) # try as number first (most likely) - d = d[n] - except TypeError: - d = d[idx] - if m: - rest = rest[m.end():] - else: - raise ValueError('Unable to convert ' - '%r at %r' % (value, rest)) - #rest should be empty - return d - - def convert(self, value): - """ - Convert values to an appropriate type. dicts, lists and tuples are - replaced by their converting alternatives. Strings are checked to - see if they have a conversion format and are converted if they do. - """ - if not isinstance(value, ConvertingDict) and isinstance(value, dict): - value = ConvertingDict(value) - value.configurator = self - elif not isinstance(value, ConvertingList) and isinstance(value, list): - value = ConvertingList(value) - value.configurator = self - elif not isinstance(value, ConvertingTuple) and\ - isinstance(value, tuple) and not hasattr(value, '_fields'): - value = ConvertingTuple(value) - value.configurator = self - elif isinstance(value, str): # str for py3k - m = self.CONVERT_PATTERN.match(value) - if m: - d = m.groupdict() - prefix = d['prefix'] - converter = self.value_converters.get(prefix, None) - if converter: - suffix = d['suffix'] - converter = getattr(self, converter) - value = converter(suffix) - return value - - def configure_custom(self, config): - """Configure an object with a user-supplied factory.""" - c = config.pop('()') - if not callable(c): - c = self.resolve(c) - props = config.pop('.', None) - # Check for valid identifiers - kwargs = {k: config[k] for k in config if valid_ident(k)} - result = c(**kwargs) - if props: - for name, value in props.items(): - setattr(result, name, value) - return result - - def as_tuple(self, value): - """Utility function which converts lists to tuples.""" - if isinstance(value, list): - value = tuple(value) - return value - -class DictConfigurator(BaseConfigurator): - """ - Configure logging using a dictionary-like object to describe the - configuration. - """ - - def configure(self): - """Do the configuration.""" - - config = self.config - if 'version' not in config: - raise ValueError("dictionary doesn't specify a version") - if config['version'] != 1: - raise ValueError("Unsupported version: %s" % config['version']) - incremental = config.pop('incremental', False) - EMPTY_DICT = {} - logging._acquireLock() - try: - if incremental: - handlers = config.get('handlers', EMPTY_DICT) - for name in handlers: - if name not in logging._handlers: - raise ValueError('No handler found with ' - 'name %r' % name) - else: - try: - handler = logging._handlers[name] - handler_config = handlers[name] - level = handler_config.get('level', None) - if level: - handler.setLevel(logging._checkLevel(level)) - except Exception as e: - raise ValueError('Unable to configure handler ' - '%r' % name) from e - loggers = config.get('loggers', EMPTY_DICT) - for name in loggers: - try: - self.configure_logger(name, loggers[name], True) - except Exception as e: - raise ValueError('Unable to configure logger ' - '%r' % name) from e - root = config.get('root', None) - if root: - try: - self.configure_root(root, True) - except Exception as e: - raise ValueError('Unable to configure root ' - 'logger') from e - else: - disable_existing = config.pop('disable_existing_loggers', True) - - _clearExistingHandlers() - - # Do formatters first - they don't refer to anything else - formatters = config.get('formatters', EMPTY_DICT) - for name in formatters: - try: - formatters[name] = self.configure_formatter( - formatters[name]) - except Exception as e: - raise ValueError('Unable to configure ' - 'formatter %r' % name) from e - # Next, do filters - they don't refer to anything else, either - filters = config.get('filters', EMPTY_DICT) - for name in filters: - try: - filters[name] = self.configure_filter(filters[name]) - except Exception as e: - raise ValueError('Unable to configure ' - 'filter %r' % name) from e - - # Next, do handlers - they refer to formatters and filters - # As handlers can refer to other handlers, sort the keys - # to allow a deterministic order of configuration - handlers = config.get('handlers', EMPTY_DICT) - deferred = [] - for name in sorted(handlers): - try: - handler = self.configure_handler(handlers[name]) - handler.name = name - handlers[name] = handler - except Exception as e: - if 'target not configured yet' in str(e.__cause__): - deferred.append(name) - else: - raise ValueError('Unable to configure handler ' - '%r' % name) from e - - # Now do any that were deferred - for name in deferred: - try: - handler = self.configure_handler(handlers[name]) - handler.name = name - handlers[name] = handler - except Exception as e: - raise ValueError('Unable to configure handler ' - '%r' % name) from e - - # Next, do loggers - they refer to handlers and filters - - #we don't want to lose the existing loggers, - #since other threads may have pointers to them. - #existing is set to contain all existing loggers, - #and as we go through the new configuration we - #remove any which are configured. At the end, - #what's left in existing is the set of loggers - #which were in the previous configuration but - #which are not in the new configuration. - root = logging.root - existing = list(root.manager.loggerDict.keys()) - #The list needs to be sorted so that we can - #avoid disabling child loggers of explicitly - #named loggers. With a sorted list it is easier - #to find the child loggers. - existing.sort() - #We'll keep the list of existing loggers - #which are children of named loggers here... - child_loggers = [] - #now set up the new ones... - loggers = config.get('loggers', EMPTY_DICT) - for name in loggers: - if name in existing: - i = existing.index(name) + 1 # look after name - prefixed = name + "." - pflen = len(prefixed) - num_existing = len(existing) - while i < num_existing: - if existing[i][:pflen] == prefixed: - child_loggers.append(existing[i]) - i += 1 - existing.remove(name) - try: - self.configure_logger(name, loggers[name]) - except Exception as e: - raise ValueError('Unable to configure logger ' - '%r' % name) from e - - #Disable any old loggers. There's no point deleting - #them as other threads may continue to hold references - #and by disabling them, you stop them doing any logging. - #However, don't disable children of named loggers, as that's - #probably not what was intended by the user. - #for log in existing: - # logger = root.manager.loggerDict[log] - # if log in child_loggers: - # logger.level = logging.NOTSET - # logger.handlers = [] - # logger.propagate = True - # elif disable_existing: - # logger.disabled = True - _handle_existing_loggers(existing, child_loggers, - disable_existing) - - # And finally, do the root logger - root = config.get('root', None) - if root: - try: - self.configure_root(root) - except Exception as e: - raise ValueError('Unable to configure root ' - 'logger') from e - finally: - logging._releaseLock() - - def configure_formatter(self, config): - """Configure a formatter from a dictionary.""" - if '()' in config: - factory = config['()'] # for use in exception handler - try: - result = self.configure_custom(config) - except TypeError as te: - if "'format'" not in str(te): - raise - #Name of parameter changed from fmt to format. - #Retry with old name. - #This is so that code can be used with older Python versions - #(e.g. by Django) - config['fmt'] = config.pop('format') - config['()'] = factory - result = self.configure_custom(config) - else: - fmt = config.get('format', None) - dfmt = config.get('datefmt', None) - style = config.get('style', '%') - cname = config.get('class', None) - - if not cname: - c = logging.Formatter - else: - c = _resolve(cname) - - # A TypeError would be raised if "validate" key is passed in with a formatter callable - # that does not accept "validate" as a parameter - if 'validate' in config: # if user hasn't mentioned it, the default will be fine - result = c(fmt, dfmt, style, config['validate']) - else: - result = c(fmt, dfmt, style) - - return result - - def configure_filter(self, config): - """Configure a filter from a dictionary.""" - if '()' in config: - result = self.configure_custom(config) - else: - name = config.get('name', '') - result = logging.Filter(name) - return result - - def add_filters(self, filterer, filters): - """Add filters to a filterer from a list of names.""" - for f in filters: - try: - if callable(f) or callable(getattr(f, 'filter', None)): - filter_ = f - else: - filter_ = self.config['filters'][f] - filterer.addFilter(filter_) - except Exception as e: - raise ValueError('Unable to add filter %r' % f) from e - - def configure_handler(self, config): - """Configure a handler from a dictionary.""" - config_copy = dict(config) # for restoring in case of error - formatter = config.pop('formatter', None) - if formatter: - try: - formatter = self.config['formatters'][formatter] - except Exception as e: - raise ValueError('Unable to set formatter ' - '%r' % formatter) from e - level = config.pop('level', None) - filters = config.pop('filters', None) - if '()' in config: - c = config.pop('()') - if not callable(c): - c = self.resolve(c) - factory = c - else: - cname = config.pop('class') - klass = self.resolve(cname) - #Special case for handler which refers to another handler - if issubclass(klass, logging.handlers.MemoryHandler) and\ - 'target' in config: - try: - th = self.config['handlers'][config['target']] - if not isinstance(th, logging.Handler): - config.update(config_copy) # restore for deferred cfg - raise TypeError('target not configured yet') - config['target'] = th - except Exception as e: - raise ValueError('Unable to set target handler ' - '%r' % config['target']) from e - elif issubclass(klass, logging.handlers.SMTPHandler) and\ - 'mailhost' in config: - config['mailhost'] = self.as_tuple(config['mailhost']) - elif issubclass(klass, logging.handlers.SysLogHandler) and\ - 'address' in config: - config['address'] = self.as_tuple(config['address']) - factory = klass - props = config.pop('.', None) - kwargs = {k: config[k] for k in config if valid_ident(k)} - try: - result = factory(**kwargs) - except TypeError as te: - if "'stream'" not in str(te): - raise - #The argument name changed from strm to stream - #Retry with old name. - #This is so that code can be used with older Python versions - #(e.g. by Django) - kwargs['strm'] = kwargs.pop('stream') - result = factory(**kwargs) - if formatter: - result.setFormatter(formatter) - if level is not None: - result.setLevel(logging._checkLevel(level)) - if filters: - self.add_filters(result, filters) - if props: - for name, value in props.items(): - setattr(result, name, value) - return result - - def add_handlers(self, logger, handlers): - """Add handlers to a logger from a list of names.""" - for h in handlers: - try: - logger.addHandler(self.config['handlers'][h]) - except Exception as e: - raise ValueError('Unable to add handler %r' % h) from e - - def common_logger_config(self, logger, config, incremental=False): - """ - Perform configuration which is common to root and non-root loggers. - """ - level = config.get('level', None) - if level is not None: - logger.setLevel(logging._checkLevel(level)) - if not incremental: - #Remove any existing handlers - for h in logger.handlers[:]: - logger.removeHandler(h) - handlers = config.get('handlers', None) - if handlers: - self.add_handlers(logger, handlers) - filters = config.get('filters', None) - if filters: - self.add_filters(logger, filters) - - def configure_logger(self, name, config, incremental=False): - """Configure a non-root logger from a dictionary.""" - logger = logging.getLogger(name) - self.common_logger_config(logger, config, incremental) - logger.disabled = False - propagate = config.get('propagate', None) - if propagate is not None: - logger.propagate = propagate - - def configure_root(self, config, incremental=False): - """Configure a root logger from a dictionary.""" - root = logging.getLogger() - self.common_logger_config(root, config, incremental) - -dictConfigClass = DictConfigurator - -def dictConfig(config): - """Configure logging using a dictionary.""" - dictConfigClass(config).configure() - - -def listen(port=DEFAULT_LOGGING_CONFIG_PORT, verify=None): - """ - Start up a socket server on the specified port, and listen for new - configurations. - - These will be sent as a file suitable for processing by fileConfig(). - Returns a Thread object on which you can call start() to start the server, - and which you can join() when appropriate. To stop the server, call - stopListening(). - - Use the ``verify`` argument to verify any bytes received across the wire - from a client. If specified, it should be a callable which receives a - single argument - the bytes of configuration data received across the - network - and it should return either ``None``, to indicate that the - passed in bytes could not be verified and should be discarded, or a - byte string which is then passed to the configuration machinery as - normal. Note that you can return transformed bytes, e.g. by decrypting - the bytes passed in. - """ - - class ConfigStreamHandler(StreamRequestHandler): - """ - Handler for a logging configuration request. - - It expects a completely new logging configuration and uses fileConfig - to install it. - """ - def handle(self): - """ - Handle a request. - - Each request is expected to be a 4-byte length, packed using - struct.pack(">L", n), followed by the config file. - Uses fileConfig() to do the grunt work. - """ - try: - conn = self.connection - chunk = conn.recv(4) - if len(chunk) == 4: - slen = struct.unpack(">L", chunk)[0] - chunk = self.connection.recv(slen) - while len(chunk) < slen: - chunk = chunk + conn.recv(slen - len(chunk)) - if self.server.verify is not None: - chunk = self.server.verify(chunk) - if chunk is not None: # verified, can process - chunk = chunk.decode("utf-8") - try: - import json - d =json.loads(chunk) - assert isinstance(d, dict) - dictConfig(d) - except Exception: - #Apply new configuration. - - file = io.StringIO(chunk) - try: - fileConfig(file) - except Exception: - traceback.print_exc() - if self.server.ready: - self.server.ready.set() - except OSError as e: - if e.errno != RESET_ERROR: - raise - - class ConfigSocketReceiver(ThreadingTCPServer): - """ - A simple TCP socket-based logging config receiver. - """ - - allow_reuse_address = 1 - - def __init__(self, host='localhost', port=DEFAULT_LOGGING_CONFIG_PORT, - handler=None, ready=None, verify=None): - ThreadingTCPServer.__init__(self, (host, port), handler) - logging._acquireLock() - self.abort = 0 - logging._releaseLock() - self.timeout = 1 - self.ready = ready - self.verify = verify - - def serve_until_stopped(self): - import select - abort = 0 - while not abort: - rd, wr, ex = select.select([self.socket.fileno()], - [], [], - self.timeout) - if rd: - self.handle_request() - logging._acquireLock() - abort = self.abort - logging._releaseLock() - self.server_close() - - class Server(threading.Thread): - - def __init__(self, rcvr, hdlr, port, verify): - super(Server, self).__init__() - self.rcvr = rcvr - self.hdlr = hdlr - self.port = port - self.verify = verify - self.ready = threading.Event() - - def run(self): - server = self.rcvr(port=self.port, handler=self.hdlr, - ready=self.ready, - verify=self.verify) - if self.port == 0: - self.port = server.server_address[1] - self.ready.set() - global _listener - logging._acquireLock() - _listener = server - logging._releaseLock() - server.serve_until_stopped() - - return Server(ConfigSocketReceiver, ConfigStreamHandler, port, verify) - -def stopListening(): - """ - Stop the listening server which was created with a call to listen(). - """ - global _listener - logging._acquireLock() - try: - if _listener: - _listener.abort = 1 - _listener = None - finally: - logging._releaseLock() diff --git a/python/Lib/logging/handlers.py b/python/Lib/logging/handlers.py deleted file mode 100644 index 7f10a5a..0000000 --- a/python/Lib/logging/handlers.py +++ /dev/null @@ -1,1610 +0,0 @@ -# Copyright 2001-2021 by Vinay Sajip. All Rights Reserved. -# -# Permission to use, copy, modify, and distribute this software and its -# documentation for any purpose and without fee is hereby granted, -# provided that the above copyright notice appear in all copies and that -# both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of Vinay Sajip -# not be used in advertising or publicity pertaining to distribution -# of the software without specific, written prior permission. -# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL -# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER -# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -""" -Additional handlers for the logging package for Python. The core package is -based on PEP 282 and comments thereto in comp.lang.python. - -Copyright (C) 2001-2021 Vinay Sajip. All Rights Reserved. - -To use, simply 'import logging.handlers' and log away! -""" - -import io, logging, socket, os, pickle, struct, time, re -from stat import ST_DEV, ST_INO, ST_MTIME -import queue -import threading -import copy - -# -# Some constants... -# - -DEFAULT_TCP_LOGGING_PORT = 9020 -DEFAULT_UDP_LOGGING_PORT = 9021 -DEFAULT_HTTP_LOGGING_PORT = 9022 -DEFAULT_SOAP_LOGGING_PORT = 9023 -SYSLOG_UDP_PORT = 514 -SYSLOG_TCP_PORT = 514 - -_MIDNIGHT = 24 * 60 * 60 # number of seconds in a day - -class BaseRotatingHandler(logging.FileHandler): - """ - Base class for handlers that rotate log files at a certain point. - Not meant to be instantiated directly. Instead, use RotatingFileHandler - or TimedRotatingFileHandler. - """ - namer = None - rotator = None - - def __init__(self, filename, mode, encoding=None, delay=False, errors=None): - """ - Use the specified filename for streamed logging - """ - logging.FileHandler.__init__(self, filename, mode=mode, - encoding=encoding, delay=delay, - errors=errors) - self.mode = mode - self.encoding = encoding - self.errors = errors - - def emit(self, record): - """ - Emit a record. - - Output the record to the file, catering for rollover as described - in doRollover(). - """ - try: - if self.shouldRollover(record): - self.doRollover() - logging.FileHandler.emit(self, record) - except Exception: - self.handleError(record) - - def rotation_filename(self, default_name): - """ - Modify the filename of a log file when rotating. - - This is provided so that a custom filename can be provided. - - The default implementation calls the 'namer' attribute of the - handler, if it's callable, passing the default name to - it. If the attribute isn't callable (the default is None), the name - is returned unchanged. - - :param default_name: The default name for the log file. - """ - if not callable(self.namer): - result = default_name - else: - result = self.namer(default_name) - return result - - def rotate(self, source, dest): - """ - When rotating, rotate the current log. - - The default implementation calls the 'rotator' attribute of the - handler, if it's callable, passing the source and dest arguments to - it. If the attribute isn't callable (the default is None), the source - is simply renamed to the destination. - - :param source: The source filename. This is normally the base - filename, e.g. 'test.log' - :param dest: The destination filename. This is normally - what the source is rotated to, e.g. 'test.log.1'. - """ - if not callable(self.rotator): - # Issue 18940: A file may not have been created if delay is True. - if os.path.exists(source): - os.rename(source, dest) - else: - self.rotator(source, dest) - -class RotatingFileHandler(BaseRotatingHandler): - """ - Handler for logging to a set of files, which switches from one file - to the next when the current file reaches a certain size. - """ - def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, - encoding=None, delay=False, errors=None): - """ - Open the specified file and use it as the stream for logging. - - By default, the file grows indefinitely. You can specify particular - values of maxBytes and backupCount to allow the file to rollover at - a predetermined size. - - Rollover occurs whenever the current log file is nearly maxBytes in - length. If backupCount is >= 1, the system will successively create - new files with the same pathname as the base file, but with extensions - ".1", ".2" etc. appended to it. For example, with a backupCount of 5 - and a base file name of "app.log", you would get "app.log", - "app.log.1", "app.log.2", ... through to "app.log.5". The file being - written to is always "app.log" - when it gets filled up, it is closed - and renamed to "app.log.1", and if files "app.log.1", "app.log.2" etc. - exist, then they are renamed to "app.log.2", "app.log.3" etc. - respectively. - - If maxBytes is zero, rollover never occurs. - """ - # If rotation/rollover is wanted, it doesn't make sense to use another - # mode. If for example 'w' were specified, then if there were multiple - # runs of the calling application, the logs from previous runs would be - # lost if the 'w' is respected, because the log file would be truncated - # on each run. - if maxBytes > 0: - mode = 'a' - if "b" not in mode: - encoding = io.text_encoding(encoding) - BaseRotatingHandler.__init__(self, filename, mode, encoding=encoding, - delay=delay, errors=errors) - self.maxBytes = maxBytes - self.backupCount = backupCount - - def doRollover(self): - """ - Do a rollover, as described in __init__(). - """ - if self.stream: - self.stream.close() - self.stream = None - if self.backupCount > 0: - for i in range(self.backupCount - 1, 0, -1): - sfn = self.rotation_filename("%s.%d" % (self.baseFilename, i)) - dfn = self.rotation_filename("%s.%d" % (self.baseFilename, - i + 1)) - if os.path.exists(sfn): - if os.path.exists(dfn): - os.remove(dfn) - os.rename(sfn, dfn) - dfn = self.rotation_filename(self.baseFilename + ".1") - if os.path.exists(dfn): - os.remove(dfn) - self.rotate(self.baseFilename, dfn) - if not self.delay: - self.stream = self._open() - - def shouldRollover(self, record): - """ - Determine if rollover should occur. - - Basically, see if the supplied record would cause the file to exceed - the size limit we have. - """ - # See bpo-45401: Never rollover anything other than regular files - if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename): - return False - if self.stream is None: # delay was set... - self.stream = self._open() - if self.maxBytes > 0: # are we rolling over? - msg = "%s\n" % self.format(record) - self.stream.seek(0, 2) #due to non-posix-compliant Windows feature - if self.stream.tell() + len(msg) >= self.maxBytes: - return True - return False - -class TimedRotatingFileHandler(BaseRotatingHandler): - """ - Handler for logging to a file, rotating the log file at certain timed - intervals. - - If backupCount is > 0, when rollover is done, no more than backupCount - files are kept - the oldest ones are deleted. - """ - def __init__(self, filename, when='h', interval=1, backupCount=0, - encoding=None, delay=False, utc=False, atTime=None, - errors=None): - encoding = io.text_encoding(encoding) - BaseRotatingHandler.__init__(self, filename, 'a', encoding=encoding, - delay=delay, errors=errors) - self.when = when.upper() - self.backupCount = backupCount - self.utc = utc - self.atTime = atTime - # Calculate the real rollover interval, which is just the number of - # seconds between rollovers. Also set the filename suffix used when - # a rollover occurs. Current 'when' events supported: - # S - Seconds - # M - Minutes - # H - Hours - # D - Days - # midnight - roll over at midnight - # W{0-6} - roll over on a certain day; 0 - Monday - # - # Case of the 'when' specifier is not important; lower or upper case - # will work. - if self.when == 'S': - self.interval = 1 # one second - self.suffix = "%Y-%m-%d_%H-%M-%S" - self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}(\.\w+)?$" - elif self.when == 'M': - self.interval = 60 # one minute - self.suffix = "%Y-%m-%d_%H-%M" - self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}(\.\w+)?$" - elif self.when == 'H': - self.interval = 60 * 60 # one hour - self.suffix = "%Y-%m-%d_%H" - self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}(\.\w+)?$" - elif self.when == 'D' or self.when == 'MIDNIGHT': - self.interval = 60 * 60 * 24 # one day - self.suffix = "%Y-%m-%d" - self.extMatch = r"^\d{4}-\d{2}-\d{2}(\.\w+)?$" - elif self.when.startswith('W'): - self.interval = 60 * 60 * 24 * 7 # one week - if len(self.when) != 2: - raise ValueError("You must specify a day for weekly rollover from 0 to 6 (0 is Monday): %s" % self.when) - if self.when[1] < '0' or self.when[1] > '6': - raise ValueError("Invalid day specified for weekly rollover: %s" % self.when) - self.dayOfWeek = int(self.when[1]) - self.suffix = "%Y-%m-%d" - self.extMatch = r"^\d{4}-\d{2}-\d{2}(\.\w+)?$" - else: - raise ValueError("Invalid rollover interval specified: %s" % self.when) - - self.extMatch = re.compile(self.extMatch, re.ASCII) - self.interval = self.interval * interval # multiply by units requested - # The following line added because the filename passed in could be a - # path object (see Issue #27493), but self.baseFilename will be a string - filename = self.baseFilename - if os.path.exists(filename): - t = os.stat(filename)[ST_MTIME] - else: - t = int(time.time()) - self.rolloverAt = self.computeRollover(t) - - def computeRollover(self, currentTime): - """ - Work out the rollover time based on the specified time. - """ - result = currentTime + self.interval - # If we are rolling over at midnight or weekly, then the interval is already known. - # What we need to figure out is WHEN the next interval is. In other words, - # if you are rolling over at midnight, then your base interval is 1 day, - # but you want to start that one day clock at midnight, not now. So, we - # have to fudge the rolloverAt value in order to trigger the first rollover - # at the right time. After that, the regular interval will take care of - # the rest. Note that this code doesn't care about leap seconds. :) - if self.when == 'MIDNIGHT' or self.when.startswith('W'): - # This could be done with less code, but I wanted it to be clear - if self.utc: - t = time.gmtime(currentTime) - else: - t = time.localtime(currentTime) - currentHour = t[3] - currentMinute = t[4] - currentSecond = t[5] - currentDay = t[6] - # r is the number of seconds left between now and the next rotation - if self.atTime is None: - rotate_ts = _MIDNIGHT - else: - rotate_ts = ((self.atTime.hour * 60 + self.atTime.minute)*60 + - self.atTime.second) - - r = rotate_ts - ((currentHour * 60 + currentMinute) * 60 + - currentSecond) - if r < 0: - # Rotate time is before the current time (for example when - # self.rotateAt is 13:45 and it now 14:15), rotation is - # tomorrow. - r += _MIDNIGHT - currentDay = (currentDay + 1) % 7 - result = currentTime + r - # If we are rolling over on a certain day, add in the number of days until - # the next rollover, but offset by 1 since we just calculated the time - # until the next day starts. There are three cases: - # Case 1) The day to rollover is today; in this case, do nothing - # Case 2) The day to rollover is further in the interval (i.e., today is - # day 2 (Wednesday) and rollover is on day 6 (Sunday). Days to - # next rollover is simply 6 - 2 - 1, or 3. - # Case 3) The day to rollover is behind us in the interval (i.e., today - # is day 5 (Saturday) and rollover is on day 3 (Thursday). - # Days to rollover is 6 - 5 + 3, or 4. In this case, it's the - # number of days left in the current week (1) plus the number - # of days in the next week until the rollover day (3). - # The calculations described in 2) and 3) above need to have a day added. - # This is because the above time calculation takes us to midnight on this - # day, i.e. the start of the next day. - if self.when.startswith('W'): - day = currentDay # 0 is Monday - if day != self.dayOfWeek: - if day < self.dayOfWeek: - daysToWait = self.dayOfWeek - day - else: - daysToWait = 6 - day + self.dayOfWeek + 1 - newRolloverAt = result + (daysToWait * (60 * 60 * 24)) - if not self.utc: - dstNow = t[-1] - dstAtRollover = time.localtime(newRolloverAt)[-1] - if dstNow != dstAtRollover: - if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour - addend = -3600 - else: # DST bows out before next rollover, so we need to add an hour - addend = 3600 - newRolloverAt += addend - result = newRolloverAt - return result - - def shouldRollover(self, record): - """ - Determine if rollover should occur. - - record is not used, as we are just comparing times, but it is needed so - the method signatures are the same - """ - t = int(time.time()) - if t >= self.rolloverAt: - # See #89564: Never rollover anything other than regular files - if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename): - # The file is not a regular file, so do not rollover, but do - # set the next rollover time to avoid repeated checks. - self.rolloverAt = self.computeRollover(t) - return False - - return True - return False - - def getFilesToDelete(self): - """ - Determine the files to delete when rolling over. - - More specific than the earlier method, which just used glob.glob(). - """ - dirName, baseName = os.path.split(self.baseFilename) - fileNames = os.listdir(dirName) - result = [] - # See bpo-44753: Don't use the extension when computing the prefix. - n, e = os.path.splitext(baseName) - prefix = n + '.' - plen = len(prefix) - for fileName in fileNames: - if self.namer is None: - # Our files will always start with baseName - if not fileName.startswith(baseName): - continue - else: - # Our files could be just about anything after custom naming, but - # likely candidates are of the form - # foo.log.DATETIME_SUFFIX or foo.DATETIME_SUFFIX.log - if (not fileName.startswith(baseName) and fileName.endswith(e) and - len(fileName) > (plen + 1) and not fileName[plen+1].isdigit()): - continue - - if fileName[:plen] == prefix: - suffix = fileName[plen:] - # See bpo-45628: The date/time suffix could be anywhere in the - # filename - parts = suffix.split('.') - for part in parts: - if self.extMatch.match(part): - result.append(os.path.join(dirName, fileName)) - break - if len(result) < self.backupCount: - result = [] - else: - result.sort() - result = result[:len(result) - self.backupCount] - return result - - def doRollover(self): - """ - do a rollover; in this case, a date/time stamp is appended to the filename - when the rollover happens. However, you want the file to be named for the - start of the interval, not the current time. If there is a backup count, - then we have to get a list of matching filenames, sort them and remove - the one with the oldest suffix. - """ - if self.stream: - self.stream.close() - self.stream = None - # get the time that this sequence started at and make it a TimeTuple - currentTime = int(time.time()) - dstNow = time.localtime(currentTime)[-1] - t = self.rolloverAt - self.interval - if self.utc: - timeTuple = time.gmtime(t) - else: - timeTuple = time.localtime(t) - dstThen = timeTuple[-1] - if dstNow != dstThen: - if dstNow: - addend = 3600 - else: - addend = -3600 - timeTuple = time.localtime(t + addend) - dfn = self.rotation_filename(self.baseFilename + "." + - time.strftime(self.suffix, timeTuple)) - if os.path.exists(dfn): - os.remove(dfn) - self.rotate(self.baseFilename, dfn) - if self.backupCount > 0: - for s in self.getFilesToDelete(): - os.remove(s) - if not self.delay: - self.stream = self._open() - newRolloverAt = self.computeRollover(currentTime) - while newRolloverAt <= currentTime: - newRolloverAt = newRolloverAt + self.interval - #If DST changes and midnight or weekly rollover, adjust for this. - if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc: - dstAtRollover = time.localtime(newRolloverAt)[-1] - if dstNow != dstAtRollover: - if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour - addend = -3600 - else: # DST bows out before next rollover, so we need to add an hour - addend = 3600 - newRolloverAt += addend - self.rolloverAt = newRolloverAt - -class WatchedFileHandler(logging.FileHandler): - """ - A handler for logging to a file, which watches the file - to see if it has changed while in use. This can happen because of - usage of programs such as newsyslog and logrotate which perform - log file rotation. This handler, intended for use under Unix, - watches the file to see if it has changed since the last emit. - (A file has changed if its device or inode have changed.) - If it has changed, the old file stream is closed, and the file - opened to get a new stream. - - This handler is not appropriate for use under Windows, because - under Windows open files cannot be moved or renamed - logging - opens the files with exclusive locks - and so there is no need - for such a handler. Furthermore, ST_INO is not supported under - Windows; stat always returns zero for this value. - - This handler is based on a suggestion and patch by Chad J. - Schroeder. - """ - def __init__(self, filename, mode='a', encoding=None, delay=False, - errors=None): - if "b" not in mode: - encoding = io.text_encoding(encoding) - logging.FileHandler.__init__(self, filename, mode=mode, - encoding=encoding, delay=delay, - errors=errors) - self.dev, self.ino = -1, -1 - self._statstream() - - def _statstream(self): - if self.stream: - sres = os.fstat(self.stream.fileno()) - self.dev, self.ino = sres[ST_DEV], sres[ST_INO] - - def reopenIfNeeded(self): - """ - Reopen log file if needed. - - Checks if the underlying file has changed, and if it - has, close the old stream and reopen the file to get the - current stream. - """ - # Reduce the chance of race conditions by stat'ing by path only - # once and then fstat'ing our new fd if we opened a new log stream. - # See issue #14632: Thanks to John Mulligan for the problem report - # and patch. - try: - # stat the file by path, checking for existence - sres = os.stat(self.baseFilename) - except FileNotFoundError: - sres = None - # compare file system stat with that of our stream file handle - if not sres or sres[ST_DEV] != self.dev or sres[ST_INO] != self.ino: - if self.stream is not None: - # we have an open file handle, clean it up - self.stream.flush() - self.stream.close() - self.stream = None # See Issue #21742: _open () might fail. - # open a new file handle and get new stat info from that fd - self.stream = self._open() - self._statstream() - - def emit(self, record): - """ - Emit a record. - - If underlying file has changed, reopen the file before emitting the - record to it. - """ - self.reopenIfNeeded() - logging.FileHandler.emit(self, record) - - -class SocketHandler(logging.Handler): - """ - A handler class which writes logging records, in pickle format, to - a streaming socket. The socket is kept open across logging calls. - If the peer resets it, an attempt is made to reconnect on the next call. - The pickle which is sent is that of the LogRecord's attribute dictionary - (__dict__), so that the receiver does not need to have the logging module - installed in order to process the logging event. - - To unpickle the record at the receiving end into a LogRecord, use the - makeLogRecord function. - """ - - def __init__(self, host, port): - """ - Initializes the handler with a specific host address and port. - - When the attribute *closeOnError* is set to True - if a socket error - occurs, the socket is silently closed and then reopened on the next - logging call. - """ - logging.Handler.__init__(self) - self.host = host - self.port = port - if port is None: - self.address = host - else: - self.address = (host, port) - self.sock = None - self.closeOnError = False - self.retryTime = None - # - # Exponential backoff parameters. - # - self.retryStart = 1.0 - self.retryMax = 30.0 - self.retryFactor = 2.0 - - def makeSocket(self, timeout=1): - """ - A factory method which allows subclasses to define the precise - type of socket they want. - """ - if self.port is not None: - result = socket.create_connection(self.address, timeout=timeout) - else: - result = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - result.settimeout(timeout) - try: - result.connect(self.address) - except OSError: - result.close() # Issue 19182 - raise - return result - - def createSocket(self): - """ - Try to create a socket, using an exponential backoff with - a max retry time. Thanks to Robert Olson for the original patch - (SF #815911) which has been slightly refactored. - """ - now = time.time() - # Either retryTime is None, in which case this - # is the first time back after a disconnect, or - # we've waited long enough. - if self.retryTime is None: - attempt = True - else: - attempt = (now >= self.retryTime) - if attempt: - try: - self.sock = self.makeSocket() - self.retryTime = None # next time, no delay before trying - except OSError: - #Creation failed, so set the retry time and return. - if self.retryTime is None: - self.retryPeriod = self.retryStart - else: - self.retryPeriod = self.retryPeriod * self.retryFactor - if self.retryPeriod > self.retryMax: - self.retryPeriod = self.retryMax - self.retryTime = now + self.retryPeriod - - def send(self, s): - """ - Send a pickled string to the socket. - - This function allows for partial sends which can happen when the - network is busy. - """ - if self.sock is None: - self.createSocket() - #self.sock can be None either because we haven't reached the retry - #time yet, or because we have reached the retry time and retried, - #but are still unable to connect. - if self.sock: - try: - self.sock.sendall(s) - except OSError: #pragma: no cover - self.sock.close() - self.sock = None # so we can call createSocket next time - - def makePickle(self, record): - """ - Pickles the record in binary format with a length prefix, and - returns it ready for transmission across the socket. - """ - ei = record.exc_info - if ei: - # just to get traceback text into record.exc_text ... - dummy = self.format(record) - # See issue #14436: If msg or args are objects, they may not be - # available on the receiving end. So we convert the msg % args - # to a string, save it as msg and zap the args. - d = dict(record.__dict__) - d['msg'] = record.getMessage() - d['args'] = None - d['exc_info'] = None - # Issue #25685: delete 'message' if present: redundant with 'msg' - d.pop('message', None) - s = pickle.dumps(d, 1) - slen = struct.pack(">L", len(s)) - return slen + s - - def handleError(self, record): - """ - Handle an error during logging. - - An error has occurred during logging. Most likely cause - - connection lost. Close the socket so that we can retry on the - next event. - """ - if self.closeOnError and self.sock: - self.sock.close() - self.sock = None #try to reconnect next time - else: - logging.Handler.handleError(self, record) - - def emit(self, record): - """ - Emit a record. - - Pickles the record and writes it to the socket in binary format. - If there is an error with the socket, silently drop the packet. - If there was a problem with the socket, re-establishes the - socket. - """ - try: - s = self.makePickle(record) - self.send(s) - except Exception: - self.handleError(record) - - def close(self): - """ - Closes the socket. - """ - self.acquire() - try: - sock = self.sock - if sock: - self.sock = None - sock.close() - logging.Handler.close(self) - finally: - self.release() - -class DatagramHandler(SocketHandler): - """ - A handler class which writes logging records, in pickle format, to - a datagram socket. The pickle which is sent is that of the LogRecord's - attribute dictionary (__dict__), so that the receiver does not need to - have the logging module installed in order to process the logging event. - - To unpickle the record at the receiving end into a LogRecord, use the - makeLogRecord function. - - """ - def __init__(self, host, port): - """ - Initializes the handler with a specific host address and port. - """ - SocketHandler.__init__(self, host, port) - self.closeOnError = False - - def makeSocket(self): - """ - The factory method of SocketHandler is here overridden to create - a UDP socket (SOCK_DGRAM). - """ - if self.port is None: - family = socket.AF_UNIX - else: - family = socket.AF_INET - s = socket.socket(family, socket.SOCK_DGRAM) - return s - - def send(self, s): - """ - Send a pickled string to a socket. - - This function no longer allows for partial sends which can happen - when the network is busy - UDP does not guarantee delivery and - can deliver packets out of sequence. - """ - if self.sock is None: - self.createSocket() - self.sock.sendto(s, self.address) - -class SysLogHandler(logging.Handler): - """ - A handler class which sends formatted logging records to a syslog - server. Based on Sam Rushing's syslog module: - http://www.nightmare.com/squirl/python-ext/misc/syslog.py - Contributed by Nicolas Untz (after which minor refactoring changes - have been made). - """ - - # from : - # ====================================================================== - # priorities/facilities are encoded into a single 32-bit quantity, where - # the bottom 3 bits are the priority (0-7) and the top 28 bits are the - # facility (0-big number). Both the priorities and the facilities map - # roughly one-to-one to strings in the syslogd(8) source code. This - # mapping is included in this file. - # - # priorities (these are ordered) - - LOG_EMERG = 0 # system is unusable - LOG_ALERT = 1 # action must be taken immediately - LOG_CRIT = 2 # critical conditions - LOG_ERR = 3 # error conditions - LOG_WARNING = 4 # warning conditions - LOG_NOTICE = 5 # normal but significant condition - LOG_INFO = 6 # informational - LOG_DEBUG = 7 # debug-level messages - - # facility codes - LOG_KERN = 0 # kernel messages - LOG_USER = 1 # random user-level messages - LOG_MAIL = 2 # mail system - LOG_DAEMON = 3 # system daemons - LOG_AUTH = 4 # security/authorization messages - LOG_SYSLOG = 5 # messages generated internally by syslogd - LOG_LPR = 6 # line printer subsystem - LOG_NEWS = 7 # network news subsystem - LOG_UUCP = 8 # UUCP subsystem - LOG_CRON = 9 # clock daemon - LOG_AUTHPRIV = 10 # security/authorization messages (private) - LOG_FTP = 11 # FTP daemon - LOG_NTP = 12 # NTP subsystem - LOG_SECURITY = 13 # Log audit - LOG_CONSOLE = 14 # Log alert - LOG_SOLCRON = 15 # Scheduling daemon (Solaris) - - # other codes through 15 reserved for system use - LOG_LOCAL0 = 16 # reserved for local use - LOG_LOCAL1 = 17 # reserved for local use - LOG_LOCAL2 = 18 # reserved for local use - LOG_LOCAL3 = 19 # reserved for local use - LOG_LOCAL4 = 20 # reserved for local use - LOG_LOCAL5 = 21 # reserved for local use - LOG_LOCAL6 = 22 # reserved for local use - LOG_LOCAL7 = 23 # reserved for local use - - priority_names = { - "alert": LOG_ALERT, - "crit": LOG_CRIT, - "critical": LOG_CRIT, - "debug": LOG_DEBUG, - "emerg": LOG_EMERG, - "err": LOG_ERR, - "error": LOG_ERR, # DEPRECATED - "info": LOG_INFO, - "notice": LOG_NOTICE, - "panic": LOG_EMERG, # DEPRECATED - "warn": LOG_WARNING, # DEPRECATED - "warning": LOG_WARNING, - } - - facility_names = { - "auth": LOG_AUTH, - "authpriv": LOG_AUTHPRIV, - "console": LOG_CONSOLE, - "cron": LOG_CRON, - "daemon": LOG_DAEMON, - "ftp": LOG_FTP, - "kern": LOG_KERN, - "lpr": LOG_LPR, - "mail": LOG_MAIL, - "news": LOG_NEWS, - "ntp": LOG_NTP, - "security": LOG_SECURITY, - "solaris-cron": LOG_SOLCRON, - "syslog": LOG_SYSLOG, - "user": LOG_USER, - "uucp": LOG_UUCP, - "local0": LOG_LOCAL0, - "local1": LOG_LOCAL1, - "local2": LOG_LOCAL2, - "local3": LOG_LOCAL3, - "local4": LOG_LOCAL4, - "local5": LOG_LOCAL5, - "local6": LOG_LOCAL6, - "local7": LOG_LOCAL7, - } - - #The map below appears to be trivially lowercasing the key. However, - #there's more to it than meets the eye - in some locales, lowercasing - #gives unexpected results. See SF #1524081: in the Turkish locale, - #"INFO".lower() != "info" - priority_map = { - "DEBUG" : "debug", - "INFO" : "info", - "WARNING" : "warning", - "ERROR" : "error", - "CRITICAL" : "critical" - } - - def __init__(self, address=('localhost', SYSLOG_UDP_PORT), - facility=LOG_USER, socktype=None): - """ - Initialize a handler. - - If address is specified as a string, a UNIX socket is used. To log to a - local syslogd, "SysLogHandler(address="/dev/log")" can be used. - If facility is not specified, LOG_USER is used. If socktype is - specified as socket.SOCK_DGRAM or socket.SOCK_STREAM, that specific - socket type will be used. For Unix sockets, you can also specify a - socktype of None, in which case socket.SOCK_DGRAM will be used, falling - back to socket.SOCK_STREAM. - """ - logging.Handler.__init__(self) - - self.address = address - self.facility = facility - self.socktype = socktype - self.socket = None - self.createSocket() - - def _connect_unixsocket(self, address): - use_socktype = self.socktype - if use_socktype is None: - use_socktype = socket.SOCK_DGRAM - self.socket = socket.socket(socket.AF_UNIX, use_socktype) - try: - self.socket.connect(address) - # it worked, so set self.socktype to the used type - self.socktype = use_socktype - except OSError: - self.socket.close() - if self.socktype is not None: - # user didn't specify falling back, so fail - raise - use_socktype = socket.SOCK_STREAM - self.socket = socket.socket(socket.AF_UNIX, use_socktype) - try: - self.socket.connect(address) - # it worked, so set self.socktype to the used type - self.socktype = use_socktype - except OSError: - self.socket.close() - raise - - def createSocket(self): - """ - Try to create a socket and, if it's not a datagram socket, connect it - to the other end. This method is called during handler initialization, - but it's not regarded as an error if the other end isn't listening yet - --- the method will be called again when emitting an event, - if there is no socket at that point. - """ - address = self.address - socktype = self.socktype - - if isinstance(address, str): - self.unixsocket = True - # Syslog server may be unavailable during handler initialisation. - # C's openlog() function also ignores connection errors. - # Moreover, we ignore these errors while logging, so it's not worse - # to ignore it also here. - try: - self._connect_unixsocket(address) - except OSError: - pass - else: - self.unixsocket = False - if socktype is None: - socktype = socket.SOCK_DGRAM - host, port = address - ress = socket.getaddrinfo(host, port, 0, socktype) - if not ress: - raise OSError("getaddrinfo returns an empty list") - for res in ress: - af, socktype, proto, _, sa = res - err = sock = None - try: - sock = socket.socket(af, socktype, proto) - if socktype == socket.SOCK_STREAM: - sock.connect(sa) - break - except OSError as exc: - err = exc - if sock is not None: - sock.close() - if err is not None: - raise err - self.socket = sock - self.socktype = socktype - - def encodePriority(self, facility, priority): - """ - Encode the facility and priority. You can pass in strings or - integers - if strings are passed, the facility_names and - priority_names mapping dictionaries are used to convert them to - integers. - """ - if isinstance(facility, str): - facility = self.facility_names[facility] - if isinstance(priority, str): - priority = self.priority_names[priority] - return (facility << 3) | priority - - def close(self): - """ - Closes the socket. - """ - self.acquire() - try: - sock = self.socket - if sock: - self.socket = None - sock.close() - logging.Handler.close(self) - finally: - self.release() - - def mapPriority(self, levelName): - """ - Map a logging level name to a key in the priority_names map. - This is useful in two scenarios: when custom levels are being - used, and in the case where you can't do a straightforward - mapping by lowercasing the logging level name because of locale- - specific issues (see SF #1524081). - """ - return self.priority_map.get(levelName, "warning") - - ident = '' # prepended to all messages - append_nul = True # some old syslog daemons expect a NUL terminator - - def emit(self, record): - """ - Emit a record. - - The record is formatted, and then sent to the syslog server. If - exception information is present, it is NOT sent to the server. - """ - try: - msg = self.format(record) - if self.ident: - msg = self.ident + msg - if self.append_nul: - msg += '\000' - - # We need to convert record level to lowercase, maybe this will - # change in the future. - prio = '<%d>' % self.encodePriority(self.facility, - self.mapPriority(record.levelname)) - prio = prio.encode('utf-8') - # Message is a string. Convert to bytes as required by RFC 5424 - msg = msg.encode('utf-8') - msg = prio + msg - - if not self.socket: - self.createSocket() - - if self.unixsocket: - try: - self.socket.send(msg) - except OSError: - self.socket.close() - self._connect_unixsocket(self.address) - self.socket.send(msg) - elif self.socktype == socket.SOCK_DGRAM: - self.socket.sendto(msg, self.address) - else: - self.socket.sendall(msg) - except Exception: - self.handleError(record) - -class SMTPHandler(logging.Handler): - """ - A handler class which sends an SMTP email for each logging event. - """ - def __init__(self, mailhost, fromaddr, toaddrs, subject, - credentials=None, secure=None, timeout=5.0): - """ - Initialize the handler. - - Initialize the instance with the from and to addresses and subject - line of the email. To specify a non-standard SMTP port, use the - (host, port) tuple format for the mailhost argument. To specify - authentication credentials, supply a (username, password) tuple - for the credentials argument. To specify the use of a secure - protocol (TLS), pass in a tuple for the secure argument. This will - only be used when authentication credentials are supplied. The tuple - will be either an empty tuple, or a single-value tuple with the name - of a keyfile, or a 2-value tuple with the names of the keyfile and - certificate file. (This tuple is passed to the `starttls` method). - A timeout in seconds can be specified for the SMTP connection (the - default is one second). - """ - logging.Handler.__init__(self) - if isinstance(mailhost, (list, tuple)): - self.mailhost, self.mailport = mailhost - else: - self.mailhost, self.mailport = mailhost, None - if isinstance(credentials, (list, tuple)): - self.username, self.password = credentials - else: - self.username = None - self.fromaddr = fromaddr - if isinstance(toaddrs, str): - toaddrs = [toaddrs] - self.toaddrs = toaddrs - self.subject = subject - self.secure = secure - self.timeout = timeout - - def getSubject(self, record): - """ - Determine the subject for the email. - - If you want to specify a subject line which is record-dependent, - override this method. - """ - return self.subject - - def emit(self, record): - """ - Emit a record. - - Format the record and send it to the specified addressees. - """ - try: - import smtplib - from email.message import EmailMessage - import email.utils - - port = self.mailport - if not port: - port = smtplib.SMTP_PORT - smtp = smtplib.SMTP(self.mailhost, port, timeout=self.timeout) - msg = EmailMessage() - msg['From'] = self.fromaddr - msg['To'] = ','.join(self.toaddrs) - msg['Subject'] = self.getSubject(record) - msg['Date'] = email.utils.localtime() - msg.set_content(self.format(record)) - if self.username: - if self.secure is not None: - smtp.ehlo() - smtp.starttls(*self.secure) - smtp.ehlo() - smtp.login(self.username, self.password) - smtp.send_message(msg) - smtp.quit() - except Exception: - self.handleError(record) - -class NTEventLogHandler(logging.Handler): - """ - A handler class which sends events to the NT Event Log. Adds a - registry entry for the specified application name. If no dllname is - provided, win32service.pyd (which contains some basic message - placeholders) is used. Note that use of these placeholders will make - your event logs big, as the entire message source is held in the log. - If you want slimmer logs, you have to pass in the name of your own DLL - which contains the message definitions you want to use in the event log. - """ - def __init__(self, appname, dllname=None, logtype="Application"): - logging.Handler.__init__(self) - try: - import win32evtlogutil, win32evtlog - self.appname = appname - self._welu = win32evtlogutil - if not dllname: - dllname = os.path.split(self._welu.__file__) - dllname = os.path.split(dllname[0]) - dllname = os.path.join(dllname[0], r'win32service.pyd') - self.dllname = dllname - self.logtype = logtype - # Administrative privileges are required to add a source to the registry. - # This may not be available for a user that just wants to add to an - # existing source - handle this specific case. - try: - self._welu.AddSourceToRegistry(appname, dllname, logtype) - except Exception as e: - # This will probably be a pywintypes.error. Only raise if it's not - # an "access denied" error, else let it pass - if getattr(e, 'winerror', None) != 5: # not access denied - raise - self.deftype = win32evtlog.EVENTLOG_ERROR_TYPE - self.typemap = { - logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE, - logging.INFO : win32evtlog.EVENTLOG_INFORMATION_TYPE, - logging.WARNING : win32evtlog.EVENTLOG_WARNING_TYPE, - logging.ERROR : win32evtlog.EVENTLOG_ERROR_TYPE, - logging.CRITICAL: win32evtlog.EVENTLOG_ERROR_TYPE, - } - except ImportError: - print("The Python Win32 extensions for NT (service, event "\ - "logging) appear not to be available.") - self._welu = None - - def getMessageID(self, record): - """ - Return the message ID for the event record. If you are using your - own messages, you could do this by having the msg passed to the - logger being an ID rather than a formatting string. Then, in here, - you could use a dictionary lookup to get the message ID. This - version returns 1, which is the base message ID in win32service.pyd. - """ - return 1 - - def getEventCategory(self, record): - """ - Return the event category for the record. - - Override this if you want to specify your own categories. This version - returns 0. - """ - return 0 - - def getEventType(self, record): - """ - Return the event type for the record. - - Override this if you want to specify your own types. This version does - a mapping using the handler's typemap attribute, which is set up in - __init__() to a dictionary which contains mappings for DEBUG, INFO, - WARNING, ERROR and CRITICAL. If you are using your own levels you will - either need to override this method or place a suitable dictionary in - the handler's typemap attribute. - """ - return self.typemap.get(record.levelno, self.deftype) - - def emit(self, record): - """ - Emit a record. - - Determine the message ID, event category and event type. Then - log the message in the NT event log. - """ - if self._welu: - try: - id = self.getMessageID(record) - cat = self.getEventCategory(record) - type = self.getEventType(record) - msg = self.format(record) - self._welu.ReportEvent(self.appname, id, cat, type, [msg]) - except Exception: - self.handleError(record) - - def close(self): - """ - Clean up this handler. - - You can remove the application name from the registry as a - source of event log entries. However, if you do this, you will - not be able to see the events as you intended in the Event Log - Viewer - it needs to be able to access the registry to get the - DLL name. - """ - #self._welu.RemoveSourceFromRegistry(self.appname, self.logtype) - logging.Handler.close(self) - -class HTTPHandler(logging.Handler): - """ - A class which sends records to a web server, using either GET or - POST semantics. - """ - def __init__(self, host, url, method="GET", secure=False, credentials=None, - context=None): - """ - Initialize the instance with the host, the request URL, and the method - ("GET" or "POST") - """ - logging.Handler.__init__(self) - method = method.upper() - if method not in ["GET", "POST"]: - raise ValueError("method must be GET or POST") - if not secure and context is not None: - raise ValueError("context parameter only makes sense " - "with secure=True") - self.host = host - self.url = url - self.method = method - self.secure = secure - self.credentials = credentials - self.context = context - - def mapLogRecord(self, record): - """ - Default implementation of mapping the log record into a dict - that is sent as the CGI data. Overwrite in your class. - Contributed by Franz Glasner. - """ - return record.__dict__ - - def getConnection(self, host, secure): - """ - get a HTTP[S]Connection. - - Override when a custom connection is required, for example if - there is a proxy. - """ - import http.client - if secure: - connection = http.client.HTTPSConnection(host, context=self.context) - else: - connection = http.client.HTTPConnection(host) - return connection - - def emit(self, record): - """ - Emit a record. - - Send the record to the web server as a percent-encoded dictionary - """ - try: - import urllib.parse - host = self.host - h = self.getConnection(host, self.secure) - url = self.url - data = urllib.parse.urlencode(self.mapLogRecord(record)) - if self.method == "GET": - if (url.find('?') >= 0): - sep = '&' - else: - sep = '?' - url = url + "%c%s" % (sep, data) - h.putrequest(self.method, url) - # support multiple hosts on one IP address... - # need to strip optional :port from host, if present - i = host.find(":") - if i >= 0: - host = host[:i] - # See issue #30904: putrequest call above already adds this header - # on Python 3.x. - # h.putheader("Host", host) - if self.method == "POST": - h.putheader("Content-type", - "application/x-www-form-urlencoded") - h.putheader("Content-length", str(len(data))) - if self.credentials: - import base64 - s = ('%s:%s' % self.credentials).encode('utf-8') - s = 'Basic ' + base64.b64encode(s).strip().decode('ascii') - h.putheader('Authorization', s) - h.endheaders() - if self.method == "POST": - h.send(data.encode('utf-8')) - h.getresponse() #can't do anything with the result - except Exception: - self.handleError(record) - -class BufferingHandler(logging.Handler): - """ - A handler class which buffers logging records in memory. Whenever each - record is added to the buffer, a check is made to see if the buffer should - be flushed. If it should, then flush() is expected to do what's needed. - """ - def __init__(self, capacity): - """ - Initialize the handler with the buffer size. - """ - logging.Handler.__init__(self) - self.capacity = capacity - self.buffer = [] - - def shouldFlush(self, record): - """ - Should the handler flush its buffer? - - Returns true if the buffer is up to capacity. This method can be - overridden to implement custom flushing strategies. - """ - return (len(self.buffer) >= self.capacity) - - def emit(self, record): - """ - Emit a record. - - Append the record. If shouldFlush() tells us to, call flush() to process - the buffer. - """ - self.buffer.append(record) - if self.shouldFlush(record): - self.flush() - - def flush(self): - """ - Override to implement custom flushing behaviour. - - This version just zaps the buffer to empty. - """ - self.acquire() - try: - self.buffer.clear() - finally: - self.release() - - def close(self): - """ - Close the handler. - - This version just flushes and chains to the parent class' close(). - """ - try: - self.flush() - finally: - logging.Handler.close(self) - -class MemoryHandler(BufferingHandler): - """ - A handler class which buffers logging records in memory, periodically - flushing them to a target handler. Flushing occurs whenever the buffer - is full, or when an event of a certain severity or greater is seen. - """ - def __init__(self, capacity, flushLevel=logging.ERROR, target=None, - flushOnClose=True): - """ - Initialize the handler with the buffer size, the level at which - flushing should occur and an optional target. - - Note that without a target being set either here or via setTarget(), - a MemoryHandler is no use to anyone! - - The ``flushOnClose`` argument is ``True`` for backward compatibility - reasons - the old behaviour is that when the handler is closed, the - buffer is flushed, even if the flush level hasn't been exceeded nor the - capacity exceeded. To prevent this, set ``flushOnClose`` to ``False``. - """ - BufferingHandler.__init__(self, capacity) - self.flushLevel = flushLevel - self.target = target - # See Issue #26559 for why this has been added - self.flushOnClose = flushOnClose - - def shouldFlush(self, record): - """ - Check for buffer full or a record at the flushLevel or higher. - """ - return (len(self.buffer) >= self.capacity) or \ - (record.levelno >= self.flushLevel) - - def setTarget(self, target): - """ - Set the target handler for this handler. - """ - self.acquire() - try: - self.target = target - finally: - self.release() - - def flush(self): - """ - For a MemoryHandler, flushing means just sending the buffered - records to the target, if there is one. Override if you want - different behaviour. - - The record buffer is also cleared by this operation. - """ - self.acquire() - try: - if self.target: - for record in self.buffer: - self.target.handle(record) - self.buffer.clear() - finally: - self.release() - - def close(self): - """ - Flush, if appropriately configured, set the target to None and lose the - buffer. - """ - try: - if self.flushOnClose: - self.flush() - finally: - self.acquire() - try: - self.target = None - BufferingHandler.close(self) - finally: - self.release() - - -class QueueHandler(logging.Handler): - """ - This handler sends events to a queue. Typically, it would be used together - with a multiprocessing Queue to centralise logging to file in one process - (in a multi-process application), so as to avoid file write contention - between processes. - - This code is new in Python 3.2, but this class can be copy pasted into - user code for use with earlier Python versions. - """ - - def __init__(self, queue): - """ - Initialise an instance, using the passed queue. - """ - logging.Handler.__init__(self) - self.queue = queue - - def enqueue(self, record): - """ - Enqueue a record. - - The base implementation uses put_nowait. You may want to override - this method if you want to use blocking, timeouts or custom queue - implementations. - """ - self.queue.put_nowait(record) - - def prepare(self, record): - """ - Prepare a record for queuing. The object returned by this method is - enqueued. - - The base implementation formats the record to merge the message and - arguments, and removes unpickleable items from the record in-place. - Specifically, it overwrites the record's `msg` and - `message` attributes with the merged message (obtained by - calling the handler's `format` method), and sets the `args`, - `exc_info` and `exc_text` attributes to None. - - You might want to override this method if you want to convert - the record to a dict or JSON string, or send a modified copy - of the record while leaving the original intact. - """ - # The format operation gets traceback text into record.exc_text - # (if there's exception data), and also returns the formatted - # message. We can then use this to replace the original - # msg + args, as these might be unpickleable. We also zap the - # exc_info, exc_text and stack_info attributes, as they are no longer - # needed and, if not None, will typically not be pickleable. - msg = self.format(record) - # bpo-35726: make copy of record to avoid affecting other handlers in the chain. - record = copy.copy(record) - record.message = msg - record.msg = msg - record.args = None - record.exc_info = None - record.exc_text = None - record.stack_info = None - return record - - def emit(self, record): - """ - Emit a record. - - Writes the LogRecord to the queue, preparing it for pickling first. - """ - try: - self.enqueue(self.prepare(record)) - except Exception: - self.handleError(record) - - -class QueueListener(object): - """ - This class implements an internal threaded listener which watches for - LogRecords being added to a queue, removes them and passes them to a - list of handlers for processing. - """ - _sentinel = None - - def __init__(self, queue, *handlers, respect_handler_level=False): - """ - Initialise an instance with the specified queue and - handlers. - """ - self.queue = queue - self.handlers = handlers - self._thread = None - self.respect_handler_level = respect_handler_level - - def dequeue(self, block): - """ - Dequeue a record and return it, optionally blocking. - - The base implementation uses get. You may want to override this method - if you want to use timeouts or work with custom queue implementations. - """ - return self.queue.get(block) - - def start(self): - """ - Start the listener. - - This starts up a background thread to monitor the queue for - LogRecords to process. - """ - self._thread = t = threading.Thread(target=self._monitor) - t.daemon = True - t.start() - - def prepare(self, record): - """ - Prepare a record for handling. - - This method just returns the passed-in record. You may want to - override this method if you need to do any custom marshalling or - manipulation of the record before passing it to the handlers. - """ - return record - - def handle(self, record): - """ - Handle a record. - - This just loops through the handlers offering them the record - to handle. - """ - record = self.prepare(record) - for handler in self.handlers: - if not self.respect_handler_level: - process = True - else: - process = record.levelno >= handler.level - if process: - handler.handle(record) - - def _monitor(self): - """ - Monitor the queue for records, and ask the handler - to deal with them. - - This method runs on a separate, internal thread. - The thread will terminate if it sees a sentinel object in the queue. - """ - q = self.queue - has_task_done = hasattr(q, 'task_done') - while True: - try: - record = self.dequeue(True) - if record is self._sentinel: - if has_task_done: - q.task_done() - break - self.handle(record) - if has_task_done: - q.task_done() - except queue.Empty: - break - - def enqueue_sentinel(self): - """ - This is used to enqueue the sentinel record. - - The base implementation uses put_nowait. You may want to override this - method if you want to use timeouts or work with custom queue - implementations. - """ - self.queue.put_nowait(self._sentinel) - - def stop(self): - """ - Stop the listener. - - This asks the thread to terminate, and then waits for it to do so. - Note that if you don't call this before your application exits, there - may be some records still left on the queue, which won't be processed. - """ - self.enqueue_sentinel() - self._thread.join() - self._thread = None diff --git a/python/Lib/lzma.py b/python/Lib/lzma.py deleted file mode 100644 index 6b26e74..0000000 --- a/python/Lib/lzma.py +++ /dev/null @@ -1,356 +0,0 @@ -"""Interface to the liblzma compression library. - -This module provides a class for reading and writing compressed files, -classes for incremental (de)compression, and convenience functions for -one-shot (de)compression. - -These classes and functions support both the XZ and legacy LZMA -container formats, as well as raw compressed data streams. -""" - -__all__ = [ - "CHECK_NONE", "CHECK_CRC32", "CHECK_CRC64", "CHECK_SHA256", - "CHECK_ID_MAX", "CHECK_UNKNOWN", - "FILTER_LZMA1", "FILTER_LZMA2", "FILTER_DELTA", "FILTER_X86", "FILTER_IA64", - "FILTER_ARM", "FILTER_ARMTHUMB", "FILTER_POWERPC", "FILTER_SPARC", - "FORMAT_AUTO", "FORMAT_XZ", "FORMAT_ALONE", "FORMAT_RAW", - "MF_HC3", "MF_HC4", "MF_BT2", "MF_BT3", "MF_BT4", - "MODE_FAST", "MODE_NORMAL", "PRESET_DEFAULT", "PRESET_EXTREME", - - "LZMACompressor", "LZMADecompressor", "LZMAFile", "LZMAError", - "open", "compress", "decompress", "is_check_supported", -] - -import builtins -import io -import os -from _lzma import * -from _lzma import _encode_filter_properties, _decode_filter_properties -import _compression - - -_MODE_CLOSED = 0 -_MODE_READ = 1 -# Value 2 no longer used -_MODE_WRITE = 3 - - -class LZMAFile(_compression.BaseStream): - - """A file object providing transparent LZMA (de)compression. - - An LZMAFile can act as a wrapper for an existing file object, or - refer directly to a named file on disk. - - Note that LZMAFile provides a *binary* file interface - data read - is returned as bytes, and data to be written must be given as bytes. - """ - - def __init__(self, filename=None, mode="r", *, - format=None, check=-1, preset=None, filters=None): - """Open an LZMA-compressed file in binary mode. - - filename can be either an actual file name (given as a str, - bytes, or PathLike object), in which case the named file is - opened, or it can be an existing file object to read from or - write to. - - mode can be "r" for reading (default), "w" for (over)writing, - "x" for creating exclusively, or "a" for appending. These can - equivalently be given as "rb", "wb", "xb" and "ab" respectively. - - format specifies the container format to use for the file. - If mode is "r", this defaults to FORMAT_AUTO. Otherwise, the - default is FORMAT_XZ. - - check specifies the integrity check to use. This argument can - only be used when opening a file for writing. For FORMAT_XZ, - the default is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not - support integrity checks - for these formats, check must be - omitted, or be CHECK_NONE. - - When opening a file for reading, the *preset* argument is not - meaningful, and should be omitted. The *filters* argument should - also be omitted, except when format is FORMAT_RAW (in which case - it is required). - - When opening a file for writing, the settings used by the - compressor can be specified either as a preset compression - level (with the *preset* argument), or in detail as a custom - filter chain (with the *filters* argument). For FORMAT_XZ and - FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset - level. For FORMAT_RAW, the caller must always specify a filter - chain; the raw compressor does not support preset compression - levels. - - preset (if provided) should be an integer in the range 0-9, - optionally OR-ed with the constant PRESET_EXTREME. - - filters (if provided) should be a sequence of dicts. Each dict - should have an entry for "id" indicating ID of the filter, plus - additional entries for options to the filter. - """ - self._fp = None - self._closefp = False - self._mode = _MODE_CLOSED - - if mode in ("r", "rb"): - if check != -1: - raise ValueError("Cannot specify an integrity check " - "when opening a file for reading") - if preset is not None: - raise ValueError("Cannot specify a preset compression " - "level when opening a file for reading") - if format is None: - format = FORMAT_AUTO - mode_code = _MODE_READ - elif mode in ("w", "wb", "a", "ab", "x", "xb"): - if format is None: - format = FORMAT_XZ - mode_code = _MODE_WRITE - self._compressor = LZMACompressor(format=format, check=check, - preset=preset, filters=filters) - self._pos = 0 - else: - raise ValueError("Invalid mode: {!r}".format(mode)) - - if isinstance(filename, (str, bytes, os.PathLike)): - if "b" not in mode: - mode += "b" - self._fp = builtins.open(filename, mode) - self._closefp = True - self._mode = mode_code - elif hasattr(filename, "read") or hasattr(filename, "write"): - self._fp = filename - self._mode = mode_code - else: - raise TypeError("filename must be a str, bytes, file or PathLike object") - - if self._mode == _MODE_READ: - raw = _compression.DecompressReader(self._fp, LZMADecompressor, - trailing_error=LZMAError, format=format, filters=filters) - self._buffer = io.BufferedReader(raw) - - def close(self): - """Flush and close the file. - - May be called more than once without error. Once the file is - closed, any other operation on it will raise a ValueError. - """ - if self._mode == _MODE_CLOSED: - return - try: - if self._mode == _MODE_READ: - self._buffer.close() - self._buffer = None - elif self._mode == _MODE_WRITE: - self._fp.write(self._compressor.flush()) - self._compressor = None - finally: - try: - if self._closefp: - self._fp.close() - finally: - self._fp = None - self._closefp = False - self._mode = _MODE_CLOSED - - @property - def closed(self): - """True if this file is closed.""" - return self._mode == _MODE_CLOSED - - def fileno(self): - """Return the file descriptor for the underlying file.""" - self._check_not_closed() - return self._fp.fileno() - - def seekable(self): - """Return whether the file supports seeking.""" - return self.readable() and self._buffer.seekable() - - def readable(self): - """Return whether the file was opened for reading.""" - self._check_not_closed() - return self._mode == _MODE_READ - - def writable(self): - """Return whether the file was opened for writing.""" - self._check_not_closed() - return self._mode == _MODE_WRITE - - def peek(self, size=-1): - """Return buffered data without advancing the file position. - - Always returns at least one byte of data, unless at EOF. - The exact number of bytes returned is unspecified. - """ - self._check_can_read() - # Relies on the undocumented fact that BufferedReader.peek() always - # returns at least one byte (except at EOF) - return self._buffer.peek(size) - - def read(self, size=-1): - """Read up to size uncompressed bytes from the file. - - If size is negative or omitted, read until EOF is reached. - Returns b"" if the file is already at EOF. - """ - self._check_can_read() - return self._buffer.read(size) - - def read1(self, size=-1): - """Read up to size uncompressed bytes, while trying to avoid - making multiple reads from the underlying stream. Reads up to a - buffer's worth of data if size is negative. - - Returns b"" if the file is at EOF. - """ - self._check_can_read() - if size < 0: - size = io.DEFAULT_BUFFER_SIZE - return self._buffer.read1(size) - - def readline(self, size=-1): - """Read a line of uncompressed bytes from the file. - - The terminating newline (if present) is retained. If size is - non-negative, no more than size bytes will be read (in which - case the line may be incomplete). Returns b'' if already at EOF. - """ - self._check_can_read() - return self._buffer.readline(size) - - def write(self, data): - """Write a bytes object to the file. - - Returns the number of uncompressed bytes written, which is - always the length of data in bytes. Note that due to buffering, - the file on disk may not reflect the data written until close() - is called. - """ - self._check_can_write() - if isinstance(data, (bytes, bytearray)): - length = len(data) - else: - # accept any data that supports the buffer protocol - data = memoryview(data) - length = data.nbytes - - compressed = self._compressor.compress(data) - self._fp.write(compressed) - self._pos += length - return length - - def seek(self, offset, whence=io.SEEK_SET): - """Change the file position. - - The new position is specified by offset, relative to the - position indicated by whence. Possible values for whence are: - - 0: start of stream (default): offset must not be negative - 1: current stream position - 2: end of stream; offset must not be positive - - Returns the new file position. - - Note that seeking is emulated, so depending on the parameters, - this operation may be extremely slow. - """ - self._check_can_seek() - return self._buffer.seek(offset, whence) - - def tell(self): - """Return the current file position.""" - self._check_not_closed() - if self._mode == _MODE_READ: - return self._buffer.tell() - return self._pos - - -def open(filename, mode="rb", *, - format=None, check=-1, preset=None, filters=None, - encoding=None, errors=None, newline=None): - """Open an LZMA-compressed file in binary or text mode. - - filename can be either an actual file name (given as a str, bytes, - or PathLike object), in which case the named file is opened, or it - can be an existing file object to read from or write to. - - The mode argument can be "r", "rb" (default), "w", "wb", "x", "xb", - "a", or "ab" for binary mode, or "rt", "wt", "xt", or "at" for text - mode. - - The format, check, preset and filters arguments specify the - compression settings, as for LZMACompressor, LZMADecompressor and - LZMAFile. - - For binary mode, this function is equivalent to the LZMAFile - constructor: LZMAFile(filename, mode, ...). In this case, the - encoding, errors and newline arguments must not be provided. - - For text mode, an LZMAFile object is created, and wrapped in an - io.TextIOWrapper instance with the specified encoding, error - handling behavior, and line ending(s). - - """ - if "t" in mode: - if "b" in mode: - raise ValueError("Invalid mode: %r" % (mode,)) - else: - if encoding is not None: - raise ValueError("Argument 'encoding' not supported in binary mode") - if errors is not None: - raise ValueError("Argument 'errors' not supported in binary mode") - if newline is not None: - raise ValueError("Argument 'newline' not supported in binary mode") - - lz_mode = mode.replace("t", "") - binary_file = LZMAFile(filename, lz_mode, format=format, check=check, - preset=preset, filters=filters) - - if "t" in mode: - encoding = io.text_encoding(encoding) - return io.TextIOWrapper(binary_file, encoding, errors, newline) - else: - return binary_file - - -def compress(data, format=FORMAT_XZ, check=-1, preset=None, filters=None): - """Compress a block of data. - - Refer to LZMACompressor's docstring for a description of the - optional arguments *format*, *check*, *preset* and *filters*. - - For incremental compression, use an LZMACompressor instead. - """ - comp = LZMACompressor(format, check, preset, filters) - return comp.compress(data) + comp.flush() - - -def decompress(data, format=FORMAT_AUTO, memlimit=None, filters=None): - """Decompress a block of data. - - Refer to LZMADecompressor's docstring for a description of the - optional arguments *format*, *check* and *filters*. - - For incremental decompression, use an LZMADecompressor instead. - """ - results = [] - while True: - decomp = LZMADecompressor(format, memlimit, filters) - try: - res = decomp.decompress(data) - except LZMAError: - if results: - break # Leftover data is not a valid LZMA/XZ stream; ignore it. - else: - raise # Error on the first iteration; bail out. - results.append(res) - if not decomp.eof: - raise LZMAError("Compressed data ended before the " - "end-of-stream marker was reached") - data = decomp.unused_data - if not data: - break - return b"".join(results) diff --git a/python/Lib/mimetypes.py b/python/Lib/mimetypes.py deleted file mode 100644 index 4909272..0000000 --- a/python/Lib/mimetypes.py +++ /dev/null @@ -1,648 +0,0 @@ -"""Guess the MIME type of a file. - -This module defines two useful functions: - -guess_type(url, strict=True) -- guess the MIME type and encoding of a URL. - -guess_extension(type, strict=True) -- guess the extension for a given MIME type. - -It also contains the following, for tuning the behavior: - -Data: - -knownfiles -- list of files to parse -inited -- flag set when init() has been called -suffix_map -- dictionary mapping suffixes to suffixes -encodings_map -- dictionary mapping suffixes to encodings -types_map -- dictionary mapping suffixes to types - -Functions: - -init([files]) -- parse a list of files, default knownfiles (on Windows, the - default values are taken from the registry) -read_mime_types(file) -- parse one file, return a dictionary or None -""" - -import os -import sys -import posixpath -import urllib.parse - -try: - from _winapi import _mimetypes_read_windows_registry -except ImportError: - _mimetypes_read_windows_registry = None - -try: - import winreg as _winreg -except ImportError: - _winreg = None - -__all__ = [ - "knownfiles", "inited", "MimeTypes", - "guess_type", "guess_all_extensions", "guess_extension", - "add_type", "init", "read_mime_types", - "suffix_map", "encodings_map", "types_map", "common_types" -] - -knownfiles = [ - "/etc/mime.types", - "/etc/httpd/mime.types", # Mac OS X - "/etc/httpd/conf/mime.types", # Apache - "/etc/apache/mime.types", # Apache 1 - "/etc/apache2/mime.types", # Apache 2 - "/usr/local/etc/httpd/conf/mime.types", - "/usr/local/lib/netscape/mime.types", - "/usr/local/etc/httpd/conf/mime.types", # Apache 1.2 - "/usr/local/etc/mime.types", # Apache 1.3 - ] - -inited = False -_db = None - - -class MimeTypes: - """MIME-types datastore. - - This datastore can handle information from mime.types-style files - and supports basic determination of MIME type from a filename or - URL, and can guess a reasonable extension given a MIME type. - """ - - def __init__(self, filenames=(), strict=True): - if not inited: - init() - self.encodings_map = _encodings_map_default.copy() - self.suffix_map = _suffix_map_default.copy() - self.types_map = ({}, {}) # dict for (non-strict, strict) - self.types_map_inv = ({}, {}) - for (ext, type) in _types_map_default.items(): - self.add_type(type, ext, True) - for (ext, type) in _common_types_default.items(): - self.add_type(type, ext, False) - for name in filenames: - self.read(name, strict) - - def add_type(self, type, ext, strict=True): - """Add a mapping between a type and an extension. - - When the extension is already known, the new - type will replace the old one. When the type - is already known the extension will be added - to the list of known extensions. - - If strict is true, information will be added to - list of standard types, else to the list of non-standard - types. - """ - self.types_map[strict][ext] = type - exts = self.types_map_inv[strict].setdefault(type, []) - if ext not in exts: - exts.append(ext) - - def guess_type(self, url, strict=True): - """Guess the type of a file which is either a URL or a path-like object. - - Return value is a tuple (type, encoding) where type is None if - the type can't be guessed (no or unknown suffix) or a string - of the form type/subtype, usable for a MIME Content-type - header; and encoding is None for no encoding or the name of - the program used to encode (e.g. compress or gzip). The - mappings are table driven. Encoding suffixes are case - sensitive; type suffixes are first tried case sensitive, then - case insensitive. - - The suffixes .tgz, .taz and .tz (case sensitive!) are all - mapped to '.tar.gz'. (This is table-driven too, using the - dictionary suffix_map.) - - Optional `strict' argument when False adds a bunch of commonly found, - but non-standard types. - """ - url = os.fspath(url) - scheme, url = urllib.parse._splittype(url) - if scheme == 'data': - # syntax of data URLs: - # dataurl := "data:" [ mediatype ] [ ";base64" ] "," data - # mediatype := [ type "/" subtype ] *( ";" parameter ) - # data := *urlchar - # parameter := attribute "=" value - # type/subtype defaults to "text/plain" - comma = url.find(',') - if comma < 0: - # bad data URL - return None, None - semi = url.find(';', 0, comma) - if semi >= 0: - type = url[:semi] - else: - type = url[:comma] - if '=' in type or '/' not in type: - type = 'text/plain' - return type, None # never compressed, so encoding is None - base, ext = posixpath.splitext(url) - while (ext_lower := ext.lower()) in self.suffix_map: - base, ext = posixpath.splitext(base + self.suffix_map[ext_lower]) - # encodings_map is case sensitive - if ext in self.encodings_map: - encoding = self.encodings_map[ext] - base, ext = posixpath.splitext(base) - else: - encoding = None - ext = ext.lower() - types_map = self.types_map[True] - if ext in types_map: - return types_map[ext], encoding - elif strict: - return None, encoding - types_map = self.types_map[False] - if ext in types_map: - return types_map[ext], encoding - else: - return None, encoding - - def guess_all_extensions(self, type, strict=True): - """Guess the extensions for a file based on its MIME type. - - Return value is a list of strings giving the possible filename - extensions, including the leading dot ('.'). The extension is not - guaranteed to have been associated with any particular data stream, - but would be mapped to the MIME type `type' by guess_type(). - - Optional `strict' argument when false adds a bunch of commonly found, - but non-standard types. - """ - type = type.lower() - extensions = list(self.types_map_inv[True].get(type, [])) - if not strict: - for ext in self.types_map_inv[False].get(type, []): - if ext not in extensions: - extensions.append(ext) - return extensions - - def guess_extension(self, type, strict=True): - """Guess the extension for a file based on its MIME type. - - Return value is a string giving a filename extension, - including the leading dot ('.'). The extension is not - guaranteed to have been associated with any particular data - stream, but would be mapped to the MIME type `type' by - guess_type(). If no extension can be guessed for `type', None - is returned. - - Optional `strict' argument when false adds a bunch of commonly found, - but non-standard types. - """ - extensions = self.guess_all_extensions(type, strict) - if not extensions: - return None - return extensions[0] - - def read(self, filename, strict=True): - """ - Read a single mime.types-format file, specified by pathname. - - If strict is true, information will be added to - list of standard types, else to the list of non-standard - types. - """ - with open(filename, encoding='utf-8') as fp: - self.readfp(fp, strict) - - def readfp(self, fp, strict=True): - """ - Read a single mime.types-format file. - - If strict is true, information will be added to - list of standard types, else to the list of non-standard - types. - """ - while 1: - line = fp.readline() - if not line: - break - words = line.split() - for i in range(len(words)): - if words[i][0] == '#': - del words[i:] - break - if not words: - continue - type, suffixes = words[0], words[1:] - for suff in suffixes: - self.add_type(type, '.' + suff, strict) - - def read_windows_registry(self, strict=True): - """ - Load the MIME types database from Windows registry. - - If strict is true, information will be added to - list of standard types, else to the list of non-standard - types. - """ - - if not _mimetypes_read_windows_registry and not _winreg: - return - - add_type = self.add_type - if strict: - add_type = lambda type, ext: self.add_type(type, ext, True) - - # Accelerated function if it is available - if _mimetypes_read_windows_registry: - _mimetypes_read_windows_registry(add_type) - elif _winreg: - self._read_windows_registry(add_type) - - @classmethod - def _read_windows_registry(cls, add_type): - def enum_types(mimedb): - i = 0 - while True: - try: - ctype = _winreg.EnumKey(mimedb, i) - except OSError: - break - else: - if '\0' not in ctype: - yield ctype - i += 1 - - with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, '') as hkcr: - for subkeyname in enum_types(hkcr): - try: - with _winreg.OpenKey(hkcr, subkeyname) as subkey: - # Only check file extensions - if not subkeyname.startswith("."): - continue - # raises OSError if no 'Content Type' value - mimetype, datatype = _winreg.QueryValueEx( - subkey, 'Content Type') - if datatype != _winreg.REG_SZ: - continue - add_type(mimetype, subkeyname) - except OSError: - continue - -def guess_type(url, strict=True): - """Guess the type of a file based on its URL. - - Return value is a tuple (type, encoding) where type is None if the - type can't be guessed (no or unknown suffix) or a string of the - form type/subtype, usable for a MIME Content-type header; and - encoding is None for no encoding or the name of the program used - to encode (e.g. compress or gzip). The mappings are table - driven. Encoding suffixes are case sensitive; type suffixes are - first tried case sensitive, then case insensitive. - - The suffixes .tgz, .taz and .tz (case sensitive!) are all mapped - to ".tar.gz". (This is table-driven too, using the dictionary - suffix_map). - - Optional `strict' argument when false adds a bunch of commonly found, but - non-standard types. - """ - if _db is None: - init() - return _db.guess_type(url, strict) - - -def guess_all_extensions(type, strict=True): - """Guess the extensions for a file based on its MIME type. - - Return value is a list of strings giving the possible filename - extensions, including the leading dot ('.'). The extension is not - guaranteed to have been associated with any particular data - stream, but would be mapped to the MIME type `type' by - guess_type(). If no extension can be guessed for `type', None - is returned. - - Optional `strict' argument when false adds a bunch of commonly found, - but non-standard types. - """ - if _db is None: - init() - return _db.guess_all_extensions(type, strict) - -def guess_extension(type, strict=True): - """Guess the extension for a file based on its MIME type. - - Return value is a string giving a filename extension, including the - leading dot ('.'). The extension is not guaranteed to have been - associated with any particular data stream, but would be mapped to the - MIME type `type' by guess_type(). If no extension can be guessed for - `type', None is returned. - - Optional `strict' argument when false adds a bunch of commonly found, - but non-standard types. - """ - if _db is None: - init() - return _db.guess_extension(type, strict) - -def add_type(type, ext, strict=True): - """Add a mapping between a type and an extension. - - When the extension is already known, the new - type will replace the old one. When the type - is already known the extension will be added - to the list of known extensions. - - If strict is true, information will be added to - list of standard types, else to the list of non-standard - types. - """ - if _db is None: - init() - return _db.add_type(type, ext, strict) - - -def init(files=None): - global suffix_map, types_map, encodings_map, common_types - global inited, _db - inited = True # so that MimeTypes.__init__() doesn't call us again - - if files is None or _db is None: - db = MimeTypes() - # Quick return if not supported - db.read_windows_registry() - - if files is None: - files = knownfiles - else: - files = knownfiles + list(files) - else: - db = _db - - for file in files: - if os.path.isfile(file): - db.read(file) - encodings_map = db.encodings_map - suffix_map = db.suffix_map - types_map = db.types_map[True] - common_types = db.types_map[False] - # Make the DB a global variable now that it is fully initialized - _db = db - - -def read_mime_types(file): - try: - f = open(file, encoding='utf-8') - except OSError: - return None - with f: - db = MimeTypes() - db.readfp(f, True) - return db.types_map[True] - - -def _default_mime_types(): - global suffix_map, _suffix_map_default - global encodings_map, _encodings_map_default - global types_map, _types_map_default - global common_types, _common_types_default - - suffix_map = _suffix_map_default = { - '.svgz': '.svg.gz', - '.tgz': '.tar.gz', - '.taz': '.tar.gz', - '.tz': '.tar.gz', - '.tbz2': '.tar.bz2', - '.txz': '.tar.xz', - } - - encodings_map = _encodings_map_default = { - '.gz': 'gzip', - '.Z': 'compress', - '.bz2': 'bzip2', - '.xz': 'xz', - '.br': 'br', - } - - # Before adding new types, make sure they are either registered with IANA, - # at http://www.iana.org/assignments/media-types - # or extensions, i.e. using the x- prefix - - # If you add to these, please keep them sorted by mime type. - # Make sure the entry with the preferred file extension for a particular mime type - # appears before any others of the same mimetype. - types_map = _types_map_default = { - '.js' : 'application/javascript', - '.mjs' : 'application/javascript', - '.json' : 'application/json', - '.webmanifest': 'application/manifest+json', - '.doc' : 'application/msword', - '.dot' : 'application/msword', - '.wiz' : 'application/msword', - '.nq' : 'application/n-quads', - '.nt' : 'application/n-triples', - '.bin' : 'application/octet-stream', - '.a' : 'application/octet-stream', - '.dll' : 'application/octet-stream', - '.exe' : 'application/octet-stream', - '.o' : 'application/octet-stream', - '.obj' : 'application/octet-stream', - '.so' : 'application/octet-stream', - '.oda' : 'application/oda', - '.pdf' : 'application/pdf', - '.p7c' : 'application/pkcs7-mime', - '.ps' : 'application/postscript', - '.ai' : 'application/postscript', - '.eps' : 'application/postscript', - '.trig' : 'application/trig', - '.m3u' : 'application/vnd.apple.mpegurl', - '.m3u8' : 'application/vnd.apple.mpegurl', - '.xls' : 'application/vnd.ms-excel', - '.xlb' : 'application/vnd.ms-excel', - '.ppt' : 'application/vnd.ms-powerpoint', - '.pot' : 'application/vnd.ms-powerpoint', - '.ppa' : 'application/vnd.ms-powerpoint', - '.pps' : 'application/vnd.ms-powerpoint', - '.pwz' : 'application/vnd.ms-powerpoint', - '.wasm' : 'application/wasm', - '.bcpio' : 'application/x-bcpio', - '.cpio' : 'application/x-cpio', - '.csh' : 'application/x-csh', - '.dvi' : 'application/x-dvi', - '.gtar' : 'application/x-gtar', - '.hdf' : 'application/x-hdf', - '.h5' : 'application/x-hdf5', - '.latex' : 'application/x-latex', - '.mif' : 'application/x-mif', - '.cdf' : 'application/x-netcdf', - '.nc' : 'application/x-netcdf', - '.p12' : 'application/x-pkcs12', - '.pfx' : 'application/x-pkcs12', - '.ram' : 'application/x-pn-realaudio', - '.pyc' : 'application/x-python-code', - '.pyo' : 'application/x-python-code', - '.sh' : 'application/x-sh', - '.shar' : 'application/x-shar', - '.swf' : 'application/x-shockwave-flash', - '.sv4cpio': 'application/x-sv4cpio', - '.sv4crc' : 'application/x-sv4crc', - '.tar' : 'application/x-tar', - '.tcl' : 'application/x-tcl', - '.tex' : 'application/x-tex', - '.texi' : 'application/x-texinfo', - '.texinfo': 'application/x-texinfo', - '.roff' : 'application/x-troff', - '.t' : 'application/x-troff', - '.tr' : 'application/x-troff', - '.man' : 'application/x-troff-man', - '.me' : 'application/x-troff-me', - '.ms' : 'application/x-troff-ms', - '.ustar' : 'application/x-ustar', - '.src' : 'application/x-wais-source', - '.xsl' : 'application/xml', - '.rdf' : 'application/xml', - '.wsdl' : 'application/xml', - '.xpdl' : 'application/xml', - '.zip' : 'application/zip', - '.3gp' : 'audio/3gpp', - '.3gpp' : 'audio/3gpp', - '.3g2' : 'audio/3gpp2', - '.3gpp2' : 'audio/3gpp2', - '.aac' : 'audio/aac', - '.adts' : 'audio/aac', - '.loas' : 'audio/aac', - '.ass' : 'audio/aac', - '.au' : 'audio/basic', - '.snd' : 'audio/basic', - '.mp3' : 'audio/mpeg', - '.mp2' : 'audio/mpeg', - '.opus' : 'audio/opus', - '.aif' : 'audio/x-aiff', - '.aifc' : 'audio/x-aiff', - '.aiff' : 'audio/x-aiff', - '.ra' : 'audio/x-pn-realaudio', - '.wav' : 'audio/x-wav', - '.avif' : 'image/avif', - '.bmp' : 'image/bmp', - '.gif' : 'image/gif', - '.ief' : 'image/ief', - '.jpg' : 'image/jpeg', - '.jpe' : 'image/jpeg', - '.jpeg' : 'image/jpeg', - '.heic' : 'image/heic', - '.heif' : 'image/heif', - '.png' : 'image/png', - '.svg' : 'image/svg+xml', - '.tiff' : 'image/tiff', - '.tif' : 'image/tiff', - '.ico' : 'image/vnd.microsoft.icon', - '.ras' : 'image/x-cmu-raster', - '.pnm' : 'image/x-portable-anymap', - '.pbm' : 'image/x-portable-bitmap', - '.pgm' : 'image/x-portable-graymap', - '.ppm' : 'image/x-portable-pixmap', - '.rgb' : 'image/x-rgb', - '.xbm' : 'image/x-xbitmap', - '.xpm' : 'image/x-xpixmap', - '.xwd' : 'image/x-xwindowdump', - '.eml' : 'message/rfc822', - '.mht' : 'message/rfc822', - '.mhtml' : 'message/rfc822', - '.nws' : 'message/rfc822', - '.css' : 'text/css', - '.csv' : 'text/csv', - '.html' : 'text/html', - '.htm' : 'text/html', - '.n3' : 'text/n3', - '.txt' : 'text/plain', - '.bat' : 'text/plain', - '.c' : 'text/plain', - '.h' : 'text/plain', - '.ksh' : 'text/plain', - '.pl' : 'text/plain', - '.srt' : 'text/plain', - '.rtx' : 'text/richtext', - '.tsv' : 'text/tab-separated-values', - '.vtt' : 'text/vtt', - '.py' : 'text/x-python', - '.etx' : 'text/x-setext', - '.sgm' : 'text/x-sgml', - '.sgml' : 'text/x-sgml', - '.vcf' : 'text/x-vcard', - '.xml' : 'text/xml', - '.mp4' : 'video/mp4', - '.mpeg' : 'video/mpeg', - '.m1v' : 'video/mpeg', - '.mpa' : 'video/mpeg', - '.mpe' : 'video/mpeg', - '.mpg' : 'video/mpeg', - '.mov' : 'video/quicktime', - '.qt' : 'video/quicktime', - '.webm' : 'video/webm', - '.avi' : 'video/x-msvideo', - '.movie' : 'video/x-sgi-movie', - } - - # These are non-standard types, commonly found in the wild. They will - # only match if strict=0 flag is given to the API methods. - - # Please sort these too - common_types = _common_types_default = { - '.rtf' : 'application/rtf', - '.midi': 'audio/midi', - '.mid' : 'audio/midi', - '.jpg' : 'image/jpg', - '.pict': 'image/pict', - '.pct' : 'image/pict', - '.pic' : 'image/pict', - '.webp': 'image/webp', - '.xul' : 'text/xul', - } - - -_default_mime_types() - - -def _main(): - import getopt - - USAGE = """\ -Usage: mimetypes.py [options] type - -Options: - --help / -h -- print this message and exit - --lenient / -l -- additionally search of some common, but non-standard - types. - --extension / -e -- guess extension instead of type - -More than one type argument may be given. -""" - - def usage(code, msg=''): - print(USAGE) - if msg: print(msg) - sys.exit(code) - - try: - opts, args = getopt.getopt(sys.argv[1:], 'hle', - ['help', 'lenient', 'extension']) - except getopt.error as msg: - usage(1, msg) - - strict = 1 - extension = 0 - for opt, arg in opts: - if opt in ('-h', '--help'): - usage(0) - elif opt in ('-l', '--lenient'): - strict = 0 - elif opt in ('-e', '--extension'): - extension = 1 - for gtype in args: - if extension: - guess = guess_extension(gtype, strict) - if not guess: print("I don't know anything about type", gtype) - else: print(guess) - else: - guess, encoding = guess_type(gtype, strict) - if not guess: print("I don't know anything about type", gtype) - else: print('type:', guess, 'encoding:', encoding) - - -if __name__ == '__main__': - _main() diff --git a/python/Lib/modulefinder.py b/python/Lib/modulefinder.py deleted file mode 100644 index f19a6b3..0000000 --- a/python/Lib/modulefinder.py +++ /dev/null @@ -1,666 +0,0 @@ -"""Find modules used by a script, using introspection.""" - -import dis -import importlib._bootstrap_external -import importlib.machinery -import marshal -import os -import io -import sys - -# Old imp constants: - -_SEARCH_ERROR = 0 -_PY_SOURCE = 1 -_PY_COMPILED = 2 -_C_EXTENSION = 3 -_PKG_DIRECTORY = 5 -_C_BUILTIN = 6 -_PY_FROZEN = 7 - -# Modulefinder does a good job at simulating Python's, but it can not -# handle __path__ modifications packages make at runtime. Therefore there -# is a mechanism whereby you can register extra paths in this map for a -# package, and it will be honored. - -# Note this is a mapping is lists of paths. -packagePathMap = {} - -# A Public interface -def AddPackagePath(packagename, path): - packagePathMap.setdefault(packagename, []).append(path) - -replacePackageMap = {} - -# This ReplacePackage mechanism allows modulefinder to work around -# situations in which a package injects itself under the name -# of another package into sys.modules at runtime by calling -# ReplacePackage("real_package_name", "faked_package_name") -# before running ModuleFinder. - -def ReplacePackage(oldname, newname): - replacePackageMap[oldname] = newname - - -def _find_module(name, path=None): - """An importlib reimplementation of imp.find_module (for our purposes).""" - - # It's necessary to clear the caches for our Finder first, in case any - # modules are being added/deleted/modified at runtime. In particular, - # test_modulefinder.py changes file tree contents in a cache-breaking way: - - importlib.machinery.PathFinder.invalidate_caches() - - spec = importlib.machinery.PathFinder.find_spec(name, path) - - if spec is None: - raise ImportError("No module named {name!r}".format(name=name), name=name) - - # Some special cases: - - if spec.loader is importlib.machinery.BuiltinImporter: - return None, None, ("", "", _C_BUILTIN) - - if spec.loader is importlib.machinery.FrozenImporter: - return None, None, ("", "", _PY_FROZEN) - - file_path = spec.origin - - if spec.loader.is_package(name): - return None, os.path.dirname(file_path), ("", "", _PKG_DIRECTORY) - - if isinstance(spec.loader, importlib.machinery.SourceFileLoader): - kind = _PY_SOURCE - - elif isinstance(spec.loader, importlib.machinery.ExtensionFileLoader): - kind = _C_EXTENSION - - elif isinstance(spec.loader, importlib.machinery.SourcelessFileLoader): - kind = _PY_COMPILED - - else: # Should never happen. - return None, None, ("", "", _SEARCH_ERROR) - - file = io.open_code(file_path) - suffix = os.path.splitext(file_path)[-1] - - return file, file_path, (suffix, "rb", kind) - - -class Module: - - def __init__(self, name, file=None, path=None): - self.__name__ = name - self.__file__ = file - self.__path__ = path - self.__code__ = None - # The set of global names that are assigned to in the module. - # This includes those names imported through starimports of - # Python modules. - self.globalnames = {} - # The set of starimports this module did that could not be - # resolved, ie. a starimport from a non-Python module. - self.starimports = {} - - def __repr__(self): - s = "Module(%r" % (self.__name__,) - if self.__file__ is not None: - s = s + ", %r" % (self.__file__,) - if self.__path__ is not None: - s = s + ", %r" % (self.__path__,) - s = s + ")" - return s - -class ModuleFinder: - - def __init__(self, path=None, debug=0, excludes=None, replace_paths=None): - if path is None: - path = sys.path - self.path = path - self.modules = {} - self.badmodules = {} - self.debug = debug - self.indent = 0 - self.excludes = excludes if excludes is not None else [] - self.replace_paths = replace_paths if replace_paths is not None else [] - self.processed_paths = [] # Used in debugging only - - def msg(self, level, str, *args): - if level <= self.debug: - for i in range(self.indent): - print(" ", end=' ') - print(str, end=' ') - for arg in args: - print(repr(arg), end=' ') - print() - - def msgin(self, *args): - level = args[0] - if level <= self.debug: - self.indent = self.indent + 1 - self.msg(*args) - - def msgout(self, *args): - level = args[0] - if level <= self.debug: - self.indent = self.indent - 1 - self.msg(*args) - - def run_script(self, pathname): - self.msg(2, "run_script", pathname) - with io.open_code(pathname) as fp: - stuff = ("", "rb", _PY_SOURCE) - self.load_module('__main__', fp, pathname, stuff) - - def load_file(self, pathname): - dir, name = os.path.split(pathname) - name, ext = os.path.splitext(name) - with io.open_code(pathname) as fp: - stuff = (ext, "rb", _PY_SOURCE) - self.load_module(name, fp, pathname, stuff) - - def import_hook(self, name, caller=None, fromlist=None, level=-1): - self.msg(3, "import_hook", name, caller, fromlist, level) - parent = self.determine_parent(caller, level=level) - q, tail = self.find_head_package(parent, name) - m = self.load_tail(q, tail) - if not fromlist: - return q - if m.__path__: - self.ensure_fromlist(m, fromlist) - return None - - def determine_parent(self, caller, level=-1): - self.msgin(4, "determine_parent", caller, level) - if not caller or level == 0: - self.msgout(4, "determine_parent -> None") - return None - pname = caller.__name__ - if level >= 1: # relative import - if caller.__path__: - level -= 1 - if level == 0: - parent = self.modules[pname] - assert parent is caller - self.msgout(4, "determine_parent ->", parent) - return parent - if pname.count(".") < level: - raise ImportError("relative importpath too deep") - pname = ".".join(pname.split(".")[:-level]) - parent = self.modules[pname] - self.msgout(4, "determine_parent ->", parent) - return parent - if caller.__path__: - parent = self.modules[pname] - assert caller is parent - self.msgout(4, "determine_parent ->", parent) - return parent - if '.' in pname: - i = pname.rfind('.') - pname = pname[:i] - parent = self.modules[pname] - assert parent.__name__ == pname - self.msgout(4, "determine_parent ->", parent) - return parent - self.msgout(4, "determine_parent -> None") - return None - - def find_head_package(self, parent, name): - self.msgin(4, "find_head_package", parent, name) - if '.' in name: - i = name.find('.') - head = name[:i] - tail = name[i+1:] - else: - head = name - tail = "" - if parent: - qname = "%s.%s" % (parent.__name__, head) - else: - qname = head - q = self.import_module(head, qname, parent) - if q: - self.msgout(4, "find_head_package ->", (q, tail)) - return q, tail - if parent: - qname = head - parent = None - q = self.import_module(head, qname, parent) - if q: - self.msgout(4, "find_head_package ->", (q, tail)) - return q, tail - self.msgout(4, "raise ImportError: No module named", qname) - raise ImportError("No module named " + qname) - - def load_tail(self, q, tail): - self.msgin(4, "load_tail", q, tail) - m = q - while tail: - i = tail.find('.') - if i < 0: i = len(tail) - head, tail = tail[:i], tail[i+1:] - mname = "%s.%s" % (m.__name__, head) - m = self.import_module(head, mname, m) - if not m: - self.msgout(4, "raise ImportError: No module named", mname) - raise ImportError("No module named " + mname) - self.msgout(4, "load_tail ->", m) - return m - - def ensure_fromlist(self, m, fromlist, recursive=0): - self.msg(4, "ensure_fromlist", m, fromlist, recursive) - for sub in fromlist: - if sub == "*": - if not recursive: - all = self.find_all_submodules(m) - if all: - self.ensure_fromlist(m, all, 1) - elif not hasattr(m, sub): - subname = "%s.%s" % (m.__name__, sub) - submod = self.import_module(sub, subname, m) - if not submod: - raise ImportError("No module named " + subname) - - def find_all_submodules(self, m): - if not m.__path__: - return - modules = {} - # 'suffixes' used to be a list hardcoded to [".py", ".pyc"]. - # But we must also collect Python extension modules - although - # we cannot separate normal dlls from Python extensions. - suffixes = [] - suffixes += importlib.machinery.EXTENSION_SUFFIXES[:] - suffixes += importlib.machinery.SOURCE_SUFFIXES[:] - suffixes += importlib.machinery.BYTECODE_SUFFIXES[:] - for dir in m.__path__: - try: - names = os.listdir(dir) - except OSError: - self.msg(2, "can't list directory", dir) - continue - for name in names: - mod = None - for suff in suffixes: - n = len(suff) - if name[-n:] == suff: - mod = name[:-n] - break - if mod and mod != "__init__": - modules[mod] = mod - return modules.keys() - - def import_module(self, partname, fqname, parent): - self.msgin(3, "import_module", partname, fqname, parent) - try: - m = self.modules[fqname] - except KeyError: - pass - else: - self.msgout(3, "import_module ->", m) - return m - if fqname in self.badmodules: - self.msgout(3, "import_module -> None") - return None - if parent and parent.__path__ is None: - self.msgout(3, "import_module -> None") - return None - try: - fp, pathname, stuff = self.find_module(partname, - parent and parent.__path__, parent) - except ImportError: - self.msgout(3, "import_module ->", None) - return None - - try: - m = self.load_module(fqname, fp, pathname, stuff) - finally: - if fp: - fp.close() - if parent: - setattr(parent, partname, m) - self.msgout(3, "import_module ->", m) - return m - - def load_module(self, fqname, fp, pathname, file_info): - suffix, mode, type = file_info - self.msgin(2, "load_module", fqname, fp and "fp", pathname) - if type == _PKG_DIRECTORY: - m = self.load_package(fqname, pathname) - self.msgout(2, "load_module ->", m) - return m - if type == _PY_SOURCE: - co = compile(fp.read(), pathname, 'exec') - elif type == _PY_COMPILED: - try: - data = fp.read() - importlib._bootstrap_external._classify_pyc(data, fqname, {}) - except ImportError as exc: - self.msgout(2, "raise ImportError: " + str(exc), pathname) - raise - co = marshal.loads(memoryview(data)[16:]) - else: - co = None - m = self.add_module(fqname) - m.__file__ = pathname - if co: - if self.replace_paths: - co = self.replace_paths_in_code(co) - m.__code__ = co - self.scan_code(co, m) - self.msgout(2, "load_module ->", m) - return m - - def _add_badmodule(self, name, caller): - if name not in self.badmodules: - self.badmodules[name] = {} - if caller: - self.badmodules[name][caller.__name__] = 1 - else: - self.badmodules[name]["-"] = 1 - - def _safe_import_hook(self, name, caller, fromlist, level=-1): - # wrapper for self.import_hook() that won't raise ImportError - if name in self.badmodules: - self._add_badmodule(name, caller) - return - try: - self.import_hook(name, caller, level=level) - except ImportError as msg: - self.msg(2, "ImportError:", str(msg)) - self._add_badmodule(name, caller) - except SyntaxError as msg: - self.msg(2, "SyntaxError:", str(msg)) - self._add_badmodule(name, caller) - else: - if fromlist: - for sub in fromlist: - fullname = name + "." + sub - if fullname in self.badmodules: - self._add_badmodule(fullname, caller) - continue - try: - self.import_hook(name, caller, [sub], level=level) - except ImportError as msg: - self.msg(2, "ImportError:", str(msg)) - self._add_badmodule(fullname, caller) - - def scan_opcodes(self, co): - # Scan the code, and yield 'interesting' opcode combinations - for name in dis._find_store_names(co): - yield "store", (name,) - for name, level, fromlist in dis._find_imports(co): - if level == 0: # absolute import - yield "absolute_import", (fromlist, name) - else: # relative import - yield "relative_import", (level, fromlist, name) - - def scan_code(self, co, m): - code = co.co_code - scanner = self.scan_opcodes - for what, args in scanner(co): - if what == "store": - name, = args - m.globalnames[name] = 1 - elif what == "absolute_import": - fromlist, name = args - have_star = 0 - if fromlist is not None: - if "*" in fromlist: - have_star = 1 - fromlist = [f for f in fromlist if f != "*"] - self._safe_import_hook(name, m, fromlist, level=0) - if have_star: - # We've encountered an "import *". If it is a Python module, - # the code has already been parsed and we can suck out the - # global names. - mm = None - if m.__path__: - # At this point we don't know whether 'name' is a - # submodule of 'm' or a global module. Let's just try - # the full name first. - mm = self.modules.get(m.__name__ + "." + name) - if mm is None: - mm = self.modules.get(name) - if mm is not None: - m.globalnames.update(mm.globalnames) - m.starimports.update(mm.starimports) - if mm.__code__ is None: - m.starimports[name] = 1 - else: - m.starimports[name] = 1 - elif what == "relative_import": - level, fromlist, name = args - if name: - self._safe_import_hook(name, m, fromlist, level=level) - else: - parent = self.determine_parent(m, level=level) - self._safe_import_hook(parent.__name__, None, fromlist, level=0) - else: - # We don't expect anything else from the generator. - raise RuntimeError(what) - - for c in co.co_consts: - if isinstance(c, type(co)): - self.scan_code(c, m) - - def load_package(self, fqname, pathname): - self.msgin(2, "load_package", fqname, pathname) - newname = replacePackageMap.get(fqname) - if newname: - fqname = newname - m = self.add_module(fqname) - m.__file__ = pathname - m.__path__ = [pathname] - - # As per comment at top of file, simulate runtime __path__ additions. - m.__path__ = m.__path__ + packagePathMap.get(fqname, []) - - fp, buf, stuff = self.find_module("__init__", m.__path__) - try: - self.load_module(fqname, fp, buf, stuff) - self.msgout(2, "load_package ->", m) - return m - finally: - if fp: - fp.close() - - def add_module(self, fqname): - if fqname in self.modules: - return self.modules[fqname] - self.modules[fqname] = m = Module(fqname) - return m - - def find_module(self, name, path, parent=None): - if parent is not None: - # assert path is not None - fullname = parent.__name__+'.'+name - else: - fullname = name - if fullname in self.excludes: - self.msgout(3, "find_module -> Excluded", fullname) - raise ImportError(name) - - if path is None: - if name in sys.builtin_module_names: - return (None, None, ("", "", _C_BUILTIN)) - - path = self.path - - return _find_module(name, path) - - def report(self): - """Print a report to stdout, listing the found modules with their - paths, as well as modules that are missing, or seem to be missing. - """ - print() - print(" %-25s %s" % ("Name", "File")) - print(" %-25s %s" % ("----", "----")) - # Print modules found - keys = sorted(self.modules.keys()) - for key in keys: - m = self.modules[key] - if m.__path__: - print("P", end=' ') - else: - print("m", end=' ') - print("%-25s" % key, m.__file__ or "") - - # Print missing modules - missing, maybe = self.any_missing_maybe() - if missing: - print() - print("Missing modules:") - for name in missing: - mods = sorted(self.badmodules[name].keys()) - print("?", name, "imported from", ', '.join(mods)) - # Print modules that may be missing, but then again, maybe not... - if maybe: - print() - print("Submodules that appear to be missing, but could also be", end=' ') - print("global names in the parent package:") - for name in maybe: - mods = sorted(self.badmodules[name].keys()) - print("?", name, "imported from", ', '.join(mods)) - - def any_missing(self): - """Return a list of modules that appear to be missing. Use - any_missing_maybe() if you want to know which modules are - certain to be missing, and which *may* be missing. - """ - missing, maybe = self.any_missing_maybe() - return missing + maybe - - def any_missing_maybe(self): - """Return two lists, one with modules that are certainly missing - and one with modules that *may* be missing. The latter names could - either be submodules *or* just global names in the package. - - The reason it can't always be determined is that it's impossible to - tell which names are imported when "from module import *" is done - with an extension module, short of actually importing it. - """ - missing = [] - maybe = [] - for name in self.badmodules: - if name in self.excludes: - continue - i = name.rfind(".") - if i < 0: - missing.append(name) - continue - subname = name[i+1:] - pkgname = name[:i] - pkg = self.modules.get(pkgname) - if pkg is not None: - if pkgname in self.badmodules[name]: - # The package tried to import this module itself and - # failed. It's definitely missing. - missing.append(name) - elif subname in pkg.globalnames: - # It's a global in the package: definitely not missing. - pass - elif pkg.starimports: - # It could be missing, but the package did an "import *" - # from a non-Python module, so we simply can't be sure. - maybe.append(name) - else: - # It's not a global in the package, the package didn't - # do funny star imports, it's very likely to be missing. - # The symbol could be inserted into the package from the - # outside, but since that's not good style we simply list - # it missing. - missing.append(name) - else: - missing.append(name) - missing.sort() - maybe.sort() - return missing, maybe - - def replace_paths_in_code(self, co): - new_filename = original_filename = os.path.normpath(co.co_filename) - for f, r in self.replace_paths: - if original_filename.startswith(f): - new_filename = r + original_filename[len(f):] - break - - if self.debug and original_filename not in self.processed_paths: - if new_filename != original_filename: - self.msgout(2, "co_filename %r changed to %r" \ - % (original_filename,new_filename,)) - else: - self.msgout(2, "co_filename %r remains unchanged" \ - % (original_filename,)) - self.processed_paths.append(original_filename) - - consts = list(co.co_consts) - for i in range(len(consts)): - if isinstance(consts[i], type(co)): - consts[i] = self.replace_paths_in_code(consts[i]) - - return co.replace(co_consts=tuple(consts), co_filename=new_filename) - - -def test(): - # Parse command line - import getopt - try: - opts, args = getopt.getopt(sys.argv[1:], "dmp:qx:") - except getopt.error as msg: - print(msg) - return - - # Process options - debug = 1 - domods = 0 - addpath = [] - exclude = [] - for o, a in opts: - if o == '-d': - debug = debug + 1 - if o == '-m': - domods = 1 - if o == '-p': - addpath = addpath + a.split(os.pathsep) - if o == '-q': - debug = 0 - if o == '-x': - exclude.append(a) - - # Provide default arguments - if not args: - script = "hello.py" - else: - script = args[0] - - # Set the path based on sys.path and the script directory - path = sys.path[:] - path[0] = os.path.dirname(script) - path = addpath + path - if debug > 1: - print("path:") - for item in path: - print(" ", repr(item)) - - # Create the module finder and turn its crank - mf = ModuleFinder(path, debug, exclude) - for arg in args[1:]: - if arg == '-m': - domods = 1 - continue - if domods: - if arg[-2:] == '.*': - mf.import_hook(arg[:-2], None, ["*"]) - else: - mf.import_hook(arg) - else: - mf.load_file(arg) - mf.run_script(script) - mf.report() - return mf # for -i debugging - - -if __name__ == '__main__': - try: - mf = test() - except KeyboardInterrupt: - print("\n[interrupted]") diff --git a/python/Lib/multiprocessing/__init__.py b/python/Lib/multiprocessing/__init__.py deleted file mode 100644 index d8d1117..0000000 --- a/python/Lib/multiprocessing/__init__.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# Package analogous to 'threading.py' but using processes -# -# multiprocessing/__init__.py -# -# This package is intended to duplicate the functionality (and much of -# the API) of threading.py but uses processes instead of threads. A -# subpackage 'multiprocessing.dummy' has the same API but is a simple -# wrapper for 'threading'. -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -import sys -from . import context - -# -# Copy stuff from default context -# - -__all__ = [x for x in dir(context._default_context) if not x.startswith('_')] -globals().update((name, getattr(context._default_context, name)) for name in __all__) - -# -# XXX These should not really be documented or public. -# - -SUBDEBUG = 5 -SUBWARNING = 25 - -# -# Alias for main module -- will be reset by bootstrapping child processes -# - -if '__main__' in sys.modules: - sys.modules['__mp_main__'] = sys.modules['__main__'] diff --git a/python/Lib/multiprocessing/connection.py b/python/Lib/multiprocessing/connection.py deleted file mode 100644 index 4f7d963..0000000 --- a/python/Lib/multiprocessing/connection.py +++ /dev/null @@ -1,972 +0,0 @@ -# -# A higher level module for using sockets (or Windows named pipes) -# -# multiprocessing/connection.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -__all__ = [ 'Client', 'Listener', 'Pipe', 'wait' ] - -import io -import os -import sys -import socket -import struct -import time -import tempfile -import itertools - -import _multiprocessing - -from . import util - -from . import AuthenticationError, BufferTooShort -from .context import reduction -_ForkingPickler = reduction.ForkingPickler - -try: - import _winapi - from _winapi import WAIT_OBJECT_0, WAIT_ABANDONED_0, WAIT_TIMEOUT, INFINITE -except ImportError: - if sys.platform == 'win32': - raise - _winapi = None - -# -# -# - -BUFSIZE = 8192 -# A very generous timeout when it comes to local connections... -CONNECTION_TIMEOUT = 20. - -_mmap_counter = itertools.count() - -default_family = 'AF_INET' -families = ['AF_INET'] - -if hasattr(socket, 'AF_UNIX'): - default_family = 'AF_UNIX' - families += ['AF_UNIX'] - -if sys.platform == 'win32': - default_family = 'AF_PIPE' - families += ['AF_PIPE'] - - -def _init_timeout(timeout=CONNECTION_TIMEOUT): - return time.monotonic() + timeout - -def _check_timeout(t): - return time.monotonic() > t - -# -# -# - -def arbitrary_address(family): - ''' - Return an arbitrary free address for the given family - ''' - if family == 'AF_INET': - return ('localhost', 0) - elif family == 'AF_UNIX': - return tempfile.mktemp(prefix='listener-', dir=util.get_temp_dir()) - elif family == 'AF_PIPE': - return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' % - (os.getpid(), next(_mmap_counter)), dir="") - else: - raise ValueError('unrecognized family') - -def _validate_family(family): - ''' - Checks if the family is valid for the current environment. - ''' - if sys.platform != 'win32' and family == 'AF_PIPE': - raise ValueError('Family %s is not recognized.' % family) - - if sys.platform == 'win32' and family == 'AF_UNIX': - # double check - if not hasattr(socket, family): - raise ValueError('Family %s is not recognized.' % family) - -def address_type(address): - ''' - Return the types of the address - - This can be 'AF_INET', 'AF_UNIX', or 'AF_PIPE' - ''' - if type(address) == tuple: - return 'AF_INET' - elif type(address) is str and address.startswith('\\\\'): - return 'AF_PIPE' - elif type(address) is str or util.is_abstract_socket_namespace(address): - return 'AF_UNIX' - else: - raise ValueError('address type of %r unrecognized' % address) - -# -# Connection classes -# - -class _ConnectionBase: - _handle = None - - def __init__(self, handle, readable=True, writable=True): - handle = handle.__index__() - if handle < 0: - raise ValueError("invalid handle") - if not readable and not writable: - raise ValueError( - "at least one of `readable` and `writable` must be True") - self._handle = handle - self._readable = readable - self._writable = writable - - # XXX should we use util.Finalize instead of a __del__? - - def __del__(self): - if self._handle is not None: - self._close() - - def _check_closed(self): - if self._handle is None: - raise OSError("handle is closed") - - def _check_readable(self): - if not self._readable: - raise OSError("connection is write-only") - - def _check_writable(self): - if not self._writable: - raise OSError("connection is read-only") - - def _bad_message_length(self): - if self._writable: - self._readable = False - else: - self.close() - raise OSError("bad message length") - - @property - def closed(self): - """True if the connection is closed""" - return self._handle is None - - @property - def readable(self): - """True if the connection is readable""" - return self._readable - - @property - def writable(self): - """True if the connection is writable""" - return self._writable - - def fileno(self): - """File descriptor or handle of the connection""" - self._check_closed() - return self._handle - - def close(self): - """Close the connection""" - if self._handle is not None: - try: - self._close() - finally: - self._handle = None - - def send_bytes(self, buf, offset=0, size=None): - """Send the bytes data from a bytes-like object""" - self._check_closed() - self._check_writable() - m = memoryview(buf) - if m.itemsize > 1: - m = m.cast('B') - n = m.nbytes - if offset < 0: - raise ValueError("offset is negative") - if n < offset: - raise ValueError("buffer length < offset") - if size is None: - size = n - offset - elif size < 0: - raise ValueError("size is negative") - elif offset + size > n: - raise ValueError("buffer length < offset + size") - self._send_bytes(m[offset:offset + size]) - - def send(self, obj): - """Send a (picklable) object""" - self._check_closed() - self._check_writable() - self._send_bytes(_ForkingPickler.dumps(obj)) - - def recv_bytes(self, maxlength=None): - """ - Receive bytes data as a bytes object. - """ - self._check_closed() - self._check_readable() - if maxlength is not None and maxlength < 0: - raise ValueError("negative maxlength") - buf = self._recv_bytes(maxlength) - if buf is None: - self._bad_message_length() - return buf.getvalue() - - def recv_bytes_into(self, buf, offset=0): - """ - Receive bytes data into a writeable bytes-like object. - Return the number of bytes read. - """ - self._check_closed() - self._check_readable() - with memoryview(buf) as m: - # Get bytesize of arbitrary buffer - itemsize = m.itemsize - bytesize = itemsize * len(m) - if offset < 0: - raise ValueError("negative offset") - elif offset > bytesize: - raise ValueError("offset too large") - result = self._recv_bytes() - size = result.tell() - if bytesize < offset + size: - raise BufferTooShort(result.getvalue()) - # Message can fit in dest - result.seek(0) - result.readinto(m[offset // itemsize : - (offset + size) // itemsize]) - return size - - def recv(self): - """Receive a (picklable) object""" - self._check_closed() - self._check_readable() - buf = self._recv_bytes() - return _ForkingPickler.loads(buf.getbuffer()) - - def poll(self, timeout=0.0): - """Whether there is any input available to be read""" - self._check_closed() - self._check_readable() - return self._poll(timeout) - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, exc_tb): - self.close() - - -if _winapi: - - class PipeConnection(_ConnectionBase): - """ - Connection class based on a Windows named pipe. - Overlapped I/O is used, so the handles must have been created - with FILE_FLAG_OVERLAPPED. - """ - _got_empty_message = False - - def _close(self, _CloseHandle=_winapi.CloseHandle): - _CloseHandle(self._handle) - - def _send_bytes(self, buf): - ov, err = _winapi.WriteFile(self._handle, buf, overlapped=True) - try: - if err == _winapi.ERROR_IO_PENDING: - waitres = _winapi.WaitForMultipleObjects( - [ov.event], False, INFINITE) - assert waitres == WAIT_OBJECT_0 - except: - ov.cancel() - raise - finally: - nwritten, err = ov.GetOverlappedResult(True) - assert err == 0 - assert nwritten == len(buf) - - def _recv_bytes(self, maxsize=None): - if self._got_empty_message: - self._got_empty_message = False - return io.BytesIO() - else: - bsize = 128 if maxsize is None else min(maxsize, 128) - try: - ov, err = _winapi.ReadFile(self._handle, bsize, - overlapped=True) - try: - if err == _winapi.ERROR_IO_PENDING: - waitres = _winapi.WaitForMultipleObjects( - [ov.event], False, INFINITE) - assert waitres == WAIT_OBJECT_0 - except: - ov.cancel() - raise - finally: - nread, err = ov.GetOverlappedResult(True) - if err == 0: - f = io.BytesIO() - f.write(ov.getbuffer()) - return f - elif err == _winapi.ERROR_MORE_DATA: - return self._get_more_data(ov, maxsize) - except OSError as e: - if e.winerror == _winapi.ERROR_BROKEN_PIPE: - raise EOFError - else: - raise - raise RuntimeError("shouldn't get here; expected KeyboardInterrupt") - - def _poll(self, timeout): - if (self._got_empty_message or - _winapi.PeekNamedPipe(self._handle)[0] != 0): - return True - return bool(wait([self], timeout)) - - def _get_more_data(self, ov, maxsize): - buf = ov.getbuffer() - f = io.BytesIO() - f.write(buf) - left = _winapi.PeekNamedPipe(self._handle)[1] - assert left > 0 - if maxsize is not None and len(buf) + left > maxsize: - self._bad_message_length() - ov, err = _winapi.ReadFile(self._handle, left, overlapped=True) - rbytes, err = ov.GetOverlappedResult(True) - assert err == 0 - assert rbytes == left - f.write(ov.getbuffer()) - return f - - -class Connection(_ConnectionBase): - """ - Connection class based on an arbitrary file descriptor (Unix only), or - a socket handle (Windows). - """ - - if _winapi: - def _close(self, _close=_multiprocessing.closesocket): - _close(self._handle) - _write = _multiprocessing.send - _read = _multiprocessing.recv - else: - def _close(self, _close=os.close): - _close(self._handle) - _write = os.write - _read = os.read - - def _send(self, buf, write=_write): - remaining = len(buf) - while True: - n = write(self._handle, buf) - remaining -= n - if remaining == 0: - break - buf = buf[n:] - - def _recv(self, size, read=_read): - buf = io.BytesIO() - handle = self._handle - remaining = size - while remaining > 0: - chunk = read(handle, remaining) - n = len(chunk) - if n == 0: - if remaining == size: - raise EOFError - else: - raise OSError("got end of file during message") - buf.write(chunk) - remaining -= n - return buf - - def _send_bytes(self, buf): - n = len(buf) - if n > 0x7fffffff: - pre_header = struct.pack("!i", -1) - header = struct.pack("!Q", n) - self._send(pre_header) - self._send(header) - self._send(buf) - else: - # For wire compatibility with 3.7 and lower - header = struct.pack("!i", n) - if n > 16384: - # The payload is large so Nagle's algorithm won't be triggered - # and we'd better avoid the cost of concatenation. - self._send(header) - self._send(buf) - else: - # Issue #20540: concatenate before sending, to avoid delays due - # to Nagle's algorithm on a TCP socket. - # Also note we want to avoid sending a 0-length buffer separately, - # to avoid "broken pipe" errors if the other end closed the pipe. - self._send(header + buf) - - def _recv_bytes(self, maxsize=None): - buf = self._recv(4) - size, = struct.unpack("!i", buf.getvalue()) - if size == -1: - buf = self._recv(8) - size, = struct.unpack("!Q", buf.getvalue()) - if maxsize is not None and size > maxsize: - return None - return self._recv(size) - - def _poll(self, timeout): - r = wait([self], timeout) - return bool(r) - - -# -# Public functions -# - -class Listener(object): - ''' - Returns a listener object. - - This is a wrapper for a bound socket which is 'listening' for - connections, or for a Windows named pipe. - ''' - def __init__(self, address=None, family=None, backlog=1, authkey=None): - family = family or (address and address_type(address)) \ - or default_family - address = address or arbitrary_address(family) - - _validate_family(family) - if family == 'AF_PIPE': - self._listener = PipeListener(address, backlog) - else: - self._listener = SocketListener(address, family, backlog) - - if authkey is not None and not isinstance(authkey, bytes): - raise TypeError('authkey should be a byte string') - - self._authkey = authkey - - def accept(self): - ''' - Accept a connection on the bound socket or named pipe of `self`. - - Returns a `Connection` object. - ''' - if self._listener is None: - raise OSError('listener is closed') - c = self._listener.accept() - if self._authkey: - deliver_challenge(c, self._authkey) - answer_challenge(c, self._authkey) - return c - - def close(self): - ''' - Close the bound socket or named pipe of `self`. - ''' - listener = self._listener - if listener is not None: - self._listener = None - listener.close() - - @property - def address(self): - return self._listener._address - - @property - def last_accepted(self): - return self._listener._last_accepted - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, exc_tb): - self.close() - - -def Client(address, family=None, authkey=None): - ''' - Returns a connection to the address of a `Listener` - ''' - family = family or address_type(address) - _validate_family(family) - if family == 'AF_PIPE': - c = PipeClient(address) - else: - c = SocketClient(address) - - if authkey is not None and not isinstance(authkey, bytes): - raise TypeError('authkey should be a byte string') - - if authkey is not None: - answer_challenge(c, authkey) - deliver_challenge(c, authkey) - - return c - - -if sys.platform != 'win32': - - def Pipe(duplex=True): - ''' - Returns pair of connection objects at either end of a pipe - ''' - if duplex: - s1, s2 = socket.socketpair() - s1.setblocking(True) - s2.setblocking(True) - c1 = Connection(s1.detach()) - c2 = Connection(s2.detach()) - else: - fd1, fd2 = os.pipe() - c1 = Connection(fd1, writable=False) - c2 = Connection(fd2, readable=False) - - return c1, c2 - -else: - - def Pipe(duplex=True): - ''' - Returns pair of connection objects at either end of a pipe - ''' - address = arbitrary_address('AF_PIPE') - if duplex: - openmode = _winapi.PIPE_ACCESS_DUPLEX - access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE - obsize, ibsize = BUFSIZE, BUFSIZE - else: - openmode = _winapi.PIPE_ACCESS_INBOUND - access = _winapi.GENERIC_WRITE - obsize, ibsize = 0, BUFSIZE - - h1 = _winapi.CreateNamedPipe( - address, openmode | _winapi.FILE_FLAG_OVERLAPPED | - _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE, - _winapi.PIPE_TYPE_MESSAGE | _winapi.PIPE_READMODE_MESSAGE | - _winapi.PIPE_WAIT, - 1, obsize, ibsize, _winapi.NMPWAIT_WAIT_FOREVER, - # default security descriptor: the handle cannot be inherited - _winapi.NULL - ) - h2 = _winapi.CreateFile( - address, access, 0, _winapi.NULL, _winapi.OPEN_EXISTING, - _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL - ) - _winapi.SetNamedPipeHandleState( - h2, _winapi.PIPE_READMODE_MESSAGE, None, None - ) - - overlapped = _winapi.ConnectNamedPipe(h1, overlapped=True) - _, err = overlapped.GetOverlappedResult(True) - assert err == 0 - - c1 = PipeConnection(h1, writable=duplex) - c2 = PipeConnection(h2, readable=duplex) - - return c1, c2 - -# -# Definitions for connections based on sockets -# - -class SocketListener(object): - ''' - Representation of a socket which is bound to an address and listening - ''' - def __init__(self, address, family, backlog=1): - self._socket = socket.socket(getattr(socket, family)) - try: - # SO_REUSEADDR has different semantics on Windows (issue #2550). - if os.name == 'posix': - self._socket.setsockopt(socket.SOL_SOCKET, - socket.SO_REUSEADDR, 1) - self._socket.setblocking(True) - self._socket.bind(address) - self._socket.listen(backlog) - self._address = self._socket.getsockname() - except OSError: - self._socket.close() - raise - self._family = family - self._last_accepted = None - - if family == 'AF_UNIX' and not util.is_abstract_socket_namespace(address): - # Linux abstract socket namespaces do not need to be explicitly unlinked - self._unlink = util.Finalize( - self, os.unlink, args=(address,), exitpriority=0 - ) - else: - self._unlink = None - - def accept(self): - s, self._last_accepted = self._socket.accept() - s.setblocking(True) - return Connection(s.detach()) - - def close(self): - try: - self._socket.close() - finally: - unlink = self._unlink - if unlink is not None: - self._unlink = None - unlink() - - -def SocketClient(address): - ''' - Return a connection object connected to the socket given by `address` - ''' - family = address_type(address) - with socket.socket( getattr(socket, family) ) as s: - s.setblocking(True) - s.connect(address) - return Connection(s.detach()) - -# -# Definitions for connections based on named pipes -# - -if sys.platform == 'win32': - - class PipeListener(object): - ''' - Representation of a named pipe - ''' - def __init__(self, address, backlog=None): - self._address = address - self._handle_queue = [self._new_handle(first=True)] - - self._last_accepted = None - util.sub_debug('listener created with address=%r', self._address) - self.close = util.Finalize( - self, PipeListener._finalize_pipe_listener, - args=(self._handle_queue, self._address), exitpriority=0 - ) - - def _new_handle(self, first=False): - flags = _winapi.PIPE_ACCESS_DUPLEX | _winapi.FILE_FLAG_OVERLAPPED - if first: - flags |= _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE - return _winapi.CreateNamedPipe( - self._address, flags, - _winapi.PIPE_TYPE_MESSAGE | _winapi.PIPE_READMODE_MESSAGE | - _winapi.PIPE_WAIT, - _winapi.PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE, - _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL - ) - - def accept(self): - self._handle_queue.append(self._new_handle()) - handle = self._handle_queue.pop(0) - try: - ov = _winapi.ConnectNamedPipe(handle, overlapped=True) - except OSError as e: - if e.winerror != _winapi.ERROR_NO_DATA: - raise - # ERROR_NO_DATA can occur if a client has already connected, - # written data and then disconnected -- see Issue 14725. - else: - try: - res = _winapi.WaitForMultipleObjects( - [ov.event], False, INFINITE) - except: - ov.cancel() - _winapi.CloseHandle(handle) - raise - finally: - _, err = ov.GetOverlappedResult(True) - assert err == 0 - return PipeConnection(handle) - - @staticmethod - def _finalize_pipe_listener(queue, address): - util.sub_debug('closing listener with address=%r', address) - for handle in queue: - _winapi.CloseHandle(handle) - - def PipeClient(address): - ''' - Return a connection object connected to the pipe given by `address` - ''' - t = _init_timeout() - while 1: - try: - _winapi.WaitNamedPipe(address, 1000) - h = _winapi.CreateFile( - address, _winapi.GENERIC_READ | _winapi.GENERIC_WRITE, - 0, _winapi.NULL, _winapi.OPEN_EXISTING, - _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL - ) - except OSError as e: - if e.winerror not in (_winapi.ERROR_SEM_TIMEOUT, - _winapi.ERROR_PIPE_BUSY) or _check_timeout(t): - raise - else: - break - else: - raise - - _winapi.SetNamedPipeHandleState( - h, _winapi.PIPE_READMODE_MESSAGE, None, None - ) - return PipeConnection(h) - -# -# Authentication stuff -# - -MESSAGE_LENGTH = 20 - -CHALLENGE = b'#CHALLENGE#' -WELCOME = b'#WELCOME#' -FAILURE = b'#FAILURE#' - -def deliver_challenge(connection, authkey): - import hmac - if not isinstance(authkey, bytes): - raise ValueError( - "Authkey must be bytes, not {0!s}".format(type(authkey))) - message = os.urandom(MESSAGE_LENGTH) - connection.send_bytes(CHALLENGE + message) - digest = hmac.new(authkey, message, 'md5').digest() - response = connection.recv_bytes(256) # reject large message - if response == digest: - connection.send_bytes(WELCOME) - else: - connection.send_bytes(FAILURE) - raise AuthenticationError('digest received was wrong') - -def answer_challenge(connection, authkey): - import hmac - if not isinstance(authkey, bytes): - raise ValueError( - "Authkey must be bytes, not {0!s}".format(type(authkey))) - message = connection.recv_bytes(256) # reject large message - assert message[:len(CHALLENGE)] == CHALLENGE, 'message = %r' % message - message = message[len(CHALLENGE):] - digest = hmac.new(authkey, message, 'md5').digest() - connection.send_bytes(digest) - response = connection.recv_bytes(256) # reject large message - if response != WELCOME: - raise AuthenticationError('digest sent was rejected') - -# -# Support for using xmlrpclib for serialization -# - -class ConnectionWrapper(object): - def __init__(self, conn, dumps, loads): - self._conn = conn - self._dumps = dumps - self._loads = loads - for attr in ('fileno', 'close', 'poll', 'recv_bytes', 'send_bytes'): - obj = getattr(conn, attr) - setattr(self, attr, obj) - def send(self, obj): - s = self._dumps(obj) - self._conn.send_bytes(s) - def recv(self): - s = self._conn.recv_bytes() - return self._loads(s) - -def _xml_dumps(obj): - return xmlrpclib.dumps((obj,), None, None, None, 1).encode('utf-8') - -def _xml_loads(s): - (obj,), method = xmlrpclib.loads(s.decode('utf-8')) - return obj - -class XmlListener(Listener): - def accept(self): - global xmlrpclib - import xmlrpc.client as xmlrpclib - obj = Listener.accept(self) - return ConnectionWrapper(obj, _xml_dumps, _xml_loads) - -def XmlClient(*args, **kwds): - global xmlrpclib - import xmlrpc.client as xmlrpclib - return ConnectionWrapper(Client(*args, **kwds), _xml_dumps, _xml_loads) - -# -# Wait -# - -if sys.platform == 'win32': - - def _exhaustive_wait(handles, timeout): - # Return ALL handles which are currently signalled. (Only - # returning the first signalled might create starvation issues.) - L = list(handles) - ready = [] - while L: - res = _winapi.WaitForMultipleObjects(L, False, timeout) - if res == WAIT_TIMEOUT: - break - elif WAIT_OBJECT_0 <= res < WAIT_OBJECT_0 + len(L): - res -= WAIT_OBJECT_0 - elif WAIT_ABANDONED_0 <= res < WAIT_ABANDONED_0 + len(L): - res -= WAIT_ABANDONED_0 - else: - raise RuntimeError('Should not get here') - ready.append(L[res]) - L = L[res+1:] - timeout = 0 - return ready - - _ready_errors = {_winapi.ERROR_BROKEN_PIPE, _winapi.ERROR_NETNAME_DELETED} - - def wait(object_list, timeout=None): - ''' - Wait till an object in object_list is ready/readable. - - Returns list of those objects in object_list which are ready/readable. - ''' - if timeout is None: - timeout = INFINITE - elif timeout < 0: - timeout = 0 - else: - timeout = int(timeout * 1000 + 0.5) - - object_list = list(object_list) - waithandle_to_obj = {} - ov_list = [] - ready_objects = set() - ready_handles = set() - - try: - for o in object_list: - try: - fileno = getattr(o, 'fileno') - except AttributeError: - waithandle_to_obj[o.__index__()] = o - else: - # start an overlapped read of length zero - try: - ov, err = _winapi.ReadFile(fileno(), 0, True) - except OSError as e: - ov, err = None, e.winerror - if err not in _ready_errors: - raise - if err == _winapi.ERROR_IO_PENDING: - ov_list.append(ov) - waithandle_to_obj[ov.event] = o - else: - # If o.fileno() is an overlapped pipe handle and - # err == 0 then there is a zero length message - # in the pipe, but it HAS NOT been consumed... - if ov and sys.getwindowsversion()[:2] >= (6, 2): - # ... except on Windows 8 and later, where - # the message HAS been consumed. - try: - _, err = ov.GetOverlappedResult(False) - except OSError as e: - err = e.winerror - if not err and hasattr(o, '_got_empty_message'): - o._got_empty_message = True - ready_objects.add(o) - timeout = 0 - - ready_handles = _exhaustive_wait(waithandle_to_obj.keys(), timeout) - finally: - # request that overlapped reads stop - for ov in ov_list: - ov.cancel() - - # wait for all overlapped reads to stop - for ov in ov_list: - try: - _, err = ov.GetOverlappedResult(True) - except OSError as e: - err = e.winerror - if err not in _ready_errors: - raise - if err != _winapi.ERROR_OPERATION_ABORTED: - o = waithandle_to_obj[ov.event] - ready_objects.add(o) - if err == 0: - # If o.fileno() is an overlapped pipe handle then - # a zero length message HAS been consumed. - if hasattr(o, '_got_empty_message'): - o._got_empty_message = True - - ready_objects.update(waithandle_to_obj[h] for h in ready_handles) - return [o for o in object_list if o in ready_objects] - -else: - - import selectors - - # poll/select have the advantage of not requiring any extra file - # descriptor, contrarily to epoll/kqueue (also, they require a single - # syscall). - if hasattr(selectors, 'PollSelector'): - _WaitSelector = selectors.PollSelector - else: - _WaitSelector = selectors.SelectSelector - - def wait(object_list, timeout=None): - ''' - Wait till an object in object_list is ready/readable. - - Returns list of those objects in object_list which are ready/readable. - ''' - with _WaitSelector() as selector: - for obj in object_list: - selector.register(obj, selectors.EVENT_READ) - - if timeout is not None: - deadline = time.monotonic() + timeout - - while True: - ready = selector.select(timeout) - if ready: - return [key.fileobj for (key, events) in ready] - else: - if timeout is not None: - timeout = deadline - time.monotonic() - if timeout < 0: - return ready - -# -# Make connection and socket objects shareable if possible -# - -if sys.platform == 'win32': - def reduce_connection(conn): - handle = conn.fileno() - with socket.fromfd(handle, socket.AF_INET, socket.SOCK_STREAM) as s: - from . import resource_sharer - ds = resource_sharer.DupSocket(s) - return rebuild_connection, (ds, conn.readable, conn.writable) - def rebuild_connection(ds, readable, writable): - sock = ds.detach() - return Connection(sock.detach(), readable, writable) - reduction.register(Connection, reduce_connection) - - def reduce_pipe_connection(conn): - access = ((_winapi.FILE_GENERIC_READ if conn.readable else 0) | - (_winapi.FILE_GENERIC_WRITE if conn.writable else 0)) - dh = reduction.DupHandle(conn.fileno(), access) - return rebuild_pipe_connection, (dh, conn.readable, conn.writable) - def rebuild_pipe_connection(dh, readable, writable): - handle = dh.detach() - return PipeConnection(handle, readable, writable) - reduction.register(PipeConnection, reduce_pipe_connection) - -else: - def reduce_connection(conn): - df = reduction.DupFd(conn.fileno()) - return rebuild_connection, (df, conn.readable, conn.writable) - def rebuild_connection(df, readable, writable): - fd = df.detach() - return Connection(fd, readable, writable) - reduction.register(Connection, reduce_connection) diff --git a/python/Lib/multiprocessing/context.py b/python/Lib/multiprocessing/context.py deleted file mode 100644 index 5052a65..0000000 --- a/python/Lib/multiprocessing/context.py +++ /dev/null @@ -1,376 +0,0 @@ -import os -import sys -import threading - -from . import process -from . import reduction - -__all__ = () - -# -# Exceptions -# - -class ProcessError(Exception): - pass - -class BufferTooShort(ProcessError): - pass - -class TimeoutError(ProcessError): - pass - -class AuthenticationError(ProcessError): - pass - -# -# Base type for contexts. Bound methods of an instance of this type are included in __all__ of __init__.py -# - -class BaseContext(object): - - ProcessError = ProcessError - BufferTooShort = BufferTooShort - TimeoutError = TimeoutError - AuthenticationError = AuthenticationError - - current_process = staticmethod(process.current_process) - parent_process = staticmethod(process.parent_process) - active_children = staticmethod(process.active_children) - - def cpu_count(self): - '''Returns the number of CPUs in the system''' - num = os.cpu_count() - if num is None: - raise NotImplementedError('cannot determine number of cpus') - else: - return num - - def Manager(self): - '''Returns a manager associated with a running server process - - The managers methods such as `Lock()`, `Condition()` and `Queue()` - can be used to create shared objects. - ''' - from .managers import SyncManager - m = SyncManager(ctx=self.get_context()) - m.start() - return m - - def Pipe(self, duplex=True): - '''Returns two connection object connected by a pipe''' - from .connection import Pipe - return Pipe(duplex) - - def Lock(self): - '''Returns a non-recursive lock object''' - from .synchronize import Lock - return Lock(ctx=self.get_context()) - - def RLock(self): - '''Returns a recursive lock object''' - from .synchronize import RLock - return RLock(ctx=self.get_context()) - - def Condition(self, lock=None): - '''Returns a condition object''' - from .synchronize import Condition - return Condition(lock, ctx=self.get_context()) - - def Semaphore(self, value=1): - '''Returns a semaphore object''' - from .synchronize import Semaphore - return Semaphore(value, ctx=self.get_context()) - - def BoundedSemaphore(self, value=1): - '''Returns a bounded semaphore object''' - from .synchronize import BoundedSemaphore - return BoundedSemaphore(value, ctx=self.get_context()) - - def Event(self): - '''Returns an event object''' - from .synchronize import Event - return Event(ctx=self.get_context()) - - def Barrier(self, parties, action=None, timeout=None): - '''Returns a barrier object''' - from .synchronize import Barrier - return Barrier(parties, action, timeout, ctx=self.get_context()) - - def Queue(self, maxsize=0): - '''Returns a queue object''' - from .queues import Queue - return Queue(maxsize, ctx=self.get_context()) - - def JoinableQueue(self, maxsize=0): - '''Returns a queue object''' - from .queues import JoinableQueue - return JoinableQueue(maxsize, ctx=self.get_context()) - - def SimpleQueue(self): - '''Returns a queue object''' - from .queues import SimpleQueue - return SimpleQueue(ctx=self.get_context()) - - def Pool(self, processes=None, initializer=None, initargs=(), - maxtasksperchild=None): - '''Returns a process pool object''' - from .pool import Pool - return Pool(processes, initializer, initargs, maxtasksperchild, - context=self.get_context()) - - def RawValue(self, typecode_or_type, *args): - '''Returns a shared object''' - from .sharedctypes import RawValue - return RawValue(typecode_or_type, *args) - - def RawArray(self, typecode_or_type, size_or_initializer): - '''Returns a shared array''' - from .sharedctypes import RawArray - return RawArray(typecode_or_type, size_or_initializer) - - def Value(self, typecode_or_type, *args, lock=True): - '''Returns a synchronized shared object''' - from .sharedctypes import Value - return Value(typecode_or_type, *args, lock=lock, - ctx=self.get_context()) - - def Array(self, typecode_or_type, size_or_initializer, *, lock=True): - '''Returns a synchronized shared array''' - from .sharedctypes import Array - return Array(typecode_or_type, size_or_initializer, lock=lock, - ctx=self.get_context()) - - def freeze_support(self): - '''Check whether this is a fake forked process in a frozen executable. - If so then run code specified by commandline and exit. - ''' - if sys.platform == 'win32' and getattr(sys, 'frozen', False): - from .spawn import freeze_support - freeze_support() - - def get_logger(self): - '''Return package logger -- if it does not already exist then - it is created. - ''' - from .util import get_logger - return get_logger() - - def log_to_stderr(self, level=None): - '''Turn on logging and add a handler which prints to stderr''' - from .util import log_to_stderr - return log_to_stderr(level) - - def allow_connection_pickling(self): - '''Install support for sending connections and sockets - between processes - ''' - # This is undocumented. In previous versions of multiprocessing - # its only effect was to make socket objects inheritable on Windows. - from . import connection - - def set_executable(self, executable): - '''Sets the path to a python.exe or pythonw.exe binary used to run - child processes instead of sys.executable when using the 'spawn' - start method. Useful for people embedding Python. - ''' - from .spawn import set_executable - set_executable(executable) - - def set_forkserver_preload(self, module_names): - '''Set list of module names to try to load in forkserver process. - This is really just a hint. - ''' - from .forkserver import set_forkserver_preload - set_forkserver_preload(module_names) - - def get_context(self, method=None): - if method is None: - return self - try: - ctx = _concrete_contexts[method] - except KeyError: - raise ValueError('cannot find context for %r' % method) from None - ctx._check_available() - return ctx - - def get_start_method(self, allow_none=False): - return self._name - - def set_start_method(self, method, force=False): - raise ValueError('cannot set start method of concrete context') - - @property - def reducer(self): - '''Controls how objects will be reduced to a form that can be - shared with other processes.''' - return globals().get('reduction') - - @reducer.setter - def reducer(self, reduction): - globals()['reduction'] = reduction - - def _check_available(self): - pass - -# -# Type of default context -- underlying context can be set at most once -# - -class Process(process.BaseProcess): - _start_method = None - @staticmethod - def _Popen(process_obj): - return _default_context.get_context().Process._Popen(process_obj) - - @staticmethod - def _after_fork(): - return _default_context.get_context().Process._after_fork() - -class DefaultContext(BaseContext): - Process = Process - - def __init__(self, context): - self._default_context = context - self._actual_context = None - - def get_context(self, method=None): - if method is None: - if self._actual_context is None: - self._actual_context = self._default_context - return self._actual_context - else: - return super().get_context(method) - - def set_start_method(self, method, force=False): - if self._actual_context is not None and not force: - raise RuntimeError('context has already been set') - if method is None and force: - self._actual_context = None - return - self._actual_context = self.get_context(method) - - def get_start_method(self, allow_none=False): - if self._actual_context is None: - if allow_none: - return None - self._actual_context = self._default_context - return self._actual_context._name - - def get_all_start_methods(self): - if sys.platform == 'win32': - return ['spawn'] - else: - methods = ['spawn', 'fork'] if sys.platform == 'darwin' else ['fork', 'spawn'] - if reduction.HAVE_SEND_HANDLE: - methods.append('forkserver') - return methods - - -# -# Context types for fixed start method -# - -if sys.platform != 'win32': - - class ForkProcess(process.BaseProcess): - _start_method = 'fork' - @staticmethod - def _Popen(process_obj): - from .popen_fork import Popen - return Popen(process_obj) - - class SpawnProcess(process.BaseProcess): - _start_method = 'spawn' - @staticmethod - def _Popen(process_obj): - from .popen_spawn_posix import Popen - return Popen(process_obj) - - @staticmethod - def _after_fork(): - # process is spawned, nothing to do - pass - - class ForkServerProcess(process.BaseProcess): - _start_method = 'forkserver' - @staticmethod - def _Popen(process_obj): - from .popen_forkserver import Popen - return Popen(process_obj) - - class ForkContext(BaseContext): - _name = 'fork' - Process = ForkProcess - - class SpawnContext(BaseContext): - _name = 'spawn' - Process = SpawnProcess - - class ForkServerContext(BaseContext): - _name = 'forkserver' - Process = ForkServerProcess - def _check_available(self): - if not reduction.HAVE_SEND_HANDLE: - raise ValueError('forkserver start method not available') - - _concrete_contexts = { - 'fork': ForkContext(), - 'spawn': SpawnContext(), - 'forkserver': ForkServerContext(), - } - if sys.platform == 'darwin': - # bpo-33725: running arbitrary code after fork() is no longer reliable - # on macOS since macOS 10.14 (Mojave). Use spawn by default instead. - _default_context = DefaultContext(_concrete_contexts['spawn']) - else: - _default_context = DefaultContext(_concrete_contexts['fork']) - -else: - - class SpawnProcess(process.BaseProcess): - _start_method = 'spawn' - @staticmethod - def _Popen(process_obj): - from .popen_spawn_win32 import Popen - return Popen(process_obj) - - @staticmethod - def _after_fork(): - # process is spawned, nothing to do - pass - - class SpawnContext(BaseContext): - _name = 'spawn' - Process = SpawnProcess - - _concrete_contexts = { - 'spawn': SpawnContext(), - } - _default_context = DefaultContext(_concrete_contexts['spawn']) - -# -# Force the start method -# - -def _force_start_method(method): - _default_context._actual_context = _concrete_contexts[method] - -# -# Check that the current thread is spawning a child process -# - -_tls = threading.local() - -def get_spawning_popen(): - return getattr(_tls, 'spawning_popen', None) - -def set_spawning_popen(popen): - _tls.spawning_popen = popen - -def assert_spawning(obj): - if get_spawning_popen() is None: - raise RuntimeError( - '%s objects should only be shared between processes' - ' through inheritance' % type(obj).__name__ - ) diff --git a/python/Lib/multiprocessing/dummy/__init__.py b/python/Lib/multiprocessing/dummy/__init__.py deleted file mode 100644 index 1af9960..0000000 --- a/python/Lib/multiprocessing/dummy/__init__.py +++ /dev/null @@ -1,126 +0,0 @@ -# -# Support for the API of the multiprocessing package using threads -# -# multiprocessing/dummy/__init__.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -__all__ = [ - 'Process', 'current_process', 'active_children', 'freeze_support', - 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', - 'Event', 'Barrier', 'Queue', 'Manager', 'Pipe', 'Pool', 'JoinableQueue' - ] - -# -# Imports -# - -import threading -import sys -import weakref -import array - -from .connection import Pipe -from threading import Lock, RLock, Semaphore, BoundedSemaphore -from threading import Event, Condition, Barrier -from queue import Queue - -# -# -# - -class DummyProcess(threading.Thread): - - def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): - threading.Thread.__init__(self, group, target, name, args, kwargs) - self._pid = None - self._children = weakref.WeakKeyDictionary() - self._start_called = False - self._parent = current_process() - - def start(self): - if self._parent is not current_process(): - raise RuntimeError( - "Parent is {0!r} but current_process is {1!r}".format( - self._parent, current_process())) - self._start_called = True - if hasattr(self._parent, '_children'): - self._parent._children[self] = None - threading.Thread.start(self) - - @property - def exitcode(self): - if self._start_called and not self.is_alive(): - return 0 - else: - return None - -# -# -# - -Process = DummyProcess -current_process = threading.current_thread -current_process()._children = weakref.WeakKeyDictionary() - -def active_children(): - children = current_process()._children - for p in list(children): - if not p.is_alive(): - children.pop(p, None) - return list(children) - -def freeze_support(): - pass - -# -# -# - -class Namespace(object): - def __init__(self, /, **kwds): - self.__dict__.update(kwds) - def __repr__(self): - items = list(self.__dict__.items()) - temp = [] - for name, value in items: - if not name.startswith('_'): - temp.append('%s=%r' % (name, value)) - temp.sort() - return '%s(%s)' % (self.__class__.__name__, ', '.join(temp)) - -dict = dict -list = list - -def Array(typecode, sequence, lock=True): - return array.array(typecode, sequence) - -class Value(object): - def __init__(self, typecode, value, lock=True): - self._typecode = typecode - self._value = value - - @property - def value(self): - return self._value - - @value.setter - def value(self, value): - self._value = value - - def __repr__(self): - return '<%s(%r, %r)>'%(type(self).__name__,self._typecode,self._value) - -def Manager(): - return sys.modules[__name__] - -def shutdown(): - pass - -def Pool(processes=None, initializer=None, initargs=()): - from ..pool import ThreadPool - return ThreadPool(processes, initializer, initargs) - -JoinableQueue = Queue diff --git a/python/Lib/multiprocessing/dummy/connection.py b/python/Lib/multiprocessing/dummy/connection.py deleted file mode 100644 index 05f55a1..0000000 --- a/python/Lib/multiprocessing/dummy/connection.py +++ /dev/null @@ -1,75 +0,0 @@ -# -# Analogue of `multiprocessing.connection` which uses queues instead of sockets -# -# multiprocessing/dummy/connection.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -__all__ = [ 'Client', 'Listener', 'Pipe' ] - -from queue import Queue - - -families = [None] - - -class Listener(object): - - def __init__(self, address=None, family=None, backlog=1): - self._backlog_queue = Queue(backlog) - - def accept(self): - return Connection(*self._backlog_queue.get()) - - def close(self): - self._backlog_queue = None - - @property - def address(self): - return self._backlog_queue - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, exc_tb): - self.close() - - -def Client(address): - _in, _out = Queue(), Queue() - address.put((_out, _in)) - return Connection(_in, _out) - - -def Pipe(duplex=True): - a, b = Queue(), Queue() - return Connection(a, b), Connection(b, a) - - -class Connection(object): - - def __init__(self, _in, _out): - self._out = _out - self._in = _in - self.send = self.send_bytes = _out.put - self.recv = self.recv_bytes = _in.get - - def poll(self, timeout=0.0): - if self._in.qsize() > 0: - return True - if timeout <= 0.0: - return False - with self._in.not_empty: - self._in.not_empty.wait(timeout) - return self._in.qsize() > 0 - - def close(self): - pass - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, exc_tb): - self.close() diff --git a/python/Lib/multiprocessing/forkserver.py b/python/Lib/multiprocessing/forkserver.py deleted file mode 100644 index 7bba725..0000000 --- a/python/Lib/multiprocessing/forkserver.py +++ /dev/null @@ -1,348 +0,0 @@ -import errno -import os -import selectors -import signal -import socket -import struct -import sys -import threading -import warnings - -from . import connection -from . import process -from .context import reduction -from . import resource_tracker -from . import spawn -from . import util - -__all__ = ['ensure_running', 'get_inherited_fds', 'connect_to_new_process', - 'set_forkserver_preload'] - -# -# -# - -MAXFDS_TO_SEND = 256 -SIGNED_STRUCT = struct.Struct('q') # large enough for pid_t - -# -# Forkserver class -# - -class ForkServer(object): - - def __init__(self): - self._forkserver_address = None - self._forkserver_alive_fd = None - self._forkserver_pid = None - self._inherited_fds = None - self._lock = threading.Lock() - self._preload_modules = ['__main__'] - - def _stop(self): - # Method used by unit tests to stop the server - with self._lock: - self._stop_unlocked() - - def _stop_unlocked(self): - if self._forkserver_pid is None: - return - - # close the "alive" file descriptor asks the server to stop - os.close(self._forkserver_alive_fd) - self._forkserver_alive_fd = None - - os.waitpid(self._forkserver_pid, 0) - self._forkserver_pid = None - - if not util.is_abstract_socket_namespace(self._forkserver_address): - os.unlink(self._forkserver_address) - self._forkserver_address = None - - def set_forkserver_preload(self, modules_names): - '''Set list of module names to try to load in forkserver process.''' - if not all(type(mod) is str for mod in self._preload_modules): - raise TypeError('module_names must be a list of strings') - self._preload_modules = modules_names - - def get_inherited_fds(self): - '''Return list of fds inherited from parent process. - - This returns None if the current process was not started by fork - server. - ''' - return self._inherited_fds - - def connect_to_new_process(self, fds): - '''Request forkserver to create a child process. - - Returns a pair of fds (status_r, data_w). The calling process can read - the child process's pid and (eventually) its returncode from status_r. - The calling process should write to data_w the pickled preparation and - process data. - ''' - self.ensure_running() - if len(fds) + 4 >= MAXFDS_TO_SEND: - raise ValueError('too many fds') - with socket.socket(socket.AF_UNIX) as client: - client.connect(self._forkserver_address) - parent_r, child_w = os.pipe() - child_r, parent_w = os.pipe() - allfds = [child_r, child_w, self._forkserver_alive_fd, - resource_tracker.getfd()] - allfds += fds - try: - reduction.sendfds(client, allfds) - return parent_r, parent_w - except: - os.close(parent_r) - os.close(parent_w) - raise - finally: - os.close(child_r) - os.close(child_w) - - def ensure_running(self): - '''Make sure that a fork server is running. - - This can be called from any process. Note that usually a child - process will just reuse the forkserver started by its parent, so - ensure_running() will do nothing. - ''' - with self._lock: - resource_tracker.ensure_running() - if self._forkserver_pid is not None: - # forkserver was launched before, is it still running? - pid, status = os.waitpid(self._forkserver_pid, os.WNOHANG) - if not pid: - # still alive - return - # dead, launch it again - os.close(self._forkserver_alive_fd) - self._forkserver_address = None - self._forkserver_alive_fd = None - self._forkserver_pid = None - - cmd = ('from multiprocessing.forkserver import main; ' + - 'main(%d, %d, %r, **%r)') - - if self._preload_modules: - desired_keys = {'main_path', 'sys_path'} - data = spawn.get_preparation_data('ignore') - data = {x: y for x, y in data.items() if x in desired_keys} - else: - data = {} - - with socket.socket(socket.AF_UNIX) as listener: - address = connection.arbitrary_address('AF_UNIX') - listener.bind(address) - if not util.is_abstract_socket_namespace(address): - os.chmod(address, 0o600) - listener.listen() - - # all client processes own the write end of the "alive" pipe; - # when they all terminate the read end becomes ready. - alive_r, alive_w = os.pipe() - try: - fds_to_pass = [listener.fileno(), alive_r] - cmd %= (listener.fileno(), alive_r, self._preload_modules, - data) - exe = spawn.get_executable() - args = [exe] + util._args_from_interpreter_flags() - args += ['-c', cmd] - pid = util.spawnv_passfds(exe, args, fds_to_pass) - except: - os.close(alive_w) - raise - finally: - os.close(alive_r) - self._forkserver_address = address - self._forkserver_alive_fd = alive_w - self._forkserver_pid = pid - -# -# -# - -def main(listener_fd, alive_r, preload, main_path=None, sys_path=None): - '''Run forkserver.''' - if preload: - if '__main__' in preload and main_path is not None: - process.current_process()._inheriting = True - try: - spawn.import_main_path(main_path) - finally: - del process.current_process()._inheriting - for modname in preload: - try: - __import__(modname) - except ImportError: - pass - - util._close_stdin() - - sig_r, sig_w = os.pipe() - os.set_blocking(sig_r, False) - os.set_blocking(sig_w, False) - - def sigchld_handler(*_unused): - # Dummy signal handler, doesn't do anything - pass - - handlers = { - # unblocking SIGCHLD allows the wakeup fd to notify our event loop - signal.SIGCHLD: sigchld_handler, - # protect the process from ^C - signal.SIGINT: signal.SIG_IGN, - } - old_handlers = {sig: signal.signal(sig, val) - for (sig, val) in handlers.items()} - - # calling os.write() in the Python signal handler is racy - signal.set_wakeup_fd(sig_w) - - # map child pids to client fds - pid_to_fd = {} - - with socket.socket(socket.AF_UNIX, fileno=listener_fd) as listener, \ - selectors.DefaultSelector() as selector: - _forkserver._forkserver_address = listener.getsockname() - - selector.register(listener, selectors.EVENT_READ) - selector.register(alive_r, selectors.EVENT_READ) - selector.register(sig_r, selectors.EVENT_READ) - - while True: - try: - while True: - rfds = [key.fileobj for (key, events) in selector.select()] - if rfds: - break - - if alive_r in rfds: - # EOF because no more client processes left - assert os.read(alive_r, 1) == b'', "Not at EOF?" - raise SystemExit - - if sig_r in rfds: - # Got SIGCHLD - os.read(sig_r, 65536) # exhaust - while True: - # Scan for child processes - try: - pid, sts = os.waitpid(-1, os.WNOHANG) - except ChildProcessError: - break - if pid == 0: - break - child_w = pid_to_fd.pop(pid, None) - if child_w is not None: - returncode = os.waitstatus_to_exitcode(sts) - - # Send exit code to client process - try: - write_signed(child_w, returncode) - except BrokenPipeError: - # client vanished - pass - os.close(child_w) - else: - # This shouldn't happen really - warnings.warn('forkserver: waitpid returned ' - 'unexpected pid %d' % pid) - - if listener in rfds: - # Incoming fork request - with listener.accept()[0] as s: - # Receive fds from client - fds = reduction.recvfds(s, MAXFDS_TO_SEND + 1) - if len(fds) > MAXFDS_TO_SEND: - raise RuntimeError( - "Too many ({0:n}) fds to send".format( - len(fds))) - child_r, child_w, *fds = fds - s.close() - pid = os.fork() - if pid == 0: - # Child - code = 1 - try: - listener.close() - selector.close() - unused_fds = [alive_r, child_w, sig_r, sig_w] - unused_fds.extend(pid_to_fd.values()) - code = _serve_one(child_r, fds, - unused_fds, - old_handlers) - except Exception: - sys.excepthook(*sys.exc_info()) - sys.stderr.flush() - finally: - os._exit(code) - else: - # Send pid to client process - try: - write_signed(child_w, pid) - except BrokenPipeError: - # client vanished - pass - pid_to_fd[pid] = child_w - os.close(child_r) - for fd in fds: - os.close(fd) - - except OSError as e: - if e.errno != errno.ECONNABORTED: - raise - - -def _serve_one(child_r, fds, unused_fds, handlers): - # close unnecessary stuff and reset signal handlers - signal.set_wakeup_fd(-1) - for sig, val in handlers.items(): - signal.signal(sig, val) - for fd in unused_fds: - os.close(fd) - - (_forkserver._forkserver_alive_fd, - resource_tracker._resource_tracker._fd, - *_forkserver._inherited_fds) = fds - - # Run process object received over pipe - parent_sentinel = os.dup(child_r) - code = spawn._main(child_r, parent_sentinel) - - return code - - -# -# Read and write signed numbers -# - -def read_signed(fd): - data = b'' - length = SIGNED_STRUCT.size - while len(data) < length: - s = os.read(fd, length - len(data)) - if not s: - raise EOFError('unexpected EOF') - data += s - return SIGNED_STRUCT.unpack(data)[0] - -def write_signed(fd, n): - msg = SIGNED_STRUCT.pack(n) - while msg: - nbytes = os.write(fd, msg) - if nbytes == 0: - raise RuntimeError('should not get here') - msg = msg[nbytes:] - -# -# -# - -_forkserver = ForkServer() -ensure_running = _forkserver.ensure_running -get_inherited_fds = _forkserver.get_inherited_fds -connect_to_new_process = _forkserver.connect_to_new_process -set_forkserver_preload = _forkserver.set_forkserver_preload diff --git a/python/Lib/multiprocessing/heap.py b/python/Lib/multiprocessing/heap.py deleted file mode 100644 index 629d03a..0000000 --- a/python/Lib/multiprocessing/heap.py +++ /dev/null @@ -1,337 +0,0 @@ -# -# Module which supports allocation of memory from an mmap -# -# multiprocessing/heap.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -import bisect -from collections import defaultdict -import mmap -import os -import sys -import tempfile -import threading - -from .context import reduction, assert_spawning -from . import util - -__all__ = ['BufferWrapper'] - -# -# Inheritable class which wraps an mmap, and from which blocks can be allocated -# - -if sys.platform == 'win32': - - import _winapi - - class Arena(object): - """ - A shared memory area backed by anonymous memory (Windows). - """ - - _rand = tempfile._RandomNameSequence() - - def __init__(self, size): - self.size = size - for i in range(100): - name = 'pym-%d-%s' % (os.getpid(), next(self._rand)) - buf = mmap.mmap(-1, size, tagname=name) - if _winapi.GetLastError() == 0: - break - # We have reopened a preexisting mmap. - buf.close() - else: - raise FileExistsError('Cannot find name for new mmap') - self.name = name - self.buffer = buf - self._state = (self.size, self.name) - - def __getstate__(self): - assert_spawning(self) - return self._state - - def __setstate__(self, state): - self.size, self.name = self._state = state - # Reopen existing mmap - self.buffer = mmap.mmap(-1, self.size, tagname=self.name) - # XXX Temporarily preventing buildbot failures while determining - # XXX the correct long-term fix. See issue 23060 - #assert _winapi.GetLastError() == _winapi.ERROR_ALREADY_EXISTS - -else: - - class Arena(object): - """ - A shared memory area backed by a temporary file (POSIX). - """ - - if sys.platform == 'linux': - _dir_candidates = ['/dev/shm'] - else: - _dir_candidates = [] - - def __init__(self, size, fd=-1): - self.size = size - self.fd = fd - if fd == -1: - # Arena is created anew (if fd != -1, it means we're coming - # from rebuild_arena() below) - self.fd, name = tempfile.mkstemp( - prefix='pym-%d-'%os.getpid(), - dir=self._choose_dir(size)) - os.unlink(name) - util.Finalize(self, os.close, (self.fd,)) - os.ftruncate(self.fd, size) - self.buffer = mmap.mmap(self.fd, self.size) - - def _choose_dir(self, size): - # Choose a non-storage backed directory if possible, - # to improve performance - for d in self._dir_candidates: - st = os.statvfs(d) - if st.f_bavail * st.f_frsize >= size: # enough free space? - return d - return util.get_temp_dir() - - def reduce_arena(a): - if a.fd == -1: - raise ValueError('Arena is unpicklable because ' - 'forking was enabled when it was created') - return rebuild_arena, (a.size, reduction.DupFd(a.fd)) - - def rebuild_arena(size, dupfd): - return Arena(size, dupfd.detach()) - - reduction.register(Arena, reduce_arena) - -# -# Class allowing allocation of chunks of memory from arenas -# - -class Heap(object): - - # Minimum malloc() alignment - _alignment = 8 - - _DISCARD_FREE_SPACE_LARGER_THAN = 4 * 1024 ** 2 # 4 MB - _DOUBLE_ARENA_SIZE_UNTIL = 4 * 1024 ** 2 - - def __init__(self, size=mmap.PAGESIZE): - self._lastpid = os.getpid() - self._lock = threading.Lock() - # Current arena allocation size - self._size = size - # A sorted list of available block sizes in arenas - self._lengths = [] - - # Free block management: - # - map each block size to a list of `(Arena, start, stop)` blocks - self._len_to_seq = {} - # - map `(Arena, start)` tuple to the `(Arena, start, stop)` block - # starting at that offset - self._start_to_block = {} - # - map `(Arena, stop)` tuple to the `(Arena, start, stop)` block - # ending at that offset - self._stop_to_block = {} - - # Map arenas to their `(Arena, start, stop)` blocks in use - self._allocated_blocks = defaultdict(set) - self._arenas = [] - - # List of pending blocks to free - see comment in free() below - self._pending_free_blocks = [] - - # Statistics - self._n_mallocs = 0 - self._n_frees = 0 - - @staticmethod - def _roundup(n, alignment): - # alignment must be a power of 2 - mask = alignment - 1 - return (n + mask) & ~mask - - def _new_arena(self, size): - # Create a new arena with at least the given *size* - length = self._roundup(max(self._size, size), mmap.PAGESIZE) - # We carve larger and larger arenas, for efficiency, until we - # reach a large-ish size (roughly L3 cache-sized) - if self._size < self._DOUBLE_ARENA_SIZE_UNTIL: - self._size *= 2 - util.info('allocating a new mmap of length %d', length) - arena = Arena(length) - self._arenas.append(arena) - return (arena, 0, length) - - def _discard_arena(self, arena): - # Possibly delete the given (unused) arena - length = arena.size - # Reusing an existing arena is faster than creating a new one, so - # we only reclaim space if it's large enough. - if length < self._DISCARD_FREE_SPACE_LARGER_THAN: - return - blocks = self._allocated_blocks.pop(arena) - assert not blocks - del self._start_to_block[(arena, 0)] - del self._stop_to_block[(arena, length)] - self._arenas.remove(arena) - seq = self._len_to_seq[length] - seq.remove((arena, 0, length)) - if not seq: - del self._len_to_seq[length] - self._lengths.remove(length) - - def _malloc(self, size): - # returns a large enough block -- it might be much larger - i = bisect.bisect_left(self._lengths, size) - if i == len(self._lengths): - return self._new_arena(size) - else: - length = self._lengths[i] - seq = self._len_to_seq[length] - block = seq.pop() - if not seq: - del self._len_to_seq[length], self._lengths[i] - - (arena, start, stop) = block - del self._start_to_block[(arena, start)] - del self._stop_to_block[(arena, stop)] - return block - - def _add_free_block(self, block): - # make block available and try to merge with its neighbours in the arena - (arena, start, stop) = block - - try: - prev_block = self._stop_to_block[(arena, start)] - except KeyError: - pass - else: - start, _ = self._absorb(prev_block) - - try: - next_block = self._start_to_block[(arena, stop)] - except KeyError: - pass - else: - _, stop = self._absorb(next_block) - - block = (arena, start, stop) - length = stop - start - - try: - self._len_to_seq[length].append(block) - except KeyError: - self._len_to_seq[length] = [block] - bisect.insort(self._lengths, length) - - self._start_to_block[(arena, start)] = block - self._stop_to_block[(arena, stop)] = block - - def _absorb(self, block): - # deregister this block so it can be merged with a neighbour - (arena, start, stop) = block - del self._start_to_block[(arena, start)] - del self._stop_to_block[(arena, stop)] - - length = stop - start - seq = self._len_to_seq[length] - seq.remove(block) - if not seq: - del self._len_to_seq[length] - self._lengths.remove(length) - - return start, stop - - def _remove_allocated_block(self, block): - arena, start, stop = block - blocks = self._allocated_blocks[arena] - blocks.remove((start, stop)) - if not blocks: - # Arena is entirely free, discard it from this process - self._discard_arena(arena) - - def _free_pending_blocks(self): - # Free all the blocks in the pending list - called with the lock held. - while True: - try: - block = self._pending_free_blocks.pop() - except IndexError: - break - self._add_free_block(block) - self._remove_allocated_block(block) - - def free(self, block): - # free a block returned by malloc() - # Since free() can be called asynchronously by the GC, it could happen - # that it's called while self._lock is held: in that case, - # self._lock.acquire() would deadlock (issue #12352). To avoid that, a - # trylock is used instead, and if the lock can't be acquired - # immediately, the block is added to a list of blocks to be freed - # synchronously sometimes later from malloc() or free(), by calling - # _free_pending_blocks() (appending and retrieving from a list is not - # strictly thread-safe but under CPython it's atomic thanks to the GIL). - if os.getpid() != self._lastpid: - raise ValueError( - "My pid ({0:n}) is not last pid {1:n}".format( - os.getpid(),self._lastpid)) - if not self._lock.acquire(False): - # can't acquire the lock right now, add the block to the list of - # pending blocks to free - self._pending_free_blocks.append(block) - else: - # we hold the lock - try: - self._n_frees += 1 - self._free_pending_blocks() - self._add_free_block(block) - self._remove_allocated_block(block) - finally: - self._lock.release() - - def malloc(self, size): - # return a block of right size (possibly rounded up) - if size < 0: - raise ValueError("Size {0:n} out of range".format(size)) - if sys.maxsize <= size: - raise OverflowError("Size {0:n} too large".format(size)) - if os.getpid() != self._lastpid: - self.__init__() # reinitialize after fork - with self._lock: - self._n_mallocs += 1 - # allow pending blocks to be marked available - self._free_pending_blocks() - size = self._roundup(max(size, 1), self._alignment) - (arena, start, stop) = self._malloc(size) - real_stop = start + size - if real_stop < stop: - # if the returned block is larger than necessary, mark - # the remainder available - self._add_free_block((arena, real_stop, stop)) - self._allocated_blocks[arena].add((start, real_stop)) - return (arena, start, real_stop) - -# -# Class wrapping a block allocated out of a Heap -- can be inherited by child process -# - -class BufferWrapper(object): - - _heap = Heap() - - def __init__(self, size): - if size < 0: - raise ValueError("Size {0:n} out of range".format(size)) - if sys.maxsize <= size: - raise OverflowError("Size {0:n} too large".format(size)) - block = BufferWrapper._heap.malloc(size) - self._state = (block, size) - util.Finalize(self, BufferWrapper._heap.free, args=(block,)) - - def create_memoryview(self): - (arena, start, stop), size = self._state - return memoryview(arena.buffer)[start:start+size] diff --git a/python/Lib/multiprocessing/managers.py b/python/Lib/multiprocessing/managers.py deleted file mode 100644 index 7622f13..0000000 --- a/python/Lib/multiprocessing/managers.py +++ /dev/null @@ -1,1381 +0,0 @@ -# -# Module providing manager classes for dealing -# with shared objects -# -# multiprocessing/managers.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -__all__ = [ 'BaseManager', 'SyncManager', 'BaseProxy', 'Token' ] - -# -# Imports -# - -import sys -import threading -import signal -import array -import queue -import time -import types -import os -from os import getpid - -from traceback import format_exc - -from . import connection -from .context import reduction, get_spawning_popen, ProcessError -from . import pool -from . import process -from . import util -from . import get_context -try: - from . import shared_memory -except ImportError: - HAS_SHMEM = False -else: - HAS_SHMEM = True - __all__.append('SharedMemoryManager') - -# -# Register some things for pickling -# - -def reduce_array(a): - return array.array, (a.typecode, a.tobytes()) -reduction.register(array.array, reduce_array) - -view_types = [type(getattr({}, name)()) for name in ('items','keys','values')] -def rebuild_as_list(obj): - return list, (list(obj),) -for view_type in view_types: - reduction.register(view_type, rebuild_as_list) -del view_type, view_types - -# -# Type for identifying shared objects -# - -class Token(object): - ''' - Type to uniquely identify a shared object - ''' - __slots__ = ('typeid', 'address', 'id') - - def __init__(self, typeid, address, id): - (self.typeid, self.address, self.id) = (typeid, address, id) - - def __getstate__(self): - return (self.typeid, self.address, self.id) - - def __setstate__(self, state): - (self.typeid, self.address, self.id) = state - - def __repr__(self): - return '%s(typeid=%r, address=%r, id=%r)' % \ - (self.__class__.__name__, self.typeid, self.address, self.id) - -# -# Function for communication with a manager's server process -# - -def dispatch(c, id, methodname, args=(), kwds={}): - ''' - Send a message to manager using connection `c` and return response - ''' - c.send((id, methodname, args, kwds)) - kind, result = c.recv() - if kind == '#RETURN': - return result - raise convert_to_error(kind, result) - -def convert_to_error(kind, result): - if kind == '#ERROR': - return result - elif kind in ('#TRACEBACK', '#UNSERIALIZABLE'): - if not isinstance(result, str): - raise TypeError( - "Result {0!r} (kind '{1}') type is {2}, not str".format( - result, kind, type(result))) - if kind == '#UNSERIALIZABLE': - return RemoteError('Unserializable message: %s\n' % result) - else: - return RemoteError(result) - else: - return ValueError('Unrecognized message type {!r}'.format(kind)) - -class RemoteError(Exception): - def __str__(self): - return ('\n' + '-'*75 + '\n' + str(self.args[0]) + '-'*75) - -# -# Functions for finding the method names of an object -# - -def all_methods(obj): - ''' - Return a list of names of methods of `obj` - ''' - temp = [] - for name in dir(obj): - func = getattr(obj, name) - if callable(func): - temp.append(name) - return temp - -def public_methods(obj): - ''' - Return a list of names of methods of `obj` which do not start with '_' - ''' - return [name for name in all_methods(obj) if name[0] != '_'] - -# -# Server which is run in a process controlled by a manager -# - -class Server(object): - ''' - Server class which runs in a process controlled by a manager object - ''' - public = ['shutdown', 'create', 'accept_connection', 'get_methods', - 'debug_info', 'number_of_objects', 'dummy', 'incref', 'decref'] - - def __init__(self, registry, address, authkey, serializer): - if not isinstance(authkey, bytes): - raise TypeError( - "Authkey {0!r} is type {1!s}, not bytes".format( - authkey, type(authkey))) - self.registry = registry - self.authkey = process.AuthenticationString(authkey) - Listener, Client = listener_client[serializer] - - # do authentication later - self.listener = Listener(address=address, backlog=16) - self.address = self.listener.address - - self.id_to_obj = {'0': (None, ())} - self.id_to_refcount = {} - self.id_to_local_proxy_obj = {} - self.mutex = threading.Lock() - - def serve_forever(self): - ''' - Run the server forever - ''' - self.stop_event = threading.Event() - process.current_process()._manager_server = self - try: - accepter = threading.Thread(target=self.accepter) - accepter.daemon = True - accepter.start() - try: - while not self.stop_event.is_set(): - self.stop_event.wait(1) - except (KeyboardInterrupt, SystemExit): - pass - finally: - if sys.stdout != sys.__stdout__: # what about stderr? - util.debug('resetting stdout, stderr') - sys.stdout = sys.__stdout__ - sys.stderr = sys.__stderr__ - sys.exit(0) - - def accepter(self): - while True: - try: - c = self.listener.accept() - except OSError: - continue - t = threading.Thread(target=self.handle_request, args=(c,)) - t.daemon = True - t.start() - - def _handle_request(self, c): - request = None - try: - connection.deliver_challenge(c, self.authkey) - connection.answer_challenge(c, self.authkey) - request = c.recv() - ignore, funcname, args, kwds = request - assert funcname in self.public, '%r unrecognized' % funcname - func = getattr(self, funcname) - except Exception: - msg = ('#TRACEBACK', format_exc()) - else: - try: - result = func(c, *args, **kwds) - except Exception: - msg = ('#TRACEBACK', format_exc()) - else: - msg = ('#RETURN', result) - - try: - c.send(msg) - except Exception as e: - try: - c.send(('#TRACEBACK', format_exc())) - except Exception: - pass - util.info('Failure to send message: %r', msg) - util.info(' ... request was %r', request) - util.info(' ... exception was %r', e) - - def handle_request(self, conn): - ''' - Handle a new connection - ''' - try: - self._handle_request(conn) - except SystemExit: - # Server.serve_client() calls sys.exit(0) on EOF - pass - finally: - conn.close() - - def serve_client(self, conn): - ''' - Handle requests from the proxies in a particular process/thread - ''' - util.debug('starting server thread to service %r', - threading.current_thread().name) - - recv = conn.recv - send = conn.send - id_to_obj = self.id_to_obj - - while not self.stop_event.is_set(): - - try: - methodname = obj = None - request = recv() - ident, methodname, args, kwds = request - try: - obj, exposed, gettypeid = id_to_obj[ident] - except KeyError as ke: - try: - obj, exposed, gettypeid = \ - self.id_to_local_proxy_obj[ident] - except KeyError: - raise ke - - if methodname not in exposed: - raise AttributeError( - 'method %r of %r object is not in exposed=%r' % - (methodname, type(obj), exposed) - ) - - function = getattr(obj, methodname) - - try: - res = function(*args, **kwds) - except Exception as e: - msg = ('#ERROR', e) - else: - typeid = gettypeid and gettypeid.get(methodname, None) - if typeid: - rident, rexposed = self.create(conn, typeid, res) - token = Token(typeid, self.address, rident) - msg = ('#PROXY', (rexposed, token)) - else: - msg = ('#RETURN', res) - - except AttributeError: - if methodname is None: - msg = ('#TRACEBACK', format_exc()) - else: - try: - fallback_func = self.fallback_mapping[methodname] - result = fallback_func( - self, conn, ident, obj, *args, **kwds - ) - msg = ('#RETURN', result) - except Exception: - msg = ('#TRACEBACK', format_exc()) - - except EOFError: - util.debug('got EOF -- exiting thread serving %r', - threading.current_thread().name) - sys.exit(0) - - except Exception: - msg = ('#TRACEBACK', format_exc()) - - try: - try: - send(msg) - except Exception: - send(('#UNSERIALIZABLE', format_exc())) - except Exception as e: - util.info('exception in thread serving %r', - threading.current_thread().name) - util.info(' ... message was %r', msg) - util.info(' ... exception was %r', e) - conn.close() - sys.exit(1) - - def fallback_getvalue(self, conn, ident, obj): - return obj - - def fallback_str(self, conn, ident, obj): - return str(obj) - - def fallback_repr(self, conn, ident, obj): - return repr(obj) - - fallback_mapping = { - '__str__':fallback_str, - '__repr__':fallback_repr, - '#GETVALUE':fallback_getvalue - } - - def dummy(self, c): - pass - - def debug_info(self, c): - ''' - Return some info --- useful to spot problems with refcounting - ''' - # Perhaps include debug info about 'c'? - with self.mutex: - result = [] - keys = list(self.id_to_refcount.keys()) - keys.sort() - for ident in keys: - if ident != '0': - result.append(' %s: refcount=%s\n %s' % - (ident, self.id_to_refcount[ident], - str(self.id_to_obj[ident][0])[:75])) - return '\n'.join(result) - - def number_of_objects(self, c): - ''' - Number of shared objects - ''' - # Doesn't use (len(self.id_to_obj) - 1) as we shouldn't count ident='0' - return len(self.id_to_refcount) - - def shutdown(self, c): - ''' - Shutdown this process - ''' - try: - util.debug('manager received shutdown message') - c.send(('#RETURN', None)) - except: - import traceback - traceback.print_exc() - finally: - self.stop_event.set() - - def create(self, c, typeid, /, *args, **kwds): - ''' - Create a new shared object and return its id - ''' - with self.mutex: - callable, exposed, method_to_typeid, proxytype = \ - self.registry[typeid] - - if callable is None: - if kwds or (len(args) != 1): - raise ValueError( - "Without callable, must have one non-keyword argument") - obj = args[0] - else: - obj = callable(*args, **kwds) - - if exposed is None: - exposed = public_methods(obj) - if method_to_typeid is not None: - if not isinstance(method_to_typeid, dict): - raise TypeError( - "Method_to_typeid {0!r}: type {1!s}, not dict".format( - method_to_typeid, type(method_to_typeid))) - exposed = list(exposed) + list(method_to_typeid) - - ident = '%x' % id(obj) # convert to string because xmlrpclib - # only has 32 bit signed integers - util.debug('%r callable returned object with id %r', typeid, ident) - - self.id_to_obj[ident] = (obj, set(exposed), method_to_typeid) - if ident not in self.id_to_refcount: - self.id_to_refcount[ident] = 0 - - self.incref(c, ident) - return ident, tuple(exposed) - - def get_methods(self, c, token): - ''' - Return the methods of the shared object indicated by token - ''' - return tuple(self.id_to_obj[token.id][1]) - - def accept_connection(self, c, name): - ''' - Spawn a new thread to serve this connection - ''' - threading.current_thread().name = name - c.send(('#RETURN', None)) - self.serve_client(c) - - def incref(self, c, ident): - with self.mutex: - try: - self.id_to_refcount[ident] += 1 - except KeyError as ke: - # If no external references exist but an internal (to the - # manager) still does and a new external reference is created - # from it, restore the manager's tracking of it from the - # previously stashed internal ref. - if ident in self.id_to_local_proxy_obj: - self.id_to_refcount[ident] = 1 - self.id_to_obj[ident] = \ - self.id_to_local_proxy_obj[ident] - obj, exposed, gettypeid = self.id_to_obj[ident] - util.debug('Server re-enabled tracking & INCREF %r', ident) - else: - raise ke - - def decref(self, c, ident): - if ident not in self.id_to_refcount and \ - ident in self.id_to_local_proxy_obj: - util.debug('Server DECREF skipping %r', ident) - return - - with self.mutex: - if self.id_to_refcount[ident] <= 0: - raise AssertionError( - "Id {0!s} ({1!r}) has refcount {2:n}, not 1+".format( - ident, self.id_to_obj[ident], - self.id_to_refcount[ident])) - self.id_to_refcount[ident] -= 1 - if self.id_to_refcount[ident] == 0: - del self.id_to_refcount[ident] - - if ident not in self.id_to_refcount: - # Two-step process in case the object turns out to contain other - # proxy objects (e.g. a managed list of managed lists). - # Otherwise, deleting self.id_to_obj[ident] would trigger the - # deleting of the stored value (another managed object) which would - # in turn attempt to acquire the mutex that is already held here. - self.id_to_obj[ident] = (None, (), None) # thread-safe - util.debug('disposing of obj with id %r', ident) - with self.mutex: - del self.id_to_obj[ident] - - -# -# Class to represent state of a manager -# - -class State(object): - __slots__ = ['value'] - INITIAL = 0 - STARTED = 1 - SHUTDOWN = 2 - -# -# Mapping from serializer name to Listener and Client types -# - -listener_client = { - 'pickle' : (connection.Listener, connection.Client), - 'xmlrpclib' : (connection.XmlListener, connection.XmlClient) - } - -# -# Definition of BaseManager -# - -class BaseManager(object): - ''' - Base class for managers - ''' - _registry = {} - _Server = Server - - def __init__(self, address=None, authkey=None, serializer='pickle', - ctx=None, *, shutdown_timeout=1.0): - if authkey is None: - authkey = process.current_process().authkey - self._address = address # XXX not final address if eg ('', 0) - self._authkey = process.AuthenticationString(authkey) - self._state = State() - self._state.value = State.INITIAL - self._serializer = serializer - self._Listener, self._Client = listener_client[serializer] - self._ctx = ctx or get_context() - self._shutdown_timeout = shutdown_timeout - - def get_server(self): - ''' - Return server object with serve_forever() method and address attribute - ''' - if self._state.value != State.INITIAL: - if self._state.value == State.STARTED: - raise ProcessError("Already started server") - elif self._state.value == State.SHUTDOWN: - raise ProcessError("Manager has shut down") - else: - raise ProcessError( - "Unknown state {!r}".format(self._state.value)) - return Server(self._registry, self._address, - self._authkey, self._serializer) - - def connect(self): - ''' - Connect manager object to the server process - ''' - Listener, Client = listener_client[self._serializer] - conn = Client(self._address, authkey=self._authkey) - dispatch(conn, None, 'dummy') - self._state.value = State.STARTED - - def start(self, initializer=None, initargs=()): - ''' - Spawn a server process for this manager object - ''' - if self._state.value != State.INITIAL: - if self._state.value == State.STARTED: - raise ProcessError("Already started server") - elif self._state.value == State.SHUTDOWN: - raise ProcessError("Manager has shut down") - else: - raise ProcessError( - "Unknown state {!r}".format(self._state.value)) - - if initializer is not None and not callable(initializer): - raise TypeError('initializer must be a callable') - - # pipe over which we will retrieve address of server - reader, writer = connection.Pipe(duplex=False) - - # spawn process which runs a server - self._process = self._ctx.Process( - target=type(self)._run_server, - args=(self._registry, self._address, self._authkey, - self._serializer, writer, initializer, initargs), - ) - ident = ':'.join(str(i) for i in self._process._identity) - self._process.name = type(self).__name__ + '-' + ident - self._process.start() - - # get address of server - writer.close() - self._address = reader.recv() - reader.close() - - # register a finalizer - self._state.value = State.STARTED - self.shutdown = util.Finalize( - self, type(self)._finalize_manager, - args=(self._process, self._address, self._authkey, self._state, - self._Client, self._shutdown_timeout), - exitpriority=0 - ) - - @classmethod - def _run_server(cls, registry, address, authkey, serializer, writer, - initializer=None, initargs=()): - ''' - Create a server, report its address and run it - ''' - # bpo-36368: protect server process from KeyboardInterrupt signals - signal.signal(signal.SIGINT, signal.SIG_IGN) - - if initializer is not None: - initializer(*initargs) - - # create server - server = cls._Server(registry, address, authkey, serializer) - - # inform parent process of the server's address - writer.send(server.address) - writer.close() - - # run the manager - util.info('manager serving at %r', server.address) - server.serve_forever() - - def _create(self, typeid, /, *args, **kwds): - ''' - Create a new shared object; return the token and exposed tuple - ''' - assert self._state.value == State.STARTED, 'server not yet started' - conn = self._Client(self._address, authkey=self._authkey) - try: - id, exposed = dispatch(conn, None, 'create', (typeid,)+args, kwds) - finally: - conn.close() - return Token(typeid, self._address, id), exposed - - def join(self, timeout=None): - ''' - Join the manager process (if it has been spawned) - ''' - if self._process is not None: - self._process.join(timeout) - if not self._process.is_alive(): - self._process = None - - def _debug_info(self): - ''' - Return some info about the servers shared objects and connections - ''' - conn = self._Client(self._address, authkey=self._authkey) - try: - return dispatch(conn, None, 'debug_info') - finally: - conn.close() - - def _number_of_objects(self): - ''' - Return the number of shared objects - ''' - conn = self._Client(self._address, authkey=self._authkey) - try: - return dispatch(conn, None, 'number_of_objects') - finally: - conn.close() - - def __enter__(self): - if self._state.value == State.INITIAL: - self.start() - if self._state.value != State.STARTED: - if self._state.value == State.INITIAL: - raise ProcessError("Unable to start server") - elif self._state.value == State.SHUTDOWN: - raise ProcessError("Manager has shut down") - else: - raise ProcessError( - "Unknown state {!r}".format(self._state.value)) - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.shutdown() - - @staticmethod - def _finalize_manager(process, address, authkey, state, _Client, - shutdown_timeout): - ''' - Shutdown the manager process; will be registered as a finalizer - ''' - if process.is_alive(): - util.info('sending shutdown message to manager') - try: - conn = _Client(address, authkey=authkey) - try: - dispatch(conn, None, 'shutdown') - finally: - conn.close() - except Exception: - pass - - process.join(timeout=shutdown_timeout) - if process.is_alive(): - util.info('manager still alive') - if hasattr(process, 'terminate'): - util.info('trying to `terminate()` manager process') - process.terminate() - process.join(timeout=shutdown_timeout) - if process.is_alive(): - util.info('manager still alive after terminate') - process.kill() - process.join() - - state.value = State.SHUTDOWN - try: - del BaseProxy._address_to_local[address] - except KeyError: - pass - - @property - def address(self): - return self._address - - @classmethod - def register(cls, typeid, callable=None, proxytype=None, exposed=None, - method_to_typeid=None, create_method=True): - ''' - Register a typeid with the manager type - ''' - if '_registry' not in cls.__dict__: - cls._registry = cls._registry.copy() - - if proxytype is None: - proxytype = AutoProxy - - exposed = exposed or getattr(proxytype, '_exposed_', None) - - method_to_typeid = method_to_typeid or \ - getattr(proxytype, '_method_to_typeid_', None) - - if method_to_typeid: - for key, value in list(method_to_typeid.items()): # isinstance? - assert type(key) is str, '%r is not a string' % key - assert type(value) is str, '%r is not a string' % value - - cls._registry[typeid] = ( - callable, exposed, method_to_typeid, proxytype - ) - - if create_method: - def temp(self, /, *args, **kwds): - util.debug('requesting creation of a shared %r object', typeid) - token, exp = self._create(typeid, *args, **kwds) - proxy = proxytype( - token, self._serializer, manager=self, - authkey=self._authkey, exposed=exp - ) - conn = self._Client(token.address, authkey=self._authkey) - dispatch(conn, None, 'decref', (token.id,)) - return proxy - temp.__name__ = typeid - setattr(cls, typeid, temp) - -# -# Subclass of set which get cleared after a fork -# - -class ProcessLocalSet(set): - def __init__(self): - util.register_after_fork(self, lambda obj: obj.clear()) - def __reduce__(self): - return type(self), () - -# -# Definition of BaseProxy -# - -class BaseProxy(object): - ''' - A base for proxies of shared objects - ''' - _address_to_local = {} - _mutex = util.ForkAwareThreadLock() - - def __init__(self, token, serializer, manager=None, - authkey=None, exposed=None, incref=True, manager_owned=False): - with BaseProxy._mutex: - tls_idset = BaseProxy._address_to_local.get(token.address, None) - if tls_idset is None: - tls_idset = util.ForkAwareLocal(), ProcessLocalSet() - BaseProxy._address_to_local[token.address] = tls_idset - - # self._tls is used to record the connection used by this - # thread to communicate with the manager at token.address - self._tls = tls_idset[0] - - # self._idset is used to record the identities of all shared - # objects for which the current process owns references and - # which are in the manager at token.address - self._idset = tls_idset[1] - - self._token = token - self._id = self._token.id - self._manager = manager - self._serializer = serializer - self._Client = listener_client[serializer][1] - - # Should be set to True only when a proxy object is being created - # on the manager server; primary use case: nested proxy objects. - # RebuildProxy detects when a proxy is being created on the manager - # and sets this value appropriately. - self._owned_by_manager = manager_owned - - if authkey is not None: - self._authkey = process.AuthenticationString(authkey) - elif self._manager is not None: - self._authkey = self._manager._authkey - else: - self._authkey = process.current_process().authkey - - if incref: - self._incref() - - util.register_after_fork(self, BaseProxy._after_fork) - - def _connect(self): - util.debug('making connection to manager') - name = process.current_process().name - if threading.current_thread().name != 'MainThread': - name += '|' + threading.current_thread().name - conn = self._Client(self._token.address, authkey=self._authkey) - dispatch(conn, None, 'accept_connection', (name,)) - self._tls.connection = conn - - def _callmethod(self, methodname, args=(), kwds={}): - ''' - Try to call a method of the referent and return a copy of the result - ''' - try: - conn = self._tls.connection - except AttributeError: - util.debug('thread %r does not own a connection', - threading.current_thread().name) - self._connect() - conn = self._tls.connection - - conn.send((self._id, methodname, args, kwds)) - kind, result = conn.recv() - - if kind == '#RETURN': - return result - elif kind == '#PROXY': - exposed, token = result - proxytype = self._manager._registry[token.typeid][-1] - token.address = self._token.address - proxy = proxytype( - token, self._serializer, manager=self._manager, - authkey=self._authkey, exposed=exposed - ) - conn = self._Client(token.address, authkey=self._authkey) - dispatch(conn, None, 'decref', (token.id,)) - return proxy - raise convert_to_error(kind, result) - - def _getvalue(self): - ''' - Get a copy of the value of the referent - ''' - return self._callmethod('#GETVALUE') - - def _incref(self): - if self._owned_by_manager: - util.debug('owned_by_manager skipped INCREF of %r', self._token.id) - return - - conn = self._Client(self._token.address, authkey=self._authkey) - dispatch(conn, None, 'incref', (self._id,)) - util.debug('INCREF %r', self._token.id) - - self._idset.add(self._id) - - state = self._manager and self._manager._state - - self._close = util.Finalize( - self, BaseProxy._decref, - args=(self._token, self._authkey, state, - self._tls, self._idset, self._Client), - exitpriority=10 - ) - - @staticmethod - def _decref(token, authkey, state, tls, idset, _Client): - idset.discard(token.id) - - # check whether manager is still alive - if state is None or state.value == State.STARTED: - # tell manager this process no longer cares about referent - try: - util.debug('DECREF %r', token.id) - conn = _Client(token.address, authkey=authkey) - dispatch(conn, None, 'decref', (token.id,)) - except Exception as e: - util.debug('... decref failed %s', e) - - else: - util.debug('DECREF %r -- manager already shutdown', token.id) - - # check whether we can close this thread's connection because - # the process owns no more references to objects for this manager - if not idset and hasattr(tls, 'connection'): - util.debug('thread %r has no more proxies so closing conn', - threading.current_thread().name) - tls.connection.close() - del tls.connection - - def _after_fork(self): - self._manager = None - try: - self._incref() - except Exception as e: - # the proxy may just be for a manager which has shutdown - util.info('incref failed: %s' % e) - - def __reduce__(self): - kwds = {} - if get_spawning_popen() is not None: - kwds['authkey'] = self._authkey - - if getattr(self, '_isauto', False): - kwds['exposed'] = self._exposed_ - return (RebuildProxy, - (AutoProxy, self._token, self._serializer, kwds)) - else: - return (RebuildProxy, - (type(self), self._token, self._serializer, kwds)) - - def __deepcopy__(self, memo): - return self._getvalue() - - def __repr__(self): - return '<%s object, typeid %r at %#x>' % \ - (type(self).__name__, self._token.typeid, id(self)) - - def __str__(self): - ''' - Return representation of the referent (or a fall-back if that fails) - ''' - try: - return self._callmethod('__repr__') - except Exception: - return repr(self)[:-1] + "; '__str__()' failed>" - -# -# Function used for unpickling -# - -def RebuildProxy(func, token, serializer, kwds): - ''' - Function used for unpickling proxy objects. - ''' - server = getattr(process.current_process(), '_manager_server', None) - if server and server.address == token.address: - util.debug('Rebuild a proxy owned by manager, token=%r', token) - kwds['manager_owned'] = True - if token.id not in server.id_to_local_proxy_obj: - server.id_to_local_proxy_obj[token.id] = \ - server.id_to_obj[token.id] - incref = ( - kwds.pop('incref', True) and - not getattr(process.current_process(), '_inheriting', False) - ) - return func(token, serializer, incref=incref, **kwds) - -# -# Functions to create proxies and proxy types -# - -def MakeProxyType(name, exposed, _cache={}): - ''' - Return a proxy type whose methods are given by `exposed` - ''' - exposed = tuple(exposed) - try: - return _cache[(name, exposed)] - except KeyError: - pass - - dic = {} - - for meth in exposed: - exec('''def %s(self, /, *args, **kwds): - return self._callmethod(%r, args, kwds)''' % (meth, meth), dic) - - ProxyType = type(name, (BaseProxy,), dic) - ProxyType._exposed_ = exposed - _cache[(name, exposed)] = ProxyType - return ProxyType - - -def AutoProxy(token, serializer, manager=None, authkey=None, - exposed=None, incref=True, manager_owned=False): - ''' - Return an auto-proxy for `token` - ''' - _Client = listener_client[serializer][1] - - if exposed is None: - conn = _Client(token.address, authkey=authkey) - try: - exposed = dispatch(conn, None, 'get_methods', (token,)) - finally: - conn.close() - - if authkey is None and manager is not None: - authkey = manager._authkey - if authkey is None: - authkey = process.current_process().authkey - - ProxyType = MakeProxyType('AutoProxy[%s]' % token.typeid, exposed) - proxy = ProxyType(token, serializer, manager=manager, authkey=authkey, - incref=incref, manager_owned=manager_owned) - proxy._isauto = True - return proxy - -# -# Types/callables which we will register with SyncManager -# - -class Namespace(object): - def __init__(self, /, **kwds): - self.__dict__.update(kwds) - def __repr__(self): - items = list(self.__dict__.items()) - temp = [] - for name, value in items: - if not name.startswith('_'): - temp.append('%s=%r' % (name, value)) - temp.sort() - return '%s(%s)' % (self.__class__.__name__, ', '.join(temp)) - -class Value(object): - def __init__(self, typecode, value, lock=True): - self._typecode = typecode - self._value = value - def get(self): - return self._value - def set(self, value): - self._value = value - def __repr__(self): - return '%s(%r, %r)'%(type(self).__name__, self._typecode, self._value) - value = property(get, set) - -def Array(typecode, sequence, lock=True): - return array.array(typecode, sequence) - -# -# Proxy types used by SyncManager -# - -class IteratorProxy(BaseProxy): - _exposed_ = ('__next__', 'send', 'throw', 'close') - def __iter__(self): - return self - def __next__(self, *args): - return self._callmethod('__next__', args) - def send(self, *args): - return self._callmethod('send', args) - def throw(self, *args): - return self._callmethod('throw', args) - def close(self, *args): - return self._callmethod('close', args) - - -class AcquirerProxy(BaseProxy): - _exposed_ = ('acquire', 'release') - def acquire(self, blocking=True, timeout=None): - args = (blocking,) if timeout is None else (blocking, timeout) - return self._callmethod('acquire', args) - def release(self): - return self._callmethod('release') - def __enter__(self): - return self._callmethod('acquire') - def __exit__(self, exc_type, exc_val, exc_tb): - return self._callmethod('release') - - -class ConditionProxy(AcquirerProxy): - _exposed_ = ('acquire', 'release', 'wait', 'notify', 'notify_all') - def wait(self, timeout=None): - return self._callmethod('wait', (timeout,)) - def notify(self, n=1): - return self._callmethod('notify', (n,)) - def notify_all(self): - return self._callmethod('notify_all') - def wait_for(self, predicate, timeout=None): - result = predicate() - if result: - return result - if timeout is not None: - endtime = time.monotonic() + timeout - else: - endtime = None - waittime = None - while not result: - if endtime is not None: - waittime = endtime - time.monotonic() - if waittime <= 0: - break - self.wait(waittime) - result = predicate() - return result - - -class EventProxy(BaseProxy): - _exposed_ = ('is_set', 'set', 'clear', 'wait') - def is_set(self): - return self._callmethod('is_set') - def set(self): - return self._callmethod('set') - def clear(self): - return self._callmethod('clear') - def wait(self, timeout=None): - return self._callmethod('wait', (timeout,)) - - -class BarrierProxy(BaseProxy): - _exposed_ = ('__getattribute__', 'wait', 'abort', 'reset') - def wait(self, timeout=None): - return self._callmethod('wait', (timeout,)) - def abort(self): - return self._callmethod('abort') - def reset(self): - return self._callmethod('reset') - @property - def parties(self): - return self._callmethod('__getattribute__', ('parties',)) - @property - def n_waiting(self): - return self._callmethod('__getattribute__', ('n_waiting',)) - @property - def broken(self): - return self._callmethod('__getattribute__', ('broken',)) - - -class NamespaceProxy(BaseProxy): - _exposed_ = ('__getattribute__', '__setattr__', '__delattr__') - def __getattr__(self, key): - if key[0] == '_': - return object.__getattribute__(self, key) - callmethod = object.__getattribute__(self, '_callmethod') - return callmethod('__getattribute__', (key,)) - def __setattr__(self, key, value): - if key[0] == '_': - return object.__setattr__(self, key, value) - callmethod = object.__getattribute__(self, '_callmethod') - return callmethod('__setattr__', (key, value)) - def __delattr__(self, key): - if key[0] == '_': - return object.__delattr__(self, key) - callmethod = object.__getattribute__(self, '_callmethod') - return callmethod('__delattr__', (key,)) - - -class ValueProxy(BaseProxy): - _exposed_ = ('get', 'set') - def get(self): - return self._callmethod('get') - def set(self, value): - return self._callmethod('set', (value,)) - value = property(get, set) - - __class_getitem__ = classmethod(types.GenericAlias) - - -BaseListProxy = MakeProxyType('BaseListProxy', ( - '__add__', '__contains__', '__delitem__', '__getitem__', '__len__', - '__mul__', '__reversed__', '__rmul__', '__setitem__', - 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', - 'reverse', 'sort', '__imul__' - )) -class ListProxy(BaseListProxy): - def __iadd__(self, value): - self._callmethod('extend', (value,)) - return self - def __imul__(self, value): - self._callmethod('__imul__', (value,)) - return self - - -DictProxy = MakeProxyType('DictProxy', ( - '__contains__', '__delitem__', '__getitem__', '__iter__', '__len__', - '__setitem__', 'clear', 'copy', 'get', 'items', - 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values' - )) -DictProxy._method_to_typeid_ = { - '__iter__': 'Iterator', - } - - -ArrayProxy = MakeProxyType('ArrayProxy', ( - '__len__', '__getitem__', '__setitem__' - )) - - -BasePoolProxy = MakeProxyType('PoolProxy', ( - 'apply', 'apply_async', 'close', 'imap', 'imap_unordered', 'join', - 'map', 'map_async', 'starmap', 'starmap_async', 'terminate', - )) -BasePoolProxy._method_to_typeid_ = { - 'apply_async': 'AsyncResult', - 'map_async': 'AsyncResult', - 'starmap_async': 'AsyncResult', - 'imap': 'Iterator', - 'imap_unordered': 'Iterator' - } -class PoolProxy(BasePoolProxy): - def __enter__(self): - return self - def __exit__(self, exc_type, exc_val, exc_tb): - self.terminate() - -# -# Definition of SyncManager -# - -class SyncManager(BaseManager): - ''' - Subclass of `BaseManager` which supports a number of shared object types. - - The types registered are those intended for the synchronization - of threads, plus `dict`, `list` and `Namespace`. - - The `multiprocessing.Manager()` function creates started instances of - this class. - ''' - -SyncManager.register('Queue', queue.Queue) -SyncManager.register('JoinableQueue', queue.Queue) -SyncManager.register('Event', threading.Event, EventProxy) -SyncManager.register('Lock', threading.Lock, AcquirerProxy) -SyncManager.register('RLock', threading.RLock, AcquirerProxy) -SyncManager.register('Semaphore', threading.Semaphore, AcquirerProxy) -SyncManager.register('BoundedSemaphore', threading.BoundedSemaphore, - AcquirerProxy) -SyncManager.register('Condition', threading.Condition, ConditionProxy) -SyncManager.register('Barrier', threading.Barrier, BarrierProxy) -SyncManager.register('Pool', pool.Pool, PoolProxy) -SyncManager.register('list', list, ListProxy) -SyncManager.register('dict', dict, DictProxy) -SyncManager.register('Value', Value, ValueProxy) -SyncManager.register('Array', Array, ArrayProxy) -SyncManager.register('Namespace', Namespace, NamespaceProxy) - -# types returned by methods of PoolProxy -SyncManager.register('Iterator', proxytype=IteratorProxy, create_method=False) -SyncManager.register('AsyncResult', create_method=False) - -# -# Definition of SharedMemoryManager and SharedMemoryServer -# - -if HAS_SHMEM: - class _SharedMemoryTracker: - "Manages one or more shared memory segments." - - def __init__(self, name, segment_names=[]): - self.shared_memory_context_name = name - self.segment_names = segment_names - - def register_segment(self, segment_name): - "Adds the supplied shared memory block name to tracker." - util.debug(f"Register segment {segment_name!r} in pid {getpid()}") - self.segment_names.append(segment_name) - - def destroy_segment(self, segment_name): - """Calls unlink() on the shared memory block with the supplied name - and removes it from the list of blocks being tracked.""" - util.debug(f"Destroy segment {segment_name!r} in pid {getpid()}") - self.segment_names.remove(segment_name) - segment = shared_memory.SharedMemory(segment_name) - segment.close() - segment.unlink() - - def unlink(self): - "Calls destroy_segment() on all tracked shared memory blocks." - for segment_name in self.segment_names[:]: - self.destroy_segment(segment_name) - - def __del__(self): - util.debug(f"Call {self.__class__.__name__}.__del__ in {getpid()}") - self.unlink() - - def __getstate__(self): - return (self.shared_memory_context_name, self.segment_names) - - def __setstate__(self, state): - self.__init__(*state) - - - class SharedMemoryServer(Server): - - public = Server.public + \ - ['track_segment', 'release_segment', 'list_segments'] - - def __init__(self, *args, **kwargs): - Server.__init__(self, *args, **kwargs) - address = self.address - # The address of Linux abstract namespaces can be bytes - if isinstance(address, bytes): - address = os.fsdecode(address) - self.shared_memory_context = \ - _SharedMemoryTracker(f"shm_{address}_{getpid()}") - util.debug(f"SharedMemoryServer started by pid {getpid()}") - - def create(self, c, typeid, /, *args, **kwargs): - """Create a new distributed-shared object (not backed by a shared - memory block) and return its id to be used in a Proxy Object.""" - # Unless set up as a shared proxy, don't make shared_memory_context - # a standard part of kwargs. This makes things easier for supplying - # simple functions. - if hasattr(self.registry[typeid][-1], "_shared_memory_proxy"): - kwargs['shared_memory_context'] = self.shared_memory_context - return Server.create(self, c, typeid, *args, **kwargs) - - def shutdown(self, c): - "Call unlink() on all tracked shared memory, terminate the Server." - self.shared_memory_context.unlink() - return Server.shutdown(self, c) - - def track_segment(self, c, segment_name): - "Adds the supplied shared memory block name to Server's tracker." - self.shared_memory_context.register_segment(segment_name) - - def release_segment(self, c, segment_name): - """Calls unlink() on the shared memory block with the supplied name - and removes it from the tracker instance inside the Server.""" - self.shared_memory_context.destroy_segment(segment_name) - - def list_segments(self, c): - """Returns a list of names of shared memory blocks that the Server - is currently tracking.""" - return self.shared_memory_context.segment_names - - - class SharedMemoryManager(BaseManager): - """Like SyncManager but uses SharedMemoryServer instead of Server. - - It provides methods for creating and returning SharedMemory instances - and for creating a list-like object (ShareableList) backed by shared - memory. It also provides methods that create and return Proxy Objects - that support synchronization across processes (i.e. multi-process-safe - locks and semaphores). - """ - - _Server = SharedMemoryServer - - def __init__(self, *args, **kwargs): - if os.name == "posix": - # bpo-36867: Ensure the resource_tracker is running before - # launching the manager process, so that concurrent - # shared_memory manipulation both in the manager and in the - # current process does not create two resource_tracker - # processes. - from . import resource_tracker - resource_tracker.ensure_running() - BaseManager.__init__(self, *args, **kwargs) - util.debug(f"{self.__class__.__name__} created by pid {getpid()}") - - def __del__(self): - util.debug(f"{self.__class__.__name__}.__del__ by pid {getpid()}") - - def get_server(self): - 'Better than monkeypatching for now; merge into Server ultimately' - if self._state.value != State.INITIAL: - if self._state.value == State.STARTED: - raise ProcessError("Already started SharedMemoryServer") - elif self._state.value == State.SHUTDOWN: - raise ProcessError("SharedMemoryManager has shut down") - else: - raise ProcessError( - "Unknown state {!r}".format(self._state.value)) - return self._Server(self._registry, self._address, - self._authkey, self._serializer) - - def SharedMemory(self, size): - """Returns a new SharedMemory instance with the specified size in - bytes, to be tracked by the manager.""" - with self._Client(self._address, authkey=self._authkey) as conn: - sms = shared_memory.SharedMemory(None, create=True, size=size) - try: - dispatch(conn, None, 'track_segment', (sms.name,)) - except BaseException as e: - sms.unlink() - raise e - return sms - - def ShareableList(self, sequence): - """Returns a new ShareableList instance populated with the values - from the input sequence, to be tracked by the manager.""" - with self._Client(self._address, authkey=self._authkey) as conn: - sl = shared_memory.ShareableList(sequence) - try: - dispatch(conn, None, 'track_segment', (sl.shm.name,)) - except BaseException as e: - sl.shm.unlink() - raise e - return sl diff --git a/python/Lib/multiprocessing/pool.py b/python/Lib/multiprocessing/pool.py deleted file mode 100644 index 5ac470d..0000000 --- a/python/Lib/multiprocessing/pool.py +++ /dev/null @@ -1,957 +0,0 @@ -# -# Module providing the `Pool` class for managing a process pool -# -# multiprocessing/pool.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -__all__ = ['Pool', 'ThreadPool'] - -# -# Imports -# - -import collections -import itertools -import os -import queue -import threading -import time -import traceback -import types -import warnings - -# If threading is available then ThreadPool should be provided. Therefore -# we avoid top-level imports which are liable to fail on some systems. -from . import util -from . import get_context, TimeoutError -from .connection import wait - -# -# Constants representing the state of a pool -# - -INIT = "INIT" -RUN = "RUN" -CLOSE = "CLOSE" -TERMINATE = "TERMINATE" - -# -# Miscellaneous -# - -job_counter = itertools.count() - -def mapstar(args): - return list(map(*args)) - -def starmapstar(args): - return list(itertools.starmap(args[0], args[1])) - -# -# Hack to embed stringification of remote traceback in local traceback -# - -class RemoteTraceback(Exception): - def __init__(self, tb): - self.tb = tb - def __str__(self): - return self.tb - -class ExceptionWithTraceback: - def __init__(self, exc, tb): - tb = traceback.format_exception(type(exc), exc, tb) - tb = ''.join(tb) - self.exc = exc - self.tb = '\n"""\n%s"""' % tb - def __reduce__(self): - return rebuild_exc, (self.exc, self.tb) - -def rebuild_exc(exc, tb): - exc.__cause__ = RemoteTraceback(tb) - return exc - -# -# Code run by worker processes -# - -class MaybeEncodingError(Exception): - """Wraps possible unpickleable errors, so they can be - safely sent through the socket.""" - - def __init__(self, exc, value): - self.exc = repr(exc) - self.value = repr(value) - super(MaybeEncodingError, self).__init__(self.exc, self.value) - - def __str__(self): - return "Error sending result: '%s'. Reason: '%s'" % (self.value, - self.exc) - - def __repr__(self): - return "<%s: %s>" % (self.__class__.__name__, self) - - -def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None, - wrap_exception=False): - if (maxtasks is not None) and not (isinstance(maxtasks, int) - and maxtasks >= 1): - raise AssertionError("Maxtasks {!r} is not valid".format(maxtasks)) - put = outqueue.put - get = inqueue.get - if hasattr(inqueue, '_writer'): - inqueue._writer.close() - outqueue._reader.close() - - if initializer is not None: - initializer(*initargs) - - completed = 0 - while maxtasks is None or (maxtasks and completed < maxtasks): - try: - task = get() - except (EOFError, OSError): - util.debug('worker got EOFError or OSError -- exiting') - break - - if task is None: - util.debug('worker got sentinel -- exiting') - break - - job, i, func, args, kwds = task - try: - result = (True, func(*args, **kwds)) - except Exception as e: - if wrap_exception and func is not _helper_reraises_exception: - e = ExceptionWithTraceback(e, e.__traceback__) - result = (False, e) - try: - put((job, i, result)) - except Exception as e: - wrapped = MaybeEncodingError(e, result[1]) - util.debug("Possible encoding error while sending result: %s" % ( - wrapped)) - put((job, i, (False, wrapped))) - - task = job = result = func = args = kwds = None - completed += 1 - util.debug('worker exiting after %d tasks' % completed) - -def _helper_reraises_exception(ex): - 'Pickle-able helper function for use by _guarded_task_generation.' - raise ex - -# -# Class representing a process pool -# - -class _PoolCache(dict): - """ - Class that implements a cache for the Pool class that will notify - the pool management threads every time the cache is emptied. The - notification is done by the use of a queue that is provided when - instantiating the cache. - """ - def __init__(self, /, *args, notifier=None, **kwds): - self.notifier = notifier - super().__init__(*args, **kwds) - - def __delitem__(self, item): - super().__delitem__(item) - - # Notify that the cache is empty. This is important because the - # pool keeps maintaining workers until the cache gets drained. This - # eliminates a race condition in which a task is finished after the - # the pool's _handle_workers method has enter another iteration of the - # loop. In this situation, the only event that can wake up the pool - # is the cache to be emptied (no more tasks available). - if not self: - self.notifier.put(None) - -class Pool(object): - ''' - Class which supports an async version of applying functions to arguments. - ''' - _wrap_exception = True - - @staticmethod - def Process(ctx, *args, **kwds): - return ctx.Process(*args, **kwds) - - def __init__(self, processes=None, initializer=None, initargs=(), - maxtasksperchild=None, context=None): - # Attributes initialized early to make sure that they exist in - # __del__() if __init__() raises an exception - self._pool = [] - self._state = INIT - - self._ctx = context or get_context() - self._setup_queues() - self._taskqueue = queue.SimpleQueue() - # The _change_notifier queue exist to wake up self._handle_workers() - # when the cache (self._cache) is empty or when there is a change in - # the _state variable of the thread that runs _handle_workers. - self._change_notifier = self._ctx.SimpleQueue() - self._cache = _PoolCache(notifier=self._change_notifier) - self._maxtasksperchild = maxtasksperchild - self._initializer = initializer - self._initargs = initargs - - if processes is None: - processes = os.cpu_count() or 1 - if processes < 1: - raise ValueError("Number of processes must be at least 1") - if maxtasksperchild is not None: - if not isinstance(maxtasksperchild, int) or maxtasksperchild <= 0: - raise ValueError("maxtasksperchild must be a positive int or None") - - if initializer is not None and not callable(initializer): - raise TypeError('initializer must be a callable') - - self._processes = processes - try: - self._repopulate_pool() - except Exception: - for p in self._pool: - if p.exitcode is None: - p.terminate() - for p in self._pool: - p.join() - raise - - sentinels = self._get_sentinels() - - self._worker_handler = threading.Thread( - target=Pool._handle_workers, - args=(self._cache, self._taskqueue, self._ctx, self.Process, - self._processes, self._pool, self._inqueue, self._outqueue, - self._initializer, self._initargs, self._maxtasksperchild, - self._wrap_exception, sentinels, self._change_notifier) - ) - self._worker_handler.daemon = True - self._worker_handler._state = RUN - self._worker_handler.start() - - - self._task_handler = threading.Thread( - target=Pool._handle_tasks, - args=(self._taskqueue, self._quick_put, self._outqueue, - self._pool, self._cache) - ) - self._task_handler.daemon = True - self._task_handler._state = RUN - self._task_handler.start() - - self._result_handler = threading.Thread( - target=Pool._handle_results, - args=(self._outqueue, self._quick_get, self._cache) - ) - self._result_handler.daemon = True - self._result_handler._state = RUN - self._result_handler.start() - - self._terminate = util.Finalize( - self, self._terminate_pool, - args=(self._taskqueue, self._inqueue, self._outqueue, self._pool, - self._change_notifier, self._worker_handler, self._task_handler, - self._result_handler, self._cache), - exitpriority=15 - ) - self._state = RUN - - # Copy globals as function locals to make sure that they are available - # during Python shutdown when the Pool is destroyed. - def __del__(self, _warn=warnings.warn, RUN=RUN): - if self._state == RUN: - _warn(f"unclosed running multiprocessing pool {self!r}", - ResourceWarning, source=self) - if getattr(self, '_change_notifier', None) is not None: - self._change_notifier.put(None) - - def __repr__(self): - cls = self.__class__ - return (f'<{cls.__module__}.{cls.__qualname__} ' - f'state={self._state} ' - f'pool_size={len(self._pool)}>') - - def _get_sentinels(self): - task_queue_sentinels = [self._outqueue._reader] - self_notifier_sentinels = [self._change_notifier._reader] - return [*task_queue_sentinels, *self_notifier_sentinels] - - @staticmethod - def _get_worker_sentinels(workers): - return [worker.sentinel for worker in - workers if hasattr(worker, "sentinel")] - - @staticmethod - def _join_exited_workers(pool): - """Cleanup after any worker processes which have exited due to reaching - their specified lifetime. Returns True if any workers were cleaned up. - """ - cleaned = False - for i in reversed(range(len(pool))): - worker = pool[i] - if worker.exitcode is not None: - # worker exited - util.debug('cleaning up worker %d' % i) - worker.join() - cleaned = True - del pool[i] - return cleaned - - def _repopulate_pool(self): - return self._repopulate_pool_static(self._ctx, self.Process, - self._processes, - self._pool, self._inqueue, - self._outqueue, self._initializer, - self._initargs, - self._maxtasksperchild, - self._wrap_exception) - - @staticmethod - def _repopulate_pool_static(ctx, Process, processes, pool, inqueue, - outqueue, initializer, initargs, - maxtasksperchild, wrap_exception): - """Bring the number of pool processes up to the specified number, - for use after reaping workers which have exited. - """ - for i in range(processes - len(pool)): - w = Process(ctx, target=worker, - args=(inqueue, outqueue, - initializer, - initargs, maxtasksperchild, - wrap_exception)) - w.name = w.name.replace('Process', 'PoolWorker') - w.daemon = True - w.start() - pool.append(w) - util.debug('added worker') - - @staticmethod - def _maintain_pool(ctx, Process, processes, pool, inqueue, outqueue, - initializer, initargs, maxtasksperchild, - wrap_exception): - """Clean up any exited workers and start replacements for them. - """ - if Pool._join_exited_workers(pool): - Pool._repopulate_pool_static(ctx, Process, processes, pool, - inqueue, outqueue, initializer, - initargs, maxtasksperchild, - wrap_exception) - - def _setup_queues(self): - self._inqueue = self._ctx.SimpleQueue() - self._outqueue = self._ctx.SimpleQueue() - self._quick_put = self._inqueue._writer.send - self._quick_get = self._outqueue._reader.recv - - def _check_running(self): - if self._state != RUN: - raise ValueError("Pool not running") - - def apply(self, func, args=(), kwds={}): - ''' - Equivalent of `func(*args, **kwds)`. - Pool must be running. - ''' - return self.apply_async(func, args, kwds).get() - - def map(self, func, iterable, chunksize=None): - ''' - Apply `func` to each element in `iterable`, collecting the results - in a list that is returned. - ''' - return self._map_async(func, iterable, mapstar, chunksize).get() - - def starmap(self, func, iterable, chunksize=None): - ''' - Like `map()` method but the elements of the `iterable` are expected to - be iterables as well and will be unpacked as arguments. Hence - `func` and (a, b) becomes func(a, b). - ''' - return self._map_async(func, iterable, starmapstar, chunksize).get() - - def starmap_async(self, func, iterable, chunksize=None, callback=None, - error_callback=None): - ''' - Asynchronous version of `starmap()` method. - ''' - return self._map_async(func, iterable, starmapstar, chunksize, - callback, error_callback) - - def _guarded_task_generation(self, result_job, func, iterable): - '''Provides a generator of tasks for imap and imap_unordered with - appropriate handling for iterables which throw exceptions during - iteration.''' - try: - i = -1 - for i, x in enumerate(iterable): - yield (result_job, i, func, (x,), {}) - except Exception as e: - yield (result_job, i+1, _helper_reraises_exception, (e,), {}) - - def imap(self, func, iterable, chunksize=1): - ''' - Equivalent of `map()` -- can be MUCH slower than `Pool.map()`. - ''' - self._check_running() - if chunksize == 1: - result = IMapIterator(self) - self._taskqueue.put( - ( - self._guarded_task_generation(result._job, func, iterable), - result._set_length - )) - return result - else: - if chunksize < 1: - raise ValueError( - "Chunksize must be 1+, not {0:n}".format( - chunksize)) - task_batches = Pool._get_tasks(func, iterable, chunksize) - result = IMapIterator(self) - self._taskqueue.put( - ( - self._guarded_task_generation(result._job, - mapstar, - task_batches), - result._set_length - )) - return (item for chunk in result for item in chunk) - - def imap_unordered(self, func, iterable, chunksize=1): - ''' - Like `imap()` method but ordering of results is arbitrary. - ''' - self._check_running() - if chunksize == 1: - result = IMapUnorderedIterator(self) - self._taskqueue.put( - ( - self._guarded_task_generation(result._job, func, iterable), - result._set_length - )) - return result - else: - if chunksize < 1: - raise ValueError( - "Chunksize must be 1+, not {0!r}".format(chunksize)) - task_batches = Pool._get_tasks(func, iterable, chunksize) - result = IMapUnorderedIterator(self) - self._taskqueue.put( - ( - self._guarded_task_generation(result._job, - mapstar, - task_batches), - result._set_length - )) - return (item for chunk in result for item in chunk) - - def apply_async(self, func, args=(), kwds={}, callback=None, - error_callback=None): - ''' - Asynchronous version of `apply()` method. - ''' - self._check_running() - result = ApplyResult(self, callback, error_callback) - self._taskqueue.put(([(result._job, 0, func, args, kwds)], None)) - return result - - def map_async(self, func, iterable, chunksize=None, callback=None, - error_callback=None): - ''' - Asynchronous version of `map()` method. - ''' - return self._map_async(func, iterable, mapstar, chunksize, callback, - error_callback) - - def _map_async(self, func, iterable, mapper, chunksize=None, callback=None, - error_callback=None): - ''' - Helper function to implement map, starmap and their async counterparts. - ''' - self._check_running() - if not hasattr(iterable, '__len__'): - iterable = list(iterable) - - if chunksize is None: - chunksize, extra = divmod(len(iterable), len(self._pool) * 4) - if extra: - chunksize += 1 - if len(iterable) == 0: - chunksize = 0 - - task_batches = Pool._get_tasks(func, iterable, chunksize) - result = MapResult(self, chunksize, len(iterable), callback, - error_callback=error_callback) - self._taskqueue.put( - ( - self._guarded_task_generation(result._job, - mapper, - task_batches), - None - ) - ) - return result - - @staticmethod - def _wait_for_updates(sentinels, change_notifier, timeout=None): - wait(sentinels, timeout=timeout) - while not change_notifier.empty(): - change_notifier.get() - - @classmethod - def _handle_workers(cls, cache, taskqueue, ctx, Process, processes, - pool, inqueue, outqueue, initializer, initargs, - maxtasksperchild, wrap_exception, sentinels, - change_notifier): - thread = threading.current_thread() - - # Keep maintaining workers until the cache gets drained, unless the pool - # is terminated. - while thread._state == RUN or (cache and thread._state != TERMINATE): - cls._maintain_pool(ctx, Process, processes, pool, inqueue, - outqueue, initializer, initargs, - maxtasksperchild, wrap_exception) - - current_sentinels = [*cls._get_worker_sentinels(pool), *sentinels] - - cls._wait_for_updates(current_sentinels, change_notifier) - # send sentinel to stop workers - taskqueue.put(None) - util.debug('worker handler exiting') - - @staticmethod - def _handle_tasks(taskqueue, put, outqueue, pool, cache): - thread = threading.current_thread() - - for taskseq, set_length in iter(taskqueue.get, None): - task = None - try: - # iterating taskseq cannot fail - for task in taskseq: - if thread._state != RUN: - util.debug('task handler found thread._state != RUN') - break - try: - put(task) - except Exception as e: - job, idx = task[:2] - try: - cache[job]._set(idx, (False, e)) - except KeyError: - pass - else: - if set_length: - util.debug('doing set_length()') - idx = task[1] if task else -1 - set_length(idx + 1) - continue - break - finally: - task = taskseq = job = None - else: - util.debug('task handler got sentinel') - - try: - # tell result handler to finish when cache is empty - util.debug('task handler sending sentinel to result handler') - outqueue.put(None) - - # tell workers there is no more work - util.debug('task handler sending sentinel to workers') - for p in pool: - put(None) - except OSError: - util.debug('task handler got OSError when sending sentinels') - - util.debug('task handler exiting') - - @staticmethod - def _handle_results(outqueue, get, cache): - thread = threading.current_thread() - - while 1: - try: - task = get() - except (OSError, EOFError): - util.debug('result handler got EOFError/OSError -- exiting') - return - - if thread._state != RUN: - assert thread._state == TERMINATE, "Thread not in TERMINATE" - util.debug('result handler found thread._state=TERMINATE') - break - - if task is None: - util.debug('result handler got sentinel') - break - - job, i, obj = task - try: - cache[job]._set(i, obj) - except KeyError: - pass - task = job = obj = None - - while cache and thread._state != TERMINATE: - try: - task = get() - except (OSError, EOFError): - util.debug('result handler got EOFError/OSError -- exiting') - return - - if task is None: - util.debug('result handler ignoring extra sentinel') - continue - job, i, obj = task - try: - cache[job]._set(i, obj) - except KeyError: - pass - task = job = obj = None - - if hasattr(outqueue, '_reader'): - util.debug('ensuring that outqueue is not full') - # If we don't make room available in outqueue then - # attempts to add the sentinel (None) to outqueue may - # block. There is guaranteed to be no more than 2 sentinels. - try: - for i in range(10): - if not outqueue._reader.poll(): - break - get() - except (OSError, EOFError): - pass - - util.debug('result handler exiting: len(cache)=%s, thread._state=%s', - len(cache), thread._state) - - @staticmethod - def _get_tasks(func, it, size): - it = iter(it) - while 1: - x = tuple(itertools.islice(it, size)) - if not x: - return - yield (func, x) - - def __reduce__(self): - raise NotImplementedError( - 'pool objects cannot be passed between processes or pickled' - ) - - def close(self): - util.debug('closing pool') - if self._state == RUN: - self._state = CLOSE - self._worker_handler._state = CLOSE - self._change_notifier.put(None) - - def terminate(self): - util.debug('terminating pool') - self._state = TERMINATE - self._terminate() - - def join(self): - util.debug('joining pool') - if self._state == RUN: - raise ValueError("Pool is still running") - elif self._state not in (CLOSE, TERMINATE): - raise ValueError("In unknown state") - self._worker_handler.join() - self._task_handler.join() - self._result_handler.join() - for p in self._pool: - p.join() - - @staticmethod - def _help_stuff_finish(inqueue, task_handler, size): - # task_handler may be blocked trying to put items on inqueue - util.debug('removing tasks from inqueue until task handler finished') - inqueue._rlock.acquire() - while task_handler.is_alive() and inqueue._reader.poll(): - inqueue._reader.recv() - time.sleep(0) - - @classmethod - def _terminate_pool(cls, taskqueue, inqueue, outqueue, pool, change_notifier, - worker_handler, task_handler, result_handler, cache): - # this is guaranteed to only be called once - util.debug('finalizing pool') - - # Notify that the worker_handler state has been changed so the - # _handle_workers loop can be unblocked (and exited) in order to - # send the finalization sentinel all the workers. - worker_handler._state = TERMINATE - change_notifier.put(None) - - task_handler._state = TERMINATE - - util.debug('helping task handler/workers to finish') - cls._help_stuff_finish(inqueue, task_handler, len(pool)) - - if (not result_handler.is_alive()) and (len(cache) != 0): - raise AssertionError( - "Cannot have cache with result_hander not alive") - - result_handler._state = TERMINATE - change_notifier.put(None) - outqueue.put(None) # sentinel - - # We must wait for the worker handler to exit before terminating - # workers because we don't want workers to be restarted behind our back. - util.debug('joining worker handler') - if threading.current_thread() is not worker_handler: - worker_handler.join() - - # Terminate workers which haven't already finished. - if pool and hasattr(pool[0], 'terminate'): - util.debug('terminating workers') - for p in pool: - if p.exitcode is None: - p.terminate() - - util.debug('joining task handler') - if threading.current_thread() is not task_handler: - task_handler.join() - - util.debug('joining result handler') - if threading.current_thread() is not result_handler: - result_handler.join() - - if pool and hasattr(pool[0], 'terminate'): - util.debug('joining pool workers') - for p in pool: - if p.is_alive(): - # worker has not yet exited - util.debug('cleaning up worker %d' % p.pid) - p.join() - - def __enter__(self): - self._check_running() - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.terminate() - -# -# Class whose instances are returned by `Pool.apply_async()` -# - -class ApplyResult(object): - - def __init__(self, pool, callback, error_callback): - self._pool = pool - self._event = threading.Event() - self._job = next(job_counter) - self._cache = pool._cache - self._callback = callback - self._error_callback = error_callback - self._cache[self._job] = self - - def ready(self): - return self._event.is_set() - - def successful(self): - if not self.ready(): - raise ValueError("{0!r} not ready".format(self)) - return self._success - - def wait(self, timeout=None): - self._event.wait(timeout) - - def get(self, timeout=None): - self.wait(timeout) - if not self.ready(): - raise TimeoutError - if self._success: - return self._value - else: - raise self._value - - def _set(self, i, obj): - self._success, self._value = obj - if self._callback and self._success: - self._callback(self._value) - if self._error_callback and not self._success: - self._error_callback(self._value) - self._event.set() - del self._cache[self._job] - self._pool = None - - __class_getitem__ = classmethod(types.GenericAlias) - -AsyncResult = ApplyResult # create alias -- see #17805 - -# -# Class whose instances are returned by `Pool.map_async()` -# - -class MapResult(ApplyResult): - - def __init__(self, pool, chunksize, length, callback, error_callback): - ApplyResult.__init__(self, pool, callback, - error_callback=error_callback) - self._success = True - self._value = [None] * length - self._chunksize = chunksize - if chunksize <= 0: - self._number_left = 0 - self._event.set() - del self._cache[self._job] - else: - self._number_left = length//chunksize + bool(length % chunksize) - - def _set(self, i, success_result): - self._number_left -= 1 - success, result = success_result - if success and self._success: - self._value[i*self._chunksize:(i+1)*self._chunksize] = result - if self._number_left == 0: - if self._callback: - self._callback(self._value) - del self._cache[self._job] - self._event.set() - self._pool = None - else: - if not success and self._success: - # only store first exception - self._success = False - self._value = result - if self._number_left == 0: - # only consider the result ready once all jobs are done - if self._error_callback: - self._error_callback(self._value) - del self._cache[self._job] - self._event.set() - self._pool = None - -# -# Class whose instances are returned by `Pool.imap()` -# - -class IMapIterator(object): - - def __init__(self, pool): - self._pool = pool - self._cond = threading.Condition(threading.Lock()) - self._job = next(job_counter) - self._cache = pool._cache - self._items = collections.deque() - self._index = 0 - self._length = None - self._unsorted = {} - self._cache[self._job] = self - - def __iter__(self): - return self - - def next(self, timeout=None): - with self._cond: - try: - item = self._items.popleft() - except IndexError: - if self._index == self._length: - self._pool = None - raise StopIteration from None - self._cond.wait(timeout) - try: - item = self._items.popleft() - except IndexError: - if self._index == self._length: - self._pool = None - raise StopIteration from None - raise TimeoutError from None - - success, value = item - if success: - return value - raise value - - __next__ = next # XXX - - def _set(self, i, obj): - with self._cond: - if self._index == i: - self._items.append(obj) - self._index += 1 - while self._index in self._unsorted: - obj = self._unsorted.pop(self._index) - self._items.append(obj) - self._index += 1 - self._cond.notify() - else: - self._unsorted[i] = obj - - if self._index == self._length: - del self._cache[self._job] - self._pool = None - - def _set_length(self, length): - with self._cond: - self._length = length - if self._index == self._length: - self._cond.notify() - del self._cache[self._job] - self._pool = None - -# -# Class whose instances are returned by `Pool.imap_unordered()` -# - -class IMapUnorderedIterator(IMapIterator): - - def _set(self, i, obj): - with self._cond: - self._items.append(obj) - self._index += 1 - self._cond.notify() - if self._index == self._length: - del self._cache[self._job] - self._pool = None - -# -# -# - -class ThreadPool(Pool): - _wrap_exception = False - - @staticmethod - def Process(ctx, *args, **kwds): - from .dummy import Process - return Process(*args, **kwds) - - def __init__(self, processes=None, initializer=None, initargs=()): - Pool.__init__(self, processes, initializer, initargs) - - def _setup_queues(self): - self._inqueue = queue.SimpleQueue() - self._outqueue = queue.SimpleQueue() - self._quick_put = self._inqueue.put - self._quick_get = self._outqueue.get - - def _get_sentinels(self): - return [self._change_notifier._reader] - - @staticmethod - def _get_worker_sentinels(workers): - return [] - - @staticmethod - def _help_stuff_finish(inqueue, task_handler, size): - # drain inqueue, and put sentinels at its head to make workers finish - try: - while True: - inqueue.get(block=False) - except queue.Empty: - pass - for i in range(size): - inqueue.put(None) - - def _wait_for_updates(self, sentinels, change_notifier, timeout): - time.sleep(timeout) diff --git a/python/Lib/multiprocessing/popen_fork.py b/python/Lib/multiprocessing/popen_fork.py deleted file mode 100644 index 9f0ee90..0000000 --- a/python/Lib/multiprocessing/popen_fork.py +++ /dev/null @@ -1,83 +0,0 @@ -import os -import signal - -from . import util - -__all__ = ['Popen'] - -# -# Start child process using fork -# - -class Popen(object): - method = 'fork' - - def __init__(self, process_obj): - util._flush_std_streams() - self.returncode = None - self.finalizer = None - self._launch(process_obj) - - def duplicate_for_child(self, fd): - return fd - - def poll(self, flag=os.WNOHANG): - if self.returncode is None: - try: - pid, sts = os.waitpid(self.pid, flag) - except OSError: - # Child process not yet created. See #1731717 - # e.errno == errno.ECHILD == 10 - return None - if pid == self.pid: - self.returncode = os.waitstatus_to_exitcode(sts) - return self.returncode - - def wait(self, timeout=None): - if self.returncode is None: - if timeout is not None: - from multiprocessing.connection import wait - if not wait([self.sentinel], timeout): - return None - # This shouldn't block if wait() returned successfully. - return self.poll(os.WNOHANG if timeout == 0.0 else 0) - return self.returncode - - def _send_signal(self, sig): - if self.returncode is None: - try: - os.kill(self.pid, sig) - except ProcessLookupError: - pass - except OSError: - if self.wait(timeout=0.1) is None: - raise - - def terminate(self): - self._send_signal(signal.SIGTERM) - - def kill(self): - self._send_signal(signal.SIGKILL) - - def _launch(self, process_obj): - code = 1 - parent_r, child_w = os.pipe() - child_r, parent_w = os.pipe() - self.pid = os.fork() - if self.pid == 0: - try: - os.close(parent_r) - os.close(parent_w) - code = process_obj._bootstrap(parent_sentinel=child_r) - finally: - os._exit(code) - else: - os.close(child_w) - os.close(child_r) - self.finalizer = util.Finalize(self, util.close_fds, - (parent_r, parent_w,)) - self.sentinel = parent_r - - def close(self): - if self.finalizer is not None: - self.finalizer() diff --git a/python/Lib/multiprocessing/popen_forkserver.py b/python/Lib/multiprocessing/popen_forkserver.py deleted file mode 100644 index dba3dd0..0000000 --- a/python/Lib/multiprocessing/popen_forkserver.py +++ /dev/null @@ -1,74 +0,0 @@ -import io -import os - -from .context import reduction, set_spawning_popen -if not reduction.HAVE_SEND_HANDLE: - raise ImportError('No support for sending fds between processes') -from . import forkserver -from . import popen_fork -from . import spawn -from . import util - - -__all__ = ['Popen'] - -# -# Wrapper for an fd used while launching a process -# - -class _DupFd(object): - def __init__(self, ind): - self.ind = ind - def detach(self): - return forkserver.get_inherited_fds()[self.ind] - -# -# Start child process using a server process -# - -class Popen(popen_fork.Popen): - method = 'forkserver' - DupFd = _DupFd - - def __init__(self, process_obj): - self._fds = [] - super().__init__(process_obj) - - def duplicate_for_child(self, fd): - self._fds.append(fd) - return len(self._fds) - 1 - - def _launch(self, process_obj): - prep_data = spawn.get_preparation_data(process_obj._name) - buf = io.BytesIO() - set_spawning_popen(self) - try: - reduction.dump(prep_data, buf) - reduction.dump(process_obj, buf) - finally: - set_spawning_popen(None) - - self.sentinel, w = forkserver.connect_to_new_process(self._fds) - # Keep a duplicate of the data pipe's write end as a sentinel of the - # parent process used by the child process. - _parent_w = os.dup(w) - self.finalizer = util.Finalize(self, util.close_fds, - (_parent_w, self.sentinel)) - with open(w, 'wb', closefd=True) as f: - f.write(buf.getbuffer()) - self.pid = forkserver.read_signed(self.sentinel) - - def poll(self, flag=os.WNOHANG): - if self.returncode is None: - from multiprocessing.connection import wait - timeout = 0 if flag == os.WNOHANG else None - if not wait([self.sentinel], timeout): - return None - try: - self.returncode = forkserver.read_signed(self.sentinel) - except (OSError, EOFError): - # This should not happen usually, but perhaps the forkserver - # process itself got killed - self.returncode = 255 - - return self.returncode diff --git a/python/Lib/multiprocessing/popen_spawn_posix.py b/python/Lib/multiprocessing/popen_spawn_posix.py deleted file mode 100644 index 14efd2b..0000000 --- a/python/Lib/multiprocessing/popen_spawn_posix.py +++ /dev/null @@ -1,72 +0,0 @@ -import io -import os - -from .context import reduction, set_spawning_popen -from . import popen_fork -from . import spawn -from . import util - -__all__ = ['Popen'] - - -# -# Wrapper for an fd used while launching a process -# - -class _DupFd(object): - def __init__(self, fd): - self.fd = fd - def detach(self): - return self.fd - -# -# Start child process using a fresh interpreter -# - -class Popen(popen_fork.Popen): - method = 'spawn' - DupFd = _DupFd - - def __init__(self, process_obj): - self._fds = [] - super().__init__(process_obj) - - def duplicate_for_child(self, fd): - self._fds.append(fd) - return fd - - def _launch(self, process_obj): - from . import resource_tracker - tracker_fd = resource_tracker.getfd() - self._fds.append(tracker_fd) - prep_data = spawn.get_preparation_data(process_obj._name) - fp = io.BytesIO() - set_spawning_popen(self) - try: - reduction.dump(prep_data, fp) - reduction.dump(process_obj, fp) - finally: - set_spawning_popen(None) - - parent_r = child_w = child_r = parent_w = None - try: - parent_r, child_w = os.pipe() - child_r, parent_w = os.pipe() - cmd = spawn.get_command_line(tracker_fd=tracker_fd, - pipe_handle=child_r) - self._fds.extend([child_r, child_w]) - self.pid = util.spawnv_passfds(spawn.get_executable(), - cmd, self._fds) - self.sentinel = parent_r - with open(parent_w, 'wb', closefd=False) as f: - f.write(fp.getbuffer()) - finally: - fds_to_close = [] - for fd in (parent_r, parent_w): - if fd is not None: - fds_to_close.append(fd) - self.finalizer = util.Finalize(self, util.close_fds, fds_to_close) - - for fd in (child_r, child_w): - if fd is not None: - os.close(fd) diff --git a/python/Lib/multiprocessing/popen_spawn_win32.py b/python/Lib/multiprocessing/popen_spawn_win32.py deleted file mode 100644 index 0add662..0000000 --- a/python/Lib/multiprocessing/popen_spawn_win32.py +++ /dev/null @@ -1,132 +0,0 @@ -import os -import msvcrt -import signal -import sys -import _winapi - -from .context import reduction, get_spawning_popen, set_spawning_popen -from . import spawn -from . import util - -__all__ = ['Popen'] - -# -# -# - -TERMINATE = 0x10000 -WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False)) -WINSERVICE = sys.executable.lower().endswith("pythonservice.exe") - - -def _path_eq(p1, p2): - return p1 == p2 or os.path.normcase(p1) == os.path.normcase(p2) - -WINENV = not _path_eq(sys.executable, sys._base_executable) - - -def _close_handles(*handles): - for handle in handles: - _winapi.CloseHandle(handle) - - -# -# We define a Popen class similar to the one from subprocess, but -# whose constructor takes a process object as its argument. -# - -class Popen(object): - ''' - Start a subprocess to run the code of a process object - ''' - method = 'spawn' - - def __init__(self, process_obj): - prep_data = spawn.get_preparation_data(process_obj._name) - - # read end of pipe will be duplicated by the child process - # -- see spawn_main() in spawn.py. - # - # bpo-33929: Previously, the read end of pipe was "stolen" by the child - # process, but it leaked a handle if the child process had been - # terminated before it could steal the handle from the parent process. - rhandle, whandle = _winapi.CreatePipe(None, 0) - wfd = msvcrt.open_osfhandle(whandle, 0) - cmd = spawn.get_command_line(parent_pid=os.getpid(), - pipe_handle=rhandle) - - python_exe = spawn.get_executable() - - # bpo-35797: When running in a venv, we bypass the redirect - # executor and launch our base Python. - if WINENV and _path_eq(python_exe, sys.executable): - cmd[0] = python_exe = sys._base_executable - env = os.environ.copy() - env["__PYVENV_LAUNCHER__"] = sys.executable - else: - env = None - - cmd = ' '.join('"%s"' % x for x in cmd) - - with open(wfd, 'wb', closefd=True) as to_child: - # start process - try: - hp, ht, pid, tid = _winapi.CreateProcess( - python_exe, cmd, - None, None, False, 0, env, None, None) - _winapi.CloseHandle(ht) - except: - _winapi.CloseHandle(rhandle) - raise - - # set attributes of self - self.pid = pid - self.returncode = None - self._handle = hp - self.sentinel = int(hp) - self.finalizer = util.Finalize(self, _close_handles, - (self.sentinel, int(rhandle))) - - # send information to child - set_spawning_popen(self) - try: - reduction.dump(prep_data, to_child) - reduction.dump(process_obj, to_child) - finally: - set_spawning_popen(None) - - def duplicate_for_child(self, handle): - assert self is get_spawning_popen() - return reduction.duplicate(handle, self.sentinel) - - def wait(self, timeout=None): - if self.returncode is None: - if timeout is None: - msecs = _winapi.INFINITE - else: - msecs = max(0, int(timeout * 1000 + 0.5)) - - res = _winapi.WaitForSingleObject(int(self._handle), msecs) - if res == _winapi.WAIT_OBJECT_0: - code = _winapi.GetExitCodeProcess(self._handle) - if code == TERMINATE: - code = -signal.SIGTERM - self.returncode = code - - return self.returncode - - def poll(self): - return self.wait(timeout=0) - - def terminate(self): - if self.returncode is None: - try: - _winapi.TerminateProcess(int(self._handle), TERMINATE) - except OSError: - if self.wait(timeout=1.0) is None: - raise - - kill = terminate - - def close(self): - self.finalizer() diff --git a/python/Lib/multiprocessing/process.py b/python/Lib/multiprocessing/process.py deleted file mode 100644 index ecbbec9..0000000 --- a/python/Lib/multiprocessing/process.py +++ /dev/null @@ -1,439 +0,0 @@ -# -# Module providing the `Process` class which emulates `threading.Thread` -# -# multiprocessing/process.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -__all__ = ['BaseProcess', 'current_process', 'active_children', - 'parent_process'] - -# -# Imports -# - -import os -import sys -import signal -import itertools -import threading -from _weakrefset import WeakSet - -# -# -# - -try: - ORIGINAL_DIR = os.path.abspath(os.getcwd()) -except OSError: - ORIGINAL_DIR = None - -# -# Public functions -# - -def current_process(): - ''' - Return process object representing the current process - ''' - return _current_process - -def active_children(): - ''' - Return list of process objects corresponding to live child processes - ''' - _cleanup() - return list(_children) - - -def parent_process(): - ''' - Return process object representing the parent process - ''' - return _parent_process - -# -# -# - -def _cleanup(): - # check for processes which have finished - for p in list(_children): - if p._popen.poll() is not None: - _children.discard(p) - -# -# The `Process` class -# - -class BaseProcess(object): - ''' - Process objects represent activity that is run in a separate process - - The class is analogous to `threading.Thread` - ''' - def _Popen(self): - raise NotImplementedError - - def __init__(self, group=None, target=None, name=None, args=(), kwargs={}, - *, daemon=None): - assert group is None, 'group argument must be None for now' - count = next(_process_counter) - self._identity = _current_process._identity + (count,) - self._config = _current_process._config.copy() - self._parent_pid = os.getpid() - self._parent_name = _current_process.name - self._popen = None - self._closed = False - self._target = target - self._args = tuple(args) - self._kwargs = dict(kwargs) - self._name = name or type(self).__name__ + '-' + \ - ':'.join(str(i) for i in self._identity) - if daemon is not None: - self.daemon = daemon - _dangling.add(self) - - def _check_closed(self): - if self._closed: - raise ValueError("process object is closed") - - def run(self): - ''' - Method to be run in sub-process; can be overridden in sub-class - ''' - if self._target: - self._target(*self._args, **self._kwargs) - - def start(self): - ''' - Start child process - ''' - self._check_closed() - assert self._popen is None, 'cannot start a process twice' - assert self._parent_pid == os.getpid(), \ - 'can only start a process object created by current process' - assert not _current_process._config.get('daemon'), \ - 'daemonic processes are not allowed to have children' - _cleanup() - self._popen = self._Popen(self) - self._sentinel = self._popen.sentinel - # Avoid a refcycle if the target function holds an indirect - # reference to the process object (see bpo-30775) - del self._target, self._args, self._kwargs - _children.add(self) - - def terminate(self): - ''' - Terminate process; sends SIGTERM signal or uses TerminateProcess() - ''' - self._check_closed() - self._popen.terminate() - - def kill(self): - ''' - Terminate process; sends SIGKILL signal or uses TerminateProcess() - ''' - self._check_closed() - self._popen.kill() - - def join(self, timeout=None): - ''' - Wait until child process terminates - ''' - self._check_closed() - assert self._parent_pid == os.getpid(), 'can only join a child process' - assert self._popen is not None, 'can only join a started process' - res = self._popen.wait(timeout) - if res is not None: - _children.discard(self) - - def is_alive(self): - ''' - Return whether process is alive - ''' - self._check_closed() - if self is _current_process: - return True - assert self._parent_pid == os.getpid(), 'can only test a child process' - - if self._popen is None: - return False - - returncode = self._popen.poll() - if returncode is None: - return True - else: - _children.discard(self) - return False - - def close(self): - ''' - Close the Process object. - - This method releases resources held by the Process object. It is - an error to call this method if the child process is still running. - ''' - if self._popen is not None: - if self._popen.poll() is None: - raise ValueError("Cannot close a process while it is still running. " - "You should first call join() or terminate().") - self._popen.close() - self._popen = None - del self._sentinel - _children.discard(self) - self._closed = True - - @property - def name(self): - return self._name - - @name.setter - def name(self, name): - assert isinstance(name, str), 'name must be a string' - self._name = name - - @property - def daemon(self): - ''' - Return whether process is a daemon - ''' - return self._config.get('daemon', False) - - @daemon.setter - def daemon(self, daemonic): - ''' - Set whether process is a daemon - ''' - assert self._popen is None, 'process has already started' - self._config['daemon'] = daemonic - - @property - def authkey(self): - return self._config['authkey'] - - @authkey.setter - def authkey(self, authkey): - ''' - Set authorization key of process - ''' - self._config['authkey'] = AuthenticationString(authkey) - - @property - def exitcode(self): - ''' - Return exit code of process or `None` if it has yet to stop - ''' - self._check_closed() - if self._popen is None: - return self._popen - return self._popen.poll() - - @property - def ident(self): - ''' - Return identifier (PID) of process or `None` if it has yet to start - ''' - self._check_closed() - if self is _current_process: - return os.getpid() - else: - return self._popen and self._popen.pid - - pid = ident - - @property - def sentinel(self): - ''' - Return a file descriptor (Unix) or handle (Windows) suitable for - waiting for process termination. - ''' - self._check_closed() - try: - return self._sentinel - except AttributeError: - raise ValueError("process not started") from None - - def __repr__(self): - exitcode = None - if self is _current_process: - status = 'started' - elif self._closed: - status = 'closed' - elif self._parent_pid != os.getpid(): - status = 'unknown' - elif self._popen is None: - status = 'initial' - else: - exitcode = self._popen.poll() - if exitcode is not None: - status = 'stopped' - else: - status = 'started' - - info = [type(self).__name__, 'name=%r' % self._name] - if self._popen is not None: - info.append('pid=%s' % self._popen.pid) - info.append('parent=%s' % self._parent_pid) - info.append(status) - if exitcode is not None: - exitcode = _exitcode_to_name.get(exitcode, exitcode) - info.append('exitcode=%s' % exitcode) - if self.daemon: - info.append('daemon') - return '<%s>' % ' '.join(info) - - ## - - def _bootstrap(self, parent_sentinel=None): - from . import util, context - global _current_process, _parent_process, _process_counter, _children - - try: - if self._start_method is not None: - context._force_start_method(self._start_method) - _process_counter = itertools.count(1) - _children = set() - util._close_stdin() - old_process = _current_process - _current_process = self - _parent_process = _ParentProcess( - self._parent_name, self._parent_pid, parent_sentinel) - if threading._HAVE_THREAD_NATIVE_ID: - threading.main_thread()._set_native_id() - try: - self._after_fork() - finally: - # delay finalization of the old process object until after - # _run_after_forkers() is executed - del old_process - util.info('child process calling self.run()') - try: - self.run() - exitcode = 0 - finally: - util._exit_function() - except SystemExit as e: - if e.code is None: - exitcode = 0 - elif isinstance(e.code, int): - exitcode = e.code - else: - sys.stderr.write(str(e.code) + '\n') - exitcode = 1 - except: - exitcode = 1 - import traceback - sys.stderr.write('Process %s:\n' % self.name) - traceback.print_exc() - finally: - threading._shutdown() - util.info('process exiting with exitcode %d' % exitcode) - util._flush_std_streams() - - return exitcode - - @staticmethod - def _after_fork(): - from . import util - util._finalizer_registry.clear() - util._run_after_forkers() - - -# -# We subclass bytes to avoid accidental transmission of auth keys over network -# - -class AuthenticationString(bytes): - def __reduce__(self): - from .context import get_spawning_popen - if get_spawning_popen() is None: - raise TypeError( - 'Pickling an AuthenticationString object is ' - 'disallowed for security reasons' - ) - return AuthenticationString, (bytes(self),) - - -# -# Create object representing the parent process -# - -class _ParentProcess(BaseProcess): - - def __init__(self, name, pid, sentinel): - self._identity = () - self._name = name - self._pid = pid - self._parent_pid = None - self._popen = None - self._closed = False - self._sentinel = sentinel - self._config = {} - - def is_alive(self): - from multiprocessing.connection import wait - return not wait([self._sentinel], timeout=0) - - @property - def ident(self): - return self._pid - - def join(self, timeout=None): - ''' - Wait until parent process terminates - ''' - from multiprocessing.connection import wait - wait([self._sentinel], timeout=timeout) - - pid = ident - -# -# Create object representing the main process -# - -class _MainProcess(BaseProcess): - - def __init__(self): - self._identity = () - self._name = 'MainProcess' - self._parent_pid = None - self._popen = None - self._closed = False - self._config = {'authkey': AuthenticationString(os.urandom(32)), - 'semprefix': '/mp'} - # Note that some versions of FreeBSD only allow named - # semaphores to have names of up to 14 characters. Therefore - # we choose a short prefix. - # - # On MacOSX in a sandbox it may be necessary to use a - # different prefix -- see #19478. - # - # Everything in self._config will be inherited by descendant - # processes. - - def close(self): - pass - - -_parent_process = None -_current_process = _MainProcess() -_process_counter = itertools.count(1) -_children = set() -del _MainProcess - -# -# Give names to some return codes -# - -_exitcode_to_name = {} - -for name, signum in list(signal.__dict__.items()): - if name[:3]=='SIG' and '_' not in name: - _exitcode_to_name[-signum] = f'-{name}' -del name, signum - -# For debug and leak testing -_dangling = WeakSet() diff --git a/python/Lib/multiprocessing/queues.py b/python/Lib/multiprocessing/queues.py deleted file mode 100644 index ebc744d..0000000 --- a/python/Lib/multiprocessing/queues.py +++ /dev/null @@ -1,379 +0,0 @@ -# -# Module implementing queues -# -# multiprocessing/queues.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -__all__ = ['Queue', 'SimpleQueue', 'JoinableQueue'] - -import sys -import os -import threading -import collections -import time -import types -import weakref -import errno - -from queue import Empty, Full - -import _multiprocessing - -from . import connection -from . import context -_ForkingPickler = context.reduction.ForkingPickler - -from .util import debug, info, Finalize, register_after_fork, is_exiting - -# -# Queue type using a pipe, buffer and thread -# - -class Queue(object): - - def __init__(self, maxsize=0, *, ctx): - if maxsize <= 0: - # Can raise ImportError (see issues #3770 and #23400) - from .synchronize import SEM_VALUE_MAX as maxsize - self._maxsize = maxsize - self._reader, self._writer = connection.Pipe(duplex=False) - self._rlock = ctx.Lock() - self._opid = os.getpid() - if sys.platform == 'win32': - self._wlock = None - else: - self._wlock = ctx.Lock() - self._sem = ctx.BoundedSemaphore(maxsize) - # For use by concurrent.futures - self._ignore_epipe = False - self._reset() - - if sys.platform != 'win32': - register_after_fork(self, Queue._after_fork) - - def __getstate__(self): - context.assert_spawning(self) - return (self._ignore_epipe, self._maxsize, self._reader, self._writer, - self._rlock, self._wlock, self._sem, self._opid) - - def __setstate__(self, state): - (self._ignore_epipe, self._maxsize, self._reader, self._writer, - self._rlock, self._wlock, self._sem, self._opid) = state - self._reset() - - def _after_fork(self): - debug('Queue._after_fork()') - self._reset(after_fork=True) - - def _reset(self, after_fork=False): - if after_fork: - self._notempty._at_fork_reinit() - else: - self._notempty = threading.Condition(threading.Lock()) - self._buffer = collections.deque() - self._thread = None - self._jointhread = None - self._joincancelled = False - self._closed = False - self._close = None - self._send_bytes = self._writer.send_bytes - self._recv_bytes = self._reader.recv_bytes - self._poll = self._reader.poll - - def put(self, obj, block=True, timeout=None): - if self._closed: - raise ValueError(f"Queue {self!r} is closed") - if not self._sem.acquire(block, timeout): - raise Full - - with self._notempty: - if self._thread is None: - self._start_thread() - self._buffer.append(obj) - self._notempty.notify() - - def get(self, block=True, timeout=None): - if self._closed: - raise ValueError(f"Queue {self!r} is closed") - if block and timeout is None: - with self._rlock: - res = self._recv_bytes() - self._sem.release() - else: - if block: - deadline = time.monotonic() + timeout - if not self._rlock.acquire(block, timeout): - raise Empty - try: - if block: - timeout = deadline - time.monotonic() - if not self._poll(timeout): - raise Empty - elif not self._poll(): - raise Empty - res = self._recv_bytes() - self._sem.release() - finally: - self._rlock.release() - # unserialize the data after having released the lock - return _ForkingPickler.loads(res) - - def qsize(self): - # Raises NotImplementedError on Mac OSX because of broken sem_getvalue() - return self._maxsize - self._sem._semlock._get_value() - - def empty(self): - return not self._poll() - - def full(self): - return self._sem._semlock._is_zero() - - def get_nowait(self): - return self.get(False) - - def put_nowait(self, obj): - return self.put(obj, False) - - def close(self): - self._closed = True - close = self._close - if close: - self._close = None - close() - - def join_thread(self): - debug('Queue.join_thread()') - assert self._closed, "Queue {0!r} not closed".format(self) - if self._jointhread: - self._jointhread() - - def cancel_join_thread(self): - debug('Queue.cancel_join_thread()') - self._joincancelled = True - try: - self._jointhread.cancel() - except AttributeError: - pass - - def _start_thread(self): - debug('Queue._start_thread()') - - # Start thread which transfers data from buffer to pipe - self._buffer.clear() - self._thread = threading.Thread( - target=Queue._feed, - args=(self._buffer, self._notempty, self._send_bytes, - self._wlock, self._reader.close, self._writer.close, - self._ignore_epipe, self._on_queue_feeder_error, - self._sem), - name='QueueFeederThread' - ) - self._thread.daemon = True - - debug('doing self._thread.start()') - self._thread.start() - debug('... done self._thread.start()') - - if not self._joincancelled: - self._jointhread = Finalize( - self._thread, Queue._finalize_join, - [weakref.ref(self._thread)], - exitpriority=-5 - ) - - # Send sentinel to the thread queue object when garbage collected - self._close = Finalize( - self, Queue._finalize_close, - [self._buffer, self._notempty], - exitpriority=10 - ) - - @staticmethod - def _finalize_join(twr): - debug('joining queue thread') - thread = twr() - if thread is not None: - thread.join() - debug('... queue thread joined') - else: - debug('... queue thread already dead') - - @staticmethod - def _finalize_close(buffer, notempty): - debug('telling queue thread to quit') - with notempty: - buffer.append(_sentinel) - notempty.notify() - - @staticmethod - def _feed(buffer, notempty, send_bytes, writelock, reader_close, - writer_close, ignore_epipe, onerror, queue_sem): - debug('starting thread to feed data to pipe') - nacquire = notempty.acquire - nrelease = notempty.release - nwait = notempty.wait - bpopleft = buffer.popleft - sentinel = _sentinel - if sys.platform != 'win32': - wacquire = writelock.acquire - wrelease = writelock.release - else: - wacquire = None - - while 1: - try: - nacquire() - try: - if not buffer: - nwait() - finally: - nrelease() - try: - while 1: - obj = bpopleft() - if obj is sentinel: - debug('feeder thread got sentinel -- exiting') - reader_close() - writer_close() - return - - # serialize the data before acquiring the lock - obj = _ForkingPickler.dumps(obj) - if wacquire is None: - send_bytes(obj) - else: - wacquire() - try: - send_bytes(obj) - finally: - wrelease() - except IndexError: - pass - except Exception as e: - if ignore_epipe and getattr(e, 'errno', 0) == errno.EPIPE: - return - # Since this runs in a daemon thread the resources it uses - # may be become unusable while the process is cleaning up. - # We ignore errors which happen after the process has - # started to cleanup. - if is_exiting(): - info('error in queue thread: %s', e) - return - else: - # Since the object has not been sent in the queue, we need - # to decrease the size of the queue. The error acts as - # if the object had been silently removed from the queue - # and this step is necessary to have a properly working - # queue. - queue_sem.release() - onerror(e, obj) - - @staticmethod - def _on_queue_feeder_error(e, obj): - """ - Private API hook called when feeding data in the background thread - raises an exception. For overriding by concurrent.futures. - """ - import traceback - traceback.print_exc() - - -_sentinel = object() - -# -# A queue type which also supports join() and task_done() methods -# -# Note that if you do not call task_done() for each finished task then -# eventually the counter's semaphore may overflow causing Bad Things -# to happen. -# - -class JoinableQueue(Queue): - - def __init__(self, maxsize=0, *, ctx): - Queue.__init__(self, maxsize, ctx=ctx) - self._unfinished_tasks = ctx.Semaphore(0) - self._cond = ctx.Condition() - - def __getstate__(self): - return Queue.__getstate__(self) + (self._cond, self._unfinished_tasks) - - def __setstate__(self, state): - Queue.__setstate__(self, state[:-2]) - self._cond, self._unfinished_tasks = state[-2:] - - def put(self, obj, block=True, timeout=None): - if self._closed: - raise ValueError(f"Queue {self!r} is closed") - if not self._sem.acquire(block, timeout): - raise Full - - with self._notempty, self._cond: - if self._thread is None: - self._start_thread() - self._buffer.append(obj) - self._unfinished_tasks.release() - self._notempty.notify() - - def task_done(self): - with self._cond: - if not self._unfinished_tasks.acquire(False): - raise ValueError('task_done() called too many times') - if self._unfinished_tasks._semlock._is_zero(): - self._cond.notify_all() - - def join(self): - with self._cond: - if not self._unfinished_tasks._semlock._is_zero(): - self._cond.wait() - -# -# Simplified Queue type -- really just a locked pipe -# - -class SimpleQueue(object): - - def __init__(self, *, ctx): - self._reader, self._writer = connection.Pipe(duplex=False) - self._rlock = ctx.Lock() - self._poll = self._reader.poll - if sys.platform == 'win32': - self._wlock = None - else: - self._wlock = ctx.Lock() - - def close(self): - self._reader.close() - self._writer.close() - - def empty(self): - return not self._poll() - - def __getstate__(self): - context.assert_spawning(self) - return (self._reader, self._writer, self._rlock, self._wlock) - - def __setstate__(self, state): - (self._reader, self._writer, self._rlock, self._wlock) = state - self._poll = self._reader.poll - - def get(self): - with self._rlock: - res = self._reader.recv_bytes() - # unserialize the data after having released the lock - return _ForkingPickler.loads(res) - - def put(self, obj): - # serialize the data before acquiring the lock - obj = _ForkingPickler.dumps(obj) - if self._wlock is None: - # writes to a message oriented win32 pipe are atomic - self._writer.send_bytes(obj) - else: - with self._wlock: - self._writer.send_bytes(obj) - - __class_getitem__ = classmethod(types.GenericAlias) diff --git a/python/Lib/multiprocessing/reduction.py b/python/Lib/multiprocessing/reduction.py deleted file mode 100644 index 8c9b0c7..0000000 --- a/python/Lib/multiprocessing/reduction.py +++ /dev/null @@ -1,281 +0,0 @@ -# -# Module which deals with pickling of objects. -# -# multiprocessing/reduction.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -from abc import ABCMeta -import copyreg -import functools -import io -import os -import pickle -import socket -import sys - -from . import context - -__all__ = ['send_handle', 'recv_handle', 'ForkingPickler', 'register', 'dump'] - - -HAVE_SEND_HANDLE = (sys.platform == 'win32' or - (hasattr(socket, 'CMSG_LEN') and - hasattr(socket, 'SCM_RIGHTS') and - hasattr(socket.socket, 'sendmsg'))) - -# -# Pickler subclass -# - -class ForkingPickler(pickle.Pickler): - '''Pickler subclass used by multiprocessing.''' - _extra_reducers = {} - _copyreg_dispatch_table = copyreg.dispatch_table - - def __init__(self, *args): - super().__init__(*args) - self.dispatch_table = self._copyreg_dispatch_table.copy() - self.dispatch_table.update(self._extra_reducers) - - @classmethod - def register(cls, type, reduce): - '''Register a reduce function for a type.''' - cls._extra_reducers[type] = reduce - - @classmethod - def dumps(cls, obj, protocol=None): - buf = io.BytesIO() - cls(buf, protocol).dump(obj) - return buf.getbuffer() - - loads = pickle.loads - -register = ForkingPickler.register - -def dump(obj, file, protocol=None): - '''Replacement for pickle.dump() using ForkingPickler.''' - ForkingPickler(file, protocol).dump(obj) - -# -# Platform specific definitions -# - -if sys.platform == 'win32': - # Windows - __all__ += ['DupHandle', 'duplicate', 'steal_handle'] - import _winapi - - def duplicate(handle, target_process=None, inheritable=False, - *, source_process=None): - '''Duplicate a handle. (target_process is a handle not a pid!)''' - current_process = _winapi.GetCurrentProcess() - if source_process is None: - source_process = current_process - if target_process is None: - target_process = current_process - return _winapi.DuplicateHandle( - source_process, handle, target_process, - 0, inheritable, _winapi.DUPLICATE_SAME_ACCESS) - - def steal_handle(source_pid, handle): - '''Steal a handle from process identified by source_pid.''' - source_process_handle = _winapi.OpenProcess( - _winapi.PROCESS_DUP_HANDLE, False, source_pid) - try: - return _winapi.DuplicateHandle( - source_process_handle, handle, - _winapi.GetCurrentProcess(), 0, False, - _winapi.DUPLICATE_SAME_ACCESS | _winapi.DUPLICATE_CLOSE_SOURCE) - finally: - _winapi.CloseHandle(source_process_handle) - - def send_handle(conn, handle, destination_pid): - '''Send a handle over a local connection.''' - dh = DupHandle(handle, _winapi.DUPLICATE_SAME_ACCESS, destination_pid) - conn.send(dh) - - def recv_handle(conn): - '''Receive a handle over a local connection.''' - return conn.recv().detach() - - class DupHandle(object): - '''Picklable wrapper for a handle.''' - def __init__(self, handle, access, pid=None): - if pid is None: - # We just duplicate the handle in the current process and - # let the receiving process steal the handle. - pid = os.getpid() - proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False, pid) - try: - self._handle = _winapi.DuplicateHandle( - _winapi.GetCurrentProcess(), - handle, proc, access, False, 0) - finally: - _winapi.CloseHandle(proc) - self._access = access - self._pid = pid - - def detach(self): - '''Get the handle. This should only be called once.''' - # retrieve handle from process which currently owns it - if self._pid == os.getpid(): - # The handle has already been duplicated for this process. - return self._handle - # We must steal the handle from the process whose pid is self._pid. - proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False, - self._pid) - try: - return _winapi.DuplicateHandle( - proc, self._handle, _winapi.GetCurrentProcess(), - self._access, False, _winapi.DUPLICATE_CLOSE_SOURCE) - finally: - _winapi.CloseHandle(proc) - -else: - # Unix - __all__ += ['DupFd', 'sendfds', 'recvfds'] - import array - - # On MacOSX we should acknowledge receipt of fds -- see Issue14669 - ACKNOWLEDGE = sys.platform == 'darwin' - - def sendfds(sock, fds): - '''Send an array of fds over an AF_UNIX socket.''' - fds = array.array('i', fds) - msg = bytes([len(fds) % 256]) - sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, fds)]) - if ACKNOWLEDGE and sock.recv(1) != b'A': - raise RuntimeError('did not receive acknowledgement of fd') - - def recvfds(sock, size): - '''Receive an array of fds over an AF_UNIX socket.''' - a = array.array('i') - bytes_size = a.itemsize * size - msg, ancdata, flags, addr = sock.recvmsg(1, socket.CMSG_SPACE(bytes_size)) - if not msg and not ancdata: - raise EOFError - try: - if ACKNOWLEDGE: - sock.send(b'A') - if len(ancdata) != 1: - raise RuntimeError('received %d items of ancdata' % - len(ancdata)) - cmsg_level, cmsg_type, cmsg_data = ancdata[0] - if (cmsg_level == socket.SOL_SOCKET and - cmsg_type == socket.SCM_RIGHTS): - if len(cmsg_data) % a.itemsize != 0: - raise ValueError - a.frombytes(cmsg_data) - if len(a) % 256 != msg[0]: - raise AssertionError( - "Len is {0:n} but msg[0] is {1!r}".format( - len(a), msg[0])) - return list(a) - except (ValueError, IndexError): - pass - raise RuntimeError('Invalid data received') - - def send_handle(conn, handle, destination_pid): - '''Send a handle over a local connection.''' - with socket.fromfd(conn.fileno(), socket.AF_UNIX, socket.SOCK_STREAM) as s: - sendfds(s, [handle]) - - def recv_handle(conn): - '''Receive a handle over a local connection.''' - with socket.fromfd(conn.fileno(), socket.AF_UNIX, socket.SOCK_STREAM) as s: - return recvfds(s, 1)[0] - - def DupFd(fd): - '''Return a wrapper for an fd.''' - popen_obj = context.get_spawning_popen() - if popen_obj is not None: - return popen_obj.DupFd(popen_obj.duplicate_for_child(fd)) - elif HAVE_SEND_HANDLE: - from . import resource_sharer - return resource_sharer.DupFd(fd) - else: - raise ValueError('SCM_RIGHTS appears not to be available') - -# -# Try making some callable types picklable -# - -def _reduce_method(m): - if m.__self__ is None: - return getattr, (m.__class__, m.__func__.__name__) - else: - return getattr, (m.__self__, m.__func__.__name__) -class _C: - def f(self): - pass -register(type(_C().f), _reduce_method) - - -def _reduce_method_descriptor(m): - return getattr, (m.__objclass__, m.__name__) -register(type(list.append), _reduce_method_descriptor) -register(type(int.__add__), _reduce_method_descriptor) - - -def _reduce_partial(p): - return _rebuild_partial, (p.func, p.args, p.keywords or {}) -def _rebuild_partial(func, args, keywords): - return functools.partial(func, *args, **keywords) -register(functools.partial, _reduce_partial) - -# -# Make sockets picklable -# - -if sys.platform == 'win32': - def _reduce_socket(s): - from .resource_sharer import DupSocket - return _rebuild_socket, (DupSocket(s),) - def _rebuild_socket(ds): - return ds.detach() - register(socket.socket, _reduce_socket) - -else: - def _reduce_socket(s): - df = DupFd(s.fileno()) - return _rebuild_socket, (df, s.family, s.type, s.proto) - def _rebuild_socket(df, family, type, proto): - fd = df.detach() - return socket.socket(family, type, proto, fileno=fd) - register(socket.socket, _reduce_socket) - - -class AbstractReducer(metaclass=ABCMeta): - '''Abstract base class for use in implementing a Reduction class - suitable for use in replacing the standard reduction mechanism - used in multiprocessing.''' - ForkingPickler = ForkingPickler - register = register - dump = dump - send_handle = send_handle - recv_handle = recv_handle - - if sys.platform == 'win32': - steal_handle = steal_handle - duplicate = duplicate - DupHandle = DupHandle - else: - sendfds = sendfds - recvfds = recvfds - DupFd = DupFd - - _reduce_method = _reduce_method - _reduce_method_descriptor = _reduce_method_descriptor - _rebuild_partial = _rebuild_partial - _reduce_socket = _reduce_socket - _rebuild_socket = _rebuild_socket - - def __init__(self, *args): - register(type(_C().f), _reduce_method) - register(type(list.append), _reduce_method_descriptor) - register(type(int.__add__), _reduce_method_descriptor) - register(functools.partial, _reduce_partial) - register(socket.socket, _reduce_socket) diff --git a/python/Lib/multiprocessing/resource_sharer.py b/python/Lib/multiprocessing/resource_sharer.py deleted file mode 100644 index 9234b06..0000000 --- a/python/Lib/multiprocessing/resource_sharer.py +++ /dev/null @@ -1,154 +0,0 @@ -# -# We use a background thread for sharing fds on Unix, and for sharing sockets on -# Windows. -# -# A client which wants to pickle a resource registers it with the resource -# sharer and gets an identifier in return. The unpickling process will connect -# to the resource sharer, sends the identifier and its pid, and then receives -# the resource. -# - -import os -import signal -import socket -import sys -import threading - -from . import process -from .context import reduction -from . import util - -__all__ = ['stop'] - - -if sys.platform == 'win32': - __all__ += ['DupSocket'] - - class DupSocket(object): - '''Picklable wrapper for a socket.''' - def __init__(self, sock): - new_sock = sock.dup() - def send(conn, pid): - share = new_sock.share(pid) - conn.send_bytes(share) - self._id = _resource_sharer.register(send, new_sock.close) - - def detach(self): - '''Get the socket. This should only be called once.''' - with _resource_sharer.get_connection(self._id) as conn: - share = conn.recv_bytes() - return socket.fromshare(share) - -else: - __all__ += ['DupFd'] - - class DupFd(object): - '''Wrapper for fd which can be used at any time.''' - def __init__(self, fd): - new_fd = os.dup(fd) - def send(conn, pid): - reduction.send_handle(conn, new_fd, pid) - def close(): - os.close(new_fd) - self._id = _resource_sharer.register(send, close) - - def detach(self): - '''Get the fd. This should only be called once.''' - with _resource_sharer.get_connection(self._id) as conn: - return reduction.recv_handle(conn) - - -class _ResourceSharer(object): - '''Manager for resources using background thread.''' - def __init__(self): - self._key = 0 - self._cache = {} - self._lock = threading.Lock() - self._listener = None - self._address = None - self._thread = None - util.register_after_fork(self, _ResourceSharer._afterfork) - - def register(self, send, close): - '''Register resource, returning an identifier.''' - with self._lock: - if self._address is None: - self._start() - self._key += 1 - self._cache[self._key] = (send, close) - return (self._address, self._key) - - @staticmethod - def get_connection(ident): - '''Return connection from which to receive identified resource.''' - from .connection import Client - address, key = ident - c = Client(address, authkey=process.current_process().authkey) - c.send((key, os.getpid())) - return c - - def stop(self, timeout=None): - '''Stop the background thread and clear registered resources.''' - from .connection import Client - with self._lock: - if self._address is not None: - c = Client(self._address, - authkey=process.current_process().authkey) - c.send(None) - c.close() - self._thread.join(timeout) - if self._thread.is_alive(): - util.sub_warning('_ResourceSharer thread did ' - 'not stop when asked') - self._listener.close() - self._thread = None - self._address = None - self._listener = None - for key, (send, close) in self._cache.items(): - close() - self._cache.clear() - - def _afterfork(self): - for key, (send, close) in self._cache.items(): - close() - self._cache.clear() - self._lock._at_fork_reinit() - if self._listener is not None: - self._listener.close() - self._listener = None - self._address = None - self._thread = None - - def _start(self): - from .connection import Listener - assert self._listener is None, "Already have Listener" - util.debug('starting listener and thread for sending handles') - self._listener = Listener(authkey=process.current_process().authkey) - self._address = self._listener.address - t = threading.Thread(target=self._serve) - t.daemon = True - t.start() - self._thread = t - - def _serve(self): - if hasattr(signal, 'pthread_sigmask'): - signal.pthread_sigmask(signal.SIG_BLOCK, signal.valid_signals()) - while 1: - try: - with self._listener.accept() as conn: - msg = conn.recv() - if msg is None: - break - key, destination_pid = msg - send, close = self._cache.pop(key) - try: - send(conn, destination_pid) - finally: - close() - except: - if not util.is_exiting(): - sys.excepthook(*sys.exc_info()) - - -_resource_sharer = _ResourceSharer() -stop = _resource_sharer.stop diff --git a/python/Lib/multiprocessing/resource_tracker.py b/python/Lib/multiprocessing/resource_tracker.py deleted file mode 100644 index 9cadffa..0000000 --- a/python/Lib/multiprocessing/resource_tracker.py +++ /dev/null @@ -1,239 +0,0 @@ -############################################################################### -# Server process to keep track of unlinked resources (like shared memory -# segments, semaphores etc.) and clean them. -# -# On Unix we run a server process which keeps track of unlinked -# resources. The server ignores SIGINT and SIGTERM and reads from a -# pipe. Every other process of the program has a copy of the writable -# end of the pipe, so we get EOF when all other processes have exited. -# Then the server process unlinks any remaining resource names. -# -# This is important because there may be system limits for such resources: for -# instance, the system only supports a limited number of named semaphores, and -# shared-memory segments live in the RAM. If a python process leaks such a -# resource, this resource will not be removed till the next reboot. Without -# this resource tracker process, "killall python" would probably leave unlinked -# resources. - -import os -import signal -import sys -import threading -import warnings - -from . import spawn -from . import util - -__all__ = ['ensure_running', 'register', 'unregister'] - -_HAVE_SIGMASK = hasattr(signal, 'pthread_sigmask') -_IGNORED_SIGNALS = (signal.SIGINT, signal.SIGTERM) - -_CLEANUP_FUNCS = { - 'noop': lambda: None, -} - -if os.name == 'posix': - import _multiprocessing - import _posixshmem - - # Use sem_unlink() to clean up named semaphores. - # - # sem_unlink() may be missing if the Python build process detected the - # absence of POSIX named semaphores. In that case, no named semaphores were - # ever opened, so no cleanup would be necessary. - if hasattr(_multiprocessing, 'sem_unlink'): - _CLEANUP_FUNCS.update({ - 'semaphore': _multiprocessing.sem_unlink, - }) - _CLEANUP_FUNCS.update({ - 'shared_memory': _posixshmem.shm_unlink, - }) - - -class ResourceTracker(object): - - def __init__(self): - self._lock = threading.Lock() - self._fd = None - self._pid = None - - def _stop(self): - with self._lock: - if self._fd is None: - # not running - return - - # closing the "alive" file descriptor stops main() - os.close(self._fd) - self._fd = None - - os.waitpid(self._pid, 0) - self._pid = None - - def getfd(self): - self.ensure_running() - return self._fd - - def ensure_running(self): - '''Make sure that resource tracker process is running. - - This can be run from any process. Usually a child process will use - the resource created by its parent.''' - with self._lock: - if self._fd is not None: - # resource tracker was launched before, is it still running? - if self._check_alive(): - # => still alive - return - # => dead, launch it again - os.close(self._fd) - - # Clean-up to avoid dangling processes. - try: - # _pid can be None if this process is a child from another - # python process, which has started the resource_tracker. - if self._pid is not None: - os.waitpid(self._pid, 0) - except ChildProcessError: - # The resource_tracker has already been terminated. - pass - self._fd = None - self._pid = None - - warnings.warn('resource_tracker: process died unexpectedly, ' - 'relaunching. Some resources might leak.') - - fds_to_pass = [] - try: - fds_to_pass.append(sys.stderr.fileno()) - except Exception: - pass - cmd = 'from multiprocessing.resource_tracker import main;main(%d)' - r, w = os.pipe() - try: - fds_to_pass.append(r) - # process will out live us, so no need to wait on pid - exe = spawn.get_executable() - args = [exe] + util._args_from_interpreter_flags() - args += ['-c', cmd % r] - # bpo-33613: Register a signal mask that will block the signals. - # This signal mask will be inherited by the child that is going - # to be spawned and will protect the child from a race condition - # that can make the child die before it registers signal handlers - # for SIGINT and SIGTERM. The mask is unregistered after spawning - # the child. - try: - if _HAVE_SIGMASK: - signal.pthread_sigmask(signal.SIG_BLOCK, _IGNORED_SIGNALS) - pid = util.spawnv_passfds(exe, args, fds_to_pass) - finally: - if _HAVE_SIGMASK: - signal.pthread_sigmask(signal.SIG_UNBLOCK, _IGNORED_SIGNALS) - except: - os.close(w) - raise - else: - self._fd = w - self._pid = pid - finally: - os.close(r) - - def _check_alive(self): - '''Check that the pipe has not been closed by sending a probe.''' - try: - # We cannot use send here as it calls ensure_running, creating - # a cycle. - os.write(self._fd, b'PROBE:0:noop\n') - except OSError: - return False - else: - return True - - def register(self, name, rtype): - '''Register name of resource with resource tracker.''' - self._send('REGISTER', name, rtype) - - def unregister(self, name, rtype): - '''Unregister name of resource with resource tracker.''' - self._send('UNREGISTER', name, rtype) - - def _send(self, cmd, name, rtype): - self.ensure_running() - msg = '{0}:{1}:{2}\n'.format(cmd, name, rtype).encode('ascii') - if len(msg) > 512: - # posix guarantees that writes to a pipe of less than PIPE_BUF - # bytes are atomic, and that PIPE_BUF >= 512 - raise ValueError('msg too long') - nbytes = os.write(self._fd, msg) - assert nbytes == len(msg), "nbytes {0:n} but len(msg) {1:n}".format( - nbytes, len(msg)) - - -_resource_tracker = ResourceTracker() -ensure_running = _resource_tracker.ensure_running -register = _resource_tracker.register -unregister = _resource_tracker.unregister -getfd = _resource_tracker.getfd - -def main(fd): - '''Run resource tracker.''' - # protect the process from ^C and "killall python" etc - signal.signal(signal.SIGINT, signal.SIG_IGN) - signal.signal(signal.SIGTERM, signal.SIG_IGN) - if _HAVE_SIGMASK: - signal.pthread_sigmask(signal.SIG_UNBLOCK, _IGNORED_SIGNALS) - - for f in (sys.stdin, sys.stdout): - try: - f.close() - except Exception: - pass - - cache = {rtype: set() for rtype in _CLEANUP_FUNCS.keys()} - try: - # keep track of registered/unregistered resources - with open(fd, 'rb') as f: - for line in f: - try: - cmd, name, rtype = line.strip().decode('ascii').split(':') - cleanup_func = _CLEANUP_FUNCS.get(rtype, None) - if cleanup_func is None: - raise ValueError( - f'Cannot register {name} for automatic cleanup: ' - f'unknown resource type {rtype}') - - if cmd == 'REGISTER': - cache[rtype].add(name) - elif cmd == 'UNREGISTER': - cache[rtype].remove(name) - elif cmd == 'PROBE': - pass - else: - raise RuntimeError('unrecognized command %r' % cmd) - except Exception: - try: - sys.excepthook(*sys.exc_info()) - except: - pass - finally: - # all processes have terminated; cleanup any remaining resources - for rtype, rtype_cache in cache.items(): - if rtype_cache: - try: - warnings.warn('resource_tracker: There appear to be %d ' - 'leaked %s objects to clean up at shutdown' % - (len(rtype_cache), rtype)) - except Exception: - pass - for name in rtype_cache: - # For some reason the process which created and registered this - # resource has failed to unregister it. Presumably it has - # died. We therefore unlink it. - try: - try: - _CLEANUP_FUNCS[rtype](name) - except Exception as e: - warnings.warn('resource_tracker: %r: %s' % (name, e)) - finally: - pass diff --git a/python/Lib/multiprocessing/shared_memory.py b/python/Lib/multiprocessing/shared_memory.py deleted file mode 100644 index 90f4ecb..0000000 --- a/python/Lib/multiprocessing/shared_memory.py +++ /dev/null @@ -1,534 +0,0 @@ -"""Provides shared memory for direct access across processes. - -The API of this package is currently provisional. Refer to the -documentation for details. -""" - - -__all__ = [ 'SharedMemory', 'ShareableList' ] - - -from functools import partial -import mmap -import os -import errno -import struct -import secrets -import types - -if os.name == "nt": - import _winapi - _USE_POSIX = False -else: - import _posixshmem - _USE_POSIX = True - -from . import resource_tracker - -_O_CREX = os.O_CREAT | os.O_EXCL - -# FreeBSD (and perhaps other BSDs) limit names to 14 characters. -_SHM_SAFE_NAME_LENGTH = 14 - -# Shared memory block name prefix -if _USE_POSIX: - _SHM_NAME_PREFIX = '/psm_' -else: - _SHM_NAME_PREFIX = 'wnsm_' - - -def _make_filename(): - "Create a random filename for the shared memory object." - # number of random bytes to use for name - nbytes = (_SHM_SAFE_NAME_LENGTH - len(_SHM_NAME_PREFIX)) // 2 - assert nbytes >= 2, '_SHM_NAME_PREFIX too long' - name = _SHM_NAME_PREFIX + secrets.token_hex(nbytes) - assert len(name) <= _SHM_SAFE_NAME_LENGTH - return name - - -class SharedMemory: - """Creates a new shared memory block or attaches to an existing - shared memory block. - - Every shared memory block is assigned a unique name. This enables - one process to create a shared memory block with a particular name - so that a different process can attach to that same shared memory - block using that same name. - - As a resource for sharing data across processes, shared memory blocks - may outlive the original process that created them. When one process - no longer needs access to a shared memory block that might still be - needed by other processes, the close() method should be called. - When a shared memory block is no longer needed by any process, the - unlink() method should be called to ensure proper cleanup.""" - - # Defaults; enables close() and unlink() to run without errors. - _name = None - _fd = -1 - _mmap = None - _buf = None - _flags = os.O_RDWR - _mode = 0o600 - _prepend_leading_slash = True if _USE_POSIX else False - - def __init__(self, name=None, create=False, size=0): - if not size >= 0: - raise ValueError("'size' must be a positive integer") - if create: - self._flags = _O_CREX | os.O_RDWR - if size == 0: - raise ValueError("'size' must be a positive number different from zero") - if name is None and not self._flags & os.O_EXCL: - raise ValueError("'name' can only be None if create=True") - - if _USE_POSIX: - - # POSIX Shared Memory - - if name is None: - while True: - name = _make_filename() - try: - self._fd = _posixshmem.shm_open( - name, - self._flags, - mode=self._mode - ) - except FileExistsError: - continue - self._name = name - break - else: - name = "/" + name if self._prepend_leading_slash else name - self._fd = _posixshmem.shm_open( - name, - self._flags, - mode=self._mode - ) - self._name = name - try: - if create and size: - os.ftruncate(self._fd, size) - stats = os.fstat(self._fd) - size = stats.st_size - self._mmap = mmap.mmap(self._fd, size) - except OSError: - self.unlink() - raise - - resource_tracker.register(self._name, "shared_memory") - - else: - - # Windows Named Shared Memory - - if create: - while True: - temp_name = _make_filename() if name is None else name - # Create and reserve shared memory block with this name - # until it can be attached to by mmap. - h_map = _winapi.CreateFileMapping( - _winapi.INVALID_HANDLE_VALUE, - _winapi.NULL, - _winapi.PAGE_READWRITE, - (size >> 32) & 0xFFFFFFFF, - size & 0xFFFFFFFF, - temp_name - ) - try: - last_error_code = _winapi.GetLastError() - if last_error_code == _winapi.ERROR_ALREADY_EXISTS: - if name is not None: - raise FileExistsError( - errno.EEXIST, - os.strerror(errno.EEXIST), - name, - _winapi.ERROR_ALREADY_EXISTS - ) - else: - continue - self._mmap = mmap.mmap(-1, size, tagname=temp_name) - finally: - _winapi.CloseHandle(h_map) - self._name = temp_name - break - - else: - self._name = name - # Dynamically determine the existing named shared memory - # block's size which is likely a multiple of mmap.PAGESIZE. - h_map = _winapi.OpenFileMapping( - _winapi.FILE_MAP_READ, - False, - name - ) - try: - p_buf = _winapi.MapViewOfFile( - h_map, - _winapi.FILE_MAP_READ, - 0, - 0, - 0 - ) - finally: - _winapi.CloseHandle(h_map) - try: - size = _winapi.VirtualQuerySize(p_buf) - finally: - _winapi.UnmapViewOfFile(p_buf) - self._mmap = mmap.mmap(-1, size, tagname=name) - - self._size = size - self._buf = memoryview(self._mmap) - - def __del__(self): - try: - self.close() - except OSError: - pass - - def __reduce__(self): - return ( - self.__class__, - ( - self.name, - False, - self.size, - ), - ) - - def __repr__(self): - return f'{self.__class__.__name__}({self.name!r}, size={self.size})' - - @property - def buf(self): - "A memoryview of contents of the shared memory block." - return self._buf - - @property - def name(self): - "Unique name that identifies the shared memory block." - reported_name = self._name - if _USE_POSIX and self._prepend_leading_slash: - if self._name.startswith("/"): - reported_name = self._name[1:] - return reported_name - - @property - def size(self): - "Size in bytes." - return self._size - - def close(self): - """Closes access to the shared memory from this instance but does - not destroy the shared memory block.""" - if self._buf is not None: - self._buf.release() - self._buf = None - if self._mmap is not None: - self._mmap.close() - self._mmap = None - if _USE_POSIX and self._fd >= 0: - os.close(self._fd) - self._fd = -1 - - def unlink(self): - """Requests that the underlying shared memory block be destroyed. - - In order to ensure proper cleanup of resources, unlink should be - called once (and only once) across all processes which have access - to the shared memory block.""" - if _USE_POSIX and self._name: - _posixshmem.shm_unlink(self._name) - resource_tracker.unregister(self._name, "shared_memory") - - -_encoding = "utf8" - -class ShareableList: - """Pattern for a mutable list-like object shareable via a shared - memory block. It differs from the built-in list type in that these - lists can not change their overall length (i.e. no append, insert, - etc.) - - Because values are packed into a memoryview as bytes, the struct - packing format for any storable value must require no more than 8 - characters to describe its format.""" - - # The shared memory area is organized as follows: - # - 8 bytes: number of items (N) as a 64-bit integer - # - (N + 1) * 8 bytes: offsets of each element from the start of the - # data area - # - K bytes: the data area storing item values (with encoding and size - # depending on their respective types) - # - N * 8 bytes: `struct` format string for each element - # - N bytes: index into _back_transforms_mapping for each element - # (for reconstructing the corresponding Python value) - _types_mapping = { - int: "q", - float: "d", - bool: "xxxxxxx?", - str: "%ds", - bytes: "%ds", - None.__class__: "xxxxxx?x", - } - _alignment = 8 - _back_transforms_mapping = { - 0: lambda value: value, # int, float, bool - 1: lambda value: value.rstrip(b'\x00').decode(_encoding), # str - 2: lambda value: value.rstrip(b'\x00'), # bytes - 3: lambda _value: None, # None - } - - @staticmethod - def _extract_recreation_code(value): - """Used in concert with _back_transforms_mapping to convert values - into the appropriate Python objects when retrieving them from - the list as well as when storing them.""" - if not isinstance(value, (str, bytes, None.__class__)): - return 0 - elif isinstance(value, str): - return 1 - elif isinstance(value, bytes): - return 2 - else: - return 3 # NoneType - - def __init__(self, sequence=None, *, name=None): - if name is None or sequence is not None: - sequence = sequence or () - _formats = [ - self._types_mapping[type(item)] - if not isinstance(item, (str, bytes)) - else self._types_mapping[type(item)] % ( - self._alignment * (len(item) // self._alignment + 1), - ) - for item in sequence - ] - self._list_len = len(_formats) - assert sum(len(fmt) <= 8 for fmt in _formats) == self._list_len - offset = 0 - # The offsets of each list element into the shared memory's - # data area (0 meaning the start of the data area, not the start - # of the shared memory area). - self._allocated_offsets = [0] - for fmt in _formats: - offset += self._alignment if fmt[-1] != "s" else int(fmt[:-1]) - self._allocated_offsets.append(offset) - _recreation_codes = [ - self._extract_recreation_code(item) for item in sequence - ] - requested_size = struct.calcsize( - "q" + self._format_size_metainfo + - "".join(_formats) + - self._format_packing_metainfo + - self._format_back_transform_codes - ) - - self.shm = SharedMemory(name, create=True, size=requested_size) - else: - self.shm = SharedMemory(name) - - if sequence is not None: - _enc = _encoding - struct.pack_into( - "q" + self._format_size_metainfo, - self.shm.buf, - 0, - self._list_len, - *(self._allocated_offsets) - ) - struct.pack_into( - "".join(_formats), - self.shm.buf, - self._offset_data_start, - *(v.encode(_enc) if isinstance(v, str) else v for v in sequence) - ) - struct.pack_into( - self._format_packing_metainfo, - self.shm.buf, - self._offset_packing_formats, - *(v.encode(_enc) for v in _formats) - ) - struct.pack_into( - self._format_back_transform_codes, - self.shm.buf, - self._offset_back_transform_codes, - *(_recreation_codes) - ) - - else: - self._list_len = len(self) # Obtains size from offset 0 in buffer. - self._allocated_offsets = list( - struct.unpack_from( - self._format_size_metainfo, - self.shm.buf, - 1 * 8 - ) - ) - - def _get_packing_format(self, position): - "Gets the packing format for a single value stored in the list." - position = position if position >= 0 else position + self._list_len - if (position >= self._list_len) or (self._list_len < 0): - raise IndexError("Requested position out of range.") - - v = struct.unpack_from( - "8s", - self.shm.buf, - self._offset_packing_formats + position * 8 - )[0] - fmt = v.rstrip(b'\x00') - fmt_as_str = fmt.decode(_encoding) - - return fmt_as_str - - def _get_back_transform(self, position): - "Gets the back transformation function for a single value." - - if (position >= self._list_len) or (self._list_len < 0): - raise IndexError("Requested position out of range.") - - transform_code = struct.unpack_from( - "b", - self.shm.buf, - self._offset_back_transform_codes + position - )[0] - transform_function = self._back_transforms_mapping[transform_code] - - return transform_function - - def _set_packing_format_and_transform(self, position, fmt_as_str, value): - """Sets the packing format and back transformation code for a - single value in the list at the specified position.""" - - if (position >= self._list_len) or (self._list_len < 0): - raise IndexError("Requested position out of range.") - - struct.pack_into( - "8s", - self.shm.buf, - self._offset_packing_formats + position * 8, - fmt_as_str.encode(_encoding) - ) - - transform_code = self._extract_recreation_code(value) - struct.pack_into( - "b", - self.shm.buf, - self._offset_back_transform_codes + position, - transform_code - ) - - def __getitem__(self, position): - position = position if position >= 0 else position + self._list_len - try: - offset = self._offset_data_start + self._allocated_offsets[position] - (v,) = struct.unpack_from( - self._get_packing_format(position), - self.shm.buf, - offset - ) - except IndexError: - raise IndexError("index out of range") - - back_transform = self._get_back_transform(position) - v = back_transform(v) - - return v - - def __setitem__(self, position, value): - position = position if position >= 0 else position + self._list_len - try: - item_offset = self._allocated_offsets[position] - offset = self._offset_data_start + item_offset - current_format = self._get_packing_format(position) - except IndexError: - raise IndexError("assignment index out of range") - - if not isinstance(value, (str, bytes)): - new_format = self._types_mapping[type(value)] - encoded_value = value - else: - allocated_length = self._allocated_offsets[position + 1] - item_offset - - encoded_value = (value.encode(_encoding) - if isinstance(value, str) else value) - if len(encoded_value) > allocated_length: - raise ValueError("bytes/str item exceeds available storage") - if current_format[-1] == "s": - new_format = current_format - else: - new_format = self._types_mapping[str] % ( - allocated_length, - ) - - self._set_packing_format_and_transform( - position, - new_format, - value - ) - struct.pack_into(new_format, self.shm.buf, offset, encoded_value) - - def __reduce__(self): - return partial(self.__class__, name=self.shm.name), () - - def __len__(self): - return struct.unpack_from("q", self.shm.buf, 0)[0] - - def __repr__(self): - return f'{self.__class__.__name__}({list(self)}, name={self.shm.name!r})' - - @property - def format(self): - "The struct packing format used by all currently stored items." - return "".join( - self._get_packing_format(i) for i in range(self._list_len) - ) - - @property - def _format_size_metainfo(self): - "The struct packing format used for the items' storage offsets." - return "q" * (self._list_len + 1) - - @property - def _format_packing_metainfo(self): - "The struct packing format used for the items' packing formats." - return "8s" * self._list_len - - @property - def _format_back_transform_codes(self): - "The struct packing format used for the items' back transforms." - return "b" * self._list_len - - @property - def _offset_data_start(self): - # - 8 bytes for the list length - # - (N + 1) * 8 bytes for the element offsets - return (self._list_len + 2) * 8 - - @property - def _offset_packing_formats(self): - return self._offset_data_start + self._allocated_offsets[-1] - - @property - def _offset_back_transform_codes(self): - return self._offset_packing_formats + self._list_len * 8 - - def count(self, value): - "L.count(value) -> integer -- return number of occurrences of value." - - return sum(value == entry for entry in self) - - def index(self, value): - """L.index(value) -> integer -- return first index of value. - Raises ValueError if the value is not present.""" - - for position, entry in enumerate(self): - if value == entry: - return position - else: - raise ValueError(f"{value!r} not in this container") - - __class_getitem__ = classmethod(types.GenericAlias) diff --git a/python/Lib/multiprocessing/sharedctypes.py b/python/Lib/multiprocessing/sharedctypes.py deleted file mode 100644 index d0b51ec..0000000 --- a/python/Lib/multiprocessing/sharedctypes.py +++ /dev/null @@ -1,240 +0,0 @@ -# -# Module which supports allocation of ctypes objects from shared memory -# -# multiprocessing/sharedctypes.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -import ctypes -import weakref - -from . import heap -from . import get_context - -from .context import reduction, assert_spawning -_ForkingPickler = reduction.ForkingPickler - -__all__ = ['RawValue', 'RawArray', 'Value', 'Array', 'copy', 'synchronized'] - -# -# -# - -typecode_to_type = { - 'c': ctypes.c_char, 'u': ctypes.c_wchar, - 'b': ctypes.c_byte, 'B': ctypes.c_ubyte, - 'h': ctypes.c_short, 'H': ctypes.c_ushort, - 'i': ctypes.c_int, 'I': ctypes.c_uint, - 'l': ctypes.c_long, 'L': ctypes.c_ulong, - 'q': ctypes.c_longlong, 'Q': ctypes.c_ulonglong, - 'f': ctypes.c_float, 'd': ctypes.c_double - } - -# -# -# - -def _new_value(type_): - size = ctypes.sizeof(type_) - wrapper = heap.BufferWrapper(size) - return rebuild_ctype(type_, wrapper, None) - -def RawValue(typecode_or_type, *args): - ''' - Returns a ctypes object allocated from shared memory - ''' - type_ = typecode_to_type.get(typecode_or_type, typecode_or_type) - obj = _new_value(type_) - ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj)) - obj.__init__(*args) - return obj - -def RawArray(typecode_or_type, size_or_initializer): - ''' - Returns a ctypes array allocated from shared memory - ''' - type_ = typecode_to_type.get(typecode_or_type, typecode_or_type) - if isinstance(size_or_initializer, int): - type_ = type_ * size_or_initializer - obj = _new_value(type_) - ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj)) - return obj - else: - type_ = type_ * len(size_or_initializer) - result = _new_value(type_) - result.__init__(*size_or_initializer) - return result - -def Value(typecode_or_type, *args, lock=True, ctx=None): - ''' - Return a synchronization wrapper for a Value - ''' - obj = RawValue(typecode_or_type, *args) - if lock is False: - return obj - if lock in (True, None): - ctx = ctx or get_context() - lock = ctx.RLock() - if not hasattr(lock, 'acquire'): - raise AttributeError("%r has no method 'acquire'" % lock) - return synchronized(obj, lock, ctx=ctx) - -def Array(typecode_or_type, size_or_initializer, *, lock=True, ctx=None): - ''' - Return a synchronization wrapper for a RawArray - ''' - obj = RawArray(typecode_or_type, size_or_initializer) - if lock is False: - return obj - if lock in (True, None): - ctx = ctx or get_context() - lock = ctx.RLock() - if not hasattr(lock, 'acquire'): - raise AttributeError("%r has no method 'acquire'" % lock) - return synchronized(obj, lock, ctx=ctx) - -def copy(obj): - new_obj = _new_value(type(obj)) - ctypes.pointer(new_obj)[0] = obj - return new_obj - -def synchronized(obj, lock=None, ctx=None): - assert not isinstance(obj, SynchronizedBase), 'object already synchronized' - ctx = ctx or get_context() - - if isinstance(obj, ctypes._SimpleCData): - return Synchronized(obj, lock, ctx) - elif isinstance(obj, ctypes.Array): - if obj._type_ is ctypes.c_char: - return SynchronizedString(obj, lock, ctx) - return SynchronizedArray(obj, lock, ctx) - else: - cls = type(obj) - try: - scls = class_cache[cls] - except KeyError: - names = [field[0] for field in cls._fields_] - d = {name: make_property(name) for name in names} - classname = 'Synchronized' + cls.__name__ - scls = class_cache[cls] = type(classname, (SynchronizedBase,), d) - return scls(obj, lock, ctx) - -# -# Functions for pickling/unpickling -# - -def reduce_ctype(obj): - assert_spawning(obj) - if isinstance(obj, ctypes.Array): - return rebuild_ctype, (obj._type_, obj._wrapper, obj._length_) - else: - return rebuild_ctype, (type(obj), obj._wrapper, None) - -def rebuild_ctype(type_, wrapper, length): - if length is not None: - type_ = type_ * length - _ForkingPickler.register(type_, reduce_ctype) - buf = wrapper.create_memoryview() - obj = type_.from_buffer(buf) - obj._wrapper = wrapper - return obj - -# -# Function to create properties -# - -def make_property(name): - try: - return prop_cache[name] - except KeyError: - d = {} - exec(template % ((name,)*7), d) - prop_cache[name] = d[name] - return d[name] - -template = ''' -def get%s(self): - self.acquire() - try: - return self._obj.%s - finally: - self.release() -def set%s(self, value): - self.acquire() - try: - self._obj.%s = value - finally: - self.release() -%s = property(get%s, set%s) -''' - -prop_cache = {} -class_cache = weakref.WeakKeyDictionary() - -# -# Synchronized wrappers -# - -class SynchronizedBase(object): - - def __init__(self, obj, lock=None, ctx=None): - self._obj = obj - if lock: - self._lock = lock - else: - ctx = ctx or get_context(force=True) - self._lock = ctx.RLock() - self.acquire = self._lock.acquire - self.release = self._lock.release - - def __enter__(self): - return self._lock.__enter__() - - def __exit__(self, *args): - return self._lock.__exit__(*args) - - def __reduce__(self): - assert_spawning(self) - return synchronized, (self._obj, self._lock) - - def get_obj(self): - return self._obj - - def get_lock(self): - return self._lock - - def __repr__(self): - return '<%s wrapper for %s>' % (type(self).__name__, self._obj) - - -class Synchronized(SynchronizedBase): - value = make_property('value') - - -class SynchronizedArray(SynchronizedBase): - - def __len__(self): - return len(self._obj) - - def __getitem__(self, i): - with self: - return self._obj[i] - - def __setitem__(self, i, value): - with self: - self._obj[i] = value - - def __getslice__(self, start, stop): - with self: - return self._obj[start:stop] - - def __setslice__(self, start, stop, values): - with self: - self._obj[start:stop] = values - - -class SynchronizedString(SynchronizedArray): - value = make_property('value') - raw = make_property('raw') diff --git a/python/Lib/multiprocessing/spawn.py b/python/Lib/multiprocessing/spawn.py deleted file mode 100644 index d535c49..0000000 --- a/python/Lib/multiprocessing/spawn.py +++ /dev/null @@ -1,301 +0,0 @@ -# -# Code used to start processes when using the spawn or forkserver -# start methods. -# -# multiprocessing/spawn.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -import os -import sys -import runpy -import types - -from . import get_start_method, set_start_method -from . import process -from .context import reduction -from . import util - -__all__ = ['_main', 'freeze_support', 'set_executable', 'get_executable', - 'get_preparation_data', 'get_command_line', 'import_main_path'] - -# -# _python_exe is the assumed path to the python executable. -# People embedding Python want to modify it. -# - -if sys.platform != 'win32': - WINEXE = False - WINSERVICE = False -else: - WINEXE = getattr(sys, 'frozen', False) - WINSERVICE = sys.executable.lower().endswith("pythonservice.exe") - -def set_executable(exe): - global _python_exe - if sys.platform == 'win32': - _python_exe = os.fsdecode(exe) - else: - _python_exe = os.fsencode(exe) - -def get_executable(): - return _python_exe - -if WINSERVICE: - set_executable(os.path.join(sys.exec_prefix, 'python.exe')) -else: - set_executable(sys.executable) - -# -# -# - -def is_forking(argv): - ''' - Return whether commandline indicates we are forking - ''' - if len(argv) >= 2 and argv[1] == '--multiprocessing-fork': - return True - else: - return False - - -def freeze_support(): - ''' - Run code for process object if this in not the main process - ''' - if is_forking(sys.argv): - kwds = {} - for arg in sys.argv[2:]: - name, value = arg.split('=') - if value == 'None': - kwds[name] = None - else: - kwds[name] = int(value) - spawn_main(**kwds) - sys.exit() - - -def get_command_line(**kwds): - ''' - Returns prefix of command line used for spawning a child process - ''' - if getattr(sys, 'frozen', False): - return ([sys.executable, '--multiprocessing-fork'] + - ['%s=%r' % item for item in kwds.items()]) - else: - prog = 'from multiprocessing.spawn import spawn_main; spawn_main(%s)' - prog %= ', '.join('%s=%r' % item for item in kwds.items()) - opts = util._args_from_interpreter_flags() - exe = get_executable() - return [exe] + opts + ['-c', prog, '--multiprocessing-fork'] - - -def spawn_main(pipe_handle, parent_pid=None, tracker_fd=None): - ''' - Run code specified by data received over pipe - ''' - assert is_forking(sys.argv), "Not forking" - if sys.platform == 'win32': - import msvcrt - import _winapi - - if parent_pid is not None: - source_process = _winapi.OpenProcess( - _winapi.SYNCHRONIZE | _winapi.PROCESS_DUP_HANDLE, - False, parent_pid) - else: - source_process = None - new_handle = reduction.duplicate(pipe_handle, - source_process=source_process) - fd = msvcrt.open_osfhandle(new_handle, os.O_RDONLY) - parent_sentinel = source_process - else: - from . import resource_tracker - resource_tracker._resource_tracker._fd = tracker_fd - fd = pipe_handle - parent_sentinel = os.dup(pipe_handle) - exitcode = _main(fd, parent_sentinel) - sys.exit(exitcode) - - -def _main(fd, parent_sentinel): - with os.fdopen(fd, 'rb', closefd=True) as from_parent: - process.current_process()._inheriting = True - try: - preparation_data = reduction.pickle.load(from_parent) - prepare(preparation_data) - self = reduction.pickle.load(from_parent) - finally: - del process.current_process()._inheriting - return self._bootstrap(parent_sentinel) - - -def _check_not_importing_main(): - if getattr(process.current_process(), '_inheriting', False): - raise RuntimeError(''' - An attempt has been made to start a new process before the - current process has finished its bootstrapping phase. - - This probably means that you are not using fork to start your - child processes and you have forgotten to use the proper idiom - in the main module: - - if __name__ == '__main__': - freeze_support() - ... - - The "freeze_support()" line can be omitted if the program - is not going to be frozen to produce an executable.''') - - -def get_preparation_data(name): - ''' - Return info about parent needed by child to unpickle process object - ''' - _check_not_importing_main() - d = dict( - log_to_stderr=util._log_to_stderr, - authkey=process.current_process().authkey, - ) - - if util._logger is not None: - d['log_level'] = util._logger.getEffectiveLevel() - - sys_path=sys.path.copy() - try: - i = sys_path.index('') - except ValueError: - pass - else: - sys_path[i] = process.ORIGINAL_DIR - - d.update( - name=name, - sys_path=sys_path, - sys_argv=sys.argv, - orig_dir=process.ORIGINAL_DIR, - dir=os.getcwd(), - start_method=get_start_method(), - ) - - # Figure out whether to initialise main in the subprocess as a module - # or through direct execution (or to leave it alone entirely) - main_module = sys.modules['__main__'] - main_mod_name = getattr(main_module.__spec__, "name", None) - if main_mod_name is not None: - d['init_main_from_name'] = main_mod_name - elif sys.platform != 'win32' or (not WINEXE and not WINSERVICE): - main_path = getattr(main_module, '__file__', None) - if main_path is not None: - if (not os.path.isabs(main_path) and - process.ORIGINAL_DIR is not None): - main_path = os.path.join(process.ORIGINAL_DIR, main_path) - d['init_main_from_path'] = os.path.normpath(main_path) - - return d - -# -# Prepare current process -# - -old_main_modules = [] - -def prepare(data): - ''' - Try to get current process ready to unpickle process object - ''' - if 'name' in data: - process.current_process().name = data['name'] - - if 'authkey' in data: - process.current_process().authkey = data['authkey'] - - if 'log_to_stderr' in data and data['log_to_stderr']: - util.log_to_stderr() - - if 'log_level' in data: - util.get_logger().setLevel(data['log_level']) - - if 'sys_path' in data: - sys.path = data['sys_path'] - - if 'sys_argv' in data: - sys.argv = data['sys_argv'] - - if 'dir' in data: - os.chdir(data['dir']) - - if 'orig_dir' in data: - process.ORIGINAL_DIR = data['orig_dir'] - - if 'start_method' in data: - set_start_method(data['start_method'], force=True) - - if 'init_main_from_name' in data: - _fixup_main_from_name(data['init_main_from_name']) - elif 'init_main_from_path' in data: - _fixup_main_from_path(data['init_main_from_path']) - -# Multiprocessing module helpers to fix up the main module in -# spawned subprocesses -def _fixup_main_from_name(mod_name): - # __main__.py files for packages, directories, zip archives, etc, run - # their "main only" code unconditionally, so we don't even try to - # populate anything in __main__, nor do we make any changes to - # __main__ attributes - current_main = sys.modules['__main__'] - if mod_name == "__main__" or mod_name.endswith(".__main__"): - return - - # If this process was forked, __main__ may already be populated - if getattr(current_main.__spec__, "name", None) == mod_name: - return - - # Otherwise, __main__ may contain some non-main code where we need to - # support unpickling it properly. We rerun it as __mp_main__ and make - # the normal __main__ an alias to that - old_main_modules.append(current_main) - main_module = types.ModuleType("__mp_main__") - main_content = runpy.run_module(mod_name, - run_name="__mp_main__", - alter_sys=True) - main_module.__dict__.update(main_content) - sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module - - -def _fixup_main_from_path(main_path): - # If this process was forked, __main__ may already be populated - current_main = sys.modules['__main__'] - - # Unfortunately, the main ipython launch script historically had no - # "if __name__ == '__main__'" guard, so we work around that - # by treating it like a __main__.py file - # See https://github.com/ipython/ipython/issues/4698 - main_name = os.path.splitext(os.path.basename(main_path))[0] - if main_name == 'ipython': - return - - # Otherwise, if __file__ already has the setting we expect, - # there's nothing more to do - if getattr(current_main, '__file__', None) == main_path: - return - - # If the parent process has sent a path through rather than a module - # name we assume it is an executable script that may contain - # non-main code that needs to be executed - old_main_modules.append(current_main) - main_module = types.ModuleType("__mp_main__") - main_content = runpy.run_path(main_path, - run_name="__mp_main__") - main_module.__dict__.update(main_content) - sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module - - -def import_main_path(main_path): - ''' - Set sys.modules['__main__'] to module at main_path - ''' - _fixup_main_from_path(main_path) diff --git a/python/Lib/multiprocessing/synchronize.py b/python/Lib/multiprocessing/synchronize.py deleted file mode 100644 index 45a7795..0000000 --- a/python/Lib/multiprocessing/synchronize.py +++ /dev/null @@ -1,397 +0,0 @@ -# -# Module implementing synchronization primitives -# -# multiprocessing/synchronize.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -__all__ = [ - 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Event' - ] - -import threading -import sys -import tempfile -import _multiprocessing -import time - -from . import context -from . import process -from . import util - -# Try to import the mp.synchronize module cleanly, if it fails -# raise ImportError for platforms lacking a working sem_open implementation. -# See issue 3770 -try: - from _multiprocessing import SemLock, sem_unlink -except (ImportError): - raise ImportError("This platform lacks a functioning sem_open" + - " implementation, therefore, the required" + - " synchronization primitives needed will not" + - " function, see issue 3770.") - -# -# Constants -# - -RECURSIVE_MUTEX, SEMAPHORE = list(range(2)) -SEM_VALUE_MAX = _multiprocessing.SemLock.SEM_VALUE_MAX - -# -# Base class for semaphores and mutexes; wraps `_multiprocessing.SemLock` -# - -class SemLock(object): - - _rand = tempfile._RandomNameSequence() - - def __init__(self, kind, value, maxvalue, *, ctx): - if ctx is None: - ctx = context._default_context.get_context() - name = ctx.get_start_method() - unlink_now = sys.platform == 'win32' or name == 'fork' - for i in range(100): - try: - sl = self._semlock = _multiprocessing.SemLock( - kind, value, maxvalue, self._make_name(), - unlink_now) - except FileExistsError: - pass - else: - break - else: - raise FileExistsError('cannot find name for semaphore') - - util.debug('created semlock with handle %s' % sl.handle) - self._make_methods() - - if sys.platform != 'win32': - def _after_fork(obj): - obj._semlock._after_fork() - util.register_after_fork(self, _after_fork) - - if self._semlock.name is not None: - # We only get here if we are on Unix with forking - # disabled. When the object is garbage collected or the - # process shuts down we unlink the semaphore name - from .resource_tracker import register - register(self._semlock.name, "semaphore") - util.Finalize(self, SemLock._cleanup, (self._semlock.name,), - exitpriority=0) - - @staticmethod - def _cleanup(name): - from .resource_tracker import unregister - sem_unlink(name) - unregister(name, "semaphore") - - def _make_methods(self): - self.acquire = self._semlock.acquire - self.release = self._semlock.release - - def __enter__(self): - return self._semlock.__enter__() - - def __exit__(self, *args): - return self._semlock.__exit__(*args) - - def __getstate__(self): - context.assert_spawning(self) - sl = self._semlock - if sys.platform == 'win32': - h = context.get_spawning_popen().duplicate_for_child(sl.handle) - else: - h = sl.handle - return (h, sl.kind, sl.maxvalue, sl.name) - - def __setstate__(self, state): - self._semlock = _multiprocessing.SemLock._rebuild(*state) - util.debug('recreated blocker with handle %r' % state[0]) - self._make_methods() - - @staticmethod - def _make_name(): - return '%s-%s' % (process.current_process()._config['semprefix'], - next(SemLock._rand)) - -# -# Semaphore -# - -class Semaphore(SemLock): - - def __init__(self, value=1, *, ctx): - SemLock.__init__(self, SEMAPHORE, value, SEM_VALUE_MAX, ctx=ctx) - - def get_value(self): - return self._semlock._get_value() - - def __repr__(self): - try: - value = self._semlock._get_value() - except Exception: - value = 'unknown' - return '<%s(value=%s)>' % (self.__class__.__name__, value) - -# -# Bounded semaphore -# - -class BoundedSemaphore(Semaphore): - - def __init__(self, value=1, *, ctx): - SemLock.__init__(self, SEMAPHORE, value, value, ctx=ctx) - - def __repr__(self): - try: - value = self._semlock._get_value() - except Exception: - value = 'unknown' - return '<%s(value=%s, maxvalue=%s)>' % \ - (self.__class__.__name__, value, self._semlock.maxvalue) - -# -# Non-recursive lock -# - -class Lock(SemLock): - - def __init__(self, *, ctx): - SemLock.__init__(self, SEMAPHORE, 1, 1, ctx=ctx) - - def __repr__(self): - try: - if self._semlock._is_mine(): - name = process.current_process().name - if threading.current_thread().name != 'MainThread': - name += '|' + threading.current_thread().name - elif self._semlock._get_value() == 1: - name = 'None' - elif self._semlock._count() > 0: - name = 'SomeOtherThread' - else: - name = 'SomeOtherProcess' - except Exception: - name = 'unknown' - return '<%s(owner=%s)>' % (self.__class__.__name__, name) - -# -# Recursive lock -# - -class RLock(SemLock): - - def __init__(self, *, ctx): - SemLock.__init__(self, RECURSIVE_MUTEX, 1, 1, ctx=ctx) - - def __repr__(self): - try: - if self._semlock._is_mine(): - name = process.current_process().name - if threading.current_thread().name != 'MainThread': - name += '|' + threading.current_thread().name - count = self._semlock._count() - elif self._semlock._get_value() == 1: - name, count = 'None', 0 - elif self._semlock._count() > 0: - name, count = 'SomeOtherThread', 'nonzero' - else: - name, count = 'SomeOtherProcess', 'nonzero' - except Exception: - name, count = 'unknown', 'unknown' - return '<%s(%s, %s)>' % (self.__class__.__name__, name, count) - -# -# Condition variable -# - -class Condition(object): - - def __init__(self, lock=None, *, ctx): - self._lock = lock or ctx.RLock() - self._sleeping_count = ctx.Semaphore(0) - self._woken_count = ctx.Semaphore(0) - self._wait_semaphore = ctx.Semaphore(0) - self._make_methods() - - def __getstate__(self): - context.assert_spawning(self) - return (self._lock, self._sleeping_count, - self._woken_count, self._wait_semaphore) - - def __setstate__(self, state): - (self._lock, self._sleeping_count, - self._woken_count, self._wait_semaphore) = state - self._make_methods() - - def __enter__(self): - return self._lock.__enter__() - - def __exit__(self, *args): - return self._lock.__exit__(*args) - - def _make_methods(self): - self.acquire = self._lock.acquire - self.release = self._lock.release - - def __repr__(self): - try: - num_waiters = (self._sleeping_count._semlock._get_value() - - self._woken_count._semlock._get_value()) - except Exception: - num_waiters = 'unknown' - return '<%s(%s, %s)>' % (self.__class__.__name__, self._lock, num_waiters) - - def wait(self, timeout=None): - assert self._lock._semlock._is_mine(), \ - 'must acquire() condition before using wait()' - - # indicate that this thread is going to sleep - self._sleeping_count.release() - - # release lock - count = self._lock._semlock._count() - for i in range(count): - self._lock.release() - - try: - # wait for notification or timeout - return self._wait_semaphore.acquire(True, timeout) - finally: - # indicate that this thread has woken - self._woken_count.release() - - # reacquire lock - for i in range(count): - self._lock.acquire() - - def notify(self, n=1): - assert self._lock._semlock._is_mine(), 'lock is not owned' - assert not self._wait_semaphore.acquire( - False), ('notify: Should not have been able to acquire ' - + '_wait_semaphore') - - # to take account of timeouts since last notify*() we subtract - # woken_count from sleeping_count and rezero woken_count - while self._woken_count.acquire(False): - res = self._sleeping_count.acquire(False) - assert res, ('notify: Bug in sleeping_count.acquire' - + '- res should not be False') - - sleepers = 0 - while sleepers < n and self._sleeping_count.acquire(False): - self._wait_semaphore.release() # wake up one sleeper - sleepers += 1 - - if sleepers: - for i in range(sleepers): - self._woken_count.acquire() # wait for a sleeper to wake - - # rezero wait_semaphore in case some timeouts just happened - while self._wait_semaphore.acquire(False): - pass - - def notify_all(self): - self.notify(n=sys.maxsize) - - def wait_for(self, predicate, timeout=None): - result = predicate() - if result: - return result - if timeout is not None: - endtime = time.monotonic() + timeout - else: - endtime = None - waittime = None - while not result: - if endtime is not None: - waittime = endtime - time.monotonic() - if waittime <= 0: - break - self.wait(waittime) - result = predicate() - return result - -# -# Event -# - -class Event(object): - - def __init__(self, *, ctx): - self._cond = ctx.Condition(ctx.Lock()) - self._flag = ctx.Semaphore(0) - - def is_set(self): - with self._cond: - if self._flag.acquire(False): - self._flag.release() - return True - return False - - def set(self): - with self._cond: - self._flag.acquire(False) - self._flag.release() - self._cond.notify_all() - - def clear(self): - with self._cond: - self._flag.acquire(False) - - def wait(self, timeout=None): - with self._cond: - if self._flag.acquire(False): - self._flag.release() - else: - self._cond.wait(timeout) - - if self._flag.acquire(False): - self._flag.release() - return True - return False - - def __repr__(self) -> str: - set_status = 'set' if self.is_set() else 'unset' - return f"<{type(self).__qualname__} at {id(self):#x} {set_status}>" -# -# Barrier -# - -class Barrier(threading.Barrier): - - def __init__(self, parties, action=None, timeout=None, *, ctx): - import struct - from .heap import BufferWrapper - wrapper = BufferWrapper(struct.calcsize('i') * 2) - cond = ctx.Condition() - self.__setstate__((parties, action, timeout, cond, wrapper)) - self._state = 0 - self._count = 0 - - def __setstate__(self, state): - (self._parties, self._action, self._timeout, - self._cond, self._wrapper) = state - self._array = self._wrapper.create_memoryview().cast('i') - - def __getstate__(self): - return (self._parties, self._action, self._timeout, - self._cond, self._wrapper) - - @property - def _state(self): - return self._array[0] - - @_state.setter - def _state(self, value): - self._array[0] = value - - @property - def _count(self): - return self._array[1] - - @_count.setter - def _count(self, value): - self._array[1] = value diff --git a/python/Lib/multiprocessing/util.py b/python/Lib/multiprocessing/util.py deleted file mode 100644 index f6cf630..0000000 --- a/python/Lib/multiprocessing/util.py +++ /dev/null @@ -1,491 +0,0 @@ -# -# Module providing various facilities to other parts of the package -# -# multiprocessing/util.py -# -# Copyright (c) 2006-2008, R Oudkerk -# Licensed to PSF under a Contributor Agreement. -# - -import os -import itertools -import sys -import weakref -import atexit -import threading # we want threading to install it's - # cleanup function before multiprocessing does -from subprocess import _args_from_interpreter_flags - -from . import process - -__all__ = [ - 'sub_debug', 'debug', 'info', 'sub_warning', 'get_logger', - 'log_to_stderr', 'get_temp_dir', 'register_after_fork', - 'is_exiting', 'Finalize', 'ForkAwareThreadLock', 'ForkAwareLocal', - 'close_all_fds_except', 'SUBDEBUG', 'SUBWARNING', - ] - -# -# Logging -# - -NOTSET = 0 -SUBDEBUG = 5 -DEBUG = 10 -INFO = 20 -SUBWARNING = 25 - -LOGGER_NAME = 'multiprocessing' -DEFAULT_LOGGING_FORMAT = '[%(levelname)s/%(processName)s] %(message)s' - -_logger = None -_log_to_stderr = False - -def sub_debug(msg, *args): - if _logger: - _logger.log(SUBDEBUG, msg, *args) - -def debug(msg, *args): - if _logger: - _logger.log(DEBUG, msg, *args) - -def info(msg, *args): - if _logger: - _logger.log(INFO, msg, *args) - -def sub_warning(msg, *args): - if _logger: - _logger.log(SUBWARNING, msg, *args) - -def get_logger(): - ''' - Returns logger used by multiprocessing - ''' - global _logger - import logging - - logging._acquireLock() - try: - if not _logger: - - _logger = logging.getLogger(LOGGER_NAME) - _logger.propagate = 0 - - # XXX multiprocessing should cleanup before logging - if hasattr(atexit, 'unregister'): - atexit.unregister(_exit_function) - atexit.register(_exit_function) - else: - atexit._exithandlers.remove((_exit_function, (), {})) - atexit._exithandlers.append((_exit_function, (), {})) - - finally: - logging._releaseLock() - - return _logger - -def log_to_stderr(level=None): - ''' - Turn on logging and add a handler which prints to stderr - ''' - global _log_to_stderr - import logging - - logger = get_logger() - formatter = logging.Formatter(DEFAULT_LOGGING_FORMAT) - handler = logging.StreamHandler() - handler.setFormatter(formatter) - logger.addHandler(handler) - - if level: - logger.setLevel(level) - _log_to_stderr = True - return _logger - - -# Abstract socket support - -def _platform_supports_abstract_sockets(): - if sys.platform == "linux": - return True - if hasattr(sys, 'getandroidapilevel'): - return True - return False - - -def is_abstract_socket_namespace(address): - if not address: - return False - if isinstance(address, bytes): - return address[0] == 0 - elif isinstance(address, str): - return address[0] == "\0" - raise TypeError(f'address type of {address!r} unrecognized') - - -abstract_sockets_supported = _platform_supports_abstract_sockets() - -# -# Function returning a temp directory which will be removed on exit -# - -def _remove_temp_dir(rmtree, tempdir): - rmtree(tempdir) - - current_process = process.current_process() - # current_process() can be None if the finalizer is called - # late during Python finalization - if current_process is not None: - current_process._config['tempdir'] = None - -def get_temp_dir(): - # get name of a temp directory which will be automatically cleaned up - tempdir = process.current_process()._config.get('tempdir') - if tempdir is None: - import shutil, tempfile - tempdir = tempfile.mkdtemp(prefix='pymp-') - info('created temp directory %s', tempdir) - # keep a strong reference to shutil.rmtree(), since the finalizer - # can be called late during Python shutdown - Finalize(None, _remove_temp_dir, args=(shutil.rmtree, tempdir), - exitpriority=-100) - process.current_process()._config['tempdir'] = tempdir - return tempdir - -# -# Support for reinitialization of objects when bootstrapping a child process -# - -_afterfork_registry = weakref.WeakValueDictionary() -_afterfork_counter = itertools.count() - -def _run_after_forkers(): - items = list(_afterfork_registry.items()) - items.sort() - for (index, ident, func), obj in items: - try: - func(obj) - except Exception as e: - info('after forker raised exception %s', e) - -def register_after_fork(obj, func): - _afterfork_registry[(next(_afterfork_counter), id(obj), func)] = obj - -# -# Finalization using weakrefs -# - -_finalizer_registry = {} -_finalizer_counter = itertools.count() - - -class Finalize(object): - ''' - Class which supports object finalization using weakrefs - ''' - def __init__(self, obj, callback, args=(), kwargs=None, exitpriority=None): - if (exitpriority is not None) and not isinstance(exitpriority,int): - raise TypeError( - "Exitpriority ({0!r}) must be None or int, not {1!s}".format( - exitpriority, type(exitpriority))) - - if obj is not None: - self._weakref = weakref.ref(obj, self) - elif exitpriority is None: - raise ValueError("Without object, exitpriority cannot be None") - - self._callback = callback - self._args = args - self._kwargs = kwargs or {} - self._key = (exitpriority, next(_finalizer_counter)) - self._pid = os.getpid() - - _finalizer_registry[self._key] = self - - def __call__(self, wr=None, - # Need to bind these locally because the globals can have - # been cleared at shutdown - _finalizer_registry=_finalizer_registry, - sub_debug=sub_debug, getpid=os.getpid): - ''' - Run the callback unless it has already been called or cancelled - ''' - try: - del _finalizer_registry[self._key] - except KeyError: - sub_debug('finalizer no longer registered') - else: - if self._pid != getpid(): - sub_debug('finalizer ignored because different process') - res = None - else: - sub_debug('finalizer calling %s with args %s and kwargs %s', - self._callback, self._args, self._kwargs) - res = self._callback(*self._args, **self._kwargs) - self._weakref = self._callback = self._args = \ - self._kwargs = self._key = None - return res - - def cancel(self): - ''' - Cancel finalization of the object - ''' - try: - del _finalizer_registry[self._key] - except KeyError: - pass - else: - self._weakref = self._callback = self._args = \ - self._kwargs = self._key = None - - def still_active(self): - ''' - Return whether this finalizer is still waiting to invoke callback - ''' - return self._key in _finalizer_registry - - def __repr__(self): - try: - obj = self._weakref() - except (AttributeError, TypeError): - obj = None - - if obj is None: - return '<%s object, dead>' % self.__class__.__name__ - - x = '<%s object, callback=%s' % ( - self.__class__.__name__, - getattr(self._callback, '__name__', self._callback)) - if self._args: - x += ', args=' + str(self._args) - if self._kwargs: - x += ', kwargs=' + str(self._kwargs) - if self._key[0] is not None: - x += ', exitpriority=' + str(self._key[0]) - return x + '>' - - -def _run_finalizers(minpriority=None): - ''' - Run all finalizers whose exit priority is not None and at least minpriority - - Finalizers with highest priority are called first; finalizers with - the same priority will be called in reverse order of creation. - ''' - if _finalizer_registry is None: - # This function may be called after this module's globals are - # destroyed. See the _exit_function function in this module for more - # notes. - return - - if minpriority is None: - f = lambda p : p[0] is not None - else: - f = lambda p : p[0] is not None and p[0] >= minpriority - - # Careful: _finalizer_registry may be mutated while this function - # is running (either by a GC run or by another thread). - - # list(_finalizer_registry) should be atomic, while - # list(_finalizer_registry.items()) is not. - keys = [key for key in list(_finalizer_registry) if f(key)] - keys.sort(reverse=True) - - for key in keys: - finalizer = _finalizer_registry.get(key) - # key may have been removed from the registry - if finalizer is not None: - sub_debug('calling %s', finalizer) - try: - finalizer() - except Exception: - import traceback - traceback.print_exc() - - if minpriority is None: - _finalizer_registry.clear() - -# -# Clean up on exit -# - -def is_exiting(): - ''' - Returns true if the process is shutting down - ''' - return _exiting or _exiting is None - -_exiting = False - -def _exit_function(info=info, debug=debug, _run_finalizers=_run_finalizers, - active_children=process.active_children, - current_process=process.current_process): - # We hold on to references to functions in the arglist due to the - # situation described below, where this function is called after this - # module's globals are destroyed. - - global _exiting - - if not _exiting: - _exiting = True - - info('process shutting down') - debug('running all "atexit" finalizers with priority >= 0') - _run_finalizers(0) - - if current_process() is not None: - # We check if the current process is None here because if - # it's None, any call to ``active_children()`` will raise - # an AttributeError (active_children winds up trying to - # get attributes from util._current_process). One - # situation where this can happen is if someone has - # manipulated sys.modules, causing this module to be - # garbage collected. The destructor for the module type - # then replaces all values in the module dict with None. - # For instance, after setuptools runs a test it replaces - # sys.modules with a copy created earlier. See issues - # #9775 and #15881. Also related: #4106, #9205, and - # #9207. - - for p in active_children(): - if p.daemon: - info('calling terminate() for daemon %s', p.name) - p._popen.terminate() - - for p in active_children(): - info('calling join() for process %s', p.name) - p.join() - - debug('running the remaining "atexit" finalizers') - _run_finalizers() - -atexit.register(_exit_function) - -# -# Some fork aware types -# - -class ForkAwareThreadLock(object): - def __init__(self): - self._lock = threading.Lock() - self.acquire = self._lock.acquire - self.release = self._lock.release - register_after_fork(self, ForkAwareThreadLock._at_fork_reinit) - - def _at_fork_reinit(self): - self._lock._at_fork_reinit() - - def __enter__(self): - return self._lock.__enter__() - - def __exit__(self, *args): - return self._lock.__exit__(*args) - - -class ForkAwareLocal(threading.local): - def __init__(self): - register_after_fork(self, lambda obj : obj.__dict__.clear()) - def __reduce__(self): - return type(self), () - -# -# Close fds except those specified -# - -try: - MAXFD = os.sysconf("SC_OPEN_MAX") -except Exception: - MAXFD = 256 - -def close_all_fds_except(fds): - fds = list(fds) + [-1, MAXFD] - fds.sort() - assert fds[-1] == MAXFD, 'fd too large' - for i in range(len(fds) - 1): - os.closerange(fds[i]+1, fds[i+1]) -# -# Close sys.stdin and replace stdin with os.devnull -# - -def _close_stdin(): - if sys.stdin is None: - return - - try: - sys.stdin.close() - except (OSError, ValueError): - pass - - try: - fd = os.open(os.devnull, os.O_RDONLY) - try: - sys.stdin = open(fd, encoding="utf-8", closefd=False) - except: - os.close(fd) - raise - except (OSError, ValueError): - pass - -# -# Flush standard streams, if any -# - -def _flush_std_streams(): - try: - sys.stdout.flush() - except (AttributeError, ValueError): - pass - try: - sys.stderr.flush() - except (AttributeError, ValueError): - pass - -# -# Start a program with only specified fds kept open -# - -def spawnv_passfds(path, args, passfds): - import _posixsubprocess - import subprocess - passfds = tuple(sorted(map(int, passfds))) - errpipe_read, errpipe_write = os.pipe() - try: - return _posixsubprocess.fork_exec( - args, [path], True, passfds, None, None, - -1, -1, -1, -1, -1, -1, errpipe_read, errpipe_write, - False, False, -1, None, None, None, -1, None, - subprocess._USE_VFORK) - finally: - os.close(errpipe_read) - os.close(errpipe_write) - - -def close_fds(*fds): - """Close each file descriptor given as an argument""" - for fd in fds: - os.close(fd) - - -def _cleanup_tests(): - """Cleanup multiprocessing resources when multiprocessing tests - completed.""" - - from test import support - - # cleanup multiprocessing - process._cleanup() - - # Stop the ForkServer process if it's running - from multiprocessing import forkserver - forkserver._forkserver._stop() - - # Stop the ResourceTracker process if it's running - from multiprocessing import resource_tracker - resource_tracker._resource_tracker._stop() - - # bpo-37421: Explicitly call _run_finalizers() to remove immediately - # temporary directories created by multiprocessing.util.get_temp_dir(). - _run_finalizers() - support.gc_collect() - - support.reap_children() diff --git a/python/Lib/netrc.py b/python/Lib/netrc.py deleted file mode 100644 index 4fce637..0000000 --- a/python/Lib/netrc.py +++ /dev/null @@ -1,192 +0,0 @@ -"""An object-oriented interface to .netrc files.""" - -# Module and documentation by Eric S. Raymond, 21 Dec 1998 - -import os, shlex, stat - -__all__ = ["netrc", "NetrcParseError"] - - -class NetrcParseError(Exception): - """Exception raised on syntax errors in the .netrc file.""" - def __init__(self, msg, filename=None, lineno=None): - self.filename = filename - self.lineno = lineno - self.msg = msg - Exception.__init__(self, msg) - - def __str__(self): - return "%s (%s, line %s)" % (self.msg, self.filename, self.lineno) - - -class _netrclex: - def __init__(self, fp): - self.lineno = 1 - self.instream = fp - self.whitespace = "\n\t\r " - self.pushback = [] - - def _read_char(self): - ch = self.instream.read(1) - if ch == "\n": - self.lineno += 1 - return ch - - def get_token(self): - if self.pushback: - return self.pushback.pop(0) - token = "" - fiter = iter(self._read_char, "") - for ch in fiter: - if ch in self.whitespace: - continue - if ch == '"': - for ch in fiter: - if ch == '"': - return token - elif ch == "\\": - ch = self._read_char() - token += ch - else: - if ch == "\\": - ch = self._read_char() - token += ch - for ch in fiter: - if ch in self.whitespace: - return token - elif ch == "\\": - ch = self._read_char() - token += ch - return token - - def push_token(self, token): - self.pushback.append(token) - - -class netrc: - def __init__(self, file=None): - default_netrc = file is None - if file is None: - file = os.path.join(os.path.expanduser("~"), ".netrc") - self.hosts = {} - self.macros = {} - try: - with open(file, encoding="utf-8") as fp: - self._parse(file, fp, default_netrc) - except UnicodeDecodeError: - with open(file, encoding="locale") as fp: - self._parse(file, fp, default_netrc) - - def _parse(self, file, fp, default_netrc): - lexer = _netrclex(fp) - while 1: - # Look for a machine, default, or macdef top-level keyword - saved_lineno = lexer.lineno - toplevel = tt = lexer.get_token() - if not tt: - break - elif tt[0] == '#': - if lexer.lineno == saved_lineno and len(tt) == 1: - lexer.instream.readline() - continue - elif tt == 'machine': - entryname = lexer.get_token() - elif tt == 'default': - entryname = 'default' - elif tt == 'macdef': - entryname = lexer.get_token() - self.macros[entryname] = [] - while 1: - line = lexer.instream.readline() - if not line: - raise NetrcParseError( - "Macro definition missing null line terminator.", - file, lexer.lineno) - if line == '\n': - # a macro definition finished with consecutive new-line - # characters. The first \n is encountered by the - # readline() method and this is the second \n. - break - self.macros[entryname].append(line) - continue - else: - raise NetrcParseError( - "bad toplevel token %r" % tt, file, lexer.lineno) - - if not entryname: - raise NetrcParseError("missing %r name" % tt, file, lexer.lineno) - - # We're looking at start of an entry for a named machine or default. - login = account = password = '' - self.hosts[entryname] = {} - while 1: - prev_lineno = lexer.lineno - tt = lexer.get_token() - if tt.startswith('#'): - if lexer.lineno == prev_lineno: - lexer.instream.readline() - continue - if tt in {'', 'machine', 'default', 'macdef'}: - self.hosts[entryname] = (login, account, password) - lexer.push_token(tt) - break - elif tt == 'login' or tt == 'user': - login = lexer.get_token() - elif tt == 'account': - account = lexer.get_token() - elif tt == 'password': - password = lexer.get_token() - else: - raise NetrcParseError("bad follower token %r" % tt, - file, lexer.lineno) - self._security_check(fp, default_netrc, self.hosts[entryname][0]) - - def _security_check(self, fp, default_netrc, login): - if os.name == 'posix' and default_netrc and login != "anonymous": - prop = os.fstat(fp.fileno()) - if prop.st_uid != os.getuid(): - import pwd - try: - fowner = pwd.getpwuid(prop.st_uid)[0] - except KeyError: - fowner = 'uid %s' % prop.st_uid - try: - user = pwd.getpwuid(os.getuid())[0] - except KeyError: - user = 'uid %s' % os.getuid() - raise NetrcParseError( - (f"~/.netrc file owner ({fowner}, {user}) does not match" - " current user")) - if (prop.st_mode & (stat.S_IRWXG | stat.S_IRWXO)): - raise NetrcParseError( - "~/.netrc access too permissive: access" - " permissions must restrict access to only" - " the owner") - - def authenticators(self, host): - """Return a (user, account, password) tuple for given host.""" - if host in self.hosts: - return self.hosts[host] - elif 'default' in self.hosts: - return self.hosts['default'] - else: - return None - - def __repr__(self): - """Dump the class data in the format of a .netrc file.""" - rep = "" - for host in self.hosts.keys(): - attrs = self.hosts[host] - rep += f"machine {host}\n\tlogin {attrs[0]}\n" - if attrs[1]: - rep += f"\taccount {attrs[1]}\n" - rep += f"\tpassword {attrs[2]}\n" - for macro in self.macros.keys(): - rep += f"macdef {macro}\n" - for line in self.macros[macro]: - rep += line - rep += "\n" - return rep - -if __name__ == '__main__': - print(netrc()) diff --git a/python/Lib/ntpath.py b/python/Lib/ntpath.py deleted file mode 100644 index 16c82f6..0000000 --- a/python/Lib/ntpath.py +++ /dev/null @@ -1,849 +0,0 @@ -# Module 'ntpath' -- common operations on WinNT/Win95 pathnames -"""Common pathname manipulations, WindowsNT/95 version. - -Instead of importing this module directly, import os and refer to this -module as os.path. -""" - -# strings representing various path-related bits and pieces -# These are primarily for export; internally, they are hardcoded. -# Should be set before imports for resolving cyclic dependency. -curdir = '.' -pardir = '..' -extsep = '.' -sep = '\\' -pathsep = ';' -altsep = '/' -defpath = '.;C:\\bin' -devnull = 'nul' - -import os -import sys -import stat -import genericpath -from genericpath import * - - -__all__ = ["normcase","isabs","join","splitdrive","split","splitext", - "basename","dirname","commonprefix","getsize","getmtime", - "getatime","getctime", "islink","exists","lexists","isdir","isfile", - "ismount", "expanduser","expandvars","normpath","abspath", - "curdir","pardir","sep","pathsep","defpath","altsep", - "extsep","devnull","realpath","supports_unicode_filenames","relpath", - "samefile", "sameopenfile", "samestat", "commonpath"] - -def _get_bothseps(path): - if isinstance(path, bytes): - return b'\\/' - else: - return '\\/' - -# Normalize the case of a pathname and map slashes to backslashes. -# Other normalizations (such as optimizing '../' away) are not done -# (this is done by normpath). - -try: - from _winapi import ( - LCMapStringEx as _LCMapStringEx, - LOCALE_NAME_INVARIANT as _LOCALE_NAME_INVARIANT, - LCMAP_LOWERCASE as _LCMAP_LOWERCASE) - - def normcase(s): - """Normalize case of pathname. - - Makes all characters lowercase and all slashes into backslashes. - """ - s = os.fspath(s) - if not s: - return s - if isinstance(s, bytes): - encoding = sys.getfilesystemencoding() - s = s.decode(encoding, 'surrogateescape').replace('/', '\\') - s = _LCMapStringEx(_LOCALE_NAME_INVARIANT, - _LCMAP_LOWERCASE, s) - return s.encode(encoding, 'surrogateescape') - else: - return _LCMapStringEx(_LOCALE_NAME_INVARIANT, - _LCMAP_LOWERCASE, - s.replace('/', '\\')) -except ImportError: - def normcase(s): - """Normalize case of pathname. - - Makes all characters lowercase and all slashes into backslashes. - """ - s = os.fspath(s) - if isinstance(s, bytes): - return os.fsencode(os.fsdecode(s).replace('/', '\\').lower()) - return s.replace('/', '\\').lower() - - -# Return whether a path is absolute. -# Trivial in Posix, harder on Windows. -# For Windows it is absolute if it starts with a slash or backslash (current -# volume), or if a pathname after the volume-letter-and-colon or UNC-resource -# starts with a slash or backslash. - -def isabs(s): - """Test whether a path is absolute""" - s = os.fspath(s) - # Paths beginning with \\?\ are always absolute, but do not - # necessarily contain a drive. - if isinstance(s, bytes): - if s.replace(b'/', b'\\').startswith(b'\\\\?\\'): - return True - else: - if s.replace('/', '\\').startswith('\\\\?\\'): - return True - s = splitdrive(s)[1] - return len(s) > 0 and s[0] and s[0] in _get_bothseps(s) - - -# Join two (or more) paths. -def join(path, *paths): - path = os.fspath(path) - if isinstance(path, bytes): - sep = b'\\' - seps = b'\\/' - colon = b':' - else: - sep = '\\' - seps = '\\/' - colon = ':' - try: - if not paths: - path[:0] + sep #23780: Ensure compatible data type even if p is null. - result_drive, result_path = splitdrive(path) - for p in map(os.fspath, paths): - p_drive, p_path = splitdrive(p) - if p_path and p_path[0] in seps: - # Second path is absolute - if p_drive or not result_drive: - result_drive = p_drive - result_path = p_path - continue - elif p_drive and p_drive != result_drive: - if p_drive.lower() != result_drive.lower(): - # Different drives => ignore the first path entirely - result_drive = p_drive - result_path = p_path - continue - # Same drive in different case - result_drive = p_drive - # Second path is relative to the first - if result_path and result_path[-1] not in seps: - result_path = result_path + sep - result_path = result_path + p_path - ## add separator between UNC and non-absolute path - if (result_path and result_path[0] not in seps and - result_drive and result_drive[-1:] != colon): - return result_drive + sep + result_path - return result_drive + result_path - except (TypeError, AttributeError, BytesWarning): - genericpath._check_arg_types('join', path, *paths) - raise - - -# Split a path in a drive specification (a drive letter followed by a -# colon) and the path specification. -# It is always true that drivespec + pathspec == p -def splitdrive(p): - """Split a pathname into drive/UNC sharepoint and relative path specifiers. - Returns a 2-tuple (drive_or_unc, path); either part may be empty. - - If you assign - result = splitdrive(p) - It is always true that: - result[0] + result[1] == p - - If the path contained a drive letter, drive_or_unc will contain everything - up to and including the colon. e.g. splitdrive("c:/dir") returns ("c:", "/dir") - - If the path contained a UNC path, the drive_or_unc will contain the host name - and share up to but not including the fourth directory separator character. - e.g. splitdrive("//host/computer/dir") returns ("//host/computer", "/dir") - - Paths cannot contain both a drive letter and a UNC path. - - """ - p = os.fspath(p) - if len(p) >= 2: - if isinstance(p, bytes): - sep = b'\\' - altsep = b'/' - colon = b':' - else: - sep = '\\' - altsep = '/' - colon = ':' - normp = p.replace(altsep, sep) - if (normp[0:2] == sep*2) and (normp[2:3] != sep): - # is a UNC path: - # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path - # \\machine\mountpoint\directory\etc\... - # directory ^^^^^^^^^^^^^^^ - index = normp.find(sep, 2) - if index == -1: - return p[:0], p - index2 = normp.find(sep, index + 1) - # a UNC path can't have two slashes in a row - # (after the initial two) - if index2 == index + 1: - return p[:0], p - if index2 == -1: - index2 = len(p) - return p[:index2], p[index2:] - if normp[1:2] == colon: - return p[:2], p[2:] - return p[:0], p - - -# Split a path in head (everything up to the last '/') and tail (the -# rest). After the trailing '/' is stripped, the invariant -# join(head, tail) == p holds. -# The resulting head won't end in '/' unless it is the root. - -def split(p): - """Split a pathname. - - Return tuple (head, tail) where tail is everything after the final slash. - Either part may be empty.""" - p = os.fspath(p) - seps = _get_bothseps(p) - d, p = splitdrive(p) - # set i to index beyond p's last slash - i = len(p) - while i and p[i-1] not in seps: - i -= 1 - head, tail = p[:i], p[i:] # now tail has no slashes - # remove trailing slashes from head, unless it's all slashes - head = head.rstrip(seps) or head - return d + head, tail - - -# Split a path in root and extension. -# The extension is everything starting at the last dot in the last -# pathname component; the root is everything before that. -# It is always true that root + ext == p. - -def splitext(p): - p = os.fspath(p) - if isinstance(p, bytes): - return genericpath._splitext(p, b'\\', b'/', b'.') - else: - return genericpath._splitext(p, '\\', '/', '.') -splitext.__doc__ = genericpath._splitext.__doc__ - - -# Return the tail (basename) part of a path. - -def basename(p): - """Returns the final component of a pathname""" - return split(p)[1] - - -# Return the head (dirname) part of a path. - -def dirname(p): - """Returns the directory component of a pathname""" - return split(p)[0] - -# Is a path a symbolic link? -# This will always return false on systems where os.lstat doesn't exist. - -def islink(path): - """Test whether a path is a symbolic link. - This will always return false for Windows prior to 6.0. - """ - try: - st = os.lstat(path) - except (OSError, ValueError, AttributeError): - return False - return stat.S_ISLNK(st.st_mode) - -# Being true for dangling symbolic links is also useful. - -def lexists(path): - """Test whether a path exists. Returns True for broken symbolic links""" - try: - st = os.lstat(path) - except (OSError, ValueError): - return False - return True - -# Is a path a mount point? -# Any drive letter root (eg c:\) -# Any share UNC (eg \\server\share) -# Any volume mounted on a filesystem folder -# -# No one method detects all three situations. Historically we've lexically -# detected drive letter roots and share UNCs. The canonical approach to -# detecting mounted volumes (querying the reparse tag) fails for the most -# common case: drive letter roots. The alternative which uses GetVolumePathName -# fails if the drive letter is the result of a SUBST. -try: - from nt import _getvolumepathname -except ImportError: - _getvolumepathname = None -def ismount(path): - """Test whether a path is a mount point (a drive root, the root of a - share, or a mounted volume)""" - path = os.fspath(path) - seps = _get_bothseps(path) - path = abspath(path) - root, rest = splitdrive(path) - if root and root[0] in seps: - return (not rest) or (rest in seps) - if rest and rest in seps: - return True - - if _getvolumepathname: - x = path.rstrip(seps) - y =_getvolumepathname(path).rstrip(seps) - return x.casefold() == y.casefold() - else: - return False - - -# Expand paths beginning with '~' or '~user'. -# '~' means $HOME; '~user' means that user's home directory. -# If the path doesn't begin with '~', or if the user or $HOME is unknown, -# the path is returned unchanged (leaving error reporting to whatever -# function is called with the expanded path as argument). -# See also module 'glob' for expansion of *, ? and [...] in pathnames. -# (A function should also be defined to do full *sh-style environment -# variable expansion.) - -def expanduser(path): - """Expand ~ and ~user constructs. - - If user or $HOME is unknown, do nothing.""" - path = os.fspath(path) - if isinstance(path, bytes): - tilde = b'~' - else: - tilde = '~' - if not path.startswith(tilde): - return path - i, n = 1, len(path) - while i < n and path[i] not in _get_bothseps(path): - i += 1 - - if 'USERPROFILE' in os.environ: - userhome = os.environ['USERPROFILE'] - elif not 'HOMEPATH' in os.environ: - return path - else: - try: - drive = os.environ['HOMEDRIVE'] - except KeyError: - drive = '' - userhome = join(drive, os.environ['HOMEPATH']) - - if i != 1: #~user - target_user = path[1:i] - if isinstance(target_user, bytes): - target_user = os.fsdecode(target_user) - current_user = os.environ.get('USERNAME') - - if target_user != current_user: - # Try to guess user home directory. By default all user - # profile directories are located in the same place and are - # named by corresponding usernames. If userhome isn't a - # normal profile directory, this guess is likely wrong, - # so we bail out. - if current_user != basename(userhome): - return path - userhome = join(dirname(userhome), target_user) - - if isinstance(path, bytes): - userhome = os.fsencode(userhome) - - return userhome + path[i:] - - -# Expand paths containing shell variable substitutions. -# The following rules apply: -# - no expansion within single quotes -# - '$$' is translated into '$' -# - '%%' is translated into '%' if '%%' are not seen in %var1%%var2% -# - ${varname} is accepted. -# - $varname is accepted. -# - %varname% is accepted. -# - varnames can be made out of letters, digits and the characters '_-' -# (though is not verified in the ${varname} and %varname% cases) -# XXX With COMMAND.COM you can use any characters in a variable name, -# XXX except '^|<>='. - -def expandvars(path): - """Expand shell variables of the forms $var, ${var} and %var%. - - Unknown variables are left unchanged.""" - path = os.fspath(path) - if isinstance(path, bytes): - if b'$' not in path and b'%' not in path: - return path - import string - varchars = bytes(string.ascii_letters + string.digits + '_-', 'ascii') - quote = b'\'' - percent = b'%' - brace = b'{' - rbrace = b'}' - dollar = b'$' - environ = getattr(os, 'environb', None) - else: - if '$' not in path and '%' not in path: - return path - import string - varchars = string.ascii_letters + string.digits + '_-' - quote = '\'' - percent = '%' - brace = '{' - rbrace = '}' - dollar = '$' - environ = os.environ - res = path[:0] - index = 0 - pathlen = len(path) - while index < pathlen: - c = path[index:index+1] - if c == quote: # no expansion within single quotes - path = path[index + 1:] - pathlen = len(path) - try: - index = path.index(c) - res += c + path[:index + 1] - except ValueError: - res += c + path - index = pathlen - 1 - elif c == percent: # variable or '%' - if path[index + 1:index + 2] == percent: - res += c - index += 1 - else: - path = path[index+1:] - pathlen = len(path) - try: - index = path.index(percent) - except ValueError: - res += percent + path - index = pathlen - 1 - else: - var = path[:index] - try: - if environ is None: - value = os.fsencode(os.environ[os.fsdecode(var)]) - else: - value = environ[var] - except KeyError: - value = percent + var + percent - res += value - elif c == dollar: # variable or '$$' - if path[index + 1:index + 2] == dollar: - res += c - index += 1 - elif path[index + 1:index + 2] == brace: - path = path[index+2:] - pathlen = len(path) - try: - index = path.index(rbrace) - except ValueError: - res += dollar + brace + path - index = pathlen - 1 - else: - var = path[:index] - try: - if environ is None: - value = os.fsencode(os.environ[os.fsdecode(var)]) - else: - value = environ[var] - except KeyError: - value = dollar + brace + var + rbrace - res += value - else: - var = path[:0] - index += 1 - c = path[index:index + 1] - while c and c in varchars: - var += c - index += 1 - c = path[index:index + 1] - try: - if environ is None: - value = os.fsencode(os.environ[os.fsdecode(var)]) - else: - value = environ[var] - except KeyError: - value = dollar + var - res += value - if c: - index -= 1 - else: - res += c - index += 1 - return res - - -# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B. -# Previously, this function also truncated pathnames to 8+3 format, -# but as this module is called "ntpath", that's obviously wrong! -try: - from nt import _path_normpath - -except ImportError: - def normpath(path): - """Normalize path, eliminating double slashes, etc.""" - path = os.fspath(path) - if isinstance(path, bytes): - sep = b'\\' - altsep = b'/' - curdir = b'.' - pardir = b'..' - special_prefixes = (b'\\\\.\\', b'\\\\?\\') - else: - sep = '\\' - altsep = '/' - curdir = '.' - pardir = '..' - special_prefixes = ('\\\\.\\', '\\\\?\\') - if path.startswith(special_prefixes): - # in the case of paths with these prefixes: - # \\.\ -> device names - # \\?\ -> literal paths - # do not do any normalization, but return the path - # unchanged apart from the call to os.fspath() - return path - path = path.replace(altsep, sep) - prefix, path = splitdrive(path) - - # collapse initial backslashes - if path.startswith(sep): - prefix += sep - path = path.lstrip(sep) - - comps = path.split(sep) - i = 0 - while i < len(comps): - if not comps[i] or comps[i] == curdir: - del comps[i] - elif comps[i] == pardir: - if i > 0 and comps[i-1] != pardir: - del comps[i-1:i+1] - i -= 1 - elif i == 0 and prefix.endswith(sep): - del comps[i] - else: - i += 1 - else: - i += 1 - # If the path is now empty, substitute '.' - if not prefix and not comps: - comps.append(curdir) - return prefix + sep.join(comps) - -else: - def normpath(path): - """Normalize path, eliminating double slashes, etc.""" - path = os.fspath(path) - if isinstance(path, bytes): - return os.fsencode(_path_normpath(os.fsdecode(path))) or b"." - return _path_normpath(path) or "." - - -def _abspath_fallback(path): - """Return the absolute version of a path as a fallback function in case - `nt._getfullpathname` is not available or raises OSError. See bpo-31047 for - more. - - """ - - path = os.fspath(path) - if not isabs(path): - if isinstance(path, bytes): - cwd = os.getcwdb() - else: - cwd = os.getcwd() - path = join(cwd, path) - return normpath(path) - -# Return an absolute path. -try: - from nt import _getfullpathname - -except ImportError: # not running on Windows - mock up something sensible - abspath = _abspath_fallback - -else: # use native Windows method on Windows - def abspath(path): - """Return the absolute version of a path.""" - try: - return _getfullpathname(normpath(path)) - except (OSError, ValueError): - return _abspath_fallback(path) - -try: - from nt import _getfinalpathname, readlink as _nt_readlink -except ImportError: - # realpath is a no-op on systems without _getfinalpathname support. - realpath = abspath -else: - def _readlink_deep(path): - # These error codes indicate that we should stop reading links and - # return the path we currently have. - # 1: ERROR_INVALID_FUNCTION - # 2: ERROR_FILE_NOT_FOUND - # 3: ERROR_DIRECTORY_NOT_FOUND - # 5: ERROR_ACCESS_DENIED - # 21: ERROR_NOT_READY (implies drive with no media) - # 32: ERROR_SHARING_VIOLATION (probably an NTFS paging file) - # 50: ERROR_NOT_SUPPORTED (implies no support for reparse points) - # 67: ERROR_BAD_NET_NAME (implies remote server unavailable) - # 87: ERROR_INVALID_PARAMETER - # 4390: ERROR_NOT_A_REPARSE_POINT - # 4392: ERROR_INVALID_REPARSE_DATA - # 4393: ERROR_REPARSE_TAG_INVALID - allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 4390, 4392, 4393 - - seen = set() - while normcase(path) not in seen: - seen.add(normcase(path)) - try: - old_path = path - path = _nt_readlink(path) - # Links may be relative, so resolve them against their - # own location - if not isabs(path): - # If it's something other than a symlink, we don't know - # what it's actually going to be resolved against, so - # just return the old path. - if not islink(old_path): - path = old_path - break - path = normpath(join(dirname(old_path), path)) - except OSError as ex: - if ex.winerror in allowed_winerror: - break - raise - except ValueError: - # Stop on reparse points that are not symlinks - break - return path - - def _getfinalpathname_nonstrict(path): - # These error codes indicate that we should stop resolving the path - # and return the value we currently have. - # 1: ERROR_INVALID_FUNCTION - # 2: ERROR_FILE_NOT_FOUND - # 3: ERROR_DIRECTORY_NOT_FOUND - # 5: ERROR_ACCESS_DENIED - # 21: ERROR_NOT_READY (implies drive with no media) - # 32: ERROR_SHARING_VIOLATION (probably an NTFS paging file) - # 50: ERROR_NOT_SUPPORTED - # 67: ERROR_BAD_NET_NAME (implies remote server unavailable) - # 87: ERROR_INVALID_PARAMETER - # 123: ERROR_INVALID_NAME - # 1920: ERROR_CANT_ACCESS_FILE - # 1921: ERROR_CANT_RESOLVE_FILENAME (implies unfollowable symlink) - allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 123, 1920, 1921 - - # Non-strict algorithm is to find as much of the target directory - # as we can and join the rest. - tail = '' - while path: - try: - path = _getfinalpathname(path) - return join(path, tail) if tail else path - except OSError as ex: - if ex.winerror not in allowed_winerror: - raise - try: - # The OS could not resolve this path fully, so we attempt - # to follow the link ourselves. If we succeed, join the tail - # and return. - new_path = _readlink_deep(path) - if new_path != path: - return join(new_path, tail) if tail else new_path - except OSError: - # If we fail to readlink(), let's keep traversing - pass - path, name = split(path) - # TODO (bpo-38186): Request the real file name from the directory - # entry using FindFirstFileW. For now, we will return the path - # as best we have it - if path and not name: - return path + tail - tail = join(name, tail) if tail else name - return tail - - def realpath(path, *, strict=False): - path = normpath(path) - if isinstance(path, bytes): - prefix = b'\\\\?\\' - unc_prefix = b'\\\\?\\UNC\\' - new_unc_prefix = b'\\\\' - cwd = os.getcwdb() - # bpo-38081: Special case for realpath(b'nul') - if normcase(path) == normcase(os.fsencode(devnull)): - return b'\\\\.\\NUL' - else: - prefix = '\\\\?\\' - unc_prefix = '\\\\?\\UNC\\' - new_unc_prefix = '\\\\' - cwd = os.getcwd() - # bpo-38081: Special case for realpath('nul') - if normcase(path) == normcase(devnull): - return '\\\\.\\NUL' - had_prefix = path.startswith(prefix) - if not had_prefix and not isabs(path): - path = join(cwd, path) - try: - path = _getfinalpathname(path) - initial_winerror = 0 - except OSError as ex: - if strict: - raise - initial_winerror = ex.winerror - path = _getfinalpathname_nonstrict(path) - # The path returned by _getfinalpathname will always start with \\?\ - - # strip off that prefix unless it was already provided on the original - # path. - if not had_prefix and path.startswith(prefix): - # For UNC paths, the prefix will actually be \\?\UNC\ - # Handle that case as well. - if path.startswith(unc_prefix): - spath = new_unc_prefix + path[len(unc_prefix):] - else: - spath = path[len(prefix):] - # Ensure that the non-prefixed path resolves to the same path - try: - if _getfinalpathname(spath) == path: - path = spath - except OSError as ex: - # If the path does not exist and originally did not exist, then - # strip the prefix anyway. - if ex.winerror == initial_winerror: - path = spath - return path - - -# Win9x family and earlier have no Unicode filename support. -supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and - sys.getwindowsversion()[3] >= 2) - -def relpath(path, start=None): - """Return a relative version of a path""" - path = os.fspath(path) - if isinstance(path, bytes): - sep = b'\\' - curdir = b'.' - pardir = b'..' - else: - sep = '\\' - curdir = '.' - pardir = '..' - - if start is None: - start = curdir - - if not path: - raise ValueError("no path specified") - - start = os.fspath(start) - try: - start_abs = abspath(normpath(start)) - path_abs = abspath(normpath(path)) - start_drive, start_rest = splitdrive(start_abs) - path_drive, path_rest = splitdrive(path_abs) - if normcase(start_drive) != normcase(path_drive): - raise ValueError("path is on mount %r, start on mount %r" % ( - path_drive, start_drive)) - - start_list = [x for x in start_rest.split(sep) if x] - path_list = [x for x in path_rest.split(sep) if x] - # Work out how much of the filepath is shared by start and path. - i = 0 - for e1, e2 in zip(start_list, path_list): - if normcase(e1) != normcase(e2): - break - i += 1 - - rel_list = [pardir] * (len(start_list)-i) + path_list[i:] - if not rel_list: - return curdir - return join(*rel_list) - except (TypeError, ValueError, AttributeError, BytesWarning, DeprecationWarning): - genericpath._check_arg_types('relpath', path, start) - raise - - -# Return the longest common sub-path of the sequence of paths given as input. -# The function is case-insensitive and 'separator-insensitive', i.e. if the -# only difference between two paths is the use of '\' versus '/' as separator, -# they are deemed to be equal. -# -# However, the returned path will have the standard '\' separator (even if the -# given paths had the alternative '/' separator) and will have the case of the -# first path given in the sequence. Additionally, any trailing separator is -# stripped from the returned path. - -def commonpath(paths): - """Given a sequence of path names, returns the longest common sub-path.""" - - if not paths: - raise ValueError('commonpath() arg is an empty sequence') - - paths = tuple(map(os.fspath, paths)) - if isinstance(paths[0], bytes): - sep = b'\\' - altsep = b'/' - curdir = b'.' - else: - sep = '\\' - altsep = '/' - curdir = '.' - - try: - drivesplits = [splitdrive(p.replace(altsep, sep).lower()) for p in paths] - split_paths = [p.split(sep) for d, p in drivesplits] - - try: - isabs, = set(p[:1] == sep for d, p in drivesplits) - except ValueError: - raise ValueError("Can't mix absolute and relative paths") from None - - # Check that all drive letters or UNC paths match. The check is made only - # now otherwise type errors for mixing strings and bytes would not be - # caught. - if len(set(d for d, p in drivesplits)) != 1: - raise ValueError("Paths don't have the same drive") - - drive, path = splitdrive(paths[0].replace(altsep, sep)) - common = path.split(sep) - common = [c for c in common if c and c != curdir] - - split_paths = [[c for c in s if c and c != curdir] for s in split_paths] - s1 = min(split_paths) - s2 = max(split_paths) - for i, c in enumerate(s1): - if c != s2[i]: - common = common[:i] - break - else: - common = common[:len(s1)] - - prefix = drive + sep if isabs else drive - return prefix + sep.join(common) - except (TypeError, AttributeError): - genericpath._check_arg_types('commonpath', *paths) - raise - - -try: - # The genericpath.isdir implementation uses os.stat and checks the mode - # attribute to tell whether or not the path is a directory. - # This is overkill on Windows - just pass the path to GetFileAttributes - # and check the attribute from there. - from nt import _isdir as isdir -except ImportError: - # Use genericpath.isdir as imported above. - pass diff --git a/python/Lib/nturl2path.py b/python/Lib/nturl2path.py deleted file mode 100644 index b4ba677..0000000 --- a/python/Lib/nturl2path.py +++ /dev/null @@ -1,81 +0,0 @@ -"""Convert a NT pathname to a file URL and vice versa. - -This module only exists to provide OS-specific code -for urllib.requests, thus do not use directly. -""" -# Testing is done through test_urllib. - -def url2pathname(url): - """OS-specific conversion from a relative URL of the 'file' scheme - to a file system path; not recommended for general use.""" - # e.g. - # ///C|/foo/bar/spam.foo - # and - # ///C:/foo/bar/spam.foo - # become - # C:\foo\bar\spam.foo - import string, urllib.parse - # Windows itself uses ":" even in URLs. - url = url.replace(':', '|') - if not '|' in url: - # No drive specifier, just convert slashes - if url[:4] == '////': - # path is something like ////host/path/on/remote/host - # convert this to \\host\path\on\remote\host - # (notice halving of slashes at the start of the path) - url = url[2:] - components = url.split('/') - # make sure not to convert quoted slashes :-) - return urllib.parse.unquote('\\'.join(components)) - comp = url.split('|') - if len(comp) != 2 or comp[0][-1] not in string.ascii_letters: - error = 'Bad URL: ' + url - raise OSError(error) - drive = comp[0][-1].upper() - components = comp[1].split('/') - path = drive + ':' - for comp in components: - if comp: - path = path + '\\' + urllib.parse.unquote(comp) - # Issue #11474 - handing url such as |c/| - if path.endswith(':') and url.endswith('/'): - path += '\\' - return path - -def pathname2url(p): - """OS-specific conversion from a file system path to a relative URL - of the 'file' scheme; not recommended for general use.""" - # e.g. - # C:\foo\bar\spam.foo - # becomes - # ///C:/foo/bar/spam.foo - import urllib.parse - # First, clean up some special forms. We are going to sacrifice - # the additional information anyway - if p[:4] == '\\\\?\\': - p = p[4:] - if p[:4].upper() == 'UNC\\': - p = '\\' + p[4:] - elif p[1:2] != ':': - raise OSError('Bad path: ' + p) - if not ':' in p: - # No drive specifier, just convert slashes and quote the name - if p[:2] == '\\\\': - # path is something like \\host\path\on\remote\host - # convert this to ////host/path/on/remote/host - # (notice doubling of slashes at the start of the path) - p = '\\\\' + p - components = p.split('\\') - return urllib.parse.quote('/'.join(components)) - comp = p.split(':', maxsplit=2) - if len(comp) != 2 or len(comp[0]) > 1: - error = 'Bad path: ' + p - raise OSError(error) - - drive = urllib.parse.quote(comp[0].upper()) - components = comp[1].split('\\') - path = '///' + drive + ':' - for comp in components: - if comp: - path = path + '/' + urllib.parse.quote(comp) - return path diff --git a/python/Lib/numbers.py b/python/Lib/numbers.py deleted file mode 100644 index a96bfad..0000000 --- a/python/Lib/numbers.py +++ /dev/null @@ -1,393 +0,0 @@ -# Copyright 2007 Google, Inc. All Rights Reserved. -# Licensed to PSF under a Contributor Agreement. - -"""Abstract Base Classes (ABCs) for numbers, according to PEP 3141. - -TODO: Fill out more detailed documentation on the operators.""" - -from abc import ABCMeta, abstractmethod - -__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] - -class Number(metaclass=ABCMeta): - """All numbers inherit from this class. - - If you just want to check if an argument x is a number, without - caring what kind, use isinstance(x, Number). - """ - __slots__ = () - - # Concrete numeric types must provide their own hash implementation - __hash__ = None - - -## Notes on Decimal -## ---------------- -## Decimal has all of the methods specified by the Real abc, but it should -## not be registered as a Real because decimals do not interoperate with -## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But, -## abstract reals are expected to interoperate (i.e. R1 + R2 should be -## expected to work if R1 and R2 are both Reals). - -class Complex(Number): - """Complex defines the operations that work on the builtin complex type. - - In short, those are: a conversion to complex, .real, .imag, +, -, - *, /, **, abs(), .conjugate, ==, and !=. - - If it is given heterogeneous arguments, and doesn't have special - knowledge about them, it should fall back to the builtin complex - type as described below. - """ - - __slots__ = () - - @abstractmethod - def __complex__(self): - """Return a builtin complex instance. Called for complex(self).""" - - def __bool__(self): - """True if self != 0. Called for bool(self).""" - return self != 0 - - @property - @abstractmethod - def real(self): - """Retrieve the real component of this number. - - This should subclass Real. - """ - raise NotImplementedError - - @property - @abstractmethod - def imag(self): - """Retrieve the imaginary component of this number. - - This should subclass Real. - """ - raise NotImplementedError - - @abstractmethod - def __add__(self, other): - """self + other""" - raise NotImplementedError - - @abstractmethod - def __radd__(self, other): - """other + self""" - raise NotImplementedError - - @abstractmethod - def __neg__(self): - """-self""" - raise NotImplementedError - - @abstractmethod - def __pos__(self): - """+self""" - raise NotImplementedError - - def __sub__(self, other): - """self - other""" - return self + -other - - def __rsub__(self, other): - """other - self""" - return -self + other - - @abstractmethod - def __mul__(self, other): - """self * other""" - raise NotImplementedError - - @abstractmethod - def __rmul__(self, other): - """other * self""" - raise NotImplementedError - - @abstractmethod - def __truediv__(self, other): - """self / other: Should promote to float when necessary.""" - raise NotImplementedError - - @abstractmethod - def __rtruediv__(self, other): - """other / self""" - raise NotImplementedError - - @abstractmethod - def __pow__(self, exponent): - """self**exponent; should promote to float or complex when necessary.""" - raise NotImplementedError - - @abstractmethod - def __rpow__(self, base): - """base ** self""" - raise NotImplementedError - - @abstractmethod - def __abs__(self): - """Returns the Real distance from 0. Called for abs(self).""" - raise NotImplementedError - - @abstractmethod - def conjugate(self): - """(x+y*i).conjugate() returns (x-y*i).""" - raise NotImplementedError - - @abstractmethod - def __eq__(self, other): - """self == other""" - raise NotImplementedError - -Complex.register(complex) - - -class Real(Complex): - """To Complex, Real adds the operations that work on real numbers. - - In short, those are: a conversion to float, trunc(), divmod, - %, <, <=, >, and >=. - - Real also provides defaults for the derived operations. - """ - - __slots__ = () - - @abstractmethod - def __float__(self): - """Any Real can be converted to a native float object. - - Called for float(self).""" - raise NotImplementedError - - @abstractmethod - def __trunc__(self): - """trunc(self): Truncates self to an Integral. - - Returns an Integral i such that: - * i>0 iff self>0; - * abs(i) <= abs(self); - * for any Integral j satisfying the first two conditions, - abs(i) >= abs(j) [i.e. i has "maximal" abs among those]. - i.e. "truncate towards 0". - """ - raise NotImplementedError - - @abstractmethod - def __floor__(self): - """Finds the greatest Integral <= self.""" - raise NotImplementedError - - @abstractmethod - def __ceil__(self): - """Finds the least Integral >= self.""" - raise NotImplementedError - - @abstractmethod - def __round__(self, ndigits=None): - """Rounds self to ndigits decimal places, defaulting to 0. - - If ndigits is omitted or None, returns an Integral, otherwise - returns a Real. Rounds half toward even. - """ - raise NotImplementedError - - def __divmod__(self, other): - """divmod(self, other): The pair (self // other, self % other). - - Sometimes this can be computed faster than the pair of - operations. - """ - return (self // other, self % other) - - def __rdivmod__(self, other): - """divmod(other, self): The pair (self // other, self % other). - - Sometimes this can be computed faster than the pair of - operations. - """ - return (other // self, other % self) - - @abstractmethod - def __floordiv__(self, other): - """self // other: The floor() of self/other.""" - raise NotImplementedError - - @abstractmethod - def __rfloordiv__(self, other): - """other // self: The floor() of other/self.""" - raise NotImplementedError - - @abstractmethod - def __mod__(self, other): - """self % other""" - raise NotImplementedError - - @abstractmethod - def __rmod__(self, other): - """other % self""" - raise NotImplementedError - - @abstractmethod - def __lt__(self, other): - """self < other - - < on Reals defines a total ordering, except perhaps for NaN.""" - raise NotImplementedError - - @abstractmethod - def __le__(self, other): - """self <= other""" - raise NotImplementedError - - # Concrete implementations of Complex abstract methods. - def __complex__(self): - """complex(self) == complex(float(self), 0)""" - return complex(float(self)) - - @property - def real(self): - """Real numbers are their real component.""" - return +self - - @property - def imag(self): - """Real numbers have no imaginary component.""" - return 0 - - def conjugate(self): - """Conjugate is a no-op for Reals.""" - return +self - -Real.register(float) - - -class Rational(Real): - """.numerator and .denominator should be in lowest terms.""" - - __slots__ = () - - @property - @abstractmethod - def numerator(self): - raise NotImplementedError - - @property - @abstractmethod - def denominator(self): - raise NotImplementedError - - # Concrete implementation of Real's conversion to float. - def __float__(self): - """float(self) = self.numerator / self.denominator - - It's important that this conversion use the integer's "true" - division rather than casting one side to float before dividing - so that ratios of huge integers convert without overflowing. - - """ - return int(self.numerator) / int(self.denominator) - - -class Integral(Rational): - """Integral adds methods that work on integral numbers. - - In short, these are conversion to int, pow with modulus, and the - bit-string operations. - """ - - __slots__ = () - - @abstractmethod - def __int__(self): - """int(self)""" - raise NotImplementedError - - def __index__(self): - """Called whenever an index is needed, such as in slicing""" - return int(self) - - @abstractmethod - def __pow__(self, exponent, modulus=None): - """self ** exponent % modulus, but maybe faster. - - Accept the modulus argument if you want to support the - 3-argument version of pow(). Raise a TypeError if exponent < 0 - or any argument isn't Integral. Otherwise, just implement the - 2-argument version described in Complex. - """ - raise NotImplementedError - - @abstractmethod - def __lshift__(self, other): - """self << other""" - raise NotImplementedError - - @abstractmethod - def __rlshift__(self, other): - """other << self""" - raise NotImplementedError - - @abstractmethod - def __rshift__(self, other): - """self >> other""" - raise NotImplementedError - - @abstractmethod - def __rrshift__(self, other): - """other >> self""" - raise NotImplementedError - - @abstractmethod - def __and__(self, other): - """self & other""" - raise NotImplementedError - - @abstractmethod - def __rand__(self, other): - """other & self""" - raise NotImplementedError - - @abstractmethod - def __xor__(self, other): - """self ^ other""" - raise NotImplementedError - - @abstractmethod - def __rxor__(self, other): - """other ^ self""" - raise NotImplementedError - - @abstractmethod - def __or__(self, other): - """self | other""" - raise NotImplementedError - - @abstractmethod - def __ror__(self, other): - """other | self""" - raise NotImplementedError - - @abstractmethod - def __invert__(self): - """~self""" - raise NotImplementedError - - # Concrete implementations of Rational and Real abstract methods. - def __float__(self): - """float(self) == float(int(self))""" - return float(int(self)) - - @property - def numerator(self): - """Integers are their own numerators.""" - return +self - - @property - def denominator(self): - """Integers have a denominator of 1.""" - return 1 - -Integral.register(int) diff --git a/python/Lib/opcode.py b/python/Lib/opcode.py deleted file mode 100644 index 9e55a6c..0000000 --- a/python/Lib/opcode.py +++ /dev/null @@ -1,407 +0,0 @@ - -""" -opcode module - potentially shared between dis and other modules which -operate on bytecodes (e.g. peephole optimizers). -""" - -__all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs", - "haslocal", "hascompare", "hasfree", "opname", "opmap", - "HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs"] - -# It's a chicken-and-egg I'm afraid: -# We're imported before _opcode's made. -# With exception unheeded -# (stack_effect is not needed) -# Both our chickens and eggs are allayed. -# --Larry Hastings, 2013/11/23 - -try: - from _opcode import stack_effect - __all__.append('stack_effect') -except ImportError: - pass - -cmp_op = ('<', '<=', '==', '!=', '>', '>=') - -hasconst = [] -hasname = [] -hasjrel = [] -hasjabs = [] -haslocal = [] -hascompare = [] -hasfree = [] -hasnargs = [] # unused - -opmap = {} -opname = ['<%r>' % (op,) for op in range(256)] - -def def_op(name, op): - opname[op] = name - opmap[name] = op - -def name_op(name, op): - def_op(name, op) - hasname.append(op) - -def jrel_op(name, op): - def_op(name, op) - hasjrel.append(op) - -def jabs_op(name, op): - def_op(name, op) - hasjabs.append(op) - -# Instruction opcodes for compiled code -# Blank lines correspond to available opcodes - -def_op('CACHE', 0) -def_op('POP_TOP', 1) -def_op('PUSH_NULL', 2) - -def_op('NOP', 9) -def_op('UNARY_POSITIVE', 10) -def_op('UNARY_NEGATIVE', 11) -def_op('UNARY_NOT', 12) - -def_op('UNARY_INVERT', 15) - -def_op('BINARY_SUBSCR', 25) - -def_op('GET_LEN', 30) -def_op('MATCH_MAPPING', 31) -def_op('MATCH_SEQUENCE', 32) -def_op('MATCH_KEYS', 33) - -def_op('PUSH_EXC_INFO', 35) -def_op('CHECK_EXC_MATCH', 36) -def_op('CHECK_EG_MATCH', 37) - -def_op('WITH_EXCEPT_START', 49) -def_op('GET_AITER', 50) -def_op('GET_ANEXT', 51) -def_op('BEFORE_ASYNC_WITH', 52) -def_op('BEFORE_WITH', 53) -def_op('END_ASYNC_FOR', 54) - -def_op('STORE_SUBSCR', 60) -def_op('DELETE_SUBSCR', 61) - -def_op('GET_ITER', 68) -def_op('GET_YIELD_FROM_ITER', 69) -def_op('PRINT_EXPR', 70) -def_op('LOAD_BUILD_CLASS', 71) - -def_op('LOAD_ASSERTION_ERROR', 74) -def_op('RETURN_GENERATOR', 75) - -def_op('LIST_TO_TUPLE', 82) -def_op('RETURN_VALUE', 83) -def_op('IMPORT_STAR', 84) -def_op('SETUP_ANNOTATIONS', 85) -def_op('YIELD_VALUE', 86) -def_op('ASYNC_GEN_WRAP', 87) -def_op('PREP_RERAISE_STAR', 88) -def_op('POP_EXCEPT', 89) - -HAVE_ARGUMENT = 90 # Opcodes from here have an argument: - -name_op('STORE_NAME', 90) # Index in name list -name_op('DELETE_NAME', 91) # "" -def_op('UNPACK_SEQUENCE', 92) # Number of tuple items -jrel_op('FOR_ITER', 93) -def_op('UNPACK_EX', 94) -name_op('STORE_ATTR', 95) # Index in name list -name_op('DELETE_ATTR', 96) # "" -name_op('STORE_GLOBAL', 97) # "" -name_op('DELETE_GLOBAL', 98) # "" -def_op('SWAP', 99) -def_op('LOAD_CONST', 100) # Index in const list -hasconst.append(100) -name_op('LOAD_NAME', 101) # Index in name list -def_op('BUILD_TUPLE', 102) # Number of tuple items -def_op('BUILD_LIST', 103) # Number of list items -def_op('BUILD_SET', 104) # Number of set items -def_op('BUILD_MAP', 105) # Number of dict entries -name_op('LOAD_ATTR', 106) # Index in name list -def_op('COMPARE_OP', 107) # Comparison operator -hascompare.append(107) -name_op('IMPORT_NAME', 108) # Index in name list -name_op('IMPORT_FROM', 109) # Index in name list -jrel_op('JUMP_FORWARD', 110) # Number of words to skip -jrel_op('JUMP_IF_FALSE_OR_POP', 111) # Number of words to skip -jrel_op('JUMP_IF_TRUE_OR_POP', 112) # "" -jrel_op('POP_JUMP_FORWARD_IF_FALSE', 114) -jrel_op('POP_JUMP_FORWARD_IF_TRUE', 115) -name_op('LOAD_GLOBAL', 116) # Index in name list -def_op('IS_OP', 117) -def_op('CONTAINS_OP', 118) -def_op('RERAISE', 119) -def_op('COPY', 120) -def_op('BINARY_OP', 122) -jrel_op('SEND', 123) # Number of bytes to skip -def_op('LOAD_FAST', 124) # Local variable number -haslocal.append(124) -def_op('STORE_FAST', 125) # Local variable number -haslocal.append(125) -def_op('DELETE_FAST', 126) # Local variable number -haslocal.append(126) -jrel_op('POP_JUMP_FORWARD_IF_NOT_NONE', 128) -jrel_op('POP_JUMP_FORWARD_IF_NONE', 129) -def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3) -def_op('GET_AWAITABLE', 131) -def_op('MAKE_FUNCTION', 132) # Flags -def_op('BUILD_SLICE', 133) # Number of items -jrel_op('JUMP_BACKWARD_NO_INTERRUPT', 134) # Number of words to skip (backwards) -def_op('MAKE_CELL', 135) -hasfree.append(135) -def_op('LOAD_CLOSURE', 136) -hasfree.append(136) -def_op('LOAD_DEREF', 137) -hasfree.append(137) -def_op('STORE_DEREF', 138) -hasfree.append(138) -def_op('DELETE_DEREF', 139) -hasfree.append(139) -jrel_op('JUMP_BACKWARD', 140) # Number of words to skip (backwards) - -def_op('CALL_FUNCTION_EX', 142) # Flags - -def_op('EXTENDED_ARG', 144) -EXTENDED_ARG = 144 -def_op('LIST_APPEND', 145) -def_op('SET_ADD', 146) -def_op('MAP_ADD', 147) -def_op('LOAD_CLASSDEREF', 148) -hasfree.append(148) -def_op('COPY_FREE_VARS', 149) - -def_op('RESUME', 151) # This must be kept in sync with deepfreeze.py -def_op('MATCH_CLASS', 152) - -def_op('FORMAT_VALUE', 155) -def_op('BUILD_CONST_KEY_MAP', 156) -def_op('BUILD_STRING', 157) - -name_op('LOAD_METHOD', 160) - -def_op('LIST_EXTEND', 162) -def_op('SET_UPDATE', 163) -def_op('DICT_MERGE', 164) -def_op('DICT_UPDATE', 165) -def_op('PRECALL', 166) - -def_op('CALL', 171) -def_op('KW_NAMES', 172) -hasconst.append(172) - -jrel_op('POP_JUMP_BACKWARD_IF_NOT_NONE', 173) -jrel_op('POP_JUMP_BACKWARD_IF_NONE', 174) -jrel_op('POP_JUMP_BACKWARD_IF_FALSE', 175) -jrel_op('POP_JUMP_BACKWARD_IF_TRUE', 176) - - -del def_op, name_op, jrel_op, jabs_op - -_nb_ops = [ - ("NB_ADD", "+"), - ("NB_AND", "&"), - ("NB_FLOOR_DIVIDE", "//"), - ("NB_LSHIFT", "<<"), - ("NB_MATRIX_MULTIPLY", "@"), - ("NB_MULTIPLY", "*"), - ("NB_REMAINDER", "%"), - ("NB_OR", "|"), - ("NB_POWER", "**"), - ("NB_RSHIFT", ">>"), - ("NB_SUBTRACT", "-"), - ("NB_TRUE_DIVIDE", "/"), - ("NB_XOR", "^"), - ("NB_INPLACE_ADD", "+="), - ("NB_INPLACE_AND", "&="), - ("NB_INPLACE_FLOOR_DIVIDE", "//="), - ("NB_INPLACE_LSHIFT", "<<="), - ("NB_INPLACE_MATRIX_MULTIPLY", "@="), - ("NB_INPLACE_MULTIPLY", "*="), - ("NB_INPLACE_REMAINDER", "%="), - ("NB_INPLACE_OR", "|="), - ("NB_INPLACE_POWER", "**="), - ("NB_INPLACE_RSHIFT", ">>="), - ("NB_INPLACE_SUBTRACT", "-="), - ("NB_INPLACE_TRUE_DIVIDE", "/="), - ("NB_INPLACE_XOR", "^="), -] - -_specializations = { - "BINARY_OP": [ - "BINARY_OP_ADAPTIVE", - "BINARY_OP_ADD_FLOAT", - "BINARY_OP_ADD_INT", - "BINARY_OP_ADD_UNICODE", - "BINARY_OP_INPLACE_ADD_UNICODE", - "BINARY_OP_MULTIPLY_FLOAT", - "BINARY_OP_MULTIPLY_INT", - "BINARY_OP_SUBTRACT_FLOAT", - "BINARY_OP_SUBTRACT_INT", - ], - "BINARY_SUBSCR": [ - "BINARY_SUBSCR_ADAPTIVE", - "BINARY_SUBSCR_DICT", - "BINARY_SUBSCR_GETITEM", - "BINARY_SUBSCR_LIST_INT", - "BINARY_SUBSCR_TUPLE_INT", - ], - "CALL": [ - "CALL_ADAPTIVE", - "CALL_PY_EXACT_ARGS", - "CALL_PY_WITH_DEFAULTS", - ], - "COMPARE_OP": [ - "COMPARE_OP_ADAPTIVE", - "COMPARE_OP_FLOAT_JUMP", - "COMPARE_OP_INT_JUMP", - "COMPARE_OP_STR_JUMP", - ], - "EXTENDED_ARG": [ - "EXTENDED_ARG_QUICK", - ], - "JUMP_BACKWARD": [ - "JUMP_BACKWARD_QUICK", - ], - "LOAD_ATTR": [ - "LOAD_ATTR_ADAPTIVE", - "LOAD_ATTR_INSTANCE_VALUE", - "LOAD_ATTR_MODULE", - "LOAD_ATTR_SLOT", - "LOAD_ATTR_WITH_HINT", - ], - "LOAD_CONST": [ - "LOAD_CONST__LOAD_FAST", - ], - "LOAD_FAST": [ - "LOAD_FAST__LOAD_CONST", - "LOAD_FAST__LOAD_FAST", - ], - "LOAD_GLOBAL": [ - "LOAD_GLOBAL_ADAPTIVE", - "LOAD_GLOBAL_BUILTIN", - "LOAD_GLOBAL_MODULE", - ], - "LOAD_METHOD": [ - "LOAD_METHOD_ADAPTIVE", - "LOAD_METHOD_CLASS", - "LOAD_METHOD_MODULE", - "LOAD_METHOD_NO_DICT", - "LOAD_METHOD_WITH_DICT", - "LOAD_METHOD_WITH_VALUES", - ], - "PRECALL": [ - "PRECALL_ADAPTIVE", - "PRECALL_BOUND_METHOD", - "PRECALL_BUILTIN_CLASS", - "PRECALL_BUILTIN_FAST_WITH_KEYWORDS", - "PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", - "PRECALL_NO_KW_BUILTIN_FAST", - "PRECALL_NO_KW_BUILTIN_O", - "PRECALL_NO_KW_ISINSTANCE", - "PRECALL_NO_KW_LEN", - "PRECALL_NO_KW_LIST_APPEND", - "PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST", - "PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", - "PRECALL_NO_KW_METHOD_DESCRIPTOR_O", - "PRECALL_NO_KW_STR_1", - "PRECALL_NO_KW_TUPLE_1", - "PRECALL_NO_KW_TYPE_1", - "PRECALL_PYFUNC", - ], - "RESUME": [ - "RESUME_QUICK", - ], - "STORE_ATTR": [ - "STORE_ATTR_ADAPTIVE", - "STORE_ATTR_INSTANCE_VALUE", - "STORE_ATTR_SLOT", - "STORE_ATTR_WITH_HINT", - ], - "STORE_FAST": [ - "STORE_FAST__LOAD_FAST", - "STORE_FAST__STORE_FAST", - ], - "STORE_SUBSCR": [ - "STORE_SUBSCR_ADAPTIVE", - "STORE_SUBSCR_DICT", - "STORE_SUBSCR_LIST_INT", - ], - "UNPACK_SEQUENCE": [ - "UNPACK_SEQUENCE_ADAPTIVE", - "UNPACK_SEQUENCE_LIST", - "UNPACK_SEQUENCE_TUPLE", - "UNPACK_SEQUENCE_TWO_TUPLE", - ], -} -_specialized_instructions = [ - opcode for family in _specializations.values() for opcode in family -] -_specialization_stats = [ - "success", - "failure", - "hit", - "deferred", - "miss", - "deopt", -] - -_cache_format = { - "LOAD_GLOBAL": { - "counter": 1, - "index": 1, - "module_keys_version": 2, - "builtin_keys_version": 1, - }, - "BINARY_OP": { - "counter": 1, - }, - "UNPACK_SEQUENCE": { - "counter": 1, - }, - "COMPARE_OP": { - "counter": 1, - "mask": 1, - }, - "BINARY_SUBSCR": { - "counter": 1, - "type_version": 2, - "func_version": 1, - }, - "LOAD_ATTR": { - "counter": 1, - "version": 2, - "index": 1, - }, - "STORE_ATTR": { - "counter": 1, - "version": 2, - "index": 1, - }, - "LOAD_METHOD": { - "counter": 1, - "type_version": 2, - "dict_offset": 1, - "keys_version": 2, - "descr": 4, - }, - "CALL": { - "counter": 1, - "func_version": 2, - "min_args": 1, - }, - "PRECALL": { - "counter": 1, - }, - "STORE_SUBSCR": { - "counter": 1, - }, -} - -_inline_cache_entries = [ - sum(_cache_format.get(opname[opcode], {}).values()) for opcode in range(256) -] diff --git a/python/Lib/operator.py b/python/Lib/operator.py deleted file mode 100644 index 0b2be4a..0000000 --- a/python/Lib/operator.py +++ /dev/null @@ -1,467 +0,0 @@ -""" -Operator Interface - -This module exports a set of functions corresponding to the intrinsic -operators of Python. For example, operator.add(x, y) is equivalent -to the expression x+y. The function names are those used for special -methods; variants without leading and trailing '__' are also provided -for convenience. - -This is the pure Python implementation of the module. -""" - -__all__ = ['abs', 'add', 'and_', 'attrgetter', 'call', 'concat', 'contains', 'countOf', - 'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand', - 'iconcat', 'ifloordiv', 'ilshift', 'imatmul', 'imod', 'imul', - 'index', 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift', - 'is_', 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le', - 'length_hint', 'lshift', 'lt', 'matmul', 'methodcaller', 'mod', - 'mul', 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', - 'setitem', 'sub', 'truediv', 'truth', 'xor'] - -from builtins import abs as _abs - - -# Comparison Operations *******************************************************# - -def lt(a, b): - "Same as a < b." - return a < b - -def le(a, b): - "Same as a <= b." - return a <= b - -def eq(a, b): - "Same as a == b." - return a == b - -def ne(a, b): - "Same as a != b." - return a != b - -def ge(a, b): - "Same as a >= b." - return a >= b - -def gt(a, b): - "Same as a > b." - return a > b - -# Logical Operations **********************************************************# - -def not_(a): - "Same as not a." - return not a - -def truth(a): - "Return True if a is true, False otherwise." - return True if a else False - -def is_(a, b): - "Same as a is b." - return a is b - -def is_not(a, b): - "Same as a is not b." - return a is not b - -# Mathematical/Bitwise Operations *********************************************# - -def abs(a): - "Same as abs(a)." - return _abs(a) - -def add(a, b): - "Same as a + b." - return a + b - -def and_(a, b): - "Same as a & b." - return a & b - -def floordiv(a, b): - "Same as a // b." - return a // b - -def index(a): - "Same as a.__index__()." - return a.__index__() - -def inv(a): - "Same as ~a." - return ~a -invert = inv - -def lshift(a, b): - "Same as a << b." - return a << b - -def mod(a, b): - "Same as a % b." - return a % b - -def mul(a, b): - "Same as a * b." - return a * b - -def matmul(a, b): - "Same as a @ b." - return a @ b - -def neg(a): - "Same as -a." - return -a - -def or_(a, b): - "Same as a | b." - return a | b - -def pos(a): - "Same as +a." - return +a - -def pow(a, b): - "Same as a ** b." - return a ** b - -def rshift(a, b): - "Same as a >> b." - return a >> b - -def sub(a, b): - "Same as a - b." - return a - b - -def truediv(a, b): - "Same as a / b." - return a / b - -def xor(a, b): - "Same as a ^ b." - return a ^ b - -# Sequence Operations *********************************************************# - -def concat(a, b): - "Same as a + b, for a and b sequences." - if not hasattr(a, '__getitem__'): - msg = "'%s' object can't be concatenated" % type(a).__name__ - raise TypeError(msg) - return a + b - -def contains(a, b): - "Same as b in a (note reversed operands)." - return b in a - -def countOf(a, b): - "Return the number of items in a which are, or which equal, b." - count = 0 - for i in a: - if i is b or i == b: - count += 1 - return count - -def delitem(a, b): - "Same as del a[b]." - del a[b] - -def getitem(a, b): - "Same as a[b]." - return a[b] - -def indexOf(a, b): - "Return the first index of b in a." - for i, j in enumerate(a): - if j is b or j == b: - return i - else: - raise ValueError('sequence.index(x): x not in sequence') - -def setitem(a, b, c): - "Same as a[b] = c." - a[b] = c - -def length_hint(obj, default=0): - """ - Return an estimate of the number of items in obj. - This is useful for presizing containers when building from an iterable. - - If the object supports len(), the result will be exact. Otherwise, it may - over- or under-estimate by an arbitrary amount. The result will be an - integer >= 0. - """ - if not isinstance(default, int): - msg = ("'%s' object cannot be interpreted as an integer" % - type(default).__name__) - raise TypeError(msg) - - try: - return len(obj) - except TypeError: - pass - - try: - hint = type(obj).__length_hint__ - except AttributeError: - return default - - try: - val = hint(obj) - except TypeError: - return default - if val is NotImplemented: - return default - if not isinstance(val, int): - msg = ('__length_hint__ must be integer, not %s' % - type(val).__name__) - raise TypeError(msg) - if val < 0: - msg = '__length_hint__() should return >= 0' - raise ValueError(msg) - return val - -# Other Operations ************************************************************# - -def call(obj, /, *args, **kwargs): - """Same as obj(*args, **kwargs).""" - return obj(*args, **kwargs) - -# Generalized Lookup Objects **************************************************# - -class attrgetter: - """ - Return a callable object that fetches the given attribute(s) from its operand. - After f = attrgetter('name'), the call f(r) returns r.name. - After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date). - After h = attrgetter('name.first', 'name.last'), the call h(r) returns - (r.name.first, r.name.last). - """ - __slots__ = ('_attrs', '_call') - - def __init__(self, attr, *attrs): - if not attrs: - if not isinstance(attr, str): - raise TypeError('attribute name must be a string') - self._attrs = (attr,) - names = attr.split('.') - def func(obj): - for name in names: - obj = getattr(obj, name) - return obj - self._call = func - else: - self._attrs = (attr,) + attrs - getters = tuple(map(attrgetter, self._attrs)) - def func(obj): - return tuple(getter(obj) for getter in getters) - self._call = func - - def __call__(self, obj): - return self._call(obj) - - def __repr__(self): - return '%s.%s(%s)' % (self.__class__.__module__, - self.__class__.__qualname__, - ', '.join(map(repr, self._attrs))) - - def __reduce__(self): - return self.__class__, self._attrs - -class itemgetter: - """ - Return a callable object that fetches the given item(s) from its operand. - After f = itemgetter(2), the call f(r) returns r[2]. - After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3]) - """ - __slots__ = ('_items', '_call') - - def __init__(self, item, *items): - if not items: - self._items = (item,) - def func(obj): - return obj[item] - self._call = func - else: - self._items = items = (item,) + items - def func(obj): - return tuple(obj[i] for i in items) - self._call = func - - def __call__(self, obj): - return self._call(obj) - - def __repr__(self): - return '%s.%s(%s)' % (self.__class__.__module__, - self.__class__.__name__, - ', '.join(map(repr, self._items))) - - def __reduce__(self): - return self.__class__, self._items - -class methodcaller: - """ - Return a callable object that calls the given method on its operand. - After f = methodcaller('name'), the call f(r) returns r.name(). - After g = methodcaller('name', 'date', foo=1), the call g(r) returns - r.name('date', foo=1). - """ - __slots__ = ('_name', '_args', '_kwargs') - - def __init__(self, name, /, *args, **kwargs): - self._name = name - if not isinstance(self._name, str): - raise TypeError('method name must be a string') - self._args = args - self._kwargs = kwargs - - def __call__(self, obj): - return getattr(obj, self._name)(*self._args, **self._kwargs) - - def __repr__(self): - args = [repr(self._name)] - args.extend(map(repr, self._args)) - args.extend('%s=%r' % (k, v) for k, v in self._kwargs.items()) - return '%s.%s(%s)' % (self.__class__.__module__, - self.__class__.__name__, - ', '.join(args)) - - def __reduce__(self): - if not self._kwargs: - return self.__class__, (self._name,) + self._args - else: - from functools import partial - return partial(self.__class__, self._name, **self._kwargs), self._args - - -# In-place Operations *********************************************************# - -def iadd(a, b): - "Same as a += b." - a += b - return a - -def iand(a, b): - "Same as a &= b." - a &= b - return a - -def iconcat(a, b): - "Same as a += b, for a and b sequences." - if not hasattr(a, '__getitem__'): - msg = "'%s' object can't be concatenated" % type(a).__name__ - raise TypeError(msg) - a += b - return a - -def ifloordiv(a, b): - "Same as a //= b." - a //= b - return a - -def ilshift(a, b): - "Same as a <<= b." - a <<= b - return a - -def imod(a, b): - "Same as a %= b." - a %= b - return a - -def imul(a, b): - "Same as a *= b." - a *= b - return a - -def imatmul(a, b): - "Same as a @= b." - a @= b - return a - -def ior(a, b): - "Same as a |= b." - a |= b - return a - -def ipow(a, b): - "Same as a **= b." - a **=b - return a - -def irshift(a, b): - "Same as a >>= b." - a >>= b - return a - -def isub(a, b): - "Same as a -= b." - a -= b - return a - -def itruediv(a, b): - "Same as a /= b." - a /= b - return a - -def ixor(a, b): - "Same as a ^= b." - a ^= b - return a - - -try: - from _operator import * -except ImportError: - pass -else: - from _operator import __doc__ - -# All of these "__func__ = func" assignments have to happen after importing -# from _operator to make sure they're set to the right function -__lt__ = lt -__le__ = le -__eq__ = eq -__ne__ = ne -__ge__ = ge -__gt__ = gt -__not__ = not_ -__abs__ = abs -__add__ = add -__and__ = and_ -__call__ = call -__floordiv__ = floordiv -__index__ = index -__inv__ = inv -__invert__ = invert -__lshift__ = lshift -__mod__ = mod -__mul__ = mul -__matmul__ = matmul -__neg__ = neg -__or__ = or_ -__pos__ = pos -__pow__ = pow -__rshift__ = rshift -__sub__ = sub -__truediv__ = truediv -__xor__ = xor -__concat__ = concat -__contains__ = contains -__delitem__ = delitem -__getitem__ = getitem -__setitem__ = setitem -__iadd__ = iadd -__iand__ = iand -__iconcat__ = iconcat -__ifloordiv__ = ifloordiv -__ilshift__ = ilshift -__imod__ = imod -__imul__ = imul -__imatmul__ = imatmul -__ior__ = ior -__ipow__ = ipow -__irshift__ = irshift -__isub__ = isub -__itruediv__ = itruediv -__ixor__ = ixor diff --git a/python/Lib/os.py b/python/Lib/os.py deleted file mode 100644 index 70a775c..0000000 --- a/python/Lib/os.py +++ /dev/null @@ -1,1124 +0,0 @@ -r"""OS routines for NT or Posix depending on what system we're on. - -This exports: - - all functions from posix or nt, e.g. unlink, stat, etc. - - os.path is either posixpath or ntpath - - os.name is either 'posix' or 'nt' - - os.curdir is a string representing the current directory (always '.') - - os.pardir is a string representing the parent directory (always '..') - - os.sep is the (or a most common) pathname separator ('/' or '\\') - - os.extsep is the extension separator (always '.') - - os.altsep is the alternate pathname separator (None or '/') - - os.pathsep is the component separator used in $PATH etc - - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n') - - os.defpath is the default search path for executables - - os.devnull is the file path of the null device ('/dev/null', etc.) - -Programs that import and use 'os' stand a better chance of being -portable between different platforms. Of course, they must then -only use functions that are defined by all platforms (e.g., unlink -and opendir), and leave all pathname manipulation to os.path -(e.g., split and join). -""" - -#' -import abc -import sys -import stat as st - -from _collections_abc import _check_methods - -GenericAlias = type(list[int]) - -_names = sys.builtin_module_names - -# Note: more names are added to __all__ later. -__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep", - "defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR", - "SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen", - "extsep"] - -def _exists(name): - return name in globals() - -def _get_exports_list(module): - try: - return list(module.__all__) - except AttributeError: - return [n for n in dir(module) if n[0] != '_'] - -# Any new dependencies of the os module and/or changes in path separator -# requires updating importlib as well. -if 'posix' in _names: - name = 'posix' - linesep = '\n' - from posix import * - try: - from posix import _exit - __all__.append('_exit') - except ImportError: - pass - import posixpath as path - - try: - from posix import _have_functions - except ImportError: - pass - - import posix - __all__.extend(_get_exports_list(posix)) - del posix - -elif 'nt' in _names: - name = 'nt' - linesep = '\r\n' - from nt import * - try: - from nt import _exit - __all__.append('_exit') - except ImportError: - pass - import ntpath as path - - import nt - __all__.extend(_get_exports_list(nt)) - del nt - - try: - from nt import _have_functions - except ImportError: - pass - -else: - raise ImportError('no os specific module found') - -sys.modules['os.path'] = path -from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep, - devnull) - -del _names - - -if _exists("_have_functions"): - _globals = globals() - def _add(str, fn): - if (fn in _globals) and (str in _have_functions): - _set.add(_globals[fn]) - - _set = set() - _add("HAVE_FACCESSAT", "access") - _add("HAVE_FCHMODAT", "chmod") - _add("HAVE_FCHOWNAT", "chown") - _add("HAVE_FSTATAT", "stat") - _add("HAVE_FUTIMESAT", "utime") - _add("HAVE_LINKAT", "link") - _add("HAVE_MKDIRAT", "mkdir") - _add("HAVE_MKFIFOAT", "mkfifo") - _add("HAVE_MKNODAT", "mknod") - _add("HAVE_OPENAT", "open") - _add("HAVE_READLINKAT", "readlink") - _add("HAVE_RENAMEAT", "rename") - _add("HAVE_SYMLINKAT", "symlink") - _add("HAVE_UNLINKAT", "unlink") - _add("HAVE_UNLINKAT", "rmdir") - _add("HAVE_UTIMENSAT", "utime") - supports_dir_fd = _set - - _set = set() - _add("HAVE_FACCESSAT", "access") - supports_effective_ids = _set - - _set = set() - _add("HAVE_FCHDIR", "chdir") - _add("HAVE_FCHMOD", "chmod") - _add("HAVE_FCHOWN", "chown") - _add("HAVE_FDOPENDIR", "listdir") - _add("HAVE_FDOPENDIR", "scandir") - _add("HAVE_FEXECVE", "execve") - _set.add(stat) # fstat always works - _add("HAVE_FTRUNCATE", "truncate") - _add("HAVE_FUTIMENS", "utime") - _add("HAVE_FUTIMES", "utime") - _add("HAVE_FPATHCONF", "pathconf") - if _exists("statvfs") and _exists("fstatvfs"): # mac os x10.3 - _add("HAVE_FSTATVFS", "statvfs") - supports_fd = _set - - _set = set() - _add("HAVE_FACCESSAT", "access") - # Some platforms don't support lchmod(). Often the function exists - # anyway, as a stub that always returns ENOSUP or perhaps EOPNOTSUPP. - # (No, I don't know why that's a good design.) ./configure will detect - # this and reject it--so HAVE_LCHMOD still won't be defined on such - # platforms. This is Very Helpful. - # - # However, sometimes platforms without a working lchmod() *do* have - # fchmodat(). (Examples: Linux kernel 3.2 with glibc 2.15, - # OpenIndiana 3.x.) And fchmodat() has a flag that theoretically makes - # it behave like lchmod(). So in theory it would be a suitable - # replacement for lchmod(). But when lchmod() doesn't work, fchmodat()'s - # flag doesn't work *either*. Sadly ./configure isn't sophisticated - # enough to detect this condition--it only determines whether or not - # fchmodat() minimally works. - # - # Therefore we simply ignore fchmodat() when deciding whether or not - # os.chmod supports follow_symlinks. Just checking lchmod() is - # sufficient. After all--if you have a working fchmodat(), your - # lchmod() almost certainly works too. - # - # _add("HAVE_FCHMODAT", "chmod") - _add("HAVE_FCHOWNAT", "chown") - _add("HAVE_FSTATAT", "stat") - _add("HAVE_LCHFLAGS", "chflags") - _add("HAVE_LCHMOD", "chmod") - if _exists("lchown"): # mac os x10.3 - _add("HAVE_LCHOWN", "chown") - _add("HAVE_LINKAT", "link") - _add("HAVE_LUTIMES", "utime") - _add("HAVE_LSTAT", "stat") - _add("HAVE_FSTATAT", "stat") - _add("HAVE_UTIMENSAT", "utime") - _add("MS_WINDOWS", "stat") - supports_follow_symlinks = _set - - del _set - del _have_functions - del _globals - del _add - - -# Python uses fixed values for the SEEK_ constants; they are mapped -# to native constants if necessary in posixmodule.c -# Other possible SEEK values are directly imported from posixmodule.c -SEEK_SET = 0 -SEEK_CUR = 1 -SEEK_END = 2 - -# Super directory utilities. -# (Inspired by Eric Raymond; the doc strings are mostly his) - -def makedirs(name, mode=0o777, exist_ok=False): - """makedirs(name [, mode=0o777][, exist_ok=False]) - - Super-mkdir; create a leaf directory and all intermediate ones. Works like - mkdir, except that any intermediate path segment (not just the rightmost) - will be created if it does not exist. If the target directory already - exists, raise an OSError if exist_ok is False. Otherwise no exception is - raised. This is recursive. - - """ - head, tail = path.split(name) - if not tail: - head, tail = path.split(head) - if head and tail and not path.exists(head): - try: - makedirs(head, exist_ok=exist_ok) - except FileExistsError: - # Defeats race condition when another thread created the path - pass - cdir = curdir - if isinstance(tail, bytes): - cdir = bytes(curdir, 'ASCII') - if tail == cdir: # xxx/newdir/. exists if xxx/newdir exists - return - try: - mkdir(name, mode) - except OSError: - # Cannot rely on checking for EEXIST, since the operating system - # could give priority to other errors like EACCES or EROFS - if not exist_ok or not path.isdir(name): - raise - -def removedirs(name): - """removedirs(name) - - Super-rmdir; remove a leaf directory and all empty intermediate - ones. Works like rmdir except that, if the leaf directory is - successfully removed, directories corresponding to rightmost path - segments will be pruned away until either the whole path is - consumed or an error occurs. Errors during this latter phase are - ignored -- they generally mean that a directory was not empty. - - """ - rmdir(name) - head, tail = path.split(name) - if not tail: - head, tail = path.split(head) - while head and tail: - try: - rmdir(head) - except OSError: - break - head, tail = path.split(head) - -def renames(old, new): - """renames(old, new) - - Super-rename; create directories as necessary and delete any left - empty. Works like rename, except creation of any intermediate - directories needed to make the new pathname good is attempted - first. After the rename, directories corresponding to rightmost - path segments of the old name will be pruned until either the - whole path is consumed or a nonempty directory is found. - - Note: this function can fail with the new directory structure made - if you lack permissions needed to unlink the leaf directory or - file. - - """ - head, tail = path.split(new) - if head and tail and not path.exists(head): - makedirs(head) - rename(old, new) - head, tail = path.split(old) - if head and tail: - try: - removedirs(head) - except OSError: - pass - -__all__.extend(["makedirs", "removedirs", "renames"]) - -def walk(top, topdown=True, onerror=None, followlinks=False): - """Directory tree generator. - - For each directory in the directory tree rooted at top (including top - itself, but excluding '.' and '..'), yields a 3-tuple - - dirpath, dirnames, filenames - - dirpath is a string, the path to the directory. dirnames is a list of - the names of the subdirectories in dirpath (including symlinks to directories, - and excluding '.' and '..'). - filenames is a list of the names of the non-directory files in dirpath. - Note that the names in the lists are just names, with no path components. - To get a full path (which begins with top) to a file or directory in - dirpath, do os.path.join(dirpath, name). - - If optional arg 'topdown' is true or not specified, the triple for a - directory is generated before the triples for any of its subdirectories - (directories are generated top down). If topdown is false, the triple - for a directory is generated after the triples for all of its - subdirectories (directories are generated bottom up). - - When topdown is true, the caller can modify the dirnames list in-place - (e.g., via del or slice assignment), and walk will only recurse into the - subdirectories whose names remain in dirnames; this can be used to prune the - search, or to impose a specific order of visiting. Modifying dirnames when - topdown is false has no effect on the behavior of os.walk(), since the - directories in dirnames have already been generated by the time dirnames - itself is generated. No matter the value of topdown, the list of - subdirectories is retrieved before the tuples for the directory and its - subdirectories are generated. - - By default errors from the os.scandir() call are ignored. If - optional arg 'onerror' is specified, it should be a function; it - will be called with one argument, an OSError instance. It can - report the error to continue with the walk, or raise the exception - to abort the walk. Note that the filename is available as the - filename attribute of the exception object. - - By default, os.walk does not follow symbolic links to subdirectories on - systems that support them. In order to get this functionality, set the - optional argument 'followlinks' to true. - - Caution: if you pass a relative pathname for top, don't change the - current working directory between resumptions of walk. walk never - changes the current directory, and assumes that the client doesn't - either. - - Example: - - import os - from os.path import join, getsize - for root, dirs, files in os.walk('python/Lib/email'): - print(root, "consumes ") - print(sum(getsize(join(root, name)) for name in files), end=" ") - print("bytes in", len(files), "non-directory files") - if 'CVS' in dirs: - dirs.remove('CVS') # don't visit CVS directories - - """ - sys.audit("os.walk", top, topdown, onerror, followlinks) - return _walk(fspath(top), topdown, onerror, followlinks) - -def _walk(top, topdown, onerror, followlinks): - dirs = [] - nondirs = [] - walk_dirs = [] - - # We may not have read permission for top, in which case we can't - # get a list of the files the directory contains. os.walk - # always suppressed the exception then, rather than blow up for a - # minor reason when (say) a thousand readable directories are still - # left to visit. That logic is copied here. - try: - # Note that scandir is global in this module due - # to earlier import-*. - scandir_it = scandir(top) - except OSError as error: - if onerror is not None: - onerror(error) - return - - with scandir_it: - while True: - try: - try: - entry = next(scandir_it) - except StopIteration: - break - except OSError as error: - if onerror is not None: - onerror(error) - return - - try: - is_dir = entry.is_dir() - except OSError: - # If is_dir() raises an OSError, consider that the entry is not - # a directory, same behaviour than os.path.isdir(). - is_dir = False - - if is_dir: - dirs.append(entry.name) - else: - nondirs.append(entry.name) - - if not topdown and is_dir: - # Bottom-up: recurse into sub-directory, but exclude symlinks to - # directories if followlinks is False - if followlinks: - walk_into = True - else: - try: - is_symlink = entry.is_symlink() - except OSError: - # If is_symlink() raises an OSError, consider that the - # entry is not a symbolic link, same behaviour than - # os.path.islink(). - is_symlink = False - walk_into = not is_symlink - - if walk_into: - walk_dirs.append(entry.path) - - # Yield before recursion if going top down - if topdown: - yield top, dirs, nondirs - - # Recurse into sub-directories - islink, join = path.islink, path.join - for dirname in dirs: - new_path = join(top, dirname) - # Issue #23605: os.path.islink() is used instead of caching - # entry.is_symlink() result during the loop on os.scandir() because - # the caller can replace the directory entry during the "yield" - # above. - if followlinks or not islink(new_path): - yield from _walk(new_path, topdown, onerror, followlinks) - else: - # Recurse into sub-directories - for new_path in walk_dirs: - yield from _walk(new_path, topdown, onerror, followlinks) - # Yield after recursion if going bottom up - yield top, dirs, nondirs - -__all__.append("walk") - -if {open, stat} <= supports_dir_fd and {scandir, stat} <= supports_fd: - - def fwalk(top=".", topdown=True, onerror=None, *, follow_symlinks=False, dir_fd=None): - """Directory tree generator. - - This behaves exactly like walk(), except that it yields a 4-tuple - - dirpath, dirnames, filenames, dirfd - - `dirpath`, `dirnames` and `filenames` are identical to walk() output, - and `dirfd` is a file descriptor referring to the directory `dirpath`. - - The advantage of fwalk() over walk() is that it's safe against symlink - races (when follow_symlinks is False). - - If dir_fd is not None, it should be a file descriptor open to a directory, - and top should be relative; top will then be relative to that directory. - (dir_fd is always supported for fwalk.) - - Caution: - Since fwalk() yields file descriptors, those are only valid until the - next iteration step, so you should dup() them if you want to keep them - for a longer period. - - Example: - - import os - for root, dirs, files, rootfd in os.fwalk('python/Lib/email'): - print(root, "consumes", end="") - print(sum(os.stat(name, dir_fd=rootfd).st_size for name in files), - end="") - print("bytes in", len(files), "non-directory files") - if 'CVS' in dirs: - dirs.remove('CVS') # don't visit CVS directories - """ - sys.audit("os.fwalk", top, topdown, onerror, follow_symlinks, dir_fd) - top = fspath(top) - # Note: To guard against symlink races, we use the standard - # lstat()/open()/fstat() trick. - if not follow_symlinks: - orig_st = stat(top, follow_symlinks=False, dir_fd=dir_fd) - topfd = open(top, O_RDONLY, dir_fd=dir_fd) - try: - if (follow_symlinks or (st.S_ISDIR(orig_st.st_mode) and - path.samestat(orig_st, stat(topfd)))): - yield from _fwalk(topfd, top, isinstance(top, bytes), - topdown, onerror, follow_symlinks) - finally: - close(topfd) - - def _fwalk(topfd, toppath, isbytes, topdown, onerror, follow_symlinks): - # Note: This uses O(depth of the directory tree) file descriptors: if - # necessary, it can be adapted to only require O(1) FDs, see issue - # #13734. - - scandir_it = scandir(topfd) - dirs = [] - nondirs = [] - entries = None if topdown or follow_symlinks else [] - for entry in scandir_it: - name = entry.name - if isbytes: - name = fsencode(name) - try: - if entry.is_dir(): - dirs.append(name) - if entries is not None: - entries.append(entry) - else: - nondirs.append(name) - except OSError: - try: - # Add dangling symlinks, ignore disappeared files - if entry.is_symlink(): - nondirs.append(name) - except OSError: - pass - - if topdown: - yield toppath, dirs, nondirs, topfd - - for name in dirs if entries is None else zip(dirs, entries): - try: - if not follow_symlinks: - if topdown: - orig_st = stat(name, dir_fd=topfd, follow_symlinks=False) - else: - assert entries is not None - name, entry = name - orig_st = entry.stat(follow_symlinks=False) - dirfd = open(name, O_RDONLY, dir_fd=topfd) - except OSError as err: - if onerror is not None: - onerror(err) - continue - try: - if follow_symlinks or path.samestat(orig_st, stat(dirfd)): - dirpath = path.join(toppath, name) - yield from _fwalk(dirfd, dirpath, isbytes, - topdown, onerror, follow_symlinks) - finally: - close(dirfd) - - if not topdown: - yield toppath, dirs, nondirs, topfd - - __all__.append("fwalk") - -def execl(file, *args): - """execl(file, *args) - - Execute the executable file with argument list args, replacing the - current process. """ - execv(file, args) - -def execle(file, *args): - """execle(file, *args, env) - - Execute the executable file with argument list args and - environment env, replacing the current process. """ - env = args[-1] - execve(file, args[:-1], env) - -def execlp(file, *args): - """execlp(file, *args) - - Execute the executable file (which is searched for along $PATH) - with argument list args, replacing the current process. """ - execvp(file, args) - -def execlpe(file, *args): - """execlpe(file, *args, env) - - Execute the executable file (which is searched for along $PATH) - with argument list args and environment env, replacing the current - process. """ - env = args[-1] - execvpe(file, args[:-1], env) - -def execvp(file, args): - """execvp(file, args) - - Execute the executable file (which is searched for along $PATH) - with argument list args, replacing the current process. - args may be a list or tuple of strings. """ - _execvpe(file, args) - -def execvpe(file, args, env): - """execvpe(file, args, env) - - Execute the executable file (which is searched for along $PATH) - with argument list args and environment env, replacing the - current process. - args may be a list or tuple of strings. """ - _execvpe(file, args, env) - -__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"]) - -def _execvpe(file, args, env=None): - if env is not None: - exec_func = execve - argrest = (args, env) - else: - exec_func = execv - argrest = (args,) - env = environ - - if path.dirname(file): - exec_func(file, *argrest) - return - saved_exc = None - path_list = get_exec_path(env) - if name != 'nt': - file = fsencode(file) - path_list = map(fsencode, path_list) - for dir in path_list: - fullname = path.join(dir, file) - try: - exec_func(fullname, *argrest) - except (FileNotFoundError, NotADirectoryError) as e: - last_exc = e - except OSError as e: - last_exc = e - if saved_exc is None: - saved_exc = e - if saved_exc is not None: - raise saved_exc - raise last_exc - - -def get_exec_path(env=None): - """Returns the sequence of directories that will be searched for the - named executable (similar to a shell) when launching a process. - - *env* must be an environment variable dict or None. If *env* is None, - os.environ will be used. - """ - # Use a local import instead of a global import to limit the number of - # modules loaded at startup: the os module is always loaded at startup by - # Python. It may also avoid a bootstrap issue. - import warnings - - if env is None: - env = environ - - # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a - # BytesWarning when using python -b or python -bb: ignore the warning - with warnings.catch_warnings(): - warnings.simplefilter("ignore", BytesWarning) - - try: - path_list = env.get('PATH') - except TypeError: - path_list = None - - if supports_bytes_environ: - try: - path_listb = env[b'PATH'] - except (KeyError, TypeError): - pass - else: - if path_list is not None: - raise ValueError( - "env cannot contain 'PATH' and b'PATH' keys") - path_list = path_listb - - if path_list is not None and isinstance(path_list, bytes): - path_list = fsdecode(path_list) - - if path_list is None: - path_list = defpath - return path_list.split(pathsep) - - -# Change environ to automatically call putenv() and unsetenv() -from _collections_abc import MutableMapping, Mapping - -class _Environ(MutableMapping): - def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue): - self.encodekey = encodekey - self.decodekey = decodekey - self.encodevalue = encodevalue - self.decodevalue = decodevalue - self._data = data - - def __getitem__(self, key): - try: - value = self._data[self.encodekey(key)] - except KeyError: - # raise KeyError with the original key value - raise KeyError(key) from None - return self.decodevalue(value) - - def __setitem__(self, key, value): - key = self.encodekey(key) - value = self.encodevalue(value) - putenv(key, value) - self._data[key] = value - - def __delitem__(self, key): - encodedkey = self.encodekey(key) - unsetenv(encodedkey) - try: - del self._data[encodedkey] - except KeyError: - # raise KeyError with the original key value - raise KeyError(key) from None - - def __iter__(self): - # list() from dict object is an atomic operation - keys = list(self._data) - for key in keys: - yield self.decodekey(key) - - def __len__(self): - return len(self._data) - - def __repr__(self): - formatted_items = ", ".join( - f"{self.decodekey(key)!r}: {self.decodevalue(value)!r}" - for key, value in self._data.items() - ) - return f"environ({{{formatted_items}}})" - - def copy(self): - return dict(self) - - def setdefault(self, key, value): - if key not in self: - self[key] = value - return self[key] - - def __ior__(self, other): - self.update(other) - return self - - def __or__(self, other): - if not isinstance(other, Mapping): - return NotImplemented - new = dict(self) - new.update(other) - return new - - def __ror__(self, other): - if not isinstance(other, Mapping): - return NotImplemented - new = dict(other) - new.update(self) - return new - -def _createenviron(): - if name == 'nt': - # Where Env Var Names Must Be UPPERCASE - def check_str(value): - if not isinstance(value, str): - raise TypeError("str expected, not %s" % type(value).__name__) - return value - encode = check_str - decode = str - def encodekey(key): - return encode(key).upper() - data = {} - for key, value in environ.items(): - data[encodekey(key)] = value - else: - # Where Env Var Names Can Be Mixed Case - encoding = sys.getfilesystemencoding() - def encode(value): - if not isinstance(value, str): - raise TypeError("str expected, not %s" % type(value).__name__) - return value.encode(encoding, 'surrogateescape') - def decode(value): - return value.decode(encoding, 'surrogateescape') - encodekey = encode - data = environ - return _Environ(data, - encodekey, decode, - encode, decode) - -# unicode environ -environ = _createenviron() -del _createenviron - - -def getenv(key, default=None): - """Get an environment variable, return None if it doesn't exist. - The optional second argument can specify an alternate default. - key, default and the result are str.""" - return environ.get(key, default) - -supports_bytes_environ = (name != 'nt') -__all__.extend(("getenv", "supports_bytes_environ")) - -if supports_bytes_environ: - def _check_bytes(value): - if not isinstance(value, bytes): - raise TypeError("bytes expected, not %s" % type(value).__name__) - return value - - # bytes environ - environb = _Environ(environ._data, - _check_bytes, bytes, - _check_bytes, bytes) - del _check_bytes - - def getenvb(key, default=None): - """Get an environment variable, return None if it doesn't exist. - The optional second argument can specify an alternate default. - key, default and the result are bytes.""" - return environb.get(key, default) - - __all__.extend(("environb", "getenvb")) - -def _fscodec(): - encoding = sys.getfilesystemencoding() - errors = sys.getfilesystemencodeerrors() - - def fsencode(filename): - """Encode filename (an os.PathLike, bytes, or str) to the filesystem - encoding with 'surrogateescape' error handler, return bytes unchanged. - On Windows, use 'strict' error handler if the file system encoding is - 'mbcs' (which is the default encoding). - """ - filename = fspath(filename) # Does type-checking of `filename`. - if isinstance(filename, str): - return filename.encode(encoding, errors) - else: - return filename - - def fsdecode(filename): - """Decode filename (an os.PathLike, bytes, or str) from the filesystem - encoding with 'surrogateescape' error handler, return str unchanged. On - Windows, use 'strict' error handler if the file system encoding is - 'mbcs' (which is the default encoding). - """ - filename = fspath(filename) # Does type-checking of `filename`. - if isinstance(filename, bytes): - return filename.decode(encoding, errors) - else: - return filename - - return fsencode, fsdecode - -fsencode, fsdecode = _fscodec() -del _fscodec - -# Supply spawn*() (probably only for Unix) -if _exists("fork") and not _exists("spawnv") and _exists("execv"): - - P_WAIT = 0 - P_NOWAIT = P_NOWAITO = 1 - - __all__.extend(["P_WAIT", "P_NOWAIT", "P_NOWAITO"]) - - # XXX Should we support P_DETACH? I suppose it could fork()**2 - # and close the std I/O streams. Also, P_OVERLAY is the same - # as execv*()? - - def _spawnvef(mode, file, args, env, func): - # Internal helper; func is the exec*() function to use - if not isinstance(args, (tuple, list)): - raise TypeError('argv must be a tuple or a list') - if not args or not args[0]: - raise ValueError('argv first element cannot be empty') - pid = fork() - if not pid: - # Child - try: - if env is None: - func(file, args) - else: - func(file, args, env) - except: - _exit(127) - else: - # Parent - if mode == P_NOWAIT: - return pid # Caller is responsible for waiting! - while 1: - wpid, sts = waitpid(pid, 0) - if WIFSTOPPED(sts): - continue - - return waitstatus_to_exitcode(sts) - - def spawnv(mode, file, args): - """spawnv(mode, file, args) -> integer - -Execute file with arguments from args in a subprocess. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return _spawnvef(mode, file, args, None, execv) - - def spawnve(mode, file, args, env): - """spawnve(mode, file, args, env) -> integer - -Execute file with arguments from args in a subprocess with the -specified environment. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return _spawnvef(mode, file, args, env, execve) - - # Note: spawnvp[e] isn't currently supported on Windows - - def spawnvp(mode, file, args): - """spawnvp(mode, file, args) -> integer - -Execute file (which is looked for along $PATH) with arguments from -args in a subprocess. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return _spawnvef(mode, file, args, None, execvp) - - def spawnvpe(mode, file, args, env): - """spawnvpe(mode, file, args, env) -> integer - -Execute file (which is looked for along $PATH) with arguments from -args in a subprocess with the supplied environment. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return _spawnvef(mode, file, args, env, execvpe) - - - __all__.extend(["spawnv", "spawnve", "spawnvp", "spawnvpe"]) - - -if _exists("spawnv"): - # These aren't supplied by the basic Windows code - # but can be easily implemented in Python - - def spawnl(mode, file, *args): - """spawnl(mode, file, *args) -> integer - -Execute file with arguments from args in a subprocess. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return spawnv(mode, file, args) - - def spawnle(mode, file, *args): - """spawnle(mode, file, *args, env) -> integer - -Execute file with arguments from args in a subprocess with the -supplied environment. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - env = args[-1] - return spawnve(mode, file, args[:-1], env) - - - __all__.extend(["spawnl", "spawnle"]) - - -if _exists("spawnvp"): - # At the moment, Windows doesn't implement spawnvp[e], - # so it won't have spawnlp[e] either. - def spawnlp(mode, file, *args): - """spawnlp(mode, file, *args) -> integer - -Execute file (which is looked for along $PATH) with arguments from -args in a subprocess with the supplied environment. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - return spawnvp(mode, file, args) - - def spawnlpe(mode, file, *args): - """spawnlpe(mode, file, *args, env) -> integer - -Execute file (which is looked for along $PATH) with arguments from -args in a subprocess with the supplied environment. -If mode == P_NOWAIT return the pid of the process. -If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return -SIG, where SIG is the signal that killed it. """ - env = args[-1] - return spawnvpe(mode, file, args[:-1], env) - - - __all__.extend(["spawnlp", "spawnlpe"]) - -# VxWorks has no user space shell provided. As a result, running -# command in a shell can't be supported. -if sys.platform != 'vxworks': - # Supply os.popen() - def popen(cmd, mode="r", buffering=-1): - if not isinstance(cmd, str): - raise TypeError("invalid cmd type (%s, expected string)" % type(cmd)) - if mode not in ("r", "w"): - raise ValueError("invalid mode %r" % mode) - if buffering == 0 or buffering is None: - raise ValueError("popen() does not support unbuffered streams") - import subprocess - if mode == "r": - proc = subprocess.Popen(cmd, - shell=True, text=True, - stdout=subprocess.PIPE, - bufsize=buffering) - return _wrap_close(proc.stdout, proc) - else: - proc = subprocess.Popen(cmd, - shell=True, text=True, - stdin=subprocess.PIPE, - bufsize=buffering) - return _wrap_close(proc.stdin, proc) - - # Helper for popen() -- a proxy for a file whose close waits for the process - class _wrap_close: - def __init__(self, stream, proc): - self._stream = stream - self._proc = proc - def close(self): - self._stream.close() - returncode = self._proc.wait() - if returncode == 0: - return None - if name == 'nt': - return returncode - else: - return returncode << 8 # Shift left to match old behavior - def __enter__(self): - return self - def __exit__(self, *args): - self.close() - def __getattr__(self, name): - return getattr(self._stream, name) - def __iter__(self): - return iter(self._stream) - - __all__.append("popen") - -# Supply os.fdopen() -def fdopen(fd, mode="r", buffering=-1, encoding=None, *args, **kwargs): - if not isinstance(fd, int): - raise TypeError("invalid fd type (%s, expected integer)" % type(fd)) - import io - if "b" not in mode: - encoding = io.text_encoding(encoding) - return io.open(fd, mode, buffering, encoding, *args, **kwargs) - - -# For testing purposes, make sure the function is available when the C -# implementation exists. -def _fspath(path): - """Return the path representation of a path-like object. - - If str or bytes is passed in, it is returned unchanged. Otherwise the - os.PathLike interface is used to get the path representation. If the - path representation is not str or bytes, TypeError is raised. If the - provided path is not str, bytes, or os.PathLike, TypeError is raised. - """ - if isinstance(path, (str, bytes)): - return path - - # Work from the object's type to match method resolution of other magic - # methods. - path_type = type(path) - try: - path_repr = path_type.__fspath__(path) - except AttributeError: - if hasattr(path_type, '__fspath__'): - raise - else: - raise TypeError("expected str, bytes or os.PathLike object, " - "not " + path_type.__name__) - if isinstance(path_repr, (str, bytes)): - return path_repr - else: - raise TypeError("expected {}.__fspath__() to return str or bytes, " - "not {}".format(path_type.__name__, - type(path_repr).__name__)) - -# If there is no C implementation, make the pure Python version the -# implementation as transparently as possible. -if not _exists('fspath'): - fspath = _fspath - fspath.__name__ = "fspath" - - -class PathLike(abc.ABC): - - """Abstract base class for implementing the file system path protocol.""" - - @abc.abstractmethod - def __fspath__(self): - """Return the file system path representation of the object.""" - raise NotImplementedError - - @classmethod - def __subclasshook__(cls, subclass): - if cls is PathLike: - return _check_methods(subclass, '__fspath__') - return NotImplemented - - __class_getitem__ = classmethod(GenericAlias) - - -if name == 'nt': - class _AddedDllDirectory: - def __init__(self, path, cookie, remove_dll_directory): - self.path = path - self._cookie = cookie - self._remove_dll_directory = remove_dll_directory - def close(self): - self._remove_dll_directory(self._cookie) - self.path = None - def __enter__(self): - return self - def __exit__(self, *args): - self.close() - def __repr__(self): - if self.path: - return "".format(self.path) - return "" - - def add_dll_directory(path): - """Add a path to the DLL search path. - - This search path is used when resolving dependencies for imported - extension modules (the module itself is resolved through sys.path), - and also by ctypes. - - Remove the directory by calling close() on the returned object or - using it in a with statement. - """ - import nt - cookie = nt._add_dll_directory(path) - return _AddedDllDirectory( - path, - cookie, - nt._remove_dll_directory - ) diff --git a/python/Lib/pathlib.py b/python/Lib/pathlib.py deleted file mode 100644 index bf20051..0000000 --- a/python/Lib/pathlib.py +++ /dev/null @@ -1,1406 +0,0 @@ -import fnmatch -import functools -import io -import ntpath -import os -import posixpath -import re -import sys -import warnings -from _collections_abc import Sequence -from errno import ENOENT, ENOTDIR, EBADF, ELOOP -from operator import attrgetter -from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO -from urllib.parse import quote_from_bytes as urlquote_from_bytes - - -__all__ = [ - "PurePath", "PurePosixPath", "PureWindowsPath", - "Path", "PosixPath", "WindowsPath", - ] - -# -# Internals -# - -_WINERROR_NOT_READY = 21 # drive exists but is not accessible -_WINERROR_INVALID_NAME = 123 # fix for bpo-35306 -_WINERROR_CANT_RESOLVE_FILENAME = 1921 # broken symlink pointing to itself - -# EBADF - guard against macOS `stat` throwing EBADF -_IGNORED_ERRNOS = (ENOENT, ENOTDIR, EBADF, ELOOP) - -_IGNORED_WINERRORS = ( - _WINERROR_NOT_READY, - _WINERROR_INVALID_NAME, - _WINERROR_CANT_RESOLVE_FILENAME) - -def _ignore_error(exception): - return (getattr(exception, 'errno', None) in _IGNORED_ERRNOS or - getattr(exception, 'winerror', None) in _IGNORED_WINERRORS) - - -def _is_wildcard_pattern(pat): - # Whether this pattern needs actual matching using fnmatch, or can - # be looked up directly as a file. - return "*" in pat or "?" in pat or "[" in pat - - -class _Flavour(object): - """A flavour implements a particular (platform-specific) set of path - semantics.""" - - def __init__(self): - self.join = self.sep.join - - def parse_parts(self, parts): - parsed = [] - sep = self.sep - altsep = self.altsep - drv = root = '' - it = reversed(parts) - for part in it: - if not part: - continue - if altsep: - part = part.replace(altsep, sep) - drv, root, rel = self.splitroot(part) - if sep in rel: - for x in reversed(rel.split(sep)): - if x and x != '.': - parsed.append(sys.intern(x)) - else: - if rel and rel != '.': - parsed.append(sys.intern(rel)) - if drv or root: - if not drv: - # If no drive is present, try to find one in the previous - # parts. This makes the result of parsing e.g. - # ("C:", "/", "a") reasonably intuitive. - for part in it: - if not part: - continue - if altsep: - part = part.replace(altsep, sep) - drv = self.splitroot(part)[0] - if drv: - break - break - if drv or root: - parsed.append(drv + root) - parsed.reverse() - return drv, root, parsed - - def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2): - """ - Join the two paths represented by the respective - (drive, root, parts) tuples. Return a new (drive, root, parts) tuple. - """ - if root2: - if not drv2 and drv: - return drv, root2, [drv + root2] + parts2[1:] - elif drv2: - if drv2 == drv or self.casefold(drv2) == self.casefold(drv): - # Same drive => second path is relative to the first - return drv, root, parts + parts2[1:] - else: - # Second path is non-anchored (common case) - return drv, root, parts + parts2 - return drv2, root2, parts2 - - -class _WindowsFlavour(_Flavour): - # Reference for Windows paths can be found at - # http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx - - sep = '\\' - altsep = '/' - has_drv = True - pathmod = ntpath - - is_supported = (os.name == 'nt') - - drive_letters = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') - ext_namespace_prefix = '\\\\?\\' - - reserved_names = ( - {'CON', 'PRN', 'AUX', 'NUL', 'CONIN$', 'CONOUT$'} | - {'COM%s' % c for c in '123456789\xb9\xb2\xb3'} | - {'LPT%s' % c for c in '123456789\xb9\xb2\xb3'} - ) - - # Interesting findings about extended paths: - # * '\\?\c:\a' is an extended path, which bypasses normal Windows API - # path processing. Thus relative paths are not resolved and slash is not - # translated to backslash. It has the native NT path limit of 32767 - # characters, but a bit less after resolving device symbolic links, - # such as '\??\C:' => '\Device\HarddiskVolume2'. - # * '\\?\c:/a' looks for a device named 'C:/a' because slash is a - # regular name character in the object namespace. - # * '\\?\c:\foo/bar' is invalid because '/' is illegal in NT filesystems. - # The only path separator at the filesystem level is backslash. - # * '//?/c:\a' and '//?/c:/a' are effectively equivalent to '\\.\c:\a' and - # thus limited to MAX_PATH. - # * Prior to Windows 8, ANSI API bytes paths are limited to MAX_PATH, - # even with the '\\?\' prefix. - - def splitroot(self, part, sep=sep): - first = part[0:1] - second = part[1:2] - if (second == sep and first == sep): - # XXX extended paths should also disable the collapsing of "." - # components (according to MSDN docs). - prefix, part = self._split_extended_path(part) - first = part[0:1] - second = part[1:2] - else: - prefix = '' - third = part[2:3] - if (second == sep and first == sep and third != sep): - # is a UNC path: - # vvvvvvvvvvvvvvvvvvvvv root - # \\machine\mountpoint\directory\etc\... - # directory ^^^^^^^^^^^^^^ - index = part.find(sep, 2) - if index != -1: - index2 = part.find(sep, index + 1) - # a UNC path can't have two slashes in a row - # (after the initial two) - if index2 != index + 1: - if index2 == -1: - index2 = len(part) - if prefix: - return prefix + part[1:index2], sep, part[index2+1:] - else: - return part[:index2], sep, part[index2+1:] - drv = root = '' - if second == ':' and first in self.drive_letters: - drv = part[:2] - part = part[2:] - first = third - if first == sep: - root = first - part = part.lstrip(sep) - return prefix + drv, root, part - - def casefold(self, s): - return s.lower() - - def casefold_parts(self, parts): - return [p.lower() for p in parts] - - def compile_pattern(self, pattern): - return re.compile(fnmatch.translate(pattern), re.IGNORECASE).fullmatch - - def _split_extended_path(self, s, ext_prefix=ext_namespace_prefix): - prefix = '' - if s.startswith(ext_prefix): - prefix = s[:4] - s = s[4:] - if s.startswith('UNC\\'): - prefix += s[:3] - s = '\\' + s[3:] - return prefix, s - - def is_reserved(self, parts): - # NOTE: the rules for reserved names seem somewhat complicated - # (e.g. r"..\NUL" is reserved but not r"foo\NUL" if "foo" does not - # exist). We err on the side of caution and return True for paths - # which are not considered reserved by Windows. - if not parts: - return False - if parts[0].startswith('\\\\'): - # UNC paths are never reserved - return False - name = parts[-1].partition('.')[0].partition(':')[0].rstrip(' ') - return name.upper() in self.reserved_names - - def make_uri(self, path): - # Under Windows, file URIs use the UTF-8 encoding. - drive = path.drive - if len(drive) == 2 and drive[1] == ':': - # It's a path on a local drive => 'file:///c:/a/b' - rest = path.as_posix()[2:].lstrip('/') - return 'file:///%s/%s' % ( - drive, urlquote_from_bytes(rest.encode('utf-8'))) - else: - # It's a path on a network drive => 'file://host/share/a/b' - return 'file:' + urlquote_from_bytes(path.as_posix().encode('utf-8')) - - -class _PosixFlavour(_Flavour): - sep = '/' - altsep = '' - has_drv = False - pathmod = posixpath - - is_supported = (os.name != 'nt') - - def splitroot(self, part, sep=sep): - if part and part[0] == sep: - stripped_part = part.lstrip(sep) - # According to POSIX path resolution: - # http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11 - # "A pathname that begins with two successive slashes may be - # interpreted in an implementation-defined manner, although more - # than two leading slashes shall be treated as a single slash". - if len(part) - len(stripped_part) == 2: - return '', sep * 2, stripped_part - else: - return '', sep, stripped_part - else: - return '', '', part - - def casefold(self, s): - return s - - def casefold_parts(self, parts): - return parts - - def compile_pattern(self, pattern): - return re.compile(fnmatch.translate(pattern)).fullmatch - - def is_reserved(self, parts): - return False - - def make_uri(self, path): - # We represent the path using the local filesystem encoding, - # for portability to other applications. - bpath = bytes(path) - return 'file://' + urlquote_from_bytes(bpath) - - -_windows_flavour = _WindowsFlavour() -_posix_flavour = _PosixFlavour() - - -# -# Globbing helpers -# - -def _make_selector(pattern_parts, flavour): - pat = pattern_parts[0] - child_parts = pattern_parts[1:] - if not pat: - return _TerminatingSelector() - if pat == '**': - cls = _RecursiveWildcardSelector - elif '**' in pat: - raise ValueError("Invalid pattern: '**' can only be an entire path component") - elif _is_wildcard_pattern(pat): - cls = _WildcardSelector - else: - cls = _PreciseSelector - return cls(pat, child_parts, flavour) - -if hasattr(functools, "lru_cache"): - _make_selector = functools.lru_cache()(_make_selector) - - -class _Selector: - """A selector matches a specific glob pattern part against the children - of a given path.""" - - def __init__(self, child_parts, flavour): - self.child_parts = child_parts - if child_parts: - self.successor = _make_selector(child_parts, flavour) - self.dironly = True - else: - self.successor = _TerminatingSelector() - self.dironly = False - - def select_from(self, parent_path): - """Iterate over all child paths of `parent_path` matched by this - selector. This can contain parent_path itself.""" - path_cls = type(parent_path) - is_dir = path_cls.is_dir - exists = path_cls.exists - scandir = path_cls._scandir - if not is_dir(parent_path): - return iter([]) - return self._select_from(parent_path, is_dir, exists, scandir) - - -class _TerminatingSelector: - - def _select_from(self, parent_path, is_dir, exists, scandir): - yield parent_path - - -class _PreciseSelector(_Selector): - - def __init__(self, name, child_parts, flavour): - self.name = name - _Selector.__init__(self, child_parts, flavour) - - def _select_from(self, parent_path, is_dir, exists, scandir): - try: - path = parent_path._make_child_relpath(self.name) - if (is_dir if self.dironly else exists)(path): - for p in self.successor._select_from(path, is_dir, exists, scandir): - yield p - except PermissionError: - return - - -class _WildcardSelector(_Selector): - - def __init__(self, pat, child_parts, flavour): - self.match = flavour.compile_pattern(pat) - _Selector.__init__(self, child_parts, flavour) - - def _select_from(self, parent_path, is_dir, exists, scandir): - try: - with scandir(parent_path) as scandir_it: - entries = list(scandir_it) - for entry in entries: - if self.dironly: - try: - # "entry.is_dir()" can raise PermissionError - # in some cases (see bpo-38894), which is not - # among the errors ignored by _ignore_error() - if not entry.is_dir(): - continue - except OSError as e: - if not _ignore_error(e): - raise - continue - name = entry.name - if self.match(name): - path = parent_path._make_child_relpath(name) - for p in self.successor._select_from(path, is_dir, exists, scandir): - yield p - except PermissionError: - return - - -class _RecursiveWildcardSelector(_Selector): - - def __init__(self, pat, child_parts, flavour): - _Selector.__init__(self, child_parts, flavour) - - def _iterate_directories(self, parent_path, is_dir, scandir): - yield parent_path - try: - with scandir(parent_path) as scandir_it: - entries = list(scandir_it) - for entry in entries: - entry_is_dir = False - try: - entry_is_dir = entry.is_dir() - except OSError as e: - if not _ignore_error(e): - raise - if entry_is_dir and not entry.is_symlink(): - path = parent_path._make_child_relpath(entry.name) - for p in self._iterate_directories(path, is_dir, scandir): - yield p - except PermissionError: - return - - def _select_from(self, parent_path, is_dir, exists, scandir): - try: - yielded = set() - try: - successor_select = self.successor._select_from - for starting_point in self._iterate_directories(parent_path, is_dir, scandir): - for p in successor_select(starting_point, is_dir, exists, scandir): - if p not in yielded: - yield p - yielded.add(p) - finally: - yielded.clear() - except PermissionError: - return - - -# -# Public API -# - -class _PathParents(Sequence): - """This object provides sequence-like access to the logical ancestors - of a path. Don't try to construct it yourself.""" - __slots__ = ('_pathcls', '_drv', '_root', '_parts') - - def __init__(self, path): - # We don't store the instance to avoid reference cycles - self._pathcls = type(path) - self._drv = path._drv - self._root = path._root - self._parts = path._parts - - def __len__(self): - if self._drv or self._root: - return len(self._parts) - 1 - else: - return len(self._parts) - - def __getitem__(self, idx): - if isinstance(idx, slice): - return tuple(self[i] for i in range(*idx.indices(len(self)))) - - if idx >= len(self) or idx < -len(self): - raise IndexError(idx) - if idx < 0: - idx += len(self) - return self._pathcls._from_parsed_parts(self._drv, self._root, - self._parts[:-idx - 1]) - - def __repr__(self): - return "<{}.parents>".format(self._pathcls.__name__) - - -class PurePath(object): - """Base class for manipulating paths without I/O. - - PurePath represents a filesystem path and offers operations which - don't imply any actual filesystem I/O. Depending on your system, - instantiating a PurePath will return either a PurePosixPath or a - PureWindowsPath object. You can also instantiate either of these classes - directly, regardless of your system. - """ - __slots__ = ( - '_drv', '_root', '_parts', - '_str', '_hash', '_pparts', '_cached_cparts', - ) - - def __new__(cls, *args): - """Construct a PurePath from one or several strings and or existing - PurePath objects. The strings and path objects are combined so as - to yield a canonicalized path, which is incorporated into the - new PurePath object. - """ - if cls is PurePath: - cls = PureWindowsPath if os.name == 'nt' else PurePosixPath - return cls._from_parts(args) - - def __reduce__(self): - # Using the parts tuple helps share interned path parts - # when pickling related paths. - return (self.__class__, tuple(self._parts)) - - @classmethod - def _parse_args(cls, args): - # This is useful when you don't want to create an instance, just - # canonicalize some constructor arguments. - parts = [] - for a in args: - if isinstance(a, PurePath): - parts += a._parts - else: - a = os.fspath(a) - if isinstance(a, str): - # Force-cast str subclasses to str (issue #21127) - parts.append(str(a)) - else: - raise TypeError( - "argument should be a str object or an os.PathLike " - "object returning str, not %r" - % type(a)) - return cls._flavour.parse_parts(parts) - - @classmethod - def _from_parts(cls, args): - # We need to call _parse_args on the instance, so as to get the - # right flavour. - self = object.__new__(cls) - drv, root, parts = self._parse_args(args) - self._drv = drv - self._root = root - self._parts = parts - return self - - @classmethod - def _from_parsed_parts(cls, drv, root, parts): - self = object.__new__(cls) - self._drv = drv - self._root = root - self._parts = parts - return self - - @classmethod - def _format_parsed_parts(cls, drv, root, parts): - if drv or root: - return drv + root + cls._flavour.join(parts[1:]) - else: - return cls._flavour.join(parts) - - def _make_child(self, args): - drv, root, parts = self._parse_args(args) - drv, root, parts = self._flavour.join_parsed_parts( - self._drv, self._root, self._parts, drv, root, parts) - return self._from_parsed_parts(drv, root, parts) - - def __str__(self): - """Return the string representation of the path, suitable for - passing to system calls.""" - try: - return self._str - except AttributeError: - self._str = self._format_parsed_parts(self._drv, self._root, - self._parts) or '.' - return self._str - - def __fspath__(self): - return str(self) - - def as_posix(self): - """Return the string representation of the path with forward (/) - slashes.""" - f = self._flavour - return str(self).replace(f.sep, '/') - - def __bytes__(self): - """Return the bytes representation of the path. This is only - recommended to use under Unix.""" - return os.fsencode(self) - - def __repr__(self): - return "{}({!r})".format(self.__class__.__name__, self.as_posix()) - - def as_uri(self): - """Return the path as a 'file' URI.""" - if not self.is_absolute(): - raise ValueError("relative path can't be expressed as a file URI") - return self._flavour.make_uri(self) - - @property - def _cparts(self): - # Cached casefolded parts, for hashing and comparison - try: - return self._cached_cparts - except AttributeError: - self._cached_cparts = self._flavour.casefold_parts(self._parts) - return self._cached_cparts - - def __eq__(self, other): - if not isinstance(other, PurePath): - return NotImplemented - return self._cparts == other._cparts and self._flavour is other._flavour - - def __hash__(self): - try: - return self._hash - except AttributeError: - self._hash = hash(tuple(self._cparts)) - return self._hash - - def __lt__(self, other): - if not isinstance(other, PurePath) or self._flavour is not other._flavour: - return NotImplemented - return self._cparts < other._cparts - - def __le__(self, other): - if not isinstance(other, PurePath) or self._flavour is not other._flavour: - return NotImplemented - return self._cparts <= other._cparts - - def __gt__(self, other): - if not isinstance(other, PurePath) or self._flavour is not other._flavour: - return NotImplemented - return self._cparts > other._cparts - - def __ge__(self, other): - if not isinstance(other, PurePath) or self._flavour is not other._flavour: - return NotImplemented - return self._cparts >= other._cparts - - drive = property(attrgetter('_drv'), - doc="""The drive prefix (letter or UNC path), if any.""") - - root = property(attrgetter('_root'), - doc="""The root of the path, if any.""") - - @property - def anchor(self): - """The concatenation of the drive and root, or ''.""" - anchor = self._drv + self._root - return anchor - - @property - def name(self): - """The final path component, if any.""" - parts = self._parts - if len(parts) == (1 if (self._drv or self._root) else 0): - return '' - return parts[-1] - - @property - def suffix(self): - """ - The final component's last suffix, if any. - - This includes the leading period. For example: '.txt' - """ - name = self.name - i = name.rfind('.') - if 0 < i < len(name) - 1: - return name[i:] - else: - return '' - - @property - def suffixes(self): - """ - A list of the final component's suffixes, if any. - - These include the leading periods. For example: ['.tar', '.gz'] - """ - name = self.name - if name.endswith('.'): - return [] - name = name.lstrip('.') - return ['.' + suffix for suffix in name.split('.')[1:]] - - @property - def stem(self): - """The final path component, minus its last suffix.""" - name = self.name - i = name.rfind('.') - if 0 < i < len(name) - 1: - return name[:i] - else: - return name - - def with_name(self, name): - """Return a new path with the file name changed.""" - if not self.name: - raise ValueError("%r has an empty name" % (self,)) - drv, root, parts = self._flavour.parse_parts((name,)) - if (not name or name[-1] in [self._flavour.sep, self._flavour.altsep] - or drv or root or len(parts) != 1): - raise ValueError("Invalid name %r" % (name)) - return self._from_parsed_parts(self._drv, self._root, - self._parts[:-1] + [name]) - - def with_stem(self, stem): - """Return a new path with the stem changed.""" - return self.with_name(stem + self.suffix) - - def with_suffix(self, suffix): - """Return a new path with the file suffix changed. If the path - has no suffix, add given suffix. If the given suffix is an empty - string, remove the suffix from the path. - """ - f = self._flavour - if f.sep in suffix or f.altsep and f.altsep in suffix: - raise ValueError("Invalid suffix %r" % (suffix,)) - if suffix and not suffix.startswith('.') or suffix == '.': - raise ValueError("Invalid suffix %r" % (suffix)) - name = self.name - if not name: - raise ValueError("%r has an empty name" % (self,)) - old_suffix = self.suffix - if not old_suffix: - name = name + suffix - else: - name = name[:-len(old_suffix)] + suffix - return self._from_parsed_parts(self._drv, self._root, - self._parts[:-1] + [name]) - - def relative_to(self, *other): - """Return the relative path to another path identified by the passed - arguments. If the operation is not possible (because this is not - a subpath of the other path), raise ValueError. - """ - # For the purpose of this method, drive and root are considered - # separate parts, i.e.: - # Path('c:/').relative_to('c:') gives Path('/') - # Path('c:/').relative_to('/') raise ValueError - if not other: - raise TypeError("need at least one argument") - parts = self._parts - drv = self._drv - root = self._root - if root: - abs_parts = [drv, root] + parts[1:] - else: - abs_parts = parts - to_drv, to_root, to_parts = self._parse_args(other) - if to_root: - to_abs_parts = [to_drv, to_root] + to_parts[1:] - else: - to_abs_parts = to_parts - n = len(to_abs_parts) - cf = self._flavour.casefold_parts - if (root or drv) if n == 0 else cf(abs_parts[:n]) != cf(to_abs_parts): - formatted = self._format_parsed_parts(to_drv, to_root, to_parts) - raise ValueError("{!r} is not in the subpath of {!r}" - " OR one path is relative and the other is absolute." - .format(str(self), str(formatted))) - return self._from_parsed_parts('', root if n == 1 else '', - abs_parts[n:]) - - def is_relative_to(self, *other): - """Return True if the path is relative to another path or False. - """ - try: - self.relative_to(*other) - return True - except ValueError: - return False - - @property - def parts(self): - """An object providing sequence-like access to the - components in the filesystem path.""" - # We cache the tuple to avoid building a new one each time .parts - # is accessed. XXX is this necessary? - try: - return self._pparts - except AttributeError: - self._pparts = tuple(self._parts) - return self._pparts - - def joinpath(self, *args): - """Combine this path with one or several arguments, and return a - new path representing either a subpath (if all arguments are relative - paths) or a totally different path (if one of the arguments is - anchored). - """ - return self._make_child(args) - - def __truediv__(self, key): - try: - return self._make_child((key,)) - except TypeError: - return NotImplemented - - def __rtruediv__(self, key): - try: - return self._from_parts([key] + self._parts) - except TypeError: - return NotImplemented - - @property - def parent(self): - """The logical parent of the path.""" - drv = self._drv - root = self._root - parts = self._parts - if len(parts) == 1 and (drv or root): - return self - return self._from_parsed_parts(drv, root, parts[:-1]) - - @property - def parents(self): - """A sequence of this path's logical parents.""" - return _PathParents(self) - - def is_absolute(self): - """True if the path is absolute (has both a root and, if applicable, - a drive).""" - if not self._root: - return False - return not self._flavour.has_drv or bool(self._drv) - - def is_reserved(self): - """Return True if the path contains one of the special names reserved - by the system, if any.""" - return self._flavour.is_reserved(self._parts) - - def match(self, path_pattern): - """ - Return True if this path matches the given pattern. - """ - cf = self._flavour.casefold - path_pattern = cf(path_pattern) - drv, root, pat_parts = self._flavour.parse_parts((path_pattern,)) - if not pat_parts: - raise ValueError("empty pattern") - if drv and drv != cf(self._drv): - return False - if root and root != cf(self._root): - return False - parts = self._cparts - if drv or root: - if len(pat_parts) != len(parts): - return False - pat_parts = pat_parts[1:] - elif len(pat_parts) > len(parts): - return False - for part, pat in zip(reversed(parts), reversed(pat_parts)): - if not fnmatch.fnmatchcase(part, pat): - return False - return True - -# Can't subclass os.PathLike from PurePath and keep the constructor -# optimizations in PurePath._parse_args(). -os.PathLike.register(PurePath) - - -class PurePosixPath(PurePath): - """PurePath subclass for non-Windows systems. - - On a POSIX system, instantiating a PurePath should return this object. - However, you can also instantiate it directly on any system. - """ - _flavour = _posix_flavour - __slots__ = () - - -class PureWindowsPath(PurePath): - """PurePath subclass for Windows systems. - - On a Windows system, instantiating a PurePath should return this object. - However, you can also instantiate it directly on any system. - """ - _flavour = _windows_flavour - __slots__ = () - - -# Filesystem-accessing classes - - -class Path(PurePath): - """PurePath subclass that can make system calls. - - Path represents a filesystem path but unlike PurePath, also offers - methods to do system calls on path objects. Depending on your system, - instantiating a Path will return either a PosixPath or a WindowsPath - object. You can also instantiate a PosixPath or WindowsPath directly, - but cannot instantiate a WindowsPath on a POSIX system or vice versa. - """ - __slots__ = () - - def __new__(cls, *args, **kwargs): - if cls is Path: - cls = WindowsPath if os.name == 'nt' else PosixPath - self = cls._from_parts(args) - if not self._flavour.is_supported: - raise NotImplementedError("cannot instantiate %r on your system" - % (cls.__name__,)) - return self - - def _make_child_relpath(self, part): - # This is an optimization used for dir walking. `part` must be - # a single part relative to this path. - parts = self._parts + [part] - return self._from_parsed_parts(self._drv, self._root, parts) - - def __enter__(self): - # In previous versions of pathlib, __exit__() marked this path as - # closed; subsequent attempts to perform I/O would raise an IOError. - # This functionality was never documented, and had the effect of - # making Path objects mutable, contrary to PEP 428. - # In Python 3.9 __exit__() was made a no-op. - # In Python 3.11 __enter__() began emitting DeprecationWarning. - # In Python 3.13 __enter__() and __exit__() should be removed. - warnings.warn("pathlib.Path.__enter__() is deprecated and scheduled " - "for removal in Python 3.13; Path objects as a context " - "manager is a no-op", - DeprecationWarning, stacklevel=2) - return self - - def __exit__(self, t, v, tb): - pass - - # Public API - - @classmethod - def cwd(cls): - """Return a new path pointing to the current working directory - (as returned by os.getcwd()). - """ - return cls(os.getcwd()) - - @classmethod - def home(cls): - """Return a new path pointing to the user's home directory (as - returned by os.path.expanduser('~')). - """ - return cls("~").expanduser() - - def samefile(self, other_path): - """Return whether other_path is the same or not as this file - (as returned by os.path.samefile()). - """ - st = self.stat() - try: - other_st = other_path.stat() - except AttributeError: - other_st = self.__class__(other_path).stat() - return os.path.samestat(st, other_st) - - def iterdir(self): - """Iterate over the files in this directory. Does not yield any - result for the special paths '.' and '..'. - """ - for name in os.listdir(self): - yield self._make_child_relpath(name) - - def _scandir(self): - # bpo-24132: a future version of pathlib will support subclassing of - # pathlib.Path to customize how the filesystem is accessed. This - # includes scandir(), which is used to implement glob(). - return os.scandir(self) - - def glob(self, pattern): - """Iterate over this subtree and yield all existing files (of any - kind, including directories) matching the given relative pattern. - """ - sys.audit("pathlib.Path.glob", self, pattern) - if not pattern: - raise ValueError("Unacceptable pattern: {!r}".format(pattern)) - drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) - if drv or root: - raise NotImplementedError("Non-relative patterns are unsupported") - if pattern[-1] in (self._flavour.sep, self._flavour.altsep): - pattern_parts.append('') - selector = _make_selector(tuple(pattern_parts), self._flavour) - for p in selector.select_from(self): - yield p - - def rglob(self, pattern): - """Recursively yield all existing files (of any kind, including - directories) matching the given relative pattern, anywhere in - this subtree. - """ - sys.audit("pathlib.Path.rglob", self, pattern) - drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) - if drv or root: - raise NotImplementedError("Non-relative patterns are unsupported") - if pattern and pattern[-1] in (self._flavour.sep, self._flavour.altsep): - pattern_parts.append('') - selector = _make_selector(("**",) + tuple(pattern_parts), self._flavour) - for p in selector.select_from(self): - yield p - - def absolute(self): - """Return an absolute version of this path by prepending the current - working directory. No normalization or symlink resolution is performed. - - Use resolve() to get the canonical path to a file. - """ - if self.is_absolute(): - return self - return self._from_parts([self.cwd()] + self._parts) - - def resolve(self, strict=False): - """ - Make the path absolute, resolving all symlinks on the way and also - normalizing it. - """ - - def check_eloop(e): - winerror = getattr(e, 'winerror', 0) - if e.errno == ELOOP or winerror == _WINERROR_CANT_RESOLVE_FILENAME: - raise RuntimeError("Symlink loop from %r" % e.filename) - - try: - s = os.path.realpath(self, strict=strict) - except OSError as e: - check_eloop(e) - raise - p = self._from_parts((s,)) - - # In non-strict mode, realpath() doesn't raise on symlink loops. - # Ensure we get an exception by calling stat() - if not strict: - try: - p.stat() - except OSError as e: - check_eloop(e) - return p - - def stat(self, *, follow_symlinks=True): - """ - Return the result of the stat() system call on this path, like - os.stat() does. - """ - return os.stat(self, follow_symlinks=follow_symlinks) - - def owner(self): - """ - Return the login name of the file owner. - """ - try: - import pwd - return pwd.getpwuid(self.stat().st_uid).pw_name - except ImportError: - raise NotImplementedError("Path.owner() is unsupported on this system") - - def group(self): - """ - Return the group name of the file gid. - """ - - try: - import grp - return grp.getgrgid(self.stat().st_gid).gr_name - except ImportError: - raise NotImplementedError("Path.group() is unsupported on this system") - - def open(self, mode='r', buffering=-1, encoding=None, - errors=None, newline=None): - """ - Open the file pointed by this path and return a file object, as - the built-in open() function does. - """ - if "b" not in mode: - encoding = io.text_encoding(encoding) - return io.open(self, mode, buffering, encoding, errors, newline) - - def read_bytes(self): - """ - Open the file in bytes mode, read it, and close the file. - """ - with self.open(mode='rb') as f: - return f.read() - - def read_text(self, encoding=None, errors=None): - """ - Open the file in text mode, read it, and close the file. - """ - encoding = io.text_encoding(encoding) - with self.open(mode='r', encoding=encoding, errors=errors) as f: - return f.read() - - def write_bytes(self, data): - """ - Open the file in bytes mode, write to it, and close the file. - """ - # type-check for the buffer interface before truncating the file - view = memoryview(data) - with self.open(mode='wb') as f: - return f.write(view) - - def write_text(self, data, encoding=None, errors=None, newline=None): - """ - Open the file in text mode, write to it, and close the file. - """ - if not isinstance(data, str): - raise TypeError('data must be str, not %s' % - data.__class__.__name__) - encoding = io.text_encoding(encoding) - with self.open(mode='w', encoding=encoding, errors=errors, newline=newline) as f: - return f.write(data) - - def readlink(self): - """ - Return the path to which the symbolic link points. - """ - if not hasattr(os, "readlink"): - raise NotImplementedError("os.readlink() not available on this system") - return self._from_parts((os.readlink(self),)) - - def touch(self, mode=0o666, exist_ok=True): - """ - Create this file with the given access mode, if it doesn't exist. - """ - - if exist_ok: - # First try to bump modification time - # Implementation note: GNU touch uses the UTIME_NOW option of - # the utimensat() / futimens() functions. - try: - os.utime(self, None) - except OSError: - # Avoid exception chaining - pass - else: - return - flags = os.O_CREAT | os.O_WRONLY - if not exist_ok: - flags |= os.O_EXCL - fd = os.open(self, flags, mode) - os.close(fd) - - def mkdir(self, mode=0o777, parents=False, exist_ok=False): - """ - Create a new directory at this given path. - """ - try: - os.mkdir(self, mode) - except FileNotFoundError: - if not parents or self.parent == self: - raise - self.parent.mkdir(parents=True, exist_ok=True) - self.mkdir(mode, parents=False, exist_ok=exist_ok) - except OSError: - # Cannot rely on checking for EEXIST, since the operating system - # could give priority to other errors like EACCES or EROFS - if not exist_ok or not self.is_dir(): - raise - - def chmod(self, mode, *, follow_symlinks=True): - """ - Change the permissions of the path, like os.chmod(). - """ - os.chmod(self, mode, follow_symlinks=follow_symlinks) - - def lchmod(self, mode): - """ - Like chmod(), except if the path points to a symlink, the symlink's - permissions are changed, rather than its target's. - """ - self.chmod(mode, follow_symlinks=False) - - def unlink(self, missing_ok=False): - """ - Remove this file or link. - If the path is a directory, use rmdir() instead. - """ - try: - os.unlink(self) - except FileNotFoundError: - if not missing_ok: - raise - - def rmdir(self): - """ - Remove this directory. The directory must be empty. - """ - os.rmdir(self) - - def lstat(self): - """ - Like stat(), except if the path points to a symlink, the symlink's - status information is returned, rather than its target's. - """ - return self.stat(follow_symlinks=False) - - def rename(self, target): - """ - Rename this path to the target path. - - The target path may be absolute or relative. Relative paths are - interpreted relative to the current working directory, *not* the - directory of the Path object. - - Returns the new Path instance pointing to the target path. - """ - os.rename(self, target) - return self.__class__(target) - - def replace(self, target): - """ - Rename this path to the target path, overwriting if that path exists. - - The target path may be absolute or relative. Relative paths are - interpreted relative to the current working directory, *not* the - directory of the Path object. - - Returns the new Path instance pointing to the target path. - """ - os.replace(self, target) - return self.__class__(target) - - def symlink_to(self, target, target_is_directory=False): - """ - Make this path a symlink pointing to the target path. - Note the order of arguments (link, target) is the reverse of os.symlink. - """ - if not hasattr(os, "symlink"): - raise NotImplementedError("os.symlink() not available on this system") - os.symlink(target, self, target_is_directory) - - def hardlink_to(self, target): - """ - Make this path a hard link pointing to the same file as *target*. - - Note the order of arguments (self, target) is the reverse of os.link's. - """ - if not hasattr(os, "link"): - raise NotImplementedError("os.link() not available on this system") - os.link(target, self) - - def link_to(self, target): - """ - Make the target path a hard link pointing to this path. - - Note this function does not make this path a hard link to *target*, - despite the implication of the function and argument names. The order - of arguments (target, link) is the reverse of Path.symlink_to, but - matches that of os.link. - - Deprecated since Python 3.10 and scheduled for removal in Python 3.12. - Use `hardlink_to()` instead. - """ - warnings.warn("pathlib.Path.link_to() is deprecated and is scheduled " - "for removal in Python 3.12. " - "Use pathlib.Path.hardlink_to() instead.", - DeprecationWarning, stacklevel=2) - self.__class__(target).hardlink_to(self) - - # Convenience functions for querying the stat results - - def exists(self): - """ - Whether this path exists. - """ - try: - self.stat() - except OSError as e: - if not _ignore_error(e): - raise - return False - except ValueError: - # Non-encodable path - return False - return True - - def is_dir(self): - """ - Whether this path is a directory. - """ - try: - return S_ISDIR(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_file(self): - """ - Whether this path is a regular file (also True for symlinks pointing - to regular files). - """ - try: - return S_ISREG(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_mount(self): - """ - Check if this path is a POSIX mount point - """ - # Need to exist and be a dir - if not self.exists() or not self.is_dir(): - return False - - try: - parent_dev = self.parent.stat().st_dev - except OSError: - return False - - dev = self.stat().st_dev - if dev != parent_dev: - return True - ino = self.stat().st_ino - parent_ino = self.parent.stat().st_ino - return ino == parent_ino - - def is_symlink(self): - """ - Whether this path is a symbolic link. - """ - try: - return S_ISLNK(self.lstat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist - return False - except ValueError: - # Non-encodable path - return False - - def is_block_device(self): - """ - Whether this path is a block device. - """ - try: - return S_ISBLK(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_char_device(self): - """ - Whether this path is a character device. - """ - try: - return S_ISCHR(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_fifo(self): - """ - Whether this path is a FIFO. - """ - try: - return S_ISFIFO(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_socket(self): - """ - Whether this path is a socket. - """ - try: - return S_ISSOCK(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def expanduser(self): - """ Return a new path with expanded ~ and ~user constructs - (as returned by os.path.expanduser) - """ - if (not (self._drv or self._root) and - self._parts and self._parts[0][:1] == '~'): - homedir = os.path.expanduser(self._parts[0]) - if homedir[:1] == "~": - raise RuntimeError("Could not determine home directory.") - return self._from_parts([homedir] + self._parts[1:]) - - return self - - -class PosixPath(Path, PurePosixPath): - """Path subclass for non-Windows systems. - - On a POSIX system, instantiating a Path should return this object. - """ - __slots__ = () - -class WindowsPath(Path, PureWindowsPath): - """Path subclass for Windows systems. - - On a Windows system, instantiating a Path should return this object. - """ - __slots__ = () - - def is_mount(self): - raise NotImplementedError("Path.is_mount() is unsupported on this system") diff --git a/python/Lib/pdb.py b/python/Lib/pdb.py deleted file mode 100644 index 09aa2b2..0000000 --- a/python/Lib/pdb.py +++ /dev/null @@ -1,1801 +0,0 @@ -#! /usr/bin/env python3 - -""" -The Python Debugger Pdb -======================= - -To use the debugger in its simplest form: - - >>> import pdb - >>> pdb.run('') - -The debugger's prompt is '(Pdb) '. This will stop in the first -function call in . - -Alternatively, if a statement terminated with an unhandled exception, -you can use pdb's post-mortem facility to inspect the contents of the -traceback: - - >>> - - >>> import pdb - >>> pdb.pm() - -The commands recognized by the debugger are listed in the next -section. Most can be abbreviated as indicated; e.g., h(elp) means -that 'help' can be typed as 'h' or 'help' (but not as 'he' or 'hel', -nor as 'H' or 'Help' or 'HELP'). Optional arguments are enclosed in -square brackets. Alternatives in the command syntax are separated -by a vertical bar (|). - -A blank line repeats the previous command literally, except for -'list', where it lists the next 11 lines. - -Commands that the debugger doesn't recognize are assumed to be Python -statements and are executed in the context of the program being -debugged. Python statements can also be prefixed with an exclamation -point ('!'). This is a powerful way to inspect the program being -debugged; it is even possible to change variables or call functions. -When an exception occurs in such a statement, the exception name is -printed but the debugger's state is not changed. - -The debugger supports aliases, which can save typing. And aliases can -have parameters (see the alias help entry) which allows one a certain -level of adaptability to the context under examination. - -Multiple commands may be entered on a single line, separated by the -pair ';;'. No intelligence is applied to separating the commands; the -input is split at the first ';;', even if it is in the middle of a -quoted string. - -If a file ".pdbrc" exists in your home directory or in the current -directory, it is read in and executed as if it had been typed at the -debugger prompt. This is particularly useful for aliases. If both -files exist, the one in the home directory is read first and aliases -defined there can be overridden by the local file. This behavior can be -disabled by passing the "readrc=False" argument to the Pdb constructor. - -Aside from aliases, the debugger is not directly programmable; but it -is implemented as a class from which you can derive your own debugger -class, which you can make as fancy as you like. - - -Debugger commands -================= - -""" -# NOTE: the actual command documentation is collected from docstrings of the -# commands and is appended to __doc__ after the class has been defined. - -import os -import io -import re -import sys -import cmd -import bdb -import dis -import code -import glob -import pprint -import signal -import inspect -import tokenize -import functools -import traceback -import linecache - -from typing import Union - - -class Restart(Exception): - """Causes a debugger to be restarted for the debugged python program.""" - pass - -__all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace", - "post_mortem", "help"] - -def find_function(funcname, filename): - cre = re.compile(r'def\s+%s\s*[(]' % re.escape(funcname)) - try: - fp = tokenize.open(filename) - except OSError: - return None - # consumer of this info expects the first line to be 1 - with fp: - for lineno, line in enumerate(fp, start=1): - if cre.match(line): - return funcname, filename, lineno - return None - -def getsourcelines(obj): - lines, lineno = inspect.findsource(obj) - if inspect.isframe(obj) and obj.f_globals is obj.f_locals: - # must be a module frame: do not try to cut a block out of it - return lines, 1 - elif inspect.ismodule(obj): - return lines, 1 - return inspect.getblock(lines[lineno:]), lineno+1 - -def lasti2lineno(code, lasti): - linestarts = list(dis.findlinestarts(code)) - linestarts.reverse() - for i, lineno in linestarts: - if lasti >= i: - return lineno - return 0 - - -class _rstr(str): - """String that doesn't quote its repr.""" - def __repr__(self): - return self - - -class _ScriptTarget(str): - def __new__(cls, val): - # Mutate self to be the "real path". - res = super().__new__(cls, os.path.realpath(val)) - - # Store the original path for error reporting. - res.orig = val - - return res - - def check(self): - if not os.path.exists(self): - print('Error:', self.orig, 'does not exist') - sys.exit(1) - - # Replace pdb's dir with script's dir in front of module search path. - sys.path[0] = os.path.dirname(self) - - @property - def filename(self): - return self - - @property - def namespace(self): - return dict( - __name__='__main__', - __file__=self, - __builtins__=__builtins__, - ) - - @property - def code(self): - with io.open(self) as fp: - return f"exec(compile({fp.read()!r}, {self!r}, 'exec'))" - - -class _ModuleTarget(str): - def check(self): - try: - self._details - except Exception: - traceback.print_exc() - sys.exit(1) - - @functools.cached_property - def _details(self): - import runpy - return runpy._get_module_details(self) - - @property - def filename(self): - return self.code.co_filename - - @property - def code(self): - name, spec, code = self._details - return code - - @property - def _spec(self): - name, spec, code = self._details - return spec - - @property - def namespace(self): - return dict( - __name__='__main__', - __file__=os.path.normcase(os.path.abspath(self.filename)), - __package__=self._spec.parent, - __loader__=self._spec.loader, - __spec__=self._spec, - __builtins__=__builtins__, - ) - - -# Interaction prompt line will separate file and call info from code -# text using value of line_prefix string. A newline and arrow may -# be to your liking. You can set it once pdb is imported using the -# command "pdb.line_prefix = '\n% '". -# line_prefix = ': ' # Use this to get the old situation back -line_prefix = '\n-> ' # Probably a better default - -class Pdb(bdb.Bdb, cmd.Cmd): - - _previous_sigint_handler = None - - def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, - nosigint=False, readrc=True): - bdb.Bdb.__init__(self, skip=skip) - cmd.Cmd.__init__(self, completekey, stdin, stdout) - sys.audit("pdb.Pdb") - if stdout: - self.use_rawinput = 0 - self.prompt = '(Pdb) ' - self.aliases = {} - self.displaying = {} - self.mainpyfile = '' - self._wait_for_mainpyfile = False - self.tb_lineno = {} - # Try to load readline if it exists - try: - import readline - # remove some common file name delimiters - readline.set_completer_delims(' \t\n`@#$%^&*()=+[{]}\\|;:\'",<>?') - except ImportError: - pass - self.allow_kbdint = False - self.nosigint = nosigint - - # Read ~/.pdbrc and ./.pdbrc - self.rcLines = [] - if readrc: - try: - with open(os.path.expanduser('~/.pdbrc'), encoding='utf-8') as rcFile: - self.rcLines.extend(rcFile) - except OSError: - pass - try: - with open(".pdbrc", encoding='utf-8') as rcFile: - self.rcLines.extend(rcFile) - except OSError: - pass - - self.commands = {} # associates a command list to breakpoint numbers - self.commands_doprompt = {} # for each bp num, tells if the prompt - # must be disp. after execing the cmd list - self.commands_silent = {} # for each bp num, tells if the stack trace - # must be disp. after execing the cmd list - self.commands_defining = False # True while in the process of defining - # a command list - self.commands_bnum = None # The breakpoint number for which we are - # defining a list - - def sigint_handler(self, signum, frame): - if self.allow_kbdint: - raise KeyboardInterrupt - self.message("\nProgram interrupted. (Use 'cont' to resume).") - self.set_step() - self.set_trace(frame) - - def reset(self): - bdb.Bdb.reset(self) - self.forget() - - def forget(self): - self.lineno = None - self.stack = [] - self.curindex = 0 - self.curframe = None - self.tb_lineno.clear() - - def setup(self, f, tb): - self.forget() - self.stack, self.curindex = self.get_stack(f, tb) - while tb: - # when setting up post-mortem debugging with a traceback, save all - # the original line numbers to be displayed along the current line - # numbers (which can be different, e.g. due to finally clauses) - lineno = lasti2lineno(tb.tb_frame.f_code, tb.tb_lasti) - self.tb_lineno[tb.tb_frame] = lineno - tb = tb.tb_next - self.curframe = self.stack[self.curindex][0] - # The f_locals dictionary is updated from the actual frame - # locals whenever the .f_locals accessor is called, so we - # cache it here to ensure that modifications are not overwritten. - self.curframe_locals = self.curframe.f_locals - return self.execRcLines() - - # Can be executed earlier than 'setup' if desired - def execRcLines(self): - if not self.rcLines: - return - # local copy because of recursion - rcLines = self.rcLines - rcLines.reverse() - # execute every line only once - self.rcLines = [] - while rcLines: - line = rcLines.pop().strip() - if line and line[0] != '#': - if self.onecmd(line): - # if onecmd returns True, the command wants to exit - # from the interaction, save leftover rc lines - # to execute before next interaction - self.rcLines += reversed(rcLines) - return True - - # Override Bdb methods - - def user_call(self, frame, argument_list): - """This method is called when there is the remote possibility - that we ever need to stop in this function.""" - if self._wait_for_mainpyfile: - return - if self.stop_here(frame): - self.message('--Call--') - self.interaction(frame, None) - - def user_line(self, frame): - """This function is called when we stop or break at this line.""" - if self._wait_for_mainpyfile: - if (self.mainpyfile != self.canonic(frame.f_code.co_filename) - or frame.f_lineno <= 0): - return - self._wait_for_mainpyfile = False - if self.bp_commands(frame): - self.interaction(frame, None) - - def bp_commands(self, frame): - """Call every command that was set for the current active breakpoint - (if there is one). - - Returns True if the normal interaction function must be called, - False otherwise.""" - # self.currentbp is set in bdb in Bdb.break_here if a breakpoint was hit - if getattr(self, "currentbp", False) and \ - self.currentbp in self.commands: - currentbp = self.currentbp - self.currentbp = 0 - lastcmd_back = self.lastcmd - self.setup(frame, None) - for line in self.commands[currentbp]: - self.onecmd(line) - self.lastcmd = lastcmd_back - if not self.commands_silent[currentbp]: - self.print_stack_entry(self.stack[self.curindex]) - if self.commands_doprompt[currentbp]: - self._cmdloop() - self.forget() - return - return 1 - - def user_return(self, frame, return_value): - """This function is called when a return trap is set here.""" - if self._wait_for_mainpyfile: - return - frame.f_locals['__return__'] = return_value - self.message('--Return--') - self.interaction(frame, None) - - def user_exception(self, frame, exc_info): - """This function is called if an exception occurs, - but only if we are to stop at or just below this level.""" - if self._wait_for_mainpyfile: - return - exc_type, exc_value, exc_traceback = exc_info - frame.f_locals['__exception__'] = exc_type, exc_value - - # An 'Internal StopIteration' exception is an exception debug event - # issued by the interpreter when handling a subgenerator run with - # 'yield from' or a generator controlled by a for loop. No exception has - # actually occurred in this case. The debugger uses this debug event to - # stop when the debuggee is returning from such generators. - prefix = 'Internal ' if (not exc_traceback - and exc_type is StopIteration) else '' - self.message('%s%s' % (prefix, - traceback.format_exception_only(exc_type, exc_value)[-1].strip())) - self.interaction(frame, exc_traceback) - - # General interaction function - def _cmdloop(self): - while True: - try: - # keyboard interrupts allow for an easy way to cancel - # the current command, so allow them during interactive input - self.allow_kbdint = True - self.cmdloop() - self.allow_kbdint = False - break - except KeyboardInterrupt: - self.message('--KeyboardInterrupt--') - - # Called before loop, handles display expressions - def preloop(self): - displaying = self.displaying.get(self.curframe) - if displaying: - for expr, oldvalue in displaying.items(): - newvalue = self._getval_except(expr) - # check for identity first; this prevents custom __eq__ to - # be called at every loop, and also prevents instances whose - # fields are changed to be displayed - if newvalue is not oldvalue and newvalue != oldvalue: - displaying[expr] = newvalue - self.message('display %s: %r [old: %r]' % - (expr, newvalue, oldvalue)) - - def interaction(self, frame, traceback): - # Restore the previous signal handler at the Pdb prompt. - if Pdb._previous_sigint_handler: - try: - signal.signal(signal.SIGINT, Pdb._previous_sigint_handler) - except ValueError: # ValueError: signal only works in main thread - pass - else: - Pdb._previous_sigint_handler = None - if self.setup(frame, traceback): - # no interaction desired at this time (happens if .pdbrc contains - # a command like "continue") - self.forget() - return - self.print_stack_entry(self.stack[self.curindex]) - self._cmdloop() - self.forget() - - def displayhook(self, obj): - """Custom displayhook for the exec in default(), which prevents - assignment of the _ variable in the builtins. - """ - # reproduce the behavior of the standard displayhook, not printing None - if obj is not None: - self.message(repr(obj)) - - def default(self, line): - if line[:1] == '!': line = line[1:] - locals = self.curframe_locals - globals = self.curframe.f_globals - try: - code = compile(line + '\n', '', 'single') - save_stdout = sys.stdout - save_stdin = sys.stdin - save_displayhook = sys.displayhook - try: - sys.stdin = self.stdin - sys.stdout = self.stdout - sys.displayhook = self.displayhook - exec(code, globals, locals) - finally: - sys.stdout = save_stdout - sys.stdin = save_stdin - sys.displayhook = save_displayhook - except: - self._error_exc() - - def precmd(self, line): - """Handle alias expansion and ';;' separator.""" - if not line.strip(): - return line - args = line.split() - while args[0] in self.aliases: - line = self.aliases[args[0]] - ii = 1 - for tmpArg in args[1:]: - line = line.replace("%" + str(ii), - tmpArg) - ii += 1 - line = line.replace("%*", ' '.join(args[1:])) - args = line.split() - # split into ';;' separated commands - # unless it's an alias command - if args[0] != 'alias': - marker = line.find(';;') - if marker >= 0: - # queue up everything after marker - next = line[marker+2:].lstrip() - self.cmdqueue.append(next) - line = line[:marker].rstrip() - return line - - def onecmd(self, line): - """Interpret the argument as though it had been typed in response - to the prompt. - - Checks whether this line is typed at the normal prompt or in - a breakpoint command list definition. - """ - if not self.commands_defining: - return cmd.Cmd.onecmd(self, line) - else: - return self.handle_command_def(line) - - def handle_command_def(self, line): - """Handles one command line during command list definition.""" - cmd, arg, line = self.parseline(line) - if not cmd: - return - if cmd == 'silent': - self.commands_silent[self.commands_bnum] = True - return # continue to handle other cmd def in the cmd list - elif cmd == 'end': - self.cmdqueue = [] - return 1 # end of cmd list - cmdlist = self.commands[self.commands_bnum] - if arg: - cmdlist.append(cmd+' '+arg) - else: - cmdlist.append(cmd) - # Determine if we must stop - try: - func = getattr(self, 'do_' + cmd) - except AttributeError: - func = self.default - # one of the resuming commands - if func.__name__ in self.commands_resuming: - self.commands_doprompt[self.commands_bnum] = False - self.cmdqueue = [] - return 1 - return - - # interface abstraction functions - - def message(self, msg): - print(msg, file=self.stdout) - - def error(self, msg): - print('***', msg, file=self.stdout) - - # Generic completion functions. Individual complete_foo methods can be - # assigned below to one of these functions. - - def _complete_location(self, text, line, begidx, endidx): - # Complete a file/module/function location for break/tbreak/clear. - if line.strip().endswith((':', ',')): - # Here comes a line number or a condition which we can't complete. - return [] - # First, try to find matching functions (i.e. expressions). - try: - ret = self._complete_expression(text, line, begidx, endidx) - except Exception: - ret = [] - # Then, try to complete file names as well. - globs = glob.glob(glob.escape(text) + '*') - for fn in globs: - if os.path.isdir(fn): - ret.append(fn + '/') - elif os.path.isfile(fn) and fn.lower().endswith(('.py', '.pyw')): - ret.append(fn + ':') - return ret - - def _complete_bpnumber(self, text, line, begidx, endidx): - # Complete a breakpoint number. (This would be more helpful if we could - # display additional info along with the completions, such as file/line - # of the breakpoint.) - return [str(i) for i, bp in enumerate(bdb.Breakpoint.bpbynumber) - if bp is not None and str(i).startswith(text)] - - def _complete_expression(self, text, line, begidx, endidx): - # Complete an arbitrary expression. - if not self.curframe: - return [] - # Collect globals and locals. It is usually not really sensible to also - # complete builtins, and they clutter the namespace quite heavily, so we - # leave them out. - ns = {**self.curframe.f_globals, **self.curframe_locals} - if '.' in text: - # Walk an attribute chain up to the last part, similar to what - # rlcompleter does. This will bail if any of the parts are not - # simple attribute access, which is what we want. - dotted = text.split('.') - try: - obj = ns[dotted[0]] - for part in dotted[1:-1]: - obj = getattr(obj, part) - except (KeyError, AttributeError): - return [] - prefix = '.'.join(dotted[:-1]) + '.' - return [prefix + n for n in dir(obj) if n.startswith(dotted[-1])] - else: - # Complete a simple name. - return [n for n in ns.keys() if n.startswith(text)] - - # Command definitions, called by cmdloop() - # The argument is the remaining string on the command line - # Return true to exit from the command loop - - def do_commands(self, arg): - """commands [bpnumber] - (com) ... - (com) end - (Pdb) - - Specify a list of commands for breakpoint number bpnumber. - The commands themselves are entered on the following lines. - Type a line containing just 'end' to terminate the commands. - The commands are executed when the breakpoint is hit. - - To remove all commands from a breakpoint, type commands and - follow it immediately with end; that is, give no commands. - - With no bpnumber argument, commands refers to the last - breakpoint set. - - You can use breakpoint commands to start your program up - again. Simply use the continue command, or step, or any other - command that resumes execution. - - Specifying any command resuming execution (currently continue, - step, next, return, jump, quit and their abbreviations) - terminates the command list (as if that command was - immediately followed by end). This is because any time you - resume execution (even with a simple next or step), you may - encounter another breakpoint -- which could have its own - command list, leading to ambiguities about which list to - execute. - - If you use the 'silent' command in the command list, the usual - message about stopping at a breakpoint is not printed. This - may be desirable for breakpoints that are to print a specific - message and then continue. If none of the other commands - print anything, you will see no sign that the breakpoint was - reached. - """ - if not arg: - bnum = len(bdb.Breakpoint.bpbynumber) - 1 - else: - try: - bnum = int(arg) - except: - self.error("Usage: commands [bnum]\n ...\n end") - return - try: - self.get_bpbynumber(bnum) - except ValueError as err: - self.error('cannot set commands: %s' % err) - return - - self.commands_bnum = bnum - # Save old definitions for the case of a keyboard interrupt. - if bnum in self.commands: - old_command_defs = (self.commands[bnum], - self.commands_doprompt[bnum], - self.commands_silent[bnum]) - else: - old_command_defs = None - self.commands[bnum] = [] - self.commands_doprompt[bnum] = True - self.commands_silent[bnum] = False - - prompt_back = self.prompt - self.prompt = '(com) ' - self.commands_defining = True - try: - self.cmdloop() - except KeyboardInterrupt: - # Restore old definitions. - if old_command_defs: - self.commands[bnum] = old_command_defs[0] - self.commands_doprompt[bnum] = old_command_defs[1] - self.commands_silent[bnum] = old_command_defs[2] - else: - del self.commands[bnum] - del self.commands_doprompt[bnum] - del self.commands_silent[bnum] - self.error('command definition aborted, old commands restored') - finally: - self.commands_defining = False - self.prompt = prompt_back - - complete_commands = _complete_bpnumber - - def do_break(self, arg, temporary = 0): - """b(reak) [ ([filename:]lineno | function) [, condition] ] - Without argument, list all breaks. - - With a line number argument, set a break at this line in the - current file. With a function name, set a break at the first - executable line of that function. If a second argument is - present, it is a string specifying an expression which must - evaluate to true before the breakpoint is honored. - - The line number may be prefixed with a filename and a colon, - to specify a breakpoint in another file (probably one that - hasn't been loaded yet). The file is searched for on - sys.path; the .py suffix may be omitted. - """ - if not arg: - if self.breaks: # There's at least one - self.message("Num Type Disp Enb Where") - for bp in bdb.Breakpoint.bpbynumber: - if bp: - self.message(bp.bpformat()) - return - # parse arguments; comma has lowest precedence - # and cannot occur in filename - filename = None - lineno = None - cond = None - comma = arg.find(',') - if comma > 0: - # parse stuff after comma: "condition" - cond = arg[comma+1:].lstrip() - arg = arg[:comma].rstrip() - # parse stuff before comma: [filename:]lineno | function - colon = arg.rfind(':') - funcname = None - if colon >= 0: - filename = arg[:colon].rstrip() - f = self.lookupmodule(filename) - if not f: - self.error('%r not found from sys.path' % filename) - return - else: - filename = f - arg = arg[colon+1:].lstrip() - try: - lineno = int(arg) - except ValueError: - self.error('Bad lineno: %s' % arg) - return - else: - # no colon; can be lineno or function - try: - lineno = int(arg) - except ValueError: - try: - func = eval(arg, - self.curframe.f_globals, - self.curframe_locals) - except: - func = arg - try: - if hasattr(func, '__func__'): - func = func.__func__ - code = func.__code__ - #use co_name to identify the bkpt (function names - #could be aliased, but co_name is invariant) - funcname = code.co_name - lineno = code.co_firstlineno - filename = code.co_filename - except: - # last thing to try - (ok, filename, ln) = self.lineinfo(arg) - if not ok: - self.error('The specified object %r is not a function ' - 'or was not found along sys.path.' % arg) - return - funcname = ok # ok contains a function name - lineno = int(ln) - if not filename: - filename = self.defaultFile() - # Check for reasonable breakpoint - line = self.checkline(filename, lineno) - if line: - # now set the break point - err = self.set_break(filename, line, temporary, cond, funcname) - if err: - self.error(err) - else: - bp = self.get_breaks(filename, line)[-1] - self.message("Breakpoint %d at %s:%d" % - (bp.number, bp.file, bp.line)) - - # To be overridden in derived debuggers - def defaultFile(self): - """Produce a reasonable default.""" - filename = self.curframe.f_code.co_filename - if filename == '' and self.mainpyfile: - filename = self.mainpyfile - return filename - - do_b = do_break - - complete_break = _complete_location - complete_b = _complete_location - - def do_tbreak(self, arg): - """tbreak [ ([filename:]lineno | function) [, condition] ] - Same arguments as break, but sets a temporary breakpoint: it - is automatically deleted when first hit. - """ - self.do_break(arg, 1) - - complete_tbreak = _complete_location - - def lineinfo(self, identifier): - failed = (None, None, None) - # Input is identifier, may be in single quotes - idstring = identifier.split("'") - if len(idstring) == 1: - # not in single quotes - id = idstring[0].strip() - elif len(idstring) == 3: - # quoted - id = idstring[1].strip() - else: - return failed - if id == '': return failed - parts = id.split('.') - # Protection for derived debuggers - if parts[0] == 'self': - del parts[0] - if len(parts) == 0: - return failed - # Best first guess at file to look at - fname = self.defaultFile() - if len(parts) == 1: - item = parts[0] - else: - # More than one part. - # First is module, second is method/class - f = self.lookupmodule(parts[0]) - if f: - fname = f - item = parts[1] - answer = find_function(item, fname) - return answer or failed - - def checkline(self, filename, lineno): - """Check whether specified line seems to be executable. - - Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank - line or EOF). Warning: testing is not comprehensive. - """ - # this method should be callable before starting debugging, so default - # to "no globals" if there is no current frame - frame = getattr(self, 'curframe', None) - globs = frame.f_globals if frame else None - line = linecache.getline(filename, lineno, globs) - if not line: - self.message('End of file') - return 0 - line = line.strip() - # Don't allow setting breakpoint at a blank line - if (not line or (line[0] == '#') or - (line[:3] == '"""') or line[:3] == "'''"): - self.error('Blank or comment') - return 0 - return lineno - - def do_enable(self, arg): - """enable bpnumber [bpnumber ...] - Enables the breakpoints given as a space separated list of - breakpoint numbers. - """ - args = arg.split() - for i in args: - try: - bp = self.get_bpbynumber(i) - except ValueError as err: - self.error(err) - else: - bp.enable() - self.message('Enabled %s' % bp) - - complete_enable = _complete_bpnumber - - def do_disable(self, arg): - """disable bpnumber [bpnumber ...] - Disables the breakpoints given as a space separated list of - breakpoint numbers. Disabling a breakpoint means it cannot - cause the program to stop execution, but unlike clearing a - breakpoint, it remains in the list of breakpoints and can be - (re-)enabled. - """ - args = arg.split() - for i in args: - try: - bp = self.get_bpbynumber(i) - except ValueError as err: - self.error(err) - else: - bp.disable() - self.message('Disabled %s' % bp) - - complete_disable = _complete_bpnumber - - def do_condition(self, arg): - """condition bpnumber [condition] - Set a new condition for the breakpoint, an expression which - must evaluate to true before the breakpoint is honored. If - condition is absent, any existing condition is removed; i.e., - the breakpoint is made unconditional. - """ - args = arg.split(' ', 1) - try: - cond = args[1] - except IndexError: - cond = None - try: - bp = self.get_bpbynumber(args[0].strip()) - except IndexError: - self.error('Breakpoint number expected') - except ValueError as err: - self.error(err) - else: - bp.cond = cond - if not cond: - self.message('Breakpoint %d is now unconditional.' % bp.number) - else: - self.message('New condition set for breakpoint %d.' % bp.number) - - complete_condition = _complete_bpnumber - - def do_ignore(self, arg): - """ignore bpnumber [count] - Set the ignore count for the given breakpoint number. If - count is omitted, the ignore count is set to 0. A breakpoint - becomes active when the ignore count is zero. When non-zero, - the count is decremented each time the breakpoint is reached - and the breakpoint is not disabled and any associated - condition evaluates to true. - """ - args = arg.split() - try: - count = int(args[1].strip()) - except: - count = 0 - try: - bp = self.get_bpbynumber(args[0].strip()) - except IndexError: - self.error('Breakpoint number expected') - except ValueError as err: - self.error(err) - else: - bp.ignore = count - if count > 0: - if count > 1: - countstr = '%d crossings' % count - else: - countstr = '1 crossing' - self.message('Will ignore next %s of breakpoint %d.' % - (countstr, bp.number)) - else: - self.message('Will stop next time breakpoint %d is reached.' - % bp.number) - - complete_ignore = _complete_bpnumber - - def do_clear(self, arg): - """cl(ear) filename:lineno\ncl(ear) [bpnumber [bpnumber...]] - With a space separated list of breakpoint numbers, clear - those breakpoints. Without argument, clear all breaks (but - first ask confirmation). With a filename:lineno argument, - clear all breaks at that line in that file. - """ - if not arg: - try: - reply = input('Clear all breaks? ') - except EOFError: - reply = 'no' - reply = reply.strip().lower() - if reply in ('y', 'yes'): - bplist = [bp for bp in bdb.Breakpoint.bpbynumber if bp] - self.clear_all_breaks() - for bp in bplist: - self.message('Deleted %s' % bp) - return - if ':' in arg: - # Make sure it works for "clear C:\foo\bar.py:12" - i = arg.rfind(':') - filename = arg[:i] - arg = arg[i+1:] - try: - lineno = int(arg) - except ValueError: - err = "Invalid line number (%s)" % arg - else: - bplist = self.get_breaks(filename, lineno)[:] - err = self.clear_break(filename, lineno) - if err: - self.error(err) - else: - for bp in bplist: - self.message('Deleted %s' % bp) - return - numberlist = arg.split() - for i in numberlist: - try: - bp = self.get_bpbynumber(i) - except ValueError as err: - self.error(err) - else: - self.clear_bpbynumber(i) - self.message('Deleted %s' % bp) - do_cl = do_clear # 'c' is already an abbreviation for 'continue' - - complete_clear = _complete_location - complete_cl = _complete_location - - def do_where(self, arg): - """w(here) - Print a stack trace, with the most recent frame at the bottom. - An arrow indicates the "current frame", which determines the - context of most commands. 'bt' is an alias for this command. - """ - self.print_stack_trace() - do_w = do_where - do_bt = do_where - - def _select_frame(self, number): - assert 0 <= number < len(self.stack) - self.curindex = number - self.curframe = self.stack[self.curindex][0] - self.curframe_locals = self.curframe.f_locals - self.print_stack_entry(self.stack[self.curindex]) - self.lineno = None - - def do_up(self, arg): - """u(p) [count] - Move the current frame count (default one) levels up in the - stack trace (to an older frame). - """ - if self.curindex == 0: - self.error('Oldest frame') - return - try: - count = int(arg or 1) - except ValueError: - self.error('Invalid frame count (%s)' % arg) - return - if count < 0: - newframe = 0 - else: - newframe = max(0, self.curindex - count) - self._select_frame(newframe) - do_u = do_up - - def do_down(self, arg): - """d(own) [count] - Move the current frame count (default one) levels down in the - stack trace (to a newer frame). - """ - if self.curindex + 1 == len(self.stack): - self.error('Newest frame') - return - try: - count = int(arg or 1) - except ValueError: - self.error('Invalid frame count (%s)' % arg) - return - if count < 0: - newframe = len(self.stack) - 1 - else: - newframe = min(len(self.stack) - 1, self.curindex + count) - self._select_frame(newframe) - do_d = do_down - - def do_until(self, arg): - """unt(il) [lineno] - Without argument, continue execution until the line with a - number greater than the current one is reached. With a line - number, continue execution until a line with a number greater - or equal to that is reached. In both cases, also stop when - the current frame returns. - """ - if arg: - try: - lineno = int(arg) - except ValueError: - self.error('Error in argument: %r' % arg) - return - if lineno <= self.curframe.f_lineno: - self.error('"until" line number is smaller than current ' - 'line number') - return - else: - lineno = None - self.set_until(self.curframe, lineno) - return 1 - do_unt = do_until - - def do_step(self, arg): - """s(tep) - Execute the current line, stop at the first possible occasion - (either in a function that is called or in the current - function). - """ - self.set_step() - return 1 - do_s = do_step - - def do_next(self, arg): - """n(ext) - Continue execution until the next line in the current function - is reached or it returns. - """ - self.set_next(self.curframe) - return 1 - do_n = do_next - - def do_run(self, arg): - """run [args...] - Restart the debugged python program. If a string is supplied - it is split with "shlex", and the result is used as the new - sys.argv. History, breakpoints, actions and debugger options - are preserved. "restart" is an alias for "run". - """ - if arg: - import shlex - argv0 = sys.argv[0:1] - try: - sys.argv = shlex.split(arg) - except ValueError as e: - self.error('Cannot run %s: %s' % (arg, e)) - return - sys.argv[:0] = argv0 - # this is caught in the main debugger loop - raise Restart - - do_restart = do_run - - def do_return(self, arg): - """r(eturn) - Continue execution until the current function returns. - """ - self.set_return(self.curframe) - return 1 - do_r = do_return - - def do_continue(self, arg): - """c(ont(inue)) - Continue execution, only stop when a breakpoint is encountered. - """ - if not self.nosigint: - try: - Pdb._previous_sigint_handler = \ - signal.signal(signal.SIGINT, self.sigint_handler) - except ValueError: - # ValueError happens when do_continue() is invoked from - # a non-main thread in which case we just continue without - # SIGINT set. Would printing a message here (once) make - # sense? - pass - self.set_continue() - return 1 - do_c = do_cont = do_continue - - def do_jump(self, arg): - """j(ump) lineno - Set the next line that will be executed. Only available in - the bottom-most frame. This lets you jump back and execute - code again, or jump forward to skip code that you don't want - to run. - - It should be noted that not all jumps are allowed -- for - instance it is not possible to jump into the middle of a - for loop or out of a finally clause. - """ - if self.curindex + 1 != len(self.stack): - self.error('You can only jump within the bottom frame') - return - try: - arg = int(arg) - except ValueError: - self.error("The 'jump' command requires a line number") - else: - try: - # Do the jump, fix up our copy of the stack, and display the - # new position - self.curframe.f_lineno = arg - self.stack[self.curindex] = self.stack[self.curindex][0], arg - self.print_stack_entry(self.stack[self.curindex]) - except ValueError as e: - self.error('Jump failed: %s' % e) - do_j = do_jump - - def do_debug(self, arg): - """debug code - Enter a recursive debugger that steps through the code - argument (which is an arbitrary expression or statement to be - executed in the current environment). - """ - sys.settrace(None) - globals = self.curframe.f_globals - locals = self.curframe_locals - p = Pdb(self.completekey, self.stdin, self.stdout) - p.prompt = "(%s) " % self.prompt.strip() - self.message("ENTERING RECURSIVE DEBUGGER") - try: - sys.call_tracing(p.run, (arg, globals, locals)) - except Exception: - self._error_exc() - self.message("LEAVING RECURSIVE DEBUGGER") - sys.settrace(self.trace_dispatch) - self.lastcmd = p.lastcmd - - complete_debug = _complete_expression - - def do_quit(self, arg): - """q(uit)\nexit - Quit from the debugger. The program being executed is aborted. - """ - self._user_requested_quit = True - self.set_quit() - return 1 - - do_q = do_quit - do_exit = do_quit - - def do_EOF(self, arg): - """EOF - Handles the receipt of EOF as a command. - """ - self.message('') - self._user_requested_quit = True - self.set_quit() - return 1 - - def do_args(self, arg): - """a(rgs) - Print the argument list of the current function. - """ - co = self.curframe.f_code - dict = self.curframe_locals - n = co.co_argcount + co.co_kwonlyargcount - if co.co_flags & inspect.CO_VARARGS: n = n+1 - if co.co_flags & inspect.CO_VARKEYWORDS: n = n+1 - for i in range(n): - name = co.co_varnames[i] - if name in dict: - self.message('%s = %r' % (name, dict[name])) - else: - self.message('%s = *** undefined ***' % (name,)) - do_a = do_args - - def do_retval(self, arg): - """retval - Print the return value for the last return of a function. - """ - if '__return__' in self.curframe_locals: - self.message(repr(self.curframe_locals['__return__'])) - else: - self.error('Not yet returned!') - do_rv = do_retval - - def _getval(self, arg): - try: - return eval(arg, self.curframe.f_globals, self.curframe_locals) - except: - self._error_exc() - raise - - def _getval_except(self, arg, frame=None): - try: - if frame is None: - return eval(arg, self.curframe.f_globals, self.curframe_locals) - else: - return eval(arg, frame.f_globals, frame.f_locals) - except: - exc_info = sys.exc_info()[:2] - err = traceback.format_exception_only(*exc_info)[-1].strip() - return _rstr('** raised %s **' % err) - - def _error_exc(self): - exc_info = sys.exc_info()[:2] - self.error(traceback.format_exception_only(*exc_info)[-1].strip()) - - def _msg_val_func(self, arg, func): - try: - val = self._getval(arg) - except: - return # _getval() has displayed the error - try: - self.message(func(val)) - except: - self._error_exc() - - def do_p(self, arg): - """p expression - Print the value of the expression. - """ - self._msg_val_func(arg, repr) - - def do_pp(self, arg): - """pp expression - Pretty-print the value of the expression. - """ - self._msg_val_func(arg, pprint.pformat) - - complete_print = _complete_expression - complete_p = _complete_expression - complete_pp = _complete_expression - - def do_list(self, arg): - """l(ist) [first [,last] | .] - - List source code for the current file. Without arguments, - list 11 lines around the current line or continue the previous - listing. With . as argument, list 11 lines around the current - line. With one argument, list 11 lines starting at that line. - With two arguments, list the given range; if the second - argument is less than the first, it is a count. - - The current line in the current frame is indicated by "->". - If an exception is being debugged, the line where the - exception was originally raised or propagated is indicated by - ">>", if it differs from the current line. - """ - self.lastcmd = 'list' - last = None - if arg and arg != '.': - try: - if ',' in arg: - first, last = arg.split(',') - first = int(first.strip()) - last = int(last.strip()) - if last < first: - # assume it's a count - last = first + last - else: - first = int(arg.strip()) - first = max(1, first - 5) - except ValueError: - self.error('Error in argument: %r' % arg) - return - elif self.lineno is None or arg == '.': - first = max(1, self.curframe.f_lineno - 5) - else: - first = self.lineno + 1 - if last is None: - last = first + 10 - filename = self.curframe.f_code.co_filename - # gh-93696: stdlib frozen modules provide a useful __file__ - # this workaround can be removed with the closure of gh-89815 - if filename.startswith("

    - - - - ''' % (cls, title) - if prelude: - result = result + ''' - - -''' % (cls, marginalia, cls, prelude, gap) - else: - result = result + ''' -''' % (cls, marginalia, gap) - - return result + '\n
     
    %s
    %s%s
    %s
    %s%s%s
    ' % contents - - def bigsection(self, title, *args): - """Format a section with a big heading.""" - title = '%s' % title - return self.section(title, *args) - - def preformat(self, text): - """Format literal preformatted text.""" - text = self.escape(text.expandtabs()) - return replace(text, '\n\n', '\n \n', '\n\n', '\n \n', - ' ', ' ', '\n', '
    \n') - - def multicolumn(self, list, format): - """Format a list of items into a multi-column list.""" - result = '' - rows = (len(list) + 3) // 4 - for col in range(4): - result = result + '' - for i in range(rows*col, rows*col+rows): - if i < len(list): - result = result + format(list[i]) + '
    \n' - result = result + '' - return '%s
    ' % result - - def grey(self, text): return '%s' % text - - def namelink(self, name, *dicts): - """Make a link for an identifier, given name-to-URL mappings.""" - for dict in dicts: - if name in dict: - return '
    %s' % (dict[name], name) - return name - - def classlink(self, object, modname): - """Make a link for a class.""" - name, module = object.__name__, sys.modules.get(object.__module__) - if hasattr(module, name) and getattr(module, name) is object: - return '%s' % ( - module.__name__, name, classname(object, modname)) - return classname(object, modname) - - def modulelink(self, object): - """Make a link for a module.""" - return '%s' % (object.__name__, object.__name__) - - def modpkglink(self, modpkginfo): - """Make a link for a module or package to display in an index.""" - name, path, ispackage, shadowed = modpkginfo - if shadowed: - return self.grey(name) - if path: - url = '%s.%s.html' % (path, name) - else: - url = '%s.html' % name - if ispackage: - text = '%s (package)' % name - else: - text = name - return '%s' % (url, text) - - def filelink(self, url, path): - """Make a link to source file.""" - return '%s' % (url, path) - - def markup(self, text, escape=None, funcs={}, classes={}, methods={}): - """Mark up some plain text, given a context of symbols to look for. - Each context dictionary maps object names to anchor names.""" - escape = escape or self.escape - results = [] - here = 0 - pattern = re.compile(r'\b((http|https|ftp)://\S+[\w/]|' - r'RFC[- ]?(\d+)|' - r'PEP[- ]?(\d+)|' - r'(self\.)?(\w+))') - while True: - match = pattern.search(text, here) - if not match: break - start, end = match.span() - results.append(escape(text[here:start])) - - all, scheme, rfc, pep, selfdot, name = match.groups() - if scheme: - url = escape(all).replace('"', '"') - results.append('%s' % (url, url)) - elif rfc: - url = 'https://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) - results.append('%s' % (url, escape(all))) - elif pep: - url = 'https://peps.python.org/pep-%04d/' % int(pep) - results.append('%s' % (url, escape(all))) - elif selfdot: - # Create a link for methods like 'self.method(...)' - # and use for attributes like 'self.attr' - if text[end:end+1] == '(': - results.append('self.' + self.namelink(name, methods)) - else: - results.append('self.%s' % name) - elif text[end:end+1] == '(': - results.append(self.namelink(name, methods, funcs, classes)) - else: - results.append(self.namelink(name, classes)) - here = end - results.append(escape(text[here:])) - return ''.join(results) - - # ---------------------------------------------- type-specific routines - - def formattree(self, tree, modname, parent=None): - """Produce HTML for a class tree as given by inspect.getclasstree().""" - result = '' - for entry in tree: - if type(entry) is type(()): - c, bases = entry - result = result + '

    ' - result = result + self.classlink(c, modname) - if bases and bases != (parent,): - parents = [] - for base in bases: - parents.append(self.classlink(base, modname)) - result = result + '(' + ', '.join(parents) + ')' - result = result + '\n
    ' - elif type(entry) is type([]): - result = result + '
    \n%s
    \n' % self.formattree( - entry, modname, c) - return '
    \n%s
    \n' % result - - def docmodule(self, object, name=None, mod=None, *ignored): - """Produce HTML documentation for a module object.""" - name = object.__name__ # ignore the passed-in name - try: - all = object.__all__ - except AttributeError: - all = None - parts = name.split('.') - links = [] - for i in range(len(parts)-1): - links.append( - '%s' % - ('.'.join(parts[:i+1]), parts[i])) - linkedname = '.'.join(links + parts[-1:]) - head = '%s' % linkedname - try: - path = inspect.getabsfile(object) - url = urllib.parse.quote(path) - filelink = self.filelink(url, path) - except TypeError: - filelink = '(built-in)' - info = [] - if hasattr(object, '__version__'): - version = str(object.__version__) - if version[:11] == '$' + 'Revision: ' and version[-1:] == '$': - version = version[11:-1].strip() - info.append('version %s' % self.escape(version)) - if hasattr(object, '__date__'): - info.append(self.escape(str(object.__date__))) - if info: - head = head + ' (%s)' % ', '.join(info) - docloc = self.getdocloc(object) - if docloc is not None: - docloc = '
    Module Reference' % locals() - else: - docloc = '' - result = self.heading(head, 'index
    ' + filelink + docloc) - - modules = inspect.getmembers(object, inspect.ismodule) - - classes, cdict = [], {} - for key, value in inspect.getmembers(object, inspect.isclass): - # if __all__ exists, believe it. Otherwise use old heuristic. - if (all is not None or - (inspect.getmodule(value) or object) is object): - if visiblename(key, all, object): - classes.append((key, value)) - cdict[key] = cdict[value] = '#' + key - for key, value in classes: - for base in value.__bases__: - key, modname = base.__name__, base.__module__ - module = sys.modules.get(modname) - if modname != name and module and hasattr(module, key): - if getattr(module, key) is base: - if not key in cdict: - cdict[key] = cdict[base] = modname + '.html#' + key - funcs, fdict = [], {} - for key, value in inspect.getmembers(object, inspect.isroutine): - # if __all__ exists, believe it. Otherwise use old heuristic. - if (all is not None or - inspect.isbuiltin(value) or inspect.getmodule(value) is object): - if visiblename(key, all, object): - funcs.append((key, value)) - fdict[key] = '#-' + key - if inspect.isfunction(value): fdict[value] = fdict[key] - data = [] - for key, value in inspect.getmembers(object, isdata): - if visiblename(key, all, object): - data.append((key, value)) - - doc = self.markup(getdoc(object), self.preformat, fdict, cdict) - doc = doc and '%s' % doc - result = result + '

    %s

    \n' % doc - - if hasattr(object, '__path__'): - modpkgs = [] - for importer, modname, ispkg in pkgutil.iter_modules(object.__path__): - modpkgs.append((modname, name, ispkg, 0)) - modpkgs.sort() - contents = self.multicolumn(modpkgs, self.modpkglink) - result = result + self.bigsection( - 'Package Contents', 'pkg-content', contents) - elif modules: - contents = self.multicolumn( - modules, lambda t: self.modulelink(t[1])) - result = result + self.bigsection( - 'Modules', 'pkg-content', contents) - - if classes: - classlist = [value for (key, value) in classes] - contents = [ - self.formattree(inspect.getclasstree(classlist, 1), name)] - for key, value in classes: - contents.append(self.document(value, key, name, fdict, cdict)) - result = result + self.bigsection( - 'Classes', 'index', ' '.join(contents)) - if funcs: - contents = [] - for key, value in funcs: - contents.append(self.document(value, key, name, fdict, cdict)) - result = result + self.bigsection( - 'Functions', 'functions', ' '.join(contents)) - if data: - contents = [] - for key, value in data: - contents.append(self.document(value, key)) - result = result + self.bigsection( - 'Data', 'data', '
    \n'.join(contents)) - if hasattr(object, '__author__'): - contents = self.markup(str(object.__author__), self.preformat) - result = result + self.bigsection('Author', 'author', contents) - if hasattr(object, '__credits__'): - contents = self.markup(str(object.__credits__), self.preformat) - result = result + self.bigsection('Credits', 'credits', contents) - - return result - - def docclass(self, object, name=None, mod=None, funcs={}, classes={}, - *ignored): - """Produce HTML documentation for a class object.""" - realname = object.__name__ - name = name or realname - bases = object.__bases__ - - contents = [] - push = contents.append - - # Cute little class to pump out a horizontal rule between sections. - class HorizontalRule: - def __init__(self): - self.needone = 0 - def maybe(self): - if self.needone: - push('
    \n') - self.needone = 1 - hr = HorizontalRule() - - # List the mro, if non-trivial. - mro = deque(inspect.getmro(object)) - if len(mro) > 2: - hr.maybe() - push('
    Method resolution order:
    \n') - for base in mro: - push('
    %s
    \n' % self.classlink(base, - object.__module__)) - push('
    \n') - - def spill(msg, attrs, predicate): - ok, attrs = _split_list(attrs, predicate) - if ok: - hr.maybe() - push(msg) - for name, kind, homecls, value in ok: - try: - value = getattr(object, name) - except Exception: - # Some descriptors may meet a failure in their __get__. - # (bug #1785) - push(self.docdata(value, name, mod)) - else: - push(self.document(value, name, mod, - funcs, classes, mdict, object)) - push('\n') - return attrs - - def spilldescriptors(msg, attrs, predicate): - ok, attrs = _split_list(attrs, predicate) - if ok: - hr.maybe() - push(msg) - for name, kind, homecls, value in ok: - push(self.docdata(value, name, mod)) - return attrs - - def spilldata(msg, attrs, predicate): - ok, attrs = _split_list(attrs, predicate) - if ok: - hr.maybe() - push(msg) - for name, kind, homecls, value in ok: - base = self.docother(getattr(object, name), name, mod) - doc = getdoc(value) - if not doc: - push('
    %s
    \n' % base) - else: - doc = self.markup(getdoc(value), self.preformat, - funcs, classes, mdict) - doc = '
    %s' % doc - push('
    %s%s
    \n' % (base, doc)) - push('\n') - return attrs - - attrs = [(name, kind, cls, value) - for name, kind, cls, value in classify_class_attrs(object) - if visiblename(name, obj=object)] - - mdict = {} - for key, kind, homecls, value in attrs: - mdict[key] = anchor = '#' + name + '-' + key - try: - value = getattr(object, name) - except Exception: - # Some descriptors may meet a failure in their __get__. - # (bug #1785) - pass - try: - # The value may not be hashable (e.g., a data attr with - # a dict or list value). - mdict[value] = anchor - except TypeError: - pass - - while attrs: - if mro: - thisclass = mro.popleft() - else: - thisclass = attrs[0][2] - attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) - - if object is not builtins.object and thisclass is builtins.object: - attrs = inherited - continue - elif thisclass is object: - tag = 'defined here' - else: - tag = 'inherited from %s' % self.classlink(thisclass, - object.__module__) - tag += ':
    \n' - - sort_attributes(attrs, object) - - # Pump out the attrs, segregated by kind. - attrs = spill('Methods %s' % tag, attrs, - lambda t: t[1] == 'method') - attrs = spill('Class methods %s' % tag, attrs, - lambda t: t[1] == 'class method') - attrs = spill('Static methods %s' % tag, attrs, - lambda t: t[1] == 'static method') - attrs = spilldescriptors("Readonly properties %s" % tag, attrs, - lambda t: t[1] == 'readonly property') - attrs = spilldescriptors('Data descriptors %s' % tag, attrs, - lambda t: t[1] == 'data descriptor') - attrs = spilldata('Data and other attributes %s' % tag, attrs, - lambda t: t[1] == 'data') - assert attrs == [] - attrs = inherited - - contents = ''.join(contents) - - if name == realname: - title = 'class %s' % ( - name, realname) - else: - title = '%s = class %s' % ( - name, name, realname) - if bases: - parents = [] - for base in bases: - parents.append(self.classlink(base, object.__module__)) - title = title + '(%s)' % ', '.join(parents) - - decl = '' - try: - signature = inspect.signature(object) - except (ValueError, TypeError): - signature = None - if signature: - argspec = str(signature) - if argspec and argspec != '()': - decl = name + self.escape(argspec) + '\n\n' - - doc = getdoc(object) - if decl: - doc = decl + (doc or '') - doc = self.markup(doc, self.preformat, funcs, classes, mdict) - doc = doc and '%s
     
    ' % doc - - return self.section(title, 'title', contents, 3, doc) - - def formatvalue(self, object): - """Format an argument default value as text.""" - return self.grey('=' + self.repr(object)) - - def docroutine(self, object, name=None, mod=None, - funcs={}, classes={}, methods={}, cl=None): - """Produce HTML documentation for a function or method object.""" - realname = object.__name__ - name = name or realname - anchor = (cl and cl.__name__ or '') + '-' + name - note = '' - skipdocs = 0 - if _is_bound_method(object): - imclass = object.__self__.__class__ - if cl: - if imclass is not cl: - note = ' from ' + self.classlink(imclass, mod) - else: - if object.__self__ is not None: - note = ' method of %s instance' % self.classlink( - object.__self__.__class__, mod) - else: - note = ' unbound %s method' % self.classlink(imclass,mod) - - if (inspect.iscoroutinefunction(object) or - inspect.isasyncgenfunction(object)): - asyncqualifier = 'async ' - else: - asyncqualifier = '' - - if name == realname: - title = '%s' % (anchor, realname) - else: - if cl and inspect.getattr_static(cl, realname, []) is object: - reallink = '%s' % ( - cl.__name__ + '-' + realname, realname) - skipdocs = 1 - else: - reallink = realname - title = '%s = %s' % ( - anchor, name, reallink) - argspec = None - if inspect.isroutine(object): - try: - signature = inspect.signature(object) - except (ValueError, TypeError): - signature = None - if signature: - argspec = str(signature) - if realname == '': - title = '%s lambda ' % name - # XXX lambda's won't usually have func_annotations['return'] - # since the syntax doesn't support but it is possible. - # So removing parentheses isn't truly safe. - argspec = argspec[1:-1] # remove parentheses - if not argspec: - argspec = '(...)' - - decl = asyncqualifier + title + self.escape(argspec) + (note and - self.grey('%s' % note)) - - if skipdocs: - return '
    %s
    \n' % decl - else: - doc = self.markup( - getdoc(object), self.preformat, funcs, classes, methods) - doc = doc and '
    %s
    ' % doc - return '
    %s
    %s
    \n' % (decl, doc) - - def docdata(self, object, name=None, mod=None, cl=None): - """Produce html documentation for a data descriptor.""" - results = [] - push = results.append - - if name: - push('
    %s
    \n' % name) - doc = self.markup(getdoc(object), self.preformat) - if doc: - push('
    %s
    \n' % doc) - push('
    \n') - - return ''.join(results) - - docproperty = docdata - - def docother(self, object, name=None, mod=None, *ignored): - """Produce HTML documentation for a data object.""" - lhs = name and '%s = ' % name or '' - return lhs + self.repr(object) - - def index(self, dir, shadowed=None): - """Generate an HTML index for a directory of modules.""" - modpkgs = [] - if shadowed is None: shadowed = {} - for importer, name, ispkg in pkgutil.iter_modules([dir]): - if any((0xD800 <= ord(ch) <= 0xDFFF) for ch in name): - # ignore a module if its name contains a surrogate character - continue - modpkgs.append((name, '', ispkg, name in shadowed)) - shadowed[name] = 1 - - modpkgs.sort() - contents = self.multicolumn(modpkgs, self.modpkglink) - return self.bigsection(dir, 'index', contents) - -# -------------------------------------------- text documentation generator - -class TextRepr(Repr): - """Class for safely making a text representation of a Python object.""" - def __init__(self): - Repr.__init__(self) - self.maxlist = self.maxtuple = 20 - self.maxdict = 10 - self.maxstring = self.maxother = 100 - - def repr1(self, x, level): - if hasattr(type(x), '__name__'): - methodname = 'repr_' + '_'.join(type(x).__name__.split()) - if hasattr(self, methodname): - return getattr(self, methodname)(x, level) - return cram(stripid(repr(x)), self.maxother) - - def repr_string(self, x, level): - test = cram(x, self.maxstring) - testrepr = repr(test) - if '\\' in test and '\\' not in replace(testrepr, r'\\', ''): - # Backslashes are only literal in the string and are never - # needed to make any special characters, so show a raw string. - return 'r' + testrepr[0] + test + testrepr[0] - return testrepr - - repr_str = repr_string - - def repr_instance(self, x, level): - try: - return cram(stripid(repr(x)), self.maxstring) - except: - return '<%s instance>' % x.__class__.__name__ - -class TextDoc(Doc): - """Formatter class for text documentation.""" - - # ------------------------------------------- text formatting utilities - - _repr_instance = TextRepr() - repr = _repr_instance.repr - - def bold(self, text): - """Format a string in bold by overstriking.""" - return ''.join(ch + '\b' + ch for ch in text) - - def indent(self, text, prefix=' '): - """Indent text by prepending a given prefix to each line.""" - if not text: return '' - lines = [prefix + line for line in text.split('\n')] - if lines: lines[-1] = lines[-1].rstrip() - return '\n'.join(lines) - - def section(self, title, contents): - """Format a section with a given heading.""" - clean_contents = self.indent(contents).rstrip() - return self.bold(title) + '\n' + clean_contents + '\n\n' - - # ---------------------------------------------- type-specific routines - - def formattree(self, tree, modname, parent=None, prefix=''): - """Render in text a class tree as returned by inspect.getclasstree().""" - result = '' - for entry in tree: - if type(entry) is type(()): - c, bases = entry - result = result + prefix + classname(c, modname) - if bases and bases != (parent,): - parents = (classname(c, modname) for c in bases) - result = result + '(%s)' % ', '.join(parents) - result = result + '\n' - elif type(entry) is type([]): - result = result + self.formattree( - entry, modname, c, prefix + ' ') - return result - - def docmodule(self, object, name=None, mod=None): - """Produce text documentation for a given module object.""" - name = object.__name__ # ignore the passed-in name - synop, desc = splitdoc(getdoc(object)) - result = self.section('NAME', name + (synop and ' - ' + synop)) - all = getattr(object, '__all__', None) - docloc = self.getdocloc(object) - if docloc is not None: - result = result + self.section('MODULE REFERENCE', docloc + """ - -The following documentation is automatically generated from the Python -source files. It may be incomplete, incorrect or include features that -are considered implementation detail and may vary between Python -implementations. When in doubt, consult the module reference at the -location listed above. -""") - - if desc: - result = result + self.section('DESCRIPTION', desc) - - classes = [] - for key, value in inspect.getmembers(object, inspect.isclass): - # if __all__ exists, believe it. Otherwise use old heuristic. - if (all is not None - or (inspect.getmodule(value) or object) is object): - if visiblename(key, all, object): - classes.append((key, value)) - funcs = [] - for key, value in inspect.getmembers(object, inspect.isroutine): - # if __all__ exists, believe it. Otherwise use old heuristic. - if (all is not None or - inspect.isbuiltin(value) or inspect.getmodule(value) is object): - if visiblename(key, all, object): - funcs.append((key, value)) - data = [] - for key, value in inspect.getmembers(object, isdata): - if visiblename(key, all, object): - data.append((key, value)) - - modpkgs = [] - modpkgs_names = set() - if hasattr(object, '__path__'): - for importer, modname, ispkg in pkgutil.iter_modules(object.__path__): - modpkgs_names.add(modname) - if ispkg: - modpkgs.append(modname + ' (package)') - else: - modpkgs.append(modname) - - modpkgs.sort() - result = result + self.section( - 'PACKAGE CONTENTS', '\n'.join(modpkgs)) - - # Detect submodules as sometimes created by C extensions - submodules = [] - for key, value in inspect.getmembers(object, inspect.ismodule): - if value.__name__.startswith(name + '.') and key not in modpkgs_names: - submodules.append(key) - if submodules: - submodules.sort() - result = result + self.section( - 'SUBMODULES', '\n'.join(submodules)) - - if classes: - classlist = [value for key, value in classes] - contents = [self.formattree( - inspect.getclasstree(classlist, 1), name)] - for key, value in classes: - contents.append(self.document(value, key, name)) - result = result + self.section('CLASSES', '\n'.join(contents)) - - if funcs: - contents = [] - for key, value in funcs: - contents.append(self.document(value, key, name)) - result = result + self.section('FUNCTIONS', '\n'.join(contents)) - - if data: - contents = [] - for key, value in data: - contents.append(self.docother(value, key, name, maxlen=70)) - result = result + self.section('DATA', '\n'.join(contents)) - - if hasattr(object, '__version__'): - version = str(object.__version__) - if version[:11] == '$' + 'Revision: ' and version[-1:] == '$': - version = version[11:-1].strip() - result = result + self.section('VERSION', version) - if hasattr(object, '__date__'): - result = result + self.section('DATE', str(object.__date__)) - if hasattr(object, '__author__'): - result = result + self.section('AUTHOR', str(object.__author__)) - if hasattr(object, '__credits__'): - result = result + self.section('CREDITS', str(object.__credits__)) - try: - file = inspect.getabsfile(object) - except TypeError: - file = '(built-in)' - result = result + self.section('FILE', file) - return result - - def docclass(self, object, name=None, mod=None, *ignored): - """Produce text documentation for a given class object.""" - realname = object.__name__ - name = name or realname - bases = object.__bases__ - - def makename(c, m=object.__module__): - return classname(c, m) - - if name == realname: - title = 'class ' + self.bold(realname) - else: - title = self.bold(name) + ' = class ' + realname - if bases: - parents = map(makename, bases) - title = title + '(%s)' % ', '.join(parents) - - contents = [] - push = contents.append - - try: - signature = inspect.signature(object) - except (ValueError, TypeError): - signature = None - if signature: - argspec = str(signature) - if argspec and argspec != '()': - push(name + argspec + '\n') - - doc = getdoc(object) - if doc: - push(doc + '\n') - - # List the mro, if non-trivial. - mro = deque(inspect.getmro(object)) - if len(mro) > 2: - push("Method resolution order:") - for base in mro: - push(' ' + makename(base)) - push('') - - # List the built-in subclasses, if any: - subclasses = sorted( - (str(cls.__name__) for cls in type.__subclasses__(object) - if not cls.__name__.startswith("_") and cls.__module__ == "builtins"), - key=str.lower - ) - no_of_subclasses = len(subclasses) - MAX_SUBCLASSES_TO_DISPLAY = 4 - if subclasses: - push("Built-in subclasses:") - for subclassname in subclasses[:MAX_SUBCLASSES_TO_DISPLAY]: - push(' ' + subclassname) - if no_of_subclasses > MAX_SUBCLASSES_TO_DISPLAY: - push(' ... and ' + - str(no_of_subclasses - MAX_SUBCLASSES_TO_DISPLAY) + - ' other subclasses') - push('') - - # Cute little class to pump out a horizontal rule between sections. - class HorizontalRule: - def __init__(self): - self.needone = 0 - def maybe(self): - if self.needone: - push('-' * 70) - self.needone = 1 - hr = HorizontalRule() - - def spill(msg, attrs, predicate): - ok, attrs = _split_list(attrs, predicate) - if ok: - hr.maybe() - push(msg) - for name, kind, homecls, value in ok: - try: - value = getattr(object, name) - except Exception: - # Some descriptors may meet a failure in their __get__. - # (bug #1785) - push(self.docdata(value, name, mod)) - else: - push(self.document(value, - name, mod, object)) - return attrs - - def spilldescriptors(msg, attrs, predicate): - ok, attrs = _split_list(attrs, predicate) - if ok: - hr.maybe() - push(msg) - for name, kind, homecls, value in ok: - push(self.docdata(value, name, mod)) - return attrs - - def spilldata(msg, attrs, predicate): - ok, attrs = _split_list(attrs, predicate) - if ok: - hr.maybe() - push(msg) - for name, kind, homecls, value in ok: - doc = getdoc(value) - try: - obj = getattr(object, name) - except AttributeError: - obj = homecls.__dict__[name] - push(self.docother(obj, name, mod, maxlen=70, doc=doc) + - '\n') - return attrs - - attrs = [(name, kind, cls, value) - for name, kind, cls, value in classify_class_attrs(object) - if visiblename(name, obj=object)] - - while attrs: - if mro: - thisclass = mro.popleft() - else: - thisclass = attrs[0][2] - attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) - - if object is not builtins.object and thisclass is builtins.object: - attrs = inherited - continue - elif thisclass is object: - tag = "defined here" - else: - tag = "inherited from %s" % classname(thisclass, - object.__module__) - - sort_attributes(attrs, object) - - # Pump out the attrs, segregated by kind. - attrs = spill("Methods %s:\n" % tag, attrs, - lambda t: t[1] == 'method') - attrs = spill("Class methods %s:\n" % tag, attrs, - lambda t: t[1] == 'class method') - attrs = spill("Static methods %s:\n" % tag, attrs, - lambda t: t[1] == 'static method') - attrs = spilldescriptors("Readonly properties %s:\n" % tag, attrs, - lambda t: t[1] == 'readonly property') - attrs = spilldescriptors("Data descriptors %s:\n" % tag, attrs, - lambda t: t[1] == 'data descriptor') - attrs = spilldata("Data and other attributes %s:\n" % tag, attrs, - lambda t: t[1] == 'data') - - assert attrs == [] - attrs = inherited - - contents = '\n'.join(contents) - if not contents: - return title + '\n' - return title + '\n' + self.indent(contents.rstrip(), ' | ') + '\n' - - def formatvalue(self, object): - """Format an argument default value as text.""" - return '=' + self.repr(object) - - def docroutine(self, object, name=None, mod=None, cl=None): - """Produce text documentation for a function or method object.""" - realname = object.__name__ - name = name or realname - note = '' - skipdocs = 0 - if _is_bound_method(object): - imclass = object.__self__.__class__ - if cl: - if imclass is not cl: - note = ' from ' + classname(imclass, mod) - else: - if object.__self__ is not None: - note = ' method of %s instance' % classname( - object.__self__.__class__, mod) - else: - note = ' unbound %s method' % classname(imclass,mod) - - if (inspect.iscoroutinefunction(object) or - inspect.isasyncgenfunction(object)): - asyncqualifier = 'async ' - else: - asyncqualifier = '' - - if name == realname: - title = self.bold(realname) - else: - if cl and inspect.getattr_static(cl, realname, []) is object: - skipdocs = 1 - title = self.bold(name) + ' = ' + realname - argspec = None - - if inspect.isroutine(object): - try: - signature = inspect.signature(object) - except (ValueError, TypeError): - signature = None - if signature: - argspec = str(signature) - if realname == '': - title = self.bold(name) + ' lambda ' - # XXX lambda's won't usually have func_annotations['return'] - # since the syntax doesn't support but it is possible. - # So removing parentheses isn't truly safe. - argspec = argspec[1:-1] # remove parentheses - if not argspec: - argspec = '(...)' - decl = asyncqualifier + title + argspec + note - - if skipdocs: - return decl + '\n' - else: - doc = getdoc(object) or '' - return decl + '\n' + (doc and self.indent(doc).rstrip() + '\n') - - def docdata(self, object, name=None, mod=None, cl=None): - """Produce text documentation for a data descriptor.""" - results = [] - push = results.append - - if name: - push(self.bold(name)) - push('\n') - doc = getdoc(object) or '' - if doc: - push(self.indent(doc)) - push('\n') - return ''.join(results) - - docproperty = docdata - - def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=None): - """Produce text documentation for a data object.""" - repr = self.repr(object) - if maxlen: - line = (name and name + ' = ' or '') + repr - chop = maxlen - len(line) - if chop < 0: repr = repr[:chop] + '...' - line = (name and self.bold(name) + ' = ' or '') + repr - if not doc: - doc = getdoc(object) - if doc: - line += '\n' + self.indent(str(doc)) + '\n' - return line - -class _PlainTextDoc(TextDoc): - """Subclass of TextDoc which overrides string styling""" - def bold(self, text): - return text - -# --------------------------------------------------------- user interfaces - -def pager(text): - """The first time this is called, determine what kind of pager to use.""" - global pager - pager = getpager() - pager(text) - -def getpager(): - """Decide what method to use for paging through text.""" - if not hasattr(sys.stdin, "isatty"): - return plainpager - if not hasattr(sys.stdout, "isatty"): - return plainpager - if not sys.stdin.isatty() or not sys.stdout.isatty(): - return plainpager - if sys.platform == "emscripten": - return plainpager - use_pager = os.environ.get('MANPAGER') or os.environ.get('PAGER') - if use_pager: - if sys.platform == 'win32': # pipes completely broken in Windows - return lambda text: tempfilepager(plain(text), use_pager) - elif os.environ.get('TERM') in ('dumb', 'emacs'): - return lambda text: pipepager(plain(text), use_pager) - else: - return lambda text: pipepager(text, use_pager) - if os.environ.get('TERM') in ('dumb', 'emacs'): - return plainpager - if sys.platform == 'win32': - return lambda text: tempfilepager(plain(text), 'more <') - if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0: - return lambda text: pipepager(text, 'less') - - import tempfile - (fd, filename) = tempfile.mkstemp() - os.close(fd) - try: - if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0: - return lambda text: pipepager(text, 'more') - else: - return ttypager - finally: - os.unlink(filename) - -def plain(text): - """Remove boldface formatting from text.""" - return re.sub('.\b', '', text) - -def pipepager(text, cmd): - """Page through text by feeding it to another program.""" - import subprocess - proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, - errors='backslashreplace') - try: - with proc.stdin as pipe: - try: - pipe.write(text) - except KeyboardInterrupt: - # We've hereby abandoned whatever text hasn't been written, - # but the pager is still in control of the terminal. - pass - except OSError: - pass # Ignore broken pipes caused by quitting the pager program. - while True: - try: - proc.wait() - break - except KeyboardInterrupt: - # Ignore ctl-c like the pager itself does. Otherwise the pager is - # left running and the terminal is in raw mode and unusable. - pass - -def tempfilepager(text, cmd): - """Page through text by invoking a program on a temporary file.""" - import tempfile - with tempfile.TemporaryDirectory() as tempdir: - filename = os.path.join(tempdir, 'pydoc.out') - with open(filename, 'w', errors='backslashreplace', - encoding=os.device_encoding(0) if - sys.platform == 'win32' else None - ) as file: - file.write(text) - os.system(cmd + ' "' + filename + '"') - -def _escape_stdout(text): - # Escape non-encodable characters to avoid encoding errors later - encoding = getattr(sys.stdout, 'encoding', None) or 'utf-8' - return text.encode(encoding, 'backslashreplace').decode(encoding) - -def ttypager(text): - """Page through text on a text terminal.""" - lines = plain(_escape_stdout(text)).split('\n') - try: - import tty - fd = sys.stdin.fileno() - old = tty.tcgetattr(fd) - tty.setcbreak(fd) - getchar = lambda: sys.stdin.read(1) - except (ImportError, AttributeError, io.UnsupportedOperation): - tty = None - getchar = lambda: sys.stdin.readline()[:-1][:1] - - try: - try: - h = int(os.environ.get('LINES', 0)) - except ValueError: - h = 0 - if h <= 1: - h = 25 - r = inc = h - 1 - sys.stdout.write('\n'.join(lines[:inc]) + '\n') - while lines[r:]: - sys.stdout.write('-- more --') - sys.stdout.flush() - c = getchar() - - if c in ('q', 'Q'): - sys.stdout.write('\r \r') - break - elif c in ('\r', '\n'): - sys.stdout.write('\r \r' + lines[r] + '\n') - r = r + 1 - continue - if c in ('b', 'B', '\x1b'): - r = r - inc - inc - if r < 0: r = 0 - sys.stdout.write('\n' + '\n'.join(lines[r:r+inc]) + '\n') - r = r + inc - - finally: - if tty: - tty.tcsetattr(fd, tty.TCSAFLUSH, old) - -def plainpager(text): - """Simply print unformatted text. This is the ultimate fallback.""" - sys.stdout.write(plain(_escape_stdout(text))) - -def describe(thing): - """Produce a short description of the given thing.""" - if inspect.ismodule(thing): - if thing.__name__ in sys.builtin_module_names: - return 'built-in module ' + thing.__name__ - if hasattr(thing, '__path__'): - return 'package ' + thing.__name__ - else: - return 'module ' + thing.__name__ - if inspect.isbuiltin(thing): - return 'built-in function ' + thing.__name__ - if inspect.isgetsetdescriptor(thing): - return 'getset descriptor %s.%s.%s' % ( - thing.__objclass__.__module__, thing.__objclass__.__name__, - thing.__name__) - if inspect.ismemberdescriptor(thing): - return 'member descriptor %s.%s.%s' % ( - thing.__objclass__.__module__, thing.__objclass__.__name__, - thing.__name__) - if inspect.isclass(thing): - return 'class ' + thing.__name__ - if inspect.isfunction(thing): - return 'function ' + thing.__name__ - if inspect.ismethod(thing): - return 'method ' + thing.__name__ - return type(thing).__name__ - -def locate(path, forceload=0): - """Locate an object by name or dotted path, importing as necessary.""" - parts = [part for part in path.split('.') if part] - module, n = None, 0 - while n < len(parts): - nextmodule = safeimport('.'.join(parts[:n+1]), forceload) - if nextmodule: module, n = nextmodule, n + 1 - else: break - if module: - object = module - else: - object = builtins - for part in parts[n:]: - try: - object = getattr(object, part) - except AttributeError: - return None - return object - -# --------------------------------------- interactive interpreter interface - -text = TextDoc() -plaintext = _PlainTextDoc() -html = HTMLDoc() - -def resolve(thing, forceload=0): - """Given an object or a path to an object, get the object and its name.""" - if isinstance(thing, str): - object = locate(thing, forceload) - if object is None: - raise ImportError('''\ -No Python documentation found for %r. -Use help() to get the interactive help utility. -Use help(str) for help on the str class.''' % thing) - return object, thing - else: - name = getattr(thing, '__name__', None) - return thing, name if isinstance(name, str) else None - -def render_doc(thing, title='Python Library Documentation: %s', forceload=0, - renderer=None): - """Render text documentation, given an object or a path to an object.""" - if renderer is None: - renderer = text - object, name = resolve(thing, forceload) - desc = describe(object) - module = inspect.getmodule(object) - if name and '.' in name: - desc += ' in ' + name[:name.rfind('.')] - elif module and module is not object: - desc += ' in module ' + module.__name__ - - if not (inspect.ismodule(object) or - inspect.isclass(object) or - inspect.isroutine(object) or - inspect.isdatadescriptor(object) or - _getdoc(object)): - # If the passed object is a piece of data or an instance, - # document its available methods instead of its value. - if hasattr(object, '__origin__'): - object = object.__origin__ - else: - object = type(object) - desc += ' object' - return title % desc + '\n\n' + renderer.document(object, name) - -def doc(thing, title='Python Library Documentation: %s', forceload=0, - output=None): - """Display text documentation, given an object or a path to an object.""" - if output is None: - pager(render_doc(thing, title, forceload)) - else: - output.write(render_doc(thing, title, forceload, plaintext)) - -def writedoc(thing, forceload=0): - """Write HTML documentation to a file in the current directory.""" - object, name = resolve(thing, forceload) - page = html.page(describe(object), html.document(object, name)) - with open(name + '.html', 'w', encoding='utf-8') as file: - file.write(page) - print('wrote', name + '.html') - -def writedocs(dir, pkgpath='', done=None): - """Write out HTML documentation for all modules in a directory tree.""" - if done is None: done = {} - for importer, modname, ispkg in pkgutil.walk_packages([dir], pkgpath): - writedoc(modname) - return - -class Helper: - - # These dictionaries map a topic name to either an alias, or a tuple - # (label, seealso-items). The "label" is the label of the corresponding - # section in the .rst file under Doc/ and an index into the dictionary - # in pydoc_data/topics.py. - # - # CAUTION: if you change one of these dictionaries, be sure to adapt the - # list of needed labels in Doc/tools/extensions/pyspecific.py and - # regenerate the pydoc_data/topics.py file by running - # make pydoc-topics - # in Doc/ and copying the output file into the Lib/ directory. - - keywords = { - 'False': '', - 'None': '', - 'True': '', - 'and': 'BOOLEAN', - 'as': 'with', - 'assert': ('assert', ''), - 'async': ('async', ''), - 'await': ('await', ''), - 'break': ('break', 'while for'), - 'class': ('class', 'CLASSES SPECIALMETHODS'), - 'continue': ('continue', 'while for'), - 'def': ('function', ''), - 'del': ('del', 'BASICMETHODS'), - 'elif': 'if', - 'else': ('else', 'while for'), - 'except': 'try', - 'finally': 'try', - 'for': ('for', 'break continue while'), - 'from': 'import', - 'global': ('global', 'nonlocal NAMESPACES'), - 'if': ('if', 'TRUTHVALUE'), - 'import': ('import', 'MODULES'), - 'in': ('in', 'SEQUENCEMETHODS'), - 'is': 'COMPARISON', - 'lambda': ('lambda', 'FUNCTIONS'), - 'nonlocal': ('nonlocal', 'global NAMESPACES'), - 'not': 'BOOLEAN', - 'or': 'BOOLEAN', - 'pass': ('pass', ''), - 'raise': ('raise', 'EXCEPTIONS'), - 'return': ('return', 'FUNCTIONS'), - 'try': ('try', 'EXCEPTIONS'), - 'while': ('while', 'break continue if TRUTHVALUE'), - 'with': ('with', 'CONTEXTMANAGERS EXCEPTIONS yield'), - 'yield': ('yield', ''), - } - # Either add symbols to this dictionary or to the symbols dictionary - # directly: Whichever is easier. They are merged later. - _strprefixes = [p + q for p in ('b', 'f', 'r', 'u') for q in ("'", '"')] - _symbols_inverse = { - 'STRINGS' : ("'", "'''", '"', '"""', *_strprefixes), - 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&', - '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'), - 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'), - 'UNARY' : ('-', '~'), - 'AUGMENTEDASSIGNMENT' : ('+=', '-=', '*=', '/=', '%=', '&=', '|=', - '^=', '<<=', '>>=', '**=', '//='), - 'BITWISE' : ('<<', '>>', '&', '|', '^', '~'), - 'COMPLEX' : ('j', 'J') - } - symbols = { - '%': 'OPERATORS FORMATTING', - '**': 'POWER', - ',': 'TUPLES LISTS FUNCTIONS', - '.': 'ATTRIBUTES FLOAT MODULES OBJECTS', - '...': 'ELLIPSIS', - ':': 'SLICINGS DICTIONARYLITERALS', - '@': 'def class', - '\\': 'STRINGS', - '_': 'PRIVATENAMES', - '__': 'PRIVATENAMES SPECIALMETHODS', - '`': 'BACKQUOTES', - '(': 'TUPLES FUNCTIONS CALLS', - ')': 'TUPLES FUNCTIONS CALLS', - '[': 'LISTS SUBSCRIPTS SLICINGS', - ']': 'LISTS SUBSCRIPTS SLICINGS' - } - for topic, symbols_ in _symbols_inverse.items(): - for symbol in symbols_: - topics = symbols.get(symbol, topic) - if topic not in topics: - topics = topics + ' ' + topic - symbols[symbol] = topics - del topic, symbols_, symbol, topics - - topics = { - 'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS ' - 'FUNCTIONS CLASSES MODULES FILES inspect'), - 'STRINGS': ('strings', 'str UNICODE SEQUENCES STRINGMETHODS ' - 'FORMATTING TYPES'), - 'STRINGMETHODS': ('string-methods', 'STRINGS FORMATTING'), - 'FORMATTING': ('formatstrings', 'OPERATORS'), - 'UNICODE': ('strings', 'encodings unicode SEQUENCES STRINGMETHODS ' - 'FORMATTING TYPES'), - 'NUMBERS': ('numbers', 'INTEGER FLOAT COMPLEX TYPES'), - 'INTEGER': ('integers', 'int range'), - 'FLOAT': ('floating', 'float math'), - 'COMPLEX': ('imaginary', 'complex cmath'), - 'SEQUENCES': ('typesseq', 'STRINGMETHODS FORMATTING range LISTS'), - 'MAPPINGS': 'DICTIONARIES', - 'FUNCTIONS': ('typesfunctions', 'def TYPES'), - 'METHODS': ('typesmethods', 'class def CLASSES TYPES'), - 'CODEOBJECTS': ('bltin-code-objects', 'compile FUNCTIONS TYPES'), - 'TYPEOBJECTS': ('bltin-type-objects', 'types TYPES'), - 'FRAMEOBJECTS': 'TYPES', - 'TRACEBACKS': 'TYPES', - 'NONE': ('bltin-null-object', ''), - 'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'), - 'SPECIALATTRIBUTES': ('specialattrs', ''), - 'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'), - 'MODULES': ('typesmodules', 'import'), - 'PACKAGES': 'import', - 'EXPRESSIONS': ('operator-summary', 'lambda or and not in is BOOLEAN ' - 'COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER ' - 'UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES ' - 'LISTS DICTIONARIES'), - 'OPERATORS': 'EXPRESSIONS', - 'PRECEDENCE': 'EXPRESSIONS', - 'OBJECTS': ('objects', 'TYPES'), - 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS ' - 'CALLABLEMETHODS SEQUENCEMETHODS MAPPINGMETHODS ' - 'NUMBERMETHODS CLASSES'), - 'BASICMETHODS': ('customization', 'hash repr str SPECIALMETHODS'), - 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'), - 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'), - 'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS ' - 'SPECIALMETHODS'), - 'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'), - 'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT ' - 'SPECIALMETHODS'), - 'EXECUTION': ('execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'), - 'NAMESPACES': ('naming', 'global nonlocal ASSIGNMENT DELETION DYNAMICFEATURES'), - 'DYNAMICFEATURES': ('dynamic-features', ''), - 'SCOPING': 'NAMESPACES', - 'FRAMES': 'NAMESPACES', - 'EXCEPTIONS': ('exceptions', 'try except finally raise'), - 'CONVERSIONS': ('conversions', ''), - 'IDENTIFIERS': ('identifiers', 'keywords SPECIALIDENTIFIERS'), - 'SPECIALIDENTIFIERS': ('id-classes', ''), - 'PRIVATENAMES': ('atom-identifiers', ''), - 'LITERALS': ('atom-literals', 'STRINGS NUMBERS TUPLELITERALS ' - 'LISTLITERALS DICTIONARYLITERALS'), - 'TUPLES': 'SEQUENCES', - 'TUPLELITERALS': ('exprlists', 'TUPLES LITERALS'), - 'LISTS': ('typesseq-mutable', 'LISTLITERALS'), - 'LISTLITERALS': ('lists', 'LISTS LITERALS'), - 'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'), - 'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'), - 'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr ATTRIBUTEMETHODS'), - 'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS'), - 'SLICINGS': ('slicings', 'SEQUENCEMETHODS'), - 'CALLS': ('calls', 'EXPRESSIONS'), - 'POWER': ('power', 'EXPRESSIONS'), - 'UNARY': ('unary', 'EXPRESSIONS'), - 'BINARY': ('binary', 'EXPRESSIONS'), - 'SHIFTING': ('shifting', 'EXPRESSIONS'), - 'BITWISE': ('bitwise', 'EXPRESSIONS'), - 'COMPARISON': ('comparisons', 'EXPRESSIONS BASICMETHODS'), - 'BOOLEAN': ('booleans', 'EXPRESSIONS TRUTHVALUE'), - 'ASSERTION': 'assert', - 'ASSIGNMENT': ('assignment', 'AUGMENTEDASSIGNMENT'), - 'AUGMENTEDASSIGNMENT': ('augassign', 'NUMBERMETHODS'), - 'DELETION': 'del', - 'RETURNING': 'return', - 'IMPORTING': 'import', - 'CONDITIONAL': 'if', - 'LOOPING': ('compound', 'for while break continue'), - 'TRUTHVALUE': ('truth', 'if while and or not BASICMETHODS'), - 'DEBUGGING': ('debugger', 'pdb'), - 'CONTEXTMANAGERS': ('context-managers', 'with'), - } - - def __init__(self, input=None, output=None): - self._input = input - self._output = output - - @property - def input(self): - return self._input or sys.stdin - - @property - def output(self): - return self._output or sys.stdout - - def __repr__(self): - if inspect.stack()[1][3] == '?': - self() - return '' - return '<%s.%s instance>' % (self.__class__.__module__, - self.__class__.__qualname__) - - _GoInteractive = object() - def __call__(self, request=_GoInteractive): - if request is not self._GoInteractive: - try: - self.help(request) - except ImportError as e: - self.output.write(f'{e}\n') - else: - self.intro() - self.interact() - self.output.write(''' -You are now leaving help and returning to the Python interpreter. -If you want to ask for help on a particular object directly from the -interpreter, you can type "help(object)". Executing "help('string')" -has the same effect as typing a particular string at the help> prompt. -''') - - def interact(self): - self.output.write('\n') - while True: - try: - request = self.getline('help> ') - if not request: break - except (KeyboardInterrupt, EOFError): - break - request = request.strip() - - # Make sure significant trailing quoting marks of literals don't - # get deleted while cleaning input - if (len(request) > 2 and request[0] == request[-1] in ("'", '"') - and request[0] not in request[1:-1]): - request = request[1:-1] - if request.lower() in ('q', 'quit'): break - if request == 'help': - self.intro() - else: - self.help(request) - - def getline(self, prompt): - """Read one line, using input() when appropriate.""" - if self.input is sys.stdin: - return input(prompt) - else: - self.output.write(prompt) - self.output.flush() - return self.input.readline() - - def help(self, request): - if type(request) is type(''): - request = request.strip() - if request == 'keywords': self.listkeywords() - elif request == 'symbols': self.listsymbols() - elif request == 'topics': self.listtopics() - elif request == 'modules': self.listmodules() - elif request[:8] == 'modules ': - self.listmodules(request.split()[1]) - elif request in self.symbols: self.showsymbol(request) - elif request in ['True', 'False', 'None']: - # special case these keywords since they are objects too - doc(eval(request), 'Help on %s:') - elif request in self.keywords: self.showtopic(request) - elif request in self.topics: self.showtopic(request) - elif request: doc(request, 'Help on %s:', output=self._output) - else: doc(str, 'Help on %s:', output=self._output) - elif isinstance(request, Helper): self() - else: doc(request, 'Help on %s:', output=self._output) - self.output.write('\n') - - def intro(self): - self.output.write(''' -Welcome to Python {0}'s help utility! - -If this is your first time using Python, you should definitely check out -the tutorial on the internet at https://docs.python.org/{0}/tutorial/. - -Enter the name of any module, keyword, or topic to get help on writing -Python programs and using Python modules. To quit this help utility and -return to the interpreter, just type "quit". - -To get a list of available modules, keywords, symbols, or topics, type -"modules", "keywords", "symbols", or "topics". Each module also comes -with a one-line summary of what it does; to list the modules whose name -or summary contain a given string such as "spam", type "modules spam". -'''.format('%d.%d' % sys.version_info[:2])) - - def list(self, items, columns=4, width=80): - items = list(sorted(items)) - colw = width // columns - rows = (len(items) + columns - 1) // columns - for row in range(rows): - for col in range(columns): - i = col * rows + row - if i < len(items): - self.output.write(items[i]) - if col < columns - 1: - self.output.write(' ' + ' ' * (colw - 1 - len(items[i]))) - self.output.write('\n') - - def listkeywords(self): - self.output.write(''' -Here is a list of the Python keywords. Enter any keyword to get more help. - -''') - self.list(self.keywords.keys()) - - def listsymbols(self): - self.output.write(''' -Here is a list of the punctuation symbols which Python assigns special meaning -to. Enter any symbol to get more help. - -''') - self.list(self.symbols.keys()) - - def listtopics(self): - self.output.write(''' -Here is a list of available topics. Enter any topic name to get more help. - -''') - self.list(self.topics.keys()) - - def showtopic(self, topic, more_xrefs=''): - try: - import pydoc_data.topics - except ImportError: - self.output.write(''' -Sorry, topic and keyword documentation is not available because the -module "pydoc_data.topics" could not be found. -''') - return - target = self.topics.get(topic, self.keywords.get(topic)) - if not target: - self.output.write('no documentation found for %s\n' % repr(topic)) - return - if type(target) is type(''): - return self.showtopic(target, more_xrefs) - - label, xrefs = target - try: - doc = pydoc_data.topics.topics[label] - except KeyError: - self.output.write('no documentation found for %s\n' % repr(topic)) - return - doc = doc.strip() + '\n' - if more_xrefs: - xrefs = (xrefs or '') + ' ' + more_xrefs - if xrefs: - import textwrap - text = 'Related help topics: ' + ', '.join(xrefs.split()) + '\n' - wrapped_text = textwrap.wrap(text, 72) - doc += '\n%s\n' % '\n'.join(wrapped_text) - pager(doc) - - def _gettopic(self, topic, more_xrefs=''): - """Return unbuffered tuple of (topic, xrefs). - - If an error occurs here, the exception is caught and displayed by - the url handler. - - This function duplicates the showtopic method but returns its - result directly so it can be formatted for display in an html page. - """ - try: - import pydoc_data.topics - except ImportError: - return(''' -Sorry, topic and keyword documentation is not available because the -module "pydoc_data.topics" could not be found. -''' , '') - target = self.topics.get(topic, self.keywords.get(topic)) - if not target: - raise ValueError('could not find topic') - if isinstance(target, str): - return self._gettopic(target, more_xrefs) - label, xrefs = target - doc = pydoc_data.topics.topics[label] - if more_xrefs: - xrefs = (xrefs or '') + ' ' + more_xrefs - return doc, xrefs - - def showsymbol(self, symbol): - target = self.symbols[symbol] - topic, _, xrefs = target.partition(' ') - self.showtopic(topic, xrefs) - - def listmodules(self, key=''): - if key: - self.output.write(''' -Here is a list of modules whose name or summary contains '{}'. -If there are any, enter a module name to get more help. - -'''.format(key)) - apropos(key) - else: - self.output.write(''' -Please wait a moment while I gather a list of all available modules... - -''') - modules = {} - def callback(path, modname, desc, modules=modules): - if modname and modname[-9:] == '.__init__': - modname = modname[:-9] + ' (package)' - if modname.find('.') < 0: - modules[modname] = 1 - def onerror(modname): - callback(None, modname, None) - ModuleScanner().run(callback, onerror=onerror) - self.list(modules.keys()) - self.output.write(''' -Enter any module name to get more help. Or, type "modules spam" to search -for modules whose name or summary contain the string "spam". -''') - -help = Helper() - -class ModuleScanner: - """An interruptible scanner that searches module synopses.""" - - def run(self, callback, key=None, completer=None, onerror=None): - if key: key = key.lower() - self.quit = False - seen = {} - - for modname in sys.builtin_module_names: - if modname != '__main__': - seen[modname] = 1 - if key is None: - callback(None, modname, '') - else: - name = __import__(modname).__doc__ or '' - desc = name.split('\n')[0] - name = modname + ' - ' + desc - if name.lower().find(key) >= 0: - callback(None, modname, desc) - - for importer, modname, ispkg in pkgutil.walk_packages(onerror=onerror): - if self.quit: - break - - if key is None: - callback(None, modname, '') - else: - try: - spec = pkgutil._get_spec(importer, modname) - except SyntaxError: - # raised by tests for bad coding cookies or BOM - continue - loader = spec.loader - if hasattr(loader, 'get_source'): - try: - source = loader.get_source(modname) - except Exception: - if onerror: - onerror(modname) - continue - desc = source_synopsis(io.StringIO(source)) or '' - if hasattr(loader, 'get_filename'): - path = loader.get_filename(modname) - else: - path = None - else: - try: - module = importlib._bootstrap._load(spec) - except ImportError: - if onerror: - onerror(modname) - continue - desc = module.__doc__.splitlines()[0] if module.__doc__ else '' - path = getattr(module,'__file__',None) - name = modname + ' - ' + desc - if name.lower().find(key) >= 0: - callback(path, modname, desc) - - if completer: - completer() - -def apropos(key): - """Print all the one-line module summaries that contain a substring.""" - def callback(path, modname, desc): - if modname[-9:] == '.__init__': - modname = modname[:-9] + ' (package)' - print(modname, desc and '- ' + desc) - def onerror(modname): - pass - with warnings.catch_warnings(): - warnings.filterwarnings('ignore') # ignore problems during import - ModuleScanner().run(callback, key, onerror=onerror) - -# --------------------------------------- enhanced web browser interface - -def _start_server(urlhandler, hostname, port): - """Start an HTTP server thread on a specific port. - - Start an HTML/text server thread, so HTML or text documents can be - browsed dynamically and interactively with a web browser. Example use: - - >>> import time - >>> import pydoc - - Define a URL handler. To determine what the client is asking - for, check the URL and content_type. - - Then get or generate some text or HTML code and return it. - - >>> def my_url_handler(url, content_type): - ... text = 'the URL sent was: (%s, %s)' % (url, content_type) - ... return text - - Start server thread on port 0. - If you use port 0, the server will pick a random port number. - You can then use serverthread.port to get the port number. - - >>> port = 0 - >>> serverthread = pydoc._start_server(my_url_handler, port) - - Check that the server is really started. If it is, open browser - and get first page. Use serverthread.url as the starting page. - - >>> if serverthread.serving: - ... import webbrowser - - The next two lines are commented out so a browser doesn't open if - doctest is run on this module. - - #... webbrowser.open(serverthread.url) - #True - - Let the server do its thing. We just need to monitor its status. - Use time.sleep so the loop doesn't hog the CPU. - - >>> starttime = time.monotonic() - >>> timeout = 1 #seconds - - This is a short timeout for testing purposes. - - >>> while serverthread.serving: - ... time.sleep(.01) - ... if serverthread.serving and time.monotonic() - starttime > timeout: - ... serverthread.stop() - ... break - - Print any errors that may have occurred. - - >>> print(serverthread.error) - None - """ - import http.server - import email.message - import select - import threading - - class DocHandler(http.server.BaseHTTPRequestHandler): - - def do_GET(self): - """Process a request from an HTML browser. - - The URL received is in self.path. - Get an HTML page from self.urlhandler and send it. - """ - if self.path.endswith('.css'): - content_type = 'text/css' - else: - content_type = 'text/html' - self.send_response(200) - self.send_header('Content-Type', '%s; charset=UTF-8' % content_type) - self.end_headers() - self.wfile.write(self.urlhandler( - self.path, content_type).encode('utf-8')) - - def log_message(self, *args): - # Don't log messages. - pass - - class DocServer(http.server.HTTPServer): - - def __init__(self, host, port, callback): - self.host = host - self.address = (self.host, port) - self.callback = callback - self.base.__init__(self, self.address, self.handler) - self.quit = False - - def serve_until_quit(self): - while not self.quit: - rd, wr, ex = select.select([self.socket.fileno()], [], [], 1) - if rd: - self.handle_request() - self.server_close() - - def server_activate(self): - self.base.server_activate(self) - if self.callback: - self.callback(self) - - class ServerThread(threading.Thread): - - def __init__(self, urlhandler, host, port): - self.urlhandler = urlhandler - self.host = host - self.port = int(port) - threading.Thread.__init__(self) - self.serving = False - self.error = None - - def run(self): - """Start the server.""" - try: - DocServer.base = http.server.HTTPServer - DocServer.handler = DocHandler - DocHandler.MessageClass = email.message.Message - DocHandler.urlhandler = staticmethod(self.urlhandler) - docsvr = DocServer(self.host, self.port, self.ready) - self.docserver = docsvr - docsvr.serve_until_quit() - except Exception as e: - self.error = e - - def ready(self, server): - self.serving = True - self.host = server.host - self.port = server.server_port - self.url = 'http://%s:%d/' % (self.host, self.port) - - def stop(self): - """Stop the server and this thread nicely""" - self.docserver.quit = True - self.join() - # explicitly break a reference cycle: DocServer.callback - # has indirectly a reference to ServerThread. - self.docserver = None - self.serving = False - self.url = None - - thread = ServerThread(urlhandler, hostname, port) - thread.start() - # Wait until thread.serving is True to make sure we are - # really up before returning. - while not thread.error and not thread.serving: - time.sleep(.01) - return thread - - -def _url_handler(url, content_type="text/html"): - """The pydoc url handler for use with the pydoc server. - - If the content_type is 'text/css', the _pydoc.css style - sheet is read and returned if it exits. - - If the content_type is 'text/html', then the result of - get_html_page(url) is returned. - """ - class _HTMLDoc(HTMLDoc): - - def page(self, title, contents): - """Format an HTML page.""" - css_path = "pydoc_data/_pydoc.css" - css_link = ( - '' % - css_path) - return '''\ - - - - -Pydoc: %s -%s%s
    %s
    -''' % (title, css_link, html_navbar(), contents) - - - html = _HTMLDoc() - - def html_navbar(): - version = html.escape("%s [%s, %s]" % (platform.python_version(), - platform.python_build()[0], - platform.python_compiler())) - return """ -
    - Python %s
    %s -
    -
    - -
    -
    - - -
      -
    - - -
    -
    -
    - """ % (version, html.escape(platform.platform(terse=True))) - - def html_index(): - """Module Index page.""" - - def bltinlink(name): - return '%s' % (name, name) - - heading = html.heading( - 'Index of Modules' - ) - names = [name for name in sys.builtin_module_names - if name != '__main__'] - contents = html.multicolumn(names, bltinlink) - contents = [heading, '

    ' + html.bigsection( - 'Built-in Modules', 'index', contents)] - - seen = {} - for dir in sys.path: - contents.append(html.index(dir, seen)) - - contents.append( - '

    pydoc by Ka-Ping Yee' - '<ping@lfw.org>

    ') - return 'Index of Modules', ''.join(contents) - - def html_search(key): - """Search results page.""" - # scan for modules - search_result = [] - - def callback(path, modname, desc): - if modname[-9:] == '.__init__': - modname = modname[:-9] + ' (package)' - search_result.append((modname, desc and '- ' + desc)) - - with warnings.catch_warnings(): - warnings.filterwarnings('ignore') # ignore problems during import - def onerror(modname): - pass - ModuleScanner().run(callback, key, onerror=onerror) - - # format page - def bltinlink(name): - return '%s' % (name, name) - - results = [] - heading = html.heading( - 'Search Results', - ) - for name, desc in search_result: - results.append(bltinlink(name) + desc) - contents = heading + html.bigsection( - 'key = %s' % key, 'index', '
    '.join(results)) - return 'Search Results', contents - - def html_topics(): - """Index of topic texts available.""" - - def bltinlink(name): - return '%s' % (name, name) - - heading = html.heading( - 'INDEX', - ) - names = sorted(Helper.topics.keys()) - - contents = html.multicolumn(names, bltinlink) - contents = heading + html.bigsection( - 'Topics', 'index', contents) - return 'Topics', contents - - def html_keywords(): - """Index of keywords.""" - heading = html.heading( - 'INDEX', - ) - names = sorted(Helper.keywords.keys()) - - def bltinlink(name): - return '%s' % (name, name) - - contents = html.multicolumn(names, bltinlink) - contents = heading + html.bigsection( - 'Keywords', 'index', contents) - return 'Keywords', contents - - def html_topicpage(topic): - """Topic or keyword help page.""" - buf = io.StringIO() - htmlhelp = Helper(buf, buf) - contents, xrefs = htmlhelp._gettopic(topic) - if topic in htmlhelp.keywords: - title = 'KEYWORD' - else: - title = 'TOPIC' - heading = html.heading( - '%s' % title, - ) - contents = '
    %s
    ' % html.markup(contents) - contents = html.bigsection(topic , 'index', contents) - if xrefs: - xrefs = sorted(xrefs.split()) - - def bltinlink(name): - return '%s' % (name, name) - - xrefs = html.multicolumn(xrefs, bltinlink) - xrefs = html.section('Related help topics: ', 'index', xrefs) - return ('%s %s' % (title, topic), - ''.join((heading, contents, xrefs))) - - def html_getobj(url): - obj = locate(url, forceload=1) - if obj is None and url != 'None': - raise ValueError('could not find object') - title = describe(obj) - content = html.document(obj, url) - return title, content - - def html_error(url, exc): - heading = html.heading( - 'Error', - ) - contents = '
    '.join(html.escape(line) for line in - format_exception_only(type(exc), exc)) - contents = heading + html.bigsection(url, 'error', contents) - return "Error - %s" % url, contents - - def get_html_page(url): - """Generate an HTML page for url.""" - complete_url = url - if url.endswith('.html'): - url = url[:-5] - try: - if url in ("", "index"): - title, content = html_index() - elif url == "topics": - title, content = html_topics() - elif url == "keywords": - title, content = html_keywords() - elif '=' in url: - op, _, url = url.partition('=') - if op == "search?key": - title, content = html_search(url) - elif op == "topic?key": - # try topics first, then objects. - try: - title, content = html_topicpage(url) - except ValueError: - title, content = html_getobj(url) - elif op == "get?key": - # try objects first, then topics. - if url in ("", "index"): - title, content = html_index() - else: - try: - title, content = html_getobj(url) - except ValueError: - title, content = html_topicpage(url) - else: - raise ValueError('bad pydoc url') - else: - title, content = html_getobj(url) - except Exception as exc: - # Catch any errors and display them in an error page. - title, content = html_error(complete_url, exc) - return html.page(title, content) - - if url.startswith('/'): - url = url[1:] - if content_type == 'text/css': - path_here = os.path.dirname(os.path.realpath(__file__)) - css_path = os.path.join(path_here, url) - with open(css_path) as fp: - return ''.join(fp.readlines()) - elif content_type == 'text/html': - return get_html_page(url) - # Errors outside the url handler are caught by the server. - raise TypeError('unknown content type %r for url %s' % (content_type, url)) - - -def browse(port=0, *, open_browser=True, hostname='localhost'): - """Start the enhanced pydoc web server and open a web browser. - - Use port '0' to start the server on an arbitrary port. - Set open_browser to False to suppress opening a browser. - """ - import webbrowser - serverthread = _start_server(_url_handler, hostname, port) - if serverthread.error: - print(serverthread.error) - return - if serverthread.serving: - server_help_msg = 'Server commands: [b]rowser, [q]uit' - if open_browser: - webbrowser.open(serverthread.url) - try: - print('Server ready at', serverthread.url) - print(server_help_msg) - while serverthread.serving: - cmd = input('server> ') - cmd = cmd.lower() - if cmd == 'q': - break - elif cmd == 'b': - webbrowser.open(serverthread.url) - else: - print(server_help_msg) - except (KeyboardInterrupt, EOFError): - print() - finally: - if serverthread.serving: - serverthread.stop() - print('Server stopped') - - -# -------------------------------------------------- command-line interface - -def ispath(x): - return isinstance(x, str) and x.find(os.sep) >= 0 - -def _get_revised_path(given_path, argv0): - """Ensures current directory is on returned path, and argv0 directory is not - - Exception: argv0 dir is left alone if it's also pydoc's directory. - - Returns a new path entry list, or None if no adjustment is needed. - """ - # Scripts may get the current directory in their path by default if they're - # run with the -m switch, or directly from the current directory. - # The interactive prompt also allows imports from the current directory. - - # Accordingly, if the current directory is already present, don't make - # any changes to the given_path - if '' in given_path or os.curdir in given_path or os.getcwd() in given_path: - return None - - # Otherwise, add the current directory to the given path, and remove the - # script directory (as long as the latter isn't also pydoc's directory. - stdlib_dir = os.path.dirname(__file__) - script_dir = os.path.dirname(argv0) - revised_path = given_path.copy() - if script_dir in given_path and not os.path.samefile(script_dir, stdlib_dir): - revised_path.remove(script_dir) - revised_path.insert(0, os.getcwd()) - return revised_path - - -# Note: the tests only cover _get_revised_path, not _adjust_cli_path itself -def _adjust_cli_sys_path(): - """Ensures current directory is on sys.path, and __main__ directory is not. - - Exception: __main__ dir is left alone if it's also pydoc's directory. - """ - revised_path = _get_revised_path(sys.path, sys.argv[0]) - if revised_path is not None: - sys.path[:] = revised_path - - -def cli(): - """Command-line interface (looks at sys.argv to decide what to do).""" - import getopt - class BadUsage(Exception): pass - - _adjust_cli_sys_path() - - try: - opts, args = getopt.getopt(sys.argv[1:], 'bk:n:p:w') - writing = False - start_server = False - open_browser = False - port = 0 - hostname = 'localhost' - for opt, val in opts: - if opt == '-b': - start_server = True - open_browser = True - if opt == '-k': - apropos(val) - return - if opt == '-p': - start_server = True - port = val - if opt == '-w': - writing = True - if opt == '-n': - start_server = True - hostname = val - - if start_server: - browse(port, hostname=hostname, open_browser=open_browser) - return - - if not args: raise BadUsage - for arg in args: - if ispath(arg) and not os.path.exists(arg): - print('file %r does not exist' % arg) - sys.exit(1) - try: - if ispath(arg) and os.path.isfile(arg): - arg = importfile(arg) - if writing: - if ispath(arg) and os.path.isdir(arg): - writedocs(arg) - else: - writedoc(arg) - else: - help.help(arg) - except (ImportError, ErrorDuringImport) as value: - print(value) - sys.exit(1) - - except (getopt.error, BadUsage): - cmd = os.path.splitext(os.path.basename(sys.argv[0]))[0] - print("""pydoc - the Python documentation tool - -{cmd} ... - Show text documentation on something. may be the name of a - Python keyword, topic, function, module, or package, or a dotted - reference to a class or function within a module or module in a - package. If contains a '{sep}', it is used as the path to a - Python source file to document. If name is 'keywords', 'topics', - or 'modules', a listing of these things is displayed. - -{cmd} -k - Search for a keyword in the synopsis lines of all available modules. - -{cmd} -n - Start an HTTP server with the given hostname (default: localhost). - -{cmd} -p - Start an HTTP server on the given port on the local machine. Port - number 0 can be used to get an arbitrary unused port. - -{cmd} -b - Start an HTTP server on an arbitrary unused port and open a web browser - to interactively browse documentation. This option can be used in - combination with -n and/or -p. - -{cmd} -w ... - Write out the HTML documentation for a module to a file in the current - directory. If contains a '{sep}', it is treated as a filename; if - it names a directory, documentation is written for all the contents. -""".format(cmd=cmd, sep=os.sep)) - -if __name__ == '__main__': - cli() diff --git a/python/Lib/queue.py b/python/Lib/queue.py deleted file mode 100644 index 7e8178f..0000000 --- a/python/Lib/queue.py +++ /dev/null @@ -1,326 +0,0 @@ -'''A multi-producer, multi-consumer queue.''' - -import threading -import types -from collections import deque -from heapq import heappush, heappop -from time import monotonic as time -try: - from _queue import SimpleQueue -except ImportError: - SimpleQueue = None - -__all__ = ['Empty', 'Full', 'Queue', 'PriorityQueue', 'LifoQueue', 'SimpleQueue'] - - -try: - from _queue import Empty -except ImportError: - class Empty(Exception): - 'Exception raised by Queue.get(block=0)/get_nowait().' - pass - -class Full(Exception): - 'Exception raised by Queue.put(block=0)/put_nowait().' - pass - - -class Queue: - '''Create a queue object with a given maximum size. - - If maxsize is <= 0, the queue size is infinite. - ''' - - def __init__(self, maxsize=0): - self.maxsize = maxsize - self._init(maxsize) - - # mutex must be held whenever the queue is mutating. All methods - # that acquire mutex must release it before returning. mutex - # is shared between the three conditions, so acquiring and - # releasing the conditions also acquires and releases mutex. - self.mutex = threading.Lock() - - # Notify not_empty whenever an item is added to the queue; a - # thread waiting to get is notified then. - self.not_empty = threading.Condition(self.mutex) - - # Notify not_full whenever an item is removed from the queue; - # a thread waiting to put is notified then. - self.not_full = threading.Condition(self.mutex) - - # Notify all_tasks_done whenever the number of unfinished tasks - # drops to zero; thread waiting to join() is notified to resume - self.all_tasks_done = threading.Condition(self.mutex) - self.unfinished_tasks = 0 - - def task_done(self): - '''Indicate that a formerly enqueued task is complete. - - Used by Queue consumer threads. For each get() used to fetch a task, - a subsequent call to task_done() tells the queue that the processing - on the task is complete. - - If a join() is currently blocking, it will resume when all items - have been processed (meaning that a task_done() call was received - for every item that had been put() into the queue). - - Raises a ValueError if called more times than there were items - placed in the queue. - ''' - with self.all_tasks_done: - unfinished = self.unfinished_tasks - 1 - if unfinished <= 0: - if unfinished < 0: - raise ValueError('task_done() called too many times') - self.all_tasks_done.notify_all() - self.unfinished_tasks = unfinished - - def join(self): - '''Blocks until all items in the Queue have been gotten and processed. - - The count of unfinished tasks goes up whenever an item is added to the - queue. The count goes down whenever a consumer thread calls task_done() - to indicate the item was retrieved and all work on it is complete. - - When the count of unfinished tasks drops to zero, join() unblocks. - ''' - with self.all_tasks_done: - while self.unfinished_tasks: - self.all_tasks_done.wait() - - def qsize(self): - '''Return the approximate size of the queue (not reliable!).''' - with self.mutex: - return self._qsize() - - def empty(self): - '''Return True if the queue is empty, False otherwise (not reliable!). - - This method is likely to be removed at some point. Use qsize() == 0 - as a direct substitute, but be aware that either approach risks a race - condition where a queue can grow before the result of empty() or - qsize() can be used. - - To create code that needs to wait for all queued tasks to be - completed, the preferred technique is to use the join() method. - ''' - with self.mutex: - return not self._qsize() - - def full(self): - '''Return True if the queue is full, False otherwise (not reliable!). - - This method is likely to be removed at some point. Use qsize() >= n - as a direct substitute, but be aware that either approach risks a race - condition where a queue can shrink before the result of full() or - qsize() can be used. - ''' - with self.mutex: - return 0 < self.maxsize <= self._qsize() - - def put(self, item, block=True, timeout=None): - '''Put an item into the queue. - - If optional args 'block' is true and 'timeout' is None (the default), - block if necessary until a free slot is available. If 'timeout' is - a non-negative number, it blocks at most 'timeout' seconds and raises - the Full exception if no free slot was available within that time. - Otherwise ('block' is false), put an item on the queue if a free slot - is immediately available, else raise the Full exception ('timeout' - is ignored in that case). - ''' - with self.not_full: - if self.maxsize > 0: - if not block: - if self._qsize() >= self.maxsize: - raise Full - elif timeout is None: - while self._qsize() >= self.maxsize: - self.not_full.wait() - elif timeout < 0: - raise ValueError("'timeout' must be a non-negative number") - else: - endtime = time() + timeout - while self._qsize() >= self.maxsize: - remaining = endtime - time() - if remaining <= 0.0: - raise Full - self.not_full.wait(remaining) - self._put(item) - self.unfinished_tasks += 1 - self.not_empty.notify() - - def get(self, block=True, timeout=None): - '''Remove and return an item from the queue. - - If optional args 'block' is true and 'timeout' is None (the default), - block if necessary until an item is available. If 'timeout' is - a non-negative number, it blocks at most 'timeout' seconds and raises - the Empty exception if no item was available within that time. - Otherwise ('block' is false), return an item if one is immediately - available, else raise the Empty exception ('timeout' is ignored - in that case). - ''' - with self.not_empty: - if not block: - if not self._qsize(): - raise Empty - elif timeout is None: - while not self._qsize(): - self.not_empty.wait() - elif timeout < 0: - raise ValueError("'timeout' must be a non-negative number") - else: - endtime = time() + timeout - while not self._qsize(): - remaining = endtime - time() - if remaining <= 0.0: - raise Empty - self.not_empty.wait(remaining) - item = self._get() - self.not_full.notify() - return item - - def put_nowait(self, item): - '''Put an item into the queue without blocking. - - Only enqueue the item if a free slot is immediately available. - Otherwise raise the Full exception. - ''' - return self.put(item, block=False) - - def get_nowait(self): - '''Remove and return an item from the queue without blocking. - - Only get an item if one is immediately available. Otherwise - raise the Empty exception. - ''' - return self.get(block=False) - - # Override these methods to implement other queue organizations - # (e.g. stack or priority queue). - # These will only be called with appropriate locks held - - # Initialize the queue representation - def _init(self, maxsize): - self.queue = deque() - - def _qsize(self): - return len(self.queue) - - # Put a new item in the queue - def _put(self, item): - self.queue.append(item) - - # Get an item from the queue - def _get(self): - return self.queue.popleft() - - __class_getitem__ = classmethod(types.GenericAlias) - - -class PriorityQueue(Queue): - '''Variant of Queue that retrieves open entries in priority order (lowest first). - - Entries are typically tuples of the form: (priority number, data). - ''' - - def _init(self, maxsize): - self.queue = [] - - def _qsize(self): - return len(self.queue) - - def _put(self, item): - heappush(self.queue, item) - - def _get(self): - return heappop(self.queue) - - -class LifoQueue(Queue): - '''Variant of Queue that retrieves most recently added entries first.''' - - def _init(self, maxsize): - self.queue = [] - - def _qsize(self): - return len(self.queue) - - def _put(self, item): - self.queue.append(item) - - def _get(self): - return self.queue.pop() - - -class _PySimpleQueue: - '''Simple, unbounded FIFO queue. - - This pure Python implementation is not reentrant. - ''' - # Note: while this pure Python version provides fairness - # (by using a threading.Semaphore which is itself fair, being based - # on threading.Condition), fairness is not part of the API contract. - # This allows the C version to use a different implementation. - - def __init__(self): - self._queue = deque() - self._count = threading.Semaphore(0) - - def put(self, item, block=True, timeout=None): - '''Put the item on the queue. - - The optional 'block' and 'timeout' arguments are ignored, as this method - never blocks. They are provided for compatibility with the Queue class. - ''' - self._queue.append(item) - self._count.release() - - def get(self, block=True, timeout=None): - '''Remove and return an item from the queue. - - If optional args 'block' is true and 'timeout' is None (the default), - block if necessary until an item is available. If 'timeout' is - a non-negative number, it blocks at most 'timeout' seconds and raises - the Empty exception if no item was available within that time. - Otherwise ('block' is false), return an item if one is immediately - available, else raise the Empty exception ('timeout' is ignored - in that case). - ''' - if timeout is not None and timeout < 0: - raise ValueError("'timeout' must be a non-negative number") - if not self._count.acquire(block, timeout): - raise Empty - return self._queue.popleft() - - def put_nowait(self, item): - '''Put an item into the queue without blocking. - - This is exactly equivalent to `put(item, block=False)` and is only provided - for compatibility with the Queue class. - ''' - return self.put(item, block=False) - - def get_nowait(self): - '''Remove and return an item from the queue without blocking. - - Only get an item if one is immediately available. Otherwise - raise the Empty exception. - ''' - return self.get(block=False) - - def empty(self): - '''Return True if the queue is empty, False otherwise (not reliable!).''' - return len(self._queue) == 0 - - def qsize(self): - '''Return the approximate size of the queue (not reliable!).''' - return len(self._queue) - - __class_getitem__ = classmethod(types.GenericAlias) - - -if SimpleQueue is None: - SimpleQueue = _PySimpleQueue diff --git a/python/Lib/quopri.py b/python/Lib/quopri.py deleted file mode 100644 index caf7a98..0000000 --- a/python/Lib/quopri.py +++ /dev/null @@ -1,242 +0,0 @@ -#! /usr/bin/env python3 - -"""Conversions to/from quoted-printable transport encoding as per RFC 1521.""" - -# (Dec 1991 version). - -__all__ = ["encode", "decode", "encodestring", "decodestring"] - -ESCAPE = b'=' -MAXLINESIZE = 76 -HEX = b'0123456789ABCDEF' -EMPTYSTRING = b'' - -try: - from binascii import a2b_qp, b2a_qp -except ImportError: - a2b_qp = None - b2a_qp = None - - -def needsquoting(c, quotetabs, header): - """Decide whether a particular byte ordinal needs to be quoted. - - The 'quotetabs' flag indicates whether embedded tabs and spaces should be - quoted. Note that line-ending tabs and spaces are always encoded, as per - RFC 1521. - """ - assert isinstance(c, bytes) - if c in b' \t': - return quotetabs - # if header, we have to escape _ because _ is used to escape space - if c == b'_': - return header - return c == ESCAPE or not (b' ' <= c <= b'~') - -def quote(c): - """Quote a single character.""" - assert isinstance(c, bytes) and len(c)==1 - c = ord(c) - return ESCAPE + bytes((HEX[c//16], HEX[c%16])) - - - -def encode(input, output, quotetabs, header=False): - """Read 'input', apply quoted-printable encoding, and write to 'output'. - - 'input' and 'output' are binary file objects. The 'quotetabs' flag - indicates whether embedded tabs and spaces should be quoted. Note that - line-ending tabs and spaces are always encoded, as per RFC 1521. - The 'header' flag indicates whether we are encoding spaces as _ as per RFC - 1522.""" - - if b2a_qp is not None: - data = input.read() - odata = b2a_qp(data, quotetabs=quotetabs, header=header) - output.write(odata) - return - - def write(s, output=output, lineEnd=b'\n'): - # RFC 1521 requires that the line ending in a space or tab must have - # that trailing character encoded. - if s and s[-1:] in b' \t': - output.write(s[:-1] + quote(s[-1:]) + lineEnd) - elif s == b'.': - output.write(quote(s) + lineEnd) - else: - output.write(s + lineEnd) - - prevline = None - while 1: - line = input.readline() - if not line: - break - outline = [] - # Strip off any readline induced trailing newline - stripped = b'' - if line[-1:] == b'\n': - line = line[:-1] - stripped = b'\n' - # Calculate the un-length-limited encoded line - for c in line: - c = bytes((c,)) - if needsquoting(c, quotetabs, header): - c = quote(c) - if header and c == b' ': - outline.append(b'_') - else: - outline.append(c) - # First, write out the previous line - if prevline is not None: - write(prevline) - # Now see if we need any soft line breaks because of RFC-imposed - # length limitations. Then do the thisline->prevline dance. - thisline = EMPTYSTRING.join(outline) - while len(thisline) > MAXLINESIZE: - # Don't forget to include the soft line break `=' sign in the - # length calculation! - write(thisline[:MAXLINESIZE-1], lineEnd=b'=\n') - thisline = thisline[MAXLINESIZE-1:] - # Write out the current line - prevline = thisline - # Write out the last line, without a trailing newline - if prevline is not None: - write(prevline, lineEnd=stripped) - -def encodestring(s, quotetabs=False, header=False): - if b2a_qp is not None: - return b2a_qp(s, quotetabs=quotetabs, header=header) - from io import BytesIO - infp = BytesIO(s) - outfp = BytesIO() - encode(infp, outfp, quotetabs, header) - return outfp.getvalue() - - - -def decode(input, output, header=False): - """Read 'input', apply quoted-printable decoding, and write to 'output'. - 'input' and 'output' are binary file objects. - If 'header' is true, decode underscore as space (per RFC 1522).""" - - if a2b_qp is not None: - data = input.read() - odata = a2b_qp(data, header=header) - output.write(odata) - return - - new = b'' - while 1: - line = input.readline() - if not line: break - i, n = 0, len(line) - if n > 0 and line[n-1:n] == b'\n': - partial = 0; n = n-1 - # Strip trailing whitespace - while n > 0 and line[n-1:n] in b" \t\r": - n = n-1 - else: - partial = 1 - while i < n: - c = line[i:i+1] - if c == b'_' and header: - new = new + b' '; i = i+1 - elif c != ESCAPE: - new = new + c; i = i+1 - elif i+1 == n and not partial: - partial = 1; break - elif i+1 < n and line[i+1:i+2] == ESCAPE: - new = new + ESCAPE; i = i+2 - elif i+2 < n and ishex(line[i+1:i+2]) and ishex(line[i+2:i+3]): - new = new + bytes((unhex(line[i+1:i+3]),)); i = i+3 - else: # Bad escape sequence -- leave it in - new = new + c; i = i+1 - if not partial: - output.write(new + b'\n') - new = b'' - if new: - output.write(new) - -def decodestring(s, header=False): - if a2b_qp is not None: - return a2b_qp(s, header=header) - from io import BytesIO - infp = BytesIO(s) - outfp = BytesIO() - decode(infp, outfp, header=header) - return outfp.getvalue() - - - -# Other helper functions -def ishex(c): - """Return true if the byte ordinal 'c' is a hexadecimal digit in ASCII.""" - assert isinstance(c, bytes) - return b'0' <= c <= b'9' or b'a' <= c <= b'f' or b'A' <= c <= b'F' - -def unhex(s): - """Get the integer value of a hexadecimal number.""" - bits = 0 - for c in s: - c = bytes((c,)) - if b'0' <= c <= b'9': - i = ord('0') - elif b'a' <= c <= b'f': - i = ord('a')-10 - elif b'A' <= c <= b'F': - i = ord(b'A')-10 - else: - assert False, "non-hex digit "+repr(c) - bits = bits*16 + (ord(c) - i) - return bits - - - -def main(): - import sys - import getopt - try: - opts, args = getopt.getopt(sys.argv[1:], 'td') - except getopt.error as msg: - sys.stdout = sys.stderr - print(msg) - print("usage: quopri [-t | -d] [file] ...") - print("-t: quote tabs") - print("-d: decode; default encode") - sys.exit(2) - deco = False - tabs = False - for o, a in opts: - if o == '-t': tabs = True - if o == '-d': deco = True - if tabs and deco: - sys.stdout = sys.stderr - print("-t and -d are mutually exclusive") - sys.exit(2) - if not args: args = ['-'] - sts = 0 - for file in args: - if file == '-': - fp = sys.stdin.buffer - else: - try: - fp = open(file, "rb") - except OSError as msg: - sys.stderr.write("%s: can't open (%s)\n" % (file, msg)) - sts = 1 - continue - try: - if deco: - decode(fp, sys.stdout.buffer) - else: - encode(fp, sys.stdout.buffer, tabs) - finally: - if file != '-': - fp.close() - if sts: - sys.exit(sts) - - - -if __name__ == '__main__': - main() diff --git a/python/Lib/random.py b/python/Lib/random.py deleted file mode 100644 index f14a2a8..0000000 --- a/python/Lib/random.py +++ /dev/null @@ -1,901 +0,0 @@ -"""Random variable generators. - - bytes - ----- - uniform bytes (values between 0 and 255) - - integers - -------- - uniform within range - - sequences - --------- - pick random element - pick random sample - pick weighted random sample - generate random permutation - - distributions on the real line: - ------------------------------ - uniform - triangular - normal (Gaussian) - lognormal - negative exponential - gamma - beta - pareto - Weibull - - distributions on the circle (angles 0 to 2pi) - --------------------------------------------- - circular uniform - von Mises - -General notes on the underlying Mersenne Twister core generator: - -* The period is 2**19937-1. -* It is one of the most extensively tested generators in existence. -* The random() method is implemented in C, executes in a single Python step, - and is, therefore, threadsafe. - -""" - -# Translated by Guido van Rossum from C source provided by -# Adrian Baddeley. Adapted by Raymond Hettinger for use with -# the Mersenne Twister and os.urandom() core generators. - -from warnings import warn as _warn -from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil -from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin -from math import tau as TWOPI, floor as _floor, isfinite as _isfinite -from os import urandom as _urandom -from _collections_abc import Set as _Set, Sequence as _Sequence -from operator import index as _index -from itertools import accumulate as _accumulate, repeat as _repeat -from bisect import bisect as _bisect -import os as _os -import _random - -try: - # hashlib is pretty heavy to load, try lean internal module first - from _sha512 import sha512 as _sha512 -except ImportError: - # fallback to official implementation - from hashlib import sha512 as _sha512 - -__all__ = [ - "Random", - "SystemRandom", - "betavariate", - "choice", - "choices", - "expovariate", - "gammavariate", - "gauss", - "getrandbits", - "getstate", - "lognormvariate", - "normalvariate", - "paretovariate", - "randbytes", - "randint", - "random", - "randrange", - "sample", - "seed", - "setstate", - "shuffle", - "triangular", - "uniform", - "vonmisesvariate", - "weibullvariate", -] - -NV_MAGICCONST = 4 * _exp(-0.5) / _sqrt(2.0) -LOG4 = _log(4.0) -SG_MAGICCONST = 1.0 + _log(4.5) -BPF = 53 # Number of bits in a float -RECIP_BPF = 2 ** -BPF -_ONE = 1 - - -class Random(_random.Random): - """Random number generator base class used by bound module functions. - - Used to instantiate instances of Random to get generators that don't - share state. - - Class Random can also be subclassed if you want to use a different basic - generator of your own devising: in that case, override the following - methods: random(), seed(), getstate(), and setstate(). - Optionally, implement a getrandbits() method so that randrange() - can cover arbitrarily large ranges. - - """ - - VERSION = 3 # used by getstate/setstate - - def __init__(self, x=None): - """Initialize an instance. - - Optional argument x controls seeding, as for Random.seed(). - """ - - self.seed(x) - self.gauss_next = None - - def seed(self, a=None, version=2): - """Initialize internal state from a seed. - - The only supported seed types are None, int, float, - str, bytes, and bytearray. - - None or no argument seeds from current time or from an operating - system specific randomness source if available. - - If *a* is an int, all bits are used. - - For version 2 (the default), all of the bits are used if *a* is a str, - bytes, or bytearray. For version 1 (provided for reproducing random - sequences from older versions of Python), the algorithm for str and - bytes generates a narrower range of seeds. - - """ - - if version == 1 and isinstance(a, (str, bytes)): - a = a.decode('latin-1') if isinstance(a, bytes) else a - x = ord(a[0]) << 7 if a else 0 - for c in map(ord, a): - x = ((1000003 * x) ^ c) & 0xFFFFFFFFFFFFFFFF - x ^= len(a) - a = -2 if x == -1 else x - - elif version == 2 and isinstance(a, (str, bytes, bytearray)): - if isinstance(a, str): - a = a.encode() - a = int.from_bytes(a + _sha512(a).digest()) - - elif not isinstance(a, (type(None), int, float, str, bytes, bytearray)): - raise TypeError('The only supported seed types are: None,\n' - 'int, float, str, bytes, and bytearray.') - - super().seed(a) - self.gauss_next = None - - def getstate(self): - """Return internal state; can be passed to setstate() later.""" - return self.VERSION, super().getstate(), self.gauss_next - - def setstate(self, state): - """Restore internal state from object returned by getstate().""" - version = state[0] - if version == 3: - version, internalstate, self.gauss_next = state - super().setstate(internalstate) - elif version == 2: - version, internalstate, self.gauss_next = state - # In version 2, the state was saved as signed ints, which causes - # inconsistencies between 32/64-bit systems. The state is - # really unsigned 32-bit ints, so we convert negative ints from - # version 2 to positive longs for version 3. - try: - internalstate = tuple(x % (2 ** 32) for x in internalstate) - except ValueError as e: - raise TypeError from e - super().setstate(internalstate) - else: - raise ValueError("state with version %s passed to " - "Random.setstate() of version %s" % - (version, self.VERSION)) - - - ## ------------------------------------------------------- - ## ---- Methods below this point do not need to be overridden or extended - ## ---- when subclassing for the purpose of using a different core generator. - - - ## -------------------- pickle support ------------------- - - # Issue 17489: Since __reduce__ was defined to fix #759889 this is no - # longer called; we leave it here because it has been here since random was - # rewritten back in 2001 and why risk breaking something. - def __getstate__(self): # for pickle - return self.getstate() - - def __setstate__(self, state): # for pickle - self.setstate(state) - - def __reduce__(self): - return self.__class__, (), self.getstate() - - - ## ---- internal support method for evenly distributed integers ---- - - def __init_subclass__(cls, /, **kwargs): - """Control how subclasses generate random integers. - - The algorithm a subclass can use depends on the random() and/or - getrandbits() implementation available to it and determines - whether it can generate random integers from arbitrarily large - ranges. - """ - - for c in cls.__mro__: - if '_randbelow' in c.__dict__: - # just inherit it - break - if 'getrandbits' in c.__dict__: - cls._randbelow = cls._randbelow_with_getrandbits - break - if 'random' in c.__dict__: - cls._randbelow = cls._randbelow_without_getrandbits - break - - def _randbelow_with_getrandbits(self, n): - "Return a random int in the range [0,n). Defined for n > 0." - - getrandbits = self.getrandbits - k = n.bit_length() # don't use (n-1) here because n can be 1 - r = getrandbits(k) # 0 <= r < 2**k - while r >= n: - r = getrandbits(k) - return r - - def _randbelow_without_getrandbits(self, n, maxsize=1< 0. - - The implementation does not use getrandbits, but only random. - """ - - random = self.random - if n >= maxsize: - _warn("Underlying random() generator does not supply \n" - "enough bits to choose from a population range this large.\n" - "To remove the range limitation, add a getrandbits() method.") - return _floor(random() * n) - rem = maxsize % n - limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0 - r = random() - while r >= limit: - r = random() - return _floor(r * maxsize) % n - - _randbelow = _randbelow_with_getrandbits - - - ## -------------------------------------------------------- - ## ---- Methods below this point generate custom distributions - ## ---- based on the methods defined above. They do not - ## ---- directly touch the underlying generator and only - ## ---- access randomness through the methods: random(), - ## ---- getrandbits(), or _randbelow(). - - - ## -------------------- bytes methods --------------------- - - def randbytes(self, n): - """Generate n random bytes.""" - return self.getrandbits(n * 8).to_bytes(n, 'little') - - - ## -------------------- integer methods ------------------- - - def randrange(self, start, stop=None, step=_ONE): - """Choose a random item from range(stop) or range(start, stop[, step]). - - Roughly equivalent to ``choice(range(start, stop, step))`` but - supports arbitrarily large ranges and is optimized for common cases. - - """ - - # This code is a bit messy to make it fast for the - # common case while still doing adequate error checking. - try: - istart = _index(start) - except TypeError: - istart = int(start) - if istart != start: - _warn('randrange() will raise TypeError in the future', - DeprecationWarning, 2) - raise ValueError("non-integer arg 1 for randrange()") - _warn('non-integer arguments to randrange() have been deprecated ' - 'since Python 3.10 and will be removed in a subsequent ' - 'version', - DeprecationWarning, 2) - if stop is None: - # We don't check for "step != 1" because it hasn't been - # type checked and converted to an integer yet. - if step is not _ONE: - raise TypeError('Missing a non-None stop argument') - if istart > 0: - return self._randbelow(istart) - raise ValueError("empty range for randrange()") - - # stop argument supplied. - try: - istop = _index(stop) - except TypeError: - istop = int(stop) - if istop != stop: - _warn('randrange() will raise TypeError in the future', - DeprecationWarning, 2) - raise ValueError("non-integer stop for randrange()") - _warn('non-integer arguments to randrange() have been deprecated ' - 'since Python 3.10 and will be removed in a subsequent ' - 'version', - DeprecationWarning, 2) - width = istop - istart - try: - istep = _index(step) - except TypeError: - istep = int(step) - if istep != step: - _warn('randrange() will raise TypeError in the future', - DeprecationWarning, 2) - raise ValueError("non-integer step for randrange()") - _warn('non-integer arguments to randrange() have been deprecated ' - 'since Python 3.10 and will be removed in a subsequent ' - 'version', - DeprecationWarning, 2) - # Fast path. - if istep == 1: - if width > 0: - return istart + self._randbelow(width) - raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width)) - - # Non-unit step argument supplied. - if istep > 0: - n = (width + istep - 1) // istep - elif istep < 0: - n = (width + istep + 1) // istep - else: - raise ValueError("zero step for randrange()") - if n <= 0: - raise ValueError("empty range for randrange()") - return istart + istep * self._randbelow(n) - - def randint(self, a, b): - """Return random integer in range [a, b], including both end points. - """ - - return self.randrange(a, b+1) - - - ## -------------------- sequence methods ------------------- - - def choice(self, seq): - """Choose a random element from a non-empty sequence.""" - if not seq: - raise IndexError('Cannot choose from an empty sequence') - return seq[self._randbelow(len(seq))] - - def shuffle(self, x): - """Shuffle list x in place, and return None.""" - - randbelow = self._randbelow - for i in reversed(range(1, len(x))): - # pick an element in x[:i+1] with which to exchange x[i] - j = randbelow(i + 1) - x[i], x[j] = x[j], x[i] - - def sample(self, population, k, *, counts=None): - """Chooses k unique random elements from a population sequence. - - Returns a new list containing elements from the population while - leaving the original population unchanged. The resulting list is - in selection order so that all sub-slices will also be valid random - samples. This allows raffle winners (the sample) to be partitioned - into grand prize and second place winners (the subslices). - - Members of the population need not be hashable or unique. If the - population contains repeats, then each occurrence is a possible - selection in the sample. - - Repeated elements can be specified one at a time or with the optional - counts parameter. For example: - - sample(['red', 'blue'], counts=[4, 2], k=5) - - is equivalent to: - - sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5) - - To choose a sample from a range of integers, use range() for the - population argument. This is especially fast and space efficient - for sampling from a large population: - - sample(range(10000000), 60) - - """ - - # Sampling without replacement entails tracking either potential - # selections (the pool) in a list or previous selections in a set. - - # When the number of selections is small compared to the - # population, then tracking selections is efficient, requiring - # only a small set and an occasional reselection. For - # a larger number of selections, the pool tracking method is - # preferred since the list takes less space than the - # set and it doesn't suffer from frequent reselections. - - # The number of calls to _randbelow() is kept at or near k, the - # theoretical minimum. This is important because running time - # is dominated by _randbelow() and because it extracts the - # least entropy from the underlying random number generators. - - # Memory requirements are kept to the smaller of a k-length - # set or an n-length list. - - # There are other sampling algorithms that do not require - # auxiliary memory, but they were rejected because they made - # too many calls to _randbelow(), making them slower and - # causing them to eat more entropy than necessary. - - if not isinstance(population, _Sequence): - raise TypeError("Population must be a sequence. " - "For dicts or sets, use sorted(d).") - n = len(population) - if counts is not None: - cum_counts = list(_accumulate(counts)) - if len(cum_counts) != n: - raise ValueError('The number of counts does not match the population') - total = cum_counts.pop() - if not isinstance(total, int): - raise TypeError('Counts must be integers') - if total <= 0: - raise ValueError('Total of counts must be greater than zero') - selections = self.sample(range(total), k=k) - bisect = _bisect - return [population[bisect(cum_counts, s)] for s in selections] - randbelow = self._randbelow - if not 0 <= k <= n: - raise ValueError("Sample larger than population or is negative") - result = [None] * k - setsize = 21 # size of a small set minus size of an empty list - if k > 5: - setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets - if n <= setsize: - # An n-length list is smaller than a k-length set. - # Invariant: non-selected at pool[0 : n-i] - pool = list(population) - for i in range(k): - j = randbelow(n - i) - result[i] = pool[j] - pool[j] = pool[n - i - 1] # move non-selected item into vacancy - else: - selected = set() - selected_add = selected.add - for i in range(k): - j = randbelow(n) - while j in selected: - j = randbelow(n) - selected_add(j) - result[i] = population[j] - return result - - def choices(self, population, weights=None, *, cum_weights=None, k=1): - """Return a k sized list of population elements chosen with replacement. - - If the relative weights or cumulative weights are not specified, - the selections are made with equal probability. - - """ - random = self.random - n = len(population) - if cum_weights is None: - if weights is None: - floor = _floor - n += 0.0 # convert to float for a small speed improvement - return [population[floor(random() * n)] for i in _repeat(None, k)] - try: - cum_weights = list(_accumulate(weights)) - except TypeError: - if not isinstance(weights, int): - raise - k = weights - raise TypeError( - f'The number of choices must be a keyword argument: {k=}' - ) from None - elif weights is not None: - raise TypeError('Cannot specify both weights and cumulative weights') - if len(cum_weights) != n: - raise ValueError('The number of weights does not match the population') - total = cum_weights[-1] + 0.0 # convert to float - if total <= 0.0: - raise ValueError('Total of weights must be greater than zero') - if not _isfinite(total): - raise ValueError('Total of weights must be finite') - bisect = _bisect - hi = n - 1 - return [population[bisect(cum_weights, random() * total, 0, hi)] - for i in _repeat(None, k)] - - - ## -------------------- real-valued distributions ------------------- - - def uniform(self, a, b): - "Get a random number in the range [a, b) or [a, b] depending on rounding." - return a + (b - a) * self.random() - - def triangular(self, low=0.0, high=1.0, mode=None): - """Triangular distribution. - - Continuous distribution bounded by given lower and upper limits, - and having a given mode value in-between. - - http://en.wikipedia.org/wiki/Triangular_distribution - - """ - u = self.random() - try: - c = 0.5 if mode is None else (mode - low) / (high - low) - except ZeroDivisionError: - return low - if u > c: - u = 1.0 - u - c = 1.0 - c - low, high = high, low - return low + (high - low) * _sqrt(u * c) - - def normalvariate(self, mu=0.0, sigma=1.0): - """Normal distribution. - - mu is the mean, and sigma is the standard deviation. - - """ - # Uses Kinderman and Monahan method. Reference: Kinderman, - # A.J. and Monahan, J.F., "Computer generation of random - # variables using the ratio of uniform deviates", ACM Trans - # Math Software, 3, (1977), pp257-260. - - random = self.random - while True: - u1 = random() - u2 = 1.0 - random() - z = NV_MAGICCONST * (u1 - 0.5) / u2 - zz = z * z / 4.0 - if zz <= -_log(u2): - break - return mu + z * sigma - - def gauss(self, mu=0.0, sigma=1.0): - """Gaussian distribution. - - mu is the mean, and sigma is the standard deviation. This is - slightly faster than the normalvariate() function. - - Not thread-safe without a lock around calls. - - """ - # When x and y are two variables from [0, 1), uniformly - # distributed, then - # - # cos(2*pi*x)*sqrt(-2*log(1-y)) - # sin(2*pi*x)*sqrt(-2*log(1-y)) - # - # are two *independent* variables with normal distribution - # (mu = 0, sigma = 1). - # (Lambert Meertens) - # (corrected version; bug discovered by Mike Miller, fixed by LM) - - # Multithreading note: When two threads call this function - # simultaneously, it is possible that they will receive the - # same return value. The window is very small though. To - # avoid this, you have to use a lock around all calls. (I - # didn't want to slow this down in the serial case by using a - # lock here.) - - random = self.random - z = self.gauss_next - self.gauss_next = None - if z is None: - x2pi = random() * TWOPI - g2rad = _sqrt(-2.0 * _log(1.0 - random())) - z = _cos(x2pi) * g2rad - self.gauss_next = _sin(x2pi) * g2rad - - return mu + z * sigma - - def lognormvariate(self, mu, sigma): - """Log normal distribution. - - If you take the natural logarithm of this distribution, you'll get a - normal distribution with mean mu and standard deviation sigma. - mu can have any value, and sigma must be greater than zero. - - """ - return _exp(self.normalvariate(mu, sigma)) - - def expovariate(self, lambd): - """Exponential distribution. - - lambd is 1.0 divided by the desired mean. It should be - nonzero. (The parameter would be called "lambda", but that is - a reserved word in Python.) Returned values range from 0 to - positive infinity if lambd is positive, and from negative - infinity to 0 if lambd is negative. - - """ - # lambd: rate lambd = 1/mean - # ('lambda' is a Python reserved word) - - # we use 1-random() instead of random() to preclude the - # possibility of taking the log of zero. - return -_log(1.0 - self.random()) / lambd - - def vonmisesvariate(self, mu, kappa): - """Circular data distribution. - - mu is the mean angle, expressed in radians between 0 and 2*pi, and - kappa is the concentration parameter, which must be greater than or - equal to zero. If kappa is equal to zero, this distribution reduces - to a uniform random angle over the range 0 to 2*pi. - - """ - # Based upon an algorithm published in: Fisher, N.I., - # "Statistical Analysis of Circular Data", Cambridge - # University Press, 1993. - - # Thanks to Magnus Kessler for a correction to the - # implementation of step 4. - - random = self.random - if kappa <= 1e-6: - return TWOPI * random() - - s = 0.5 / kappa - r = s + _sqrt(1.0 + s * s) - - while True: - u1 = random() - z = _cos(_pi * u1) - - d = z / (r + z) - u2 = random() - if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d): - break - - q = 1.0 / r - f = (q + z) / (1.0 + q * z) - u3 = random() - if u3 > 0.5: - theta = (mu + _acos(f)) % TWOPI - else: - theta = (mu - _acos(f)) % TWOPI - - return theta - - def gammavariate(self, alpha, beta): - """Gamma distribution. Not the gamma function! - - Conditions on the parameters are alpha > 0 and beta > 0. - - The probability distribution function is: - - x ** (alpha - 1) * math.exp(-x / beta) - pdf(x) = -------------------------------------- - math.gamma(alpha) * beta ** alpha - - """ - # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2 - - # Warning: a few older sources define the gamma distribution in terms - # of alpha > -1.0 - if alpha <= 0.0 or beta <= 0.0: - raise ValueError('gammavariate: alpha and beta must be > 0.0') - - random = self.random - if alpha > 1.0: - - # Uses R.C.H. Cheng, "The generation of Gamma - # variables with non-integral shape parameters", - # Applied Statistics, (1977), 26, No. 1, p71-74 - - ainv = _sqrt(2.0 * alpha - 1.0) - bbb = alpha - LOG4 - ccc = alpha + ainv - - while True: - u1 = random() - if not 1e-7 < u1 < 0.9999999: - continue - u2 = 1.0 - random() - v = _log(u1 / (1.0 - u1)) / ainv - x = alpha * _exp(v) - z = u1 * u1 * u2 - r = bbb + ccc * v - x - if r + SG_MAGICCONST - 4.5 * z >= 0.0 or r >= _log(z): - return x * beta - - elif alpha == 1.0: - # expovariate(1/beta) - return -_log(1.0 - random()) * beta - - else: - # alpha is between 0 and 1 (exclusive) - # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle - while True: - u = random() - b = (_e + alpha) / _e - p = b * u - if p <= 1.0: - x = p ** (1.0 / alpha) - else: - x = -_log((b - p) / alpha) - u1 = random() - if p > 1.0: - if u1 <= x ** (alpha - 1.0): - break - elif u1 <= _exp(-x): - break - return x * beta - - def betavariate(self, alpha, beta): - """Beta distribution. - - Conditions on the parameters are alpha > 0 and beta > 0. - Returned values range between 0 and 1. - - """ - ## See - ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html - ## for Ivan Frohne's insightful analysis of why the original implementation: - ## - ## def betavariate(self, alpha, beta): - ## # Discrete Event Simulation in C, pp 87-88. - ## - ## y = self.expovariate(alpha) - ## z = self.expovariate(1.0/beta) - ## return z/(y+z) - ## - ## was dead wrong, and how it probably got that way. - - # This version due to Janne Sinkkonen, and matches all the std - # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution"). - y = self.gammavariate(alpha, 1.0) - if y: - return y / (y + self.gammavariate(beta, 1.0)) - return 0.0 - - def paretovariate(self, alpha): - """Pareto distribution. alpha is the shape parameter.""" - # Jain, pg. 495 - - u = 1.0 - self.random() - return u ** (-1.0 / alpha) - - def weibullvariate(self, alpha, beta): - """Weibull distribution. - - alpha is the scale parameter and beta is the shape parameter. - - """ - # Jain, pg. 499; bug fix courtesy Bill Arms - - u = 1.0 - self.random() - return alpha * (-_log(u)) ** (1.0 / beta) - - -## ------------------------------------------------------------------ -## --------------- Operating System Random Source ------------------ - - -class SystemRandom(Random): - """Alternate random number generator using sources provided - by the operating system (such as /dev/urandom on Unix or - CryptGenRandom on Windows). - - Not available on all systems (see os.urandom() for details). - - """ - - def random(self): - """Get the next random number in the range [0.0, 1.0).""" - return (int.from_bytes(_urandom(7)) >> 3) * RECIP_BPF - - def getrandbits(self, k): - """getrandbits(k) -> x. Generates an int with k random bits.""" - if k < 0: - raise ValueError('number of bits must be non-negative') - numbytes = (k + 7) // 8 # bits / 8 and rounded up - x = int.from_bytes(_urandom(numbytes)) - return x >> (numbytes * 8 - k) # trim excess bits - - def randbytes(self, n): - """Generate n random bytes.""" - # os.urandom(n) fails with ValueError for n < 0 - # and returns an empty bytes string for n == 0. - return _urandom(n) - - def seed(self, *args, **kwds): - "Stub method. Not used for a system random number generator." - return None - - def _notimplemented(self, *args, **kwds): - "Method should not be called for a system random number generator." - raise NotImplementedError('System entropy source does not have state.') - getstate = setstate = _notimplemented - - -# ---------------------------------------------------------------------- -# Create one instance, seeded from current time, and export its methods -# as module-level functions. The functions share state across all uses -# (both in the user's code and in the Python libraries), but that's fine -# for most programs and is easier for the casual user than making them -# instantiate their own Random() instance. - -_inst = Random() -seed = _inst.seed -random = _inst.random -uniform = _inst.uniform -triangular = _inst.triangular -randint = _inst.randint -choice = _inst.choice -randrange = _inst.randrange -sample = _inst.sample -shuffle = _inst.shuffle -choices = _inst.choices -normalvariate = _inst.normalvariate -lognormvariate = _inst.lognormvariate -expovariate = _inst.expovariate -vonmisesvariate = _inst.vonmisesvariate -gammavariate = _inst.gammavariate -gauss = _inst.gauss -betavariate = _inst.betavariate -paretovariate = _inst.paretovariate -weibullvariate = _inst.weibullvariate -getstate = _inst.getstate -setstate = _inst.setstate -getrandbits = _inst.getrandbits -randbytes = _inst.randbytes - - -## ------------------------------------------------------ -## ----------------- test program ----------------------- - -def _test_generator(n, func, args): - from statistics import stdev, fmean as mean - from time import perf_counter - - t0 = perf_counter() - data = [func(*args) for i in _repeat(None, n)] - t1 = perf_counter() - - xbar = mean(data) - sigma = stdev(data, xbar) - low = min(data) - high = max(data) - - print(f'{t1 - t0:.3f} sec, {n} times {func.__name__}') - print('avg %g, stddev %g, min %g, max %g\n' % (xbar, sigma, low, high)) - - -def _test(N=2000): - _test_generator(N, random, ()) - _test_generator(N, normalvariate, (0.0, 1.0)) - _test_generator(N, lognormvariate, (0.0, 1.0)) - _test_generator(N, vonmisesvariate, (0.0, 1.0)) - _test_generator(N, gammavariate, (0.01, 1.0)) - _test_generator(N, gammavariate, (0.1, 1.0)) - _test_generator(N, gammavariate, (0.1, 2.0)) - _test_generator(N, gammavariate, (0.5, 1.0)) - _test_generator(N, gammavariate, (0.9, 1.0)) - _test_generator(N, gammavariate, (1.0, 1.0)) - _test_generator(N, gammavariate, (2.0, 1.0)) - _test_generator(N, gammavariate, (20.0, 1.0)) - _test_generator(N, gammavariate, (200.0, 1.0)) - _test_generator(N, gauss, (0.0, 1.0)) - _test_generator(N, betavariate, (3.0, 3.0)) - _test_generator(N, triangular, (0.0, 1.0, 1.0 / 3.0)) - - -## ------------------------------------------------------ -## ------------------ fork support --------------------- - -if hasattr(_os, "fork"): - _os.register_at_fork(after_in_child=_inst.seed) - - -if __name__ == '__main__': - _test() diff --git a/python/Lib/re/__init__.py b/python/Lib/re/__init__.py deleted file mode 100644 index 2cf30bf..0000000 --- a/python/Lib/re/__init__.py +++ /dev/null @@ -1,374 +0,0 @@ -# -# Secret Labs' Regular Expression Engine -# -# re-compatible interface for the sre matching engine -# -# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. -# -# This version of the SRE library can be redistributed under CNRI's -# Python 1.6 license. For any other use, please contact Secret Labs -# AB (info@pythonware.com). -# -# Portions of this engine have been developed in cooperation with -# CNRI. Hewlett-Packard provided funding for 1.6 integration and -# other compatibility work. -# - -r"""Support for regular expressions (RE). - -This module provides regular expression matching operations similar to -those found in Perl. It supports both 8-bit and Unicode strings; both -the pattern and the strings being processed can contain null bytes and -characters outside the US ASCII range. - -Regular expressions can contain both special and ordinary characters. -Most ordinary characters, like "A", "a", or "0", are the simplest -regular expressions; they simply match themselves. You can -concatenate ordinary characters, so last matches the string 'last'. - -The special characters are: - "." Matches any character except a newline. - "^" Matches the start of the string. - "$" Matches the end of the string or just before the newline at - the end of the string. - "*" Matches 0 or more (greedy) repetitions of the preceding RE. - Greedy means that it will match as many repetitions as possible. - "+" Matches 1 or more (greedy) repetitions of the preceding RE. - "?" Matches 0 or 1 (greedy) of the preceding RE. - *?,+?,?? Non-greedy versions of the previous three special characters. - {m,n} Matches from m to n repetitions of the preceding RE. - {m,n}? Non-greedy version of the above. - "\\" Either escapes special characters or signals a special sequence. - [] Indicates a set of characters. - A "^" as the first character indicates a complementing set. - "|" A|B, creates an RE that will match either A or B. - (...) Matches the RE inside the parentheses. - The contents can be retrieved or matched later in the string. - (?aiLmsux) The letters set the corresponding flags defined below. - (?:...) Non-grouping version of regular parentheses. - (?P...) The substring matched by the group is accessible by name. - (?P=name) Matches the text matched earlier by the group named name. - (?#...) A comment; ignored. - (?=...) Matches if ... matches next, but doesn't consume the string. - (?!...) Matches if ... doesn't match next. - (?<=...) Matches if preceded by ... (must be fixed length). - (?= _MAXCACHE: - # Drop the oldest item - try: - del _cache[next(iter(_cache))] - except (StopIteration, RuntimeError, KeyError): - pass - _cache[type(pattern), pattern, flags] = p - return p - -@functools.lru_cache(_MAXCACHE) -def _compile_repl(repl, pattern): - # internal: compile replacement pattern - return _parser.parse_template(repl, pattern) - -def _expand(pattern, match, template): - # internal: Match.expand implementation hook - template = _parser.parse_template(template, pattern) - return _parser.expand_template(template, match) - -def _subx(pattern, template): - # internal: Pattern.sub/subn implementation helper - template = _compile_repl(template, pattern) - if not template[0] and len(template[1]) == 1: - # literal replacement - return template[1][0] - def filter(match, template=template): - return _parser.expand_template(template, match) - return filter - -# register myself for pickling - -import copyreg - -def _pickle(p): - return _compile, (p.pattern, p.flags) - -copyreg.pickle(Pattern, _pickle, _compile) - -# -------------------------------------------------------------------- -# experimental stuff (see python-dev discussions for details) - -class Scanner: - def __init__(self, lexicon, flags=0): - from ._constants import BRANCH, SUBPATTERN - if isinstance(flags, RegexFlag): - flags = flags.value - self.lexicon = lexicon - # combine phrases into a compound pattern - p = [] - s = _parser.State() - s.flags = flags - for phrase, action in lexicon: - gid = s.opengroup() - p.append(_parser.SubPattern(s, [ - (SUBPATTERN, (gid, 0, 0, _parser.parse(phrase, flags))), - ])) - s.closegroup(gid, p[-1]) - p = _parser.SubPattern(s, [(BRANCH, (None, p))]) - self.scanner = _compiler.compile(p) - def scan(self, string): - result = [] - append = result.append - match = self.scanner.scanner(string).match - i = 0 - while True: - m = match() - if not m: - break - j = m.end() - if i == j: - break - action = self.lexicon[m.lastindex-1][1] - if callable(action): - self.match = m - action = action(self, m.group()) - if action is not None: - append(action) - i = j - return result, string[i:] diff --git a/python/Lib/re/_casefix.py b/python/Lib/re/_casefix.py deleted file mode 100644 index 6e82ce1..0000000 --- a/python/Lib/re/_casefix.py +++ /dev/null @@ -1,106 +0,0 @@ -# Auto-generated by Tools/scripts/generate_re_casefix.py. - -# Maps the code of lowercased character to codes of different lowercased -# characters which have the same uppercase. -_EXTRA_CASES = { - # LATIN SMALL LETTER I: LATIN SMALL LETTER DOTLESS I - 0x0069: (0x0131,), # 'i': 'ı' - # LATIN SMALL LETTER S: LATIN SMALL LETTER LONG S - 0x0073: (0x017f,), # 's': 'ſ' - # MICRO SIGN: GREEK SMALL LETTER MU - 0x00b5: (0x03bc,), # 'µ': 'μ' - # LATIN SMALL LETTER DOTLESS I: LATIN SMALL LETTER I - 0x0131: (0x0069,), # 'ı': 'i' - # LATIN SMALL LETTER LONG S: LATIN SMALL LETTER S - 0x017f: (0x0073,), # 'ſ': 's' - # COMBINING GREEK YPOGEGRAMMENI: GREEK SMALL LETTER IOTA, GREEK PROSGEGRAMMENI - 0x0345: (0x03b9, 0x1fbe), # '\u0345': 'ιι' - # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS: GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA - 0x0390: (0x1fd3,), # 'ΐ': 'ΐ' - # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS: GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA - 0x03b0: (0x1fe3,), # 'ΰ': 'ΰ' - # GREEK SMALL LETTER BETA: GREEK BETA SYMBOL - 0x03b2: (0x03d0,), # 'β': 'ϐ' - # GREEK SMALL LETTER EPSILON: GREEK LUNATE EPSILON SYMBOL - 0x03b5: (0x03f5,), # 'ε': 'ϵ' - # GREEK SMALL LETTER THETA: GREEK THETA SYMBOL - 0x03b8: (0x03d1,), # 'θ': 'ϑ' - # GREEK SMALL LETTER IOTA: COMBINING GREEK YPOGEGRAMMENI, GREEK PROSGEGRAMMENI - 0x03b9: (0x0345, 0x1fbe), # 'ι': '\u0345ι' - # GREEK SMALL LETTER KAPPA: GREEK KAPPA SYMBOL - 0x03ba: (0x03f0,), # 'κ': 'ϰ' - # GREEK SMALL LETTER MU: MICRO SIGN - 0x03bc: (0x00b5,), # 'μ': 'µ' - # GREEK SMALL LETTER PI: GREEK PI SYMBOL - 0x03c0: (0x03d6,), # 'π': 'ϖ' - # GREEK SMALL LETTER RHO: GREEK RHO SYMBOL - 0x03c1: (0x03f1,), # 'ρ': 'ϱ' - # GREEK SMALL LETTER FINAL SIGMA: GREEK SMALL LETTER SIGMA - 0x03c2: (0x03c3,), # 'ς': 'σ' - # GREEK SMALL LETTER SIGMA: GREEK SMALL LETTER FINAL SIGMA - 0x03c3: (0x03c2,), # 'σ': 'ς' - # GREEK SMALL LETTER PHI: GREEK PHI SYMBOL - 0x03c6: (0x03d5,), # 'φ': 'ϕ' - # GREEK BETA SYMBOL: GREEK SMALL LETTER BETA - 0x03d0: (0x03b2,), # 'ϐ': 'β' - # GREEK THETA SYMBOL: GREEK SMALL LETTER THETA - 0x03d1: (0x03b8,), # 'ϑ': 'θ' - # GREEK PHI SYMBOL: GREEK SMALL LETTER PHI - 0x03d5: (0x03c6,), # 'ϕ': 'φ' - # GREEK PI SYMBOL: GREEK SMALL LETTER PI - 0x03d6: (0x03c0,), # 'ϖ': 'π' - # GREEK KAPPA SYMBOL: GREEK SMALL LETTER KAPPA - 0x03f0: (0x03ba,), # 'ϰ': 'κ' - # GREEK RHO SYMBOL: GREEK SMALL LETTER RHO - 0x03f1: (0x03c1,), # 'ϱ': 'ρ' - # GREEK LUNATE EPSILON SYMBOL: GREEK SMALL LETTER EPSILON - 0x03f5: (0x03b5,), # 'ϵ': 'ε' - # CYRILLIC SMALL LETTER VE: CYRILLIC SMALL LETTER ROUNDED VE - 0x0432: (0x1c80,), # 'в': 'ᲀ' - # CYRILLIC SMALL LETTER DE: CYRILLIC SMALL LETTER LONG-LEGGED DE - 0x0434: (0x1c81,), # 'д': 'ᲁ' - # CYRILLIC SMALL LETTER O: CYRILLIC SMALL LETTER NARROW O - 0x043e: (0x1c82,), # 'о': 'ᲂ' - # CYRILLIC SMALL LETTER ES: CYRILLIC SMALL LETTER WIDE ES - 0x0441: (0x1c83,), # 'с': 'ᲃ' - # CYRILLIC SMALL LETTER TE: CYRILLIC SMALL LETTER TALL TE, CYRILLIC SMALL LETTER THREE-LEGGED TE - 0x0442: (0x1c84, 0x1c85), # 'т': 'ᲄᲅ' - # CYRILLIC SMALL LETTER HARD SIGN: CYRILLIC SMALL LETTER TALL HARD SIGN - 0x044a: (0x1c86,), # 'ъ': 'ᲆ' - # CYRILLIC SMALL LETTER YAT: CYRILLIC SMALL LETTER TALL YAT - 0x0463: (0x1c87,), # 'ѣ': 'ᲇ' - # CYRILLIC SMALL LETTER ROUNDED VE: CYRILLIC SMALL LETTER VE - 0x1c80: (0x0432,), # 'ᲀ': 'в' - # CYRILLIC SMALL LETTER LONG-LEGGED DE: CYRILLIC SMALL LETTER DE - 0x1c81: (0x0434,), # 'ᲁ': 'д' - # CYRILLIC SMALL LETTER NARROW O: CYRILLIC SMALL LETTER O - 0x1c82: (0x043e,), # 'ᲂ': 'о' - # CYRILLIC SMALL LETTER WIDE ES: CYRILLIC SMALL LETTER ES - 0x1c83: (0x0441,), # 'ᲃ': 'с' - # CYRILLIC SMALL LETTER TALL TE: CYRILLIC SMALL LETTER TE, CYRILLIC SMALL LETTER THREE-LEGGED TE - 0x1c84: (0x0442, 0x1c85), # 'ᲄ': 'тᲅ' - # CYRILLIC SMALL LETTER THREE-LEGGED TE: CYRILLIC SMALL LETTER TE, CYRILLIC SMALL LETTER TALL TE - 0x1c85: (0x0442, 0x1c84), # 'ᲅ': 'тᲄ' - # CYRILLIC SMALL LETTER TALL HARD SIGN: CYRILLIC SMALL LETTER HARD SIGN - 0x1c86: (0x044a,), # 'ᲆ': 'ъ' - # CYRILLIC SMALL LETTER TALL YAT: CYRILLIC SMALL LETTER YAT - 0x1c87: (0x0463,), # 'ᲇ': 'ѣ' - # CYRILLIC SMALL LETTER UNBLENDED UK: CYRILLIC SMALL LETTER MONOGRAPH UK - 0x1c88: (0xa64b,), # 'ᲈ': 'ꙋ' - # LATIN SMALL LETTER S WITH DOT ABOVE: LATIN SMALL LETTER LONG S WITH DOT ABOVE - 0x1e61: (0x1e9b,), # 'ṡ': 'ẛ' - # LATIN SMALL LETTER LONG S WITH DOT ABOVE: LATIN SMALL LETTER S WITH DOT ABOVE - 0x1e9b: (0x1e61,), # 'ẛ': 'ṡ' - # GREEK PROSGEGRAMMENI: COMBINING GREEK YPOGEGRAMMENI, GREEK SMALL LETTER IOTA - 0x1fbe: (0x0345, 0x03b9), # 'ι': '\u0345ι' - # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA: GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - 0x1fd3: (0x0390,), # 'ΐ': 'ΐ' - # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA: GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - 0x1fe3: (0x03b0,), # 'ΰ': 'ΰ' - # CYRILLIC SMALL LETTER MONOGRAPH UK: CYRILLIC SMALL LETTER UNBLENDED UK - 0xa64b: (0x1c88,), # 'ꙋ': 'ᲈ' - # LATIN SMALL LIGATURE LONG S T: LATIN SMALL LIGATURE ST - 0xfb05: (0xfb06,), # 'ſt': 'st' - # LATIN SMALL LIGATURE ST: LATIN SMALL LIGATURE LONG S T - 0xfb06: (0xfb05,), # 'st': 'ſt' -} diff --git a/python/Lib/re/_compiler.py b/python/Lib/re/_compiler.py deleted file mode 100644 index f69c57c..0000000 --- a/python/Lib/re/_compiler.py +++ /dev/null @@ -1,763 +0,0 @@ -# -# Secret Labs' Regular Expression Engine -# -# convert template to internal format -# -# Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. -# -# See the __init__.py file for information on usage and redistribution. -# - -"""Internal support module for sre""" - -import _sre -from . import _parser -from ._constants import * -from ._casefix import _EXTRA_CASES - -assert _sre.MAGIC == MAGIC, "SRE module mismatch" - -_LITERAL_CODES = {LITERAL, NOT_LITERAL} -_SUCCESS_CODES = {SUCCESS, FAILURE} -_ASSERT_CODES = {ASSERT, ASSERT_NOT} -_UNIT_CODES = _LITERAL_CODES | {ANY, IN} - -_REPEATING_CODES = { - MIN_REPEAT: (REPEAT, MIN_UNTIL, MIN_REPEAT_ONE), - MAX_REPEAT: (REPEAT, MAX_UNTIL, REPEAT_ONE), - POSSESSIVE_REPEAT: (POSSESSIVE_REPEAT, SUCCESS, POSSESSIVE_REPEAT_ONE), -} - -def _combine_flags(flags, add_flags, del_flags, - TYPE_FLAGS=_parser.TYPE_FLAGS): - if add_flags & TYPE_FLAGS: - flags &= ~TYPE_FLAGS - return (flags | add_flags) & ~del_flags - -def _compile(code, pattern, flags): - # internal: compile a (sub)pattern - emit = code.append - _len = len - LITERAL_CODES = _LITERAL_CODES - REPEATING_CODES = _REPEATING_CODES - SUCCESS_CODES = _SUCCESS_CODES - ASSERT_CODES = _ASSERT_CODES - iscased = None - tolower = None - fixes = None - if flags & SRE_FLAG_IGNORECASE and not flags & SRE_FLAG_LOCALE: - if flags & SRE_FLAG_UNICODE: - iscased = _sre.unicode_iscased - tolower = _sre.unicode_tolower - fixes = _EXTRA_CASES - else: - iscased = _sre.ascii_iscased - tolower = _sre.ascii_tolower - for op, av in pattern: - if op in LITERAL_CODES: - if not flags & SRE_FLAG_IGNORECASE: - emit(op) - emit(av) - elif flags & SRE_FLAG_LOCALE: - emit(OP_LOCALE_IGNORE[op]) - emit(av) - elif not iscased(av): - emit(op) - emit(av) - else: - lo = tolower(av) - if not fixes: # ascii - emit(OP_IGNORE[op]) - emit(lo) - elif lo not in fixes: - emit(OP_UNICODE_IGNORE[op]) - emit(lo) - else: - emit(IN_UNI_IGNORE) - skip = _len(code); emit(0) - if op is NOT_LITERAL: - emit(NEGATE) - for k in (lo,) + fixes[lo]: - emit(LITERAL) - emit(k) - emit(FAILURE) - code[skip] = _len(code) - skip - elif op is IN: - charset, hascased = _optimize_charset(av, iscased, tolower, fixes) - if flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE: - emit(IN_LOC_IGNORE) - elif not hascased: - emit(IN) - elif not fixes: # ascii - emit(IN_IGNORE) - else: - emit(IN_UNI_IGNORE) - skip = _len(code); emit(0) - _compile_charset(charset, flags, code) - code[skip] = _len(code) - skip - elif op is ANY: - if flags & SRE_FLAG_DOTALL: - emit(ANY_ALL) - else: - emit(ANY) - elif op in REPEATING_CODES: - if flags & SRE_FLAG_TEMPLATE: - raise error("internal: unsupported template operator %r" % (op,)) - if _simple(av[2]): - emit(REPEATING_CODES[op][2]) - skip = _len(code); emit(0) - emit(av[0]) - emit(av[1]) - _compile(code, av[2], flags) - emit(SUCCESS) - code[skip] = _len(code) - skip - else: - emit(REPEATING_CODES[op][0]) - skip = _len(code); emit(0) - emit(av[0]) - emit(av[1]) - _compile(code, av[2], flags) - code[skip] = _len(code) - skip - emit(REPEATING_CODES[op][1]) - elif op is SUBPATTERN: - group, add_flags, del_flags, p = av - if group: - emit(MARK) - emit((group-1)*2) - # _compile_info(code, p, _combine_flags(flags, add_flags, del_flags)) - _compile(code, p, _combine_flags(flags, add_flags, del_flags)) - if group: - emit(MARK) - emit((group-1)*2+1) - elif op is ATOMIC_GROUP: - # Atomic Groups are handled by starting with an Atomic - # Group op code, then putting in the atomic group pattern - # and finally a success op code to tell any repeat - # operations within the Atomic Group to stop eating and - # pop their stack if they reach it - emit(ATOMIC_GROUP) - skip = _len(code); emit(0) - _compile(code, av, flags) - emit(SUCCESS) - code[skip] = _len(code) - skip - elif op in SUCCESS_CODES: - emit(op) - elif op in ASSERT_CODES: - emit(op) - skip = _len(code); emit(0) - if av[0] >= 0: - emit(0) # look ahead - else: - lo, hi = av[1].getwidth() - if lo != hi: - raise error("look-behind requires fixed-width pattern") - emit(lo) # look behind - _compile(code, av[1], flags) - emit(SUCCESS) - code[skip] = _len(code) - skip - elif op is AT: - emit(op) - if flags & SRE_FLAG_MULTILINE: - av = AT_MULTILINE.get(av, av) - if flags & SRE_FLAG_LOCALE: - av = AT_LOCALE.get(av, av) - elif flags & SRE_FLAG_UNICODE: - av = AT_UNICODE.get(av, av) - emit(av) - elif op is BRANCH: - emit(op) - tail = [] - tailappend = tail.append - for av in av[1]: - skip = _len(code); emit(0) - # _compile_info(code, av, flags) - _compile(code, av, flags) - emit(JUMP) - tailappend(_len(code)); emit(0) - code[skip] = _len(code) - skip - emit(FAILURE) # end of branch - for tail in tail: - code[tail] = _len(code) - tail - elif op is CATEGORY: - emit(op) - if flags & SRE_FLAG_LOCALE: - av = CH_LOCALE[av] - elif flags & SRE_FLAG_UNICODE: - av = CH_UNICODE[av] - emit(av) - elif op is GROUPREF: - if not flags & SRE_FLAG_IGNORECASE: - emit(op) - elif flags & SRE_FLAG_LOCALE: - emit(GROUPREF_LOC_IGNORE) - elif not fixes: # ascii - emit(GROUPREF_IGNORE) - else: - emit(GROUPREF_UNI_IGNORE) - emit(av-1) - elif op is GROUPREF_EXISTS: - emit(op) - emit(av[0]-1) - skipyes = _len(code); emit(0) - _compile(code, av[1], flags) - if av[2]: - emit(JUMP) - skipno = _len(code); emit(0) - code[skipyes] = _len(code) - skipyes + 1 - _compile(code, av[2], flags) - code[skipno] = _len(code) - skipno - else: - code[skipyes] = _len(code) - skipyes + 1 - else: - raise error("internal: unsupported operand type %r" % (op,)) - -def _compile_charset(charset, flags, code): - # compile charset subprogram - emit = code.append - for op, av in charset: - emit(op) - if op is NEGATE: - pass - elif op is LITERAL: - emit(av) - elif op is RANGE or op is RANGE_UNI_IGNORE: - emit(av[0]) - emit(av[1]) - elif op is CHARSET: - code.extend(av) - elif op is BIGCHARSET: - code.extend(av) - elif op is CATEGORY: - if flags & SRE_FLAG_LOCALE: - emit(CH_LOCALE[av]) - elif flags & SRE_FLAG_UNICODE: - emit(CH_UNICODE[av]) - else: - emit(av) - else: - raise error("internal: unsupported set operator %r" % (op,)) - emit(FAILURE) - -def _optimize_charset(charset, iscased=None, fixup=None, fixes=None): - # internal: optimize character set - out = [] - tail = [] - charmap = bytearray(256) - hascased = False - for op, av in charset: - while True: - try: - if op is LITERAL: - if fixup: - lo = fixup(av) - charmap[lo] = 1 - if fixes and lo in fixes: - for k in fixes[lo]: - charmap[k] = 1 - if not hascased and iscased(av): - hascased = True - else: - charmap[av] = 1 - elif op is RANGE: - r = range(av[0], av[1]+1) - if fixup: - if fixes: - for i in map(fixup, r): - charmap[i] = 1 - if i in fixes: - for k in fixes[i]: - charmap[k] = 1 - else: - for i in map(fixup, r): - charmap[i] = 1 - if not hascased: - hascased = any(map(iscased, r)) - else: - for i in r: - charmap[i] = 1 - elif op is NEGATE: - out.append((op, av)) - else: - tail.append((op, av)) - except IndexError: - if len(charmap) == 256: - # character set contains non-UCS1 character codes - charmap += b'\0' * 0xff00 - continue - # Character set contains non-BMP character codes. - # For range, all BMP characters in the range are already - # proceeded. - if fixup: - hascased = True - # For now, IN_UNI_IGNORE+LITERAL and - # IN_UNI_IGNORE+RANGE_UNI_IGNORE work for all non-BMP - # characters, because two characters (at least one of - # which is not in the BMP) match case-insensitively - # if and only if: - # 1) c1.lower() == c2.lower() - # 2) c1.lower() == c2 or c1.lower().upper() == c2 - # Also, both c.lower() and c.lower().upper() are single - # characters for every non-BMP character. - if op is RANGE: - op = RANGE_UNI_IGNORE - tail.append((op, av)) - break - - # compress character map - runs = [] - q = 0 - while True: - p = charmap.find(1, q) - if p < 0: - break - if len(runs) >= 2: - runs = None - break - q = charmap.find(0, p) - if q < 0: - runs.append((p, len(charmap))) - break - runs.append((p, q)) - if runs is not None: - # use literal/range - for p, q in runs: - if q - p == 1: - out.append((LITERAL, p)) - else: - out.append((RANGE, (p, q - 1))) - out += tail - # if the case was changed or new representation is more compact - if hascased or len(out) < len(charset): - return out, hascased - # else original character set is good enough - return charset, hascased - - # use bitmap - if len(charmap) == 256: - data = _mk_bitmap(charmap) - out.append((CHARSET, data)) - out += tail - return out, hascased - - # To represent a big charset, first a bitmap of all characters in the - # set is constructed. Then, this bitmap is sliced into chunks of 256 - # characters, duplicate chunks are eliminated, and each chunk is - # given a number. In the compiled expression, the charset is - # represented by a 32-bit word sequence, consisting of one word for - # the number of different chunks, a sequence of 256 bytes (64 words) - # of chunk numbers indexed by their original chunk position, and a - # sequence of 256-bit chunks (8 words each). - - # Compression is normally good: in a typical charset, large ranges of - # Unicode will be either completely excluded (e.g. if only cyrillic - # letters are to be matched), or completely included (e.g. if large - # subranges of Kanji match). These ranges will be represented by - # chunks of all one-bits or all zero-bits. - - # Matching can be also done efficiently: the more significant byte of - # the Unicode character is an index into the chunk number, and the - # less significant byte is a bit index in the chunk (just like the - # CHARSET matching). - - charmap = bytes(charmap) # should be hashable - comps = {} - mapping = bytearray(256) - block = 0 - data = bytearray() - for i in range(0, 65536, 256): - chunk = charmap[i: i + 256] - if chunk in comps: - mapping[i // 256] = comps[chunk] - else: - mapping[i // 256] = comps[chunk] = block - block += 1 - data += chunk - data = _mk_bitmap(data) - data[0:0] = [block] + _bytes_to_codes(mapping) - out.append((BIGCHARSET, data)) - out += tail - return out, hascased - -_CODEBITS = _sre.CODESIZE * 8 -MAXCODE = (1 << _CODEBITS) - 1 -_BITS_TRANS = b'0' + b'1' * 255 -def _mk_bitmap(bits, _CODEBITS=_CODEBITS, _int=int): - s = bits.translate(_BITS_TRANS)[::-1] - return [_int(s[i - _CODEBITS: i], 2) - for i in range(len(s), 0, -_CODEBITS)] - -def _bytes_to_codes(b): - # Convert block indices to word array - a = memoryview(b).cast('I') - assert a.itemsize == _sre.CODESIZE - assert len(a) * a.itemsize == len(b) - return a.tolist() - -def _simple(p): - # check if this subpattern is a "simple" operator - if len(p) != 1: - return False - op, av = p[0] - if op is SUBPATTERN: - return av[0] is None and _simple(av[-1]) - return op in _UNIT_CODES - -def _generate_overlap_table(prefix): - """ - Generate an overlap table for the following prefix. - An overlap table is a table of the same size as the prefix which - informs about the potential self-overlap for each index in the prefix: - - if overlap[i] == 0, prefix[i:] can't overlap prefix[0:...] - - if overlap[i] == k with 0 < k <= i, prefix[i-k+1:i+1] overlaps with - prefix[0:k] - """ - table = [0] * len(prefix) - for i in range(1, len(prefix)): - idx = table[i - 1] - while prefix[i] != prefix[idx]: - if idx == 0: - table[i] = 0 - break - idx = table[idx - 1] - else: - table[i] = idx + 1 - return table - -def _get_iscased(flags): - if not flags & SRE_FLAG_IGNORECASE: - return None - elif flags & SRE_FLAG_UNICODE: - return _sre.unicode_iscased - else: - return _sre.ascii_iscased - -def _get_literal_prefix(pattern, flags): - # look for literal prefix - prefix = [] - prefixappend = prefix.append - prefix_skip = None - iscased = _get_iscased(flags) - for op, av in pattern.data: - if op is LITERAL: - if iscased and iscased(av): - break - prefixappend(av) - elif op is SUBPATTERN: - group, add_flags, del_flags, p = av - flags1 = _combine_flags(flags, add_flags, del_flags) - if flags1 & SRE_FLAG_IGNORECASE and flags1 & SRE_FLAG_LOCALE: - break - prefix1, prefix_skip1, got_all = _get_literal_prefix(p, flags1) - if prefix_skip is None: - if group is not None: - prefix_skip = len(prefix) - elif prefix_skip1 is not None: - prefix_skip = len(prefix) + prefix_skip1 - prefix.extend(prefix1) - if not got_all: - break - else: - break - else: - return prefix, prefix_skip, True - return prefix, prefix_skip, False - -def _get_charset_prefix(pattern, flags): - while True: - if not pattern.data: - return None - op, av = pattern.data[0] - if op is not SUBPATTERN: - break - group, add_flags, del_flags, pattern = av - flags = _combine_flags(flags, add_flags, del_flags) - if flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE: - return None - - iscased = _get_iscased(flags) - if op is LITERAL: - if iscased and iscased(av): - return None - return [(op, av)] - elif op is BRANCH: - charset = [] - charsetappend = charset.append - for p in av[1]: - if not p: - return None - op, av = p[0] - if op is LITERAL and not (iscased and iscased(av)): - charsetappend((op, av)) - else: - return None - return charset - elif op is IN: - charset = av - if iscased: - for op, av in charset: - if op is LITERAL: - if iscased(av): - return None - elif op is RANGE: - if av[1] > 0xffff: - return None - if any(map(iscased, range(av[0], av[1]+1))): - return None - return charset - return None - -def _compile_info(code, pattern, flags): - # internal: compile an info block. in the current version, - # this contains min/max pattern width, and an optional literal - # prefix or a character map - lo, hi = pattern.getwidth() - if hi > MAXCODE: - hi = MAXCODE - if lo == 0: - code.extend([INFO, 4, 0, lo, hi]) - return - # look for a literal prefix - prefix = [] - prefix_skip = 0 - charset = [] # not used - if not (flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE): - # look for literal prefix - prefix, prefix_skip, got_all = _get_literal_prefix(pattern, flags) - # if no prefix, look for charset prefix - if not prefix: - charset = _get_charset_prefix(pattern, flags) -## if prefix: -## print("*** PREFIX", prefix, prefix_skip) -## if charset: -## print("*** CHARSET", charset) - # add an info block - emit = code.append - emit(INFO) - skip = len(code); emit(0) - # literal flag - mask = 0 - if prefix: - mask = SRE_INFO_PREFIX - if prefix_skip is None and got_all: - mask = mask | SRE_INFO_LITERAL - elif charset: - mask = mask | SRE_INFO_CHARSET - emit(mask) - # pattern length - if lo < MAXCODE: - emit(lo) - else: - emit(MAXCODE) - prefix = prefix[:MAXCODE] - emit(min(hi, MAXCODE)) - # add literal prefix - if prefix: - emit(len(prefix)) # length - if prefix_skip is None: - prefix_skip = len(prefix) - emit(prefix_skip) # skip - code.extend(prefix) - # generate overlap table - code.extend(_generate_overlap_table(prefix)) - elif charset: - charset, hascased = _optimize_charset(charset) - assert not hascased - _compile_charset(charset, flags, code) - code[skip] = len(code) - skip - -def isstring(obj): - return isinstance(obj, (str, bytes)) - -def _code(p, flags): - - flags = p.state.flags | flags - code = [] - - # compile info block - _compile_info(code, p, flags) - - # compile the pattern - _compile(code, p.data, flags) - - code.append(SUCCESS) - - return code - -def _hex_code(code): - return '[%s]' % ', '.join('%#0*x' % (_sre.CODESIZE*2+2, x) for x in code) - -def dis(code): - import sys - - labels = set() - level = 0 - offset_width = len(str(len(code) - 1)) - - def dis_(start, end): - def print_(*args, to=None): - if to is not None: - labels.add(to) - args += ('(to %d)' % (to,),) - print('%*d%s ' % (offset_width, start, ':' if start in labels else '.'), - end=' '*(level-1)) - print(*args) - - def print_2(*args): - print(end=' '*(offset_width + 2*level)) - print(*args) - - nonlocal level - level += 1 - i = start - while i < end: - start = i - op = code[i] - i += 1 - op = OPCODES[op] - if op in (SUCCESS, FAILURE, ANY, ANY_ALL, - MAX_UNTIL, MIN_UNTIL, NEGATE): - print_(op) - elif op in (LITERAL, NOT_LITERAL, - LITERAL_IGNORE, NOT_LITERAL_IGNORE, - LITERAL_UNI_IGNORE, NOT_LITERAL_UNI_IGNORE, - LITERAL_LOC_IGNORE, NOT_LITERAL_LOC_IGNORE): - arg = code[i] - i += 1 - print_(op, '%#02x (%r)' % (arg, chr(arg))) - elif op is AT: - arg = code[i] - i += 1 - arg = str(ATCODES[arg]) - assert arg[:3] == 'AT_' - print_(op, arg[3:]) - elif op is CATEGORY: - arg = code[i] - i += 1 - arg = str(CHCODES[arg]) - assert arg[:9] == 'CATEGORY_' - print_(op, arg[9:]) - elif op in (IN, IN_IGNORE, IN_UNI_IGNORE, IN_LOC_IGNORE): - skip = code[i] - print_(op, skip, to=i+skip) - dis_(i+1, i+skip) - i += skip - elif op in (RANGE, RANGE_UNI_IGNORE): - lo, hi = code[i: i+2] - i += 2 - print_(op, '%#02x %#02x (%r-%r)' % (lo, hi, chr(lo), chr(hi))) - elif op is CHARSET: - print_(op, _hex_code(code[i: i + 256//_CODEBITS])) - i += 256//_CODEBITS - elif op is BIGCHARSET: - arg = code[i] - i += 1 - mapping = list(b''.join(x.to_bytes(_sre.CODESIZE, sys.byteorder) - for x in code[i: i + 256//_sre.CODESIZE])) - print_(op, arg, mapping) - i += 256//_sre.CODESIZE - level += 1 - for j in range(arg): - print_2(_hex_code(code[i: i + 256//_CODEBITS])) - i += 256//_CODEBITS - level -= 1 - elif op in (MARK, GROUPREF, GROUPREF_IGNORE, GROUPREF_UNI_IGNORE, - GROUPREF_LOC_IGNORE): - arg = code[i] - i += 1 - print_(op, arg) - elif op is JUMP: - skip = code[i] - print_(op, skip, to=i+skip) - i += 1 - elif op is BRANCH: - skip = code[i] - print_(op, skip, to=i+skip) - while skip: - dis_(i+1, i+skip) - i += skip - start = i - skip = code[i] - if skip: - print_('branch', skip, to=i+skip) - else: - print_(FAILURE) - i += 1 - elif op in (REPEAT, REPEAT_ONE, MIN_REPEAT_ONE, - POSSESSIVE_REPEAT, POSSESSIVE_REPEAT_ONE): - skip, min, max = code[i: i+3] - if max == MAXREPEAT: - max = 'MAXREPEAT' - print_(op, skip, min, max, to=i+skip) - dis_(i+3, i+skip) - i += skip - elif op is GROUPREF_EXISTS: - arg, skip = code[i: i+2] - print_(op, arg, skip, to=i+skip) - i += 2 - elif op in (ASSERT, ASSERT_NOT): - skip, arg = code[i: i+2] - print_(op, skip, arg, to=i+skip) - dis_(i+2, i+skip) - i += skip - elif op is ATOMIC_GROUP: - skip = code[i] - print_(op, skip, to=i+skip) - dis_(i+1, i+skip) - i += skip - elif op is INFO: - skip, flags, min, max = code[i: i+4] - if max == MAXREPEAT: - max = 'MAXREPEAT' - print_(op, skip, bin(flags), min, max, to=i+skip) - start = i+4 - if flags & SRE_INFO_PREFIX: - prefix_len, prefix_skip = code[i+4: i+6] - print_2(' prefix_skip', prefix_skip) - start = i + 6 - prefix = code[start: start+prefix_len] - print_2(' prefix', - '[%s]' % ', '.join('%#02x' % x for x in prefix), - '(%r)' % ''.join(map(chr, prefix))) - start += prefix_len - print_2(' overlap', code[start: start+prefix_len]) - start += prefix_len - if flags & SRE_INFO_CHARSET: - level += 1 - print_2('in') - dis_(start, i+skip) - level -= 1 - i += skip - else: - raise ValueError(op) - - level -= 1 - - dis_(0, len(code)) - - -def compile(p, flags=0): - # internal: convert pattern list to internal format - - if isstring(p): - pattern = p - p = _parser.parse(p, flags) - else: - pattern = None - - code = _code(p, flags) - - if flags & SRE_FLAG_DEBUG: - print() - dis(code) - - # map in either direction - groupindex = p.state.groupdict - indexgroup = [None] * p.state.groups - for k, i in groupindex.items(): - indexgroup[i] = k - - return _sre.compile( - pattern, flags | p.state.flags, code, - p.state.groups-1, - groupindex, tuple(indexgroup) - ) diff --git a/python/Lib/re/_constants.py b/python/Lib/re/_constants.py deleted file mode 100644 index 94e6acc..0000000 --- a/python/Lib/re/_constants.py +++ /dev/null @@ -1,220 +0,0 @@ -# -# Secret Labs' Regular Expression Engine -# -# various symbols used by the regular expression engine. -# run this script to update the _sre include files! -# -# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. -# -# See the __init__.py file for information on usage and redistribution. -# - -"""Internal support module for sre""" - -# update when constants are added or removed - -MAGIC = 20220615 - -from _sre import MAXREPEAT, MAXGROUPS - -# SRE standard exception (access as sre.error) -# should this really be here? - -class error(Exception): - """Exception raised for invalid regular expressions. - - Attributes: - - msg: The unformatted error message - pattern: The regular expression pattern - pos: The index in the pattern where compilation failed (may be None) - lineno: The line corresponding to pos (may be None) - colno: The column corresponding to pos (may be None) - """ - - __module__ = 're' - - def __init__(self, msg, pattern=None, pos=None): - self.msg = msg - self.pattern = pattern - self.pos = pos - if pattern is not None and pos is not None: - msg = '%s at position %d' % (msg, pos) - if isinstance(pattern, str): - newline = '\n' - else: - newline = b'\n' - self.lineno = pattern.count(newline, 0, pos) + 1 - self.colno = pos - pattern.rfind(newline, 0, pos) - if newline in pattern: - msg = '%s (line %d, column %d)' % (msg, self.lineno, self.colno) - else: - self.lineno = self.colno = None - super().__init__(msg) - - -class _NamedIntConstant(int): - def __new__(cls, value, name): - self = super(_NamedIntConstant, cls).__new__(cls, value) - self.name = name - return self - - def __repr__(self): - return self.name - - __reduce__ = None - -MAXREPEAT = _NamedIntConstant(MAXREPEAT, 'MAXREPEAT') - -def _makecodes(*names): - items = [_NamedIntConstant(i, name) for i, name in enumerate(names)] - globals().update({item.name: item for item in items}) - return items - -# operators -OPCODES = _makecodes( - # failure=0 success=1 (just because it looks better that way :-) - 'FAILURE', 'SUCCESS', - - 'ANY', 'ANY_ALL', - 'ASSERT', 'ASSERT_NOT', - 'AT', - 'BRANCH', - 'CATEGORY', - 'CHARSET', 'BIGCHARSET', - 'GROUPREF', 'GROUPREF_EXISTS', - 'IN', - 'INFO', - 'JUMP', - 'LITERAL', - 'MARK', - 'MAX_UNTIL', - 'MIN_UNTIL', - 'NOT_LITERAL', - 'NEGATE', - 'RANGE', - 'REPEAT', - 'REPEAT_ONE', - 'SUBPATTERN', - 'MIN_REPEAT_ONE', - 'ATOMIC_GROUP', - 'POSSESSIVE_REPEAT', - 'POSSESSIVE_REPEAT_ONE', - - 'GROUPREF_IGNORE', - 'IN_IGNORE', - 'LITERAL_IGNORE', - 'NOT_LITERAL_IGNORE', - - 'GROUPREF_LOC_IGNORE', - 'IN_LOC_IGNORE', - 'LITERAL_LOC_IGNORE', - 'NOT_LITERAL_LOC_IGNORE', - - 'GROUPREF_UNI_IGNORE', - 'IN_UNI_IGNORE', - 'LITERAL_UNI_IGNORE', - 'NOT_LITERAL_UNI_IGNORE', - 'RANGE_UNI_IGNORE', - - # The following opcodes are only occurred in the parser output, - # but not in the compiled code. - 'MIN_REPEAT', 'MAX_REPEAT', -) -del OPCODES[-2:] # remove MIN_REPEAT and MAX_REPEAT - -# positions -ATCODES = _makecodes( - 'AT_BEGINNING', 'AT_BEGINNING_LINE', 'AT_BEGINNING_STRING', - 'AT_BOUNDARY', 'AT_NON_BOUNDARY', - 'AT_END', 'AT_END_LINE', 'AT_END_STRING', - - 'AT_LOC_BOUNDARY', 'AT_LOC_NON_BOUNDARY', - - 'AT_UNI_BOUNDARY', 'AT_UNI_NON_BOUNDARY', -) - -# categories -CHCODES = _makecodes( - 'CATEGORY_DIGIT', 'CATEGORY_NOT_DIGIT', - 'CATEGORY_SPACE', 'CATEGORY_NOT_SPACE', - 'CATEGORY_WORD', 'CATEGORY_NOT_WORD', - 'CATEGORY_LINEBREAK', 'CATEGORY_NOT_LINEBREAK', - - 'CATEGORY_LOC_WORD', 'CATEGORY_LOC_NOT_WORD', - - 'CATEGORY_UNI_DIGIT', 'CATEGORY_UNI_NOT_DIGIT', - 'CATEGORY_UNI_SPACE', 'CATEGORY_UNI_NOT_SPACE', - 'CATEGORY_UNI_WORD', 'CATEGORY_UNI_NOT_WORD', - 'CATEGORY_UNI_LINEBREAK', 'CATEGORY_UNI_NOT_LINEBREAK', -) - - -# replacement operations for "ignore case" mode -OP_IGNORE = { - LITERAL: LITERAL_IGNORE, - NOT_LITERAL: NOT_LITERAL_IGNORE, -} - -OP_LOCALE_IGNORE = { - LITERAL: LITERAL_LOC_IGNORE, - NOT_LITERAL: NOT_LITERAL_LOC_IGNORE, -} - -OP_UNICODE_IGNORE = { - LITERAL: LITERAL_UNI_IGNORE, - NOT_LITERAL: NOT_LITERAL_UNI_IGNORE, -} - -AT_MULTILINE = { - AT_BEGINNING: AT_BEGINNING_LINE, - AT_END: AT_END_LINE -} - -AT_LOCALE = { - AT_BOUNDARY: AT_LOC_BOUNDARY, - AT_NON_BOUNDARY: AT_LOC_NON_BOUNDARY -} - -AT_UNICODE = { - AT_BOUNDARY: AT_UNI_BOUNDARY, - AT_NON_BOUNDARY: AT_UNI_NON_BOUNDARY -} - -CH_LOCALE = { - CATEGORY_DIGIT: CATEGORY_DIGIT, - CATEGORY_NOT_DIGIT: CATEGORY_NOT_DIGIT, - CATEGORY_SPACE: CATEGORY_SPACE, - CATEGORY_NOT_SPACE: CATEGORY_NOT_SPACE, - CATEGORY_WORD: CATEGORY_LOC_WORD, - CATEGORY_NOT_WORD: CATEGORY_LOC_NOT_WORD, - CATEGORY_LINEBREAK: CATEGORY_LINEBREAK, - CATEGORY_NOT_LINEBREAK: CATEGORY_NOT_LINEBREAK -} - -CH_UNICODE = { - CATEGORY_DIGIT: CATEGORY_UNI_DIGIT, - CATEGORY_NOT_DIGIT: CATEGORY_UNI_NOT_DIGIT, - CATEGORY_SPACE: CATEGORY_UNI_SPACE, - CATEGORY_NOT_SPACE: CATEGORY_UNI_NOT_SPACE, - CATEGORY_WORD: CATEGORY_UNI_WORD, - CATEGORY_NOT_WORD: CATEGORY_UNI_NOT_WORD, - CATEGORY_LINEBREAK: CATEGORY_UNI_LINEBREAK, - CATEGORY_NOT_LINEBREAK: CATEGORY_UNI_NOT_LINEBREAK -} - -# flags -SRE_FLAG_TEMPLATE = 1 # template mode (unknown purpose, deprecated) -SRE_FLAG_IGNORECASE = 2 # case insensitive -SRE_FLAG_LOCALE = 4 # honour system locale -SRE_FLAG_MULTILINE = 8 # treat target as multiline string -SRE_FLAG_DOTALL = 16 # treat target as a single string -SRE_FLAG_UNICODE = 32 # use unicode "locale" -SRE_FLAG_VERBOSE = 64 # ignore whitespace and comments -SRE_FLAG_DEBUG = 128 # debugging -SRE_FLAG_ASCII = 256 # use ascii "locale" - -# flags for INFO primitive -SRE_INFO_PREFIX = 1 # has prefix -SRE_INFO_LITERAL = 2 # entire pattern is literal (given by prefix) -SRE_INFO_CHARSET = 4 # pattern starts with character from given set diff --git a/python/Lib/re/_parser.py b/python/Lib/re/_parser.py deleted file mode 100644 index bd4203b..0000000 --- a/python/Lib/re/_parser.py +++ /dev/null @@ -1,1100 +0,0 @@ -# -# Secret Labs' Regular Expression Engine -# -# convert re-style regular expression to sre pattern -# -# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. -# -# See the __init__.py file for information on usage and redistribution. -# - -"""Internal support module for sre""" - -# XXX: show string offset and offending character for all errors - -from ._constants import * - -SPECIAL_CHARS = ".\\[{()*+?^$|" -REPEAT_CHARS = "*+?{" - -DIGITS = frozenset("0123456789") - -OCTDIGITS = frozenset("01234567") -HEXDIGITS = frozenset("0123456789abcdefABCDEF") -ASCIILETTERS = frozenset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - -WHITESPACE = frozenset(" \t\n\r\v\f") - -_REPEATCODES = frozenset({MIN_REPEAT, MAX_REPEAT, POSSESSIVE_REPEAT}) -_UNITCODES = frozenset({ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY}) - -ESCAPES = { - r"\a": (LITERAL, ord("\a")), - r"\b": (LITERAL, ord("\b")), - r"\f": (LITERAL, ord("\f")), - r"\n": (LITERAL, ord("\n")), - r"\r": (LITERAL, ord("\r")), - r"\t": (LITERAL, ord("\t")), - r"\v": (LITERAL, ord("\v")), - r"\\": (LITERAL, ord("\\")) -} - -CATEGORIES = { - r"\A": (AT, AT_BEGINNING_STRING), # start of string - r"\b": (AT, AT_BOUNDARY), - r"\B": (AT, AT_NON_BOUNDARY), - r"\d": (IN, [(CATEGORY, CATEGORY_DIGIT)]), - r"\D": (IN, [(CATEGORY, CATEGORY_NOT_DIGIT)]), - r"\s": (IN, [(CATEGORY, CATEGORY_SPACE)]), - r"\S": (IN, [(CATEGORY, CATEGORY_NOT_SPACE)]), - r"\w": (IN, [(CATEGORY, CATEGORY_WORD)]), - r"\W": (IN, [(CATEGORY, CATEGORY_NOT_WORD)]), - r"\Z": (AT, AT_END_STRING), # end of string -} - -FLAGS = { - # standard flags - "i": SRE_FLAG_IGNORECASE, - "L": SRE_FLAG_LOCALE, - "m": SRE_FLAG_MULTILINE, - "s": SRE_FLAG_DOTALL, - "x": SRE_FLAG_VERBOSE, - # extensions - "a": SRE_FLAG_ASCII, - "t": SRE_FLAG_TEMPLATE, - "u": SRE_FLAG_UNICODE, -} - -TYPE_FLAGS = SRE_FLAG_ASCII | SRE_FLAG_LOCALE | SRE_FLAG_UNICODE -GLOBAL_FLAGS = SRE_FLAG_DEBUG | SRE_FLAG_TEMPLATE - -class State: - # keeps track of state for parsing - def __init__(self): - self.flags = 0 - self.groupdict = {} - self.groupwidths = [None] # group 0 - self.lookbehindgroups = None - self.grouprefpos = {} - @property - def groups(self): - return len(self.groupwidths) - def opengroup(self, name=None): - gid = self.groups - self.groupwidths.append(None) - if self.groups > MAXGROUPS: - raise error("too many groups") - if name is not None: - ogid = self.groupdict.get(name, None) - if ogid is not None: - raise error("redefinition of group name %r as group %d; " - "was group %d" % (name, gid, ogid)) - self.groupdict[name] = gid - return gid - def closegroup(self, gid, p): - self.groupwidths[gid] = p.getwidth() - def checkgroup(self, gid): - return gid < self.groups and self.groupwidths[gid] is not None - - def checklookbehindgroup(self, gid, source): - if self.lookbehindgroups is not None: - if not self.checkgroup(gid): - raise source.error('cannot refer to an open group') - if gid >= self.lookbehindgroups: - raise source.error('cannot refer to group defined in the same ' - 'lookbehind subpattern') - -class SubPattern: - # a subpattern, in intermediate form - def __init__(self, state, data=None): - self.state = state - if data is None: - data = [] - self.data = data - self.width = None - - def dump(self, level=0): - nl = True - seqtypes = (tuple, list) - for op, av in self.data: - print(level*" " + str(op), end='') - if op is IN: - # member sublanguage - print() - for op, a in av: - print((level+1)*" " + str(op), a) - elif op is BRANCH: - print() - for i, a in enumerate(av[1]): - if i: - print(level*" " + "OR") - a.dump(level+1) - elif op is GROUPREF_EXISTS: - condgroup, item_yes, item_no = av - print('', condgroup) - item_yes.dump(level+1) - if item_no: - print(level*" " + "ELSE") - item_no.dump(level+1) - elif isinstance(av, seqtypes): - nl = False - for a in av: - if isinstance(a, SubPattern): - if not nl: - print() - a.dump(level+1) - nl = True - else: - if not nl: - print(' ', end='') - print(a, end='') - nl = False - if not nl: - print() - else: - print('', av) - def __repr__(self): - return repr(self.data) - def __len__(self): - return len(self.data) - def __delitem__(self, index): - del self.data[index] - def __getitem__(self, index): - if isinstance(index, slice): - return SubPattern(self.state, self.data[index]) - return self.data[index] - def __setitem__(self, index, code): - self.data[index] = code - def insert(self, index, code): - self.data.insert(index, code) - def append(self, code): - self.data.append(code) - def getwidth(self): - # determine the width (min, max) for this subpattern - if self.width is not None: - return self.width - lo = hi = 0 - for op, av in self.data: - if op is BRANCH: - i = MAXREPEAT - 1 - j = 0 - for av in av[1]: - l, h = av.getwidth() - i = min(i, l) - j = max(j, h) - lo = lo + i - hi = hi + j - elif op is ATOMIC_GROUP: - i, j = av.getwidth() - lo = lo + i - hi = hi + j - elif op is SUBPATTERN: - i, j = av[-1].getwidth() - lo = lo + i - hi = hi + j - elif op in _REPEATCODES: - i, j = av[2].getwidth() - lo = lo + i * av[0] - hi = hi + j * av[1] - elif op in _UNITCODES: - lo = lo + 1 - hi = hi + 1 - elif op is GROUPREF: - i, j = self.state.groupwidths[av] - lo = lo + i - hi = hi + j - elif op is GROUPREF_EXISTS: - i, j = av[1].getwidth() - if av[2] is not None: - l, h = av[2].getwidth() - i = min(i, l) - j = max(j, h) - else: - i = 0 - lo = lo + i - hi = hi + j - elif op is SUCCESS: - break - self.width = min(lo, MAXREPEAT - 1), min(hi, MAXREPEAT) - return self.width - -class Tokenizer: - def __init__(self, string): - self.istext = isinstance(string, str) - self.string = string - if not self.istext: - string = str(string, 'latin1') - self.decoded_string = string - self.index = 0 - self.next = None - self.__next() - def __next(self): - index = self.index - try: - char = self.decoded_string[index] - except IndexError: - self.next = None - return - if char == "\\": - index += 1 - try: - char += self.decoded_string[index] - except IndexError: - raise error("bad escape (end of pattern)", - self.string, len(self.string) - 1) from None - self.index = index + 1 - self.next = char - def match(self, char): - if char == self.next: - self.__next() - return True - return False - def get(self): - this = self.next - self.__next() - return this - def getwhile(self, n, charset): - result = '' - for _ in range(n): - c = self.next - if c not in charset: - break - result += c - self.__next() - return result - def getuntil(self, terminator, name): - result = '' - while True: - c = self.next - self.__next() - if c is None: - if not result: - raise self.error("missing " + name) - raise self.error("missing %s, unterminated name" % terminator, - len(result)) - if c == terminator: - if not result: - raise self.error("missing " + name, 1) - break - result += c - return result - @property - def pos(self): - return self.index - len(self.next or '') - def tell(self): - return self.index - len(self.next or '') - def seek(self, index): - self.index = index - self.__next() - - def error(self, msg, offset=0): - if not self.istext: - msg = msg.encode('ascii', 'backslashreplace').decode('ascii') - return error(msg, self.string, self.tell() - offset) - - def checkgroupname(self, name, offset, nested): - if not name.isidentifier(): - msg = "bad character in group name %r" % name - raise self.error(msg, len(name) + offset) - if not (self.istext or name.isascii()): - import warnings - warnings.warn( - "bad character in group name %a at position %d" % - (name, self.tell() - len(name) - offset), - DeprecationWarning, stacklevel=nested + 7 - ) - -def _class_escape(source, escape): - # handle escape code inside character class - code = ESCAPES.get(escape) - if code: - return code - code = CATEGORIES.get(escape) - if code and code[0] is IN: - return code - try: - c = escape[1:2] - if c == "x": - # hexadecimal escape (exactly two digits) - escape += source.getwhile(2, HEXDIGITS) - if len(escape) != 4: - raise source.error("incomplete escape %s" % escape, len(escape)) - return LITERAL, int(escape[2:], 16) - elif c == "u" and source.istext: - # unicode escape (exactly four digits) - escape += source.getwhile(4, HEXDIGITS) - if len(escape) != 6: - raise source.error("incomplete escape %s" % escape, len(escape)) - return LITERAL, int(escape[2:], 16) - elif c == "U" and source.istext: - # unicode escape (exactly eight digits) - escape += source.getwhile(8, HEXDIGITS) - if len(escape) != 10: - raise source.error("incomplete escape %s" % escape, len(escape)) - c = int(escape[2:], 16) - chr(c) # raise ValueError for invalid code - return LITERAL, c - elif c == "N" and source.istext: - import unicodedata - # named unicode escape e.g. \N{EM DASH} - if not source.match('{'): - raise source.error("missing {") - charname = source.getuntil('}', 'character name') - try: - c = ord(unicodedata.lookup(charname)) - except (KeyError, TypeError): - raise source.error("undefined character name %r" % charname, - len(charname) + len(r'\N{}')) from None - return LITERAL, c - elif c in OCTDIGITS: - # octal escape (up to three digits) - escape += source.getwhile(2, OCTDIGITS) - c = int(escape[1:], 8) - if c > 0o377: - raise source.error('octal escape value %s outside of ' - 'range 0-0o377' % escape, len(escape)) - return LITERAL, c - elif c in DIGITS: - raise ValueError - if len(escape) == 2: - if c in ASCIILETTERS: - raise source.error('bad escape %s' % escape, len(escape)) - return LITERAL, ord(escape[1]) - except ValueError: - pass - raise source.error("bad escape %s" % escape, len(escape)) - -def _escape(source, escape, state): - # handle escape code in expression - code = CATEGORIES.get(escape) - if code: - return code - code = ESCAPES.get(escape) - if code: - return code - try: - c = escape[1:2] - if c == "x": - # hexadecimal escape - escape += source.getwhile(2, HEXDIGITS) - if len(escape) != 4: - raise source.error("incomplete escape %s" % escape, len(escape)) - return LITERAL, int(escape[2:], 16) - elif c == "u" and source.istext: - # unicode escape (exactly four digits) - escape += source.getwhile(4, HEXDIGITS) - if len(escape) != 6: - raise source.error("incomplete escape %s" % escape, len(escape)) - return LITERAL, int(escape[2:], 16) - elif c == "U" and source.istext: - # unicode escape (exactly eight digits) - escape += source.getwhile(8, HEXDIGITS) - if len(escape) != 10: - raise source.error("incomplete escape %s" % escape, len(escape)) - c = int(escape[2:], 16) - chr(c) # raise ValueError for invalid code - return LITERAL, c - elif c == "N" and source.istext: - import unicodedata - # named unicode escape e.g. \N{EM DASH} - if not source.match('{'): - raise source.error("missing {") - charname = source.getuntil('}', 'character name') - try: - c = ord(unicodedata.lookup(charname)) - except (KeyError, TypeError): - raise source.error("undefined character name %r" % charname, - len(charname) + len(r'\N{}')) from None - return LITERAL, c - elif c == "0": - # octal escape - escape += source.getwhile(2, OCTDIGITS) - return LITERAL, int(escape[1:], 8) - elif c in DIGITS: - # octal escape *or* decimal group reference (sigh) - if source.next in DIGITS: - escape += source.get() - if (escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and - source.next in OCTDIGITS): - # got three octal digits; this is an octal escape - escape += source.get() - c = int(escape[1:], 8) - if c > 0o377: - raise source.error('octal escape value %s outside of ' - 'range 0-0o377' % escape, - len(escape)) - return LITERAL, c - # not an octal escape, so this is a group reference - group = int(escape[1:]) - if group < state.groups: - if not state.checkgroup(group): - raise source.error("cannot refer to an open group", - len(escape)) - state.checklookbehindgroup(group, source) - return GROUPREF, group - raise source.error("invalid group reference %d" % group, len(escape) - 1) - if len(escape) == 2: - if c in ASCIILETTERS: - raise source.error("bad escape %s" % escape, len(escape)) - return LITERAL, ord(escape[1]) - except ValueError: - pass - raise source.error("bad escape %s" % escape, len(escape)) - -def _uniq(items): - return list(dict.fromkeys(items)) - -def _parse_sub(source, state, verbose, nested): - # parse an alternation: a|b|c - - items = [] - itemsappend = items.append - sourcematch = source.match - start = source.tell() - while True: - itemsappend(_parse(source, state, verbose, nested + 1, - not nested and not items)) - if not sourcematch("|"): - break - if not nested: - verbose = state.flags & SRE_FLAG_VERBOSE - - if len(items) == 1: - return items[0] - - subpattern = SubPattern(state) - - # check if all items share a common prefix - while True: - prefix = None - for item in items: - if not item: - break - if prefix is None: - prefix = item[0] - elif item[0] != prefix: - break - else: - # all subitems start with a common "prefix". - # move it out of the branch - for item in items: - del item[0] - subpattern.append(prefix) - continue # check next one - break - - # check if the branch can be replaced by a character set - set = [] - for item in items: - if len(item) != 1: - break - op, av = item[0] - if op is LITERAL: - set.append((op, av)) - elif op is IN and av[0][0] is not NEGATE: - set.extend(av) - else: - break - else: - # we can store this as a character set instead of a - # branch (the compiler may optimize this even more) - subpattern.append((IN, _uniq(set))) - return subpattern - - subpattern.append((BRANCH, (None, items))) - return subpattern - -def _parse(source, state, verbose, nested, first=False): - # parse a simple pattern - subpattern = SubPattern(state) - - # precompute constants into local variables - subpatternappend = subpattern.append - sourceget = source.get - sourcematch = source.match - _len = len - _ord = ord - - while True: - - this = source.next - if this is None: - break # end of pattern - if this in "|)": - break # end of subpattern - sourceget() - - if verbose: - # skip whitespace and comments - if this in WHITESPACE: - continue - if this == "#": - while True: - this = sourceget() - if this is None or this == "\n": - break - continue - - if this[0] == "\\": - code = _escape(source, this, state) - subpatternappend(code) - - elif this not in SPECIAL_CHARS: - subpatternappend((LITERAL, _ord(this))) - - elif this == "[": - here = source.tell() - 1 - # character set - set = [] - setappend = set.append -## if sourcematch(":"): -## pass # handle character classes - if source.next == '[': - import warnings - warnings.warn( - 'Possible nested set at position %d' % source.tell(), - FutureWarning, stacklevel=nested + 6 - ) - negate = sourcematch("^") - # check remaining characters - while True: - this = sourceget() - if this is None: - raise source.error("unterminated character set", - source.tell() - here) - if this == "]" and set: - break - elif this[0] == "\\": - code1 = _class_escape(source, this) - else: - if set and this in '-&~|' and source.next == this: - import warnings - warnings.warn( - 'Possible set %s at position %d' % ( - 'difference' if this == '-' else - 'intersection' if this == '&' else - 'symmetric difference' if this == '~' else - 'union', - source.tell() - 1), - FutureWarning, stacklevel=nested + 6 - ) - code1 = LITERAL, _ord(this) - if sourcematch("-"): - # potential range - that = sourceget() - if that is None: - raise source.error("unterminated character set", - source.tell() - here) - if that == "]": - if code1[0] is IN: - code1 = code1[1][0] - setappend(code1) - setappend((LITERAL, _ord("-"))) - break - if that[0] == "\\": - code2 = _class_escape(source, that) - else: - if that == '-': - import warnings - warnings.warn( - 'Possible set difference at position %d' % ( - source.tell() - 2), - FutureWarning, stacklevel=nested + 6 - ) - code2 = LITERAL, _ord(that) - if code1[0] != LITERAL or code2[0] != LITERAL: - msg = "bad character range %s-%s" % (this, that) - raise source.error(msg, len(this) + 1 + len(that)) - lo = code1[1] - hi = code2[1] - if hi < lo: - msg = "bad character range %s-%s" % (this, that) - raise source.error(msg, len(this) + 1 + len(that)) - setappend((RANGE, (lo, hi))) - else: - if code1[0] is IN: - code1 = code1[1][0] - setappend(code1) - - set = _uniq(set) - # XXX: should move set optimization to compiler! - if _len(set) == 1 and set[0][0] is LITERAL: - # optimization - if negate: - subpatternappend((NOT_LITERAL, set[0][1])) - else: - subpatternappend(set[0]) - else: - if negate: - set.insert(0, (NEGATE, None)) - # charmap optimization can't be added here because - # global flags still are not known - subpatternappend((IN, set)) - - elif this in REPEAT_CHARS: - # repeat previous item - here = source.tell() - if this == "?": - min, max = 0, 1 - elif this == "*": - min, max = 0, MAXREPEAT - - elif this == "+": - min, max = 1, MAXREPEAT - elif this == "{": - if source.next == "}": - subpatternappend((LITERAL, _ord(this))) - continue - - min, max = 0, MAXREPEAT - lo = hi = "" - while source.next in DIGITS: - lo += sourceget() - if sourcematch(","): - while source.next in DIGITS: - hi += sourceget() - else: - hi = lo - if not sourcematch("}"): - subpatternappend((LITERAL, _ord(this))) - source.seek(here) - continue - - if lo: - min = int(lo) - if min >= MAXREPEAT: - raise OverflowError("the repetition number is too large") - if hi: - max = int(hi) - if max >= MAXREPEAT: - raise OverflowError("the repetition number is too large") - if max < min: - raise source.error("min repeat greater than max repeat", - source.tell() - here) - else: - raise AssertionError("unsupported quantifier %r" % (char,)) - # figure out which item to repeat - if subpattern: - item = subpattern[-1:] - else: - item = None - if not item or item[0][0] is AT: - raise source.error("nothing to repeat", - source.tell() - here + len(this)) - if item[0][0] in _REPEATCODES: - raise source.error("multiple repeat", - source.tell() - here + len(this)) - if item[0][0] is SUBPATTERN: - group, add_flags, del_flags, p = item[0][1] - if group is None and not add_flags and not del_flags: - item = p - if sourcematch("?"): - # Non-Greedy Match - subpattern[-1] = (MIN_REPEAT, (min, max, item)) - elif sourcematch("+"): - # Possessive Match (Always Greedy) - subpattern[-1] = (POSSESSIVE_REPEAT, (min, max, item)) - else: - # Greedy Match - subpattern[-1] = (MAX_REPEAT, (min, max, item)) - - elif this == ".": - subpatternappend((ANY, None)) - - elif this == "(": - start = source.tell() - 1 - capture = True - atomic = False - name = None - add_flags = 0 - del_flags = 0 - if sourcematch("?"): - # options - char = sourceget() - if char is None: - raise source.error("unexpected end of pattern") - if char == "P": - # python extensions - if sourcematch("<"): - # named group: skip forward to end of name - name = source.getuntil(">", "group name") - source.checkgroupname(name, 1, nested) - elif sourcematch("="): - # named backreference - name = source.getuntil(")", "group name") - source.checkgroupname(name, 1, nested) - gid = state.groupdict.get(name) - if gid is None: - msg = "unknown group name %r" % name - raise source.error(msg, len(name) + 1) - if not state.checkgroup(gid): - raise source.error("cannot refer to an open group", - len(name) + 1) - state.checklookbehindgroup(gid, source) - subpatternappend((GROUPREF, gid)) - continue - - else: - char = sourceget() - if char is None: - raise source.error("unexpected end of pattern") - raise source.error("unknown extension ?P" + char, - len(char) + 2) - elif char == ":": - # non-capturing group - capture = False - elif char == "#": - # comment - while True: - if source.next is None: - raise source.error("missing ), unterminated comment", - source.tell() - start) - if sourceget() == ")": - break - continue - - elif char in "=!<": - # lookahead assertions - dir = 1 - if char == "<": - char = sourceget() - if char is None: - raise source.error("unexpected end of pattern") - if char not in "=!": - raise source.error("unknown extension ?<" + char, - len(char) + 2) - dir = -1 # lookbehind - lookbehindgroups = state.lookbehindgroups - if lookbehindgroups is None: - state.lookbehindgroups = state.groups - p = _parse_sub(source, state, verbose, nested + 1) - if dir < 0: - if lookbehindgroups is None: - state.lookbehindgroups = None - if not sourcematch(")"): - raise source.error("missing ), unterminated subpattern", - source.tell() - start) - if char == "=": - subpatternappend((ASSERT, (dir, p))) - else: - subpatternappend((ASSERT_NOT, (dir, p))) - continue - - elif char == "(": - # conditional backreference group - condname = source.getuntil(")", "group name") - if condname.isidentifier(): - source.checkgroupname(condname, 1, nested) - condgroup = state.groupdict.get(condname) - if condgroup is None: - msg = "unknown group name %r" % condname - raise source.error(msg, len(condname) + 1) - else: - try: - condgroup = int(condname) - if condgroup < 0: - raise ValueError - except ValueError: - msg = "bad character in group name %r" % condname - raise source.error(msg, len(condname) + 1) from None - if not condgroup: - raise source.error("bad group number", - len(condname) + 1) - if condgroup >= MAXGROUPS: - msg = "invalid group reference %d" % condgroup - raise source.error(msg, len(condname) + 1) - if condgroup not in state.grouprefpos: - state.grouprefpos[condgroup] = ( - source.tell() - len(condname) - 1 - ) - if not (condname.isdecimal() and condname.isascii()): - import warnings - warnings.warn( - "bad character in group name %s at position %d" % - (repr(condname) if source.istext else ascii(condname), - source.tell() - len(condname) - 1), - DeprecationWarning, stacklevel=nested + 6 - ) - state.checklookbehindgroup(condgroup, source) - item_yes = _parse(source, state, verbose, nested + 1) - if source.match("|"): - item_no = _parse(source, state, verbose, nested + 1) - if source.next == "|": - raise source.error("conditional backref with more than two branches") - else: - item_no = None - if not source.match(")"): - raise source.error("missing ), unterminated subpattern", - source.tell() - start) - subpatternappend((GROUPREF_EXISTS, (condgroup, item_yes, item_no))) - continue - - elif char == ">": - # non-capturing, atomic group - capture = False - atomic = True - elif char in FLAGS or char == "-": - # flags - flags = _parse_flags(source, state, char) - if flags is None: # global flags - if not first or subpattern: - raise source.error('global flags not at the start ' - 'of the expression', - source.tell() - start) - verbose = state.flags & SRE_FLAG_VERBOSE - continue - - add_flags, del_flags = flags - capture = False - else: - raise source.error("unknown extension ?" + char, - len(char) + 1) - - # parse group contents - if capture: - try: - group = state.opengroup(name) - except error as err: - raise source.error(err.msg, len(name) + 1) from None - else: - group = None - sub_verbose = ((verbose or (add_flags & SRE_FLAG_VERBOSE)) and - not (del_flags & SRE_FLAG_VERBOSE)) - p = _parse_sub(source, state, sub_verbose, nested + 1) - if not source.match(")"): - raise source.error("missing ), unterminated subpattern", - source.tell() - start) - if group is not None: - state.closegroup(group, p) - if atomic: - assert group is None - subpatternappend((ATOMIC_GROUP, p)) - else: - subpatternappend((SUBPATTERN, (group, add_flags, del_flags, p))) - - elif this == "^": - subpatternappend((AT, AT_BEGINNING)) - - elif this == "$": - subpatternappend((AT, AT_END)) - - else: - raise AssertionError("unsupported special character %r" % (char,)) - - # unpack non-capturing groups - for i in range(len(subpattern))[::-1]: - op, av = subpattern[i] - if op is SUBPATTERN: - group, add_flags, del_flags, p = av - if group is None and not add_flags and not del_flags: - subpattern[i: i+1] = p - - return subpattern - -def _parse_flags(source, state, char): - sourceget = source.get - add_flags = 0 - del_flags = 0 - if char != "-": - while True: - flag = FLAGS[char] - if source.istext: - if char == 'L': - msg = "bad inline flags: cannot use 'L' flag with a str pattern" - raise source.error(msg) - else: - if char == 'u': - msg = "bad inline flags: cannot use 'u' flag with a bytes pattern" - raise source.error(msg) - add_flags |= flag - if (flag & TYPE_FLAGS) and (add_flags & TYPE_FLAGS) != flag: - msg = "bad inline flags: flags 'a', 'u' and 'L' are incompatible" - raise source.error(msg) - char = sourceget() - if char is None: - raise source.error("missing -, : or )") - if char in ")-:": - break - if char not in FLAGS: - msg = "unknown flag" if char.isalpha() else "missing -, : or )" - raise source.error(msg, len(char)) - if char == ")": - state.flags |= add_flags - return None - if add_flags & GLOBAL_FLAGS: - raise source.error("bad inline flags: cannot turn on global flag", 1) - if char == "-": - char = sourceget() - if char is None: - raise source.error("missing flag") - if char not in FLAGS: - msg = "unknown flag" if char.isalpha() else "missing flag" - raise source.error(msg, len(char)) - while True: - flag = FLAGS[char] - if flag & TYPE_FLAGS: - msg = "bad inline flags: cannot turn off flags 'a', 'u' and 'L'" - raise source.error(msg) - del_flags |= flag - char = sourceget() - if char is None: - raise source.error("missing :") - if char == ":": - break - if char not in FLAGS: - msg = "unknown flag" if char.isalpha() else "missing :" - raise source.error(msg, len(char)) - assert char == ":" - if del_flags & GLOBAL_FLAGS: - raise source.error("bad inline flags: cannot turn off global flag", 1) - if add_flags & del_flags: - raise source.error("bad inline flags: flag turned on and off", 1) - return add_flags, del_flags - -def fix_flags(src, flags): - # Check and fix flags according to the type of pattern (str or bytes) - if isinstance(src, str): - if flags & SRE_FLAG_LOCALE: - raise ValueError("cannot use LOCALE flag with a str pattern") - if not flags & SRE_FLAG_ASCII: - flags |= SRE_FLAG_UNICODE - elif flags & SRE_FLAG_UNICODE: - raise ValueError("ASCII and UNICODE flags are incompatible") - else: - if flags & SRE_FLAG_UNICODE: - raise ValueError("cannot use UNICODE flag with a bytes pattern") - if flags & SRE_FLAG_LOCALE and flags & SRE_FLAG_ASCII: - raise ValueError("ASCII and LOCALE flags are incompatible") - return flags - -def parse(str, flags=0, state=None): - # parse 're' pattern into list of (opcode, argument) tuples - - source = Tokenizer(str) - - if state is None: - state = State() - state.flags = flags - state.str = str - - p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0) - p.state.flags = fix_flags(str, p.state.flags) - - if source.next is not None: - assert source.next == ")" - raise source.error("unbalanced parenthesis") - - for g in p.state.grouprefpos: - if g >= p.state.groups: - msg = "invalid group reference %d" % g - raise error(msg, str, p.state.grouprefpos[g]) - - if flags & SRE_FLAG_DEBUG: - p.dump() - - return p - -def parse_template(source, state): - # parse 're' replacement string into list of literals and - # group references - s = Tokenizer(source) - sget = s.get - groups = [] - literals = [] - literal = [] - lappend = literal.append - def addgroup(index, pos): - if index > state.groups: - raise s.error("invalid group reference %d" % index, pos) - if literal: - literals.append(''.join(literal)) - del literal[:] - groups.append((len(literals), index)) - literals.append(None) - groupindex = state.groupindex - while True: - this = sget() - if this is None: - break # end of replacement string - if this[0] == "\\": - # group - c = this[1] - if c == "g": - if not s.match("<"): - raise s.error("missing <") - name = s.getuntil(">", "group name") - if name.isidentifier(): - s.checkgroupname(name, 1, -1) - try: - index = groupindex[name] - except KeyError: - raise IndexError("unknown group name %r" % name) from None - else: - try: - index = int(name) - if index < 0: - raise ValueError - except ValueError: - raise s.error("bad character in group name %r" % name, - len(name) + 1) from None - if index >= MAXGROUPS: - raise s.error("invalid group reference %d" % index, - len(name) + 1) - if not (name.isdecimal() and name.isascii()): - import warnings - warnings.warn( - "bad character in group name %s at position %d" % - (repr(name) if s.istext else ascii(name), - s.tell() - len(name) - 1), - DeprecationWarning, stacklevel=5 - ) - addgroup(index, len(name) + 1) - elif c == "0": - if s.next in OCTDIGITS: - this += sget() - if s.next in OCTDIGITS: - this += sget() - lappend(chr(int(this[1:], 8) & 0xff)) - elif c in DIGITS: - isoctal = False - if s.next in DIGITS: - this += sget() - if (c in OCTDIGITS and this[2] in OCTDIGITS and - s.next in OCTDIGITS): - this += sget() - isoctal = True - c = int(this[1:], 8) - if c > 0o377: - raise s.error('octal escape value %s outside of ' - 'range 0-0o377' % this, len(this)) - lappend(chr(c)) - if not isoctal: - addgroup(int(this[1:]), len(this) - 1) - else: - try: - this = chr(ESCAPES[this][1]) - except KeyError: - if c in ASCIILETTERS: - raise s.error('bad escape %s' % this, len(this)) from None - lappend(this) - else: - lappend(this) - if literal: - literals.append(''.join(literal)) - if not isinstance(source, str): - # The tokenizer implicitly decodes bytes objects as latin-1, we must - # therefore re-encode the final representation. - literals = [None if s is None else s.encode('latin-1') for s in literals] - return groups, literals - -def expand_template(template, match): - g = match.group - empty = match.string[:0] - groups, literals = template - literals = literals[:] - try: - for index, group in groups: - literals[index] = g(group) or empty - except IndexError: - raise error("invalid group reference %d" % index) from None - return empty.join(literals) diff --git a/python/Lib/reprlib.py b/python/Lib/reprlib.py deleted file mode 100644 index 1a084b0..0000000 --- a/python/Lib/reprlib.py +++ /dev/null @@ -1,167 +0,0 @@ -"""Redo the builtin repr() (representation) but with limits on most sizes.""" - -__all__ = ["Repr", "repr", "recursive_repr"] - -import builtins -from itertools import islice -from _thread import get_ident - -def recursive_repr(fillvalue='...'): - 'Decorator to make a repr function return fillvalue for a recursive call' - - def decorating_function(user_function): - repr_running = set() - - def wrapper(self): - key = id(self), get_ident() - if key in repr_running: - return fillvalue - repr_running.add(key) - try: - result = user_function(self) - finally: - repr_running.discard(key) - return result - - # Can't use functools.wraps() here because of bootstrap issues - wrapper.__module__ = getattr(user_function, '__module__') - wrapper.__doc__ = getattr(user_function, '__doc__') - wrapper.__name__ = getattr(user_function, '__name__') - wrapper.__qualname__ = getattr(user_function, '__qualname__') - wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) - return wrapper - - return decorating_function - -class Repr: - - def __init__(self): - self.fillvalue = '...' - self.maxlevel = 6 - self.maxtuple = 6 - self.maxlist = 6 - self.maxarray = 5 - self.maxdict = 4 - self.maxset = 6 - self.maxfrozenset = 6 - self.maxdeque = 6 - self.maxstring = 30 - self.maxlong = 40 - self.maxother = 30 - - def repr(self, x): - return self.repr1(x, self.maxlevel) - - def repr1(self, x, level): - typename = type(x).__name__ - if ' ' in typename: - parts = typename.split() - typename = '_'.join(parts) - if hasattr(self, 'repr_' + typename): - return getattr(self, 'repr_' + typename)(x, level) - else: - return self.repr_instance(x, level) - - def _repr_iterable(self, x, level, left, right, maxiter, trail=''): - n = len(x) - if level <= 0 and n: - s = self.fillvalue - else: - newlevel = level - 1 - repr1 = self.repr1 - pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)] - if n > maxiter: - pieces.append(self.fillvalue) - s = ', '.join(pieces) - if n == 1 and trail: - right = trail + right - return '%s%s%s' % (left, s, right) - - def repr_tuple(self, x, level): - return self._repr_iterable(x, level, '(', ')', self.maxtuple, ',') - - def repr_list(self, x, level): - return self._repr_iterable(x, level, '[', ']', self.maxlist) - - def repr_array(self, x, level): - if not x: - return "array('%s')" % x.typecode - header = "array('%s', [" % x.typecode - return self._repr_iterable(x, level, header, '])', self.maxarray) - - def repr_set(self, x, level): - if not x: - return 'set()' - x = _possibly_sorted(x) - return self._repr_iterable(x, level, '{', '}', self.maxset) - - def repr_frozenset(self, x, level): - if not x: - return 'frozenset()' - x = _possibly_sorted(x) - return self._repr_iterable(x, level, 'frozenset({', '})', - self.maxfrozenset) - - def repr_deque(self, x, level): - return self._repr_iterable(x, level, 'deque([', '])', self.maxdeque) - - def repr_dict(self, x, level): - n = len(x) - if n == 0: - return '{}' - if level <= 0: - return '{' + self.fillvalue + '}' - newlevel = level - 1 - repr1 = self.repr1 - pieces = [] - for key in islice(_possibly_sorted(x), self.maxdict): - keyrepr = repr1(key, newlevel) - valrepr = repr1(x[key], newlevel) - pieces.append('%s: %s' % (keyrepr, valrepr)) - if n > self.maxdict: - pieces.append(self.fillvalue) - s = ', '.join(pieces) - return '{%s}' % (s,) - - def repr_str(self, x, level): - s = builtins.repr(x[:self.maxstring]) - if len(s) > self.maxstring: - i = max(0, (self.maxstring-3)//2) - j = max(0, self.maxstring-3-i) - s = builtins.repr(x[:i] + x[len(x)-j:]) - s = s[:i] + self.fillvalue + s[len(s)-j:] - return s - - def repr_int(self, x, level): - s = builtins.repr(x) # XXX Hope this isn't too slow... - if len(s) > self.maxlong: - i = max(0, (self.maxlong-3)//2) - j = max(0, self.maxlong-3-i) - s = s[:i] + self.fillvalue + s[len(s)-j:] - return s - - def repr_instance(self, x, level): - try: - s = builtins.repr(x) - # Bugs in x.__repr__() can cause arbitrary - # exceptions -- then make up something - except Exception: - return '<%s instance at %#x>' % (x.__class__.__name__, id(x)) - if len(s) > self.maxother: - i = max(0, (self.maxother-3)//2) - j = max(0, self.maxother-3-i) - s = s[:i] + self.fillvalue + s[len(s)-j:] - return s - - -def _possibly_sorted(x): - # Since not all sequences of items can be sorted and comparison - # functions may raise arbitrary exceptions, return an unsorted - # sequence in that case. - try: - return sorted(x) - except Exception: - return list(x) - -aRepr = Repr() -repr = aRepr.repr diff --git a/python/Lib/rlcompleter.py b/python/Lib/rlcompleter.py deleted file mode 100644 index 814a3b7..0000000 --- a/python/Lib/rlcompleter.py +++ /dev/null @@ -1,219 +0,0 @@ -"""Word completion for GNU readline. - -The completer completes keywords, built-ins and globals in a selectable -namespace (which defaults to __main__); when completing NAME.NAME..., it -evaluates (!) the expression up to the last dot and completes its attributes. - -It's very cool to do "import sys" type "sys.", hit the completion key (twice), -and see the list of names defined by the sys module! - -Tip: to use the tab key as the completion key, call - - readline.parse_and_bind("tab: complete") - -Notes: - -- Exceptions raised by the completer function are *ignored* (and generally cause - the completion to fail). This is a feature -- since readline sets the tty - device in raw (or cbreak) mode, printing a traceback wouldn't work well - without some complicated hoopla to save, reset and restore the tty state. - -- The evaluation of the NAME.NAME... form may cause arbitrary application - defined code to be executed if an object with a __getattr__ hook is found. - Since it is the responsibility of the application (or the user) to enable this - feature, I consider this an acceptable risk. More complicated expressions - (e.g. function calls or indexing operations) are *not* evaluated. - -- When the original stdin is not a tty device, GNU readline is never - used, and this module (and the readline module) are silently inactive. - -""" - -import atexit -import builtins -import inspect -import keyword -import re -import __main__ - -__all__ = ["Completer"] - -class Completer: - def __init__(self, namespace = None): - """Create a new completer for the command line. - - Completer([namespace]) -> completer instance. - - If unspecified, the default namespace where completions are performed - is __main__ (technically, __main__.__dict__). Namespaces should be - given as dictionaries. - - Completer instances should be used as the completion mechanism of - readline via the set_completer() call: - - readline.set_completer(Completer(my_namespace).complete) - """ - - if namespace and not isinstance(namespace, dict): - raise TypeError('namespace must be a dictionary') - - # Don't bind to namespace quite yet, but flag whether the user wants a - # specific namespace or to use __main__.__dict__. This will allow us - # to bind to __main__.__dict__ at completion time, not now. - if namespace is None: - self.use_main_ns = 1 - else: - self.use_main_ns = 0 - self.namespace = namespace - - def complete(self, text, state): - """Return the next possible completion for 'text'. - - This is called successively with state == 0, 1, 2, ... until it - returns None. The completion should begin with 'text'. - - """ - if self.use_main_ns: - self.namespace = __main__.__dict__ - - if not text.strip(): - if state == 0: - if _readline_available: - readline.insert_text('\t') - readline.redisplay() - return '' - else: - return '\t' - else: - return None - - if state == 0: - if "." in text: - self.matches = self.attr_matches(text) - else: - self.matches = self.global_matches(text) - try: - return self.matches[state] - except IndexError: - return None - - def _callable_postfix(self, val, word): - if callable(val): - word += "(" - try: - if not inspect.signature(val).parameters: - word += ")" - except ValueError: - pass - - return word - - def global_matches(self, text): - """Compute matches when text is a simple name. - - Return a list of all keywords, built-in functions and names currently - defined in self.namespace that match. - - """ - matches = [] - seen = {"__builtins__"} - n = len(text) - for word in keyword.kwlist + keyword.softkwlist: - if word[:n] == text: - seen.add(word) - if word in {'finally', 'try'}: - word = word + ':' - elif word not in {'False', 'None', 'True', - 'break', 'continue', 'pass', - 'else', '_'}: - word = word + ' ' - matches.append(word) - for nspace in [self.namespace, builtins.__dict__]: - for word, val in nspace.items(): - if word[:n] == text and word not in seen: - seen.add(word) - matches.append(self._callable_postfix(val, word)) - return matches - - def attr_matches(self, text): - """Compute matches when text contains a dot. - - Assuming the text is of the form NAME.NAME....[NAME], and is - evaluable in self.namespace, it will be evaluated and its attributes - (as revealed by dir()) are used as possible completions. (For class - instances, class members are also considered.) - - WARNING: this can still invoke arbitrary C code, if an object - with a __getattr__ hook is evaluated. - - """ - m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text) - if not m: - return [] - expr, attr = m.group(1, 3) - try: - thisobject = eval(expr, self.namespace) - except Exception: - return [] - - # get the content of the object, except __builtins__ - words = set(dir(thisobject)) - words.discard("__builtins__") - - if hasattr(thisobject, '__class__'): - words.add('__class__') - words.update(get_class_members(thisobject.__class__)) - matches = [] - n = len(attr) - if attr == '': - noprefix = '_' - elif attr == '_': - noprefix = '__' - else: - noprefix = None - while True: - for word in words: - if (word[:n] == attr and - not (noprefix and word[:n+1] == noprefix)): - match = "%s.%s" % (expr, word) - if isinstance(getattr(type(thisobject), word, None), - property): - # bpo-44752: thisobject.word is a method decorated by - # `@property`. What follows applies a postfix if - # thisobject.word is callable, but know we know that - # this is not callable (because it is a property). - # Also, getattr(thisobject, word) will evaluate the - # property method, which is not desirable. - matches.append(match) - continue - if (value := getattr(thisobject, word, None)) is not None: - matches.append(self._callable_postfix(value, match)) - else: - matches.append(match) - if matches or not noprefix: - break - if noprefix == '_': - noprefix = '__' - else: - noprefix = None - matches.sort() - return matches - -def get_class_members(klass): - ret = dir(klass) - if hasattr(klass,'__bases__'): - for base in klass.__bases__: - ret = ret + get_class_members(base) - return ret - -try: - import readline -except ImportError: - _readline_available = False -else: - readline.set_completer(Completer().complete) - # Release references early at shutdown (the readline module's - # contents are quasi-immortal, and the completer function holds a - # reference to globals). - atexit.register(lambda: readline.set_completer(None)) - _readline_available = True diff --git a/python/Lib/runpy.py b/python/Lib/runpy.py deleted file mode 100644 index fcd8457..0000000 --- a/python/Lib/runpy.py +++ /dev/null @@ -1,323 +0,0 @@ -"""runpy.py - locating and running Python code using the module namespace - -Provides support for locating and running Python scripts using the Python -module namespace instead of the native filesystem. - -This allows Python code to play nicely with non-filesystem based PEP 302 -importers when locating support scripts as well as when importing modules. -""" -# Written by Nick Coghlan -# to implement PEP 338 (Executing Modules as Scripts) - - -import sys -import importlib.machinery # importlib first so we can test #15386 via -m -import importlib.util -import io -import os - -__all__ = [ - "run_module", "run_path", -] - -# avoid 'import types' just for ModuleType -ModuleType = type(sys) - -class _TempModule(object): - """Temporarily replace a module in sys.modules with an empty namespace""" - def __init__(self, mod_name): - self.mod_name = mod_name - self.module = ModuleType(mod_name) - self._saved_module = [] - - def __enter__(self): - mod_name = self.mod_name - try: - self._saved_module.append(sys.modules[mod_name]) - except KeyError: - pass - sys.modules[mod_name] = self.module - return self - - def __exit__(self, *args): - if self._saved_module: - sys.modules[self.mod_name] = self._saved_module[0] - else: - del sys.modules[self.mod_name] - self._saved_module = [] - -class _ModifiedArgv0(object): - def __init__(self, value): - self.value = value - self._saved_value = self._sentinel = object() - - def __enter__(self): - if self._saved_value is not self._sentinel: - raise RuntimeError("Already preserving saved value") - self._saved_value = sys.argv[0] - sys.argv[0] = self.value - - def __exit__(self, *args): - self.value = self._sentinel - sys.argv[0] = self._saved_value - -# TODO: Replace these helpers with importlib._bootstrap_external functions. -def _run_code(code, run_globals, init_globals=None, - mod_name=None, mod_spec=None, - pkg_name=None, script_name=None): - """Helper to run code in nominated namespace""" - if init_globals is not None: - run_globals.update(init_globals) - if mod_spec is None: - loader = None - fname = script_name - cached = None - else: - loader = mod_spec.loader - fname = mod_spec.origin - cached = mod_spec.cached - if pkg_name is None: - pkg_name = mod_spec.parent - run_globals.update(__name__ = mod_name, - __file__ = fname, - __cached__ = cached, - __doc__ = None, - __loader__ = loader, - __package__ = pkg_name, - __spec__ = mod_spec) - exec(code, run_globals) - return run_globals - -def _run_module_code(code, init_globals=None, - mod_name=None, mod_spec=None, - pkg_name=None, script_name=None): - """Helper to run code in new namespace with sys modified""" - fname = script_name if mod_spec is None else mod_spec.origin - with _TempModule(mod_name) as temp_module, _ModifiedArgv0(fname): - mod_globals = temp_module.module.__dict__ - _run_code(code, mod_globals, init_globals, - mod_name, mod_spec, pkg_name, script_name) - # Copy the globals of the temporary module, as they - # may be cleared when the temporary module goes away - return mod_globals.copy() - -# Helper to get the full name, spec and code for a module -def _get_module_details(mod_name, error=ImportError): - if mod_name.startswith("."): - raise error("Relative module names not supported") - pkg_name, _, _ = mod_name.rpartition(".") - if pkg_name: - # Try importing the parent to avoid catching initialization errors - try: - __import__(pkg_name) - except ImportError as e: - # If the parent or higher ancestor package is missing, let the - # error be raised by find_spec() below and then be caught. But do - # not allow other errors to be caught. - if e.name is None or (e.name != pkg_name and - not pkg_name.startswith(e.name + ".")): - raise - # Warn if the module has already been imported under its normal name - existing = sys.modules.get(mod_name) - if existing is not None and not hasattr(existing, "__path__"): - from warnings import warn - msg = "{mod_name!r} found in sys.modules after import of " \ - "package {pkg_name!r}, but prior to execution of " \ - "{mod_name!r}; this may result in unpredictable " \ - "behaviour".format(mod_name=mod_name, pkg_name=pkg_name) - warn(RuntimeWarning(msg)) - - try: - spec = importlib.util.find_spec(mod_name) - except (ImportError, AttributeError, TypeError, ValueError) as ex: - # This hack fixes an impedance mismatch between pkgutil and - # importlib, where the latter raises other errors for cases where - # pkgutil previously raised ImportError - msg = "Error while finding module specification for {!r} ({}: {})" - if mod_name.endswith(".py"): - msg += (f". Try using '{mod_name[:-3]}' instead of " - f"'{mod_name}' as the module name.") - raise error(msg.format(mod_name, type(ex).__name__, ex)) from ex - if spec is None: - raise error("No module named %s" % mod_name) - if spec.submodule_search_locations is not None: - if mod_name == "__main__" or mod_name.endswith(".__main__"): - raise error("Cannot use package as __main__ module") - try: - pkg_main_name = mod_name + ".__main__" - return _get_module_details(pkg_main_name, error) - except error as e: - if mod_name not in sys.modules: - raise # No module loaded; being a package is irrelevant - raise error(("%s; %r is a package and cannot " + - "be directly executed") %(e, mod_name)) - loader = spec.loader - if loader is None: - raise error("%r is a namespace package and cannot be executed" - % mod_name) - try: - code = loader.get_code(mod_name) - except ImportError as e: - raise error(format(e)) from e - if code is None: - raise error("No code object available for %s" % mod_name) - return mod_name, spec, code - -class _Error(Exception): - """Error that _run_module_as_main() should report without a traceback""" - -# XXX ncoghlan: Should this be documented and made public? -# (Current thoughts: don't repeat the mistake that lead to its -# creation when run_module() no longer met the needs of -# mainmodule.c, but couldn't be changed because it was public) -def _run_module_as_main(mod_name, alter_argv=True): - """Runs the designated module in the __main__ namespace - - Note that the executed module will have full access to the - __main__ namespace. If this is not desirable, the run_module() - function should be used to run the module code in a fresh namespace. - - At the very least, these variables in __main__ will be overwritten: - __name__ - __file__ - __cached__ - __loader__ - __package__ - """ - try: - if alter_argv or mod_name != "__main__": # i.e. -m switch - mod_name, mod_spec, code = _get_module_details(mod_name, _Error) - else: # i.e. directory or zipfile execution - mod_name, mod_spec, code = _get_main_module_details(_Error) - except _Error as exc: - msg = "%s: %s" % (sys.executable, exc) - sys.exit(msg) - main_globals = sys.modules["__main__"].__dict__ - if alter_argv: - sys.argv[0] = mod_spec.origin - return _run_code(code, main_globals, None, - "__main__", mod_spec) - -def run_module(mod_name, init_globals=None, - run_name=None, alter_sys=False): - """Execute a module's code without importing it. - - mod_name -- an absolute module name or package name. - - Optional arguments: - init_globals -- dictionary used to pre-populate the module’s - globals dictionary before the code is executed. - - run_name -- if not None, this will be used for setting __name__; - otherwise, __name__ will be set to mod_name + '__main__' if the - named module is a package and to just mod_name otherwise. - - alter_sys -- if True, sys.argv[0] is updated with the value of - __file__ and sys.modules[__name__] is updated with a temporary - module object for the module being executed. Both are - restored to their original values before the function returns. - - Returns the resulting module globals dictionary. - """ - mod_name, mod_spec, code = _get_module_details(mod_name) - if run_name is None: - run_name = mod_name - if alter_sys: - return _run_module_code(code, init_globals, run_name, mod_spec) - else: - # Leave the sys module alone - return _run_code(code, {}, init_globals, run_name, mod_spec) - -def _get_main_module_details(error=ImportError): - # Helper that gives a nicer error message when attempting to - # execute a zipfile or directory by invoking __main__.py - # Also moves the standard __main__ out of the way so that the - # preexisting __loader__ entry doesn't cause issues - main_name = "__main__" - saved_main = sys.modules[main_name] - del sys.modules[main_name] - try: - return _get_module_details(main_name) - except ImportError as exc: - if main_name in str(exc): - raise error("can't find %r module in %r" % - (main_name, sys.path[0])) from exc - raise - finally: - sys.modules[main_name] = saved_main - - -def _get_code_from_file(run_name, fname): - # Check for a compiled file first - from pkgutil import read_code - decoded_path = os.path.abspath(os.fsdecode(fname)) - with io.open_code(decoded_path) as f: - code = read_code(f) - if code is None: - # That didn't work, so try it as normal source code - with io.open_code(decoded_path) as f: - code = compile(f.read(), fname, 'exec') - return code, fname - -def run_path(path_name, init_globals=None, run_name=None): - """Execute code located at the specified filesystem location. - - path_name -- filesystem location of a Python script, zipfile, - or directory containing a top level __main__.py script. - - Optional arguments: - init_globals -- dictionary used to pre-populate the module’s - globals dictionary before the code is executed. - - run_name -- if not None, this will be used to set __name__; - otherwise, '' will be used for __name__. - - Returns the resulting module globals dictionary. - """ - if run_name is None: - run_name = "" - pkg_name = run_name.rpartition(".")[0] - from pkgutil import get_importer - importer = get_importer(path_name) - # Trying to avoid importing imp so as to not consume the deprecation warning. - is_NullImporter = False - if type(importer).__module__ == 'imp': - if type(importer).__name__ == 'NullImporter': - is_NullImporter = True - if isinstance(importer, type(None)) or is_NullImporter: - # Not a valid sys.path entry, so run the code directly - # execfile() doesn't help as we want to allow compiled files - code, fname = _get_code_from_file(run_name, path_name) - return _run_module_code(code, init_globals, run_name, - pkg_name=pkg_name, script_name=fname) - else: - # Finder is defined for path, so add it to - # the start of sys.path - sys.path.insert(0, path_name) - try: - # Here's where things are a little different from the run_module - # case. There, we only had to replace the module in sys while the - # code was running and doing so was somewhat optional. Here, we - # have no choice and we have to remove it even while we read the - # code. If we don't do this, a __loader__ attribute in the - # existing __main__ module may prevent location of the new module. - mod_name, mod_spec, code = _get_main_module_details() - with _TempModule(run_name) as temp_module, \ - _ModifiedArgv0(path_name): - mod_globals = temp_module.module.__dict__ - return _run_code(code, mod_globals, init_globals, - run_name, mod_spec, pkg_name).copy() - finally: - try: - sys.path.remove(path_name) - except ValueError: - pass - - -if __name__ == "__main__": - # Run the module specified as the next command line argument - if len(sys.argv) < 2: - print("No module specified for execution", file=sys.stderr) - else: - del sys.argv[0] # Make the requested module sys.argv[0] - _run_module_as_main(sys.argv[0]) diff --git a/python/Lib/sched.py b/python/Lib/sched.py deleted file mode 100644 index 6a46ffd..0000000 --- a/python/Lib/sched.py +++ /dev/null @@ -1,167 +0,0 @@ -"""A generally useful event scheduler class. - -Each instance of this class manages its own queue. -No multi-threading is implied; you are supposed to hack that -yourself, or use a single instance per application. - -Each instance is parametrized with two functions, one that is -supposed to return the current time, one that is supposed to -implement a delay. You can implement real-time scheduling by -substituting time and sleep from built-in module time, or you can -implement simulated time by writing your own functions. This can -also be used to integrate scheduling with STDWIN events; the delay -function is allowed to modify the queue. Time can be expressed as -integers or floating point numbers, as long as it is consistent. - -Events are specified by tuples (time, priority, action, argument, kwargs). -As in UNIX, lower priority numbers mean higher priority; in this -way the queue can be maintained as a priority queue. Execution of the -event means calling the action function, passing it the argument -sequence in "argument" (remember that in Python, multiple function -arguments are be packed in a sequence) and keyword parameters in "kwargs". -The action function may be an instance method so it -has another way to reference private data (besides global variables). -""" - -import time -import heapq -from collections import namedtuple -from itertools import count -import threading -from time import monotonic as _time - -__all__ = ["scheduler"] - -Event = namedtuple('Event', 'time, priority, sequence, action, argument, kwargs') -Event.time.__doc__ = ('''Numeric type compatible with the return value of the -timefunc function passed to the constructor.''') -Event.priority.__doc__ = ('''Events scheduled for the same time will be executed -in the order of their priority.''') -Event.sequence.__doc__ = ('''A continually increasing sequence number that - separates events if time and priority are equal.''') -Event.action.__doc__ = ('''Executing the event means executing -action(*argument, **kwargs)''') -Event.argument.__doc__ = ('''argument is a sequence holding the positional -arguments for the action.''') -Event.kwargs.__doc__ = ('''kwargs is a dictionary holding the keyword -arguments for the action.''') - -_sentinel = object() - -class scheduler: - - def __init__(self, timefunc=_time, delayfunc=time.sleep): - """Initialize a new instance, passing the time and delay - functions""" - self._queue = [] - self._lock = threading.RLock() - self.timefunc = timefunc - self.delayfunc = delayfunc - self._sequence_generator = count() - - def enterabs(self, time, priority, action, argument=(), kwargs=_sentinel): - """Enter a new event in the queue at an absolute time. - - Returns an ID for the event which can be used to remove it, - if necessary. - - """ - if kwargs is _sentinel: - kwargs = {} - - with self._lock: - event = Event(time, priority, next(self._sequence_generator), - action, argument, kwargs) - heapq.heappush(self._queue, event) - return event # The ID - - def enter(self, delay, priority, action, argument=(), kwargs=_sentinel): - """A variant that specifies the time as a relative time. - - This is actually the more commonly used interface. - - """ - time = self.timefunc() + delay - return self.enterabs(time, priority, action, argument, kwargs) - - def cancel(self, event): - """Remove an event from the queue. - - This must be presented the ID as returned by enter(). - If the event is not in the queue, this raises ValueError. - - """ - with self._lock: - self._queue.remove(event) - heapq.heapify(self._queue) - - def empty(self): - """Check whether the queue is empty.""" - with self._lock: - return not self._queue - - def run(self, blocking=True): - """Execute events until the queue is empty. - If blocking is False executes the scheduled events due to - expire soonest (if any) and then return the deadline of the - next scheduled call in the scheduler. - - When there is a positive delay until the first event, the - delay function is called and the event is left in the queue; - otherwise, the event is removed from the queue and executed - (its action function is called, passing it the argument). If - the delay function returns prematurely, it is simply - restarted. - - It is legal for both the delay function and the action - function to modify the queue or to raise an exception; - exceptions are not caught but the scheduler's state remains - well-defined so run() may be called again. - - A questionable hack is added to allow other threads to run: - just after an event is executed, a delay of 0 is executed, to - avoid monopolizing the CPU when other threads are also - runnable. - - """ - # localize variable access to minimize overhead - # and to improve thread safety - lock = self._lock - q = self._queue - delayfunc = self.delayfunc - timefunc = self.timefunc - pop = heapq.heappop - while True: - with lock: - if not q: - break - (time, priority, sequence, action, - argument, kwargs) = q[0] - now = timefunc() - if time > now: - delay = True - else: - delay = False - pop(q) - if delay: - if not blocking: - return time - now - delayfunc(time - now) - else: - action(*argument, **kwargs) - delayfunc(0) # Let other threads run - - @property - def queue(self): - """An ordered list of upcoming events. - - Events are named tuples with fields for: - time, priority, action, arguments, kwargs - - """ - # Use heapq to sort the queue rather than using 'sorted(self._queue)'. - # With heapq, two events scheduled at the same time will show in - # the actual order they would be retrieved. - with self._lock: - events = self._queue[:] - return list(map(heapq.heappop, [events]*len(events))) diff --git a/python/Lib/secrets.py b/python/Lib/secrets.py deleted file mode 100644 index 0f52b4b..0000000 --- a/python/Lib/secrets.py +++ /dev/null @@ -1,72 +0,0 @@ -"""Generate cryptographically strong pseudo-random numbers suitable for -managing secrets such as account authentication, tokens, and similar. - -See PEP 506 for more information. -https://peps.python.org/pep-0506/ - -""" - -__all__ = ['choice', 'randbelow', 'randbits', 'SystemRandom', - 'token_bytes', 'token_hex', 'token_urlsafe', - 'compare_digest', - ] - - -import base64 -import binascii - -from hmac import compare_digest -from random import SystemRandom - -_sysrand = SystemRandom() - -randbits = _sysrand.getrandbits -choice = _sysrand.choice - -def randbelow(exclusive_upper_bound): - """Return a random int in the range [0, n).""" - if exclusive_upper_bound <= 0: - raise ValueError("Upper bound must be positive.") - return _sysrand._randbelow(exclusive_upper_bound) - -DEFAULT_ENTROPY = 32 # number of bytes to return by default - -def token_bytes(nbytes=None): - """Return a random byte string containing *nbytes* bytes. - - If *nbytes* is ``None`` or not supplied, a reasonable - default is used. - - >>> token_bytes(16) #doctest:+SKIP - b'\\xebr\\x17D*t\\xae\\xd4\\xe3S\\xb6\\xe2\\xebP1\\x8b' - - """ - if nbytes is None: - nbytes = DEFAULT_ENTROPY - return _sysrand.randbytes(nbytes) - -def token_hex(nbytes=None): - """Return a random text string, in hexadecimal. - - The string has *nbytes* random bytes, each byte converted to two - hex digits. If *nbytes* is ``None`` or not supplied, a reasonable - default is used. - - >>> token_hex(16) #doctest:+SKIP - 'f9bf78b9a18ce6d46a0cd2b0b86df9da' - - """ - return binascii.hexlify(token_bytes(nbytes)).decode('ascii') - -def token_urlsafe(nbytes=None): - """Return a random URL-safe text string, in Base64 encoding. - - The string has *nbytes* random bytes. If *nbytes* is ``None`` - or not supplied, a reasonable default is used. - - >>> token_urlsafe(16) #doctest:+SKIP - 'Drmhze6EPcv0fN_81Bj-nA' - - """ - tok = token_bytes(nbytes) - return base64.urlsafe_b64encode(tok).rstrip(b'=').decode('ascii') diff --git a/python/Lib/selectors.py b/python/Lib/selectors.py deleted file mode 100644 index 58046e8..0000000 --- a/python/Lib/selectors.py +++ /dev/null @@ -1,618 +0,0 @@ -"""Selectors module. - -This module allows high-level and efficient I/O multiplexing, built upon the -`select` module primitives. -""" - - -from abc import ABCMeta, abstractmethod -from collections import namedtuple -from collections.abc import Mapping -import math -import select -import sys - - -# generic events, that must be mapped to implementation-specific ones -EVENT_READ = (1 << 0) -EVENT_WRITE = (1 << 1) - - -def _fileobj_to_fd(fileobj): - """Return a file descriptor from a file object. - - Parameters: - fileobj -- file object or file descriptor - - Returns: - corresponding file descriptor - - Raises: - ValueError if the object is invalid - """ - if isinstance(fileobj, int): - fd = fileobj - else: - try: - fd = int(fileobj.fileno()) - except (AttributeError, TypeError, ValueError): - raise ValueError("Invalid file object: " - "{!r}".format(fileobj)) from None - if fd < 0: - raise ValueError("Invalid file descriptor: {}".format(fd)) - return fd - - -SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data']) - -SelectorKey.__doc__ = """SelectorKey(fileobj, fd, events, data) - - Object used to associate a file object to its backing - file descriptor, selected event mask, and attached data. -""" -SelectorKey.fileobj.__doc__ = 'File object registered.' -SelectorKey.fd.__doc__ = 'Underlying file descriptor.' -SelectorKey.events.__doc__ = 'Events that must be waited for on this file object.' -SelectorKey.data.__doc__ = ('''Optional opaque data associated to this file object. -For example, this could be used to store a per-client session ID.''') - - -class _SelectorMapping(Mapping): - """Mapping of file objects to selector keys.""" - - def __init__(self, selector): - self._selector = selector - - def __len__(self): - return len(self._selector._fd_to_key) - - def __getitem__(self, fileobj): - try: - fd = self._selector._fileobj_lookup(fileobj) - return self._selector._fd_to_key[fd] - except KeyError: - raise KeyError("{!r} is not registered".format(fileobj)) from None - - def __iter__(self): - return iter(self._selector._fd_to_key) - - -class BaseSelector(metaclass=ABCMeta): - """Selector abstract base class. - - A selector supports registering file objects to be monitored for specific - I/O events. - - A file object is a file descriptor or any object with a `fileno()` method. - An arbitrary object can be attached to the file object, which can be used - for example to store context information, a callback, etc. - - A selector can use various implementations (select(), poll(), epoll()...) - depending on the platform. The default `Selector` class uses the most - efficient implementation on the current platform. - """ - - @abstractmethod - def register(self, fileobj, events, data=None): - """Register a file object. - - Parameters: - fileobj -- file object or file descriptor - events -- events to monitor (bitwise mask of EVENT_READ|EVENT_WRITE) - data -- attached data - - Returns: - SelectorKey instance - - Raises: - ValueError if events is invalid - KeyError if fileobj is already registered - OSError if fileobj is closed or otherwise is unacceptable to - the underlying system call (if a system call is made) - - Note: - OSError may or may not be raised - """ - raise NotImplementedError - - @abstractmethod - def unregister(self, fileobj): - """Unregister a file object. - - Parameters: - fileobj -- file object or file descriptor - - Returns: - SelectorKey instance - - Raises: - KeyError if fileobj is not registered - - Note: - If fileobj is registered but has since been closed this does - *not* raise OSError (even if the wrapped syscall does) - """ - raise NotImplementedError - - def modify(self, fileobj, events, data=None): - """Change a registered file object monitored events or attached data. - - Parameters: - fileobj -- file object or file descriptor - events -- events to monitor (bitwise mask of EVENT_READ|EVENT_WRITE) - data -- attached data - - Returns: - SelectorKey instance - - Raises: - Anything that unregister() or register() raises - """ - self.unregister(fileobj) - return self.register(fileobj, events, data) - - @abstractmethod - def select(self, timeout=None): - """Perform the actual selection, until some monitored file objects are - ready or a timeout expires. - - Parameters: - timeout -- if timeout > 0, this specifies the maximum wait time, in - seconds - if timeout <= 0, the select() call won't block, and will - report the currently ready file objects - if timeout is None, select() will block until a monitored - file object becomes ready - - Returns: - list of (key, events) for ready file objects - `events` is a bitwise mask of EVENT_READ|EVENT_WRITE - """ - raise NotImplementedError - - def close(self): - """Close the selector. - - This must be called to make sure that any underlying resource is freed. - """ - pass - - def get_key(self, fileobj): - """Return the key associated to a registered file object. - - Returns: - SelectorKey for this file object - """ - mapping = self.get_map() - if mapping is None: - raise RuntimeError('Selector is closed') - try: - return mapping[fileobj] - except KeyError: - raise KeyError("{!r} is not registered".format(fileobj)) from None - - @abstractmethod - def get_map(self): - """Return a mapping of file objects to selector keys.""" - raise NotImplementedError - - def __enter__(self): - return self - - def __exit__(self, *args): - self.close() - - -class _BaseSelectorImpl(BaseSelector): - """Base selector implementation.""" - - def __init__(self): - # this maps file descriptors to keys - self._fd_to_key = {} - # read-only mapping returned by get_map() - self._map = _SelectorMapping(self) - - def _fileobj_lookup(self, fileobj): - """Return a file descriptor from a file object. - - This wraps _fileobj_to_fd() to do an exhaustive search in case - the object is invalid but we still have it in our map. This - is used by unregister() so we can unregister an object that - was previously registered even if it is closed. It is also - used by _SelectorMapping. - """ - try: - return _fileobj_to_fd(fileobj) - except ValueError: - # Do an exhaustive search. - for key in self._fd_to_key.values(): - if key.fileobj is fileobj: - return key.fd - # Raise ValueError after all. - raise - - def register(self, fileobj, events, data=None): - if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)): - raise ValueError("Invalid events: {!r}".format(events)) - - key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data) - - if key.fd in self._fd_to_key: - raise KeyError("{!r} (FD {}) is already registered" - .format(fileobj, key.fd)) - - self._fd_to_key[key.fd] = key - return key - - def unregister(self, fileobj): - try: - key = self._fd_to_key.pop(self._fileobj_lookup(fileobj)) - except KeyError: - raise KeyError("{!r} is not registered".format(fileobj)) from None - return key - - def modify(self, fileobj, events, data=None): - try: - key = self._fd_to_key[self._fileobj_lookup(fileobj)] - except KeyError: - raise KeyError("{!r} is not registered".format(fileobj)) from None - if events != key.events: - self.unregister(fileobj) - key = self.register(fileobj, events, data) - elif data != key.data: - # Use a shortcut to update the data. - key = key._replace(data=data) - self._fd_to_key[key.fd] = key - return key - - def close(self): - self._fd_to_key.clear() - self._map = None - - def get_map(self): - return self._map - - def _key_from_fd(self, fd): - """Return the key associated to a given file descriptor. - - Parameters: - fd -- file descriptor - - Returns: - corresponding key, or None if not found - """ - try: - return self._fd_to_key[fd] - except KeyError: - return None - - -class SelectSelector(_BaseSelectorImpl): - """Select-based selector.""" - - def __init__(self): - super().__init__() - self._readers = set() - self._writers = set() - - def register(self, fileobj, events, data=None): - key = super().register(fileobj, events, data) - if events & EVENT_READ: - self._readers.add(key.fd) - if events & EVENT_WRITE: - self._writers.add(key.fd) - return key - - def unregister(self, fileobj): - key = super().unregister(fileobj) - self._readers.discard(key.fd) - self._writers.discard(key.fd) - return key - - if sys.platform == 'win32': - def _select(self, r, w, _, timeout=None): - r, w, x = select.select(r, w, w, timeout) - return r, w + x, [] - else: - _select = select.select - - def select(self, timeout=None): - timeout = None if timeout is None else max(timeout, 0) - ready = [] - try: - r, w, _ = self._select(self._readers, self._writers, [], timeout) - except InterruptedError: - return ready - r = set(r) - w = set(w) - for fd in r | w: - events = 0 - if fd in r: - events |= EVENT_READ - if fd in w: - events |= EVENT_WRITE - - key = self._key_from_fd(fd) - if key: - ready.append((key, events & key.events)) - return ready - - -class _PollLikeSelector(_BaseSelectorImpl): - """Base class shared between poll, epoll and devpoll selectors.""" - _selector_cls = None - _EVENT_READ = None - _EVENT_WRITE = None - - def __init__(self): - super().__init__() - self._selector = self._selector_cls() - - def register(self, fileobj, events, data=None): - key = super().register(fileobj, events, data) - poller_events = 0 - if events & EVENT_READ: - poller_events |= self._EVENT_READ - if events & EVENT_WRITE: - poller_events |= self._EVENT_WRITE - try: - self._selector.register(key.fd, poller_events) - except: - super().unregister(fileobj) - raise - return key - - def unregister(self, fileobj): - key = super().unregister(fileobj) - try: - self._selector.unregister(key.fd) - except OSError: - # This can happen if the FD was closed since it - # was registered. - pass - return key - - def modify(self, fileobj, events, data=None): - try: - key = self._fd_to_key[self._fileobj_lookup(fileobj)] - except KeyError: - raise KeyError(f"{fileobj!r} is not registered") from None - - changed = False - if events != key.events: - selector_events = 0 - if events & EVENT_READ: - selector_events |= self._EVENT_READ - if events & EVENT_WRITE: - selector_events |= self._EVENT_WRITE - try: - self._selector.modify(key.fd, selector_events) - except: - super().unregister(fileobj) - raise - changed = True - if data != key.data: - changed = True - - if changed: - key = key._replace(events=events, data=data) - self._fd_to_key[key.fd] = key - return key - - def select(self, timeout=None): - # This is shared between poll() and epoll(). - # epoll() has a different signature and handling of timeout parameter. - if timeout is None: - timeout = None - elif timeout <= 0: - timeout = 0 - else: - # poll() has a resolution of 1 millisecond, round away from - # zero to wait *at least* timeout seconds. - timeout = math.ceil(timeout * 1e3) - ready = [] - try: - fd_event_list = self._selector.poll(timeout) - except InterruptedError: - return ready - for fd, event in fd_event_list: - events = 0 - if event & ~self._EVENT_READ: - events |= EVENT_WRITE - if event & ~self._EVENT_WRITE: - events |= EVENT_READ - - key = self._key_from_fd(fd) - if key: - ready.append((key, events & key.events)) - return ready - - -if hasattr(select, 'poll'): - - class PollSelector(_PollLikeSelector): - """Poll-based selector.""" - _selector_cls = select.poll - _EVENT_READ = select.POLLIN - _EVENT_WRITE = select.POLLOUT - - -if hasattr(select, 'epoll'): - - class EpollSelector(_PollLikeSelector): - """Epoll-based selector.""" - _selector_cls = select.epoll - _EVENT_READ = select.EPOLLIN - _EVENT_WRITE = select.EPOLLOUT - - def fileno(self): - return self._selector.fileno() - - def select(self, timeout=None): - if timeout is None: - timeout = -1 - elif timeout <= 0: - timeout = 0 - else: - # epoll_wait() has a resolution of 1 millisecond, round away - # from zero to wait *at least* timeout seconds. - timeout = math.ceil(timeout * 1e3) * 1e-3 - - # epoll_wait() expects `maxevents` to be greater than zero; - # we want to make sure that `select()` can be called when no - # FD is registered. - max_ev = max(len(self._fd_to_key), 1) - - ready = [] - try: - fd_event_list = self._selector.poll(timeout, max_ev) - except InterruptedError: - return ready - for fd, event in fd_event_list: - events = 0 - if event & ~select.EPOLLIN: - events |= EVENT_WRITE - if event & ~select.EPOLLOUT: - events |= EVENT_READ - - key = self._key_from_fd(fd) - if key: - ready.append((key, events & key.events)) - return ready - - def close(self): - self._selector.close() - super().close() - - -if hasattr(select, 'devpoll'): - - class DevpollSelector(_PollLikeSelector): - """Solaris /dev/poll selector.""" - _selector_cls = select.devpoll - _EVENT_READ = select.POLLIN - _EVENT_WRITE = select.POLLOUT - - def fileno(self): - return self._selector.fileno() - - def close(self): - self._selector.close() - super().close() - - -if hasattr(select, 'kqueue'): - - class KqueueSelector(_BaseSelectorImpl): - """Kqueue-based selector.""" - - def __init__(self): - super().__init__() - self._selector = select.kqueue() - - def fileno(self): - return self._selector.fileno() - - def register(self, fileobj, events, data=None): - key = super().register(fileobj, events, data) - try: - if events & EVENT_READ: - kev = select.kevent(key.fd, select.KQ_FILTER_READ, - select.KQ_EV_ADD) - self._selector.control([kev], 0, 0) - if events & EVENT_WRITE: - kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, - select.KQ_EV_ADD) - self._selector.control([kev], 0, 0) - except: - super().unregister(fileobj) - raise - return key - - def unregister(self, fileobj): - key = super().unregister(fileobj) - if key.events & EVENT_READ: - kev = select.kevent(key.fd, select.KQ_FILTER_READ, - select.KQ_EV_DELETE) - try: - self._selector.control([kev], 0, 0) - except OSError: - # This can happen if the FD was closed since it - # was registered. - pass - if key.events & EVENT_WRITE: - kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, - select.KQ_EV_DELETE) - try: - self._selector.control([kev], 0, 0) - except OSError: - # See comment above. - pass - return key - - def select(self, timeout=None): - timeout = None if timeout is None else max(timeout, 0) - # If max_ev is 0, kqueue will ignore the timeout. For consistent - # behavior with the other selector classes, we prevent that here - # (using max). See https://bugs.python.org/issue29255 - max_ev = max(len(self._fd_to_key), 1) - ready = [] - try: - kev_list = self._selector.control(None, max_ev, timeout) - except InterruptedError: - return ready - for kev in kev_list: - fd = kev.ident - flag = kev.filter - events = 0 - if flag == select.KQ_FILTER_READ: - events |= EVENT_READ - if flag == select.KQ_FILTER_WRITE: - events |= EVENT_WRITE - - key = self._key_from_fd(fd) - if key: - ready.append((key, events & key.events)) - return ready - - def close(self): - self._selector.close() - super().close() - - -def _can_use(method): - """Check if we can use the selector depending upon the - operating system. """ - # Implementation based upon https://github.com/sethmlarson/selectors2/blob/master/selectors2.py - selector = getattr(select, method, None) - if selector is None: - # select module does not implement method - return False - # check if the OS and Kernel actually support the method. Call may fail with - # OSError: [Errno 38] Function not implemented - try: - selector_obj = selector() - if method == 'poll': - # check that poll actually works - selector_obj.poll(0) - else: - # close epoll, kqueue, and devpoll fd - selector_obj.close() - return True - except OSError: - return False - - -# Choose the best implementation, roughly: -# epoll|kqueue|devpoll > poll > select. -# select() also can't accept a FD > FD_SETSIZE (usually around 1024) -if _can_use('kqueue'): - DefaultSelector = KqueueSelector -elif _can_use('epoll'): - DefaultSelector = EpollSelector -elif _can_use('devpoll'): - DefaultSelector = DevpollSelector -elif _can_use('poll'): - DefaultSelector = PollSelector -else: - DefaultSelector = SelectSelector diff --git a/python/Lib/shelve.py b/python/Lib/shelve.py deleted file mode 100644 index a26559e..0000000 --- a/python/Lib/shelve.py +++ /dev/null @@ -1,243 +0,0 @@ -"""Manage shelves of pickled objects. - -A "shelf" is a persistent, dictionary-like object. The difference -with dbm databases is that the values (not the keys!) in a shelf can -be essentially arbitrary Python objects -- anything that the "pickle" -module can handle. This includes most class instances, recursive data -types, and objects containing lots of shared sub-objects. The keys -are ordinary strings. - -To summarize the interface (key is a string, data is an arbitrary -object): - - import shelve - d = shelve.open(filename) # open, with (g)dbm filename -- no suffix - - d[key] = data # store data at key (overwrites old data if - # using an existing key) - data = d[key] # retrieve a COPY of the data at key (raise - # KeyError if no such key) -- NOTE that this - # access returns a *copy* of the entry! - del d[key] # delete data stored at key (raises KeyError - # if no such key) - flag = key in d # true if the key exists - list = d.keys() # a list of all existing keys (slow!) - - d.close() # close it - -Dependent on the implementation, closing a persistent dictionary may -or may not be necessary to flush changes to disk. - -Normally, d[key] returns a COPY of the entry. This needs care when -mutable entries are mutated: for example, if d[key] is a list, - d[key].append(anitem) -does NOT modify the entry d[key] itself, as stored in the persistent -mapping -- it only modifies the copy, which is then immediately -discarded, so that the append has NO effect whatsoever. To append an -item to d[key] in a way that will affect the persistent mapping, use: - data = d[key] - data.append(anitem) - d[key] = data - -To avoid the problem with mutable entries, you may pass the keyword -argument writeback=True in the call to shelve.open. When you use: - d = shelve.open(filename, writeback=True) -then d keeps a cache of all entries you access, and writes them all back -to the persistent mapping when you call d.close(). This ensures that -such usage as d[key].append(anitem) works as intended. - -However, using keyword argument writeback=True may consume vast amount -of memory for the cache, and it may make d.close() very slow, if you -access many of d's entries after opening it in this way: d has no way to -check which of the entries you access are mutable and/or which ones you -actually mutate, so it must cache, and write back at close, all of the -entries that you access. You can call d.sync() to write back all the -entries in the cache, and empty the cache (d.sync() also synchronizes -the persistent dictionary on disk, if feasible). -""" - -from pickle import DEFAULT_PROTOCOL, Pickler, Unpickler -from io import BytesIO - -import collections.abc - -__all__ = ["Shelf", "BsdDbShelf", "DbfilenameShelf", "open"] - -class _ClosedDict(collections.abc.MutableMapping): - 'Marker for a closed dict. Access attempts raise a ValueError.' - - def closed(self, *args): - raise ValueError('invalid operation on closed shelf') - __iter__ = __len__ = __getitem__ = __setitem__ = __delitem__ = keys = closed - - def __repr__(self): - return '' - - -class Shelf(collections.abc.MutableMapping): - """Base class for shelf implementations. - - This is initialized with a dictionary-like object. - See the module's __doc__ string for an overview of the interface. - """ - - def __init__(self, dict, protocol=None, writeback=False, - keyencoding="utf-8"): - self.dict = dict - if protocol is None: - protocol = DEFAULT_PROTOCOL - self._protocol = protocol - self.writeback = writeback - self.cache = {} - self.keyencoding = keyencoding - - def __iter__(self): - for k in self.dict.keys(): - yield k.decode(self.keyencoding) - - def __len__(self): - return len(self.dict) - - def __contains__(self, key): - return key.encode(self.keyencoding) in self.dict - - def get(self, key, default=None): - if key.encode(self.keyencoding) in self.dict: - return self[key] - return default - - def __getitem__(self, key): - try: - value = self.cache[key] - except KeyError: - f = BytesIO(self.dict[key.encode(self.keyencoding)]) - value = Unpickler(f).load() - if self.writeback: - self.cache[key] = value - return value - - def __setitem__(self, key, value): - if self.writeback: - self.cache[key] = value - f = BytesIO() - p = Pickler(f, self._protocol) - p.dump(value) - self.dict[key.encode(self.keyencoding)] = f.getvalue() - - def __delitem__(self, key): - del self.dict[key.encode(self.keyencoding)] - try: - del self.cache[key] - except KeyError: - pass - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - self.close() - - def close(self): - if self.dict is None: - return - try: - self.sync() - try: - self.dict.close() - except AttributeError: - pass - finally: - # Catch errors that may happen when close is called from __del__ - # because CPython is in interpreter shutdown. - try: - self.dict = _ClosedDict() - except: - self.dict = None - - def __del__(self): - if not hasattr(self, 'writeback'): - # __init__ didn't succeed, so don't bother closing - # see http://bugs.python.org/issue1339007 for details - return - self.close() - - def sync(self): - if self.writeback and self.cache: - self.writeback = False - for key, entry in self.cache.items(): - self[key] = entry - self.writeback = True - self.cache = {} - if hasattr(self.dict, 'sync'): - self.dict.sync() - - -class BsdDbShelf(Shelf): - """Shelf implementation using the "BSD" db interface. - - This adds methods first(), next(), previous(), last() and - set_location() that have no counterpart in [g]dbm databases. - - The actual database must be opened using one of the "bsddb" - modules "open" routines (i.e. bsddb.hashopen, bsddb.btopen or - bsddb.rnopen) and passed to the constructor. - - See the module's __doc__ string for an overview of the interface. - """ - - def __init__(self, dict, protocol=None, writeback=False, - keyencoding="utf-8"): - Shelf.__init__(self, dict, protocol, writeback, keyencoding) - - def set_location(self, key): - (key, value) = self.dict.set_location(key) - f = BytesIO(value) - return (key.decode(self.keyencoding), Unpickler(f).load()) - - def next(self): - (key, value) = next(self.dict) - f = BytesIO(value) - return (key.decode(self.keyencoding), Unpickler(f).load()) - - def previous(self): - (key, value) = self.dict.previous() - f = BytesIO(value) - return (key.decode(self.keyencoding), Unpickler(f).load()) - - def first(self): - (key, value) = self.dict.first() - f = BytesIO(value) - return (key.decode(self.keyencoding), Unpickler(f).load()) - - def last(self): - (key, value) = self.dict.last() - f = BytesIO(value) - return (key.decode(self.keyencoding), Unpickler(f).load()) - - -class DbfilenameShelf(Shelf): - """Shelf implementation using the "dbm" generic dbm interface. - - This is initialized with the filename for the dbm database. - See the module's __doc__ string for an overview of the interface. - """ - - def __init__(self, filename, flag='c', protocol=None, writeback=False): - import dbm - Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback) - - -def open(filename, flag='c', protocol=None, writeback=False): - """Open a persistent dictionary for reading and writing. - - The filename parameter is the base filename for the underlying - database. As a side-effect, an extension may be added to the - filename and more than one file may be created. The optional flag - parameter has the same interpretation as the flag parameter of - dbm.open(). The optional protocol parameter specifies the - version of the pickle protocol. - - See the module's __doc__ string for an overview of the interface. - """ - - return DbfilenameShelf(filename, flag, protocol, writeback) diff --git a/python/Lib/shlex.py b/python/Lib/shlex.py deleted file mode 100644 index e427963..0000000 --- a/python/Lib/shlex.py +++ /dev/null @@ -1,350 +0,0 @@ -"""A lexical analyzer class for simple shell-like syntaxes.""" - -# Module and documentation by Eric S. Raymond, 21 Dec 1998 -# Input stacking and error message cleanup added by ESR, March 2000 -# push_source() and pop_source() made explicit by ESR, January 2001. -# Posix compliance, split(), string arguments, and -# iterator interface by Gustavo Niemeyer, April 2003. -# changes to tokenize more like Posix shells by Vinay Sajip, July 2016. - -import os -import re -import sys -from collections import deque - -from io import StringIO - -__all__ = ["shlex", "split", "quote", "join"] - -class shlex: - "A lexical analyzer class for simple shell-like syntaxes." - def __init__(self, instream=None, infile=None, posix=False, - punctuation_chars=False): - if isinstance(instream, str): - instream = StringIO(instream) - if instream is not None: - self.instream = instream - self.infile = infile - else: - self.instream = sys.stdin - self.infile = None - self.posix = posix - if posix: - self.eof = None - else: - self.eof = '' - self.commenters = '#' - self.wordchars = ('abcdfeghijklmnopqrstuvwxyz' - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_') - if self.posix: - self.wordchars += ('ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ' - 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ') - self.whitespace = ' \t\r\n' - self.whitespace_split = False - self.quotes = '\'"' - self.escape = '\\' - self.escapedquotes = '"' - self.state = ' ' - self.pushback = deque() - self.lineno = 1 - self.debug = 0 - self.token = '' - self.filestack = deque() - self.source = None - if not punctuation_chars: - punctuation_chars = '' - elif punctuation_chars is True: - punctuation_chars = '();<>|&' - self._punctuation_chars = punctuation_chars - if punctuation_chars: - # _pushback_chars is a push back queue used by lookahead logic - self._pushback_chars = deque() - # these chars added because allowed in file names, args, wildcards - self.wordchars += '~-./*?=' - #remove any punctuation chars from wordchars - t = self.wordchars.maketrans(dict.fromkeys(punctuation_chars)) - self.wordchars = self.wordchars.translate(t) - - @property - def punctuation_chars(self): - return self._punctuation_chars - - def push_token(self, tok): - "Push a token onto the stack popped by the get_token method" - if self.debug >= 1: - print("shlex: pushing token " + repr(tok)) - self.pushback.appendleft(tok) - - def push_source(self, newstream, newfile=None): - "Push an input source onto the lexer's input source stack." - if isinstance(newstream, str): - newstream = StringIO(newstream) - self.filestack.appendleft((self.infile, self.instream, self.lineno)) - self.infile = newfile - self.instream = newstream - self.lineno = 1 - if self.debug: - if newfile is not None: - print('shlex: pushing to file %s' % (self.infile,)) - else: - print('shlex: pushing to stream %s' % (self.instream,)) - - def pop_source(self): - "Pop the input source stack." - self.instream.close() - (self.infile, self.instream, self.lineno) = self.filestack.popleft() - if self.debug: - print('shlex: popping to %s, line %d' \ - % (self.instream, self.lineno)) - self.state = ' ' - - def get_token(self): - "Get a token from the input stream (or from stack if it's nonempty)" - if self.pushback: - tok = self.pushback.popleft() - if self.debug >= 1: - print("shlex: popping token " + repr(tok)) - return tok - # No pushback. Get a token. - raw = self.read_token() - # Handle inclusions - if self.source is not None: - while raw == self.source: - spec = self.sourcehook(self.read_token()) - if spec: - (newfile, newstream) = spec - self.push_source(newstream, newfile) - raw = self.get_token() - # Maybe we got EOF instead? - while raw == self.eof: - if not self.filestack: - return self.eof - else: - self.pop_source() - raw = self.get_token() - # Neither inclusion nor EOF - if self.debug >= 1: - if raw != self.eof: - print("shlex: token=" + repr(raw)) - else: - print("shlex: token=EOF") - return raw - - def read_token(self): - quoted = False - escapedstate = ' ' - while True: - if self.punctuation_chars and self._pushback_chars: - nextchar = self._pushback_chars.pop() - else: - nextchar = self.instream.read(1) - if nextchar == '\n': - self.lineno += 1 - if self.debug >= 3: - print("shlex: in state %r I see character: %r" % (self.state, - nextchar)) - if self.state is None: - self.token = '' # past end of file - break - elif self.state == ' ': - if not nextchar: - self.state = None # end of file - break - elif nextchar in self.whitespace: - if self.debug >= 2: - print("shlex: I see whitespace in whitespace state") - if self.token or (self.posix and quoted): - break # emit current token - else: - continue - elif nextchar in self.commenters: - self.instream.readline() - self.lineno += 1 - elif self.posix and nextchar in self.escape: - escapedstate = 'a' - self.state = nextchar - elif nextchar in self.wordchars: - self.token = nextchar - self.state = 'a' - elif nextchar in self.punctuation_chars: - self.token = nextchar - self.state = 'c' - elif nextchar in self.quotes: - if not self.posix: - self.token = nextchar - self.state = nextchar - elif self.whitespace_split: - self.token = nextchar - self.state = 'a' - else: - self.token = nextchar - if self.token or (self.posix and quoted): - break # emit current token - else: - continue - elif self.state in self.quotes: - quoted = True - if not nextchar: # end of file - if self.debug >= 2: - print("shlex: I see EOF in quotes state") - # XXX what error should be raised here? - raise ValueError("No closing quotation") - if nextchar == self.state: - if not self.posix: - self.token += nextchar - self.state = ' ' - break - else: - self.state = 'a' - elif (self.posix and nextchar in self.escape and self.state - in self.escapedquotes): - escapedstate = self.state - self.state = nextchar - else: - self.token += nextchar - elif self.state in self.escape: - if not nextchar: # end of file - if self.debug >= 2: - print("shlex: I see EOF in escape state") - # XXX what error should be raised here? - raise ValueError("No escaped character") - # In posix shells, only the quote itself or the escape - # character may be escaped within quotes. - if (escapedstate in self.quotes and - nextchar != self.state and nextchar != escapedstate): - self.token += self.state - self.token += nextchar - self.state = escapedstate - elif self.state in ('a', 'c'): - if not nextchar: - self.state = None # end of file - break - elif nextchar in self.whitespace: - if self.debug >= 2: - print("shlex: I see whitespace in word state") - self.state = ' ' - if self.token or (self.posix and quoted): - break # emit current token - else: - continue - elif nextchar in self.commenters: - self.instream.readline() - self.lineno += 1 - if self.posix: - self.state = ' ' - if self.token or (self.posix and quoted): - break # emit current token - else: - continue - elif self.state == 'c': - if nextchar in self.punctuation_chars: - self.token += nextchar - else: - if nextchar not in self.whitespace: - self._pushback_chars.append(nextchar) - self.state = ' ' - break - elif self.posix and nextchar in self.quotes: - self.state = nextchar - elif self.posix and nextchar in self.escape: - escapedstate = 'a' - self.state = nextchar - elif (nextchar in self.wordchars or nextchar in self.quotes - or (self.whitespace_split and - nextchar not in self.punctuation_chars)): - self.token += nextchar - else: - if self.punctuation_chars: - self._pushback_chars.append(nextchar) - else: - self.pushback.appendleft(nextchar) - if self.debug >= 2: - print("shlex: I see punctuation in word state") - self.state = ' ' - if self.token or (self.posix and quoted): - break # emit current token - else: - continue - result = self.token - self.token = '' - if self.posix and not quoted and result == '': - result = None - if self.debug > 1: - if result: - print("shlex: raw token=" + repr(result)) - else: - print("shlex: raw token=EOF") - return result - - def sourcehook(self, newfile): - "Hook called on a filename to be sourced." - if newfile[0] == '"': - newfile = newfile[1:-1] - # This implements cpp-like semantics for relative-path inclusion. - if isinstance(self.infile, str) and not os.path.isabs(newfile): - newfile = os.path.join(os.path.dirname(self.infile), newfile) - return (newfile, open(newfile, "r")) - - def error_leader(self, infile=None, lineno=None): - "Emit a C-compiler-like, Emacs-friendly error-message leader." - if infile is None: - infile = self.infile - if lineno is None: - lineno = self.lineno - return "\"%s\", line %d: " % (infile, lineno) - - def __iter__(self): - return self - - def __next__(self): - token = self.get_token() - if token == self.eof: - raise StopIteration - return token - -def split(s, comments=False, posix=True): - """Split the string *s* using shell-like syntax.""" - if s is None: - import warnings - warnings.warn("Passing None for 's' to shlex.split() is deprecated.", - DeprecationWarning, stacklevel=2) - lex = shlex(s, posix=posix) - lex.whitespace_split = True - if not comments: - lex.commenters = '' - return list(lex) - - -def join(split_command): - """Return a shell-escaped string from *split_command*.""" - return ' '.join(quote(arg) for arg in split_command) - - -_find_unsafe = re.compile(r'[^\w@%+=:,./-]', re.ASCII).search - -def quote(s): - """Return a shell-escaped version of the string *s*.""" - if not s: - return "''" - if _find_unsafe(s) is None: - return s - - # use single quotes, and put single quotes into double quotes - # the string $'b is then quoted as '$'"'"'b' - return "'" + s.replace("'", "'\"'\"'") + "'" - - -def _print_tokens(lexer): - while 1: - tt = lexer.get_token() - if not tt: - break - print("Token: " + repr(tt)) - -if __name__ == '__main__': - if len(sys.argv) == 1: - _print_tokens(shlex()) - else: - fn = sys.argv[1] - with open(fn) as f: - _print_tokens(shlex(f, fn)) diff --git a/python/Lib/shutil.py b/python/Lib/shutil.py deleted file mode 100644 index cec9da8..0000000 --- a/python/Lib/shutil.py +++ /dev/null @@ -1,1519 +0,0 @@ -"""Utility functions for copying and archiving files and directory trees. - -XXX The functions here don't copy the resource fork or other metadata on Mac. - -""" - -import os -import sys -import stat -import fnmatch -import collections -import errno - -try: - import zlib - del zlib - _ZLIB_SUPPORTED = True -except ImportError: - _ZLIB_SUPPORTED = False - -try: - import bz2 - del bz2 - _BZ2_SUPPORTED = True -except ImportError: - _BZ2_SUPPORTED = False - -try: - import lzma - del lzma - _LZMA_SUPPORTED = True -except ImportError: - _LZMA_SUPPORTED = False - -_WINDOWS = os.name == 'nt' -posix = nt = None -if os.name == 'posix': - import posix -elif _WINDOWS: - import nt - -COPY_BUFSIZE = 1024 * 1024 if _WINDOWS else 64 * 1024 -# This should never be removed, see rationale in: -# https://bugs.python.org/issue43743#msg393429 -_USE_CP_SENDFILE = hasattr(os, "sendfile") and sys.platform.startswith("linux") -_HAS_FCOPYFILE = posix and hasattr(posix, "_fcopyfile") # macOS - -# CMD defaults in Windows 10 -_WIN_DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC" - -__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", - "copytree", "move", "rmtree", "Error", "SpecialFileError", - "ExecError", "make_archive", "get_archive_formats", - "register_archive_format", "unregister_archive_format", - "get_unpack_formats", "register_unpack_format", - "unregister_unpack_format", "unpack_archive", - "ignore_patterns", "chown", "which", "get_terminal_size", - "SameFileError"] - # disk_usage is added later, if available on the platform - -class Error(OSError): - pass - -class SameFileError(Error): - """Raised when source and destination are the same file.""" - -class SpecialFileError(OSError): - """Raised when trying to do a kind of operation (e.g. copying) which is - not supported on a special file (e.g. a named pipe)""" - -class ExecError(OSError): - """Raised when a command could not be executed""" - -class ReadError(OSError): - """Raised when an archive cannot be read""" - -class RegistryError(Exception): - """Raised when a registry operation with the archiving - and unpacking registries fails""" - -class _GiveupOnFastCopy(Exception): - """Raised as a signal to fallback on using raw read()/write() - file copy when fast-copy functions fail to do so. - """ - -def _fastcopy_fcopyfile(fsrc, fdst, flags): - """Copy a regular file content or metadata by using high-performance - fcopyfile(3) syscall (macOS). - """ - try: - infd = fsrc.fileno() - outfd = fdst.fileno() - except Exception as err: - raise _GiveupOnFastCopy(err) # not a regular file - - try: - posix._fcopyfile(infd, outfd, flags) - except OSError as err: - err.filename = fsrc.name - err.filename2 = fdst.name - if err.errno in {errno.EINVAL, errno.ENOTSUP}: - raise _GiveupOnFastCopy(err) - else: - raise err from None - -def _fastcopy_sendfile(fsrc, fdst): - """Copy data from one regular mmap-like fd to another by using - high-performance sendfile(2) syscall. - This should work on Linux >= 2.6.33 only. - """ - # Note: copyfileobj() is left alone in order to not introduce any - # unexpected breakage. Possible risks by using zero-copy calls - # in copyfileobj() are: - # - fdst cannot be open in "a"(ppend) mode - # - fsrc and fdst may be open in "t"(ext) mode - # - fsrc may be a BufferedReader (which hides unread data in a buffer), - # GzipFile (which decompresses data), HTTPResponse (which decodes - # chunks). - # - possibly others (e.g. encrypted fs/partition?) - global _USE_CP_SENDFILE - try: - infd = fsrc.fileno() - outfd = fdst.fileno() - except Exception as err: - raise _GiveupOnFastCopy(err) # not a regular file - - # Hopefully the whole file will be copied in a single call. - # sendfile() is called in a loop 'till EOF is reached (0 return) - # so a bufsize smaller or bigger than the actual file size - # should not make any difference, also in case the file content - # changes while being copied. - try: - blocksize = max(os.fstat(infd).st_size, 2 ** 23) # min 8MiB - except OSError: - blocksize = 2 ** 27 # 128MiB - # On 32-bit architectures truncate to 1GiB to avoid OverflowError, - # see bpo-38319. - if sys.maxsize < 2 ** 32: - blocksize = min(blocksize, 2 ** 30) - - offset = 0 - while True: - try: - sent = os.sendfile(outfd, infd, offset, blocksize) - except OSError as err: - # ...in oder to have a more informative exception. - err.filename = fsrc.name - err.filename2 = fdst.name - - if err.errno == errno.ENOTSOCK: - # sendfile() on this platform (probably Linux < 2.6.33) - # does not support copies between regular files (only - # sockets). - _USE_CP_SENDFILE = False - raise _GiveupOnFastCopy(err) - - if err.errno == errno.ENOSPC: # filesystem is full - raise err from None - - # Give up on first call and if no data was copied. - if offset == 0 and os.lseek(outfd, 0, os.SEEK_CUR) == 0: - raise _GiveupOnFastCopy(err) - - raise err - else: - if sent == 0: - break # EOF - offset += sent - -def _copyfileobj_readinto(fsrc, fdst, length=COPY_BUFSIZE): - """readinto()/memoryview() based variant of copyfileobj(). - *fsrc* must support readinto() method and both files must be - open in binary mode. - """ - # Localize variable access to minimize overhead. - fsrc_readinto = fsrc.readinto - fdst_write = fdst.write - with memoryview(bytearray(length)) as mv: - while True: - n = fsrc_readinto(mv) - if not n: - break - elif n < length: - with mv[:n] as smv: - fdst.write(smv) - else: - fdst_write(mv) - -def copyfileobj(fsrc, fdst, length=0): - """copy data from file-like object fsrc to file-like object fdst""" - if not length: - length = COPY_BUFSIZE - # Localize variable access to minimize overhead. - fsrc_read = fsrc.read - fdst_write = fdst.write - while True: - buf = fsrc_read(length) - if not buf: - break - fdst_write(buf) - -def _samefile(src, dst): - # Macintosh, Unix. - if isinstance(src, os.DirEntry) and hasattr(os.path, 'samestat'): - try: - return os.path.samestat(src.stat(), os.stat(dst)) - except OSError: - return False - - if hasattr(os.path, 'samefile'): - try: - return os.path.samefile(src, dst) - except OSError: - return False - - # All other platforms: check for same pathname. - return (os.path.normcase(os.path.abspath(src)) == - os.path.normcase(os.path.abspath(dst))) - -def _stat(fn): - return fn.stat() if isinstance(fn, os.DirEntry) else os.stat(fn) - -def _islink(fn): - return fn.is_symlink() if isinstance(fn, os.DirEntry) else os.path.islink(fn) - -def copyfile(src, dst, *, follow_symlinks=True): - """Copy data from src to dst in the most efficient way possible. - - If follow_symlinks is not set and src is a symbolic link, a new - symlink will be created instead of copying the file it points to. - - """ - sys.audit("shutil.copyfile", src, dst) - - if _samefile(src, dst): - raise SameFileError("{!r} and {!r} are the same file".format(src, dst)) - - file_size = 0 - for i, fn in enumerate([src, dst]): - try: - st = _stat(fn) - except OSError: - # File most likely does not exist - pass - else: - # XXX What about other special files? (sockets, devices...) - if stat.S_ISFIFO(st.st_mode): - fn = fn.path if isinstance(fn, os.DirEntry) else fn - raise SpecialFileError("`%s` is a named pipe" % fn) - if _WINDOWS and i == 0: - file_size = st.st_size - - if not follow_symlinks and _islink(src): - os.symlink(os.readlink(src), dst) - else: - with open(src, 'rb') as fsrc: - try: - with open(dst, 'wb') as fdst: - # macOS - if _HAS_FCOPYFILE: - try: - _fastcopy_fcopyfile(fsrc, fdst, posix._COPYFILE_DATA) - return dst - except _GiveupOnFastCopy: - pass - # Linux - elif _USE_CP_SENDFILE: - try: - _fastcopy_sendfile(fsrc, fdst) - return dst - except _GiveupOnFastCopy: - pass - # Windows, see: - # https://github.com/python/cpython/pull/7160#discussion_r195405230 - elif _WINDOWS and file_size > 0: - _copyfileobj_readinto(fsrc, fdst, min(file_size, COPY_BUFSIZE)) - return dst - - copyfileobj(fsrc, fdst) - - # Issue 43219, raise a less confusing exception - except IsADirectoryError as e: - if not os.path.exists(dst): - raise FileNotFoundError(f'Directory does not exist: {dst}') from e - else: - raise - - return dst - -def copymode(src, dst, *, follow_symlinks=True): - """Copy mode bits from src to dst. - - If follow_symlinks is not set, symlinks aren't followed if and only - if both `src` and `dst` are symlinks. If `lchmod` isn't available - (e.g. Linux) this method does nothing. - - """ - sys.audit("shutil.copymode", src, dst) - - if not follow_symlinks and _islink(src) and os.path.islink(dst): - if hasattr(os, 'lchmod'): - stat_func, chmod_func = os.lstat, os.lchmod - else: - return - else: - stat_func, chmod_func = _stat, os.chmod - - st = stat_func(src) - chmod_func(dst, stat.S_IMODE(st.st_mode)) - -if hasattr(os, 'listxattr'): - def _copyxattr(src, dst, *, follow_symlinks=True): - """Copy extended filesystem attributes from `src` to `dst`. - - Overwrite existing attributes. - - If `follow_symlinks` is false, symlinks won't be followed. - - """ - - try: - names = os.listxattr(src, follow_symlinks=follow_symlinks) - except OSError as e: - if e.errno not in (errno.ENOTSUP, errno.ENODATA, errno.EINVAL): - raise - return - for name in names: - try: - value = os.getxattr(src, name, follow_symlinks=follow_symlinks) - os.setxattr(dst, name, value, follow_symlinks=follow_symlinks) - except OSError as e: - if e.errno not in (errno.EPERM, errno.ENOTSUP, errno.ENODATA, - errno.EINVAL): - raise -else: - def _copyxattr(*args, **kwargs): - pass - -def copystat(src, dst, *, follow_symlinks=True): - """Copy file metadata - - Copy the permission bits, last access time, last modification time, and - flags from `src` to `dst`. On Linux, copystat() also copies the "extended - attributes" where possible. The file contents, owner, and group are - unaffected. `src` and `dst` are path-like objects or path names given as - strings. - - If the optional flag `follow_symlinks` is not set, symlinks aren't - followed if and only if both `src` and `dst` are symlinks. - """ - sys.audit("shutil.copystat", src, dst) - - def _nop(*args, ns=None, follow_symlinks=None): - pass - - # follow symlinks (aka don't not follow symlinks) - follow = follow_symlinks or not (_islink(src) and os.path.islink(dst)) - if follow: - # use the real function if it exists - def lookup(name): - return getattr(os, name, _nop) - else: - # use the real function only if it exists - # *and* it supports follow_symlinks - def lookup(name): - fn = getattr(os, name, _nop) - if fn in os.supports_follow_symlinks: - return fn - return _nop - - if isinstance(src, os.DirEntry): - st = src.stat(follow_symlinks=follow) - else: - st = lookup("stat")(src, follow_symlinks=follow) - mode = stat.S_IMODE(st.st_mode) - lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns), - follow_symlinks=follow) - # We must copy extended attributes before the file is (potentially) - # chmod()'ed read-only, otherwise setxattr() will error with -EACCES. - _copyxattr(src, dst, follow_symlinks=follow) - try: - lookup("chmod")(dst, mode, follow_symlinks=follow) - except NotImplementedError: - # if we got a NotImplementedError, it's because - # * follow_symlinks=False, - # * lchown() is unavailable, and - # * either - # * fchownat() is unavailable or - # * fchownat() doesn't implement AT_SYMLINK_NOFOLLOW. - # (it returned ENOSUP.) - # therefore we're out of options--we simply cannot chown the - # symlink. give up, suppress the error. - # (which is what shutil always did in this circumstance.) - pass - if hasattr(st, 'st_flags'): - try: - lookup("chflags")(dst, st.st_flags, follow_symlinks=follow) - except OSError as why: - for err in 'EOPNOTSUPP', 'ENOTSUP': - if hasattr(errno, err) and why.errno == getattr(errno, err): - break - else: - raise - -def copy(src, dst, *, follow_symlinks=True): - """Copy data and mode bits ("cp src dst"). Return the file's destination. - - The destination may be a directory. - - If follow_symlinks is false, symlinks won't be followed. This - resembles GNU's "cp -P src dst". - - If source and destination are the same file, a SameFileError will be - raised. - - """ - if os.path.isdir(dst): - dst = os.path.join(dst, os.path.basename(src)) - copyfile(src, dst, follow_symlinks=follow_symlinks) - copymode(src, dst, follow_symlinks=follow_symlinks) - return dst - -def copy2(src, dst, *, follow_symlinks=True): - """Copy data and metadata. Return the file's destination. - - Metadata is copied with copystat(). Please see the copystat function - for more information. - - The destination may be a directory. - - If follow_symlinks is false, symlinks won't be followed. This - resembles GNU's "cp -P src dst". - """ - if os.path.isdir(dst): - dst = os.path.join(dst, os.path.basename(src)) - copyfile(src, dst, follow_symlinks=follow_symlinks) - copystat(src, dst, follow_symlinks=follow_symlinks) - return dst - -def ignore_patterns(*patterns): - """Function that can be used as copytree() ignore parameter. - - Patterns is a sequence of glob-style patterns - that are used to exclude files""" - def _ignore_patterns(path, names): - ignored_names = [] - for pattern in patterns: - ignored_names.extend(fnmatch.filter(names, pattern)) - return set(ignored_names) - return _ignore_patterns - -def _copytree(entries, src, dst, symlinks, ignore, copy_function, - ignore_dangling_symlinks, dirs_exist_ok=False): - if ignore is not None: - ignored_names = ignore(os.fspath(src), [x.name for x in entries]) - else: - ignored_names = set() - - os.makedirs(dst, exist_ok=dirs_exist_ok) - errors = [] - use_srcentry = copy_function is copy2 or copy_function is copy - - for srcentry in entries: - if srcentry.name in ignored_names: - continue - srcname = os.path.join(src, srcentry.name) - dstname = os.path.join(dst, srcentry.name) - srcobj = srcentry if use_srcentry else srcname - try: - is_symlink = srcentry.is_symlink() - if is_symlink and os.name == 'nt': - # Special check for directory junctions, which appear as - # symlinks but we want to recurse. - lstat = srcentry.stat(follow_symlinks=False) - if lstat.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT: - is_symlink = False - if is_symlink: - linkto = os.readlink(srcname) - if symlinks: - # We can't just leave it to `copy_function` because legacy - # code with a custom `copy_function` may rely on copytree - # doing the right thing. - os.symlink(linkto, dstname) - copystat(srcobj, dstname, follow_symlinks=not symlinks) - else: - # ignore dangling symlink if the flag is on - if not os.path.exists(linkto) and ignore_dangling_symlinks: - continue - # otherwise let the copy occur. copy2 will raise an error - if srcentry.is_dir(): - copytree(srcobj, dstname, symlinks, ignore, - copy_function, ignore_dangling_symlinks, - dirs_exist_ok) - else: - copy_function(srcobj, dstname) - elif srcentry.is_dir(): - copytree(srcobj, dstname, symlinks, ignore, copy_function, - ignore_dangling_symlinks, dirs_exist_ok) - else: - # Will raise a SpecialFileError for unsupported file types - copy_function(srcobj, dstname) - # catch the Error from the recursive copytree so that we can - # continue with other files - except Error as err: - errors.extend(err.args[0]) - except OSError as why: - errors.append((srcname, dstname, str(why))) - try: - copystat(src, dst) - except OSError as why: - # Copying file access times may fail on Windows - if getattr(why, 'winerror', None) is None: - errors.append((src, dst, str(why))) - if errors: - raise Error(errors) - return dst - -def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, - ignore_dangling_symlinks=False, dirs_exist_ok=False): - """Recursively copy a directory tree and return the destination directory. - - If exception(s) occur, an Error is raised with a list of reasons. - - If the optional symlinks flag is true, symbolic links in the - source tree result in symbolic links in the destination tree; if - it is false, the contents of the files pointed to by symbolic - links are copied. If the file pointed by the symlink doesn't - exist, an exception will be added in the list of errors raised in - an Error exception at the end of the copy process. - - You can set the optional ignore_dangling_symlinks flag to true if you - want to silence this exception. Notice that this has no effect on - platforms that don't support os.symlink. - - The optional ignore argument is a callable. If given, it - is called with the `src` parameter, which is the directory - being visited by copytree(), and `names` which is the list of - `src` contents, as returned by os.listdir(): - - callable(src, names) -> ignored_names - - Since copytree() is called recursively, the callable will be - called once for each directory that is copied. It returns a - list of names relative to the `src` directory that should - not be copied. - - The optional copy_function argument is a callable that will be used - to copy each file. It will be called with the source path and the - destination path as arguments. By default, copy2() is used, but any - function that supports the same signature (like copy()) can be used. - - If dirs_exist_ok is false (the default) and `dst` already exists, a - `FileExistsError` is raised. If `dirs_exist_ok` is true, the copying - operation will continue if it encounters existing directories, and files - within the `dst` tree will be overwritten by corresponding files from the - `src` tree. - """ - sys.audit("shutil.copytree", src, dst) - with os.scandir(src) as itr: - entries = list(itr) - return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks, - ignore=ignore, copy_function=copy_function, - ignore_dangling_symlinks=ignore_dangling_symlinks, - dirs_exist_ok=dirs_exist_ok) - -if hasattr(os.stat_result, 'st_file_attributes'): - # Special handling for directory junctions to make them behave like - # symlinks for shutil.rmtree, since in general they do not appear as - # regular links. - def _rmtree_isdir(entry): - try: - st = entry.stat(follow_symlinks=False) - return (stat.S_ISDIR(st.st_mode) and not - (st.st_file_attributes & stat.FILE_ATTRIBUTE_REPARSE_POINT - and st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT)) - except OSError: - return False - - def _rmtree_islink(path): - try: - st = os.lstat(path) - return (stat.S_ISLNK(st.st_mode) or - (st.st_file_attributes & stat.FILE_ATTRIBUTE_REPARSE_POINT - and st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT)) - except OSError: - return False -else: - def _rmtree_isdir(entry): - try: - return entry.is_dir(follow_symlinks=False) - except OSError: - return False - - def _rmtree_islink(path): - return os.path.islink(path) - -# version vulnerable to race conditions -def _rmtree_unsafe(path, onerror): - try: - with os.scandir(path) as scandir_it: - entries = list(scandir_it) - except OSError: - onerror(os.scandir, path, sys.exc_info()) - entries = [] - for entry in entries: - fullname = entry.path - if _rmtree_isdir(entry): - try: - if entry.is_symlink(): - # This can only happen if someone replaces - # a directory with a symlink after the call to - # os.scandir or entry.is_dir above. - raise OSError("Cannot call rmtree on a symbolic link") - except OSError: - onerror(os.path.islink, fullname, sys.exc_info()) - continue - _rmtree_unsafe(fullname, onerror) - else: - try: - os.unlink(fullname) - except OSError: - onerror(os.unlink, fullname, sys.exc_info()) - try: - os.rmdir(path) - except OSError: - onerror(os.rmdir, path, sys.exc_info()) - -# Version using fd-based APIs to protect against races -def _rmtree_safe_fd(topfd, path, onerror): - try: - with os.scandir(topfd) as scandir_it: - entries = list(scandir_it) - except OSError as err: - err.filename = path - onerror(os.scandir, path, sys.exc_info()) - return - for entry in entries: - fullname = os.path.join(path, entry.name) - try: - is_dir = entry.is_dir(follow_symlinks=False) - except OSError: - is_dir = False - else: - if is_dir: - try: - orig_st = entry.stat(follow_symlinks=False) - is_dir = stat.S_ISDIR(orig_st.st_mode) - except OSError: - onerror(os.lstat, fullname, sys.exc_info()) - continue - if is_dir: - try: - dirfd = os.open(entry.name, os.O_RDONLY, dir_fd=topfd) - dirfd_closed = False - except OSError: - onerror(os.open, fullname, sys.exc_info()) - else: - try: - if os.path.samestat(orig_st, os.fstat(dirfd)): - _rmtree_safe_fd(dirfd, fullname, onerror) - try: - os.close(dirfd) - dirfd_closed = True - os.rmdir(entry.name, dir_fd=topfd) - except OSError: - onerror(os.rmdir, fullname, sys.exc_info()) - else: - try: - # This can only happen if someone replaces - # a directory with a symlink after the call to - # os.scandir or stat.S_ISDIR above. - raise OSError("Cannot call rmtree on a symbolic " - "link") - except OSError: - onerror(os.path.islink, fullname, sys.exc_info()) - finally: - if not dirfd_closed: - os.close(dirfd) - else: - try: - os.unlink(entry.name, dir_fd=topfd) - except OSError: - onerror(os.unlink, fullname, sys.exc_info()) - -_use_fd_functions = ({os.open, os.stat, os.unlink, os.rmdir} <= - os.supports_dir_fd and - os.scandir in os.supports_fd and - os.stat in os.supports_follow_symlinks) - -def rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None): - """Recursively delete a directory tree. - - If dir_fd is not None, it should be a file descriptor open to a directory; - path will then be relative to that directory. - dir_fd may not be implemented on your platform. - If it is unavailable, using it will raise a NotImplementedError. - - If ignore_errors is set, errors are ignored; otherwise, if onerror - is set, it is called to handle the error with arguments (func, - path, exc_info) where func is platform and implementation dependent; - path is the argument to that function that caused it to fail; and - exc_info is a tuple returned by sys.exc_info(). If ignore_errors - is false and onerror is None, an exception is raised. - - """ - sys.audit("shutil.rmtree", path, dir_fd) - if ignore_errors: - def onerror(*args): - pass - elif onerror is None: - def onerror(*args): - raise - if _use_fd_functions: - # While the unsafe rmtree works fine on bytes, the fd based does not. - if isinstance(path, bytes): - path = os.fsdecode(path) - # Note: To guard against symlink races, we use the standard - # lstat()/open()/fstat() trick. - try: - orig_st = os.lstat(path, dir_fd=dir_fd) - except Exception: - onerror(os.lstat, path, sys.exc_info()) - return - try: - fd = os.open(path, os.O_RDONLY, dir_fd=dir_fd) - fd_closed = False - except Exception: - onerror(os.open, path, sys.exc_info()) - return - try: - if os.path.samestat(orig_st, os.fstat(fd)): - _rmtree_safe_fd(fd, path, onerror) - try: - os.close(fd) - fd_closed = True - os.rmdir(path, dir_fd=dir_fd) - except OSError: - onerror(os.rmdir, path, sys.exc_info()) - else: - try: - # symlinks to directories are forbidden, see bug #1669 - raise OSError("Cannot call rmtree on a symbolic link") - except OSError: - onerror(os.path.islink, path, sys.exc_info()) - finally: - if not fd_closed: - os.close(fd) - else: - if dir_fd is not None: - raise NotImplementedError("dir_fd unavailable on this platform") - try: - if _rmtree_islink(path): - # symlinks to directories are forbidden, see bug #1669 - raise OSError("Cannot call rmtree on a symbolic link") - except OSError: - onerror(os.path.islink, path, sys.exc_info()) - # can't continue even if onerror hook returns - return - return _rmtree_unsafe(path, onerror) - -# Allow introspection of whether or not the hardening against symlink -# attacks is supported on the current platform -rmtree.avoids_symlink_attacks = _use_fd_functions - -def _basename(path): - """A basename() variant which first strips the trailing slash, if present. - Thus we always get the last component of the path, even for directories. - - path: Union[PathLike, str] - - e.g. - >>> os.path.basename('/bar/foo') - 'foo' - >>> os.path.basename('/bar/foo/') - '' - >>> _basename('/bar/foo/') - 'foo' - """ - path = os.fspath(path) - sep = os.path.sep + (os.path.altsep or '') - return os.path.basename(path.rstrip(sep)) - -def move(src, dst, copy_function=copy2): - """Recursively move a file or directory to another location. This is - similar to the Unix "mv" command. Return the file or directory's - destination. - - If the destination is a directory or a symlink to a directory, the source - is moved inside the directory. The destination path must not already - exist. - - If the destination already exists but is not a directory, it may be - overwritten depending on os.rename() semantics. - - If the destination is on our current filesystem, then rename() is used. - Otherwise, src is copied to the destination and then removed. Symlinks are - recreated under the new name if os.rename() fails because of cross - filesystem renames. - - The optional `copy_function` argument is a callable that will be used - to copy the source or it will be delegated to `copytree`. - By default, copy2() is used, but any function that supports the same - signature (like copy()) can be used. - - A lot more could be done here... A look at a mv.c shows a lot of - the issues this implementation glosses over. - - """ - sys.audit("shutil.move", src, dst) - real_dst = dst - if os.path.isdir(dst): - if _samefile(src, dst): - # We might be on a case insensitive filesystem, - # perform the rename anyway. - os.rename(src, dst) - return - - # Using _basename instead of os.path.basename is important, as we must - # ignore any trailing slash to avoid the basename returning '' - real_dst = os.path.join(dst, _basename(src)) - - if os.path.exists(real_dst): - raise Error("Destination path '%s' already exists" % real_dst) - try: - os.rename(src, real_dst) - except OSError: - if os.path.islink(src): - linkto = os.readlink(src) - os.symlink(linkto, real_dst) - os.unlink(src) - elif os.path.isdir(src): - if _destinsrc(src, dst): - raise Error("Cannot move a directory '%s' into itself" - " '%s'." % (src, dst)) - if (_is_immutable(src) - or (not os.access(src, os.W_OK) and os.listdir(src) - and sys.platform == 'darwin')): - raise PermissionError("Cannot move the non-empty directory " - "'%s': Lacking write permission to '%s'." - % (src, src)) - copytree(src, real_dst, copy_function=copy_function, - symlinks=True) - rmtree(src) - else: - copy_function(src, real_dst) - os.unlink(src) - return real_dst - -def _destinsrc(src, dst): - src = os.path.abspath(src) - dst = os.path.abspath(dst) - if not src.endswith(os.path.sep): - src += os.path.sep - if not dst.endswith(os.path.sep): - dst += os.path.sep - return dst.startswith(src) - -def _is_immutable(src): - st = _stat(src) - immutable_states = [stat.UF_IMMUTABLE, stat.SF_IMMUTABLE] - return hasattr(st, 'st_flags') and st.st_flags in immutable_states - -def _get_gid(name): - """Returns a gid, given a group name.""" - if name is None: - return None - - try: - from grp import getgrnam - except ImportError: - return None - - try: - result = getgrnam(name) - except KeyError: - result = None - if result is not None: - return result[2] - return None - -def _get_uid(name): - """Returns an uid, given a user name.""" - if name is None: - return None - - try: - from pwd import getpwnam - except ImportError: - return None - - try: - result = getpwnam(name) - except KeyError: - result = None - if result is not None: - return result[2] - return None - -def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, - owner=None, group=None, logger=None, root_dir=None): - """Create a (possibly compressed) tar file from all the files under - 'base_dir'. - - 'compress' must be "gzip" (the default), "bzip2", "xz", or None. - - 'owner' and 'group' can be used to define an owner and a group for the - archive that is being built. If not provided, the current owner and group - will be used. - - The output tar file will be named 'base_name' + ".tar", possibly plus - the appropriate compression extension (".gz", ".bz2", or ".xz"). - - Returns the output filename. - """ - if compress is None: - tar_compression = '' - elif _ZLIB_SUPPORTED and compress == 'gzip': - tar_compression = 'gz' - elif _BZ2_SUPPORTED and compress == 'bzip2': - tar_compression = 'bz2' - elif _LZMA_SUPPORTED and compress == 'xz': - tar_compression = 'xz' - else: - raise ValueError("bad value for 'compress', or compression format not " - "supported : {0}".format(compress)) - - import tarfile # late import for breaking circular dependency - - compress_ext = '.' + tar_compression if compress else '' - archive_name = base_name + '.tar' + compress_ext - archive_dir = os.path.dirname(archive_name) - - if archive_dir and not os.path.exists(archive_dir): - if logger is not None: - logger.info("creating %s", archive_dir) - if not dry_run: - os.makedirs(archive_dir) - - # creating the tarball - if logger is not None: - logger.info('Creating tar archive') - - uid = _get_uid(owner) - gid = _get_gid(group) - - def _set_uid_gid(tarinfo): - if gid is not None: - tarinfo.gid = gid - tarinfo.gname = group - if uid is not None: - tarinfo.uid = uid - tarinfo.uname = owner - return tarinfo - - if not dry_run: - tar = tarfile.open(archive_name, 'w|%s' % tar_compression) - arcname = base_dir - if root_dir is not None: - base_dir = os.path.join(root_dir, base_dir) - try: - tar.add(base_dir, arcname, filter=_set_uid_gid) - finally: - tar.close() - - if root_dir is not None: - archive_name = os.path.abspath(archive_name) - return archive_name - -def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, - logger=None, owner=None, group=None, root_dir=None): - """Create a zip file from all the files under 'base_dir'. - - The output zip file will be named 'base_name' + ".zip". Returns the - name of the output zip file. - """ - import zipfile # late import for breaking circular dependency - - zip_filename = base_name + ".zip" - archive_dir = os.path.dirname(base_name) - - if archive_dir and not os.path.exists(archive_dir): - if logger is not None: - logger.info("creating %s", archive_dir) - if not dry_run: - os.makedirs(archive_dir) - - if logger is not None: - logger.info("creating '%s' and adding '%s' to it", - zip_filename, base_dir) - - if not dry_run: - with zipfile.ZipFile(zip_filename, "w", - compression=zipfile.ZIP_DEFLATED) as zf: - arcname = os.path.normpath(base_dir) - if root_dir is not None: - base_dir = os.path.join(root_dir, base_dir) - base_dir = os.path.normpath(base_dir) - if arcname != os.curdir: - zf.write(base_dir, arcname) - if logger is not None: - logger.info("adding '%s'", base_dir) - for dirpath, dirnames, filenames in os.walk(base_dir): - arcdirpath = dirpath - if root_dir is not None: - arcdirpath = os.path.relpath(arcdirpath, root_dir) - arcdirpath = os.path.normpath(arcdirpath) - for name in sorted(dirnames): - path = os.path.join(dirpath, name) - arcname = os.path.join(arcdirpath, name) - zf.write(path, arcname) - if logger is not None: - logger.info("adding '%s'", path) - for name in filenames: - path = os.path.join(dirpath, name) - path = os.path.normpath(path) - if os.path.isfile(path): - arcname = os.path.join(arcdirpath, name) - zf.write(path, arcname) - if logger is not None: - logger.info("adding '%s'", path) - - if root_dir is not None: - zip_filename = os.path.abspath(zip_filename) - return zip_filename - -# Maps the name of the archive format to a tuple containing: -# * the archiving function -# * extra keyword arguments -# * description -# * does it support the root_dir argument? -_ARCHIVE_FORMATS = { - 'tar': (_make_tarball, [('compress', None)], - "uncompressed tar file", True), -} - -if _ZLIB_SUPPORTED: - _ARCHIVE_FORMATS['gztar'] = (_make_tarball, [('compress', 'gzip')], - "gzip'ed tar-file", True) - _ARCHIVE_FORMATS['zip'] = (_make_zipfile, [], "ZIP file", True) - -if _BZ2_SUPPORTED: - _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], - "bzip2'ed tar-file", True) - -if _LZMA_SUPPORTED: - _ARCHIVE_FORMATS['xztar'] = (_make_tarball, [('compress', 'xz')], - "xz'ed tar-file", True) - -def get_archive_formats(): - """Returns a list of supported formats for archiving and unarchiving. - - Each element of the returned sequence is a tuple (name, description) - """ - formats = [(name, registry[2]) for name, registry in - _ARCHIVE_FORMATS.items()] - formats.sort() - return formats - -def register_archive_format(name, function, extra_args=None, description=''): - """Registers an archive format. - - name is the name of the format. function is the callable that will be - used to create archives. If provided, extra_args is a sequence of - (name, value) tuples that will be passed as arguments to the callable. - description can be provided to describe the format, and will be returned - by the get_archive_formats() function. - """ - if extra_args is None: - extra_args = [] - if not callable(function): - raise TypeError('The %s object is not callable' % function) - if not isinstance(extra_args, (tuple, list)): - raise TypeError('extra_args needs to be a sequence') - for element in extra_args: - if not isinstance(element, (tuple, list)) or len(element) !=2: - raise TypeError('extra_args elements are : (arg_name, value)') - - _ARCHIVE_FORMATS[name] = (function, extra_args, description, False) - -def unregister_archive_format(name): - del _ARCHIVE_FORMATS[name] - -def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, - dry_run=0, owner=None, group=None, logger=None): - """Create an archive file (eg. zip or tar). - - 'base_name' is the name of the file to create, minus any format-specific - extension; 'format' is the archive format: one of "zip", "tar", "gztar", - "bztar", or "xztar". Or any other registered format. - - 'root_dir' is a directory that will be the root directory of the - archive; ie. we typically chdir into 'root_dir' before creating the - archive. 'base_dir' is the directory where we start archiving from; - ie. 'base_dir' will be the common prefix of all files and - directories in the archive. 'root_dir' and 'base_dir' both default - to the current directory. Returns the name of the archive file. - - 'owner' and 'group' are used when creating a tar archive. By default, - uses the current owner and group. - """ - sys.audit("shutil.make_archive", base_name, format, root_dir, base_dir) - try: - format_info = _ARCHIVE_FORMATS[format] - except KeyError: - raise ValueError("unknown archive format '%s'" % format) from None - - kwargs = {'dry_run': dry_run, 'logger': logger, - 'owner': owner, 'group': group} - - func = format_info[0] - for arg, val in format_info[1]: - kwargs[arg] = val - - if base_dir is None: - base_dir = os.curdir - - support_root_dir = format_info[3] - save_cwd = None - if root_dir is not None: - if support_root_dir: - # Support path-like base_name here for backwards-compatibility. - base_name = os.fspath(base_name) - kwargs['root_dir'] = root_dir - else: - save_cwd = os.getcwd() - if logger is not None: - logger.debug("changing into '%s'", root_dir) - base_name = os.path.abspath(base_name) - if not dry_run: - os.chdir(root_dir) - - try: - filename = func(base_name, base_dir, **kwargs) - finally: - if save_cwd is not None: - if logger is not None: - logger.debug("changing back to '%s'", save_cwd) - os.chdir(save_cwd) - - return filename - - -def get_unpack_formats(): - """Returns a list of supported formats for unpacking. - - Each element of the returned sequence is a tuple - (name, extensions, description) - """ - formats = [(name, info[0], info[3]) for name, info in - _UNPACK_FORMATS.items()] - formats.sort() - return formats - -def _check_unpack_options(extensions, function, extra_args): - """Checks what gets registered as an unpacker.""" - # first make sure no other unpacker is registered for this extension - existing_extensions = {} - for name, info in _UNPACK_FORMATS.items(): - for ext in info[0]: - existing_extensions[ext] = name - - for extension in extensions: - if extension in existing_extensions: - msg = '%s is already registered for "%s"' - raise RegistryError(msg % (extension, - existing_extensions[extension])) - - if not callable(function): - raise TypeError('The registered function must be a callable') - - -def register_unpack_format(name, extensions, function, extra_args=None, - description=''): - """Registers an unpack format. - - `name` is the name of the format. `extensions` is a list of extensions - corresponding to the format. - - `function` is the callable that will be - used to unpack archives. The callable will receive archives to unpack. - If it's unable to handle an archive, it needs to raise a ReadError - exception. - - If provided, `extra_args` is a sequence of - (name, value) tuples that will be passed as arguments to the callable. - description can be provided to describe the format, and will be returned - by the get_unpack_formats() function. - """ - if extra_args is None: - extra_args = [] - _check_unpack_options(extensions, function, extra_args) - _UNPACK_FORMATS[name] = extensions, function, extra_args, description - -def unregister_unpack_format(name): - """Removes the pack format from the registry.""" - del _UNPACK_FORMATS[name] - -def _ensure_directory(path): - """Ensure that the parent directory of `path` exists""" - dirname = os.path.dirname(path) - if not os.path.isdir(dirname): - os.makedirs(dirname) - -def _unpack_zipfile(filename, extract_dir): - """Unpack zip `filename` to `extract_dir` - """ - import zipfile # late import for breaking circular dependency - - if not zipfile.is_zipfile(filename): - raise ReadError("%s is not a zip file" % filename) - - zip = zipfile.ZipFile(filename) - try: - for info in zip.infolist(): - name = info.filename - - # don't extract absolute paths or ones with .. in them - if name.startswith('/') or '..' in name: - continue - - targetpath = os.path.join(extract_dir, *name.split('/')) - if not targetpath: - continue - - _ensure_directory(targetpath) - if not name.endswith('/'): - # file - with zip.open(name, 'r') as source, \ - open(targetpath, 'wb') as target: - copyfileobj(source, target) - finally: - zip.close() - -def _unpack_tarfile(filename, extract_dir): - """Unpack tar/tar.gz/tar.bz2/tar.xz `filename` to `extract_dir` - """ - import tarfile # late import for breaking circular dependency - try: - tarobj = tarfile.open(filename) - except tarfile.TarError: - raise ReadError( - "%s is not a compressed or uncompressed tar file" % filename) - try: - tarobj.extractall(extract_dir) - finally: - tarobj.close() - -# Maps the name of the unpack format to a tuple containing: -# * extensions -# * the unpacking function -# * extra keyword arguments -# * description -_UNPACK_FORMATS = { - 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), - 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file"), -} - -if _ZLIB_SUPPORTED: - _UNPACK_FORMATS['gztar'] = (['.tar.gz', '.tgz'], _unpack_tarfile, [], - "gzip'ed tar-file") - -if _BZ2_SUPPORTED: - _UNPACK_FORMATS['bztar'] = (['.tar.bz2', '.tbz2'], _unpack_tarfile, [], - "bzip2'ed tar-file") - -if _LZMA_SUPPORTED: - _UNPACK_FORMATS['xztar'] = (['.tar.xz', '.txz'], _unpack_tarfile, [], - "xz'ed tar-file") - -def _find_unpack_format(filename): - for name, info in _UNPACK_FORMATS.items(): - for extension in info[0]: - if filename.endswith(extension): - return name - return None - -def unpack_archive(filename, extract_dir=None, format=None): - """Unpack an archive. - - `filename` is the name of the archive. - - `extract_dir` is the name of the target directory, where the archive - is unpacked. If not provided, the current working directory is used. - - `format` is the archive format: one of "zip", "tar", "gztar", "bztar", - or "xztar". Or any other registered format. If not provided, - unpack_archive will use the filename extension and see if an unpacker - was registered for that extension. - - In case none is found, a ValueError is raised. - """ - sys.audit("shutil.unpack_archive", filename, extract_dir, format) - - if extract_dir is None: - extract_dir = os.getcwd() - - extract_dir = os.fspath(extract_dir) - filename = os.fspath(filename) - - if format is not None: - try: - format_info = _UNPACK_FORMATS[format] - except KeyError: - raise ValueError("Unknown unpack format '{0}'".format(format)) from None - - func = format_info[1] - func(filename, extract_dir, **dict(format_info[2])) - else: - # we need to look at the registered unpackers supported extensions - format = _find_unpack_format(filename) - if format is None: - raise ReadError("Unknown archive format '{0}'".format(filename)) - - func = _UNPACK_FORMATS[format][1] - kwargs = dict(_UNPACK_FORMATS[format][2]) - func(filename, extract_dir, **kwargs) - - -if hasattr(os, 'statvfs'): - - __all__.append('disk_usage') - _ntuple_diskusage = collections.namedtuple('usage', 'total used free') - _ntuple_diskusage.total.__doc__ = 'Total space in bytes' - _ntuple_diskusage.used.__doc__ = 'Used space in bytes' - _ntuple_diskusage.free.__doc__ = 'Free space in bytes' - - def disk_usage(path): - """Return disk usage statistics about the given path. - - Returned value is a named tuple with attributes 'total', 'used' and - 'free', which are the amount of total, used and free space, in bytes. - """ - st = os.statvfs(path) - free = st.f_bavail * st.f_frsize - total = st.f_blocks * st.f_frsize - used = (st.f_blocks - st.f_bfree) * st.f_frsize - return _ntuple_diskusage(total, used, free) - -elif _WINDOWS: - - __all__.append('disk_usage') - _ntuple_diskusage = collections.namedtuple('usage', 'total used free') - - def disk_usage(path): - """Return disk usage statistics about the given path. - - Returned values is a named tuple with attributes 'total', 'used' and - 'free', which are the amount of total, used and free space, in bytes. - """ - total, free = nt._getdiskusage(path) - used = total - free - return _ntuple_diskusage(total, used, free) - - -def chown(path, user=None, group=None): - """Change owner user and group of the given path. - - user and group can be the uid/gid or the user/group names, and in that case, - they are converted to their respective uid/gid. - """ - sys.audit('shutil.chown', path, user, group) - - if user is None and group is None: - raise ValueError("user and/or group must be set") - - _user = user - _group = group - - # -1 means don't change it - if user is None: - _user = -1 - # user can either be an int (the uid) or a string (the system username) - elif isinstance(user, str): - _user = _get_uid(user) - if _user is None: - raise LookupError("no such user: {!r}".format(user)) - - if group is None: - _group = -1 - elif not isinstance(group, int): - _group = _get_gid(group) - if _group is None: - raise LookupError("no such group: {!r}".format(group)) - - os.chown(path, _user, _group) - -def get_terminal_size(fallback=(80, 24)): - """Get the size of the terminal window. - - For each of the two dimensions, the environment variable, COLUMNS - and LINES respectively, is checked. If the variable is defined and - the value is a positive integer, it is used. - - When COLUMNS or LINES is not defined, which is the common case, - the terminal connected to sys.__stdout__ is queried - by invoking os.get_terminal_size. - - If the terminal size cannot be successfully queried, either because - the system doesn't support querying, or because we are not - connected to a terminal, the value given in fallback parameter - is used. Fallback defaults to (80, 24) which is the default - size used by many terminal emulators. - - The value returned is a named tuple of type os.terminal_size. - """ - # columns, lines are the working values - try: - columns = int(os.environ['COLUMNS']) - except (KeyError, ValueError): - columns = 0 - - try: - lines = int(os.environ['LINES']) - except (KeyError, ValueError): - lines = 0 - - # only query if necessary - if columns <= 0 or lines <= 0: - try: - size = os.get_terminal_size(sys.__stdout__.fileno()) - except (AttributeError, ValueError, OSError): - # stdout is None, closed, detached, or not a terminal, or - # os.get_terminal_size() is unsupported - size = os.terminal_size(fallback) - if columns <= 0: - columns = size.columns or fallback[0] - if lines <= 0: - lines = size.lines or fallback[1] - - return os.terminal_size((columns, lines)) - - -# Check that a given file can be accessed with the correct mode. -# Additionally check that `file` is not a directory, as on Windows -# directories pass the os.access check. -def _access_check(fn, mode): - return (os.path.exists(fn) and os.access(fn, mode) - and not os.path.isdir(fn)) - - -def which(cmd, mode=os.F_OK | os.X_OK, path=None): - """Given a command, mode, and a PATH string, return the path which - conforms to the given mode on the PATH, or None if there is no such - file. - - `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result - of os.environ.get("PATH"), or can be overridden with a custom search - path. - - """ - # If we're given a path with a directory part, look it up directly rather - # than referring to PATH directories. This includes checking relative to the - # current directory, e.g. ./script - if os.path.dirname(cmd): - if _access_check(cmd, mode): - return cmd - return None - - use_bytes = isinstance(cmd, bytes) - - if path is None: - path = os.environ.get("PATH", None) - if path is None: - try: - path = os.confstr("CS_PATH") - except (AttributeError, ValueError): - # os.confstr() or CS_PATH is not available - path = os.defpath - # bpo-35755: Don't use os.defpath if the PATH environment variable is - # set to an empty string - - # PATH='' doesn't match, whereas PATH=':' looks in the current directory - if not path: - return None - - if use_bytes: - path = os.fsencode(path) - path = path.split(os.fsencode(os.pathsep)) - else: - path = os.fsdecode(path) - path = path.split(os.pathsep) - - if sys.platform == "win32": - # The current directory takes precedence on Windows. - curdir = os.curdir - if use_bytes: - curdir = os.fsencode(curdir) - if curdir not in path: - path.insert(0, curdir) - - # PATHEXT is necessary to check on Windows. - pathext_source = os.getenv("PATHEXT") or _WIN_DEFAULT_PATHEXT - pathext = [ext for ext in pathext_source.split(os.pathsep) if ext] - - if use_bytes: - pathext = [os.fsencode(ext) for ext in pathext] - # See if the given file matches any of the expected path extensions. - # This will allow us to short circuit when given "python.exe". - # If it does match, only test that one, otherwise we have to try - # others. - if any(cmd.lower().endswith(ext.lower()) for ext in pathext): - files = [cmd] - else: - files = [cmd + ext for ext in pathext] - else: - # On other platforms you don't have things like PATHEXT to tell you - # what file suffixes are executable, so just pass on cmd as-is. - files = [cmd] - - seen = set() - for dir in path: - normdir = os.path.normcase(dir) - if not normdir in seen: - seen.add(normdir) - for thefile in files: - name = os.path.join(dir, thefile) - if _access_check(name, mode): - return name - return None diff --git a/python/Lib/signal.py b/python/Lib/signal.py deleted file mode 100644 index 3bcd510..0000000 --- a/python/Lib/signal.py +++ /dev/null @@ -1,92 +0,0 @@ -import _signal -from _signal import * -from enum import IntEnum as _IntEnum - -_globals = globals() - -_IntEnum._convert_( - 'Signals', __name__, - lambda name: - name.isupper() - and (name.startswith('SIG') and not name.startswith('SIG_')) - or name.startswith('CTRL_')) - -_IntEnum._convert_( - 'Handlers', __name__, - lambda name: name in ('SIG_DFL', 'SIG_IGN')) - -if 'pthread_sigmask' in _globals: - _IntEnum._convert_( - 'Sigmasks', __name__, - lambda name: name in ('SIG_BLOCK', 'SIG_UNBLOCK', 'SIG_SETMASK')) - - -def _int_to_enum(value, enum_klass): - """Convert a numeric value to an IntEnum member. - If it's not a known member, return the numeric value itself. - """ - try: - return enum_klass(value) - except ValueError: - return value - - -def _enum_to_int(value): - """Convert an IntEnum member to a numeric value. - If it's not an IntEnum member return the value itself. - """ - try: - return int(value) - except (ValueError, TypeError): - return value - - -# Similar to functools.wraps(), but only assign __doc__. -# __module__ should be preserved, -# __name__ and __qualname__ are already fine, -# __annotations__ is not set. -def _wraps(wrapped): - def decorator(wrapper): - wrapper.__doc__ = wrapped.__doc__ - return wrapper - return decorator - -@_wraps(_signal.signal) -def signal(signalnum, handler): - handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler)) - return _int_to_enum(handler, Handlers) - - -@_wraps(_signal.getsignal) -def getsignal(signalnum): - handler = _signal.getsignal(signalnum) - return _int_to_enum(handler, Handlers) - - -if 'pthread_sigmask' in _globals: - @_wraps(_signal.pthread_sigmask) - def pthread_sigmask(how, mask): - sigs_set = _signal.pthread_sigmask(how, mask) - return set(_int_to_enum(x, Signals) for x in sigs_set) - - -if 'sigpending' in _globals: - @_wraps(_signal.sigpending) - def sigpending(): - return {_int_to_enum(x, Signals) for x in _signal.sigpending()} - - -if 'sigwait' in _globals: - @_wraps(_signal.sigwait) - def sigwait(sigset): - retsig = _signal.sigwait(sigset) - return _int_to_enum(retsig, Signals) - - -if 'valid_signals' in _globals: - @_wraps(_signal.valid_signals) - def valid_signals(): - return {_int_to_enum(x, Signals) for x in _signal.valid_signals()} - - -del _globals, _wraps diff --git a/python/Lib/site.py b/python/Lib/site.py deleted file mode 100644 index 50e5e3d..0000000 --- a/python/Lib/site.py +++ /dev/null @@ -1,673 +0,0 @@ -"""Append module search paths for third-party packages to sys.path. - -**************************************************************** -* This module is automatically imported during initialization. * -**************************************************************** - -This will append site-specific paths to the module search path. On -Unix (including Mac OSX), it starts with sys.prefix and -sys.exec_prefix (if different) and appends -lib/python/site-packages. -On other platforms (such as Windows), it tries each of the -prefixes directly, as well as with lib/site-packages appended. The -resulting directories, if they exist, are appended to sys.path, and -also inspected for path configuration files. - -If a file named "pyvenv.cfg" exists one directory above sys.executable, -sys.prefix and sys.exec_prefix are set to that directory and -it is also checked for site-packages (sys.base_prefix and -sys.base_exec_prefix will always be the "real" prefixes of the Python -installation). If "pyvenv.cfg" (a bootstrap configuration file) contains -the key "include-system-site-packages" set to anything other than "false" -(case-insensitive), the system-level prefixes will still also be -searched for site-packages; otherwise they won't. - -All of the resulting site-specific directories, if they exist, are -appended to sys.path, and also inspected for path configuration -files. - -A path configuration file is a file whose name has the form -.pth; its contents are additional directories (one per line) -to be added to sys.path. Non-existing directories (or -non-directories) are never added to sys.path; no directory is added to -sys.path more than once. Blank lines and lines beginning with -'#' are skipped. Lines starting with 'import' are executed. - -For example, suppose sys.prefix and sys.exec_prefix are set to -/usr/local and there is a directory /usr/local/lib/python2.5/site-packages -with three subdirectories, foo, bar and spam, and two path -configuration files, foo.pth and bar.pth. Assume foo.pth contains the -following: - - # foo package configuration - foo - bar - bletch - -and bar.pth contains: - - # bar package configuration - bar - -Then the following directories are added to sys.path, in this order: - - /usr/local/lib/python2.5/site-packages/bar - /usr/local/lib/python2.5/site-packages/foo - -Note that bletch is omitted because it doesn't exist; bar precedes foo -because bar.pth comes alphabetically before foo.pth; and spam is -omitted because it is not mentioned in either path configuration file. - -The readline module is also automatically configured to enable -completion for systems that support it. This can be overridden in -sitecustomize, usercustomize or PYTHONSTARTUP. Starting Python in -isolated mode (-I) disables automatic readline configuration. - -After these operations, an attempt is made to import a module -named sitecustomize, which can perform arbitrary additional -site-specific customizations. If this import fails with an -ImportError exception, it is silently ignored. -""" - -import sys -import os -import builtins -import _sitebuiltins -import io - -# Prefixes for site-packages; add additional prefixes like /usr/local here -PREFIXES = [sys.prefix, sys.exec_prefix] -# Enable per user site-packages directory -# set it to False to disable the feature or True to force the feature -ENABLE_USER_SITE = None - -# for distutils.commands.install -# These values are initialized by the getuserbase() and getusersitepackages() -# functions, through the main() function when Python starts. -USER_SITE = None -USER_BASE = None - - -def _trace(message): - if sys.flags.verbose: - print(message, file=sys.stderr) - - -def makepath(*paths): - dir = os.path.join(*paths) - try: - dir = os.path.abspath(dir) - except OSError: - pass - return dir, os.path.normcase(dir) - - -def abs_paths(): - """Set all module __file__ and __cached__ attributes to an absolute path""" - for m in set(sys.modules.values()): - loader_module = None - try: - loader_module = m.__loader__.__module__ - except AttributeError: - try: - loader_module = m.__spec__.loader.__module__ - except AttributeError: - pass - if loader_module not in {'_frozen_importlib', '_frozen_importlib_external'}: - continue # don't mess with a PEP 302-supplied __file__ - try: - m.__file__ = os.path.abspath(m.__file__) - except (AttributeError, OSError, TypeError): - pass - try: - m.__cached__ = os.path.abspath(m.__cached__) - except (AttributeError, OSError, TypeError): - pass - - -def removeduppaths(): - """ Remove duplicate entries from sys.path along with making them - absolute""" - # This ensures that the initial path provided by the interpreter contains - # only absolute pathnames, even if we're running from the build directory. - L = [] - known_paths = set() - for dir in sys.path: - # Filter out duplicate paths (on case-insensitive file systems also - # if they only differ in case); turn relative paths into absolute - # paths. - dir, dircase = makepath(dir) - if dircase not in known_paths: - L.append(dir) - known_paths.add(dircase) - sys.path[:] = L - return known_paths - - -def _init_pathinfo(): - """Return a set containing all existing file system items from sys.path.""" - d = set() - for item in sys.path: - try: - if os.path.exists(item): - _, itemcase = makepath(item) - d.add(itemcase) - except TypeError: - continue - return d - - -def addpackage(sitedir, name, known_paths): - """Process a .pth file within the site-packages directory: - For each line in the file, either combine it with sitedir to a path - and add that to known_paths, or execute it if it starts with 'import '. - """ - if known_paths is None: - known_paths = _init_pathinfo() - reset = True - else: - reset = False - fullname = os.path.join(sitedir, name) - _trace(f"Processing .pth file: {fullname!r}") - try: - # locale encoding is not ideal especially on Windows. But we have used - # it for a long time. setuptools uses the locale encoding too. - f = io.TextIOWrapper(io.open_code(fullname), encoding="locale") - except OSError: - return - with f: - for n, line in enumerate(f): - if line.startswith("#"): - continue - if line.strip() == "": - continue - try: - if line.startswith(("import ", "import\t")): - exec(line) - continue - line = line.rstrip() - dir, dircase = makepath(sitedir, line) - if not dircase in known_paths and os.path.exists(dir): - sys.path.append(dir) - known_paths.add(dircase) - except Exception: - print("Error processing line {:d} of {}:\n".format(n+1, fullname), - file=sys.stderr) - import traceback - for record in traceback.format_exception(*sys.exc_info()): - for line in record.splitlines(): - print(' '+line, file=sys.stderr) - print("\nRemainder of file ignored", file=sys.stderr) - break - if reset: - known_paths = None - return known_paths - - -def addsitedir(sitedir, known_paths=None): - """Add 'sitedir' argument to sys.path if missing and handle .pth files in - 'sitedir'""" - _trace(f"Adding directory: {sitedir!r}") - if known_paths is None: - known_paths = _init_pathinfo() - reset = True - else: - reset = False - sitedir, sitedircase = makepath(sitedir) - if not sitedircase in known_paths: - sys.path.append(sitedir) # Add path component - known_paths.add(sitedircase) - try: - names = os.listdir(sitedir) - except OSError: - return - names = [name for name in names if name.endswith(".pth")] - for name in sorted(names): - addpackage(sitedir, name, known_paths) - if reset: - known_paths = None - return known_paths - - -def check_enableusersite(): - """Check if user site directory is safe for inclusion - - The function tests for the command line flag (including environment var), - process uid/gid equal to effective uid/gid. - - None: Disabled for security reasons - False: Disabled by user (command line option) - True: Safe and enabled - """ - if sys.flags.no_user_site: - return False - - if hasattr(os, "getuid") and hasattr(os, "geteuid"): - # check process uid == effective uid - if os.geteuid() != os.getuid(): - return None - if hasattr(os, "getgid") and hasattr(os, "getegid"): - # check process gid == effective gid - if os.getegid() != os.getgid(): - return None - - return True - - -# NOTE: sysconfig and it's dependencies are relatively large but site module -# needs very limited part of them. -# To speedup startup time, we have copy of them. -# -# See https://bugs.python.org/issue29585 - -# Copy of sysconfig._getuserbase() -def _getuserbase(): - env_base = os.environ.get("PYTHONUSERBASE", None) - if env_base: - return env_base - - # Emscripten, VxWorks, and WASI have no home directories - if sys.platform in {"emscripten", "vxworks", "wasi"}: - return None - - def joinuser(*args): - return os.path.expanduser(os.path.join(*args)) - - if os.name == "nt": - base = os.environ.get("APPDATA") or "~" - return joinuser(base, "Python") - - if sys.platform == "darwin" and sys._framework: - return joinuser("~", "Library", sys._framework, - "%d.%d" % sys.version_info[:2]) - - return joinuser("~", ".local") - - -# Same to sysconfig.get_path('purelib', os.name+'_user') -def _get_path(userbase): - version = sys.version_info - - if os.name == 'nt': - ver_nodot = sys.winver.replace('.', '') - return f'{userbase}\\Python{ver_nodot}\\site-packages' - - if sys.platform == 'darwin' and sys._framework: - return f'{userbase}/lib/python/site-packages' - - return f'{userbase}/lib/python{version[0]}.{version[1]}/site-packages' - - -def getuserbase(): - """Returns the `user base` directory path. - - The `user base` directory can be used to store data. If the global - variable ``USER_BASE`` is not initialized yet, this function will also set - it. - """ - global USER_BASE - if USER_BASE is None: - USER_BASE = _getuserbase() - return USER_BASE - - -def getusersitepackages(): - """Returns the user-specific site-packages directory path. - - If the global variable ``USER_SITE`` is not initialized yet, this - function will also set it. - """ - global USER_SITE, ENABLE_USER_SITE - userbase = getuserbase() # this will also set USER_BASE - - if USER_SITE is None: - if userbase is None: - ENABLE_USER_SITE = False # disable user site and return None - else: - USER_SITE = _get_path(userbase) - - return USER_SITE - -def addusersitepackages(known_paths): - """Add a per user site-package to sys.path - - Each user has its own python directory with site-packages in the - home directory. - """ - # get the per user site-package path - # this call will also make sure USER_BASE and USER_SITE are set - _trace("Processing user site-packages") - user_site = getusersitepackages() - - if ENABLE_USER_SITE and os.path.isdir(user_site): - addsitedir(user_site, known_paths) - return known_paths - -def getsitepackages(prefixes=None): - """Returns a list containing all global site-packages directories. - - For each directory present in ``prefixes`` (or the global ``PREFIXES``), - this function will find its `site-packages` subdirectory depending on the - system environment, and will return a list of full paths. - """ - sitepackages = [] - seen = set() - - if prefixes is None: - prefixes = PREFIXES - - for prefix in prefixes: - if not prefix or prefix in seen: - continue - seen.add(prefix) - - if os.sep == '/': - libdirs = [sys.platlibdir] - if sys.platlibdir != "lib": - libdirs.append("lib") - - for libdir in libdirs: - path = os.path.join(prefix, libdir, - "python%d.%d" % sys.version_info[:2], - "site-packages") - sitepackages.append(path) - else: - sitepackages.append(prefix) - sitepackages.append(os.path.join(prefix, "Lib", "site-packages")) - return sitepackages - -def addsitepackages(known_paths, prefixes=None): - """Add site-packages to sys.path""" - _trace("Processing global site-packages") - for sitedir in getsitepackages(prefixes): - if os.path.isdir(sitedir): - addsitedir(sitedir, known_paths) - - return known_paths - -def setquit(): - """Define new builtins 'quit' and 'exit'. - - These are objects which make the interpreter exit when called. - The repr of each object contains a hint at how it works. - - """ - if os.sep == '\\': - eof = 'Ctrl-Z plus Return' - else: - eof = 'Ctrl-D (i.e. EOF)' - - builtins.quit = _sitebuiltins.Quitter('quit', eof) - builtins.exit = _sitebuiltins.Quitter('exit', eof) - - -def setcopyright(): - """Set 'copyright' and 'credits' in builtins""" - builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright) - if sys.platform[:4] == 'java': - builtins.credits = _sitebuiltins._Printer( - "credits", - "Jython is maintained by the Jython developers (www.jython.org).") - else: - builtins.credits = _sitebuiltins._Printer("credits", """\ - Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands - for supporting Python development. See www.python.org for more information.""") - files, dirs = [], [] - # Not all modules are required to have a __file__ attribute. See - # PEP 420 for more details. - here = getattr(sys, '_stdlib_dir', None) - if not here and hasattr(os, '__file__'): - here = os.path.dirname(os.__file__) - if here: - files.extend(["LICENSE.txt", "LICENSE"]) - dirs.extend([os.path.join(here, os.pardir), here, os.curdir]) - builtins.license = _sitebuiltins._Printer( - "license", - "See https://www.python.org/psf/license/", - files, dirs) - - -def sethelper(): - builtins.help = _sitebuiltins._Helper() - -def enablerlcompleter(): - """Enable default readline configuration on interactive prompts, by - registering a sys.__interactivehook__. - - If the readline module can be imported, the hook will set the Tab key - as completion key and register ~/.python_history as history file. - This can be overridden in the sitecustomize or usercustomize module, - or in a PYTHONSTARTUP file. - """ - def register_readline(): - import atexit - try: - import readline - import rlcompleter - except ImportError: - return - - # Reading the initialization (config) file may not be enough to set a - # completion key, so we set one first and then read the file. - readline_doc = getattr(readline, '__doc__', '') - if readline_doc is not None and 'libedit' in readline_doc: - readline.parse_and_bind('bind ^I rl_complete') - else: - readline.parse_and_bind('tab: complete') - - try: - readline.read_init_file() - except OSError: - # An OSError here could have many causes, but the most likely one - # is that there's no .inputrc file (or .editrc file in the case of - # Mac OS X + libedit) in the expected location. In that case, we - # want to ignore the exception. - pass - - if readline.get_current_history_length() == 0: - # If no history was loaded, default to .python_history. - # The guard is necessary to avoid doubling history size at - # each interpreter exit when readline was already configured - # through a PYTHONSTARTUP hook, see: - # http://bugs.python.org/issue5845#msg198636 - history = os.path.join(os.path.expanduser('~'), - '.python_history') - try: - readline.read_history_file(history) - except OSError: - pass - - def write_history(): - try: - readline.write_history_file(history) - except OSError: - # bpo-19891, bpo-41193: Home directory does not exist - # or is not writable, or the filesystem is read-only. - pass - - atexit.register(write_history) - - sys.__interactivehook__ = register_readline - -def venv(known_paths): - global PREFIXES, ENABLE_USER_SITE - - env = os.environ - if sys.platform == 'darwin' and '__PYVENV_LAUNCHER__' in env: - executable = sys._base_executable = os.environ['__PYVENV_LAUNCHER__'] - else: - executable = sys.executable - exe_dir, _ = os.path.split(os.path.abspath(executable)) - site_prefix = os.path.dirname(exe_dir) - sys._home = None - conf_basename = 'pyvenv.cfg' - candidate_confs = [ - conffile for conffile in ( - os.path.join(exe_dir, conf_basename), - os.path.join(site_prefix, conf_basename) - ) - if os.path.isfile(conffile) - ] - - if candidate_confs: - virtual_conf = candidate_confs[0] - system_site = "true" - # Issue 25185: Use UTF-8, as that's what the venv module uses when - # writing the file. - with open(virtual_conf, encoding='utf-8') as f: - for line in f: - if '=' in line: - key, _, value = line.partition('=') - key = key.strip().lower() - value = value.strip() - if key == 'include-system-site-packages': - system_site = value.lower() - elif key == 'home': - sys._home = value - - sys.prefix = sys.exec_prefix = site_prefix - - # Doing this here ensures venv takes precedence over user-site - addsitepackages(known_paths, [sys.prefix]) - - # addsitepackages will process site_prefix again if its in PREFIXES, - # but that's ok; known_paths will prevent anything being added twice - if system_site == "true": - PREFIXES.insert(0, sys.prefix) - else: - PREFIXES = [sys.prefix] - ENABLE_USER_SITE = False - - return known_paths - - -def execsitecustomize(): - """Run custom site specific code, if available.""" - try: - try: - import sitecustomize - except ImportError as exc: - if exc.name == 'sitecustomize': - pass - else: - raise - except Exception as err: - if sys.flags.verbose: - sys.excepthook(*sys.exc_info()) - else: - sys.stderr.write( - "Error in sitecustomize; set PYTHONVERBOSE for traceback:\n" - "%s: %s\n" % - (err.__class__.__name__, err)) - - -def execusercustomize(): - """Run custom user specific code, if available.""" - try: - try: - import usercustomize - except ImportError as exc: - if exc.name == 'usercustomize': - pass - else: - raise - except Exception as err: - if sys.flags.verbose: - sys.excepthook(*sys.exc_info()) - else: - sys.stderr.write( - "Error in usercustomize; set PYTHONVERBOSE for traceback:\n" - "%s: %s\n" % - (err.__class__.__name__, err)) - - -def main(): - """Add standard site-specific directories to the module search path. - - This function is called automatically when this module is imported, - unless the python interpreter was started with the -S flag. - """ - global ENABLE_USER_SITE - - orig_path = sys.path[:] - known_paths = removeduppaths() - if orig_path != sys.path: - # removeduppaths() might make sys.path absolute. - # fix __file__ and __cached__ of already imported modules too. - abs_paths() - - known_paths = venv(known_paths) - if ENABLE_USER_SITE is None: - ENABLE_USER_SITE = check_enableusersite() - known_paths = addusersitepackages(known_paths) - known_paths = addsitepackages(known_paths) - setquit() - setcopyright() - sethelper() - if not sys.flags.isolated: - enablerlcompleter() - execsitecustomize() - if ENABLE_USER_SITE: - execusercustomize() - -# Prevent extending of sys.path when python was started with -S and -# site is imported later. -if not sys.flags.no_site: - main() - -def _script(): - help = """\ - %s [--user-base] [--user-site] - - Without arguments print some useful information - With arguments print the value of USER_BASE and/or USER_SITE separated - by '%s'. - - Exit codes with --user-base or --user-site: - 0 - user site directory is enabled - 1 - user site directory is disabled by user - 2 - user site directory is disabled by super user - or for security reasons - >2 - unknown error - """ - args = sys.argv[1:] - if not args: - user_base = getuserbase() - user_site = getusersitepackages() - print("sys.path = [") - for dir in sys.path: - print(" %r," % (dir,)) - print("]") - def exists(path): - if path is not None and os.path.isdir(path): - return "exists" - else: - return "doesn't exist" - print(f"USER_BASE: {user_base!r} ({exists(user_base)})") - print(f"USER_SITE: {user_site!r} ({exists(user_site)})") - print(f"ENABLE_USER_SITE: {ENABLE_USER_SITE!r}") - sys.exit(0) - - buffer = [] - if '--user-base' in args: - buffer.append(USER_BASE) - if '--user-site' in args: - buffer.append(USER_SITE) - - if buffer: - print(os.pathsep.join(buffer)) - if ENABLE_USER_SITE: - sys.exit(0) - elif ENABLE_USER_SITE is False: - sys.exit(1) - elif ENABLE_USER_SITE is None: - sys.exit(2) - else: - sys.exit(3) - else: - import textwrap - print(textwrap.dedent(help % (sys.argv[0], os.pathsep))) - sys.exit(10) - -if __name__ == '__main__': - _script() diff --git a/python/Lib/socket.py b/python/Lib/socket.py deleted file mode 100644 index 5965fea..0000000 --- a/python/Lib/socket.py +++ /dev/null @@ -1,967 +0,0 @@ -# Wrapper module for _socket, providing some additional facilities -# implemented in Python. - -"""\ -This module provides socket operations and some related functions. -On Unix, it supports IP (Internet Protocol) and Unix domain sockets. -On other systems, it only supports IP. Functions specific for a -socket are available as methods of the socket object. - -Functions: - -socket() -- create a new socket object -socketpair() -- create a pair of new socket objects [*] -fromfd() -- create a socket object from an open file descriptor [*] -send_fds() -- Send file descriptor to the socket. -recv_fds() -- Receive file descriptors from the socket. -fromshare() -- create a socket object from data received from socket.share() [*] -gethostname() -- return the current hostname -gethostbyname() -- map a hostname to its IP number -gethostbyaddr() -- map an IP number or hostname to DNS info -getservbyname() -- map a service name and a protocol name to a port number -getprotobyname() -- map a protocol name (e.g. 'tcp') to a number -ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order -htons(), htonl() -- convert 16, 32 bit int from host to network byte order -inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format -inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89) -socket.getdefaulttimeout() -- get the default timeout value -socket.setdefaulttimeout() -- set the default timeout value -create_connection() -- connects to an address, with an optional timeout and - optional source address. - - [*] not available on all platforms! - -Special objects: - -SocketType -- type object for socket objects -error -- exception raised for I/O errors -has_ipv6 -- boolean value indicating if IPv6 is supported - -IntEnum constants: - -AF_INET, AF_UNIX -- socket domains (first argument to socket() call) -SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument) - -Integer constants: - -Many other constants may be defined; these may be used in calls to -the setsockopt() and getsockopt() methods. -""" - -import _socket -from _socket import * - -import os, sys, io, selectors -from enum import IntEnum, IntFlag - -try: - import errno -except ImportError: - errno = None -EBADF = getattr(errno, 'EBADF', 9) -EAGAIN = getattr(errno, 'EAGAIN', 11) -EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11) - -__all__ = ["fromfd", "getfqdn", "create_connection", "create_server", - "has_dualstack_ipv6", "AddressFamily", "SocketKind"] -__all__.extend(os._get_exports_list(_socket)) - -# Set up the socket.AF_* socket.SOCK_* constants as members of IntEnums for -# nicer string representations. -# Note that _socket only knows about the integer values. The public interface -# in this module understands the enums and translates them back from integers -# where needed (e.g. .family property of a socket object). - -IntEnum._convert_( - 'AddressFamily', - __name__, - lambda C: C.isupper() and C.startswith('AF_')) - -IntEnum._convert_( - 'SocketKind', - __name__, - lambda C: C.isupper() and C.startswith('SOCK_')) - -IntFlag._convert_( - 'MsgFlag', - __name__, - lambda C: C.isupper() and C.startswith('MSG_')) - -IntFlag._convert_( - 'AddressInfo', - __name__, - lambda C: C.isupper() and C.startswith('AI_')) - -_LOCALHOST = '127.0.0.1' -_LOCALHOST_V6 = '::1' - - -def _intenum_converter(value, enum_klass): - """Convert a numeric family value to an IntEnum member. - - If it's not a known member, return the numeric value itself. - """ - try: - return enum_klass(value) - except ValueError: - return value - - -# WSA error codes -if sys.platform.lower().startswith("win"): - errorTab = {} - errorTab[6] = "Specified event object handle is invalid." - errorTab[8] = "Insufficient memory available." - errorTab[87] = "One or more parameters are invalid." - errorTab[995] = "Overlapped operation aborted." - errorTab[996] = "Overlapped I/O event object not in signaled state." - errorTab[997] = "Overlapped operation will complete later." - errorTab[10004] = "The operation was interrupted." - errorTab[10009] = "A bad file handle was passed." - errorTab[10013] = "Permission denied." - errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT - errorTab[10022] = "An invalid operation was attempted." - errorTab[10024] = "Too many open files." - errorTab[10035] = "The socket operation would block." - errorTab[10036] = "A blocking operation is already in progress." - errorTab[10037] = "Operation already in progress." - errorTab[10038] = "Socket operation on nonsocket." - errorTab[10039] = "Destination address required." - errorTab[10040] = "Message too long." - errorTab[10041] = "Protocol wrong type for socket." - errorTab[10042] = "Bad protocol option." - errorTab[10043] = "Protocol not supported." - errorTab[10044] = "Socket type not supported." - errorTab[10045] = "Operation not supported." - errorTab[10046] = "Protocol family not supported." - errorTab[10047] = "Address family not supported by protocol family." - errorTab[10048] = "The network address is in use." - errorTab[10049] = "Cannot assign requested address." - errorTab[10050] = "Network is down." - errorTab[10051] = "Network is unreachable." - errorTab[10052] = "Network dropped connection on reset." - errorTab[10053] = "Software caused connection abort." - errorTab[10054] = "The connection has been reset." - errorTab[10055] = "No buffer space available." - errorTab[10056] = "Socket is already connected." - errorTab[10057] = "Socket is not connected." - errorTab[10058] = "The network has been shut down." - errorTab[10059] = "Too many references." - errorTab[10060] = "The operation timed out." - errorTab[10061] = "Connection refused." - errorTab[10062] = "Cannot translate name." - errorTab[10063] = "The name is too long." - errorTab[10064] = "The host is down." - errorTab[10065] = "The host is unreachable." - errorTab[10066] = "Directory not empty." - errorTab[10067] = "Too many processes." - errorTab[10068] = "User quota exceeded." - errorTab[10069] = "Disk quota exceeded." - errorTab[10070] = "Stale file handle reference." - errorTab[10071] = "Item is remote." - errorTab[10091] = "Network subsystem is unavailable." - errorTab[10092] = "Winsock.dll version out of range." - errorTab[10093] = "Successful WSAStartup not yet performed." - errorTab[10101] = "Graceful shutdown in progress." - errorTab[10102] = "No more results from WSALookupServiceNext." - errorTab[10103] = "Call has been canceled." - errorTab[10104] = "Procedure call table is invalid." - errorTab[10105] = "Service provider is invalid." - errorTab[10106] = "Service provider failed to initialize." - errorTab[10107] = "System call failure." - errorTab[10108] = "Service not found." - errorTab[10109] = "Class type not found." - errorTab[10110] = "No more results from WSALookupServiceNext." - errorTab[10111] = "Call was canceled." - errorTab[10112] = "Database query was refused." - errorTab[11001] = "Host not found." - errorTab[11002] = "Nonauthoritative host not found." - errorTab[11003] = "This is a nonrecoverable error." - errorTab[11004] = "Valid name, no data record requested type." - errorTab[11005] = "QoS receivers." - errorTab[11006] = "QoS senders." - errorTab[11007] = "No QoS senders." - errorTab[11008] = "QoS no receivers." - errorTab[11009] = "QoS request confirmed." - errorTab[11010] = "QoS admission error." - errorTab[11011] = "QoS policy failure." - errorTab[11012] = "QoS bad style." - errorTab[11013] = "QoS bad object." - errorTab[11014] = "QoS traffic control error." - errorTab[11015] = "QoS generic error." - errorTab[11016] = "QoS service type error." - errorTab[11017] = "QoS flowspec error." - errorTab[11018] = "Invalid QoS provider buffer." - errorTab[11019] = "Invalid QoS filter style." - errorTab[11020] = "Invalid QoS filter style." - errorTab[11021] = "Incorrect QoS filter count." - errorTab[11022] = "Invalid QoS object length." - errorTab[11023] = "Incorrect QoS flow count." - errorTab[11024] = "Unrecognized QoS object." - errorTab[11025] = "Invalid QoS policy object." - errorTab[11026] = "Invalid QoS flow descriptor." - errorTab[11027] = "Invalid QoS provider-specific flowspec." - errorTab[11028] = "Invalid QoS provider-specific filterspec." - errorTab[11029] = "Invalid QoS shape discard mode object." - errorTab[11030] = "Invalid QoS shaping rate object." - errorTab[11031] = "Reserved policy QoS element type." - __all__.append("errorTab") - - -class _GiveupOnSendfile(Exception): pass - - -class socket(_socket.socket): - - """A subclass of _socket.socket adding the makefile() method.""" - - __slots__ = ["__weakref__", "_io_refs", "_closed"] - - def __init__(self, family=-1, type=-1, proto=-1, fileno=None): - # For user code address family and type values are IntEnum members, but - # for the underlying _socket.socket they're just integers. The - # constructor of _socket.socket converts the given argument to an - # integer automatically. - if fileno is None: - if family == -1: - family = AF_INET - if type == -1: - type = SOCK_STREAM - if proto == -1: - proto = 0 - _socket.socket.__init__(self, family, type, proto, fileno) - self._io_refs = 0 - self._closed = False - - def __enter__(self): - return self - - def __exit__(self, *args): - if not self._closed: - self.close() - - def __repr__(self): - """Wrap __repr__() to reveal the real class name and socket - address(es). - """ - closed = getattr(self, '_closed', False) - s = "<%s.%s%s fd=%i, family=%s, type=%s, proto=%i" \ - % (self.__class__.__module__, - self.__class__.__qualname__, - " [closed]" if closed else "", - self.fileno(), - self.family, - self.type, - self.proto) - if not closed: - # getsockname and getpeername may not be available on WASI. - try: - laddr = self.getsockname() - if laddr: - s += ", laddr=%s" % str(laddr) - except (error, AttributeError): - pass - try: - raddr = self.getpeername() - if raddr: - s += ", raddr=%s" % str(raddr) - except (error, AttributeError): - pass - s += '>' - return s - - def __getstate__(self): - raise TypeError(f"cannot pickle {self.__class__.__name__!r} object") - - def dup(self): - """dup() -> socket object - - Duplicate the socket. Return a new socket object connected to the same - system resource. The new socket is non-inheritable. - """ - fd = dup(self.fileno()) - sock = self.__class__(self.family, self.type, self.proto, fileno=fd) - sock.settimeout(self.gettimeout()) - return sock - - def accept(self): - """accept() -> (socket object, address info) - - Wait for an incoming connection. Return a new socket - representing the connection, and the address of the client. - For IP sockets, the address info is a pair (hostaddr, port). - """ - fd, addr = self._accept() - sock = socket(self.family, self.type, self.proto, fileno=fd) - # Issue #7995: if no default timeout is set and the listening - # socket had a (non-zero) timeout, force the new socket in blocking - # mode to override platform-specific socket flags inheritance. - if getdefaulttimeout() is None and self.gettimeout(): - sock.setblocking(True) - return sock, addr - - def makefile(self, mode="r", buffering=None, *, - encoding=None, errors=None, newline=None): - """makefile(...) -> an I/O stream connected to the socket - - The arguments are as for io.open() after the filename, except the only - supported mode values are 'r' (default), 'w' and 'b'. - """ - # XXX refactor to share code? - if not set(mode) <= {"r", "w", "b"}: - raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,)) - writing = "w" in mode - reading = "r" in mode or not writing - assert reading or writing - binary = "b" in mode - rawmode = "" - if reading: - rawmode += "r" - if writing: - rawmode += "w" - raw = SocketIO(self, rawmode) - self._io_refs += 1 - if buffering is None: - buffering = -1 - if buffering < 0: - buffering = io.DEFAULT_BUFFER_SIZE - if buffering == 0: - if not binary: - raise ValueError("unbuffered streams must be binary") - return raw - if reading and writing: - buffer = io.BufferedRWPair(raw, raw, buffering) - elif reading: - buffer = io.BufferedReader(raw, buffering) - else: - assert writing - buffer = io.BufferedWriter(raw, buffering) - if binary: - return buffer - encoding = io.text_encoding(encoding) - text = io.TextIOWrapper(buffer, encoding, errors, newline) - text.mode = mode - return text - - if hasattr(os, 'sendfile'): - - def _sendfile_use_sendfile(self, file, offset=0, count=None): - self._check_sendfile_params(file, offset, count) - sockno = self.fileno() - try: - fileno = file.fileno() - except (AttributeError, io.UnsupportedOperation) as err: - raise _GiveupOnSendfile(err) # not a regular file - try: - fsize = os.fstat(fileno).st_size - except OSError as err: - raise _GiveupOnSendfile(err) # not a regular file - if not fsize: - return 0 # empty file - # Truncate to 1GiB to avoid OverflowError, see bpo-38319. - blocksize = min(count or fsize, 2 ** 30) - timeout = self.gettimeout() - if timeout == 0: - raise ValueError("non-blocking sockets are not supported") - # poll/select have the advantage of not requiring any - # extra file descriptor, contrarily to epoll/kqueue - # (also, they require a single syscall). - if hasattr(selectors, 'PollSelector'): - selector = selectors.PollSelector() - else: - selector = selectors.SelectSelector() - selector.register(sockno, selectors.EVENT_WRITE) - - total_sent = 0 - # localize variable access to minimize overhead - selector_select = selector.select - os_sendfile = os.sendfile - try: - while True: - if timeout and not selector_select(timeout): - raise TimeoutError('timed out') - if count: - blocksize = count - total_sent - if blocksize <= 0: - break - try: - sent = os_sendfile(sockno, fileno, offset, blocksize) - except BlockingIOError: - if not timeout: - # Block until the socket is ready to send some - # data; avoids hogging CPU resources. - selector_select() - continue - except OSError as err: - if total_sent == 0: - # We can get here for different reasons, the main - # one being 'file' is not a regular mmap(2)-like - # file, in which case we'll fall back on using - # plain send(). - raise _GiveupOnSendfile(err) - raise err from None - else: - if sent == 0: - break # EOF - offset += sent - total_sent += sent - return total_sent - finally: - if total_sent > 0 and hasattr(file, 'seek'): - file.seek(offset) - else: - def _sendfile_use_sendfile(self, file, offset=0, count=None): - raise _GiveupOnSendfile( - "os.sendfile() not available on this platform") - - def _sendfile_use_send(self, file, offset=0, count=None): - self._check_sendfile_params(file, offset, count) - if self.gettimeout() == 0: - raise ValueError("non-blocking sockets are not supported") - if offset: - file.seek(offset) - blocksize = min(count, 8192) if count else 8192 - total_sent = 0 - # localize variable access to minimize overhead - file_read = file.read - sock_send = self.send - try: - while True: - if count: - blocksize = min(count - total_sent, blocksize) - if blocksize <= 0: - break - data = memoryview(file_read(blocksize)) - if not data: - break # EOF - while True: - try: - sent = sock_send(data) - except BlockingIOError: - continue - else: - total_sent += sent - if sent < len(data): - data = data[sent:] - else: - break - return total_sent - finally: - if total_sent > 0 and hasattr(file, 'seek'): - file.seek(offset + total_sent) - - def _check_sendfile_params(self, file, offset, count): - if 'b' not in getattr(file, 'mode', 'b'): - raise ValueError("file should be opened in binary mode") - if not self.type & SOCK_STREAM: - raise ValueError("only SOCK_STREAM type sockets are supported") - if count is not None: - if not isinstance(count, int): - raise TypeError( - "count must be a positive integer (got {!r})".format(count)) - if count <= 0: - raise ValueError( - "count must be a positive integer (got {!r})".format(count)) - - def sendfile(self, file, offset=0, count=None): - """sendfile(file[, offset[, count]]) -> sent - - Send a file until EOF is reached by using high-performance - os.sendfile() and return the total number of bytes which - were sent. - *file* must be a regular file object opened in binary mode. - If os.sendfile() is not available (e.g. Windows) or file is - not a regular file socket.send() will be used instead. - *offset* tells from where to start reading the file. - If specified, *count* is the total number of bytes to transmit - as opposed to sending the file until EOF is reached. - File position is updated on return or also in case of error in - which case file.tell() can be used to figure out the number of - bytes which were sent. - The socket must be of SOCK_STREAM type. - Non-blocking sockets are not supported. - """ - try: - return self._sendfile_use_sendfile(file, offset, count) - except _GiveupOnSendfile: - return self._sendfile_use_send(file, offset, count) - - def _decref_socketios(self): - if self._io_refs > 0: - self._io_refs -= 1 - if self._closed: - self.close() - - def _real_close(self, _ss=_socket.socket): - # This function should not reference any globals. See issue #808164. - _ss.close(self) - - def close(self): - # This function should not reference any globals. See issue #808164. - self._closed = True - if self._io_refs <= 0: - self._real_close() - - def detach(self): - """detach() -> file descriptor - - Close the socket object without closing the underlying file descriptor. - The object cannot be used after this call, but the file descriptor - can be reused for other purposes. The file descriptor is returned. - """ - self._closed = True - return super().detach() - - @property - def family(self): - """Read-only access to the address family for this socket. - """ - return _intenum_converter(super().family, AddressFamily) - - @property - def type(self): - """Read-only access to the socket type. - """ - return _intenum_converter(super().type, SocketKind) - - if os.name == 'nt': - def get_inheritable(self): - return os.get_handle_inheritable(self.fileno()) - def set_inheritable(self, inheritable): - os.set_handle_inheritable(self.fileno(), inheritable) - else: - def get_inheritable(self): - return os.get_inheritable(self.fileno()) - def set_inheritable(self, inheritable): - os.set_inheritable(self.fileno(), inheritable) - get_inheritable.__doc__ = "Get the inheritable flag of the socket" - set_inheritable.__doc__ = "Set the inheritable flag of the socket" - -def fromfd(fd, family, type, proto=0): - """ fromfd(fd, family, type[, proto]) -> socket object - - Create a socket object from a duplicate of the given file - descriptor. The remaining arguments are the same as for socket(). - """ - nfd = dup(fd) - return socket(family, type, proto, nfd) - -if hasattr(_socket.socket, "sendmsg"): - import array - - def send_fds(sock, buffers, fds, flags=0, address=None): - """ send_fds(sock, buffers, fds[, flags[, address]]) -> integer - - Send the list of file descriptors fds over an AF_UNIX socket. - """ - return sock.sendmsg(buffers, [(_socket.SOL_SOCKET, - _socket.SCM_RIGHTS, array.array("i", fds))]) - __all__.append("send_fds") - -if hasattr(_socket.socket, "recvmsg"): - import array - - def recv_fds(sock, bufsize, maxfds, flags=0): - """ recv_fds(sock, bufsize, maxfds[, flags]) -> (data, list of file - descriptors, msg_flags, address) - - Receive up to maxfds file descriptors returning the message - data and a list containing the descriptors. - """ - # Array of ints - fds = array.array("i") - msg, ancdata, flags, addr = sock.recvmsg(bufsize, - _socket.CMSG_LEN(maxfds * fds.itemsize)) - for cmsg_level, cmsg_type, cmsg_data in ancdata: - if (cmsg_level == _socket.SOL_SOCKET and cmsg_type == _socket.SCM_RIGHTS): - fds.frombytes(cmsg_data[: - len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) - - return msg, list(fds), flags, addr - __all__.append("recv_fds") - -if hasattr(_socket.socket, "share"): - def fromshare(info): - """ fromshare(info) -> socket object - - Create a socket object from the bytes object returned by - socket.share(pid). - """ - return socket(0, 0, 0, info) - __all__.append("fromshare") - -if hasattr(_socket, "socketpair"): - - def socketpair(family=None, type=SOCK_STREAM, proto=0): - """socketpair([family[, type[, proto]]]) -> (socket object, socket object) - - Create a pair of socket objects from the sockets returned by the platform - socketpair() function. - The arguments are the same as for socket() except the default family is - AF_UNIX if defined on the platform; otherwise, the default is AF_INET. - """ - if family is None: - try: - family = AF_UNIX - except NameError: - family = AF_INET - a, b = _socket.socketpair(family, type, proto) - a = socket(family, type, proto, a.detach()) - b = socket(family, type, proto, b.detach()) - return a, b - -else: - - # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain. - def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0): - if family == AF_INET: - host = _LOCALHOST - elif family == AF_INET6: - host = _LOCALHOST_V6 - else: - raise ValueError("Only AF_INET and AF_INET6 socket address families " - "are supported") - if type != SOCK_STREAM: - raise ValueError("Only SOCK_STREAM socket type is supported") - if proto != 0: - raise ValueError("Only protocol zero is supported") - - # We create a connected TCP socket. Note the trick with - # setblocking(False) that prevents us from having to create a thread. - lsock = socket(family, type, proto) - try: - lsock.bind((host, 0)) - lsock.listen() - # On IPv6, ignore flow_info and scope_id - addr, port = lsock.getsockname()[:2] - csock = socket(family, type, proto) - try: - csock.setblocking(False) - try: - csock.connect((addr, port)) - except (BlockingIOError, InterruptedError): - pass - csock.setblocking(True) - ssock, _ = lsock.accept() - except: - csock.close() - raise - finally: - lsock.close() - return (ssock, csock) - __all__.append("socketpair") - -socketpair.__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object) -Create a pair of socket objects from the sockets returned by the platform -socketpair() function. -The arguments are the same as for socket() except the default family is AF_UNIX -if defined on the platform; otherwise, the default is AF_INET. -""" - -_blocking_errnos = { EAGAIN, EWOULDBLOCK } - -class SocketIO(io.RawIOBase): - - """Raw I/O implementation for stream sockets. - - This class supports the makefile() method on sockets. It provides - the raw I/O interface on top of a socket object. - """ - - # One might wonder why not let FileIO do the job instead. There are two - # main reasons why FileIO is not adapted: - # - it wouldn't work under Windows (where you can't used read() and - # write() on a socket handle) - # - it wouldn't work with socket timeouts (FileIO would ignore the - # timeout and consider the socket non-blocking) - - # XXX More docs - - def __init__(self, sock, mode): - if mode not in ("r", "w", "rw", "rb", "wb", "rwb"): - raise ValueError("invalid mode: %r" % mode) - io.RawIOBase.__init__(self) - self._sock = sock - if "b" not in mode: - mode += "b" - self._mode = mode - self._reading = "r" in mode - self._writing = "w" in mode - self._timeout_occurred = False - - def readinto(self, b): - """Read up to len(b) bytes into the writable buffer *b* and return - the number of bytes read. If the socket is non-blocking and no bytes - are available, None is returned. - - If *b* is non-empty, a 0 return value indicates that the connection - was shutdown at the other end. - """ - self._checkClosed() - self._checkReadable() - if self._timeout_occurred: - raise OSError("cannot read from timed out object") - while True: - try: - return self._sock.recv_into(b) - except timeout: - self._timeout_occurred = True - raise - except error as e: - if e.errno in _blocking_errnos: - return None - raise - - def write(self, b): - """Write the given bytes or bytearray object *b* to the socket - and return the number of bytes written. This can be less than - len(b) if not all data could be written. If the socket is - non-blocking and no bytes could be written None is returned. - """ - self._checkClosed() - self._checkWritable() - try: - return self._sock.send(b) - except error as e: - # XXX what about EINTR? - if e.errno in _blocking_errnos: - return None - raise - - def readable(self): - """True if the SocketIO is open for reading. - """ - if self.closed: - raise ValueError("I/O operation on closed socket.") - return self._reading - - def writable(self): - """True if the SocketIO is open for writing. - """ - if self.closed: - raise ValueError("I/O operation on closed socket.") - return self._writing - - def seekable(self): - """True if the SocketIO is open for seeking. - """ - if self.closed: - raise ValueError("I/O operation on closed socket.") - return super().seekable() - - def fileno(self): - """Return the file descriptor of the underlying socket. - """ - self._checkClosed() - return self._sock.fileno() - - @property - def name(self): - if not self.closed: - return self.fileno() - else: - return -1 - - @property - def mode(self): - return self._mode - - def close(self): - """Close the SocketIO object. This doesn't close the underlying - socket, except if all references to it have disappeared. - """ - if self.closed: - return - io.RawIOBase.close(self) - self._sock._decref_socketios() - self._sock = None - - -def getfqdn(name=''): - """Get fully qualified domain name from name. - - An empty argument is interpreted as meaning the local host. - - First the hostname returned by gethostbyaddr() is checked, then - possibly existing aliases. In case no FQDN is available and `name` - was given, it is returned unchanged. If `name` was empty or '0.0.0.0', - hostname from gethostname() is returned. - """ - name = name.strip() - if not name or name == '0.0.0.0': - name = gethostname() - try: - hostname, aliases, ipaddrs = gethostbyaddr(name) - except error: - pass - else: - aliases.insert(0, hostname) - for name in aliases: - if '.' in name: - break - else: - name = hostname - return name - - -_GLOBAL_DEFAULT_TIMEOUT = object() - -def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, - source_address=None, *, all_errors=False): - """Connect to *address* and return the socket object. - - Convenience function. Connect to *address* (a 2-tuple ``(host, - port)``) and return the socket object. Passing the optional - *timeout* parameter will set the timeout on the socket instance - before attempting to connect. If no *timeout* is supplied, the - global default timeout setting returned by :func:`getdefaulttimeout` - is used. If *source_address* is set it must be a tuple of (host, port) - for the socket to bind as a source address before making the connection. - A host of '' or port 0 tells the OS to use the default. When a connection - cannot be created, raises the last error if *all_errors* is False, - and an ExceptionGroup of all errors if *all_errors* is True. - """ - - host, port = address - exceptions = [] - for res in getaddrinfo(host, port, 0, SOCK_STREAM): - af, socktype, proto, canonname, sa = res - sock = None - try: - sock = socket(af, socktype, proto) - if timeout is not _GLOBAL_DEFAULT_TIMEOUT: - sock.settimeout(timeout) - if source_address: - sock.bind(source_address) - sock.connect(sa) - # Break explicitly a reference cycle - exceptions.clear() - return sock - - except error as exc: - if not all_errors: - exceptions.clear() # raise only the last error - exceptions.append(exc) - if sock is not None: - sock.close() - - if len(exceptions): - try: - if not all_errors: - raise exceptions[0] - raise ExceptionGroup("create_connection failed", exceptions) - finally: - # Break explicitly a reference cycle - exceptions.clear() - else: - raise error("getaddrinfo returns an empty list") - - -def has_dualstack_ipv6(): - """Return True if the platform supports creating a SOCK_STREAM socket - which can handle both AF_INET and AF_INET6 (IPv4 / IPv6) connections. - """ - if not has_ipv6 \ - or not hasattr(_socket, 'IPPROTO_IPV6') \ - or not hasattr(_socket, 'IPV6_V6ONLY'): - return False - try: - with socket(AF_INET6, SOCK_STREAM) as sock: - sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 0) - return True - except error: - return False - - -def create_server(address, *, family=AF_INET, backlog=None, reuse_port=False, - dualstack_ipv6=False): - """Convenience function which creates a SOCK_STREAM type socket - bound to *address* (a 2-tuple (host, port)) and return the socket - object. - - *family* should be either AF_INET or AF_INET6. - *backlog* is the queue size passed to socket.listen(). - *reuse_port* dictates whether to use the SO_REUSEPORT socket option. - *dualstack_ipv6*: if true and the platform supports it, it will - create an AF_INET6 socket able to accept both IPv4 or IPv6 - connections. When false it will explicitly disable this option on - platforms that enable it by default (e.g. Linux). - - >>> with create_server(('', 8000)) as server: - ... while True: - ... conn, addr = server.accept() - ... # handle new connection - """ - if reuse_port and not hasattr(_socket, "SO_REUSEPORT"): - raise ValueError("SO_REUSEPORT not supported on this platform") - if dualstack_ipv6: - if not has_dualstack_ipv6(): - raise ValueError("dualstack_ipv6 not supported on this platform") - if family != AF_INET6: - raise ValueError("dualstack_ipv6 requires AF_INET6 family") - sock = socket(family, SOCK_STREAM) - try: - # Note about Windows. We don't set SO_REUSEADDR because: - # 1) It's unnecessary: bind() will succeed even in case of a - # previous closed socket on the same address and still in - # TIME_WAIT state. - # 2) If set, another socket is free to bind() on the same - # address, effectively preventing this one from accepting - # connections. Also, it may set the process in a state where - # it'll no longer respond to any signals or graceful kills. - # See: msdn2.microsoft.com/en-us/library/ms740621(VS.85).aspx - if os.name not in ('nt', 'cygwin') and \ - hasattr(_socket, 'SO_REUSEADDR'): - try: - sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) - except error: - # Fail later on bind(), for platforms which may not - # support this option. - pass - if reuse_port: - sock.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1) - if has_ipv6 and family == AF_INET6: - if dualstack_ipv6: - sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 0) - elif hasattr(_socket, "IPV6_V6ONLY") and \ - hasattr(_socket, "IPPROTO_IPV6"): - sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 1) - try: - sock.bind(address) - except error as err: - msg = '%s (while attempting to bind on address %r)' % \ - (err.strerror, address) - raise error(err.errno, msg) from None - if backlog is None: - sock.listen() - else: - sock.listen(backlog) - return sock - except error: - sock.close() - raise - - -def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): - """Resolve host and port into list of address info entries. - - Translate the host/port argument into a sequence of 5-tuples that contain - all the necessary arguments for creating a socket connected to that service. - host is a domain name, a string representation of an IPv4/v6 address or - None. port is a string service name such as 'http', a numeric port number or - None. By passing None as the value of host and port, you can pass NULL to - the underlying C API. - - The family, type and proto arguments can be optionally specified in order to - narrow the list of addresses returned. Passing zero as a value for each of - these arguments selects the full range of results. - """ - # We override this function since we want to translate the numeric family - # and socket type values to enum constants. - addrlist = [] - for res in _socket.getaddrinfo(host, port, family, type, proto, flags): - af, socktype, proto, canonname, sa = res - addrlist.append((_intenum_converter(af, AddressFamily), - _intenum_converter(socktype, SocketKind), - proto, canonname, sa)) - return addrlist diff --git a/python/Lib/socketserver.py b/python/Lib/socketserver.py deleted file mode 100644 index ccc42ef..0000000 --- a/python/Lib/socketserver.py +++ /dev/null @@ -1,852 +0,0 @@ -"""Generic socket server classes. - -This module tries to capture the various aspects of defining a server: - -For socket-based servers: - -- address family: - - AF_INET{,6}: IP (Internet Protocol) sockets (default) - - AF_UNIX: Unix domain sockets - - others, e.g. AF_DECNET are conceivable (see -- socket type: - - SOCK_STREAM (reliable stream, e.g. TCP) - - SOCK_DGRAM (datagrams, e.g. UDP) - -For request-based servers (including socket-based): - -- client address verification before further looking at the request - (This is actually a hook for any processing that needs to look - at the request before anything else, e.g. logging) -- how to handle multiple requests: - - synchronous (one request is handled at a time) - - forking (each request is handled by a new process) - - threading (each request is handled by a new thread) - -The classes in this module favor the server type that is simplest to -write: a synchronous TCP/IP server. This is bad class design, but -saves some typing. (There's also the issue that a deep class hierarchy -slows down method lookups.) - -There are five classes in an inheritance diagram, four of which represent -synchronous servers of four types: - - +------------+ - | BaseServer | - +------------+ - | - v - +-----------+ +------------------+ - | TCPServer |------->| UnixStreamServer | - +-----------+ +------------------+ - | - v - +-----------+ +--------------------+ - | UDPServer |------->| UnixDatagramServer | - +-----------+ +--------------------+ - -Note that UnixDatagramServer derives from UDPServer, not from -UnixStreamServer -- the only difference between an IP and a Unix -stream server is the address family, which is simply repeated in both -unix server classes. - -Forking and threading versions of each type of server can be created -using the ForkingMixIn and ThreadingMixIn mix-in classes. For -instance, a threading UDP server class is created as follows: - - class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass - -The Mix-in class must come first, since it overrides a method defined -in UDPServer! Setting the various member variables also changes -the behavior of the underlying server mechanism. - -To implement a service, you must derive a class from -BaseRequestHandler and redefine its handle() method. You can then run -various versions of the service by combining one of the server classes -with your request handler class. - -The request handler class must be different for datagram or stream -services. This can be hidden by using the request handler -subclasses StreamRequestHandler or DatagramRequestHandler. - -Of course, you still have to use your head! - -For instance, it makes no sense to use a forking server if the service -contains state in memory that can be modified by requests (since the -modifications in the child process would never reach the initial state -kept in the parent process and passed to each child). In this case, -you can use a threading server, but you will probably have to use -locks to avoid two requests that come in nearly simultaneous to apply -conflicting changes to the server state. - -On the other hand, if you are building e.g. an HTTP server, where all -data is stored externally (e.g. in the file system), a synchronous -class will essentially render the service "deaf" while one request is -being handled -- which may be for a very long time if a client is slow -to read all the data it has requested. Here a threading or forking -server is appropriate. - -In some cases, it may be appropriate to process part of a request -synchronously, but to finish processing in a forked child depending on -the request data. This can be implemented by using a synchronous -server and doing an explicit fork in the request handler class -handle() method. - -Another approach to handling multiple simultaneous requests in an -environment that supports neither threads nor fork (or where these are -too expensive or inappropriate for the service) is to maintain an -explicit table of partially finished requests and to use a selector to -decide which request to work on next (or whether to handle a new -incoming request). This is particularly important for stream services -where each client can potentially be connected for a long time (if -threads or subprocesses cannot be used). - -Future work: -- Standard classes for Sun RPC (which uses either UDP or TCP) -- Standard mix-in classes to implement various authentication - and encryption schemes - -XXX Open problems: -- What to do with out-of-band data? - -BaseServer: -- split generic "request" functionality out into BaseServer class. - Copyright (C) 2000 Luke Kenneth Casson Leighton - - example: read entries from a SQL database (requires overriding - get_request() to return a table entry from the database). - entry is processed by a RequestHandlerClass. - -""" - -# Author of the BaseServer patch: Luke Kenneth Casson Leighton - -__version__ = "0.4" - - -import socket -import selectors -import os -import sys -import threading -from io import BufferedIOBase -from time import monotonic as time - -__all__ = ["BaseServer", "TCPServer", "UDPServer", - "ThreadingUDPServer", "ThreadingTCPServer", - "BaseRequestHandler", "StreamRequestHandler", - "DatagramRequestHandler", "ThreadingMixIn"] -if hasattr(os, "fork"): - __all__.extend(["ForkingUDPServer","ForkingTCPServer", "ForkingMixIn"]) -if hasattr(socket, "AF_UNIX"): - __all__.extend(["UnixStreamServer","UnixDatagramServer", - "ThreadingUnixStreamServer", - "ThreadingUnixDatagramServer"]) - -# poll/select have the advantage of not requiring any extra file descriptor, -# contrarily to epoll/kqueue (also, they require a single syscall). -if hasattr(selectors, 'PollSelector'): - _ServerSelector = selectors.PollSelector -else: - _ServerSelector = selectors.SelectSelector - - -class BaseServer: - - """Base class for server classes. - - Methods for the caller: - - - __init__(server_address, RequestHandlerClass) - - serve_forever(poll_interval=0.5) - - shutdown() - - handle_request() # if you do not use serve_forever() - - fileno() -> int # for selector - - Methods that may be overridden: - - - server_bind() - - server_activate() - - get_request() -> request, client_address - - handle_timeout() - - verify_request(request, client_address) - - server_close() - - process_request(request, client_address) - - shutdown_request(request) - - close_request(request) - - service_actions() - - handle_error() - - Methods for derived classes: - - - finish_request(request, client_address) - - Class variables that may be overridden by derived classes or - instances: - - - timeout - - address_family - - socket_type - - allow_reuse_address - - allow_reuse_port - - Instance variables: - - - RequestHandlerClass - - socket - - """ - - timeout = None - - def __init__(self, server_address, RequestHandlerClass): - """Constructor. May be extended, do not override.""" - self.server_address = server_address - self.RequestHandlerClass = RequestHandlerClass - self.__is_shut_down = threading.Event() - self.__shutdown_request = False - - def server_activate(self): - """Called by constructor to activate the server. - - May be overridden. - - """ - pass - - def serve_forever(self, poll_interval=0.5): - """Handle one request at a time until shutdown. - - Polls for shutdown every poll_interval seconds. Ignores - self.timeout. If you need to do periodic tasks, do them in - another thread. - """ - self.__is_shut_down.clear() - try: - # XXX: Consider using another file descriptor or connecting to the - # socket to wake this up instead of polling. Polling reduces our - # responsiveness to a shutdown request and wastes cpu at all other - # times. - with _ServerSelector() as selector: - selector.register(self, selectors.EVENT_READ) - - while not self.__shutdown_request: - ready = selector.select(poll_interval) - # bpo-35017: shutdown() called during select(), exit immediately. - if self.__shutdown_request: - break - if ready: - self._handle_request_noblock() - - self.service_actions() - finally: - self.__shutdown_request = False - self.__is_shut_down.set() - - def shutdown(self): - """Stops the serve_forever loop. - - Blocks until the loop has finished. This must be called while - serve_forever() is running in another thread, or it will - deadlock. - """ - self.__shutdown_request = True - self.__is_shut_down.wait() - - def service_actions(self): - """Called by the serve_forever() loop. - - May be overridden by a subclass / Mixin to implement any code that - needs to be run during the loop. - """ - pass - - # The distinction between handling, getting, processing and finishing a - # request is fairly arbitrary. Remember: - # - # - handle_request() is the top-level call. It calls selector.select(), - # get_request(), verify_request() and process_request() - # - get_request() is different for stream or datagram sockets - # - process_request() is the place that may fork a new process or create a - # new thread to finish the request - # - finish_request() instantiates the request handler class; this - # constructor will handle the request all by itself - - def handle_request(self): - """Handle one request, possibly blocking. - - Respects self.timeout. - """ - # Support people who used socket.settimeout() to escape - # handle_request before self.timeout was available. - timeout = self.socket.gettimeout() - if timeout is None: - timeout = self.timeout - elif self.timeout is not None: - timeout = min(timeout, self.timeout) - if timeout is not None: - deadline = time() + timeout - - # Wait until a request arrives or the timeout expires - the loop is - # necessary to accommodate early wakeups due to EINTR. - with _ServerSelector() as selector: - selector.register(self, selectors.EVENT_READ) - - while True: - ready = selector.select(timeout) - if ready: - return self._handle_request_noblock() - else: - if timeout is not None: - timeout = deadline - time() - if timeout < 0: - return self.handle_timeout() - - def _handle_request_noblock(self): - """Handle one request, without blocking. - - I assume that selector.select() has returned that the socket is - readable before this function was called, so there should be no risk of - blocking in get_request(). - """ - try: - request, client_address = self.get_request() - except OSError: - return - if self.verify_request(request, client_address): - try: - self.process_request(request, client_address) - except Exception: - self.handle_error(request, client_address) - self.shutdown_request(request) - except: - self.shutdown_request(request) - raise - else: - self.shutdown_request(request) - - def handle_timeout(self): - """Called if no new request arrives within self.timeout. - - Overridden by ForkingMixIn. - """ - pass - - def verify_request(self, request, client_address): - """Verify the request. May be overridden. - - Return True if we should proceed with this request. - - """ - return True - - def process_request(self, request, client_address): - """Call finish_request. - - Overridden by ForkingMixIn and ThreadingMixIn. - - """ - self.finish_request(request, client_address) - self.shutdown_request(request) - - def server_close(self): - """Called to clean-up the server. - - May be overridden. - - """ - pass - - def finish_request(self, request, client_address): - """Finish one request by instantiating RequestHandlerClass.""" - self.RequestHandlerClass(request, client_address, self) - - def shutdown_request(self, request): - """Called to shutdown and close an individual request.""" - self.close_request(request) - - def close_request(self, request): - """Called to clean up an individual request.""" - pass - - def handle_error(self, request, client_address): - """Handle an error gracefully. May be overridden. - - The default is to print a traceback and continue. - - """ - print('-'*40, file=sys.stderr) - print('Exception occurred during processing of request from', - client_address, file=sys.stderr) - import traceback - traceback.print_exc() - print('-'*40, file=sys.stderr) - - def __enter__(self): - return self - - def __exit__(self, *args): - self.server_close() - - -class TCPServer(BaseServer): - - """Base class for various socket-based server classes. - - Defaults to synchronous IP stream (i.e., TCP). - - Methods for the caller: - - - __init__(server_address, RequestHandlerClass, bind_and_activate=True) - - serve_forever(poll_interval=0.5) - - shutdown() - - handle_request() # if you don't use serve_forever() - - fileno() -> int # for selector - - Methods that may be overridden: - - - server_bind() - - server_activate() - - get_request() -> request, client_address - - handle_timeout() - - verify_request(request, client_address) - - process_request(request, client_address) - - shutdown_request(request) - - close_request(request) - - handle_error() - - Methods for derived classes: - - - finish_request(request, client_address) - - Class variables that may be overridden by derived classes or - instances: - - - timeout - - address_family - - socket_type - - request_queue_size (only for stream sockets) - - allow_reuse_address - - allow_reuse_port - - Instance variables: - - - server_address - - RequestHandlerClass - - socket - - """ - - address_family = socket.AF_INET - - socket_type = socket.SOCK_STREAM - - request_queue_size = 5 - - allow_reuse_address = False - - allow_reuse_port = False - - def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): - """Constructor. May be extended, do not override.""" - BaseServer.__init__(self, server_address, RequestHandlerClass) - self.socket = socket.socket(self.address_family, - self.socket_type) - if bind_and_activate: - try: - self.server_bind() - self.server_activate() - except: - self.server_close() - raise - - def server_bind(self): - """Called by constructor to bind the socket. - - May be overridden. - - """ - if self.allow_reuse_address and hasattr(socket, "SO_REUSEADDR"): - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - if self.allow_reuse_port and hasattr(socket, "SO_REUSEPORT"): - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - self.socket.bind(self.server_address) - self.server_address = self.socket.getsockname() - - def server_activate(self): - """Called by constructor to activate the server. - - May be overridden. - - """ - self.socket.listen(self.request_queue_size) - - def server_close(self): - """Called to clean-up the server. - - May be overridden. - - """ - self.socket.close() - - def fileno(self): - """Return socket file number. - - Interface required by selector. - - """ - return self.socket.fileno() - - def get_request(self): - """Get the request and client address from the socket. - - May be overridden. - - """ - return self.socket.accept() - - def shutdown_request(self, request): - """Called to shutdown and close an individual request.""" - try: - #explicitly shutdown. socket.close() merely releases - #the socket and waits for GC to perform the actual close. - request.shutdown(socket.SHUT_WR) - except OSError: - pass #some platforms may raise ENOTCONN here - self.close_request(request) - - def close_request(self, request): - """Called to clean up an individual request.""" - request.close() - - -class UDPServer(TCPServer): - - """UDP server class.""" - - allow_reuse_address = False - - allow_reuse_port = False - - socket_type = socket.SOCK_DGRAM - - max_packet_size = 8192 - - def get_request(self): - data, client_addr = self.socket.recvfrom(self.max_packet_size) - return (data, self.socket), client_addr - - def server_activate(self): - # No need to call listen() for UDP. - pass - - def shutdown_request(self, request): - # No need to shutdown anything. - self.close_request(request) - - def close_request(self, request): - # No need to close anything. - pass - -if hasattr(os, "fork"): - class ForkingMixIn: - """Mix-in class to handle each request in a new process.""" - - timeout = 300 - active_children = None - max_children = 40 - # If true, server_close() waits until all child processes complete. - block_on_close = True - - def collect_children(self, *, blocking=False): - """Internal routine to wait for children that have exited.""" - if self.active_children is None: - return - - # If we're above the max number of children, wait and reap them until - # we go back below threshold. Note that we use waitpid(-1) below to be - # able to collect children in size() syscalls instead - # of size(): the downside is that this might reap children - # which we didn't spawn, which is why we only resort to this when we're - # above max_children. - while len(self.active_children) >= self.max_children: - try: - pid, _ = os.waitpid(-1, 0) - self.active_children.discard(pid) - except ChildProcessError: - # we don't have any children, we're done - self.active_children.clear() - except OSError: - break - - # Now reap all defunct children. - for pid in self.active_children.copy(): - try: - flags = 0 if blocking else os.WNOHANG - pid, _ = os.waitpid(pid, flags) - # if the child hasn't exited yet, pid will be 0 and ignored by - # discard() below - self.active_children.discard(pid) - except ChildProcessError: - # someone else reaped it - self.active_children.discard(pid) - except OSError: - pass - - def handle_timeout(self): - """Wait for zombies after self.timeout seconds of inactivity. - - May be extended, do not override. - """ - self.collect_children() - - def service_actions(self): - """Collect the zombie child processes regularly in the ForkingMixIn. - - service_actions is called in the BaseServer's serve_forever loop. - """ - self.collect_children() - - def process_request(self, request, client_address): - """Fork a new subprocess to process the request.""" - pid = os.fork() - if pid: - # Parent process - if self.active_children is None: - self.active_children = set() - self.active_children.add(pid) - self.close_request(request) - return - else: - # Child process. - # This must never return, hence os._exit()! - status = 1 - try: - self.finish_request(request, client_address) - status = 0 - except Exception: - self.handle_error(request, client_address) - finally: - try: - self.shutdown_request(request) - finally: - os._exit(status) - - def server_close(self): - super().server_close() - self.collect_children(blocking=self.block_on_close) - - -class _Threads(list): - """ - Joinable list of all non-daemon threads. - """ - def append(self, thread): - self.reap() - if thread.daemon: - return - super().append(thread) - - def pop_all(self): - self[:], result = [], self[:] - return result - - def join(self): - for thread in self.pop_all(): - thread.join() - - def reap(self): - self[:] = (thread for thread in self if thread.is_alive()) - - -class _NoThreads: - """ - Degenerate version of _Threads. - """ - def append(self, thread): - pass - - def join(self): - pass - - -class ThreadingMixIn: - """Mix-in class to handle each request in a new thread.""" - - # Decides how threads will act upon termination of the - # main process - daemon_threads = False - # If true, server_close() waits until all non-daemonic threads terminate. - block_on_close = True - # Threads object - # used by server_close() to wait for all threads completion. - _threads = _NoThreads() - - def process_request_thread(self, request, client_address): - """Same as in BaseServer but as a thread. - - In addition, exception handling is done here. - - """ - try: - self.finish_request(request, client_address) - except Exception: - self.handle_error(request, client_address) - finally: - self.shutdown_request(request) - - def process_request(self, request, client_address): - """Start a new thread to process the request.""" - if self.block_on_close: - vars(self).setdefault('_threads', _Threads()) - t = threading.Thread(target = self.process_request_thread, - args = (request, client_address)) - t.daemon = self.daemon_threads - self._threads.append(t) - t.start() - - def server_close(self): - super().server_close() - self._threads.join() - - -if hasattr(os, "fork"): - class ForkingUDPServer(ForkingMixIn, UDPServer): pass - class ForkingTCPServer(ForkingMixIn, TCPServer): pass - -class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass -class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass - -if hasattr(socket, 'AF_UNIX'): - - class UnixStreamServer(TCPServer): - address_family = socket.AF_UNIX - - class UnixDatagramServer(UDPServer): - address_family = socket.AF_UNIX - - class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer): pass - - class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): pass - -class BaseRequestHandler: - - """Base class for request handler classes. - - This class is instantiated for each request to be handled. The - constructor sets the instance variables request, client_address - and server, and then calls the handle() method. To implement a - specific service, all you need to do is to derive a class which - defines a handle() method. - - The handle() method can find the request as self.request, the - client address as self.client_address, and the server (in case it - needs access to per-server information) as self.server. Since a - separate instance is created for each request, the handle() method - can define other arbitrary instance variables. - - """ - - def __init__(self, request, client_address, server): - self.request = request - self.client_address = client_address - self.server = server - self.setup() - try: - self.handle() - finally: - self.finish() - - def setup(self): - pass - - def handle(self): - pass - - def finish(self): - pass - - -# The following two classes make it possible to use the same service -# class for stream or datagram servers. -# Each class sets up these instance variables: -# - rfile: a file object from which receives the request is read -# - wfile: a file object to which the reply is written -# When the handle() method returns, wfile is flushed properly - - -class StreamRequestHandler(BaseRequestHandler): - - """Define self.rfile and self.wfile for stream sockets.""" - - # Default buffer sizes for rfile, wfile. - # We default rfile to buffered because otherwise it could be - # really slow for large data (a getc() call per byte); we make - # wfile unbuffered because (a) often after a write() we want to - # read and we need to flush the line; (b) big writes to unbuffered - # files are typically optimized by stdio even when big reads - # aren't. - rbufsize = -1 - wbufsize = 0 - - # A timeout to apply to the request socket, if not None. - timeout = None - - # Disable nagle algorithm for this socket, if True. - # Use only when wbufsize != 0, to avoid small packets. - disable_nagle_algorithm = False - - def setup(self): - self.connection = self.request - if self.timeout is not None: - self.connection.settimeout(self.timeout) - if self.disable_nagle_algorithm: - self.connection.setsockopt(socket.IPPROTO_TCP, - socket.TCP_NODELAY, True) - self.rfile = self.connection.makefile('rb', self.rbufsize) - if self.wbufsize == 0: - self.wfile = _SocketWriter(self.connection) - else: - self.wfile = self.connection.makefile('wb', self.wbufsize) - - def finish(self): - if not self.wfile.closed: - try: - self.wfile.flush() - except socket.error: - # A final socket error may have occurred here, such as - # the local error ECONNABORTED. - pass - self.wfile.close() - self.rfile.close() - -class _SocketWriter(BufferedIOBase): - """Simple writable BufferedIOBase implementation for a socket - - Does not hold data in a buffer, avoiding any need to call flush().""" - - def __init__(self, sock): - self._sock = sock - - def writable(self): - return True - - def write(self, b): - self._sock.sendall(b) - with memoryview(b) as view: - return view.nbytes - - def fileno(self): - return self._sock.fileno() - -class DatagramRequestHandler(BaseRequestHandler): - - """Define self.rfile and self.wfile for datagram sockets.""" - - def setup(self): - from io import BytesIO - self.packet, self.socket = self.request - self.rfile = BytesIO(self.packet) - self.wfile = BytesIO() - - def finish(self): - self.socket.sendto(self.wfile.getvalue(), self.client_address) diff --git a/python/Lib/sre_compile.py b/python/Lib/sre_compile.py deleted file mode 100644 index 974e5e2..0000000 --- a/python/Lib/sre_compile.py +++ /dev/null @@ -1,7 +0,0 @@ -import warnings -warnings.warn(f"module {__name__!r} is deprecated", - DeprecationWarning, - stacklevel=2) - -from re import _compiler as _ -globals().update({k: v for k, v in vars(_).items() if k[:2] != '__'}) diff --git a/python/Lib/sre_constants.py b/python/Lib/sre_constants.py deleted file mode 100644 index 00cc967..0000000 --- a/python/Lib/sre_constants.py +++ /dev/null @@ -1,7 +0,0 @@ -import warnings -warnings.warn(f"module {__name__!r} is deprecated", - DeprecationWarning, - stacklevel=2) - -from re import _constants as _ -globals().update({k: v for k, v in vars(_).items() if k[:2] != '__'}) diff --git a/python/Lib/sre_parse.py b/python/Lib/sre_parse.py deleted file mode 100644 index 10ee816..0000000 --- a/python/Lib/sre_parse.py +++ /dev/null @@ -1,7 +0,0 @@ -import warnings -warnings.warn(f"module {__name__!r} is deprecated", - DeprecationWarning, - stacklevel=2) - -from re import _parser as _ -globals().update({k: v for k, v in vars(_).items() if k[:2] != '__'}) diff --git a/python/Lib/ssl.py b/python/Lib/ssl.py deleted file mode 100644 index f44d8a4..0000000 --- a/python/Lib/ssl.py +++ /dev/null @@ -1,1533 +0,0 @@ -# Wrapper module for _ssl, providing some additional facilities -# implemented in Python. Written by Bill Janssen. - -"""This module provides some more Pythonic support for SSL. - -Object types: - - SSLSocket -- subtype of socket.socket which does SSL over the socket - -Exceptions: - - SSLError -- exception raised for I/O errors - -Functions: - - cert_time_to_seconds -- convert time string used for certificate - notBefore and notAfter functions to integer - seconds past the Epoch (the time values - returned from time.time()) - - get_server_certificate (addr, ssl_version, ca_certs, timeout) -- Retrieve the - certificate from the server at the specified - address and return it as a PEM-encoded string - - -Integer constants: - -SSL_ERROR_ZERO_RETURN -SSL_ERROR_WANT_READ -SSL_ERROR_WANT_WRITE -SSL_ERROR_WANT_X509_LOOKUP -SSL_ERROR_SYSCALL -SSL_ERROR_SSL -SSL_ERROR_WANT_CONNECT - -SSL_ERROR_EOF -SSL_ERROR_INVALID_ERROR_CODE - -The following group define certificate requirements that one side is -allowing/requiring from the other side: - -CERT_NONE - no certificates from the other side are required (or will - be looked at if provided) -CERT_OPTIONAL - certificates are not required, but if provided will be - validated, and if validation fails, the connection will - also fail -CERT_REQUIRED - certificates are required, and will be validated, and - if validation fails, the connection will also fail - -The following constants identify various SSL protocol variants: - -PROTOCOL_SSLv2 -PROTOCOL_SSLv3 -PROTOCOL_SSLv23 -PROTOCOL_TLS -PROTOCOL_TLS_CLIENT -PROTOCOL_TLS_SERVER -PROTOCOL_TLSv1 -PROTOCOL_TLSv1_1 -PROTOCOL_TLSv1_2 - -The following constants identify various SSL alert message descriptions as per -http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6 - -ALERT_DESCRIPTION_CLOSE_NOTIFY -ALERT_DESCRIPTION_UNEXPECTED_MESSAGE -ALERT_DESCRIPTION_BAD_RECORD_MAC -ALERT_DESCRIPTION_RECORD_OVERFLOW -ALERT_DESCRIPTION_DECOMPRESSION_FAILURE -ALERT_DESCRIPTION_HANDSHAKE_FAILURE -ALERT_DESCRIPTION_BAD_CERTIFICATE -ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE -ALERT_DESCRIPTION_CERTIFICATE_REVOKED -ALERT_DESCRIPTION_CERTIFICATE_EXPIRED -ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN -ALERT_DESCRIPTION_ILLEGAL_PARAMETER -ALERT_DESCRIPTION_UNKNOWN_CA -ALERT_DESCRIPTION_ACCESS_DENIED -ALERT_DESCRIPTION_DECODE_ERROR -ALERT_DESCRIPTION_DECRYPT_ERROR -ALERT_DESCRIPTION_PROTOCOL_VERSION -ALERT_DESCRIPTION_INSUFFICIENT_SECURITY -ALERT_DESCRIPTION_INTERNAL_ERROR -ALERT_DESCRIPTION_USER_CANCELLED -ALERT_DESCRIPTION_NO_RENEGOTIATION -ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION -ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE -ALERT_DESCRIPTION_UNRECOGNIZED_NAME -ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE -ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE -ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY -""" - -import sys -import os -from collections import namedtuple -from enum import Enum as _Enum, IntEnum as _IntEnum, IntFlag as _IntFlag -from enum import _simple_enum - -import _ssl # if we can't import it, let the error propagate - -from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION -from _ssl import _SSLContext, MemoryBIO, SSLSession -from _ssl import ( - SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError, - SSLSyscallError, SSLEOFError, SSLCertVerificationError - ) -from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj -from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes -try: - from _ssl import RAND_egd -except ImportError: - # LibreSSL does not provide RAND_egd - pass - - -from _ssl import ( - HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_SSLv2, HAS_SSLv3, HAS_TLSv1, - HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3 -) -from _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION - -_IntEnum._convert_( - '_SSLMethod', __name__, - lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23', - source=_ssl) - -_IntFlag._convert_( - 'Options', __name__, - lambda name: name.startswith('OP_'), - source=_ssl) - -_IntEnum._convert_( - 'AlertDescription', __name__, - lambda name: name.startswith('ALERT_DESCRIPTION_'), - source=_ssl) - -_IntEnum._convert_( - 'SSLErrorNumber', __name__, - lambda name: name.startswith('SSL_ERROR_'), - source=_ssl) - -_IntFlag._convert_( - 'VerifyFlags', __name__, - lambda name: name.startswith('VERIFY_'), - source=_ssl) - -_IntEnum._convert_( - 'VerifyMode', __name__, - lambda name: name.startswith('CERT_'), - source=_ssl) - -PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_TLS -_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()} - -_SSLv2_IF_EXISTS = getattr(_SSLMethod, 'PROTOCOL_SSLv2', None) - - -@_simple_enum(_IntEnum) -class TLSVersion: - MINIMUM_SUPPORTED = _ssl.PROTO_MINIMUM_SUPPORTED - SSLv3 = _ssl.PROTO_SSLv3 - TLSv1 = _ssl.PROTO_TLSv1 - TLSv1_1 = _ssl.PROTO_TLSv1_1 - TLSv1_2 = _ssl.PROTO_TLSv1_2 - TLSv1_3 = _ssl.PROTO_TLSv1_3 - MAXIMUM_SUPPORTED = _ssl.PROTO_MAXIMUM_SUPPORTED - - -@_simple_enum(_IntEnum) -class _TLSContentType: - """Content types (record layer) - - See RFC 8446, section B.1 - """ - CHANGE_CIPHER_SPEC = 20 - ALERT = 21 - HANDSHAKE = 22 - APPLICATION_DATA = 23 - # pseudo content types - HEADER = 0x100 - INNER_CONTENT_TYPE = 0x101 - - -@_simple_enum(_IntEnum) -class _TLSAlertType: - """Alert types for TLSContentType.ALERT messages - - See RFC 8466, section B.2 - """ - CLOSE_NOTIFY = 0 - UNEXPECTED_MESSAGE = 10 - BAD_RECORD_MAC = 20 - DECRYPTION_FAILED = 21 - RECORD_OVERFLOW = 22 - DECOMPRESSION_FAILURE = 30 - HANDSHAKE_FAILURE = 40 - NO_CERTIFICATE = 41 - BAD_CERTIFICATE = 42 - UNSUPPORTED_CERTIFICATE = 43 - CERTIFICATE_REVOKED = 44 - CERTIFICATE_EXPIRED = 45 - CERTIFICATE_UNKNOWN = 46 - ILLEGAL_PARAMETER = 47 - UNKNOWN_CA = 48 - ACCESS_DENIED = 49 - DECODE_ERROR = 50 - DECRYPT_ERROR = 51 - EXPORT_RESTRICTION = 60 - PROTOCOL_VERSION = 70 - INSUFFICIENT_SECURITY = 71 - INTERNAL_ERROR = 80 - INAPPROPRIATE_FALLBACK = 86 - USER_CANCELED = 90 - NO_RENEGOTIATION = 100 - MISSING_EXTENSION = 109 - UNSUPPORTED_EXTENSION = 110 - CERTIFICATE_UNOBTAINABLE = 111 - UNRECOGNIZED_NAME = 112 - BAD_CERTIFICATE_STATUS_RESPONSE = 113 - BAD_CERTIFICATE_HASH_VALUE = 114 - UNKNOWN_PSK_IDENTITY = 115 - CERTIFICATE_REQUIRED = 116 - NO_APPLICATION_PROTOCOL = 120 - - -@_simple_enum(_IntEnum) -class _TLSMessageType: - """Message types (handshake protocol) - - See RFC 8446, section B.3 - """ - HELLO_REQUEST = 0 - CLIENT_HELLO = 1 - SERVER_HELLO = 2 - HELLO_VERIFY_REQUEST = 3 - NEWSESSION_TICKET = 4 - END_OF_EARLY_DATA = 5 - HELLO_RETRY_REQUEST = 6 - ENCRYPTED_EXTENSIONS = 8 - CERTIFICATE = 11 - SERVER_KEY_EXCHANGE = 12 - CERTIFICATE_REQUEST = 13 - SERVER_DONE = 14 - CERTIFICATE_VERIFY = 15 - CLIENT_KEY_EXCHANGE = 16 - FINISHED = 20 - CERTIFICATE_URL = 21 - CERTIFICATE_STATUS = 22 - SUPPLEMENTAL_DATA = 23 - KEY_UPDATE = 24 - NEXT_PROTO = 67 - MESSAGE_HASH = 254 - CHANGE_CIPHER_SPEC = 0x0101 - - -if sys.platform == "win32": - from _ssl import enum_certificates, enum_crls - -from socket import socket, SOCK_STREAM, create_connection -from socket import SOL_SOCKET, SO_TYPE, _GLOBAL_DEFAULT_TIMEOUT -import socket as _socket -import base64 # for DER-to-PEM translation -import errno -import warnings - - -socket_error = OSError # keep that public name in module namespace - -CHANNEL_BINDING_TYPES = ['tls-unique'] - -HAS_NEVER_CHECK_COMMON_NAME = hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT') - - -_RESTRICTED_SERVER_CIPHERS = _DEFAULT_CIPHERS - -CertificateError = SSLCertVerificationError - - -def _dnsname_match(dn, hostname): - """Matching according to RFC 6125, section 6.4.3 - - - Hostnames are compared lower-case. - - For IDNA, both dn and hostname must be encoded as IDN A-label (ACE). - - Partial wildcards like 'www*.example.org', multiple wildcards, sole - wildcard or wildcards in labels other then the left-most label are not - supported and a CertificateError is raised. - - A wildcard must match at least one character. - """ - if not dn: - return False - - wildcards = dn.count('*') - # speed up common case w/o wildcards - if not wildcards: - return dn.lower() == hostname.lower() - - if wildcards > 1: - raise CertificateError( - "too many wildcards in certificate DNS name: {!r}.".format(dn)) - - dn_leftmost, sep, dn_remainder = dn.partition('.') - - if '*' in dn_remainder: - # Only match wildcard in leftmost segment. - raise CertificateError( - "wildcard can only be present in the leftmost label: " - "{!r}.".format(dn)) - - if not sep: - # no right side - raise CertificateError( - "sole wildcard without additional labels are not support: " - "{!r}.".format(dn)) - - if dn_leftmost != '*': - # no partial wildcard matching - raise CertificateError( - "partial wildcards in leftmost label are not supported: " - "{!r}.".format(dn)) - - hostname_leftmost, sep, hostname_remainder = hostname.partition('.') - if not hostname_leftmost or not sep: - # wildcard must match at least one char - return False - return dn_remainder.lower() == hostname_remainder.lower() - - -def _inet_paton(ipname): - """Try to convert an IP address to packed binary form - - Supports IPv4 addresses on all platforms and IPv6 on platforms with IPv6 - support. - """ - # inet_aton() also accepts strings like '1', '127.1', some also trailing - # data like '127.0.0.1 whatever'. - try: - addr = _socket.inet_aton(ipname) - except OSError: - # not an IPv4 address - pass - else: - if _socket.inet_ntoa(addr) == ipname: - # only accept injective ipnames - return addr - else: - # refuse for short IPv4 notation and additional trailing data - raise ValueError( - "{!r} is not a quad-dotted IPv4 address.".format(ipname) - ) - - try: - return _socket.inet_pton(_socket.AF_INET6, ipname) - except OSError: - raise ValueError("{!r} is neither an IPv4 nor an IP6 " - "address.".format(ipname)) - except AttributeError: - # AF_INET6 not available - pass - - raise ValueError("{!r} is not an IPv4 address.".format(ipname)) - - -def _ipaddress_match(cert_ipaddress, host_ip): - """Exact matching of IP addresses. - - RFC 6125 explicitly doesn't define an algorithm for this - (section 1.7.2 - "Out of Scope"). - """ - # OpenSSL may add a trailing newline to a subjectAltName's IP address, - # commonly with IPv6 addresses. Strip off trailing \n. - ip = _inet_paton(cert_ipaddress.rstrip()) - return ip == host_ip - - -def match_hostname(cert, hostname): - """Verify that *cert* (in decoded format as returned by - SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 - rules are followed. - - The function matches IP addresses rather than dNSNames if hostname is a - valid ipaddress string. IPv4 addresses are supported on all platforms. - IPv6 addresses are supported on platforms with IPv6 support (AF_INET6 - and inet_pton). - - CertificateError is raised on failure. On success, the function - returns nothing. - """ - warnings.warn( - "ssl.match_hostname() is deprecated", - category=DeprecationWarning, - stacklevel=2 - ) - if not cert: - raise ValueError("empty or no certificate, match_hostname needs a " - "SSL socket or SSL context with either " - "CERT_OPTIONAL or CERT_REQUIRED") - try: - host_ip = _inet_paton(hostname) - except ValueError: - # Not an IP address (common case) - host_ip = None - dnsnames = [] - san = cert.get('subjectAltName', ()) - for key, value in san: - if key == 'DNS': - if host_ip is None and _dnsname_match(value, hostname): - return - dnsnames.append(value) - elif key == 'IP Address': - if host_ip is not None and _ipaddress_match(value, host_ip): - return - dnsnames.append(value) - if not dnsnames: - # The subject is only checked when there is no dNSName entry - # in subjectAltName - for sub in cert.get('subject', ()): - for key, value in sub: - # XXX according to RFC 2818, the most specific Common Name - # must be used. - if key == 'commonName': - if _dnsname_match(value, hostname): - return - dnsnames.append(value) - if len(dnsnames) > 1: - raise CertificateError("hostname %r " - "doesn't match either of %s" - % (hostname, ', '.join(map(repr, dnsnames)))) - elif len(dnsnames) == 1: - raise CertificateError("hostname %r " - "doesn't match %r" - % (hostname, dnsnames[0])) - else: - raise CertificateError("no appropriate commonName or " - "subjectAltName fields were found") - - -DefaultVerifyPaths = namedtuple("DefaultVerifyPaths", - "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env " - "openssl_capath") - -def get_default_verify_paths(): - """Return paths to default cafile and capath. - """ - parts = _ssl.get_default_verify_paths() - - # environment vars shadow paths - cafile = os.environ.get(parts[0], parts[1]) - capath = os.environ.get(parts[2], parts[3]) - - return DefaultVerifyPaths(cafile if os.path.isfile(cafile) else None, - capath if os.path.isdir(capath) else None, - *parts) - - -class _ASN1Object(namedtuple("_ASN1Object", "nid shortname longname oid")): - """ASN.1 object identifier lookup - """ - __slots__ = () - - def __new__(cls, oid): - return super().__new__(cls, *_txt2obj(oid, name=False)) - - @classmethod - def fromnid(cls, nid): - """Create _ASN1Object from OpenSSL numeric ID - """ - return super().__new__(cls, *_nid2obj(nid)) - - @classmethod - def fromname(cls, name): - """Create _ASN1Object from short name, long name or OID - """ - return super().__new__(cls, *_txt2obj(name, name=True)) - - -class Purpose(_ASN1Object, _Enum): - """SSLContext purpose flags with X509v3 Extended Key Usage objects - """ - SERVER_AUTH = '1.3.6.1.5.5.7.3.1' - CLIENT_AUTH = '1.3.6.1.5.5.7.3.2' - - -class SSLContext(_SSLContext): - """An SSLContext holds various SSL-related configuration options and - data, such as certificates and possibly a private key.""" - _windows_cert_stores = ("CA", "ROOT") - - sslsocket_class = None # SSLSocket is assigned later. - sslobject_class = None # SSLObject is assigned later. - - def __new__(cls, protocol=None, *args, **kwargs): - if protocol is None: - warnings.warn( - "ssl.SSLContext() without protocol argument is deprecated.", - category=DeprecationWarning, - stacklevel=2 - ) - protocol = PROTOCOL_TLS - self = _SSLContext.__new__(cls, protocol) - return self - - def _encode_hostname(self, hostname): - if hostname is None: - return None - elif isinstance(hostname, str): - return hostname.encode('idna').decode('ascii') - else: - return hostname.decode('ascii') - - def wrap_socket(self, sock, server_side=False, - do_handshake_on_connect=True, - suppress_ragged_eofs=True, - server_hostname=None, session=None): - # SSLSocket class handles server_hostname encoding before it calls - # ctx._wrap_socket() - return self.sslsocket_class._create( - sock=sock, - server_side=server_side, - do_handshake_on_connect=do_handshake_on_connect, - suppress_ragged_eofs=suppress_ragged_eofs, - server_hostname=server_hostname, - context=self, - session=session - ) - - def wrap_bio(self, incoming, outgoing, server_side=False, - server_hostname=None, session=None): - # Need to encode server_hostname here because _wrap_bio() can only - # handle ASCII str. - return self.sslobject_class._create( - incoming, outgoing, server_side=server_side, - server_hostname=self._encode_hostname(server_hostname), - session=session, context=self, - ) - - def set_npn_protocols(self, npn_protocols): - warnings.warn( - "ssl NPN is deprecated, use ALPN instead", - DeprecationWarning, - stacklevel=2 - ) - protos = bytearray() - for protocol in npn_protocols: - b = bytes(protocol, 'ascii') - if len(b) == 0 or len(b) > 255: - raise SSLError('NPN protocols must be 1 to 255 in length') - protos.append(len(b)) - protos.extend(b) - - self._set_npn_protocols(protos) - - def set_servername_callback(self, server_name_callback): - if server_name_callback is None: - self.sni_callback = None - else: - if not callable(server_name_callback): - raise TypeError("not a callable object") - - def shim_cb(sslobj, servername, sslctx): - servername = self._encode_hostname(servername) - return server_name_callback(sslobj, servername, sslctx) - - self.sni_callback = shim_cb - - def set_alpn_protocols(self, alpn_protocols): - protos = bytearray() - for protocol in alpn_protocols: - b = bytes(protocol, 'ascii') - if len(b) == 0 or len(b) > 255: - raise SSLError('ALPN protocols must be 1 to 255 in length') - protos.append(len(b)) - protos.extend(b) - - self._set_alpn_protocols(protos) - - def _load_windows_store_certs(self, storename, purpose): - certs = bytearray() - try: - for cert, encoding, trust in enum_certificates(storename): - # CA certs are never PKCS#7 encoded - if encoding == "x509_asn": - if trust is True or purpose.oid in trust: - certs.extend(cert) - except PermissionError: - warnings.warn("unable to enumerate Windows certificate store") - if certs: - self.load_verify_locations(cadata=certs) - return certs - - def load_default_certs(self, purpose=Purpose.SERVER_AUTH): - if not isinstance(purpose, _ASN1Object): - raise TypeError(purpose) - if sys.platform == "win32": - for storename in self._windows_cert_stores: - self._load_windows_store_certs(storename, purpose) - self.set_default_verify_paths() - - if hasattr(_SSLContext, 'minimum_version'): - @property - def minimum_version(self): - return TLSVersion(super().minimum_version) - - @minimum_version.setter - def minimum_version(self, value): - if value == TLSVersion.SSLv3: - self.options &= ~Options.OP_NO_SSLv3 - super(SSLContext, SSLContext).minimum_version.__set__(self, value) - - @property - def maximum_version(self): - return TLSVersion(super().maximum_version) - - @maximum_version.setter - def maximum_version(self, value): - super(SSLContext, SSLContext).maximum_version.__set__(self, value) - - @property - def options(self): - return Options(super().options) - - @options.setter - def options(self, value): - super(SSLContext, SSLContext).options.__set__(self, value) - - if hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT'): - @property - def hostname_checks_common_name(self): - ncs = self._host_flags & _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT - return ncs != _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT - - @hostname_checks_common_name.setter - def hostname_checks_common_name(self, value): - if value: - self._host_flags &= ~_ssl.HOSTFLAG_NEVER_CHECK_SUBJECT - else: - self._host_flags |= _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT - else: - @property - def hostname_checks_common_name(self): - return True - - @property - def _msg_callback(self): - """TLS message callback - - The message callback provides a debugging hook to analyze TLS - connections. The callback is called for any TLS protocol message - (header, handshake, alert, and more), but not for application data. - Due to technical limitations, the callback can't be used to filter - traffic or to abort a connection. Any exception raised in the - callback is delayed until the handshake, read, or write operation - has been performed. - - def msg_cb(conn, direction, version, content_type, msg_type, data): - pass - - conn - :class:`SSLSocket` or :class:`SSLObject` instance - direction - ``read`` or ``write`` - version - :class:`TLSVersion` enum member or int for unknown version. For a - frame header, it's the header version. - content_type - :class:`_TLSContentType` enum member or int for unsupported - content type. - msg_type - Either a :class:`_TLSContentType` enum number for a header - message, a :class:`_TLSAlertType` enum member for an alert - message, a :class:`_TLSMessageType` enum member for other - messages, or int for unsupported message types. - data - Raw, decrypted message content as bytes - """ - inner = super()._msg_callback - if inner is not None: - return inner.user_function - else: - return None - - @_msg_callback.setter - def _msg_callback(self, callback): - if callback is None: - super(SSLContext, SSLContext)._msg_callback.__set__(self, None) - return - - if not hasattr(callback, '__call__'): - raise TypeError(f"{callback} is not callable.") - - def inner(conn, direction, version, content_type, msg_type, data): - try: - version = TLSVersion(version) - except ValueError: - pass - - try: - content_type = _TLSContentType(content_type) - except ValueError: - pass - - if content_type == _TLSContentType.HEADER: - msg_enum = _TLSContentType - elif content_type == _TLSContentType.ALERT: - msg_enum = _TLSAlertType - else: - msg_enum = _TLSMessageType - try: - msg_type = msg_enum(msg_type) - except ValueError: - pass - - return callback(conn, direction, version, - content_type, msg_type, data) - - inner.user_function = callback - - super(SSLContext, SSLContext)._msg_callback.__set__(self, inner) - - @property - def protocol(self): - return _SSLMethod(super().protocol) - - @property - def verify_flags(self): - return VerifyFlags(super().verify_flags) - - @verify_flags.setter - def verify_flags(self, value): - super(SSLContext, SSLContext).verify_flags.__set__(self, value) - - @property - def verify_mode(self): - value = super().verify_mode - try: - return VerifyMode(value) - except ValueError: - return value - - @verify_mode.setter - def verify_mode(self, value): - super(SSLContext, SSLContext).verify_mode.__set__(self, value) - - -def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, - capath=None, cadata=None): - """Create a SSLContext object with default settings. - - NOTE: The protocol and settings may change anytime without prior - deprecation. The values represent a fair balance between maximum - compatibility and security. - """ - if not isinstance(purpose, _ASN1Object): - raise TypeError(purpose) - - # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION, - # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE - # by default. - if purpose == Purpose.SERVER_AUTH: - # verify certs and host name in client mode - context = SSLContext(PROTOCOL_TLS_CLIENT) - context.verify_mode = CERT_REQUIRED - context.check_hostname = True - elif purpose == Purpose.CLIENT_AUTH: - context = SSLContext(PROTOCOL_TLS_SERVER) - else: - raise ValueError(purpose) - - if cafile or capath or cadata: - context.load_verify_locations(cafile, capath, cadata) - elif context.verify_mode != CERT_NONE: - # no explicit cafile, capath or cadata but the verify mode is - # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system - # root CA certificates for the given purpose. This may fail silently. - context.load_default_certs(purpose) - # OpenSSL 1.1.1 keylog file - if hasattr(context, 'keylog_filename'): - keylogfile = os.environ.get('SSLKEYLOGFILE') - if keylogfile and not sys.flags.ignore_environment: - context.keylog_filename = keylogfile - return context - -def _create_unverified_context(protocol=None, *, cert_reqs=CERT_NONE, - check_hostname=False, purpose=Purpose.SERVER_AUTH, - certfile=None, keyfile=None, - cafile=None, capath=None, cadata=None): - """Create a SSLContext object for Python stdlib modules - - All Python stdlib modules shall use this function to create SSLContext - objects in order to keep common settings in one place. The configuration - is less restrict than create_default_context()'s to increase backward - compatibility. - """ - if not isinstance(purpose, _ASN1Object): - raise TypeError(purpose) - - # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION, - # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE - # by default. - if purpose == Purpose.SERVER_AUTH: - # verify certs and host name in client mode - if protocol is None: - protocol = PROTOCOL_TLS_CLIENT - elif purpose == Purpose.CLIENT_AUTH: - if protocol is None: - protocol = PROTOCOL_TLS_SERVER - else: - raise ValueError(purpose) - - context = SSLContext(protocol) - context.check_hostname = check_hostname - if cert_reqs is not None: - context.verify_mode = cert_reqs - if check_hostname: - context.check_hostname = True - - if keyfile and not certfile: - raise ValueError("certfile must be specified") - if certfile or keyfile: - context.load_cert_chain(certfile, keyfile) - - # load CA root certs - if cafile or capath or cadata: - context.load_verify_locations(cafile, capath, cadata) - elif context.verify_mode != CERT_NONE: - # no explicit cafile, capath or cadata but the verify mode is - # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system - # root CA certificates for the given purpose. This may fail silently. - context.load_default_certs(purpose) - # OpenSSL 1.1.1 keylog file - if hasattr(context, 'keylog_filename'): - keylogfile = os.environ.get('SSLKEYLOGFILE') - if keylogfile and not sys.flags.ignore_environment: - context.keylog_filename = keylogfile - return context - -# Used by http.client if no context is explicitly passed. -_create_default_https_context = create_default_context - - -# Backwards compatibility alias, even though it's not a public name. -_create_stdlib_context = _create_unverified_context - - -class SSLObject: - """This class implements an interface on top of a low-level SSL object as - implemented by OpenSSL. This object captures the state of an SSL connection - but does not provide any network IO itself. IO needs to be performed - through separate "BIO" objects which are OpenSSL's IO abstraction layer. - - This class does not have a public constructor. Instances are returned by - ``SSLContext.wrap_bio``. This class is typically used by framework authors - that want to implement asynchronous IO for SSL through memory buffers. - - When compared to ``SSLSocket``, this object lacks the following features: - - * Any form of network IO, including methods such as ``recv`` and ``send``. - * The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery. - """ - def __init__(self, *args, **kwargs): - raise TypeError( - f"{self.__class__.__name__} does not have a public " - f"constructor. Instances are returned by SSLContext.wrap_bio()." - ) - - @classmethod - def _create(cls, incoming, outgoing, server_side=False, - server_hostname=None, session=None, context=None): - self = cls.__new__(cls) - sslobj = context._wrap_bio( - incoming, outgoing, server_side=server_side, - server_hostname=server_hostname, - owner=self, session=session - ) - self._sslobj = sslobj - return self - - @property - def context(self): - """The SSLContext that is currently in use.""" - return self._sslobj.context - - @context.setter - def context(self, ctx): - self._sslobj.context = ctx - - @property - def session(self): - """The SSLSession for client socket.""" - return self._sslobj.session - - @session.setter - def session(self, session): - self._sslobj.session = session - - @property - def session_reused(self): - """Was the client session reused during handshake""" - return self._sslobj.session_reused - - @property - def server_side(self): - """Whether this is a server-side socket.""" - return self._sslobj.server_side - - @property - def server_hostname(self): - """The currently set server hostname (for SNI), or ``None`` if no - server hostname is set.""" - return self._sslobj.server_hostname - - def read(self, len=1024, buffer=None): - """Read up to 'len' bytes from the SSL object and return them. - - If 'buffer' is provided, read into this buffer and return the number of - bytes read. - """ - if buffer is not None: - v = self._sslobj.read(len, buffer) - else: - v = self._sslobj.read(len) - return v - - def write(self, data): - """Write 'data' to the SSL object and return the number of bytes - written. - - The 'data' argument must support the buffer interface. - """ - return self._sslobj.write(data) - - def getpeercert(self, binary_form=False): - """Returns a formatted version of the data in the certificate provided - by the other end of the SSL channel. - - Return None if no certificate was provided, {} if a certificate was - provided, but not validated. - """ - return self._sslobj.getpeercert(binary_form) - - def selected_npn_protocol(self): - """Return the currently selected NPN protocol as a string, or ``None`` - if a next protocol was not negotiated or if NPN is not supported by one - of the peers.""" - warnings.warn( - "ssl NPN is deprecated, use ALPN instead", - DeprecationWarning, - stacklevel=2 - ) - - def selected_alpn_protocol(self): - """Return the currently selected ALPN protocol as a string, or ``None`` - if a next protocol was not negotiated or if ALPN is not supported by one - of the peers.""" - return self._sslobj.selected_alpn_protocol() - - def cipher(self): - """Return the currently selected cipher as a 3-tuple ``(name, - ssl_version, secret_bits)``.""" - return self._sslobj.cipher() - - def shared_ciphers(self): - """Return a list of ciphers shared by the client during the handshake or - None if this is not a valid server connection. - """ - return self._sslobj.shared_ciphers() - - def compression(self): - """Return the current compression algorithm in use, or ``None`` if - compression was not negotiated or not supported by one of the peers.""" - return self._sslobj.compression() - - def pending(self): - """Return the number of bytes that can be read immediately.""" - return self._sslobj.pending() - - def do_handshake(self): - """Start the SSL/TLS handshake.""" - self._sslobj.do_handshake() - - def unwrap(self): - """Start the SSL shutdown handshake.""" - return self._sslobj.shutdown() - - def get_channel_binding(self, cb_type="tls-unique"): - """Get channel binding data for current connection. Raise ValueError - if the requested `cb_type` is not supported. Return bytes of the data - or None if the data is not available (e.g. before the handshake).""" - return self._sslobj.get_channel_binding(cb_type) - - def version(self): - """Return a string identifying the protocol version used by the - current SSL channel. """ - return self._sslobj.version() - - def verify_client_post_handshake(self): - return self._sslobj.verify_client_post_handshake() - - -def _sslcopydoc(func): - """Copy docstring from SSLObject to SSLSocket""" - func.__doc__ = getattr(SSLObject, func.__name__).__doc__ - return func - - -class SSLSocket(socket): - """This class implements a subtype of socket.socket that wraps - the underlying OS socket in an SSL context when necessary, and - provides read and write methods over that channel. """ - - def __init__(self, *args, **kwargs): - raise TypeError( - f"{self.__class__.__name__} does not have a public " - f"constructor. Instances are returned by " - f"SSLContext.wrap_socket()." - ) - - @classmethod - def _create(cls, sock, server_side=False, do_handshake_on_connect=True, - suppress_ragged_eofs=True, server_hostname=None, - context=None, session=None): - if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM: - raise NotImplementedError("only stream sockets are supported") - if server_side: - if server_hostname: - raise ValueError("server_hostname can only be specified " - "in client mode") - if session is not None: - raise ValueError("session can only be specified in " - "client mode") - if context.check_hostname and not server_hostname: - raise ValueError("check_hostname requires server_hostname") - - kwargs = dict( - family=sock.family, type=sock.type, proto=sock.proto, - fileno=sock.fileno() - ) - self = cls.__new__(cls, **kwargs) - super(SSLSocket, self).__init__(**kwargs) - self.settimeout(sock.gettimeout()) - sock.detach() - - self._context = context - self._session = session - self._closed = False - self._sslobj = None - self.server_side = server_side - self.server_hostname = context._encode_hostname(server_hostname) - self.do_handshake_on_connect = do_handshake_on_connect - self.suppress_ragged_eofs = suppress_ragged_eofs - - # See if we are connected - try: - self.getpeername() - except OSError as e: - if e.errno != errno.ENOTCONN: - raise - connected = False - else: - connected = True - - self._connected = connected - if connected: - # create the SSL object - try: - self._sslobj = self._context._wrap_socket( - self, server_side, self.server_hostname, - owner=self, session=self._session, - ) - if do_handshake_on_connect: - timeout = self.gettimeout() - if timeout == 0.0: - # non-blocking - raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets") - self.do_handshake() - except (OSError, ValueError): - self.close() - raise - return self - - @property - @_sslcopydoc - def context(self): - return self._context - - @context.setter - def context(self, ctx): - self._context = ctx - self._sslobj.context = ctx - - @property - @_sslcopydoc - def session(self): - if self._sslobj is not None: - return self._sslobj.session - - @session.setter - def session(self, session): - self._session = session - if self._sslobj is not None: - self._sslobj.session = session - - @property - @_sslcopydoc - def session_reused(self): - if self._sslobj is not None: - return self._sslobj.session_reused - - def dup(self): - raise NotImplementedError("Can't dup() %s instances" % - self.__class__.__name__) - - def _checkClosed(self, msg=None): - # raise an exception here if you wish to check for spurious closes - pass - - def _check_connected(self): - if not self._connected: - # getpeername() will raise ENOTCONN if the socket is really - # not connected; note that we can be connected even without - # _connected being set, e.g. if connect() first returned - # EAGAIN. - self.getpeername() - - def read(self, len=1024, buffer=None): - """Read up to LEN bytes and return them. - Return zero-length string on EOF.""" - - self._checkClosed() - if self._sslobj is None: - raise ValueError("Read on closed or unwrapped SSL socket.") - try: - if buffer is not None: - return self._sslobj.read(len, buffer) - else: - return self._sslobj.read(len) - except SSLError as x: - if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: - if buffer is not None: - return 0 - else: - return b'' - else: - raise - - def write(self, data): - """Write DATA to the underlying SSL channel. Returns - number of bytes of DATA actually transmitted.""" - - self._checkClosed() - if self._sslobj is None: - raise ValueError("Write on closed or unwrapped SSL socket.") - return self._sslobj.write(data) - - @_sslcopydoc - def getpeercert(self, binary_form=False): - self._checkClosed() - self._check_connected() - return self._sslobj.getpeercert(binary_form) - - @_sslcopydoc - def selected_npn_protocol(self): - self._checkClosed() - warnings.warn( - "ssl NPN is deprecated, use ALPN instead", - DeprecationWarning, - stacklevel=2 - ) - return None - - @_sslcopydoc - def selected_alpn_protocol(self): - self._checkClosed() - if self._sslobj is None or not _ssl.HAS_ALPN: - return None - else: - return self._sslobj.selected_alpn_protocol() - - @_sslcopydoc - def cipher(self): - self._checkClosed() - if self._sslobj is None: - return None - else: - return self._sslobj.cipher() - - @_sslcopydoc - def shared_ciphers(self): - self._checkClosed() - if self._sslobj is None: - return None - else: - return self._sslobj.shared_ciphers() - - @_sslcopydoc - def compression(self): - self._checkClosed() - if self._sslobj is None: - return None - else: - return self._sslobj.compression() - - def send(self, data, flags=0): - self._checkClosed() - if self._sslobj is not None: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to send() on %s" % - self.__class__) - return self._sslobj.write(data) - else: - return super().send(data, flags) - - def sendto(self, data, flags_or_addr, addr=None): - self._checkClosed() - if self._sslobj is not None: - raise ValueError("sendto not allowed on instances of %s" % - self.__class__) - elif addr is None: - return super().sendto(data, flags_or_addr) - else: - return super().sendto(data, flags_or_addr, addr) - - def sendmsg(self, *args, **kwargs): - # Ensure programs don't send data unencrypted if they try to - # use this method. - raise NotImplementedError("sendmsg not allowed on instances of %s" % - self.__class__) - - def sendall(self, data, flags=0): - self._checkClosed() - if self._sslobj is not None: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to sendall() on %s" % - self.__class__) - count = 0 - with memoryview(data) as view, view.cast("B") as byte_view: - amount = len(byte_view) - while count < amount: - v = self.send(byte_view[count:]) - count += v - else: - return super().sendall(data, flags) - - def sendfile(self, file, offset=0, count=None): - """Send a file, possibly by using os.sendfile() if this is a - clear-text socket. Return the total number of bytes sent. - """ - if self._sslobj is not None: - return self._sendfile_use_send(file, offset, count) - else: - # os.sendfile() works with plain sockets only - return super().sendfile(file, offset, count) - - def recv(self, buflen=1024, flags=0): - self._checkClosed() - if self._sslobj is not None: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to recv() on %s" % - self.__class__) - return self.read(buflen) - else: - return super().recv(buflen, flags) - - def recv_into(self, buffer, nbytes=None, flags=0): - self._checkClosed() - if buffer and (nbytes is None): - nbytes = len(buffer) - elif nbytes is None: - nbytes = 1024 - if self._sslobj is not None: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to recv_into() on %s" % - self.__class__) - return self.read(nbytes, buffer) - else: - return super().recv_into(buffer, nbytes, flags) - - def recvfrom(self, buflen=1024, flags=0): - self._checkClosed() - if self._sslobj is not None: - raise ValueError("recvfrom not allowed on instances of %s" % - self.__class__) - else: - return super().recvfrom(buflen, flags) - - def recvfrom_into(self, buffer, nbytes=None, flags=0): - self._checkClosed() - if self._sslobj is not None: - raise ValueError("recvfrom_into not allowed on instances of %s" % - self.__class__) - else: - return super().recvfrom_into(buffer, nbytes, flags) - - def recvmsg(self, *args, **kwargs): - raise NotImplementedError("recvmsg not allowed on instances of %s" % - self.__class__) - - def recvmsg_into(self, *args, **kwargs): - raise NotImplementedError("recvmsg_into not allowed on instances of " - "%s" % self.__class__) - - @_sslcopydoc - def pending(self): - self._checkClosed() - if self._sslobj is not None: - return self._sslobj.pending() - else: - return 0 - - def shutdown(self, how): - self._checkClosed() - self._sslobj = None - super().shutdown(how) - - @_sslcopydoc - def unwrap(self): - if self._sslobj: - s = self._sslobj.shutdown() - self._sslobj = None - return s - else: - raise ValueError("No SSL wrapper around " + str(self)) - - @_sslcopydoc - def verify_client_post_handshake(self): - if self._sslobj: - return self._sslobj.verify_client_post_handshake() - else: - raise ValueError("No SSL wrapper around " + str(self)) - - def _real_close(self): - self._sslobj = None - super()._real_close() - - @_sslcopydoc - def do_handshake(self, block=False): - self._check_connected() - timeout = self.gettimeout() - try: - if timeout == 0.0 and block: - self.settimeout(None) - self._sslobj.do_handshake() - finally: - self.settimeout(timeout) - - def _real_connect(self, addr, connect_ex): - if self.server_side: - raise ValueError("can't connect in server-side mode") - # Here we assume that the socket is client-side, and not - # connected at the time of the call. We connect it, then wrap it. - if self._connected or self._sslobj is not None: - raise ValueError("attempt to connect already-connected SSLSocket!") - self._sslobj = self.context._wrap_socket( - self, False, self.server_hostname, - owner=self, session=self._session - ) - try: - if connect_ex: - rc = super().connect_ex(addr) - else: - rc = None - super().connect(addr) - if not rc: - self._connected = True - if self.do_handshake_on_connect: - self.do_handshake() - return rc - except (OSError, ValueError): - self._sslobj = None - raise - - def connect(self, addr): - """Connects to remote ADDR, and then wraps the connection in - an SSL channel.""" - self._real_connect(addr, False) - - def connect_ex(self, addr): - """Connects to remote ADDR, and then wraps the connection in - an SSL channel.""" - return self._real_connect(addr, True) - - def accept(self): - """Accepts a new connection from a remote client, and returns - a tuple containing that new connection wrapped with a server-side - SSL channel, and the address of the remote client.""" - - newsock, addr = super().accept() - newsock = self.context.wrap_socket(newsock, - do_handshake_on_connect=self.do_handshake_on_connect, - suppress_ragged_eofs=self.suppress_ragged_eofs, - server_side=True) - return newsock, addr - - @_sslcopydoc - def get_channel_binding(self, cb_type="tls-unique"): - if self._sslobj is not None: - return self._sslobj.get_channel_binding(cb_type) - else: - if cb_type not in CHANNEL_BINDING_TYPES: - raise ValueError( - "{0} channel binding type not implemented".format(cb_type) - ) - return None - - @_sslcopydoc - def version(self): - if self._sslobj is not None: - return self._sslobj.version() - else: - return None - - -# Python does not support forward declaration of types. -SSLContext.sslsocket_class = SSLSocket -SSLContext.sslobject_class = SSLObject - - -def wrap_socket(sock, keyfile=None, certfile=None, - server_side=False, cert_reqs=CERT_NONE, - ssl_version=PROTOCOL_TLS, ca_certs=None, - do_handshake_on_connect=True, - suppress_ragged_eofs=True, - ciphers=None): - warnings.warn( - "ssl.wrap_socket() is deprecated, use SSLContext.wrap_socket()", - category=DeprecationWarning, - stacklevel=2 - ) - if server_side and not certfile: - raise ValueError("certfile must be specified for server-side " - "operations") - if keyfile and not certfile: - raise ValueError("certfile must be specified") - context = SSLContext(ssl_version) - context.verify_mode = cert_reqs - if ca_certs: - context.load_verify_locations(ca_certs) - if certfile: - context.load_cert_chain(certfile, keyfile) - if ciphers: - context.set_ciphers(ciphers) - return context.wrap_socket( - sock=sock, server_side=server_side, - do_handshake_on_connect=do_handshake_on_connect, - suppress_ragged_eofs=suppress_ragged_eofs - ) - -# some utility functions - -def cert_time_to_seconds(cert_time): - """Return the time in seconds since the Epoch, given the timestring - representing the "notBefore" or "notAfter" date from a certificate - in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale). - - "notBefore" or "notAfter" dates must use UTC (RFC 5280). - - Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec - UTC should be specified as GMT (see ASN1_TIME_print()) - """ - from time import strptime - from calendar import timegm - - months = ( - "Jan","Feb","Mar","Apr","May","Jun", - "Jul","Aug","Sep","Oct","Nov","Dec" - ) - time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT - try: - month_number = months.index(cert_time[:3].title()) + 1 - except ValueError: - raise ValueError('time data %r does not match ' - 'format "%%b%s"' % (cert_time, time_format)) - else: - # found valid month - tt = strptime(cert_time[3:], time_format) - # return an integer, the previous mktime()-based implementation - # returned a float (fractional seconds are always zero here). - return timegm((tt[0], month_number) + tt[2:6]) - -PEM_HEADER = "-----BEGIN CERTIFICATE-----" -PEM_FOOTER = "-----END CERTIFICATE-----" - -def DER_cert_to_PEM_cert(der_cert_bytes): - """Takes a certificate in binary DER format and returns the - PEM version of it as a string.""" - - f = str(base64.standard_b64encode(der_cert_bytes), 'ASCII', 'strict') - ss = [PEM_HEADER] - ss += [f[i:i+64] for i in range(0, len(f), 64)] - ss.append(PEM_FOOTER + '\n') - return '\n'.join(ss) - -def PEM_cert_to_DER_cert(pem_cert_string): - """Takes a certificate in ASCII PEM format and returns the - DER-encoded version of it as a byte sequence""" - - if not pem_cert_string.startswith(PEM_HEADER): - raise ValueError("Invalid PEM encoding; must start with %s" - % PEM_HEADER) - if not pem_cert_string.strip().endswith(PEM_FOOTER): - raise ValueError("Invalid PEM encoding; must end with %s" - % PEM_FOOTER) - d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)] - return base64.decodebytes(d.encode('ASCII', 'strict')) - -def get_server_certificate(addr, ssl_version=PROTOCOL_TLS_CLIENT, - ca_certs=None, timeout=_GLOBAL_DEFAULT_TIMEOUT): - """Retrieve the certificate from the server at the specified address, - and return it as a PEM-encoded string. - If 'ca_certs' is specified, validate the server cert against it. - If 'ssl_version' is specified, use it in the connection attempt. - If 'timeout' is specified, use it in the connection attempt. - """ - - host, port = addr - if ca_certs is not None: - cert_reqs = CERT_REQUIRED - else: - cert_reqs = CERT_NONE - context = _create_stdlib_context(ssl_version, - cert_reqs=cert_reqs, - cafile=ca_certs) - with create_connection(addr, timeout=timeout) as sock: - with context.wrap_socket(sock, server_hostname=host) as sslsock: - dercert = sslsock.getpeercert(True) - return DER_cert_to_PEM_cert(dercert) - -def get_protocol_name(protocol_code): - return _PROTOCOL_NAMES.get(protocol_code, '') diff --git a/python/Lib/stat.py b/python/Lib/stat.py deleted file mode 100644 index 6a60dcc..0000000 --- a/python/Lib/stat.py +++ /dev/null @@ -1,195 +0,0 @@ -"""Constants/functions for interpreting results of os.stat() and os.lstat(). - -Suggested usage: from stat import * -""" - -# Indices for stat struct members in the tuple returned by os.stat() - -ST_MODE = 0 -ST_INO = 1 -ST_DEV = 2 -ST_NLINK = 3 -ST_UID = 4 -ST_GID = 5 -ST_SIZE = 6 -ST_ATIME = 7 -ST_MTIME = 8 -ST_CTIME = 9 - -# Extract bits from the mode - -def S_IMODE(mode): - """Return the portion of the file's mode that can be set by - os.chmod(). - """ - return mode & 0o7777 - -def S_IFMT(mode): - """Return the portion of the file's mode that describes the - file type. - """ - return mode & 0o170000 - -# Constants used as S_IFMT() for various file types -# (not all are implemented on all systems) - -S_IFDIR = 0o040000 # directory -S_IFCHR = 0o020000 # character device -S_IFBLK = 0o060000 # block device -S_IFREG = 0o100000 # regular file -S_IFIFO = 0o010000 # fifo (named pipe) -S_IFLNK = 0o120000 # symbolic link -S_IFSOCK = 0o140000 # socket file -# Fallbacks for uncommon platform-specific constants -S_IFDOOR = 0 -S_IFPORT = 0 -S_IFWHT = 0 - -# Functions to test for each file type - -def S_ISDIR(mode): - """Return True if mode is from a directory.""" - return S_IFMT(mode) == S_IFDIR - -def S_ISCHR(mode): - """Return True if mode is from a character special device file.""" - return S_IFMT(mode) == S_IFCHR - -def S_ISBLK(mode): - """Return True if mode is from a block special device file.""" - return S_IFMT(mode) == S_IFBLK - -def S_ISREG(mode): - """Return True if mode is from a regular file.""" - return S_IFMT(mode) == S_IFREG - -def S_ISFIFO(mode): - """Return True if mode is from a FIFO (named pipe).""" - return S_IFMT(mode) == S_IFIFO - -def S_ISLNK(mode): - """Return True if mode is from a symbolic link.""" - return S_IFMT(mode) == S_IFLNK - -def S_ISSOCK(mode): - """Return True if mode is from a socket.""" - return S_IFMT(mode) == S_IFSOCK - -def S_ISDOOR(mode): - """Return True if mode is from a door.""" - return False - -def S_ISPORT(mode): - """Return True if mode is from an event port.""" - return False - -def S_ISWHT(mode): - """Return True if mode is from a whiteout.""" - return False - -# Names for permission bits - -S_ISUID = 0o4000 # set UID bit -S_ISGID = 0o2000 # set GID bit -S_ENFMT = S_ISGID # file locking enforcement -S_ISVTX = 0o1000 # sticky bit -S_IREAD = 0o0400 # Unix V7 synonym for S_IRUSR -S_IWRITE = 0o0200 # Unix V7 synonym for S_IWUSR -S_IEXEC = 0o0100 # Unix V7 synonym for S_IXUSR -S_IRWXU = 0o0700 # mask for owner permissions -S_IRUSR = 0o0400 # read by owner -S_IWUSR = 0o0200 # write by owner -S_IXUSR = 0o0100 # execute by owner -S_IRWXG = 0o0070 # mask for group permissions -S_IRGRP = 0o0040 # read by group -S_IWGRP = 0o0020 # write by group -S_IXGRP = 0o0010 # execute by group -S_IRWXO = 0o0007 # mask for others (not in group) permissions -S_IROTH = 0o0004 # read by others -S_IWOTH = 0o0002 # write by others -S_IXOTH = 0o0001 # execute by others - -# Names for file flags - -UF_NODUMP = 0x00000001 # do not dump file -UF_IMMUTABLE = 0x00000002 # file may not be changed -UF_APPEND = 0x00000004 # file may only be appended to -UF_OPAQUE = 0x00000008 # directory is opaque when viewed through a union stack -UF_NOUNLINK = 0x00000010 # file may not be renamed or deleted -UF_COMPRESSED = 0x00000020 # OS X: file is hfs-compressed -UF_HIDDEN = 0x00008000 # OS X: file should not be displayed -SF_ARCHIVED = 0x00010000 # file may be archived -SF_IMMUTABLE = 0x00020000 # file may not be changed -SF_APPEND = 0x00040000 # file may only be appended to -SF_NOUNLINK = 0x00100000 # file may not be renamed or deleted -SF_SNAPSHOT = 0x00200000 # file is a snapshot file - - -_filemode_table = ( - ((S_IFLNK, "l"), - (S_IFSOCK, "s"), # Must appear before IFREG and IFDIR as IFSOCK == IFREG | IFDIR - (S_IFREG, "-"), - (S_IFBLK, "b"), - (S_IFDIR, "d"), - (S_IFCHR, "c"), - (S_IFIFO, "p")), - - ((S_IRUSR, "r"),), - ((S_IWUSR, "w"),), - ((S_IXUSR|S_ISUID, "s"), - (S_ISUID, "S"), - (S_IXUSR, "x")), - - ((S_IRGRP, "r"),), - ((S_IWGRP, "w"),), - ((S_IXGRP|S_ISGID, "s"), - (S_ISGID, "S"), - (S_IXGRP, "x")), - - ((S_IROTH, "r"),), - ((S_IWOTH, "w"),), - ((S_IXOTH|S_ISVTX, "t"), - (S_ISVTX, "T"), - (S_IXOTH, "x")) -) - -def filemode(mode): - """Convert a file's mode to a string of the form '-rwxrwxrwx'.""" - perm = [] - for table in _filemode_table: - for bit, char in table: - if mode & bit == bit: - perm.append(char) - break - else: - perm.append("-") - return "".join(perm) - - -# Windows FILE_ATTRIBUTE constants for interpreting os.stat()'s -# "st_file_attributes" member - -FILE_ATTRIBUTE_ARCHIVE = 32 -FILE_ATTRIBUTE_COMPRESSED = 2048 -FILE_ATTRIBUTE_DEVICE = 64 -FILE_ATTRIBUTE_DIRECTORY = 16 -FILE_ATTRIBUTE_ENCRYPTED = 16384 -FILE_ATTRIBUTE_HIDDEN = 2 -FILE_ATTRIBUTE_INTEGRITY_STREAM = 32768 -FILE_ATTRIBUTE_NORMAL = 128 -FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 8192 -FILE_ATTRIBUTE_NO_SCRUB_DATA = 131072 -FILE_ATTRIBUTE_OFFLINE = 4096 -FILE_ATTRIBUTE_READONLY = 1 -FILE_ATTRIBUTE_REPARSE_POINT = 1024 -FILE_ATTRIBUTE_SPARSE_FILE = 512 -FILE_ATTRIBUTE_SYSTEM = 4 -FILE_ATTRIBUTE_TEMPORARY = 256 -FILE_ATTRIBUTE_VIRTUAL = 65536 - - -# If available, use C implementation -try: - from _stat import * -except ImportError: - pass diff --git a/python/Lib/statistics.py b/python/Lib/statistics.py deleted file mode 100644 index c0f1486..0000000 --- a/python/Lib/statistics.py +++ /dev/null @@ -1,1390 +0,0 @@ -""" -Basic statistics module. - -This module provides functions for calculating statistics of data, including -averages, variance, and standard deviation. - -Calculating averages --------------------- - -================== ================================================== -Function Description -================== ================================================== -mean Arithmetic mean (average) of data. -fmean Fast, floating point arithmetic mean. -geometric_mean Geometric mean of data. -harmonic_mean Harmonic mean of data. -median Median (middle value) of data. -median_low Low median of data. -median_high High median of data. -median_grouped Median, or 50th percentile, of grouped data. -mode Mode (most common value) of data. -multimode List of modes (most common values of data). -quantiles Divide data into intervals with equal probability. -================== ================================================== - -Calculate the arithmetic mean ("the average") of data: - ->>> mean([-1.0, 2.5, 3.25, 5.75]) -2.625 - - -Calculate the standard median of discrete data: - ->>> median([2, 3, 4, 5]) -3.5 - - -Calculate the median, or 50th percentile, of data grouped into class intervals -centred on the data values provided. E.g. if your data points are rounded to -the nearest whole number: - ->>> median_grouped([2, 2, 3, 3, 3, 4]) #doctest: +ELLIPSIS -2.8333333333... - -This should be interpreted in this way: you have two data points in the class -interval 1.5-2.5, three data points in the class interval 2.5-3.5, and one in -the class interval 3.5-4.5. The median of these data points is 2.8333... - - -Calculating variability or spread ---------------------------------- - -================== ============================================= -Function Description -================== ============================================= -pvariance Population variance of data. -variance Sample variance of data. -pstdev Population standard deviation of data. -stdev Sample standard deviation of data. -================== ============================================= - -Calculate the standard deviation of sample data: - ->>> stdev([2.5, 3.25, 5.5, 11.25, 11.75]) #doctest: +ELLIPSIS -4.38961843444... - -If you have previously calculated the mean, you can pass it as the optional -second argument to the four "spread" functions to avoid recalculating it: - ->>> data = [1, 2, 2, 4, 4, 4, 5, 6] ->>> mu = mean(data) ->>> pvariance(data, mu) -2.5 - - -Statistics for relations between two inputs -------------------------------------------- - -================== ==================================================== -Function Description -================== ==================================================== -covariance Sample covariance for two variables. -correlation Pearson's correlation coefficient for two variables. -linear_regression Intercept and slope for simple linear regression. -================== ==================================================== - -Calculate covariance, Pearson's correlation, and simple linear regression -for two inputs: - ->>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] ->>> y = [1, 2, 3, 1, 2, 3, 1, 2, 3] ->>> covariance(x, y) -0.75 ->>> correlation(x, y) #doctest: +ELLIPSIS -0.31622776601... ->>> linear_regression(x, y) #doctest: -LinearRegression(slope=0.1, intercept=1.5) - - -Exceptions ----------- - -A single exception is defined: StatisticsError is a subclass of ValueError. - -""" - -__all__ = [ - 'NormalDist', - 'StatisticsError', - 'correlation', - 'covariance', - 'fmean', - 'geometric_mean', - 'harmonic_mean', - 'linear_regression', - 'mean', - 'median', - 'median_grouped', - 'median_high', - 'median_low', - 'mode', - 'multimode', - 'pstdev', - 'pvariance', - 'quantiles', - 'stdev', - 'variance', -] - -import math -import numbers -import random -import sys - -from fractions import Fraction -from decimal import Decimal -from itertools import groupby, repeat -from bisect import bisect_left, bisect_right -from math import hypot, sqrt, fabs, exp, erf, tau, log, fsum -from functools import reduce -from operator import mul -from collections import Counter, namedtuple, defaultdict - -_SQRT2 = sqrt(2.0) - -# === Exceptions === - -class StatisticsError(ValueError): - pass - - -# === Private utilities === - -def _sum(data): - """_sum(data) -> (type, sum, count) - - Return a high-precision sum of the given numeric data as a fraction, - together with the type to be converted to and the count of items. - - Examples - -------- - - >>> _sum([3, 2.25, 4.5, -0.5, 0.25]) - (, Fraction(19, 2), 5) - - Some sources of round-off error will be avoided: - - # Built-in sum returns zero. - >>> _sum([1e50, 1, -1e50] * 1000) - (, Fraction(1000, 1), 3000) - - Fractions and Decimals are also supported: - - >>> from fractions import Fraction as F - >>> _sum([F(2, 3), F(7, 5), F(1, 4), F(5, 6)]) - (, Fraction(63, 20), 4) - - >>> from decimal import Decimal as D - >>> data = [D("0.1375"), D("0.2108"), D("0.3061"), D("0.0419")] - >>> _sum(data) - (, Fraction(6963, 10000), 4) - - Mixed types are currently treated as an error, except that int is - allowed. - """ - count = 0 - types = set() - types_add = types.add - partials = {} - partials_get = partials.get - for typ, values in groupby(data, type): - types_add(typ) - for n, d in map(_exact_ratio, values): - count += 1 - partials[d] = partials_get(d, 0) + n - if None in partials: - # The sum will be a NAN or INF. We can ignore all the finite - # partials, and just look at this special one. - total = partials[None] - assert not _isfinite(total) - else: - # Sum all the partial sums using builtin sum. - total = sum(Fraction(n, d) for d, n in partials.items()) - T = reduce(_coerce, types, int) # or raise TypeError - return (T, total, count) - - -def _ss(data, c=None): - """Return the exact mean and sum of square deviations of sequence data. - - Calculations are done in a single pass, allowing the input to be an iterator. - - If given *c* is used the mean; otherwise, it is calculated from the data. - Use the *c* argument with care, as it can lead to garbage results. - - """ - if c is not None: - T, ssd, count = _sum((d := x - c) * d for x in data) - return (T, ssd, c, count) - count = 0 - types = set() - types_add = types.add - sx_partials = defaultdict(int) - sxx_partials = defaultdict(int) - for typ, values in groupby(data, type): - types_add(typ) - for n, d in map(_exact_ratio, values): - count += 1 - sx_partials[d] += n - sxx_partials[d] += n * n - if not count: - ssd = c = Fraction(0) - elif None in sx_partials: - # The sum will be a NAN or INF. We can ignore all the finite - # partials, and just look at this special one. - ssd = c = sx_partials[None] - assert not _isfinite(ssd) - else: - sx = sum(Fraction(n, d) for d, n in sx_partials.items()) - sxx = sum(Fraction(n, d*d) for d, n in sxx_partials.items()) - # This formula has poor numeric properties for floats, - # but with fractions it is exact. - ssd = (count * sxx - sx * sx) / count - c = sx / count - T = reduce(_coerce, types, int) # or raise TypeError - return (T, ssd, c, count) - - -def _isfinite(x): - try: - return x.is_finite() # Likely a Decimal. - except AttributeError: - return math.isfinite(x) # Coerces to float first. - - -def _coerce(T, S): - """Coerce types T and S to a common type, or raise TypeError. - - Coercion rules are currently an implementation detail. See the CoerceTest - test class in test_statistics for details. - """ - # See http://bugs.python.org/issue24068. - assert T is not bool, "initial type T is bool" - # If the types are the same, no need to coerce anything. Put this - # first, so that the usual case (no coercion needed) happens as soon - # as possible. - if T is S: return T - # Mixed int & other coerce to the other type. - if S is int or S is bool: return T - if T is int: return S - # If one is a (strict) subclass of the other, coerce to the subclass. - if issubclass(S, T): return S - if issubclass(T, S): return T - # Ints coerce to the other type. - if issubclass(T, int): return S - if issubclass(S, int): return T - # Mixed fraction & float coerces to float (or float subclass). - if issubclass(T, Fraction) and issubclass(S, float): - return S - if issubclass(T, float) and issubclass(S, Fraction): - return T - # Any other combination is disallowed. - msg = "don't know how to coerce %s and %s" - raise TypeError(msg % (T.__name__, S.__name__)) - - -def _exact_ratio(x): - """Return Real number x to exact (numerator, denominator) pair. - - >>> _exact_ratio(0.25) - (1, 4) - - x is expected to be an int, Fraction, Decimal or float. - """ - - # XXX We should revisit whether using fractions to accumulate exact - # ratios is the right way to go. - - # The integer ratios for binary floats can have numerators or - # denominators with over 300 decimal digits. The problem is more - # acute with decimal floats where the default decimal context - # supports a huge range of exponents from Emin=-999999 to - # Emax=999999. When expanded with as_integer_ratio(), numbers like - # Decimal('3.14E+5000') and Decimal('3.14E-5000') have large - # numerators or denominators that will slow computation. - - # When the integer ratios are accumulated as fractions, the size - # grows to cover the full range from the smallest magnitude to the - # largest. For example, Fraction(3.14E+300) + Fraction(3.14E-300), - # has a 616 digit numerator. Likewise, - # Fraction(Decimal('3.14E+5000')) + Fraction(Decimal('3.14E-5000')) - # has 10,003 digit numerator. - - # This doesn't seem to have been problem in practice, but it is a - # potential pitfall. - - try: - return x.as_integer_ratio() - except AttributeError: - pass - except (OverflowError, ValueError): - # float NAN or INF. - assert not _isfinite(x) - return (x, None) - try: - # x may be an Integral ABC. - return (x.numerator, x.denominator) - except AttributeError: - msg = f"can't convert type '{type(x).__name__}' to numerator/denominator" - raise TypeError(msg) - - -def _convert(value, T): - """Convert value to given numeric type T.""" - if type(value) is T: - # This covers the cases where T is Fraction, or where value is - # a NAN or INF (Decimal or float). - return value - if issubclass(T, int) and value.denominator != 1: - T = float - try: - # FIXME: what do we do if this overflows? - return T(value) - except TypeError: - if issubclass(T, Decimal): - return T(value.numerator) / T(value.denominator) - else: - raise - - -def _fail_neg(values, errmsg='negative value'): - """Iterate over values, failing if any are less than zero.""" - for x in values: - if x < 0: - raise StatisticsError(errmsg) - yield x - - -def _integer_sqrt_of_frac_rto(n: int, m: int) -> int: - """Square root of n/m, rounded to the nearest integer using round-to-odd.""" - # Reference: https://www.lri.fr/~melquion/doc/05-imacs17_1-expose.pdf - a = math.isqrt(n // m) - return a | (a*a*m != n) - - -# For 53 bit precision floats, the bit width used in -# _float_sqrt_of_frac() is 109. -_sqrt_bit_width: int = 2 * sys.float_info.mant_dig + 3 - - -def _float_sqrt_of_frac(n: int, m: int) -> float: - """Square root of n/m as a float, correctly rounded.""" - # See principle and proof sketch at: https://bugs.python.org/msg407078 - q = (n.bit_length() - m.bit_length() - _sqrt_bit_width) // 2 - if q >= 0: - numerator = _integer_sqrt_of_frac_rto(n, m << 2 * q) << q - denominator = 1 - else: - numerator = _integer_sqrt_of_frac_rto(n << -2 * q, m) - denominator = 1 << -q - return numerator / denominator # Convert to float - - -def _decimal_sqrt_of_frac(n: int, m: int) -> Decimal: - """Square root of n/m as a Decimal, correctly rounded.""" - # Premise: For decimal, computing (n/m).sqrt() can be off - # by 1 ulp from the correctly rounded result. - # Method: Check the result, moving up or down a step if needed. - if n <= 0: - if not n: - return Decimal('0.0') - n, m = -n, -m - - root = (Decimal(n) / Decimal(m)).sqrt() - nr, dr = root.as_integer_ratio() - - plus = root.next_plus() - np, dp = plus.as_integer_ratio() - # test: n / m > ((root + plus) / 2) ** 2 - if 4 * n * (dr*dp)**2 > m * (dr*np + dp*nr)**2: - return plus - - minus = root.next_minus() - nm, dm = minus.as_integer_ratio() - # test: n / m < ((root + minus) / 2) ** 2 - if 4 * n * (dr*dm)**2 < m * (dr*nm + dm*nr)**2: - return minus - - return root - - -# === Measures of central tendency (averages) === - -def mean(data): - """Return the sample arithmetic mean of data. - - >>> mean([1, 2, 3, 4, 4]) - 2.8 - - >>> from fractions import Fraction as F - >>> mean([F(3, 7), F(1, 21), F(5, 3), F(1, 3)]) - Fraction(13, 21) - - >>> from decimal import Decimal as D - >>> mean([D("0.5"), D("0.75"), D("0.625"), D("0.375")]) - Decimal('0.5625') - - If ``data`` is empty, StatisticsError will be raised. - """ - T, total, n = _sum(data) - if n < 1: - raise StatisticsError('mean requires at least one data point') - return _convert(total / n, T) - - -def fmean(data, weights=None): - """Convert data to floats and compute the arithmetic mean. - - This runs faster than the mean() function and it always returns a float. - If the input dataset is empty, it raises a StatisticsError. - - >>> fmean([3.5, 4.0, 5.25]) - 4.25 - """ - try: - n = len(data) - except TypeError: - # Handle iterators that do not define __len__(). - n = 0 - def count(iterable): - nonlocal n - for n, x in enumerate(iterable, start=1): - yield x - data = count(data) - if weights is None: - total = fsum(data) - if not n: - raise StatisticsError('fmean requires at least one data point') - return total / n - try: - num_weights = len(weights) - except TypeError: - weights = list(weights) - num_weights = len(weights) - num = fsum(map(mul, data, weights)) - if n != num_weights: - raise StatisticsError('data and weights must be the same length') - den = fsum(weights) - if not den: - raise StatisticsError('sum of weights must be non-zero') - return num / den - - -def geometric_mean(data): - """Convert data to floats and compute the geometric mean. - - Raises a StatisticsError if the input dataset is empty, - if it contains a zero, or if it contains a negative value. - - No special efforts are made to achieve exact results. - (However, this may change in the future.) - - >>> round(geometric_mean([54, 24, 36]), 9) - 36.0 - """ - try: - return exp(fmean(map(log, data))) - except ValueError: - raise StatisticsError('geometric mean requires a non-empty dataset ' - 'containing positive numbers') from None - - -def harmonic_mean(data, weights=None): - """Return the harmonic mean of data. - - The harmonic mean is the reciprocal of the arithmetic mean of the - reciprocals of the data. It can be used for averaging ratios or - rates, for example speeds. - - Suppose a car travels 40 km/hr for 5 km and then speeds-up to - 60 km/hr for another 5 km. What is the average speed? - - >>> harmonic_mean([40, 60]) - 48.0 - - Suppose a car travels 40 km/hr for 5 km, and when traffic clears, - speeds-up to 60 km/hr for the remaining 30 km of the journey. What - is the average speed? - - >>> harmonic_mean([40, 60], weights=[5, 30]) - 56.0 - - If ``data`` is empty, or any element is less than zero, - ``harmonic_mean`` will raise ``StatisticsError``. - """ - if iter(data) is data: - data = list(data) - errmsg = 'harmonic mean does not support negative values' - n = len(data) - if n < 1: - raise StatisticsError('harmonic_mean requires at least one data point') - elif n == 1 and weights is None: - x = data[0] - if isinstance(x, (numbers.Real, Decimal)): - if x < 0: - raise StatisticsError(errmsg) - return x - else: - raise TypeError('unsupported type') - if weights is None: - weights = repeat(1, n) - sum_weights = n - else: - if iter(weights) is weights: - weights = list(weights) - if len(weights) != n: - raise StatisticsError('Number of weights does not match data size') - _, sum_weights, _ = _sum(w for w in _fail_neg(weights, errmsg)) - try: - data = _fail_neg(data, errmsg) - T, total, count = _sum(w / x if w else 0 for w, x in zip(weights, data)) - except ZeroDivisionError: - return 0 - if total <= 0: - raise StatisticsError('Weighted sum must be positive') - return _convert(sum_weights / total, T) - -# FIXME: investigate ways to calculate medians without sorting? Quickselect? -def median(data): - """Return the median (middle value) of numeric data. - - When the number of data points is odd, return the middle data point. - When the number of data points is even, the median is interpolated by - taking the average of the two middle values: - - >>> median([1, 3, 5]) - 3 - >>> median([1, 3, 5, 7]) - 4.0 - - """ - data = sorted(data) - n = len(data) - if n == 0: - raise StatisticsError("no median for empty data") - if n % 2 == 1: - return data[n // 2] - else: - i = n // 2 - return (data[i - 1] + data[i]) / 2 - - -def median_low(data): - """Return the low median of numeric data. - - When the number of data points is odd, the middle value is returned. - When it is even, the smaller of the two middle values is returned. - - >>> median_low([1, 3, 5]) - 3 - >>> median_low([1, 3, 5, 7]) - 3 - - """ - data = sorted(data) - n = len(data) - if n == 0: - raise StatisticsError("no median for empty data") - if n % 2 == 1: - return data[n // 2] - else: - return data[n // 2 - 1] - - -def median_high(data): - """Return the high median of data. - - When the number of data points is odd, the middle value is returned. - When it is even, the larger of the two middle values is returned. - - >>> median_high([1, 3, 5]) - 3 - >>> median_high([1, 3, 5, 7]) - 5 - - """ - data = sorted(data) - n = len(data) - if n == 0: - raise StatisticsError("no median for empty data") - return data[n // 2] - - -def median_grouped(data, interval=1.0): - """Estimates the median for numeric data binned around the midpoints - of consecutive, fixed-width intervals. - - The *data* can be any iterable of numeric data with each value being - exactly the midpoint of a bin. At least one value must be present. - - The *interval* is width of each bin. - - For example, demographic information may have been summarized into - consecutive ten-year age groups with each group being represented - by the 5-year midpoints of the intervals: - - >>> demographics = Counter({ - ... 25: 172, # 20 to 30 years old - ... 35: 484, # 30 to 40 years old - ... 45: 387, # 40 to 50 years old - ... 55: 22, # 50 to 60 years old - ... 65: 6, # 60 to 70 years old - ... }) - - The 50th percentile (median) is the 536th person out of the 1071 - member cohort. That person is in the 30 to 40 year old age group. - - The regular median() function would assume that everyone in the - tricenarian age group was exactly 35 years old. A more tenable - assumption is that the 484 members of that age group are evenly - distributed between 30 and 40. For that, we use median_grouped(). - - >>> data = list(demographics.elements()) - >>> median(data) - 35 - >>> round(median_grouped(data, interval=10), 1) - 37.5 - - The caller is responsible for making sure the data points are separated - by exact multiples of *interval*. This is essential for getting a - correct result. The function does not check this precondition. - - Inputs may be any numeric type that can be coerced to a float during - the interpolation step. - - """ - data = sorted(data) - n = len(data) - if not n: - raise StatisticsError("no median for empty data") - - # Find the value at the midpoint. Remember this corresponds to the - # midpoint of the class interval. - x = data[n // 2] - - # Using O(log n) bisection, find where all the x values occur in the data. - # All x will lie within data[i:j]. - i = bisect_left(data, x) - j = bisect_right(data, x, lo=i) - - # Coerce to floats, raising a TypeError if not possible - try: - interval = float(interval) - x = float(x) - except ValueError: - raise TypeError(f'Value cannot be converted to a float') - - # Interpolate the median using the formula found at: - # https://www.cuemath.com/data/median-of-grouped-data/ - L = x - interval / 2.0 # Lower limit of the median interval - cf = i # Cumulative frequency of the preceding interval - f = j - i # Number of elements in the median internal - return L + interval * (n / 2 - cf) / f - - -def mode(data): - """Return the most common data point from discrete or nominal data. - - ``mode`` assumes discrete data, and returns a single value. This is the - standard treatment of the mode as commonly taught in schools: - - >>> mode([1, 1, 2, 3, 3, 3, 3, 4]) - 3 - - This also works with nominal (non-numeric) data: - - >>> mode(["red", "blue", "blue", "red", "green", "red", "red"]) - 'red' - - If there are multiple modes with same frequency, return the first one - encountered: - - >>> mode(['red', 'red', 'green', 'blue', 'blue']) - 'red' - - If *data* is empty, ``mode``, raises StatisticsError. - - """ - pairs = Counter(iter(data)).most_common(1) - try: - return pairs[0][0] - except IndexError: - raise StatisticsError('no mode for empty data') from None - - -def multimode(data): - """Return a list of the most frequently occurring values. - - Will return more than one result if there are multiple modes - or an empty list if *data* is empty. - - >>> multimode('aabbbbbbbbcc') - ['b'] - >>> multimode('aabbbbccddddeeffffgg') - ['b', 'd', 'f'] - >>> multimode('') - [] - """ - counts = Counter(iter(data)) - if not counts: - return [] - maxcount = max(counts.values()) - return [value for value, count in counts.items() if count == maxcount] - - -# Notes on methods for computing quantiles -# ---------------------------------------- -# -# There is no one perfect way to compute quantiles. Here we offer -# two methods that serve common needs. Most other packages -# surveyed offered at least one or both of these two, making them -# "standard" in the sense of "widely-adopted and reproducible". -# They are also easy to explain, easy to compute manually, and have -# straight-forward interpretations that aren't surprising. - -# The default method is known as "R6", "PERCENTILE.EXC", or "expected -# value of rank order statistics". The alternative method is known as -# "R7", "PERCENTILE.INC", or "mode of rank order statistics". - -# For sample data where there is a positive probability for values -# beyond the range of the data, the R6 exclusive method is a -# reasonable choice. Consider a random sample of nine values from a -# population with a uniform distribution from 0.0 to 1.0. The -# distribution of the third ranked sample point is described by -# betavariate(alpha=3, beta=7) which has mode=0.250, median=0.286, and -# mean=0.300. Only the latter (which corresponds with R6) gives the -# desired cut point with 30% of the population falling below that -# value, making it comparable to a result from an inv_cdf() function. -# The R6 exclusive method is also idempotent. - -# For describing population data where the end points are known to -# be included in the data, the R7 inclusive method is a reasonable -# choice. Instead of the mean, it uses the mode of the beta -# distribution for the interior points. Per Hyndman & Fan, "One nice -# property is that the vertices of Q7(p) divide the range into n - 1 -# intervals, and exactly 100p% of the intervals lie to the left of -# Q7(p) and 100(1 - p)% of the intervals lie to the right of Q7(p)." - -# If needed, other methods could be added. However, for now, the -# position is that fewer options make for easier choices and that -# external packages can be used for anything more advanced. - -def quantiles(data, *, n=4, method='exclusive'): - """Divide *data* into *n* continuous intervals with equal probability. - - Returns a list of (n - 1) cut points separating the intervals. - - Set *n* to 4 for quartiles (the default). Set *n* to 10 for deciles. - Set *n* to 100 for percentiles which gives the 99 cuts points that - separate *data* in to 100 equal sized groups. - - The *data* can be any iterable containing sample. - The cut points are linearly interpolated between data points. - - If *method* is set to *inclusive*, *data* is treated as population - data. The minimum value is treated as the 0th percentile and the - maximum value is treated as the 100th percentile. - """ - if n < 1: - raise StatisticsError('n must be at least 1') - data = sorted(data) - ld = len(data) - if ld < 2: - raise StatisticsError('must have at least two data points') - if method == 'inclusive': - m = ld - 1 - result = [] - for i in range(1, n): - j, delta = divmod(i * m, n) - interpolated = (data[j] * (n - delta) + data[j + 1] * delta) / n - result.append(interpolated) - return result - if method == 'exclusive': - m = ld + 1 - result = [] - for i in range(1, n): - j = i * m // n # rescale i to m/n - j = 1 if j < 1 else ld-1 if j > ld-1 else j # clamp to 1 .. ld-1 - delta = i*m - j*n # exact integer math - interpolated = (data[j - 1] * (n - delta) + data[j] * delta) / n - result.append(interpolated) - return result - raise ValueError(f'Unknown method: {method!r}') - - -# === Measures of spread === - -# See http://mathworld.wolfram.com/Variance.html -# http://mathworld.wolfram.com/SampleVariance.html - - -def variance(data, xbar=None): - """Return the sample variance of data. - - data should be an iterable of Real-valued numbers, with at least two - values. The optional argument xbar, if given, should be the mean of - the data. If it is missing or None, the mean is automatically calculated. - - Use this function when your data is a sample from a population. To - calculate the variance from the entire population, see ``pvariance``. - - Examples: - - >>> data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5] - >>> variance(data) - 1.3720238095238095 - - If you have already calculated the mean of your data, you can pass it as - the optional second argument ``xbar`` to avoid recalculating it: - - >>> m = mean(data) - >>> variance(data, m) - 1.3720238095238095 - - This function does not check that ``xbar`` is actually the mean of - ``data``. Giving arbitrary values for ``xbar`` may lead to invalid or - impossible results. - - Decimals and Fractions are supported: - - >>> from decimal import Decimal as D - >>> variance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")]) - Decimal('31.01875') - - >>> from fractions import Fraction as F - >>> variance([F(1, 6), F(1, 2), F(5, 3)]) - Fraction(67, 108) - - """ - T, ss, c, n = _ss(data, xbar) - if n < 2: - raise StatisticsError('variance requires at least two data points') - return _convert(ss / (n - 1), T) - - -def pvariance(data, mu=None): - """Return the population variance of ``data``. - - data should be a sequence or iterable of Real-valued numbers, with at least one - value. The optional argument mu, if given, should be the mean of - the data. If it is missing or None, the mean is automatically calculated. - - Use this function to calculate the variance from the entire population. - To estimate the variance from a sample, the ``variance`` function is - usually a better choice. - - Examples: - - >>> data = [0.0, 0.25, 0.25, 1.25, 1.5, 1.75, 2.75, 3.25] - >>> pvariance(data) - 1.25 - - If you have already calculated the mean of the data, you can pass it as - the optional second argument to avoid recalculating it: - - >>> mu = mean(data) - >>> pvariance(data, mu) - 1.25 - - Decimals and Fractions are supported: - - >>> from decimal import Decimal as D - >>> pvariance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")]) - Decimal('24.815') - - >>> from fractions import Fraction as F - >>> pvariance([F(1, 4), F(5, 4), F(1, 2)]) - Fraction(13, 72) - - """ - T, ss, c, n = _ss(data, mu) - if n < 1: - raise StatisticsError('pvariance requires at least one data point') - return _convert(ss / n, T) - - -def stdev(data, xbar=None): - """Return the square root of the sample variance. - - See ``variance`` for arguments and other details. - - >>> stdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75]) - 1.0810874155219827 - - """ - T, ss, c, n = _ss(data, xbar) - if n < 2: - raise StatisticsError('stdev requires at least two data points') - mss = ss / (n - 1) - if issubclass(T, Decimal): - return _decimal_sqrt_of_frac(mss.numerator, mss.denominator) - return _float_sqrt_of_frac(mss.numerator, mss.denominator) - - -def pstdev(data, mu=None): - """Return the square root of the population variance. - - See ``pvariance`` for arguments and other details. - - >>> pstdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75]) - 0.986893273527251 - - """ - T, ss, c, n = _ss(data, mu) - if n < 1: - raise StatisticsError('pstdev requires at least one data point') - mss = ss / n - if issubclass(T, Decimal): - return _decimal_sqrt_of_frac(mss.numerator, mss.denominator) - return _float_sqrt_of_frac(mss.numerator, mss.denominator) - - -def _mean_stdev(data): - """In one pass, compute the mean and sample standard deviation as floats.""" - T, ss, xbar, n = _ss(data) - if n < 2: - raise StatisticsError('stdev requires at least two data points') - mss = ss / (n - 1) - try: - return float(xbar), _float_sqrt_of_frac(mss.numerator, mss.denominator) - except AttributeError: - # Handle Nans and Infs gracefully - return float(xbar), float(xbar) / float(ss) - - -# === Statistics for relations between two inputs === - -# See https://en.wikipedia.org/wiki/Covariance -# https://en.wikipedia.org/wiki/Pearson_correlation_coefficient -# https://en.wikipedia.org/wiki/Simple_linear_regression - - -def covariance(x, y, /): - """Covariance - - Return the sample covariance of two inputs *x* and *y*. Covariance - is a measure of the joint variability of two inputs. - - >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] - >>> y = [1, 2, 3, 1, 2, 3, 1, 2, 3] - >>> covariance(x, y) - 0.75 - >>> z = [9, 8, 7, 6, 5, 4, 3, 2, 1] - >>> covariance(x, z) - -7.5 - >>> covariance(z, x) - -7.5 - - """ - n = len(x) - if len(y) != n: - raise StatisticsError('covariance requires that both inputs have same number of data points') - if n < 2: - raise StatisticsError('covariance requires at least two data points') - xbar = fsum(x) / n - ybar = fsum(y) / n - sxy = fsum((xi - xbar) * (yi - ybar) for xi, yi in zip(x, y)) - return sxy / (n - 1) - - -def correlation(x, y, /): - """Pearson's correlation coefficient - - Return the Pearson's correlation coefficient for two inputs. Pearson's - correlation coefficient *r* takes values between -1 and +1. It measures the - strength and direction of the linear relationship, where +1 means very - strong, positive linear relationship, -1 very strong, negative linear - relationship, and 0 no linear relationship. - - >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] - >>> y = [9, 8, 7, 6, 5, 4, 3, 2, 1] - >>> correlation(x, x) - 1.0 - >>> correlation(x, y) - -1.0 - - """ - n = len(x) - if len(y) != n: - raise StatisticsError('correlation requires that both inputs have same number of data points') - if n < 2: - raise StatisticsError('correlation requires at least two data points') - xbar = fsum(x) / n - ybar = fsum(y) / n - sxy = fsum((xi - xbar) * (yi - ybar) for xi, yi in zip(x, y)) - sxx = fsum((d := xi - xbar) * d for xi in x) - syy = fsum((d := yi - ybar) * d for yi in y) - try: - return sxy / sqrt(sxx * syy) - except ZeroDivisionError: - raise StatisticsError('at least one of the inputs is constant') - - -LinearRegression = namedtuple('LinearRegression', ('slope', 'intercept')) - - -def linear_regression(x, y, /, *, proportional=False): - """Slope and intercept for simple linear regression. - - Return the slope and intercept of simple linear regression - parameters estimated using ordinary least squares. Simple linear - regression describes relationship between an independent variable - *x* and a dependent variable *y* in terms of a linear function: - - y = slope * x + intercept + noise - - where *slope* and *intercept* are the regression parameters that are - estimated, and noise represents the variability of the data that was - not explained by the linear regression (it is equal to the - difference between predicted and actual values of the dependent - variable). - - The parameters are returned as a named tuple. - - >>> x = [1, 2, 3, 4, 5] - >>> noise = NormalDist().samples(5, seed=42) - >>> y = [3 * x[i] + 2 + noise[i] for i in range(5)] - >>> linear_regression(x, y) #doctest: +ELLIPSIS - LinearRegression(slope=3.09078914170..., intercept=1.75684970486...) - - If *proportional* is true, the independent variable *x* and the - dependent variable *y* are assumed to be directly proportional. - The data is fit to a line passing through the origin. - - Since the *intercept* will always be 0.0, the underlying linear - function simplifies to: - - y = slope * x + noise - - >>> y = [3 * x[i] + noise[i] for i in range(5)] - >>> linear_regression(x, y, proportional=True) #doctest: +ELLIPSIS - LinearRegression(slope=3.02447542484..., intercept=0.0) - - """ - n = len(x) - if len(y) != n: - raise StatisticsError('linear regression requires that both inputs have same number of data points') - if n < 2: - raise StatisticsError('linear regression requires at least two data points') - if proportional: - sxy = fsum(xi * yi for xi, yi in zip(x, y)) - sxx = fsum(xi * xi for xi in x) - else: - xbar = fsum(x) / n - ybar = fsum(y) / n - sxy = fsum((xi - xbar) * (yi - ybar) for xi, yi in zip(x, y)) - sxx = fsum((d := xi - xbar) * d for xi in x) - try: - slope = sxy / sxx # equivalent to: covariance(x, y) / variance(x) - except ZeroDivisionError: - raise StatisticsError('x is constant') - intercept = 0.0 if proportional else ybar - slope * xbar - return LinearRegression(slope=slope, intercept=intercept) - - -## Normal Distribution ##################################################### - - -def _normal_dist_inv_cdf(p, mu, sigma): - # There is no closed-form solution to the inverse CDF for the normal - # distribution, so we use a rational approximation instead: - # Wichura, M.J. (1988). "Algorithm AS241: The Percentage Points of the - # Normal Distribution". Applied Statistics. Blackwell Publishing. 37 - # (3): 477–484. doi:10.2307/2347330. JSTOR 2347330. - q = p - 0.5 - if fabs(q) <= 0.425: - r = 0.180625 - q * q - # Hash sum: 55.88319_28806_14901_4439 - num = (((((((2.50908_09287_30122_6727e+3 * r + - 3.34305_75583_58812_8105e+4) * r + - 6.72657_70927_00870_0853e+4) * r + - 4.59219_53931_54987_1457e+4) * r + - 1.37316_93765_50946_1125e+4) * r + - 1.97159_09503_06551_4427e+3) * r + - 1.33141_66789_17843_7745e+2) * r + - 3.38713_28727_96366_6080e+0) * q - den = (((((((5.22649_52788_52854_5610e+3 * r + - 2.87290_85735_72194_2674e+4) * r + - 3.93078_95800_09271_0610e+4) * r + - 2.12137_94301_58659_5867e+4) * r + - 5.39419_60214_24751_1077e+3) * r + - 6.87187_00749_20579_0830e+2) * r + - 4.23133_30701_60091_1252e+1) * r + - 1.0) - x = num / den - return mu + (x * sigma) - r = p if q <= 0.0 else 1.0 - p - r = sqrt(-log(r)) - if r <= 5.0: - r = r - 1.6 - # Hash sum: 49.33206_50330_16102_89036 - num = (((((((7.74545_01427_83414_07640e-4 * r + - 2.27238_44989_26918_45833e-2) * r + - 2.41780_72517_74506_11770e-1) * r + - 1.27045_82524_52368_38258e+0) * r + - 3.64784_83247_63204_60504e+0) * r + - 5.76949_72214_60691_40550e+0) * r + - 4.63033_78461_56545_29590e+0) * r + - 1.42343_71107_49683_57734e+0) - den = (((((((1.05075_00716_44416_84324e-9 * r + - 5.47593_80849_95344_94600e-4) * r + - 1.51986_66563_61645_71966e-2) * r + - 1.48103_97642_74800_74590e-1) * r + - 6.89767_33498_51000_04550e-1) * r + - 1.67638_48301_83803_84940e+0) * r + - 2.05319_16266_37758_82187e+0) * r + - 1.0) - else: - r = r - 5.0 - # Hash sum: 47.52583_31754_92896_71629 - num = (((((((2.01033_43992_92288_13265e-7 * r + - 2.71155_55687_43487_57815e-5) * r + - 1.24266_09473_88078_43860e-3) * r + - 2.65321_89526_57612_30930e-2) * r + - 2.96560_57182_85048_91230e-1) * r + - 1.78482_65399_17291_33580e+0) * r + - 5.46378_49111_64114_36990e+0) * r + - 6.65790_46435_01103_77720e+0) - den = (((((((2.04426_31033_89939_78564e-15 * r + - 1.42151_17583_16445_88870e-7) * r + - 1.84631_83175_10054_68180e-5) * r + - 7.86869_13114_56132_59100e-4) * r + - 1.48753_61290_85061_48525e-2) * r + - 1.36929_88092_27358_05310e-1) * r + - 5.99832_20655_58879_37690e-1) * r + - 1.0) - x = num / den - if q < 0.0: - x = -x - return mu + (x * sigma) - - -# If available, use C implementation -try: - from _statistics import _normal_dist_inv_cdf -except ImportError: - pass - - -class NormalDist: - "Normal distribution of a random variable" - # https://en.wikipedia.org/wiki/Normal_distribution - # https://en.wikipedia.org/wiki/Variance#Properties - - __slots__ = { - '_mu': 'Arithmetic mean of a normal distribution', - '_sigma': 'Standard deviation of a normal distribution', - } - - def __init__(self, mu=0.0, sigma=1.0): - "NormalDist where mu is the mean and sigma is the standard deviation." - if sigma < 0.0: - raise StatisticsError('sigma must be non-negative') - self._mu = float(mu) - self._sigma = float(sigma) - - @classmethod - def from_samples(cls, data): - "Make a normal distribution instance from sample data." - return cls(*_mean_stdev(data)) - - def samples(self, n, *, seed=None): - "Generate *n* samples for a given mean and standard deviation." - gauss = random.gauss if seed is None else random.Random(seed).gauss - mu, sigma = self._mu, self._sigma - return [gauss(mu, sigma) for i in range(n)] - - def pdf(self, x): - "Probability density function. P(x <= X < x+dx) / dx" - variance = self._sigma * self._sigma - if not variance: - raise StatisticsError('pdf() not defined when sigma is zero') - diff = x - self._mu - return exp(diff * diff / (-2.0 * variance)) / sqrt(tau * variance) - - def cdf(self, x): - "Cumulative distribution function. P(X <= x)" - if not self._sigma: - raise StatisticsError('cdf() not defined when sigma is zero') - return 0.5 * (1.0 + erf((x - self._mu) / (self._sigma * _SQRT2))) - - def inv_cdf(self, p): - """Inverse cumulative distribution function. x : P(X <= x) = p - - Finds the value of the random variable such that the probability of - the variable being less than or equal to that value equals the given - probability. - - This function is also called the percent point function or quantile - function. - """ - if p <= 0.0 or p >= 1.0: - raise StatisticsError('p must be in the range 0.0 < p < 1.0') - if self._sigma <= 0.0: - raise StatisticsError('cdf() not defined when sigma at or below zero') - return _normal_dist_inv_cdf(p, self._mu, self._sigma) - - def quantiles(self, n=4): - """Divide into *n* continuous intervals with equal probability. - - Returns a list of (n - 1) cut points separating the intervals. - - Set *n* to 4 for quartiles (the default). Set *n* to 10 for deciles. - Set *n* to 100 for percentiles which gives the 99 cuts points that - separate the normal distribution in to 100 equal sized groups. - """ - return [self.inv_cdf(i / n) for i in range(1, n)] - - def overlap(self, other): - """Compute the overlapping coefficient (OVL) between two normal distributions. - - Measures the agreement between two normal probability distributions. - Returns a value between 0.0 and 1.0 giving the overlapping area in - the two underlying probability density functions. - - >>> N1 = NormalDist(2.4, 1.6) - >>> N2 = NormalDist(3.2, 2.0) - >>> N1.overlap(N2) - 0.8035050657330205 - """ - # See: "The overlapping coefficient as a measure of agreement between - # probability distributions and point estimation of the overlap of two - # normal densities" -- Henry F. Inman and Edwin L. Bradley Jr - # http://dx.doi.org/10.1080/03610928908830127 - if not isinstance(other, NormalDist): - raise TypeError('Expected another NormalDist instance') - X, Y = self, other - if (Y._sigma, Y._mu) < (X._sigma, X._mu): # sort to assure commutativity - X, Y = Y, X - X_var, Y_var = X.variance, Y.variance - if not X_var or not Y_var: - raise StatisticsError('overlap() not defined when sigma is zero') - dv = Y_var - X_var - dm = fabs(Y._mu - X._mu) - if not dv: - return 1.0 - erf(dm / (2.0 * X._sigma * _SQRT2)) - a = X._mu * Y_var - Y._mu * X_var - b = X._sigma * Y._sigma * sqrt(dm * dm + dv * log(Y_var / X_var)) - x1 = (a + b) / dv - x2 = (a - b) / dv - return 1.0 - (fabs(Y.cdf(x1) - X.cdf(x1)) + fabs(Y.cdf(x2) - X.cdf(x2))) - - def zscore(self, x): - """Compute the Standard Score. (x - mean) / stdev - - Describes *x* in terms of the number of standard deviations - above or below the mean of the normal distribution. - """ - # https://www.statisticshowto.com/probability-and-statistics/z-score/ - if not self._sigma: - raise StatisticsError('zscore() not defined when sigma is zero') - return (x - self._mu) / self._sigma - - @property - def mean(self): - "Arithmetic mean of the normal distribution." - return self._mu - - @property - def median(self): - "Return the median of the normal distribution" - return self._mu - - @property - def mode(self): - """Return the mode of the normal distribution - - The mode is the value x where which the probability density - function (pdf) takes its maximum value. - """ - return self._mu - - @property - def stdev(self): - "Standard deviation of the normal distribution." - return self._sigma - - @property - def variance(self): - "Square of the standard deviation." - return self._sigma * self._sigma - - def __add__(x1, x2): - """Add a constant or another NormalDist instance. - - If *other* is a constant, translate mu by the constant, - leaving sigma unchanged. - - If *other* is a NormalDist, add both the means and the variances. - Mathematically, this works only if the two distributions are - independent or if they are jointly normally distributed. - """ - if isinstance(x2, NormalDist): - return NormalDist(x1._mu + x2._mu, hypot(x1._sigma, x2._sigma)) - return NormalDist(x1._mu + x2, x1._sigma) - - def __sub__(x1, x2): - """Subtract a constant or another NormalDist instance. - - If *other* is a constant, translate by the constant mu, - leaving sigma unchanged. - - If *other* is a NormalDist, subtract the means and add the variances. - Mathematically, this works only if the two distributions are - independent or if they are jointly normally distributed. - """ - if isinstance(x2, NormalDist): - return NormalDist(x1._mu - x2._mu, hypot(x1._sigma, x2._sigma)) - return NormalDist(x1._mu - x2, x1._sigma) - - def __mul__(x1, x2): - """Multiply both mu and sigma by a constant. - - Used for rescaling, perhaps to change measurement units. - Sigma is scaled with the absolute value of the constant. - """ - return NormalDist(x1._mu * x2, x1._sigma * fabs(x2)) - - def __truediv__(x1, x2): - """Divide both mu and sigma by a constant. - - Used for rescaling, perhaps to change measurement units. - Sigma is scaled with the absolute value of the constant. - """ - return NormalDist(x1._mu / x2, x1._sigma / fabs(x2)) - - def __pos__(x1): - "Return a copy of the instance." - return NormalDist(x1._mu, x1._sigma) - - def __neg__(x1): - "Negates mu while keeping sigma the same." - return NormalDist(-x1._mu, x1._sigma) - - __radd__ = __add__ - - def __rsub__(x1, x2): - "Subtract a NormalDist from a constant or another NormalDist." - return -(x1 - x2) - - __rmul__ = __mul__ - - def __eq__(x1, x2): - "Two NormalDist objects are equal if their mu and sigma are both equal." - if not isinstance(x2, NormalDist): - return NotImplemented - return x1._mu == x2._mu and x1._sigma == x2._sigma - - def __hash__(self): - "NormalDist objects hash equal if their mu and sigma are both equal." - return hash((self._mu, self._sigma)) - - def __repr__(self): - return f'{type(self).__name__}(mu={self._mu!r}, sigma={self._sigma!r})' - - def __getstate__(self): - return self._mu, self._sigma - - def __setstate__(self, state): - self._mu, self._sigma = state diff --git a/python/Lib/string.py b/python/Lib/string.py deleted file mode 100644 index 5424f22..0000000 --- a/python/Lib/string.py +++ /dev/null @@ -1,309 +0,0 @@ -"""A collection of string constants. - -Public module variables: - -whitespace -- a string containing all ASCII whitespace -ascii_lowercase -- a string containing all ASCII lowercase letters -ascii_uppercase -- a string containing all ASCII uppercase letters -ascii_letters -- a string containing all ASCII letters -digits -- a string containing all ASCII decimal digits -hexdigits -- a string containing all ASCII hexadecimal digits -octdigits -- a string containing all ASCII octal digits -punctuation -- a string containing all ASCII punctuation characters -printable -- a string containing all ASCII characters considered printable - -""" - -__all__ = ["ascii_letters", "ascii_lowercase", "ascii_uppercase", "capwords", - "digits", "hexdigits", "octdigits", "printable", "punctuation", - "whitespace", "Formatter", "Template"] - -import _string - -# Some strings for ctype-style character classification -whitespace = ' \t\n\r\v\f' -ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz' -ascii_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' -ascii_letters = ascii_lowercase + ascii_uppercase -digits = '0123456789' -hexdigits = digits + 'abcdef' + 'ABCDEF' -octdigits = '01234567' -punctuation = r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" -printable = digits + ascii_letters + punctuation + whitespace - -# Functions which aren't available as string methods. - -# Capitalize the words in a string, e.g. " aBc dEf " -> "Abc Def". -def capwords(s, sep=None): - """capwords(s [,sep]) -> string - - Split the argument into words using split, capitalize each - word using capitalize, and join the capitalized words using - join. If the optional second argument sep is absent or None, - runs of whitespace characters are replaced by a single space - and leading and trailing whitespace are removed, otherwise - sep is used to split and join the words. - - """ - return (sep or ' ').join(map(str.capitalize, s.split(sep))) - - -#################################################################### -import re as _re -from collections import ChainMap as _ChainMap - -_sentinel_dict = {} - -class Template: - """A string class for supporting $-substitutions.""" - - delimiter = '$' - # r'[a-z]' matches to non-ASCII letters when used with IGNORECASE, but - # without the ASCII flag. We can't add re.ASCII to flags because of - # backward compatibility. So we use the ?a local flag and [a-z] pattern. - # See https://bugs.python.org/issue31672 - idpattern = r'(?a:[_a-z][_a-z0-9]*)' - braceidpattern = None - flags = _re.IGNORECASE - - def __init_subclass__(cls): - super().__init_subclass__() - if 'pattern' in cls.__dict__: - pattern = cls.pattern - else: - delim = _re.escape(cls.delimiter) - id = cls.idpattern - bid = cls.braceidpattern or cls.idpattern - pattern = fr""" - {delim}(?: - (?P{delim}) | # Escape sequence of two delimiters - (?P{id}) | # delimiter and a Python identifier - {{(?P{bid})}} | # delimiter and a braced identifier - (?P) # Other ill-formed delimiter exprs - ) - """ - cls.pattern = _re.compile(pattern, cls.flags | _re.VERBOSE) - - def __init__(self, template): - self.template = template - - # Search for $$, $identifier, ${identifier}, and any bare $'s - - def _invalid(self, mo): - i = mo.start('invalid') - lines = self.template[:i].splitlines(keepends=True) - if not lines: - colno = 1 - lineno = 1 - else: - colno = i - len(''.join(lines[:-1])) - lineno = len(lines) - raise ValueError('Invalid placeholder in string: line %d, col %d' % - (lineno, colno)) - - def substitute(self, mapping=_sentinel_dict, /, **kws): - if mapping is _sentinel_dict: - mapping = kws - elif kws: - mapping = _ChainMap(kws, mapping) - # Helper function for .sub() - def convert(mo): - # Check the most common path first. - named = mo.group('named') or mo.group('braced') - if named is not None: - return str(mapping[named]) - if mo.group('escaped') is not None: - return self.delimiter - if mo.group('invalid') is not None: - self._invalid(mo) - raise ValueError('Unrecognized named group in pattern', - self.pattern) - return self.pattern.sub(convert, self.template) - - def safe_substitute(self, mapping=_sentinel_dict, /, **kws): - if mapping is _sentinel_dict: - mapping = kws - elif kws: - mapping = _ChainMap(kws, mapping) - # Helper function for .sub() - def convert(mo): - named = mo.group('named') or mo.group('braced') - if named is not None: - try: - return str(mapping[named]) - except KeyError: - return mo.group() - if mo.group('escaped') is not None: - return self.delimiter - if mo.group('invalid') is not None: - return mo.group() - raise ValueError('Unrecognized named group in pattern', - self.pattern) - return self.pattern.sub(convert, self.template) - - def is_valid(self): - for mo in self.pattern.finditer(self.template): - if mo.group('invalid') is not None: - return False - if (mo.group('named') is None - and mo.group('braced') is None - and mo.group('escaped') is None): - # If all the groups are None, there must be - # another group we're not expecting - raise ValueError('Unrecognized named group in pattern', - self.pattern) - return True - - def get_identifiers(self): - ids = [] - for mo in self.pattern.finditer(self.template): - named = mo.group('named') or mo.group('braced') - if named is not None and named not in ids: - # add a named group only the first time it appears - ids.append(named) - elif (named is None - and mo.group('invalid') is None - and mo.group('escaped') is None): - # If all the groups are None, there must be - # another group we're not expecting - raise ValueError('Unrecognized named group in pattern', - self.pattern) - return ids - -# Initialize Template.pattern. __init_subclass__() is automatically called -# only for subclasses, not for the Template class itself. -Template.__init_subclass__() - - -######################################################################## -# the Formatter class -# see PEP 3101 for details and purpose of this class - -# The hard parts are reused from the C implementation. They're exposed as "_" -# prefixed methods of str. - -# The overall parser is implemented in _string.formatter_parser. -# The field name parser is implemented in _string.formatter_field_name_split - -class Formatter: - def format(self, format_string, /, *args, **kwargs): - return self.vformat(format_string, args, kwargs) - - def vformat(self, format_string, args, kwargs): - used_args = set() - result, _ = self._vformat(format_string, args, kwargs, used_args, 2) - self.check_unused_args(used_args, args, kwargs) - return result - - def _vformat(self, format_string, args, kwargs, used_args, recursion_depth, - auto_arg_index=0): - if recursion_depth < 0: - raise ValueError('Max string recursion exceeded') - result = [] - for literal_text, field_name, format_spec, conversion in \ - self.parse(format_string): - - # output the literal text - if literal_text: - result.append(literal_text) - - # if there's a field, output it - if field_name is not None: - # this is some markup, find the object and do - # the formatting - - # handle arg indexing when empty field_names are given. - if field_name == '': - if auto_arg_index is False: - raise ValueError('cannot switch from manual field ' - 'specification to automatic field ' - 'numbering') - field_name = str(auto_arg_index) - auto_arg_index += 1 - elif field_name.isdigit(): - if auto_arg_index: - raise ValueError('cannot switch from manual field ' - 'specification to automatic field ' - 'numbering') - # disable auto arg incrementing, if it gets - # used later on, then an exception will be raised - auto_arg_index = False - - # given the field_name, find the object it references - # and the argument it came from - obj, arg_used = self.get_field(field_name, args, kwargs) - used_args.add(arg_used) - - # do any conversion on the resulting object - obj = self.convert_field(obj, conversion) - - # expand the format spec, if needed - format_spec, auto_arg_index = self._vformat( - format_spec, args, kwargs, - used_args, recursion_depth-1, - auto_arg_index=auto_arg_index) - - # format the object and append to the result - result.append(self.format_field(obj, format_spec)) - - return ''.join(result), auto_arg_index - - - def get_value(self, key, args, kwargs): - if isinstance(key, int): - return args[key] - else: - return kwargs[key] - - - def check_unused_args(self, used_args, args, kwargs): - pass - - - def format_field(self, value, format_spec): - return format(value, format_spec) - - - def convert_field(self, value, conversion): - # do any conversion on the resulting object - if conversion is None: - return value - elif conversion == 's': - return str(value) - elif conversion == 'r': - return repr(value) - elif conversion == 'a': - return ascii(value) - raise ValueError("Unknown conversion specifier {0!s}".format(conversion)) - - - # returns an iterable that contains tuples of the form: - # (literal_text, field_name, format_spec, conversion) - # literal_text can be zero length - # field_name can be None, in which case there's no - # object to format and output - # if field_name is not None, it is looked up, formatted - # with format_spec and conversion and then used - def parse(self, format_string): - return _string.formatter_parser(format_string) - - - # given a field_name, find the object it references. - # field_name: the field being looked up, e.g. "0.name" - # or "lookup[3]" - # used_args: a set of which args have been used - # args, kwargs: as passed in to vformat - def get_field(self, field_name, args, kwargs): - first, rest = _string.formatter_field_name_split(field_name) - - obj = self.get_value(first, args, kwargs) - - # loop through the rest of the field_name, doing - # getattr or getitem as needed - for is_attr, i in rest: - if is_attr: - obj = getattr(obj, i) - else: - obj = obj[i] - - return obj, first diff --git a/python/Lib/stringprep.py b/python/Lib/stringprep.py deleted file mode 100644 index dd6cb8d..0000000 --- a/python/Lib/stringprep.py +++ /dev/null @@ -1,272 +0,0 @@ -# This file is generated by mkstringprep.py. DO NOT EDIT. -"""Library that exposes various tables found in the StringPrep RFC 3454. - -There are two kinds of tables: sets, for which a member test is provided, -and mappings, for which a mapping function is provided. -""" - -from unicodedata import ucd_3_2_0 as unicodedata - -assert unicodedata.unidata_version == '3.2.0' - -def in_table_a1(code): - if unicodedata.category(code) != 'Cn': return False - c = ord(code) - if 0xFDD0 <= c < 0xFDF0: return False - return (c & 0xFFFF) not in (0xFFFE, 0xFFFF) - - -b1_set = set([173, 847, 6150, 6155, 6156, 6157, 8203, 8204, 8205, 8288, 65279] + list(range(65024,65040))) -def in_table_b1(code): - return ord(code) in b1_set - - -b3_exceptions = { -0xb5:'\u03bc', 0xdf:'ss', 0x130:'i\u0307', 0x149:'\u02bcn', -0x17f:'s', 0x1f0:'j\u030c', 0x345:'\u03b9', 0x37a:' \u03b9', -0x390:'\u03b9\u0308\u0301', 0x3b0:'\u03c5\u0308\u0301', 0x3c2:'\u03c3', 0x3d0:'\u03b2', -0x3d1:'\u03b8', 0x3d2:'\u03c5', 0x3d3:'\u03cd', 0x3d4:'\u03cb', -0x3d5:'\u03c6', 0x3d6:'\u03c0', 0x3f0:'\u03ba', 0x3f1:'\u03c1', -0x3f2:'\u03c3', 0x3f5:'\u03b5', 0x587:'\u0565\u0582', 0x1e96:'h\u0331', -0x1e97:'t\u0308', 0x1e98:'w\u030a', 0x1e99:'y\u030a', 0x1e9a:'a\u02be', -0x1e9b:'\u1e61', 0x1f50:'\u03c5\u0313', 0x1f52:'\u03c5\u0313\u0300', 0x1f54:'\u03c5\u0313\u0301', -0x1f56:'\u03c5\u0313\u0342', 0x1f80:'\u1f00\u03b9', 0x1f81:'\u1f01\u03b9', 0x1f82:'\u1f02\u03b9', -0x1f83:'\u1f03\u03b9', 0x1f84:'\u1f04\u03b9', 0x1f85:'\u1f05\u03b9', 0x1f86:'\u1f06\u03b9', -0x1f87:'\u1f07\u03b9', 0x1f88:'\u1f00\u03b9', 0x1f89:'\u1f01\u03b9', 0x1f8a:'\u1f02\u03b9', -0x1f8b:'\u1f03\u03b9', 0x1f8c:'\u1f04\u03b9', 0x1f8d:'\u1f05\u03b9', 0x1f8e:'\u1f06\u03b9', -0x1f8f:'\u1f07\u03b9', 0x1f90:'\u1f20\u03b9', 0x1f91:'\u1f21\u03b9', 0x1f92:'\u1f22\u03b9', -0x1f93:'\u1f23\u03b9', 0x1f94:'\u1f24\u03b9', 0x1f95:'\u1f25\u03b9', 0x1f96:'\u1f26\u03b9', -0x1f97:'\u1f27\u03b9', 0x1f98:'\u1f20\u03b9', 0x1f99:'\u1f21\u03b9', 0x1f9a:'\u1f22\u03b9', -0x1f9b:'\u1f23\u03b9', 0x1f9c:'\u1f24\u03b9', 0x1f9d:'\u1f25\u03b9', 0x1f9e:'\u1f26\u03b9', -0x1f9f:'\u1f27\u03b9', 0x1fa0:'\u1f60\u03b9', 0x1fa1:'\u1f61\u03b9', 0x1fa2:'\u1f62\u03b9', -0x1fa3:'\u1f63\u03b9', 0x1fa4:'\u1f64\u03b9', 0x1fa5:'\u1f65\u03b9', 0x1fa6:'\u1f66\u03b9', -0x1fa7:'\u1f67\u03b9', 0x1fa8:'\u1f60\u03b9', 0x1fa9:'\u1f61\u03b9', 0x1faa:'\u1f62\u03b9', -0x1fab:'\u1f63\u03b9', 0x1fac:'\u1f64\u03b9', 0x1fad:'\u1f65\u03b9', 0x1fae:'\u1f66\u03b9', -0x1faf:'\u1f67\u03b9', 0x1fb2:'\u1f70\u03b9', 0x1fb3:'\u03b1\u03b9', 0x1fb4:'\u03ac\u03b9', -0x1fb6:'\u03b1\u0342', 0x1fb7:'\u03b1\u0342\u03b9', 0x1fbc:'\u03b1\u03b9', 0x1fbe:'\u03b9', -0x1fc2:'\u1f74\u03b9', 0x1fc3:'\u03b7\u03b9', 0x1fc4:'\u03ae\u03b9', 0x1fc6:'\u03b7\u0342', -0x1fc7:'\u03b7\u0342\u03b9', 0x1fcc:'\u03b7\u03b9', 0x1fd2:'\u03b9\u0308\u0300', 0x1fd3:'\u03b9\u0308\u0301', -0x1fd6:'\u03b9\u0342', 0x1fd7:'\u03b9\u0308\u0342', 0x1fe2:'\u03c5\u0308\u0300', 0x1fe3:'\u03c5\u0308\u0301', -0x1fe4:'\u03c1\u0313', 0x1fe6:'\u03c5\u0342', 0x1fe7:'\u03c5\u0308\u0342', 0x1ff2:'\u1f7c\u03b9', -0x1ff3:'\u03c9\u03b9', 0x1ff4:'\u03ce\u03b9', 0x1ff6:'\u03c9\u0342', 0x1ff7:'\u03c9\u0342\u03b9', -0x1ffc:'\u03c9\u03b9', 0x20a8:'rs', 0x2102:'c', 0x2103:'\xb0c', -0x2107:'\u025b', 0x2109:'\xb0f', 0x210b:'h', 0x210c:'h', -0x210d:'h', 0x2110:'i', 0x2111:'i', 0x2112:'l', -0x2115:'n', 0x2116:'no', 0x2119:'p', 0x211a:'q', -0x211b:'r', 0x211c:'r', 0x211d:'r', 0x2120:'sm', -0x2121:'tel', 0x2122:'tm', 0x2124:'z', 0x2128:'z', -0x212c:'b', 0x212d:'c', 0x2130:'e', 0x2131:'f', -0x2133:'m', 0x213e:'\u03b3', 0x213f:'\u03c0', 0x2145:'d', -0x3371:'hpa', 0x3373:'au', 0x3375:'ov', 0x3380:'pa', -0x3381:'na', 0x3382:'\u03bca', 0x3383:'ma', 0x3384:'ka', -0x3385:'kb', 0x3386:'mb', 0x3387:'gb', 0x338a:'pf', -0x338b:'nf', 0x338c:'\u03bcf', 0x3390:'hz', 0x3391:'khz', -0x3392:'mhz', 0x3393:'ghz', 0x3394:'thz', 0x33a9:'pa', -0x33aa:'kpa', 0x33ab:'mpa', 0x33ac:'gpa', 0x33b4:'pv', -0x33b5:'nv', 0x33b6:'\u03bcv', 0x33b7:'mv', 0x33b8:'kv', -0x33b9:'mv', 0x33ba:'pw', 0x33bb:'nw', 0x33bc:'\u03bcw', -0x33bd:'mw', 0x33be:'kw', 0x33bf:'mw', 0x33c0:'k\u03c9', -0x33c1:'m\u03c9', 0x33c3:'bq', 0x33c6:'c\u2215kg', 0x33c7:'co.', -0x33c8:'db', 0x33c9:'gy', 0x33cb:'hp', 0x33cd:'kk', -0x33ce:'km', 0x33d7:'ph', 0x33d9:'ppm', 0x33da:'pr', -0x33dc:'sv', 0x33dd:'wb', 0xfb00:'ff', 0xfb01:'fi', -0xfb02:'fl', 0xfb03:'ffi', 0xfb04:'ffl', 0xfb05:'st', -0xfb06:'st', 0xfb13:'\u0574\u0576', 0xfb14:'\u0574\u0565', 0xfb15:'\u0574\u056b', -0xfb16:'\u057e\u0576', 0xfb17:'\u0574\u056d', 0x1d400:'a', 0x1d401:'b', -0x1d402:'c', 0x1d403:'d', 0x1d404:'e', 0x1d405:'f', -0x1d406:'g', 0x1d407:'h', 0x1d408:'i', 0x1d409:'j', -0x1d40a:'k', 0x1d40b:'l', 0x1d40c:'m', 0x1d40d:'n', -0x1d40e:'o', 0x1d40f:'p', 0x1d410:'q', 0x1d411:'r', -0x1d412:'s', 0x1d413:'t', 0x1d414:'u', 0x1d415:'v', -0x1d416:'w', 0x1d417:'x', 0x1d418:'y', 0x1d419:'z', -0x1d434:'a', 0x1d435:'b', 0x1d436:'c', 0x1d437:'d', -0x1d438:'e', 0x1d439:'f', 0x1d43a:'g', 0x1d43b:'h', -0x1d43c:'i', 0x1d43d:'j', 0x1d43e:'k', 0x1d43f:'l', -0x1d440:'m', 0x1d441:'n', 0x1d442:'o', 0x1d443:'p', -0x1d444:'q', 0x1d445:'r', 0x1d446:'s', 0x1d447:'t', -0x1d448:'u', 0x1d449:'v', 0x1d44a:'w', 0x1d44b:'x', -0x1d44c:'y', 0x1d44d:'z', 0x1d468:'a', 0x1d469:'b', -0x1d46a:'c', 0x1d46b:'d', 0x1d46c:'e', 0x1d46d:'f', -0x1d46e:'g', 0x1d46f:'h', 0x1d470:'i', 0x1d471:'j', -0x1d472:'k', 0x1d473:'l', 0x1d474:'m', 0x1d475:'n', -0x1d476:'o', 0x1d477:'p', 0x1d478:'q', 0x1d479:'r', -0x1d47a:'s', 0x1d47b:'t', 0x1d47c:'u', 0x1d47d:'v', -0x1d47e:'w', 0x1d47f:'x', 0x1d480:'y', 0x1d481:'z', -0x1d49c:'a', 0x1d49e:'c', 0x1d49f:'d', 0x1d4a2:'g', -0x1d4a5:'j', 0x1d4a6:'k', 0x1d4a9:'n', 0x1d4aa:'o', -0x1d4ab:'p', 0x1d4ac:'q', 0x1d4ae:'s', 0x1d4af:'t', -0x1d4b0:'u', 0x1d4b1:'v', 0x1d4b2:'w', 0x1d4b3:'x', -0x1d4b4:'y', 0x1d4b5:'z', 0x1d4d0:'a', 0x1d4d1:'b', -0x1d4d2:'c', 0x1d4d3:'d', 0x1d4d4:'e', 0x1d4d5:'f', -0x1d4d6:'g', 0x1d4d7:'h', 0x1d4d8:'i', 0x1d4d9:'j', -0x1d4da:'k', 0x1d4db:'l', 0x1d4dc:'m', 0x1d4dd:'n', -0x1d4de:'o', 0x1d4df:'p', 0x1d4e0:'q', 0x1d4e1:'r', -0x1d4e2:'s', 0x1d4e3:'t', 0x1d4e4:'u', 0x1d4e5:'v', -0x1d4e6:'w', 0x1d4e7:'x', 0x1d4e8:'y', 0x1d4e9:'z', -0x1d504:'a', 0x1d505:'b', 0x1d507:'d', 0x1d508:'e', -0x1d509:'f', 0x1d50a:'g', 0x1d50d:'j', 0x1d50e:'k', -0x1d50f:'l', 0x1d510:'m', 0x1d511:'n', 0x1d512:'o', -0x1d513:'p', 0x1d514:'q', 0x1d516:'s', 0x1d517:'t', -0x1d518:'u', 0x1d519:'v', 0x1d51a:'w', 0x1d51b:'x', -0x1d51c:'y', 0x1d538:'a', 0x1d539:'b', 0x1d53b:'d', -0x1d53c:'e', 0x1d53d:'f', 0x1d53e:'g', 0x1d540:'i', -0x1d541:'j', 0x1d542:'k', 0x1d543:'l', 0x1d544:'m', -0x1d546:'o', 0x1d54a:'s', 0x1d54b:'t', 0x1d54c:'u', -0x1d54d:'v', 0x1d54e:'w', 0x1d54f:'x', 0x1d550:'y', -0x1d56c:'a', 0x1d56d:'b', 0x1d56e:'c', 0x1d56f:'d', -0x1d570:'e', 0x1d571:'f', 0x1d572:'g', 0x1d573:'h', -0x1d574:'i', 0x1d575:'j', 0x1d576:'k', 0x1d577:'l', -0x1d578:'m', 0x1d579:'n', 0x1d57a:'o', 0x1d57b:'p', -0x1d57c:'q', 0x1d57d:'r', 0x1d57e:'s', 0x1d57f:'t', -0x1d580:'u', 0x1d581:'v', 0x1d582:'w', 0x1d583:'x', -0x1d584:'y', 0x1d585:'z', 0x1d5a0:'a', 0x1d5a1:'b', -0x1d5a2:'c', 0x1d5a3:'d', 0x1d5a4:'e', 0x1d5a5:'f', -0x1d5a6:'g', 0x1d5a7:'h', 0x1d5a8:'i', 0x1d5a9:'j', -0x1d5aa:'k', 0x1d5ab:'l', 0x1d5ac:'m', 0x1d5ad:'n', -0x1d5ae:'o', 0x1d5af:'p', 0x1d5b0:'q', 0x1d5b1:'r', -0x1d5b2:'s', 0x1d5b3:'t', 0x1d5b4:'u', 0x1d5b5:'v', -0x1d5b6:'w', 0x1d5b7:'x', 0x1d5b8:'y', 0x1d5b9:'z', -0x1d5d4:'a', 0x1d5d5:'b', 0x1d5d6:'c', 0x1d5d7:'d', -0x1d5d8:'e', 0x1d5d9:'f', 0x1d5da:'g', 0x1d5db:'h', -0x1d5dc:'i', 0x1d5dd:'j', 0x1d5de:'k', 0x1d5df:'l', -0x1d5e0:'m', 0x1d5e1:'n', 0x1d5e2:'o', 0x1d5e3:'p', -0x1d5e4:'q', 0x1d5e5:'r', 0x1d5e6:'s', 0x1d5e7:'t', -0x1d5e8:'u', 0x1d5e9:'v', 0x1d5ea:'w', 0x1d5eb:'x', -0x1d5ec:'y', 0x1d5ed:'z', 0x1d608:'a', 0x1d609:'b', -0x1d60a:'c', 0x1d60b:'d', 0x1d60c:'e', 0x1d60d:'f', -0x1d60e:'g', 0x1d60f:'h', 0x1d610:'i', 0x1d611:'j', -0x1d612:'k', 0x1d613:'l', 0x1d614:'m', 0x1d615:'n', -0x1d616:'o', 0x1d617:'p', 0x1d618:'q', 0x1d619:'r', -0x1d61a:'s', 0x1d61b:'t', 0x1d61c:'u', 0x1d61d:'v', -0x1d61e:'w', 0x1d61f:'x', 0x1d620:'y', 0x1d621:'z', -0x1d63c:'a', 0x1d63d:'b', 0x1d63e:'c', 0x1d63f:'d', -0x1d640:'e', 0x1d641:'f', 0x1d642:'g', 0x1d643:'h', -0x1d644:'i', 0x1d645:'j', 0x1d646:'k', 0x1d647:'l', -0x1d648:'m', 0x1d649:'n', 0x1d64a:'o', 0x1d64b:'p', -0x1d64c:'q', 0x1d64d:'r', 0x1d64e:'s', 0x1d64f:'t', -0x1d650:'u', 0x1d651:'v', 0x1d652:'w', 0x1d653:'x', -0x1d654:'y', 0x1d655:'z', 0x1d670:'a', 0x1d671:'b', -0x1d672:'c', 0x1d673:'d', 0x1d674:'e', 0x1d675:'f', -0x1d676:'g', 0x1d677:'h', 0x1d678:'i', 0x1d679:'j', -0x1d67a:'k', 0x1d67b:'l', 0x1d67c:'m', 0x1d67d:'n', -0x1d67e:'o', 0x1d67f:'p', 0x1d680:'q', 0x1d681:'r', -0x1d682:'s', 0x1d683:'t', 0x1d684:'u', 0x1d685:'v', -0x1d686:'w', 0x1d687:'x', 0x1d688:'y', 0x1d689:'z', -0x1d6a8:'\u03b1', 0x1d6a9:'\u03b2', 0x1d6aa:'\u03b3', 0x1d6ab:'\u03b4', -0x1d6ac:'\u03b5', 0x1d6ad:'\u03b6', 0x1d6ae:'\u03b7', 0x1d6af:'\u03b8', -0x1d6b0:'\u03b9', 0x1d6b1:'\u03ba', 0x1d6b2:'\u03bb', 0x1d6b3:'\u03bc', -0x1d6b4:'\u03bd', 0x1d6b5:'\u03be', 0x1d6b6:'\u03bf', 0x1d6b7:'\u03c0', -0x1d6b8:'\u03c1', 0x1d6b9:'\u03b8', 0x1d6ba:'\u03c3', 0x1d6bb:'\u03c4', -0x1d6bc:'\u03c5', 0x1d6bd:'\u03c6', 0x1d6be:'\u03c7', 0x1d6bf:'\u03c8', -0x1d6c0:'\u03c9', 0x1d6d3:'\u03c3', 0x1d6e2:'\u03b1', 0x1d6e3:'\u03b2', -0x1d6e4:'\u03b3', 0x1d6e5:'\u03b4', 0x1d6e6:'\u03b5', 0x1d6e7:'\u03b6', -0x1d6e8:'\u03b7', 0x1d6e9:'\u03b8', 0x1d6ea:'\u03b9', 0x1d6eb:'\u03ba', -0x1d6ec:'\u03bb', 0x1d6ed:'\u03bc', 0x1d6ee:'\u03bd', 0x1d6ef:'\u03be', -0x1d6f0:'\u03bf', 0x1d6f1:'\u03c0', 0x1d6f2:'\u03c1', 0x1d6f3:'\u03b8', -0x1d6f4:'\u03c3', 0x1d6f5:'\u03c4', 0x1d6f6:'\u03c5', 0x1d6f7:'\u03c6', -0x1d6f8:'\u03c7', 0x1d6f9:'\u03c8', 0x1d6fa:'\u03c9', 0x1d70d:'\u03c3', -0x1d71c:'\u03b1', 0x1d71d:'\u03b2', 0x1d71e:'\u03b3', 0x1d71f:'\u03b4', -0x1d720:'\u03b5', 0x1d721:'\u03b6', 0x1d722:'\u03b7', 0x1d723:'\u03b8', -0x1d724:'\u03b9', 0x1d725:'\u03ba', 0x1d726:'\u03bb', 0x1d727:'\u03bc', -0x1d728:'\u03bd', 0x1d729:'\u03be', 0x1d72a:'\u03bf', 0x1d72b:'\u03c0', -0x1d72c:'\u03c1', 0x1d72d:'\u03b8', 0x1d72e:'\u03c3', 0x1d72f:'\u03c4', -0x1d730:'\u03c5', 0x1d731:'\u03c6', 0x1d732:'\u03c7', 0x1d733:'\u03c8', -0x1d734:'\u03c9', 0x1d747:'\u03c3', 0x1d756:'\u03b1', 0x1d757:'\u03b2', -0x1d758:'\u03b3', 0x1d759:'\u03b4', 0x1d75a:'\u03b5', 0x1d75b:'\u03b6', -0x1d75c:'\u03b7', 0x1d75d:'\u03b8', 0x1d75e:'\u03b9', 0x1d75f:'\u03ba', -0x1d760:'\u03bb', 0x1d761:'\u03bc', 0x1d762:'\u03bd', 0x1d763:'\u03be', -0x1d764:'\u03bf', 0x1d765:'\u03c0', 0x1d766:'\u03c1', 0x1d767:'\u03b8', -0x1d768:'\u03c3', 0x1d769:'\u03c4', 0x1d76a:'\u03c5', 0x1d76b:'\u03c6', -0x1d76c:'\u03c7', 0x1d76d:'\u03c8', 0x1d76e:'\u03c9', 0x1d781:'\u03c3', -0x1d790:'\u03b1', 0x1d791:'\u03b2', 0x1d792:'\u03b3', 0x1d793:'\u03b4', -0x1d794:'\u03b5', 0x1d795:'\u03b6', 0x1d796:'\u03b7', 0x1d797:'\u03b8', -0x1d798:'\u03b9', 0x1d799:'\u03ba', 0x1d79a:'\u03bb', 0x1d79b:'\u03bc', -0x1d79c:'\u03bd', 0x1d79d:'\u03be', 0x1d79e:'\u03bf', 0x1d79f:'\u03c0', -0x1d7a0:'\u03c1', 0x1d7a1:'\u03b8', 0x1d7a2:'\u03c3', 0x1d7a3:'\u03c4', -0x1d7a4:'\u03c5', 0x1d7a5:'\u03c6', 0x1d7a6:'\u03c7', 0x1d7a7:'\u03c8', -0x1d7a8:'\u03c9', 0x1d7bb:'\u03c3', } - -def map_table_b3(code): - r = b3_exceptions.get(ord(code)) - if r is not None: return r - return code.lower() - - -def map_table_b2(a): - al = map_table_b3(a) - b = unicodedata.normalize("NFKC", al) - bl = "".join([map_table_b3(ch) for ch in b]) - c = unicodedata.normalize("NFKC", bl) - if b != c: - return c - else: - return al - - -def in_table_c11(code): - return code == " " - - -def in_table_c12(code): - return unicodedata.category(code) == "Zs" and code != " " - -def in_table_c11_c12(code): - return unicodedata.category(code) == "Zs" - - -def in_table_c21(code): - return ord(code) < 128 and unicodedata.category(code) == "Cc" - -c22_specials = set([1757, 1807, 6158, 8204, 8205, 8232, 8233, 65279] + list(range(8288,8292)) + list(range(8298,8304)) + list(range(65529,65533)) + list(range(119155,119163))) -def in_table_c22(code): - c = ord(code) - if c < 128: return False - if unicodedata.category(code) == "Cc": return True - return c in c22_specials - -def in_table_c21_c22(code): - return unicodedata.category(code) == "Cc" or \ - ord(code) in c22_specials - - -def in_table_c3(code): - return unicodedata.category(code) == "Co" - - -def in_table_c4(code): - c = ord(code) - if c < 0xFDD0: return False - if c < 0xFDF0: return True - return (ord(code) & 0xFFFF) in (0xFFFE, 0xFFFF) - - -def in_table_c5(code): - return unicodedata.category(code) == "Cs" - - -c6_set = set(range(65529,65534)) -def in_table_c6(code): - return ord(code) in c6_set - - -c7_set = set(range(12272,12284)) -def in_table_c7(code): - return ord(code) in c7_set - - -c8_set = set([832, 833, 8206, 8207] + list(range(8234,8239)) + list(range(8298,8304))) -def in_table_c8(code): - return ord(code) in c8_set - - -c9_set = set([917505] + list(range(917536,917632))) -def in_table_c9(code): - return ord(code) in c9_set - - -def in_table_d1(code): - return unicodedata.bidirectional(code) in ("R","AL") - - -def in_table_d2(code): - return unicodedata.bidirectional(code) == "L" diff --git a/python/Lib/struct.py b/python/Lib/struct.py deleted file mode 100644 index 06d7d18..0000000 --- a/python/Lib/struct.py +++ /dev/null @@ -1,15 +0,0 @@ -__all__ = [ - # Functions - 'calcsize', 'pack', 'pack_into', 'unpack', 'unpack_from', - 'iter_unpack', - - # Classes - 'Struct', - - # Exceptions - 'error' - ] - -from _struct import * -from _struct import _clearcache -from _struct import __doc__ diff --git a/python/Lib/subprocess.py b/python/Lib/subprocess.py deleted file mode 100644 index 8b72467..0000000 --- a/python/Lib/subprocess.py +++ /dev/null @@ -1,2160 +0,0 @@ -# subprocess - Subprocesses with accessible I/O streams -# -# For more information about this module, see PEP 324. -# -# Copyright (c) 2003-2005 by Peter Astrand -# -# Licensed to PSF under a Contributor Agreement. - -r"""Subprocesses with accessible I/O streams - -This module allows you to spawn processes, connect to their -input/output/error pipes, and obtain their return codes. - -For a complete description of this module see the Python documentation. - -Main API -======== -run(...): Runs a command, waits for it to complete, then returns a - CompletedProcess instance. -Popen(...): A class for flexibly executing a command in a new process - -Constants ---------- -DEVNULL: Special value that indicates that os.devnull should be used -PIPE: Special value that indicates a pipe should be created -STDOUT: Special value that indicates that stderr should go to stdout - - -Older API -========= -call(...): Runs a command, waits for it to complete, then returns - the return code. -check_call(...): Same as call() but raises CalledProcessError() - if return code is not 0 -check_output(...): Same as check_call() but returns the contents of - stdout instead of a return code -getoutput(...): Runs a command in the shell, waits for it to complete, - then returns the output -getstatusoutput(...): Runs a command in the shell, waits for it to complete, - then returns a (exitcode, output) tuple -""" - -import builtins -import errno -import io -import locale -import os -import time -import signal -import sys -import threading -import warnings -import contextlib -from time import monotonic as _time -import types - -try: - import fcntl -except ImportError: - fcntl = None - - -__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput", - "getoutput", "check_output", "run", "CalledProcessError", "DEVNULL", - "SubprocessError", "TimeoutExpired", "CompletedProcess"] - # NOTE: We intentionally exclude list2cmdline as it is - # considered an internal implementation detail. issue10838. - -# use presence of msvcrt to detect Windows-like platforms (see bpo-8110) -try: - import msvcrt -except ModuleNotFoundError: - _mswindows = False -else: - _mswindows = True - -# wasm32-emscripten and wasm32-wasi do not support processes -_can_fork_exec = sys.platform not in {"emscripten", "wasi"} - -if _mswindows: - import _winapi - from _winapi import (CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP, - STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, - STD_ERROR_HANDLE, SW_HIDE, - STARTF_USESTDHANDLES, STARTF_USESHOWWINDOW, - ABOVE_NORMAL_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS, - HIGH_PRIORITY_CLASS, IDLE_PRIORITY_CLASS, - NORMAL_PRIORITY_CLASS, REALTIME_PRIORITY_CLASS, - CREATE_NO_WINDOW, DETACHED_PROCESS, - CREATE_DEFAULT_ERROR_MODE, CREATE_BREAKAWAY_FROM_JOB) - - __all__.extend(["CREATE_NEW_CONSOLE", "CREATE_NEW_PROCESS_GROUP", - "STD_INPUT_HANDLE", "STD_OUTPUT_HANDLE", - "STD_ERROR_HANDLE", "SW_HIDE", - "STARTF_USESTDHANDLES", "STARTF_USESHOWWINDOW", - "STARTUPINFO", - "ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS", - "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS", - "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS", - "CREATE_NO_WINDOW", "DETACHED_PROCESS", - "CREATE_DEFAULT_ERROR_MODE", "CREATE_BREAKAWAY_FROM_JOB"]) -else: - if _can_fork_exec: - from _posixsubprocess import fork_exec as _fork_exec - # used in methods that are called by __del__ - _waitpid = os.waitpid - _waitstatus_to_exitcode = os.waitstatus_to_exitcode - _WIFSTOPPED = os.WIFSTOPPED - _WSTOPSIG = os.WSTOPSIG - _WNOHANG = os.WNOHANG - else: - _fork_exec = None - _waitpid = None - _waitstatus_to_exitcode = None - _WIFSTOPPED = None - _WSTOPSIG = None - _WNOHANG = None - import select - import selectors - - -# Exception classes used by this module. -class SubprocessError(Exception): pass - - -class CalledProcessError(SubprocessError): - """Raised when run() is called with check=True and the process - returns a non-zero exit status. - - Attributes: - cmd, returncode, stdout, stderr, output - """ - def __init__(self, returncode, cmd, output=None, stderr=None): - self.returncode = returncode - self.cmd = cmd - self.output = output - self.stderr = stderr - - def __str__(self): - if self.returncode and self.returncode < 0: - try: - return "Command '%s' died with %r." % ( - self.cmd, signal.Signals(-self.returncode)) - except ValueError: - return "Command '%s' died with unknown signal %d." % ( - self.cmd, -self.returncode) - else: - return "Command '%s' returned non-zero exit status %d." % ( - self.cmd, self.returncode) - - @property - def stdout(self): - """Alias for output attribute, to match stderr""" - return self.output - - @stdout.setter - def stdout(self, value): - # There's no obvious reason to set this, but allow it anyway so - # .stdout is a transparent alias for .output - self.output = value - - -class TimeoutExpired(SubprocessError): - """This exception is raised when the timeout expires while waiting for a - child process. - - Attributes: - cmd, output, stdout, stderr, timeout - """ - def __init__(self, cmd, timeout, output=None, stderr=None): - self.cmd = cmd - self.timeout = timeout - self.output = output - self.stderr = stderr - - def __str__(self): - return ("Command '%s' timed out after %s seconds" % - (self.cmd, self.timeout)) - - @property - def stdout(self): - return self.output - - @stdout.setter - def stdout(self, value): - # There's no obvious reason to set this, but allow it anyway so - # .stdout is a transparent alias for .output - self.output = value - - -if _mswindows: - class STARTUPINFO: - def __init__(self, *, dwFlags=0, hStdInput=None, hStdOutput=None, - hStdError=None, wShowWindow=0, lpAttributeList=None): - self.dwFlags = dwFlags - self.hStdInput = hStdInput - self.hStdOutput = hStdOutput - self.hStdError = hStdError - self.wShowWindow = wShowWindow - self.lpAttributeList = lpAttributeList or {"handle_list": []} - - def copy(self): - attr_list = self.lpAttributeList.copy() - if 'handle_list' in attr_list: - attr_list['handle_list'] = list(attr_list['handle_list']) - - return STARTUPINFO(dwFlags=self.dwFlags, - hStdInput=self.hStdInput, - hStdOutput=self.hStdOutput, - hStdError=self.hStdError, - wShowWindow=self.wShowWindow, - lpAttributeList=attr_list) - - - class Handle(int): - closed = False - - def Close(self, CloseHandle=_winapi.CloseHandle): - if not self.closed: - self.closed = True - CloseHandle(self) - - def Detach(self): - if not self.closed: - self.closed = True - return int(self) - raise ValueError("already closed") - - def __repr__(self): - return "%s(%d)" % (self.__class__.__name__, int(self)) - - __del__ = Close -else: - # When select or poll has indicated that the file is writable, - # we can write up to _PIPE_BUF bytes without risk of blocking. - # POSIX defines PIPE_BUF as >= 512. - _PIPE_BUF = getattr(select, 'PIPE_BUF', 512) - - # poll/select have the advantage of not requiring any extra file - # descriptor, contrarily to epoll/kqueue (also, they require a single - # syscall). - if hasattr(selectors, 'PollSelector'): - _PopenSelector = selectors.PollSelector - else: - _PopenSelector = selectors.SelectSelector - - -if _mswindows: - # On Windows we just need to close `Popen._handle` when we no longer need - # it, so that the kernel can free it. `Popen._handle` gets closed - # implicitly when the `Popen` instance is finalized (see `Handle.__del__`, - # which is calling `CloseHandle` as requested in [1]), so there is nothing - # for `_cleanup` to do. - # - # [1] https://docs.microsoft.com/en-us/windows/desktop/ProcThread/ - # creating-processes - _active = None - - def _cleanup(): - pass -else: - # This lists holds Popen instances for which the underlying process had not - # exited at the time its __del__ method got called: those processes are - # wait()ed for synchronously from _cleanup() when a new Popen object is - # created, to avoid zombie processes. - _active = [] - - def _cleanup(): - if _active is None: - return - for inst in _active[:]: - res = inst._internal_poll(_deadstate=sys.maxsize) - if res is not None: - try: - _active.remove(inst) - except ValueError: - # This can happen if two threads create a new Popen instance. - # It's harmless that it was already removed, so ignore. - pass - -PIPE = -1 -STDOUT = -2 -DEVNULL = -3 - - -# XXX This function is only used by multiprocessing and the test suite, -# but it's here so that it can be imported when Python is compiled without -# threads. - -def _optim_args_from_interpreter_flags(): - """Return a list of command-line arguments reproducing the current - optimization settings in sys.flags.""" - args = [] - value = sys.flags.optimize - if value > 0: - args.append('-' + 'O' * value) - return args - - -def _args_from_interpreter_flags(): - """Return a list of command-line arguments reproducing the current - settings in sys.flags, sys.warnoptions and sys._xoptions.""" - flag_opt_map = { - 'debug': 'd', - # 'inspect': 'i', - # 'interactive': 'i', - 'dont_write_bytecode': 'B', - 'no_site': 'S', - 'verbose': 'v', - 'bytes_warning': 'b', - 'quiet': 'q', - # -O is handled in _optim_args_from_interpreter_flags() - } - args = _optim_args_from_interpreter_flags() - for flag, opt in flag_opt_map.items(): - v = getattr(sys.flags, flag) - if v > 0: - args.append('-' + opt * v) - - if sys.flags.isolated: - args.append('-I') - else: - if sys.flags.ignore_environment: - args.append('-E') - if sys.flags.no_user_site: - args.append('-s') - if sys.flags.safe_path: - args.append('-P') - - # -W options - warnopts = sys.warnoptions[:] - xoptions = getattr(sys, '_xoptions', {}) - bytes_warning = sys.flags.bytes_warning - dev_mode = sys.flags.dev_mode - - if bytes_warning > 1: - warnopts.remove("error::BytesWarning") - elif bytes_warning: - warnopts.remove("default::BytesWarning") - if dev_mode: - warnopts.remove('default') - for opt in warnopts: - args.append('-W' + opt) - - # -X options - if dev_mode: - args.extend(('-X', 'dev')) - for opt in ('faulthandler', 'tracemalloc', 'importtime', - 'showrefcount', 'utf8'): - if opt in xoptions: - value = xoptions[opt] - if value is True: - arg = opt - else: - arg = '%s=%s' % (opt, value) - args.extend(('-X', arg)) - - return args - - -def _text_encoding(): - # Return default text encoding and emit EncodingWarning if - # sys.flags.warn_default_encoding is true. - if sys.flags.warn_default_encoding: - f = sys._getframe() - filename = f.f_code.co_filename - stacklevel = 2 - while f := f.f_back: - if f.f_code.co_filename != filename: - break - stacklevel += 1 - warnings.warn("'encoding' argument not specified.", - EncodingWarning, stacklevel) - - if sys.flags.utf8_mode: - return "utf-8" - else: - return locale.getencoding() - - -def call(*popenargs, timeout=None, **kwargs): - """Run command with arguments. Wait for command to complete or - timeout, then return the returncode attribute. - - The arguments are the same as for the Popen constructor. Example: - - retcode = call(["ls", "-l"]) - """ - with Popen(*popenargs, **kwargs) as p: - try: - return p.wait(timeout=timeout) - except: # Including KeyboardInterrupt, wait handled that. - p.kill() - # We don't call p.wait() again as p.__exit__ does that for us. - raise - - -def check_call(*popenargs, **kwargs): - """Run command with arguments. Wait for command to complete. If - the exit code was zero then return, otherwise raise - CalledProcessError. The CalledProcessError object will have the - return code in the returncode attribute. - - The arguments are the same as for the call function. Example: - - check_call(["ls", "-l"]) - """ - retcode = call(*popenargs, **kwargs) - if retcode: - cmd = kwargs.get("args") - if cmd is None: - cmd = popenargs[0] - raise CalledProcessError(retcode, cmd) - return 0 - - -def check_output(*popenargs, timeout=None, **kwargs): - r"""Run command with arguments and return its output. - - If the exit code was non-zero it raises a CalledProcessError. The - CalledProcessError object will have the return code in the returncode - attribute and output in the output attribute. - - The arguments are the same as for the Popen constructor. Example: - - >>> check_output(["ls", "-l", "/dev/null"]) - b'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' - - The stdout argument is not allowed as it is used internally. - To capture standard error in the result, use stderr=STDOUT. - - >>> check_output(["/bin/sh", "-c", - ... "ls -l non_existent_file ; exit 0"], - ... stderr=STDOUT) - b'ls: non_existent_file: No such file or directory\n' - - There is an additional optional argument, "input", allowing you to - pass a string to the subprocess's stdin. If you use this argument - you may not also use the Popen constructor's "stdin" argument, as - it too will be used internally. Example: - - >>> check_output(["sed", "-e", "s/foo/bar/"], - ... input=b"when in the course of fooman events\n") - b'when in the course of barman events\n' - - By default, all communication is in bytes, and therefore any "input" - should be bytes, and the return value will be bytes. If in text mode, - any "input" should be a string, and the return value will be a string - decoded according to locale encoding, or by "encoding" if set. Text mode - is triggered by setting any of text, encoding, errors or universal_newlines. - """ - for kw in ('stdout', 'check'): - if kw in kwargs: - raise ValueError(f'{kw} argument not allowed, it will be overridden.') - - if 'input' in kwargs and kwargs['input'] is None: - # Explicitly passing input=None was previously equivalent to passing an - # empty string. That is maintained here for backwards compatibility. - if kwargs.get('universal_newlines') or kwargs.get('text') or kwargs.get('encoding') \ - or kwargs.get('errors'): - empty = '' - else: - empty = b'' - kwargs['input'] = empty - - return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, - **kwargs).stdout - - -class CompletedProcess(object): - """A process that has finished running. - - This is returned by run(). - - Attributes: - args: The list or str args passed to run(). - returncode: The exit code of the process, negative for signals. - stdout: The standard output (None if not captured). - stderr: The standard error (None if not captured). - """ - def __init__(self, args, returncode, stdout=None, stderr=None): - self.args = args - self.returncode = returncode - self.stdout = stdout - self.stderr = stderr - - def __repr__(self): - args = ['args={!r}'.format(self.args), - 'returncode={!r}'.format(self.returncode)] - if self.stdout is not None: - args.append('stdout={!r}'.format(self.stdout)) - if self.stderr is not None: - args.append('stderr={!r}'.format(self.stderr)) - return "{}({})".format(type(self).__name__, ', '.join(args)) - - __class_getitem__ = classmethod(types.GenericAlias) - - - def check_returncode(self): - """Raise CalledProcessError if the exit code is non-zero.""" - if self.returncode: - raise CalledProcessError(self.returncode, self.args, self.stdout, - self.stderr) - - -def run(*popenargs, - input=None, capture_output=False, timeout=None, check=False, **kwargs): - """Run command with arguments and return a CompletedProcess instance. - - The returned instance will have attributes args, returncode, stdout and - stderr. By default, stdout and stderr are not captured, and those attributes - will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, - or pass capture_output=True to capture both. - - If check is True and the exit code was non-zero, it raises a - CalledProcessError. The CalledProcessError object will have the return code - in the returncode attribute, and output & stderr attributes if those streams - were captured. - - If timeout is given, and the process takes too long, a TimeoutExpired - exception will be raised. - - There is an optional argument "input", allowing you to - pass bytes or a string to the subprocess's stdin. If you use this argument - you may not also use the Popen constructor's "stdin" argument, as - it will be used internally. - - By default, all communication is in bytes, and therefore any "input" should - be bytes, and the stdout and stderr will be bytes. If in text mode, any - "input" should be a string, and stdout and stderr will be strings decoded - according to locale encoding, or by "encoding" if set. Text mode is - triggered by setting any of text, encoding, errors or universal_newlines. - - The other arguments are the same as for the Popen constructor. - """ - if input is not None: - if kwargs.get('stdin') is not None: - raise ValueError('stdin and input arguments may not both be used.') - kwargs['stdin'] = PIPE - - if capture_output: - if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: - raise ValueError('stdout and stderr arguments may not be used ' - 'with capture_output.') - kwargs['stdout'] = PIPE - kwargs['stderr'] = PIPE - - with Popen(*popenargs, **kwargs) as process: - try: - stdout, stderr = process.communicate(input, timeout=timeout) - except TimeoutExpired as exc: - process.kill() - if _mswindows: - # Windows accumulates the output in a single blocking - # read() call run on child threads, with the timeout - # being done in a join() on those threads. communicate() - # _after_ kill() is required to collect that and add it - # to the exception. - exc.stdout, exc.stderr = process.communicate() - else: - # POSIX _communicate already populated the output so - # far into the TimeoutExpired exception. - process.wait() - raise - except: # Including KeyboardInterrupt, communicate handled that. - process.kill() - # We don't call process.wait() as .__exit__ does that for us. - raise - retcode = process.poll() - if check and retcode: - raise CalledProcessError(retcode, process.args, - output=stdout, stderr=stderr) - return CompletedProcess(process.args, retcode, stdout, stderr) - - -def list2cmdline(seq): - """ - Translate a sequence of arguments into a command line - string, using the same rules as the MS C runtime: - - 1) Arguments are delimited by white space, which is either a - space or a tab. - - 2) A string surrounded by double quotation marks is - interpreted as a single argument, regardless of white space - contained within. A quoted string can be embedded in an - argument. - - 3) A double quotation mark preceded by a backslash is - interpreted as a literal double quotation mark. - - 4) Backslashes are interpreted literally, unless they - immediately precede a double quotation mark. - - 5) If backslashes immediately precede a double quotation mark, - every pair of backslashes is interpreted as a literal - backslash. If the number of backslashes is odd, the last - backslash escapes the next double quotation mark as - described in rule 3. - """ - - # See - # http://msdn.microsoft.com/en-us/library/17w5ykft.aspx - # or search http://msdn.microsoft.com for - # "Parsing C++ Command-Line Arguments" - result = [] - needquote = False - for arg in map(os.fsdecode, seq): - bs_buf = [] - - # Add a space to separate this argument from the others - if result: - result.append(' ') - - needquote = (" " in arg) or ("\t" in arg) or not arg - if needquote: - result.append('"') - - for c in arg: - if c == '\\': - # Don't know if we need to double yet. - bs_buf.append(c) - elif c == '"': - # Double backslashes. - result.append('\\' * len(bs_buf)*2) - bs_buf = [] - result.append('\\"') - else: - # Normal char - if bs_buf: - result.extend(bs_buf) - bs_buf = [] - result.append(c) - - # Add remaining backslashes, if any. - if bs_buf: - result.extend(bs_buf) - - if needquote: - result.extend(bs_buf) - result.append('"') - - return ''.join(result) - - -# Various tools for executing commands and looking at their output and status. -# - -def getstatusoutput(cmd, *, encoding=None, errors=None): - """Return (exitcode, output) of executing cmd in a shell. - - Execute the string 'cmd' in a shell with 'check_output' and - return a 2-tuple (status, output). The locale encoding is used - to decode the output and process newlines. - - A trailing newline is stripped from the output. - The exit status for the command can be interpreted - according to the rules for the function 'wait'. Example: - - >>> import subprocess - >>> subprocess.getstatusoutput('ls /bin/ls') - (0, '/bin/ls') - >>> subprocess.getstatusoutput('cat /bin/junk') - (1, 'cat: /bin/junk: No such file or directory') - >>> subprocess.getstatusoutput('/bin/junk') - (127, 'sh: /bin/junk: not found') - >>> subprocess.getstatusoutput('/bin/kill $$') - (-15, '') - """ - try: - data = check_output(cmd, shell=True, text=True, stderr=STDOUT, - encoding=encoding, errors=errors) - exitcode = 0 - except CalledProcessError as ex: - data = ex.output - exitcode = ex.returncode - if data[-1:] == '\n': - data = data[:-1] - return exitcode, data - -def getoutput(cmd, *, encoding=None, errors=None): - """Return output (stdout or stderr) of executing cmd in a shell. - - Like getstatusoutput(), except the exit status is ignored and the return - value is a string containing the command's output. Example: - - >>> import subprocess - >>> subprocess.getoutput('ls /bin/ls') - '/bin/ls' - """ - return getstatusoutput(cmd, encoding=encoding, errors=errors)[1] - - - -def _use_posix_spawn(): - """Check if posix_spawn() can be used for subprocess. - - subprocess requires a posix_spawn() implementation that properly reports - errors to the parent process, & sets errno on the following failures: - - * Process attribute actions failed. - * File actions failed. - * exec() failed. - - Prefer an implementation which can use vfork() in some cases for best - performance. - """ - if _mswindows or not hasattr(os, 'posix_spawn'): - # os.posix_spawn() is not available - return False - - if sys.platform in ('darwin', 'sunos5'): - # posix_spawn() is a syscall on both macOS and Solaris, - # and properly reports errors - return True - - # Check libc name and runtime libc version - try: - ver = os.confstr('CS_GNU_LIBC_VERSION') - # parse 'glibc 2.28' as ('glibc', (2, 28)) - parts = ver.split(maxsplit=1) - if len(parts) != 2: - # reject unknown format - raise ValueError - libc = parts[0] - version = tuple(map(int, parts[1].split('.'))) - - if sys.platform == 'linux' and libc == 'glibc' and version >= (2, 24): - # glibc 2.24 has a new Linux posix_spawn implementation using vfork - # which properly reports errors to the parent process. - return True - # Note: Don't use the implementation in earlier glibc because it doesn't - # use vfork (even if glibc 2.26 added a pipe to properly report errors - # to the parent process). - except (AttributeError, ValueError, OSError): - # os.confstr() or CS_GNU_LIBC_VERSION value not available - pass - - # By default, assume that posix_spawn() does not properly report errors. - return False - - -# These are primarily fail-safe knobs for negatives. A True value does not -# guarantee the given libc/syscall API will be used. -_USE_POSIX_SPAWN = _use_posix_spawn() -_USE_VFORK = True - - -class Popen: - """ Execute a child program in a new process. - - For a complete description of the arguments see the Python documentation. - - Arguments: - args: A string, or a sequence of program arguments. - - bufsize: supplied as the buffering argument to the open() function when - creating the stdin/stdout/stderr pipe file objects - - executable: A replacement program to execute. - - stdin, stdout and stderr: These specify the executed programs' standard - input, standard output and standard error file handles, respectively. - - preexec_fn: (POSIX only) An object to be called in the child process - just before the child is executed. - - close_fds: Controls closing or inheriting of file descriptors. - - shell: If true, the command will be executed through the shell. - - cwd: Sets the current directory before the child is executed. - - env: Defines the environment variables for the new process. - - text: If true, decode stdin, stdout and stderr using the given encoding - (if set) or the system default otherwise. - - universal_newlines: Alias of text, provided for backwards compatibility. - - startupinfo and creationflags (Windows only) - - restore_signals (POSIX only) - - start_new_session (POSIX only) - - process_group (POSIX only) - - group (POSIX only) - - extra_groups (POSIX only) - - user (POSIX only) - - umask (POSIX only) - - pass_fds (POSIX only) - - encoding and errors: Text mode encoding and error handling to use for - file objects stdin, stdout and stderr. - - Attributes: - stdin, stdout, stderr, pid, returncode - """ - _child_created = False # Set here since __del__ checks it - - def __init__(self, args, bufsize=-1, executable=None, - stdin=None, stdout=None, stderr=None, - preexec_fn=None, close_fds=True, - shell=False, cwd=None, env=None, universal_newlines=None, - startupinfo=None, creationflags=0, - restore_signals=True, start_new_session=False, - pass_fds=(), *, user=None, group=None, extra_groups=None, - encoding=None, errors=None, text=None, umask=-1, pipesize=-1, - process_group=None): - """Create new Popen instance.""" - if not _can_fork_exec: - raise OSError( - errno.ENOTSUP, f"{sys.platform} does not support processes." - ) - - _cleanup() - # Held while anything is calling waitpid before returncode has been - # updated to prevent clobbering returncode if wait() or poll() are - # called from multiple threads at once. After acquiring the lock, - # code must re-check self.returncode to see if another thread just - # finished a waitpid() call. - self._waitpid_lock = threading.Lock() - - self._input = None - self._communication_started = False - if bufsize is None: - bufsize = -1 # Restore default - if not isinstance(bufsize, int): - raise TypeError("bufsize must be an integer") - - if pipesize is None: - pipesize = -1 # Restore default - if not isinstance(pipesize, int): - raise TypeError("pipesize must be an integer") - - if _mswindows: - if preexec_fn is not None: - raise ValueError("preexec_fn is not supported on Windows " - "platforms") - else: - # POSIX - if pass_fds and not close_fds: - warnings.warn("pass_fds overriding close_fds.", RuntimeWarning) - close_fds = True - if startupinfo is not None: - raise ValueError("startupinfo is only supported on Windows " - "platforms") - if creationflags != 0: - raise ValueError("creationflags is only supported on Windows " - "platforms") - - self.args = args - self.stdin = None - self.stdout = None - self.stderr = None - self.pid = None - self.returncode = None - self.encoding = encoding - self.errors = errors - self.pipesize = pipesize - - # Validate the combinations of text and universal_newlines - if (text is not None and universal_newlines is not None - and bool(universal_newlines) != bool(text)): - raise SubprocessError('Cannot disambiguate when both text ' - 'and universal_newlines are supplied but ' - 'different. Pass one or the other.') - - # Input and output objects. The general principle is like - # this: - # - # Parent Child - # ------ ----- - # p2cwrite ---stdin---> p2cread - # c2pread <--stdout--- c2pwrite - # errread <--stderr--- errwrite - # - # On POSIX, the child objects are file descriptors. On - # Windows, these are Windows file handles. The parent objects - # are file descriptors on both platforms. The parent objects - # are -1 when not using PIPEs. The child objects are -1 - # when not redirecting. - - (p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) = self._get_handles(stdin, stdout, stderr) - - # We wrap OS handles *before* launching the child, otherwise a - # quickly terminating child could make our fds unwrappable - # (see #8458). - - if _mswindows: - if p2cwrite != -1: - p2cwrite = msvcrt.open_osfhandle(p2cwrite.Detach(), 0) - if c2pread != -1: - c2pread = msvcrt.open_osfhandle(c2pread.Detach(), 0) - if errread != -1: - errread = msvcrt.open_osfhandle(errread.Detach(), 0) - - self.text_mode = encoding or errors or text or universal_newlines - if self.text_mode and encoding is None: - self.encoding = encoding = _text_encoding() - - # How long to resume waiting on a child after the first ^C. - # There is no right value for this. The purpose is to be polite - # yet remain good for interactive users trying to exit a tool. - self._sigint_wait_secs = 0.25 # 1/xkcd221.getRandomNumber() - - self._closed_child_pipe_fds = False - - if self.text_mode: - if bufsize == 1: - line_buffering = True - # Use the default buffer size for the underlying binary streams - # since they don't support line buffering. - bufsize = -1 - else: - line_buffering = False - - if process_group is None: - process_group = -1 # The internal APIs are int-only - - gid = None - if group is not None: - if not hasattr(os, 'setregid'): - raise ValueError("The 'group' parameter is not supported on the " - "current platform") - - elif isinstance(group, str): - try: - import grp - except ImportError: - raise ValueError("The group parameter cannot be a string " - "on systems without the grp module") - - gid = grp.getgrnam(group).gr_gid - elif isinstance(group, int): - gid = group - else: - raise TypeError("Group must be a string or an integer, not {}" - .format(type(group))) - - if gid < 0: - raise ValueError(f"Group ID cannot be negative, got {gid}") - - gids = None - if extra_groups is not None: - if not hasattr(os, 'setgroups'): - raise ValueError("The 'extra_groups' parameter is not " - "supported on the current platform") - - elif isinstance(extra_groups, str): - raise ValueError("Groups must be a list, not a string") - - gids = [] - for extra_group in extra_groups: - if isinstance(extra_group, str): - try: - import grp - except ImportError: - raise ValueError("Items in extra_groups cannot be " - "strings on systems without the " - "grp module") - - gids.append(grp.getgrnam(extra_group).gr_gid) - elif isinstance(extra_group, int): - gids.append(extra_group) - else: - raise TypeError("Items in extra_groups must be a string " - "or integer, not {}" - .format(type(extra_group))) - - # make sure that the gids are all positive here so we can do less - # checking in the C code - for gid_check in gids: - if gid_check < 0: - raise ValueError(f"Group ID cannot be negative, got {gid_check}") - - uid = None - if user is not None: - if not hasattr(os, 'setreuid'): - raise ValueError("The 'user' parameter is not supported on " - "the current platform") - - elif isinstance(user, str): - try: - import pwd - except ImportError: - raise ValueError("The user parameter cannot be a string " - "on systems without the pwd module") - uid = pwd.getpwnam(user).pw_uid - elif isinstance(user, int): - uid = user - else: - raise TypeError("User must be a string or an integer") - - if uid < 0: - raise ValueError(f"User ID cannot be negative, got {uid}") - - try: - if p2cwrite != -1: - self.stdin = io.open(p2cwrite, 'wb', bufsize) - if self.text_mode: - self.stdin = io.TextIOWrapper(self.stdin, write_through=True, - line_buffering=line_buffering, - encoding=encoding, errors=errors) - if c2pread != -1: - self.stdout = io.open(c2pread, 'rb', bufsize) - if self.text_mode: - self.stdout = io.TextIOWrapper(self.stdout, - encoding=encoding, errors=errors) - if errread != -1: - self.stderr = io.open(errread, 'rb', bufsize) - if self.text_mode: - self.stderr = io.TextIOWrapper(self.stderr, - encoding=encoding, errors=errors) - - self._execute_child(args, executable, preexec_fn, close_fds, - pass_fds, cwd, env, - startupinfo, creationflags, shell, - p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite, - restore_signals, - gid, gids, uid, umask, - start_new_session, process_group) - except: - # Cleanup if the child failed starting. - for f in filter(None, (self.stdin, self.stdout, self.stderr)): - try: - f.close() - except OSError: - pass # Ignore EBADF or other errors. - - if not self._closed_child_pipe_fds: - to_close = [] - if stdin == PIPE: - to_close.append(p2cread) - if stdout == PIPE: - to_close.append(c2pwrite) - if stderr == PIPE: - to_close.append(errwrite) - if hasattr(self, '_devnull'): - to_close.append(self._devnull) - for fd in to_close: - try: - if _mswindows and isinstance(fd, Handle): - fd.Close() - else: - os.close(fd) - except OSError: - pass - - raise - - def __repr__(self): - obj_repr = ( - f"<{self.__class__.__name__}: " - f"returncode: {self.returncode} args: {self.args!r}>" - ) - if len(obj_repr) > 80: - obj_repr = obj_repr[:76] + "...>" - return obj_repr - - __class_getitem__ = classmethod(types.GenericAlias) - - @property - def universal_newlines(self): - # universal_newlines as retained as an alias of text_mode for API - # compatibility. bpo-31756 - return self.text_mode - - @universal_newlines.setter - def universal_newlines(self, universal_newlines): - self.text_mode = bool(universal_newlines) - - def _translate_newlines(self, data, encoding, errors): - data = data.decode(encoding, errors) - return data.replace("\r\n", "\n").replace("\r", "\n") - - def __enter__(self): - return self - - def __exit__(self, exc_type, value, traceback): - if self.stdout: - self.stdout.close() - if self.stderr: - self.stderr.close() - try: # Flushing a BufferedWriter may raise an error - if self.stdin: - self.stdin.close() - finally: - if exc_type == KeyboardInterrupt: - # https://bugs.python.org/issue25942 - # In the case of a KeyboardInterrupt we assume the SIGINT - # was also already sent to our child processes. We can't - # block indefinitely as that is not user friendly. - # If we have not already waited a brief amount of time in - # an interrupted .wait() or .communicate() call, do so here - # for consistency. - if self._sigint_wait_secs > 0: - try: - self._wait(timeout=self._sigint_wait_secs) - except TimeoutExpired: - pass - self._sigint_wait_secs = 0 # Note that this has been done. - return # resume the KeyboardInterrupt - - # Wait for the process to terminate, to avoid zombies. - self.wait() - - def __del__(self, _maxsize=sys.maxsize, _warn=warnings.warn): - if not self._child_created: - # We didn't get to successfully create a child process. - return - if self.returncode is None: - # Not reading subprocess exit status creates a zombie process which - # is only destroyed at the parent python process exit - _warn("subprocess %s is still running" % self.pid, - ResourceWarning, source=self) - # In case the child hasn't been waited on, check if it's done. - self._internal_poll(_deadstate=_maxsize) - if self.returncode is None and _active is not None: - # Child is still running, keep us alive until we can wait on it. - _active.append(self) - - def _get_devnull(self): - if not hasattr(self, '_devnull'): - self._devnull = os.open(os.devnull, os.O_RDWR) - return self._devnull - - def _stdin_write(self, input): - if input: - try: - self.stdin.write(input) - except BrokenPipeError: - pass # communicate() must ignore broken pipe errors. - except OSError as exc: - if exc.errno == errno.EINVAL: - # bpo-19612, bpo-30418: On Windows, stdin.write() fails - # with EINVAL if the child process exited or if the child - # process is still running but closed the pipe. - pass - else: - raise - - try: - self.stdin.close() - except BrokenPipeError: - pass # communicate() must ignore broken pipe errors. - except OSError as exc: - if exc.errno == errno.EINVAL: - pass - else: - raise - - def communicate(self, input=None, timeout=None): - """Interact with process: Send data to stdin and close it. - Read data from stdout and stderr, until end-of-file is - reached. Wait for process to terminate. - - The optional "input" argument should be data to be sent to the - child process, or None, if no data should be sent to the child. - communicate() returns a tuple (stdout, stderr). - - By default, all communication is in bytes, and therefore any - "input" should be bytes, and the (stdout, stderr) will be bytes. - If in text mode (indicated by self.text_mode), any "input" should - be a string, and (stdout, stderr) will be strings decoded - according to locale encoding, or by "encoding" if set. Text mode - is triggered by setting any of text, encoding, errors or - universal_newlines. - """ - - if self._communication_started and input: - raise ValueError("Cannot send input after starting communication") - - # Optimization: If we are not worried about timeouts, we haven't - # started communicating, and we have one or zero pipes, using select() - # or threads is unnecessary. - if (timeout is None and not self._communication_started and - [self.stdin, self.stdout, self.stderr].count(None) >= 2): - stdout = None - stderr = None - if self.stdin: - self._stdin_write(input) - elif self.stdout: - stdout = self.stdout.read() - self.stdout.close() - elif self.stderr: - stderr = self.stderr.read() - self.stderr.close() - self.wait() - else: - if timeout is not None: - endtime = _time() + timeout - else: - endtime = None - - try: - stdout, stderr = self._communicate(input, endtime, timeout) - except KeyboardInterrupt: - # https://bugs.python.org/issue25942 - # See the detailed comment in .wait(). - if timeout is not None: - sigint_timeout = min(self._sigint_wait_secs, - self._remaining_time(endtime)) - else: - sigint_timeout = self._sigint_wait_secs - self._sigint_wait_secs = 0 # nothing else should wait. - try: - self._wait(timeout=sigint_timeout) - except TimeoutExpired: - pass - raise # resume the KeyboardInterrupt - - finally: - self._communication_started = True - - sts = self.wait(timeout=self._remaining_time(endtime)) - - return (stdout, stderr) - - - def poll(self): - """Check if child process has terminated. Set and return returncode - attribute.""" - return self._internal_poll() - - - def _remaining_time(self, endtime): - """Convenience for _communicate when computing timeouts.""" - if endtime is None: - return None - else: - return endtime - _time() - - - def _check_timeout(self, endtime, orig_timeout, stdout_seq, stderr_seq, - skip_check_and_raise=False): - """Convenience for checking if a timeout has expired.""" - if endtime is None: - return - if skip_check_and_raise or _time() > endtime: - raise TimeoutExpired( - self.args, orig_timeout, - output=b''.join(stdout_seq) if stdout_seq else None, - stderr=b''.join(stderr_seq) if stderr_seq else None) - - - def wait(self, timeout=None): - """Wait for child process to terminate; returns self.returncode.""" - if timeout is not None: - endtime = _time() + timeout - try: - return self._wait(timeout=timeout) - except KeyboardInterrupt: - # https://bugs.python.org/issue25942 - # The first keyboard interrupt waits briefly for the child to - # exit under the common assumption that it also received the ^C - # generated SIGINT and will exit rapidly. - if timeout is not None: - sigint_timeout = min(self._sigint_wait_secs, - self._remaining_time(endtime)) - else: - sigint_timeout = self._sigint_wait_secs - self._sigint_wait_secs = 0 # nothing else should wait. - try: - self._wait(timeout=sigint_timeout) - except TimeoutExpired: - pass - raise # resume the KeyboardInterrupt - - def _close_pipe_fds(self, - p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite): - # self._devnull is not always defined. - devnull_fd = getattr(self, '_devnull', None) - - with contextlib.ExitStack() as stack: - if _mswindows: - if p2cread != -1: - stack.callback(p2cread.Close) - if c2pwrite != -1: - stack.callback(c2pwrite.Close) - if errwrite != -1: - stack.callback(errwrite.Close) - else: - if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: - stack.callback(os.close, p2cread) - if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: - stack.callback(os.close, c2pwrite) - if errwrite != -1 and errread != -1 and errwrite != devnull_fd: - stack.callback(os.close, errwrite) - - if devnull_fd is not None: - stack.callback(os.close, devnull_fd) - - # Prevent a double close of these handles/fds from __init__ on error. - self._closed_child_pipe_fds = True - - if _mswindows: - # - # Windows methods - # - def _get_handles(self, stdin, stdout, stderr): - """Construct and return tuple with IO objects: - p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite - """ - if stdin is None and stdout is None and stderr is None: - return (-1, -1, -1, -1, -1, -1) - - p2cread, p2cwrite = -1, -1 - c2pread, c2pwrite = -1, -1 - errread, errwrite = -1, -1 - - if stdin is None: - p2cread = _winapi.GetStdHandle(_winapi.STD_INPUT_HANDLE) - if p2cread is None: - p2cread, _ = _winapi.CreatePipe(None, 0) - p2cread = Handle(p2cread) - _winapi.CloseHandle(_) - elif stdin == PIPE: - p2cread, p2cwrite = _winapi.CreatePipe(None, 0) - p2cread, p2cwrite = Handle(p2cread), Handle(p2cwrite) - elif stdin == DEVNULL: - p2cread = msvcrt.get_osfhandle(self._get_devnull()) - elif isinstance(stdin, int): - p2cread = msvcrt.get_osfhandle(stdin) - else: - # Assuming file-like object - p2cread = msvcrt.get_osfhandle(stdin.fileno()) - p2cread = self._make_inheritable(p2cread) - - if stdout is None: - c2pwrite = _winapi.GetStdHandle(_winapi.STD_OUTPUT_HANDLE) - if c2pwrite is None: - _, c2pwrite = _winapi.CreatePipe(None, 0) - c2pwrite = Handle(c2pwrite) - _winapi.CloseHandle(_) - elif stdout == PIPE: - c2pread, c2pwrite = _winapi.CreatePipe(None, 0) - c2pread, c2pwrite = Handle(c2pread), Handle(c2pwrite) - elif stdout == DEVNULL: - c2pwrite = msvcrt.get_osfhandle(self._get_devnull()) - elif isinstance(stdout, int): - c2pwrite = msvcrt.get_osfhandle(stdout) - else: - # Assuming file-like object - c2pwrite = msvcrt.get_osfhandle(stdout.fileno()) - c2pwrite = self._make_inheritable(c2pwrite) - - if stderr is None: - errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE) - if errwrite is None: - _, errwrite = _winapi.CreatePipe(None, 0) - errwrite = Handle(errwrite) - _winapi.CloseHandle(_) - elif stderr == PIPE: - errread, errwrite = _winapi.CreatePipe(None, 0) - errread, errwrite = Handle(errread), Handle(errwrite) - elif stderr == STDOUT: - errwrite = c2pwrite - elif stderr == DEVNULL: - errwrite = msvcrt.get_osfhandle(self._get_devnull()) - elif isinstance(stderr, int): - errwrite = msvcrt.get_osfhandle(stderr) - else: - # Assuming file-like object - errwrite = msvcrt.get_osfhandle(stderr.fileno()) - errwrite = self._make_inheritable(errwrite) - - return (p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) - - - def _make_inheritable(self, handle): - """Return a duplicate of handle, which is inheritable""" - h = _winapi.DuplicateHandle( - _winapi.GetCurrentProcess(), handle, - _winapi.GetCurrentProcess(), 0, 1, - _winapi.DUPLICATE_SAME_ACCESS) - return Handle(h) - - - def _filter_handle_list(self, handle_list): - """Filter out console handles that can't be used - in lpAttributeList["handle_list"] and make sure the list - isn't empty. This also removes duplicate handles.""" - # An handle with it's lowest two bits set might be a special console - # handle that if passed in lpAttributeList["handle_list"], will - # cause it to fail. - return list({handle for handle in handle_list - if handle & 0x3 != 0x3 - or _winapi.GetFileType(handle) != - _winapi.FILE_TYPE_CHAR}) - - - def _execute_child(self, args, executable, preexec_fn, close_fds, - pass_fds, cwd, env, - startupinfo, creationflags, shell, - p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite, - unused_restore_signals, - unused_gid, unused_gids, unused_uid, - unused_umask, - unused_start_new_session, unused_process_group): - """Execute program (MS Windows version)""" - - assert not pass_fds, "pass_fds not supported on Windows." - - if isinstance(args, str): - pass - elif isinstance(args, bytes): - if shell: - raise TypeError('bytes args is not allowed on Windows') - args = list2cmdline([args]) - elif isinstance(args, os.PathLike): - if shell: - raise TypeError('path-like args is not allowed when ' - 'shell is true') - args = list2cmdline([args]) - else: - args = list2cmdline(args) - - if executable is not None: - executable = os.fsdecode(executable) - - # Process startup details - if startupinfo is None: - startupinfo = STARTUPINFO() - else: - # bpo-34044: Copy STARTUPINFO since it is modified above, - # so the caller can reuse it multiple times. - startupinfo = startupinfo.copy() - - use_std_handles = -1 not in (p2cread, c2pwrite, errwrite) - if use_std_handles: - startupinfo.dwFlags |= _winapi.STARTF_USESTDHANDLES - startupinfo.hStdInput = p2cread - startupinfo.hStdOutput = c2pwrite - startupinfo.hStdError = errwrite - - attribute_list = startupinfo.lpAttributeList - have_handle_list = bool(attribute_list and - "handle_list" in attribute_list and - attribute_list["handle_list"]) - - # If we were given an handle_list or need to create one - if have_handle_list or (use_std_handles and close_fds): - if attribute_list is None: - attribute_list = startupinfo.lpAttributeList = {} - handle_list = attribute_list["handle_list"] = \ - list(attribute_list.get("handle_list", [])) - - if use_std_handles: - handle_list += [int(p2cread), int(c2pwrite), int(errwrite)] - - handle_list[:] = self._filter_handle_list(handle_list) - - if handle_list: - if not close_fds: - warnings.warn("startupinfo.lpAttributeList['handle_list'] " - "overriding close_fds", RuntimeWarning) - - # When using the handle_list we always request to inherit - # handles but the only handles that will be inherited are - # the ones in the handle_list - close_fds = False - - if shell: - startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = _winapi.SW_HIDE - comspec = os.environ.get("COMSPEC", "cmd.exe") - args = '{} /c "{}"'.format (comspec, args) - - if cwd is not None: - cwd = os.fsdecode(cwd) - - sys.audit("subprocess.Popen", executable, args, cwd, env) - - # Start the process - try: - hp, ht, pid, tid = _winapi.CreateProcess(executable, args, - # no special security - None, None, - int(not close_fds), - creationflags, - env, - cwd, - startupinfo) - finally: - # Child is launched. Close the parent's copy of those pipe - # handles that only the child should have open. You need - # to make sure that no handles to the write end of the - # output pipe are maintained in this process or else the - # pipe will not close when the child process exits and the - # ReadFile will hang. - self._close_pipe_fds(p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) - - # Retain the process handle, but close the thread handle - self._child_created = True - self._handle = Handle(hp) - self.pid = pid - _winapi.CloseHandle(ht) - - def _internal_poll(self, _deadstate=None, - _WaitForSingleObject=_winapi.WaitForSingleObject, - _WAIT_OBJECT_0=_winapi.WAIT_OBJECT_0, - _GetExitCodeProcess=_winapi.GetExitCodeProcess): - """Check if child process has terminated. Returns returncode - attribute. - - This method is called by __del__, so it can only refer to objects - in its local scope. - - """ - if self.returncode is None: - if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0: - self.returncode = _GetExitCodeProcess(self._handle) - return self.returncode - - - def _wait(self, timeout): - """Internal implementation of wait() on Windows.""" - if timeout is None: - timeout_millis = _winapi.INFINITE - else: - timeout_millis = int(timeout * 1000) - if self.returncode is None: - # API note: Returns immediately if timeout_millis == 0. - result = _winapi.WaitForSingleObject(self._handle, - timeout_millis) - if result == _winapi.WAIT_TIMEOUT: - raise TimeoutExpired(self.args, timeout) - self.returncode = _winapi.GetExitCodeProcess(self._handle) - return self.returncode - - - def _readerthread(self, fh, buffer): - buffer.append(fh.read()) - fh.close() - - - def _communicate(self, input, endtime, orig_timeout): - # Start reader threads feeding into a list hanging off of this - # object, unless they've already been started. - if self.stdout and not hasattr(self, "_stdout_buff"): - self._stdout_buff = [] - self.stdout_thread = \ - threading.Thread(target=self._readerthread, - args=(self.stdout, self._stdout_buff)) - self.stdout_thread.daemon = True - self.stdout_thread.start() - if self.stderr and not hasattr(self, "_stderr_buff"): - self._stderr_buff = [] - self.stderr_thread = \ - threading.Thread(target=self._readerthread, - args=(self.stderr, self._stderr_buff)) - self.stderr_thread.daemon = True - self.stderr_thread.start() - - if self.stdin: - self._stdin_write(input) - - # Wait for the reader threads, or time out. If we time out, the - # threads remain reading and the fds left open in case the user - # calls communicate again. - if self.stdout is not None: - self.stdout_thread.join(self._remaining_time(endtime)) - if self.stdout_thread.is_alive(): - raise TimeoutExpired(self.args, orig_timeout) - if self.stderr is not None: - self.stderr_thread.join(self._remaining_time(endtime)) - if self.stderr_thread.is_alive(): - raise TimeoutExpired(self.args, orig_timeout) - - # Collect the output from and close both pipes, now that we know - # both have been read successfully. - stdout = None - stderr = None - if self.stdout: - stdout = self._stdout_buff - self.stdout.close() - if self.stderr: - stderr = self._stderr_buff - self.stderr.close() - - # All data exchanged. Translate lists into strings. - stdout = stdout[0] if stdout else None - stderr = stderr[0] if stderr else None - - return (stdout, stderr) - - def send_signal(self, sig): - """Send a signal to the process.""" - # Don't signal a process that we know has already died. - if self.returncode is not None: - return - if sig == signal.SIGTERM: - self.terminate() - elif sig == signal.CTRL_C_EVENT: - os.kill(self.pid, signal.CTRL_C_EVENT) - elif sig == signal.CTRL_BREAK_EVENT: - os.kill(self.pid, signal.CTRL_BREAK_EVENT) - else: - raise ValueError("Unsupported signal: {}".format(sig)) - - def terminate(self): - """Terminates the process.""" - # Don't terminate a process that we know has already died. - if self.returncode is not None: - return - try: - _winapi.TerminateProcess(self._handle, 1) - except PermissionError: - # ERROR_ACCESS_DENIED (winerror 5) is received when the - # process already died. - rc = _winapi.GetExitCodeProcess(self._handle) - if rc == _winapi.STILL_ACTIVE: - raise - self.returncode = rc - - kill = terminate - - else: - # - # POSIX methods - # - def _get_handles(self, stdin, stdout, stderr): - """Construct and return tuple with IO objects: - p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite - """ - p2cread, p2cwrite = -1, -1 - c2pread, c2pwrite = -1, -1 - errread, errwrite = -1, -1 - - if stdin is None: - pass - elif stdin == PIPE: - p2cread, p2cwrite = os.pipe() - if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"): - fcntl.fcntl(p2cwrite, fcntl.F_SETPIPE_SZ, self.pipesize) - elif stdin == DEVNULL: - p2cread = self._get_devnull() - elif isinstance(stdin, int): - p2cread = stdin - else: - # Assuming file-like object - p2cread = stdin.fileno() - - if stdout is None: - pass - elif stdout == PIPE: - c2pread, c2pwrite = os.pipe() - if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"): - fcntl.fcntl(c2pwrite, fcntl.F_SETPIPE_SZ, self.pipesize) - elif stdout == DEVNULL: - c2pwrite = self._get_devnull() - elif isinstance(stdout, int): - c2pwrite = stdout - else: - # Assuming file-like object - c2pwrite = stdout.fileno() - - if stderr is None: - pass - elif stderr == PIPE: - errread, errwrite = os.pipe() - if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"): - fcntl.fcntl(errwrite, fcntl.F_SETPIPE_SZ, self.pipesize) - elif stderr == STDOUT: - if c2pwrite != -1: - errwrite = c2pwrite - else: # child's stdout is not set, use parent's stdout - errwrite = sys.__stdout__.fileno() - elif stderr == DEVNULL: - errwrite = self._get_devnull() - elif isinstance(stderr, int): - errwrite = stderr - else: - # Assuming file-like object - errwrite = stderr.fileno() - - return (p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) - - - def _posix_spawn(self, args, executable, env, restore_signals, - p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite): - """Execute program using os.posix_spawn().""" - if env is None: - env = os.environ - - kwargs = {} - if restore_signals: - # See _Py_RestoreSignals() in Python/pylifecycle.c - sigset = [] - for signame in ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ'): - signum = getattr(signal, signame, None) - if signum is not None: - sigset.append(signum) - kwargs['setsigdef'] = sigset - - file_actions = [] - for fd in (p2cwrite, c2pread, errread): - if fd != -1: - file_actions.append((os.POSIX_SPAWN_CLOSE, fd)) - for fd, fd2 in ( - (p2cread, 0), - (c2pwrite, 1), - (errwrite, 2), - ): - if fd != -1: - file_actions.append((os.POSIX_SPAWN_DUP2, fd, fd2)) - if file_actions: - kwargs['file_actions'] = file_actions - - self.pid = os.posix_spawn(executable, args, env, **kwargs) - self._child_created = True - - self._close_pipe_fds(p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) - - def _execute_child(self, args, executable, preexec_fn, close_fds, - pass_fds, cwd, env, - startupinfo, creationflags, shell, - p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite, - restore_signals, - gid, gids, uid, umask, - start_new_session, process_group): - """Execute program (POSIX version)""" - - if isinstance(args, (str, bytes)): - args = [args] - elif isinstance(args, os.PathLike): - if shell: - raise TypeError('path-like args is not allowed when ' - 'shell is true') - args = [args] - else: - args = list(args) - - if shell: - # On Android the default shell is at '/system/bin/sh'. - unix_shell = ('/system/bin/sh' if - hasattr(sys, 'getandroidapilevel') else '/bin/sh') - args = [unix_shell, "-c"] + args - if executable: - args[0] = executable - - if executable is None: - executable = args[0] - - sys.audit("subprocess.Popen", executable, args, cwd, env) - - if (_USE_POSIX_SPAWN - and os.path.dirname(executable) - and preexec_fn is None - and not close_fds - and not pass_fds - and cwd is None - and (p2cread == -1 or p2cread > 2) - and (c2pwrite == -1 or c2pwrite > 2) - and (errwrite == -1 or errwrite > 2) - and not start_new_session - and process_group == -1 - and gid is None - and gids is None - and uid is None - and umask < 0): - self._posix_spawn(args, executable, env, restore_signals, - p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) - return - - orig_executable = executable - - # For transferring possible exec failure from child to parent. - # Data format: "exception name:hex errno:description" - # Pickle is not used; it is complex and involves memory allocation. - errpipe_read, errpipe_write = os.pipe() - # errpipe_write must not be in the standard io 0, 1, or 2 fd range. - low_fds_to_close = [] - while errpipe_write < 3: - low_fds_to_close.append(errpipe_write) - errpipe_write = os.dup(errpipe_write) - for low_fd in low_fds_to_close: - os.close(low_fd) - try: - try: - # We must avoid complex work that could involve - # malloc or free in the child process to avoid - # potential deadlocks, thus we do all this here. - # and pass it to fork_exec() - - if env is not None: - env_list = [] - for k, v in env.items(): - k = os.fsencode(k) - if b'=' in k: - raise ValueError("illegal environment variable name") - env_list.append(k + b'=' + os.fsencode(v)) - else: - env_list = None # Use execv instead of execve. - executable = os.fsencode(executable) - if os.path.dirname(executable): - executable_list = (executable,) - else: - # This matches the behavior of os._execvpe(). - executable_list = tuple( - os.path.join(os.fsencode(dir), executable) - for dir in os.get_exec_path(env)) - fds_to_keep = set(pass_fds) - fds_to_keep.add(errpipe_write) - self.pid = _fork_exec( - args, executable_list, - close_fds, tuple(sorted(map(int, fds_to_keep))), - cwd, env_list, - p2cread, p2cwrite, c2pread, c2pwrite, - errread, errwrite, - errpipe_read, errpipe_write, - restore_signals, start_new_session, - process_group, gid, gids, uid, umask, - preexec_fn, _USE_VFORK) - self._child_created = True - finally: - # be sure the FD is closed no matter what - os.close(errpipe_write) - - self._close_pipe_fds(p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) - - # Wait for exec to fail or succeed; possibly raising an - # exception (limited in size) - errpipe_data = bytearray() - while True: - part = os.read(errpipe_read, 50000) - errpipe_data += part - if not part or len(errpipe_data) > 50000: - break - finally: - # be sure the FD is closed no matter what - os.close(errpipe_read) - - if errpipe_data: - try: - pid, sts = os.waitpid(self.pid, 0) - if pid == self.pid: - self._handle_exitstatus(sts) - else: - self.returncode = sys.maxsize - except ChildProcessError: - pass - - try: - exception_name, hex_errno, err_msg = ( - errpipe_data.split(b':', 2)) - # The encoding here should match the encoding - # written in by the subprocess implementations - # like _posixsubprocess - err_msg = err_msg.decode() - except ValueError: - exception_name = b'SubprocessError' - hex_errno = b'0' - err_msg = 'Bad exception data from child: {!r}'.format( - bytes(errpipe_data)) - child_exception_type = getattr( - builtins, exception_name.decode('ascii'), - SubprocessError) - if issubclass(child_exception_type, OSError) and hex_errno: - errno_num = int(hex_errno, 16) - child_exec_never_called = (err_msg == "noexec") - if child_exec_never_called: - err_msg = "" - # The error must be from chdir(cwd). - err_filename = cwd - else: - err_filename = orig_executable - if errno_num != 0: - err_msg = os.strerror(errno_num) - raise child_exception_type(errno_num, err_msg, err_filename) - raise child_exception_type(err_msg) - - - def _handle_exitstatus(self, sts, - _waitstatus_to_exitcode=_waitstatus_to_exitcode, - _WIFSTOPPED=_WIFSTOPPED, - _WSTOPSIG=_WSTOPSIG): - """All callers to this function MUST hold self._waitpid_lock.""" - # This method is called (indirectly) by __del__, so it cannot - # refer to anything outside of its local scope. - if _WIFSTOPPED(sts): - self.returncode = -_WSTOPSIG(sts) - else: - self.returncode = _waitstatus_to_exitcode(sts) - - def _internal_poll(self, _deadstate=None, _waitpid=_waitpid, - _WNOHANG=_WNOHANG, _ECHILD=errno.ECHILD): - """Check if child process has terminated. Returns returncode - attribute. - - This method is called by __del__, so it cannot reference anything - outside of the local scope (nor can any methods it calls). - - """ - if self.returncode is None: - if not self._waitpid_lock.acquire(False): - # Something else is busy calling waitpid. Don't allow two - # at once. We know nothing yet. - return None - try: - if self.returncode is not None: - return self.returncode # Another thread waited. - pid, sts = _waitpid(self.pid, _WNOHANG) - if pid == self.pid: - self._handle_exitstatus(sts) - except OSError as e: - if _deadstate is not None: - self.returncode = _deadstate - elif e.errno == _ECHILD: - # This happens if SIGCLD is set to be ignored or - # waiting for child processes has otherwise been - # disabled for our process. This child is dead, we - # can't get the status. - # http://bugs.python.org/issue15756 - self.returncode = 0 - finally: - self._waitpid_lock.release() - return self.returncode - - - def _try_wait(self, wait_flags): - """All callers to this function MUST hold self._waitpid_lock.""" - try: - (pid, sts) = os.waitpid(self.pid, wait_flags) - except ChildProcessError: - # This happens if SIGCLD is set to be ignored or waiting - # for child processes has otherwise been disabled for our - # process. This child is dead, we can't get the status. - pid = self.pid - sts = 0 - return (pid, sts) - - - def _wait(self, timeout): - """Internal implementation of wait() on POSIX.""" - if self.returncode is not None: - return self.returncode - - if timeout is not None: - endtime = _time() + timeout - # Enter a busy loop if we have a timeout. This busy loop was - # cribbed from Lib/threading.py in Thread.wait() at r71065. - delay = 0.0005 # 500 us -> initial delay of 1 ms - while True: - if self._waitpid_lock.acquire(False): - try: - if self.returncode is not None: - break # Another thread waited. - (pid, sts) = self._try_wait(os.WNOHANG) - assert pid == self.pid or pid == 0 - if pid == self.pid: - self._handle_exitstatus(sts) - break - finally: - self._waitpid_lock.release() - remaining = self._remaining_time(endtime) - if remaining <= 0: - raise TimeoutExpired(self.args, timeout) - delay = min(delay * 2, remaining, .05) - time.sleep(delay) - else: - while self.returncode is None: - with self._waitpid_lock: - if self.returncode is not None: - break # Another thread waited. - (pid, sts) = self._try_wait(0) - # Check the pid and loop as waitpid has been known to - # return 0 even without WNOHANG in odd situations. - # http://bugs.python.org/issue14396. - if pid == self.pid: - self._handle_exitstatus(sts) - return self.returncode - - - def _communicate(self, input, endtime, orig_timeout): - if self.stdin and not self._communication_started: - # Flush stdio buffer. This might block, if the user has - # been writing to .stdin in an uncontrolled fashion. - try: - self.stdin.flush() - except BrokenPipeError: - pass # communicate() must ignore BrokenPipeError. - if not input: - try: - self.stdin.close() - except BrokenPipeError: - pass # communicate() must ignore BrokenPipeError. - - stdout = None - stderr = None - - # Only create this mapping if we haven't already. - if not self._communication_started: - self._fileobj2output = {} - if self.stdout: - self._fileobj2output[self.stdout] = [] - if self.stderr: - self._fileobj2output[self.stderr] = [] - - if self.stdout: - stdout = self._fileobj2output[self.stdout] - if self.stderr: - stderr = self._fileobj2output[self.stderr] - - self._save_input(input) - - if self._input: - input_view = memoryview(self._input) - - with _PopenSelector() as selector: - if self.stdin and input: - selector.register(self.stdin, selectors.EVENT_WRITE) - if self.stdout and not self.stdout.closed: - selector.register(self.stdout, selectors.EVENT_READ) - if self.stderr and not self.stderr.closed: - selector.register(self.stderr, selectors.EVENT_READ) - - while selector.get_map(): - timeout = self._remaining_time(endtime) - if timeout is not None and timeout < 0: - self._check_timeout(endtime, orig_timeout, - stdout, stderr, - skip_check_and_raise=True) - raise RuntimeError( # Impossible :) - '_check_timeout(..., skip_check_and_raise=True) ' - 'failed to raise TimeoutExpired.') - - ready = selector.select(timeout) - self._check_timeout(endtime, orig_timeout, stdout, stderr) - - # XXX Rewrite these to use non-blocking I/O on the file - # objects; they are no longer using C stdio! - - for key, events in ready: - if key.fileobj is self.stdin: - chunk = input_view[self._input_offset : - self._input_offset + _PIPE_BUF] - try: - self._input_offset += os.write(key.fd, chunk) - except BrokenPipeError: - selector.unregister(key.fileobj) - key.fileobj.close() - else: - if self._input_offset >= len(self._input): - selector.unregister(key.fileobj) - key.fileobj.close() - elif key.fileobj in (self.stdout, self.stderr): - data = os.read(key.fd, 32768) - if not data: - selector.unregister(key.fileobj) - key.fileobj.close() - self._fileobj2output[key.fileobj].append(data) - - self.wait(timeout=self._remaining_time(endtime)) - - # All data exchanged. Translate lists into strings. - if stdout is not None: - stdout = b''.join(stdout) - if stderr is not None: - stderr = b''.join(stderr) - - # Translate newlines, if requested. - # This also turns bytes into strings. - if self.text_mode: - if stdout is not None: - stdout = self._translate_newlines(stdout, - self.stdout.encoding, - self.stdout.errors) - if stderr is not None: - stderr = self._translate_newlines(stderr, - self.stderr.encoding, - self.stderr.errors) - - return (stdout, stderr) - - - def _save_input(self, input): - # This method is called from the _communicate_with_*() methods - # so that if we time out while communicating, we can continue - # sending input if we retry. - if self.stdin and self._input is None: - self._input_offset = 0 - self._input = input - if input is not None and self.text_mode: - self._input = self._input.encode(self.stdin.encoding, - self.stdin.errors) - - - def send_signal(self, sig): - """Send a signal to the process.""" - # bpo-38630: Polling reduces the risk of sending a signal to the - # wrong process if the process completed, the Popen.returncode - # attribute is still None, and the pid has been reassigned - # (recycled) to a new different process. This race condition can - # happens in two cases. - # - # Case 1. Thread A calls Popen.poll(), thread B calls - # Popen.send_signal(). In thread A, waitpid() succeed and returns - # the exit status. Thread B calls kill() because poll() in thread A - # did not set returncode yet. Calling poll() in thread B prevents - # the race condition thanks to Popen._waitpid_lock. - # - # Case 2. waitpid(pid, 0) has been called directly, without - # using Popen methods: returncode is still None is this case. - # Calling Popen.poll() will set returncode to a default value, - # since waitpid() fails with ProcessLookupError. - self.poll() - if self.returncode is not None: - # Skip signalling a process that we know has already died. - return - - # The race condition can still happen if the race condition - # described above happens between the returncode test - # and the kill() call. - try: - os.kill(self.pid, sig) - except ProcessLookupError: - # Suppress the race condition error; bpo-40550. - pass - - def terminate(self): - """Terminate the process with SIGTERM - """ - self.send_signal(signal.SIGTERM) - - def kill(self): - """Kill the process with SIGKILL - """ - self.send_signal(signal.SIGKILL) diff --git a/python/Lib/symtable.py b/python/Lib/symtable.py deleted file mode 100644 index 208096f..0000000 --- a/python/Lib/symtable.py +++ /dev/null @@ -1,326 +0,0 @@ -"""Interface to the compiler's internal symbol tables""" - -import _symtable -from _symtable import (USE, DEF_GLOBAL, DEF_NONLOCAL, DEF_LOCAL, DEF_PARAM, - DEF_IMPORT, DEF_BOUND, DEF_ANNOT, SCOPE_OFF, SCOPE_MASK, FREE, - LOCAL, GLOBAL_IMPLICIT, GLOBAL_EXPLICIT, CELL) - -import weakref - -__all__ = ["symtable", "SymbolTable", "Class", "Function", "Symbol"] - -def symtable(code, filename, compile_type): - """ Return the toplevel *SymbolTable* for the source code. - - *filename* is the name of the file with the code - and *compile_type* is the *compile()* mode argument. - """ - top = _symtable.symtable(code, filename, compile_type) - return _newSymbolTable(top, filename) - -class SymbolTableFactory: - def __init__(self): - self.__memo = weakref.WeakValueDictionary() - - def new(self, table, filename): - if table.type == _symtable.TYPE_FUNCTION: - return Function(table, filename) - if table.type == _symtable.TYPE_CLASS: - return Class(table, filename) - return SymbolTable(table, filename) - - def __call__(self, table, filename): - key = table, filename - obj = self.__memo.get(key, None) - if obj is None: - obj = self.__memo[key] = self.new(table, filename) - return obj - -_newSymbolTable = SymbolTableFactory() - - -class SymbolTable: - - def __init__(self, raw_table, filename): - self._table = raw_table - self._filename = filename - self._symbols = {} - - def __repr__(self): - if self.__class__ == SymbolTable: - kind = "" - else: - kind = "%s " % self.__class__.__name__ - - if self._table.name == "top": - return "<{0}SymbolTable for module {1}>".format(kind, self._filename) - else: - return "<{0}SymbolTable for {1} in {2}>".format(kind, - self._table.name, - self._filename) - - def get_type(self): - """Return the type of the symbol table. - - The values returned are 'class', 'module' and - 'function'. - """ - if self._table.type == _symtable.TYPE_MODULE: - return "module" - if self._table.type == _symtable.TYPE_FUNCTION: - return "function" - if self._table.type == _symtable.TYPE_CLASS: - return "class" - assert self._table.type in (1, 2, 3), \ - "unexpected type: {0}".format(self._table.type) - - def get_id(self): - """Return an identifier for the table. - """ - return self._table.id - - def get_name(self): - """Return the table's name. - - This corresponds to the name of the class, function - or 'top' if the table is for a class, function or - global respectively. - """ - return self._table.name - - def get_lineno(self): - """Return the number of the first line in the - block for the table. - """ - return self._table.lineno - - def is_optimized(self): - """Return *True* if the locals in the table - are optimizable. - """ - return bool(self._table.type == _symtable.TYPE_FUNCTION) - - def is_nested(self): - """Return *True* if the block is a nested class - or function.""" - return bool(self._table.nested) - - def has_children(self): - """Return *True* if the block has nested namespaces. - """ - return bool(self._table.children) - - def get_identifiers(self): - """Return a view object containing the names of symbols in the table. - """ - return self._table.symbols.keys() - - def lookup(self, name): - """Lookup a *name* in the table. - - Returns a *Symbol* instance. - """ - sym = self._symbols.get(name) - if sym is None: - flags = self._table.symbols[name] - namespaces = self.__check_children(name) - module_scope = (self._table.name == "top") - sym = self._symbols[name] = Symbol(name, flags, namespaces, - module_scope=module_scope) - return sym - - def get_symbols(self): - """Return a list of *Symbol* instances for - names in the table. - """ - return [self.lookup(ident) for ident in self.get_identifiers()] - - def __check_children(self, name): - return [_newSymbolTable(st, self._filename) - for st in self._table.children - if st.name == name] - - def get_children(self): - """Return a list of the nested symbol tables. - """ - return [_newSymbolTable(st, self._filename) - for st in self._table.children] - - -class Function(SymbolTable): - - # Default values for instance variables - __params = None - __locals = None - __frees = None - __globals = None - __nonlocals = None - - def __idents_matching(self, test_func): - return tuple(ident for ident in self.get_identifiers() - if test_func(self._table.symbols[ident])) - - def get_parameters(self): - """Return a tuple of parameters to the function. - """ - if self.__params is None: - self.__params = self.__idents_matching(lambda x:x & DEF_PARAM) - return self.__params - - def get_locals(self): - """Return a tuple of locals in the function. - """ - if self.__locals is None: - locs = (LOCAL, CELL) - test = lambda x: ((x >> SCOPE_OFF) & SCOPE_MASK) in locs - self.__locals = self.__idents_matching(test) - return self.__locals - - def get_globals(self): - """Return a tuple of globals in the function. - """ - if self.__globals is None: - glob = (GLOBAL_IMPLICIT, GLOBAL_EXPLICIT) - test = lambda x:((x >> SCOPE_OFF) & SCOPE_MASK) in glob - self.__globals = self.__idents_matching(test) - return self.__globals - - def get_nonlocals(self): - """Return a tuple of nonlocals in the function. - """ - if self.__nonlocals is None: - self.__nonlocals = self.__idents_matching(lambda x:x & DEF_NONLOCAL) - return self.__nonlocals - - def get_frees(self): - """Return a tuple of free variables in the function. - """ - if self.__frees is None: - is_free = lambda x:((x >> SCOPE_OFF) & SCOPE_MASK) == FREE - self.__frees = self.__idents_matching(is_free) - return self.__frees - - -class Class(SymbolTable): - - __methods = None - - def get_methods(self): - """Return a tuple of methods declared in the class. - """ - if self.__methods is None: - d = {} - for st in self._table.children: - d[st.name] = 1 - self.__methods = tuple(d) - return self.__methods - - -class Symbol: - - def __init__(self, name, flags, namespaces=None, *, module_scope=False): - self.__name = name - self.__flags = flags - self.__scope = (flags >> SCOPE_OFF) & SCOPE_MASK # like PyST_GetScope() - self.__namespaces = namespaces or () - self.__module_scope = module_scope - - def __repr__(self): - return "".format(self.__name) - - def get_name(self): - """Return a name of a symbol. - """ - return self.__name - - def is_referenced(self): - """Return *True* if the symbol is used in - its block. - """ - return bool(self.__flags & _symtable.USE) - - def is_parameter(self): - """Return *True* if the symbol is a parameter. - """ - return bool(self.__flags & DEF_PARAM) - - def is_global(self): - """Return *True* if the symbol is global. - """ - return bool(self.__scope in (GLOBAL_IMPLICIT, GLOBAL_EXPLICIT) - or (self.__module_scope and self.__flags & DEF_BOUND)) - - def is_nonlocal(self): - """Return *True* if the symbol is nonlocal.""" - return bool(self.__flags & DEF_NONLOCAL) - - def is_declared_global(self): - """Return *True* if the symbol is declared global - with a global statement.""" - return bool(self.__scope == GLOBAL_EXPLICIT) - - def is_local(self): - """Return *True* if the symbol is local. - """ - return bool(self.__scope in (LOCAL, CELL) - or (self.__module_scope and self.__flags & DEF_BOUND)) - - def is_annotated(self): - """Return *True* if the symbol is annotated. - """ - return bool(self.__flags & DEF_ANNOT) - - def is_free(self): - """Return *True* if a referenced symbol is - not assigned to. - """ - return bool(self.__scope == FREE) - - def is_imported(self): - """Return *True* if the symbol is created from - an import statement. - """ - return bool(self.__flags & DEF_IMPORT) - - def is_assigned(self): - """Return *True* if a symbol is assigned to.""" - return bool(self.__flags & DEF_LOCAL) - - def is_namespace(self): - """Returns *True* if name binding introduces new namespace. - - If the name is used as the target of a function or class - statement, this will be true. - - Note that a single name can be bound to multiple objects. If - is_namespace() is true, the name may also be bound to other - objects, like an int or list, that does not introduce a new - namespace. - """ - return bool(self.__namespaces) - - def get_namespaces(self): - """Return a list of namespaces bound to this name""" - return self.__namespaces - - def get_namespace(self): - """Return the single namespace bound to this name. - - Raises ValueError if the name is bound to multiple namespaces - or no namespace. - """ - if len(self.__namespaces) == 0: - raise ValueError("name is not bound to any namespaces") - elif len(self.__namespaces) > 1: - raise ValueError("name is bound to multiple namespaces") - else: - return self.__namespaces[0] - -if __name__ == "__main__": - import os, sys - with open(sys.argv[0]) as f: - src = f.read() - mod = symtable(src, os.path.split(sys.argv[0])[1], "exec") - for ident in mod.get_identifiers(): - info = mod.lookup(ident) - print(info, info.is_local(), info.is_namespace()) diff --git a/python/Lib/sysconfig.py b/python/Lib/sysconfig.py deleted file mode 100644 index d96d0d0..0000000 --- a/python/Lib/sysconfig.py +++ /dev/null @@ -1,851 +0,0 @@ -"""Access to Python's configuration information.""" - -import os -import sys -from os.path import pardir, realpath - -__all__ = [ - 'get_config_h_filename', - 'get_config_var', - 'get_config_vars', - 'get_makefile_filename', - 'get_path', - 'get_path_names', - 'get_paths', - 'get_platform', - 'get_python_version', - 'get_scheme_names', - 'parse_config_h', -] - -# Keys for get_config_var() that are never converted to Python integers. -_ALWAYS_STR = { - 'MACOSX_DEPLOYMENT_TARGET', -} - -_INSTALL_SCHEMES = { - 'posix_prefix': { - 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', - 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', - 'purelib': '{base}/lib/python{py_version_short}/site-packages', - 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', - 'include': - '{installed_base}/include/python{py_version_short}{abiflags}', - 'platinclude': - '{installed_platbase}/include/python{py_version_short}{abiflags}', - 'scripts': '{base}/bin', - 'data': '{base}', - }, - 'posix_home': { - 'stdlib': '{installed_base}/lib/python', - 'platstdlib': '{base}/lib/python', - 'purelib': '{base}/lib/python', - 'platlib': '{base}/lib/python', - 'include': '{installed_base}/include/python', - 'platinclude': '{installed_base}/include/python', - 'scripts': '{base}/bin', - 'data': '{base}', - }, - 'nt': { - 'stdlib': '{installed_base}/Lib', - 'platstdlib': '{base}/Lib', - 'purelib': '{base}/Lib/site-packages', - 'platlib': '{base}/Lib/site-packages', - 'include': '{installed_base}/Include', - 'platinclude': '{installed_base}/Include', - 'scripts': '{base}/Scripts', - 'data': '{base}', - }, - # Downstream distributors can overwrite the default install scheme. - # This is done to support downstream modifications where distributors change - # the installation layout (eg. different site-packages directory). - # So, distributors will change the default scheme to one that correctly - # represents their layout. - # This presents an issue for projects/people that need to bootstrap virtual - # environments, like virtualenv. As distributors might now be customizing - # the default install scheme, there is no guarantee that the information - # returned by sysconfig.get_default_scheme/get_paths is correct for - # a virtual environment, the only guarantee we have is that it is correct - # for the *current* environment. When bootstrapping a virtual environment, - # we need to know its layout, so that we can place the files in the - # correct locations. - # The "*_venv" install scheme is a scheme to bootstrap virtual environments, - # essentially identical to the default posix_prefix/nt schemes. - # Downstream distributors who patch posix_prefix/nt scheme are encouraged to - # leave the following schemes unchanged - 'posix_venv': { - 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', - 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', - 'purelib': '{base}/lib/python{py_version_short}/site-packages', - 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', - 'include': - '{installed_base}/include/python{py_version_short}{abiflags}', - 'platinclude': - '{installed_platbase}/include/python{py_version_short}{abiflags}', - 'scripts': '{base}/bin', - 'data': '{base}', - }, - 'nt_venv': { - 'stdlib': '{installed_base}/Lib', - 'platstdlib': '{base}/Lib', - 'purelib': '{base}/Lib/site-packages', - 'platlib': '{base}/Lib/site-packages', - 'include': '{installed_base}/Include', - 'platinclude': '{installed_base}/Include', - 'scripts': '{base}/Scripts', - 'data': '{base}', - }, - } - -# For the OS-native venv scheme, we essentially provide an alias: -if os.name == 'nt': - _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['nt_venv'] -else: - _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv'] - - -# NOTE: site.py has copy of this function. -# Sync it when modify this function. -def _getuserbase(): - env_base = os.environ.get("PYTHONUSERBASE", None) - if env_base: - return env_base - - # Emscripten, VxWorks, and WASI have no home directories - if sys.platform in {"emscripten", "vxworks", "wasi"}: - return None - - def joinuser(*args): - return os.path.expanduser(os.path.join(*args)) - - if os.name == "nt": - base = os.environ.get("APPDATA") or "~" - return joinuser(base, "Python") - - if sys.platform == "darwin" and sys._framework: - return joinuser("~", "Library", sys._framework, - f"{sys.version_info[0]}.{sys.version_info[1]}") - - return joinuser("~", ".local") - -_HAS_USER_BASE = (_getuserbase() is not None) - -if _HAS_USER_BASE: - _INSTALL_SCHEMES |= { - # NOTE: When modifying "purelib" scheme, update site._get_path() too. - 'nt_user': { - 'stdlib': '{userbase}/Python{py_version_nodot_plat}', - 'platstdlib': '{userbase}/Python{py_version_nodot_plat}', - 'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages', - 'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages', - 'include': '{userbase}/Python{py_version_nodot_plat}/Include', - 'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts', - 'data': '{userbase}', - }, - 'posix_user': { - 'stdlib': '{userbase}/{platlibdir}/python{py_version_short}', - 'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}', - 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', - 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', - 'include': '{userbase}/include/python{py_version_short}', - 'scripts': '{userbase}/bin', - 'data': '{userbase}', - }, - 'osx_framework_user': { - 'stdlib': '{userbase}/lib/python', - 'platstdlib': '{userbase}/lib/python', - 'purelib': '{userbase}/lib/python/site-packages', - 'platlib': '{userbase}/lib/python/site-packages', - 'include': '{userbase}/include/python{py_version_short}', - 'scripts': '{userbase}/bin', - 'data': '{userbase}', - }, - } - -_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', - 'scripts', 'data') - -_PY_VERSION = sys.version.split()[0] -_PY_VERSION_SHORT = f'{sys.version_info[0]}.{sys.version_info[1]}' -_PY_VERSION_SHORT_NO_DOT = f'{sys.version_info[0]}{sys.version_info[1]}' -_PREFIX = os.path.normpath(sys.prefix) -_BASE_PREFIX = os.path.normpath(sys.base_prefix) -_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) -_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) -_CONFIG_VARS = None -_USER_BASE = None - -# Regexes needed for parsing Makefile (and similar syntaxes, -# like old-style Setup files). -_variable_rx = r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)" -_findvar1_rx = r"\$\(([A-Za-z][A-Za-z0-9_]*)\)" -_findvar2_rx = r"\${([A-Za-z][A-Za-z0-9_]*)}" - - -def _safe_realpath(path): - try: - return realpath(path) - except OSError: - return path - -if sys.executable: - _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) -else: - # sys.executable can be empty if argv[0] has been changed and Python is - # unable to retrieve the real program name - _PROJECT_BASE = _safe_realpath(os.getcwd()) - -# In a virtual environment, `sys._home` gives us the target directory -# `_PROJECT_BASE` for the executable that created it when the virtual -# python is an actual executable ('venv --copies' or Windows). -_sys_home = getattr(sys, '_home', None) -if _sys_home: - _PROJECT_BASE = _sys_home - -if os.name == 'nt': - # In a source build, the executable is in a subdirectory of the root - # that we want (\PCbuild\). - # `_BASE_PREFIX` is used as the base installation is where the source - # will be. The realpath is needed to prevent mount point confusion - # that can occur with just string comparisons. - if _safe_realpath(_PROJECT_BASE).startswith( - _safe_realpath(f'{_BASE_PREFIX}\\PCbuild')): - _PROJECT_BASE = _BASE_PREFIX - -# set for cross builds -if "_PYTHON_PROJECT_BASE" in os.environ: - _PROJECT_BASE = _safe_realpath(os.environ["_PYTHON_PROJECT_BASE"]) - -def is_python_build(check_home=None): - if check_home is not None: - import warnings - warnings.warn("check_home argument is deprecated and ignored.", - DeprecationWarning, stacklevel=2) - for fn in ("Setup", "Setup.local"): - if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): - return True - return False - -_PYTHON_BUILD = is_python_build() - -if _PYTHON_BUILD: - for scheme in ('posix_prefix', 'posix_home'): - # On POSIX-y platforms, Python will: - # - Build from .h files in 'headers' (which is only added to the - # scheme when building CPython) - # - Install .h files to 'include' - scheme = _INSTALL_SCHEMES[scheme] - scheme['headers'] = scheme['include'] - scheme['include'] = '{srcdir}/Include' - scheme['platinclude'] = '{projectbase}/.' - del scheme - - -def _subst_vars(s, local_vars): - try: - return s.format(**local_vars) - except KeyError as var: - try: - return s.format(**os.environ) - except KeyError: - raise AttributeError(f'{var}') from None - -def _extend_dict(target_dict, other_dict): - target_keys = target_dict.keys() - for key, value in other_dict.items(): - if key in target_keys: - continue - target_dict[key] = value - - -def _expand_vars(scheme, vars): - res = {} - if vars is None: - vars = {} - _extend_dict(vars, get_config_vars()) - if os.name == 'nt': - # On Windows we want to substitute 'lib' for schemes rather - # than the native value (without modifying vars, in case it - # was passed in) - vars = vars | {'platlibdir': 'lib'} - - for key, value in _INSTALL_SCHEMES[scheme].items(): - if os.name in ('posix', 'nt'): - value = os.path.expanduser(value) - res[key] = os.path.normpath(_subst_vars(value, vars)) - return res - - -def _get_preferred_schemes(): - if os.name == 'nt': - return { - 'prefix': 'nt', - 'home': 'posix_home', - 'user': 'nt_user', - } - if sys.platform == 'darwin' and sys._framework: - return { - 'prefix': 'posix_prefix', - 'home': 'posix_home', - 'user': 'osx_framework_user', - } - return { - 'prefix': 'posix_prefix', - 'home': 'posix_home', - 'user': 'posix_user', - } - - -def get_preferred_scheme(key): - if key == 'prefix' and sys.prefix != sys.base_prefix: - return 'venv' - scheme = _get_preferred_schemes()[key] - if scheme not in _INSTALL_SCHEMES: - raise ValueError( - f"{key!r} returned {scheme!r}, which is not a valid scheme " - f"on this platform" - ) - return scheme - - -def get_default_scheme(): - return get_preferred_scheme('prefix') - - -def _parse_makefile(filename, vars=None, keep_unresolved=True): - """Parse a Makefile-style file. - - A dictionary containing name/value pairs is returned. If an - optional dictionary is passed in as the second argument, it is - used instead of a new dictionary. - """ - import re - - if vars is None: - vars = {} - done = {} - notdone = {} - - with open(filename, encoding=sys.getfilesystemencoding(), - errors="surrogateescape") as f: - lines = f.readlines() - - for line in lines: - if line.startswith('#') or line.strip() == '': - continue - m = re.match(_variable_rx, line) - if m: - n, v = m.group(1, 2) - v = v.strip() - # `$$' is a literal `$' in make - tmpv = v.replace('$$', '') - - if "$" in tmpv: - notdone[n] = v - else: - try: - if n in _ALWAYS_STR: - raise ValueError - - v = int(v) - except ValueError: - # insert literal `$' - done[n] = v.replace('$$', '$') - else: - done[n] = v - - # do variable interpolation here - variables = list(notdone.keys()) - - # Variables with a 'PY_' prefix in the makefile. These need to - # be made available without that prefix through sysconfig. - # Special care is needed to ensure that variable expansion works, even - # if the expansion uses the name without a prefix. - renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') - - while len(variables) > 0: - for name in tuple(variables): - value = notdone[name] - m1 = re.search(_findvar1_rx, value) - m2 = re.search(_findvar2_rx, value) - if m1 and m2: - m = m1 if m1.start() < m2.start() else m2 - else: - m = m1 if m1 else m2 - if m is not None: - n = m.group(1) - found = True - if n in done: - item = str(done[n]) - elif n in notdone: - # get it on a subsequent round - found = False - elif n in os.environ: - # do it like make: fall back to environment - item = os.environ[n] - - elif n in renamed_variables: - if (name.startswith('PY_') and - name[3:] in renamed_variables): - item = "" - - elif 'PY_' + n in notdone: - found = False - - else: - item = str(done['PY_' + n]) - - else: - done[n] = item = "" - - if found: - after = value[m.end():] - value = value[:m.start()] + item + after - if "$" in after: - notdone[name] = value - else: - try: - if name in _ALWAYS_STR: - raise ValueError - value = int(value) - except ValueError: - done[name] = value.strip() - else: - done[name] = value - variables.remove(name) - - if name.startswith('PY_') \ - and name[3:] in renamed_variables: - - name = name[3:] - if name not in done: - done[name] = value - - else: - # Adds unresolved variables to the done dict. - # This is disabled when called from distutils.sysconfig - if keep_unresolved: - done[name] = value - # bogus variable reference (e.g. "prefix=$/opt/python"); - # just drop it since we can't deal - variables.remove(name) - - # strip spurious spaces - for k, v in done.items(): - if isinstance(v, str): - done[k] = v.strip() - - # save the results in the global dictionary - vars.update(done) - return vars - - -def get_makefile_filename(): - """Return the path of the Makefile.""" - if _PYTHON_BUILD: - return os.path.join(_PROJECT_BASE, "Makefile") - if hasattr(sys, 'abiflags'): - config_dir_name = f'config-{_PY_VERSION_SHORT}{sys.abiflags}' - else: - config_dir_name = 'config' - if hasattr(sys.implementation, '_multiarch'): - config_dir_name += f'-{sys.implementation._multiarch}' - return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') - - -def _get_sysconfigdata_name(): - multiarch = getattr(sys.implementation, '_multiarch', '') - return os.environ.get( - '_PYTHON_SYSCONFIGDATA_NAME', - f'_sysconfigdata_{sys.abiflags}_{sys.platform}_{multiarch}', - ) - - -def _generate_posix_vars(): - """Generate the Python module containing build-time variables.""" - import pprint - vars = {} - # load the installed Makefile: - makefile = get_makefile_filename() - try: - _parse_makefile(makefile, vars) - except OSError as e: - msg = f"invalid Python installation: unable to open {makefile}" - if hasattr(e, "strerror"): - msg = f"{msg} ({e.strerror})" - raise OSError(msg) - # load the installed pyconfig.h: - config_h = get_config_h_filename() - try: - with open(config_h, encoding="utf-8") as f: - parse_config_h(f, vars) - except OSError as e: - msg = f"invalid Python installation: unable to open {config_h}" - if hasattr(e, "strerror"): - msg = f"{msg} ({e.strerror})" - raise OSError(msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile - # -- these paths are relative to the Python source, but when installed - # the scripts are in another directory. - if _PYTHON_BUILD: - vars['BLDSHARED'] = vars['LDSHARED'] - - # There's a chicken-and-egg situation on OS X with regards to the - # _sysconfigdata module after the changes introduced by #15298: - # get_config_vars() is called by get_platform() as part of the - # `make pybuilddir.txt` target -- which is a precursor to the - # _sysconfigdata.py module being constructed. Unfortunately, - # get_config_vars() eventually calls _init_posix(), which attempts - # to import _sysconfigdata, which we won't have built yet. In order - # for _init_posix() to work, if we're on Darwin, just mock up the - # _sysconfigdata module manually and populate it with the build vars. - # This is more than sufficient for ensuring the subsequent call to - # get_platform() succeeds. - name = _get_sysconfigdata_name() - if 'darwin' in sys.platform: - import types - module = types.ModuleType(name) - module.build_time_vars = vars - sys.modules[name] = module - - pybuilddir = f'build/lib.{get_platform()}-{_PY_VERSION_SHORT}' - if hasattr(sys, "gettotalrefcount"): - pybuilddir += '-pydebug' - os.makedirs(pybuilddir, exist_ok=True) - destfile = os.path.join(pybuilddir, name + '.py') - - with open(destfile, 'w', encoding='utf8') as f: - f.write('# system configuration generated and used by' - ' the sysconfig module\n') - f.write('build_time_vars = ') - pprint.pprint(vars, stream=f) - - # Create file used for sys.path fixup -- see Modules/getpath.c - with open('pybuilddir.txt', 'w', encoding='utf8') as f: - f.write(pybuilddir) - -def _init_posix(vars): - """Initialize the module as appropriate for POSIX systems.""" - # _sysconfigdata is generated at build time, see _generate_posix_vars() - name = _get_sysconfigdata_name() - _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) - build_time_vars = _temp.build_time_vars - vars.update(build_time_vars) - -def _init_non_posix(vars): - """Initialize the module as appropriate for NT""" - # set basic install directories - import _imp - vars['LIBDEST'] = get_path('stdlib') - vars['BINLIBDEST'] = get_path('platstdlib') - vars['INCLUDEPY'] = get_path('include') - vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0] - vars['EXE'] = '.exe' - vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT - vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) - vars['TZPATH'] = '' - -# -# public APIs -# - - -def parse_config_h(fp, vars=None): - """Parse a config.h-style file. - - A dictionary containing name/value pairs is returned. If an - optional dictionary is passed in as the second argument, it is - used instead of a new dictionary. - """ - if vars is None: - vars = {} - import re - define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") - undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") - - while True: - line = fp.readline() - if not line: - break - m = define_rx.match(line) - if m: - n, v = m.group(1, 2) - try: - if n in _ALWAYS_STR: - raise ValueError - v = int(v) - except ValueError: - pass - vars[n] = v - else: - m = undef_rx.match(line) - if m: - vars[m.group(1)] = 0 - return vars - - -def get_config_h_filename(): - """Return the path of pyconfig.h.""" - if _PYTHON_BUILD: - if os.name == "nt": - inc_dir = os.path.join(_PROJECT_BASE, "PC") - else: - inc_dir = _PROJECT_BASE - else: - inc_dir = get_path('platinclude') - return os.path.join(inc_dir, 'pyconfig.h') - - -def get_scheme_names(): - """Return a tuple containing the schemes names.""" - return tuple(sorted(_INSTALL_SCHEMES)) - - -def get_path_names(): - """Return a tuple containing the paths names.""" - return _SCHEME_KEYS - - -def get_paths(scheme=get_default_scheme(), vars=None, expand=True): - """Return a mapping containing an install scheme. - - ``scheme`` is the install scheme name. If not provided, it will - return the default scheme for the current platform. - """ - if expand: - return _expand_vars(scheme, vars) - else: - return _INSTALL_SCHEMES[scheme] - - -def get_path(name, scheme=get_default_scheme(), vars=None, expand=True): - """Return a path corresponding to the scheme. - - ``scheme`` is the install scheme name. - """ - return get_paths(scheme, vars, expand)[name] - - -def get_config_vars(*args): - """With no arguments, return a dictionary of all configuration - variables relevant for the current platform. - - On Unix, this means every variable defined in Python's installed Makefile; - On Windows it's a much smaller set. - - With arguments, return a list of values that result from looking up - each argument in the configuration variable dictionary. - """ - global _CONFIG_VARS - if _CONFIG_VARS is None: - _CONFIG_VARS = {} - # Normalized versions of prefix and exec_prefix are handy to have; - # in fact, these are the standard versions used most places in the - # Distutils. - _CONFIG_VARS['prefix'] = _PREFIX - _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX - _CONFIG_VARS['py_version'] = _PY_VERSION - _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT - _CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT - _CONFIG_VARS['installed_base'] = _BASE_PREFIX - _CONFIG_VARS['base'] = _PREFIX - _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX - _CONFIG_VARS['platbase'] = _EXEC_PREFIX - _CONFIG_VARS['projectbase'] = _PROJECT_BASE - _CONFIG_VARS['platlibdir'] = sys.platlibdir - try: - _CONFIG_VARS['abiflags'] = sys.abiflags - except AttributeError: - # sys.abiflags may not be defined on all platforms. - _CONFIG_VARS['abiflags'] = '' - try: - _CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '') - except AttributeError: - _CONFIG_VARS['py_version_nodot_plat'] = '' - - if os.name == 'nt': - _init_non_posix(_CONFIG_VARS) - _CONFIG_VARS['VPATH'] = sys._vpath - if os.name == 'posix': - _init_posix(_CONFIG_VARS) - if _HAS_USER_BASE: - # Setting 'userbase' is done below the call to the - # init function to enable using 'get_config_var' in - # the init-function. - _CONFIG_VARS['userbase'] = _getuserbase() - - # Always convert srcdir to an absolute path - srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) - if os.name == 'posix': - if _PYTHON_BUILD: - # If srcdir is a relative path (typically '.' or '..') - # then it should be interpreted relative to the directory - # containing Makefile. - base = os.path.dirname(get_makefile_filename()) - srcdir = os.path.join(base, srcdir) - else: - # srcdir is not meaningful since the installation is - # spread about the filesystem. We choose the - # directory containing the Makefile since we know it - # exists. - srcdir = os.path.dirname(get_makefile_filename()) - _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir) - - # OS X platforms require special customization to handle - # multi-architecture, multi-os-version installers - if sys.platform == 'darwin': - import _osx_support - _osx_support.customize_config_vars(_CONFIG_VARS) - - if args: - vals = [] - for name in args: - vals.append(_CONFIG_VARS.get(name)) - return vals - else: - return _CONFIG_VARS - - -def get_config_var(name): - """Return the value of a single variable using the dictionary returned by - 'get_config_vars()'. - - Equivalent to get_config_vars().get(name) - """ - return get_config_vars().get(name) - - -def get_platform(): - """Return a string that identifies the current platform. - - This is used mainly to distinguish platform-specific build directories and - platform-specific built distributions. Typically includes the OS name and - version and the architecture (as supplied by 'os.uname()'), although the - exact information included depends on the OS; on Linux, the kernel version - isn't particularly important. - - Examples of returned values: - linux-i586 - linux-alpha (?) - solaris-2.6-sun4u - - Windows will return one of: - win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) - win32 (all others - specifically, sys.platform is returned) - - For other non-POSIX platforms, currently just returns 'sys.platform'. - - """ - if os.name == 'nt': - if 'amd64' in sys.version.lower(): - return 'win-amd64' - if '(arm)' in sys.version.lower(): - return 'win-arm32' - if '(arm64)' in sys.version.lower(): - return 'win-arm64' - return sys.platform - - if os.name != "posix" or not hasattr(os, 'uname'): - # XXX what about the architecture? NT is Intel or Alpha - return sys.platform - - # Set for cross builds explicitly - if "_PYTHON_HOST_PLATFORM" in os.environ: - return os.environ["_PYTHON_HOST_PLATFORM"] - - # Try to distinguish various flavours of Unix - osname, host, release, version, machine = os.uname() - - # Convert the OS name to lowercase, remove '/' characters, and translate - # spaces (for "Power Macintosh") - osname = osname.lower().replace('/', '') - machine = machine.replace(' ', '_') - machine = machine.replace('/', '-') - - if osname[:5] == "linux": - # At least on Linux/Intel, 'machine' is the processor -- - # i386, etc. - # XXX what about Alpha, SPARC, etc? - return f"{osname}-{machine}" - elif osname[:5] == "sunos": - if release[0] >= "5": # SunOS 5 == Solaris 2 - osname = "solaris" - release = f"{int(release[0]) - 3}.{release[2:]}" - # We can't use "platform.architecture()[0]" because a - # bootstrap problem. We use a dict to get an error - # if some suspicious happens. - bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} - machine += f".{bitness[sys.maxsize]}" - # fall through to standard osname-release-machine representation - elif osname[:3] == "aix": - from _aix_support import aix_platform - return aix_platform() - elif osname[:6] == "cygwin": - osname = "cygwin" - import re - rel_re = re.compile(r'[\d.]+') - m = rel_re.match(release) - if m: - release = m.group() - elif osname[:6] == "darwin": - import _osx_support - osname, release, machine = _osx_support.get_platform_osx( - get_config_vars(), - osname, release, machine) - - return f"{osname}-{release}-{machine}" - - -def get_python_version(): - return _PY_VERSION_SHORT - - -def expand_makefile_vars(s, vars): - """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in - 'string' according to 'vars' (a dictionary mapping variable names to - values). Variables not present in 'vars' are silently expanded to the - empty string. The variable values in 'vars' should not contain further - variable expansions; if 'vars' is the output of 'parse_makefile()', - you're fine. Returns a variable-expanded version of 's'. - """ - import re - - # This algorithm does multiple expansion, so if vars['foo'] contains - # "${bar}", it will expand ${foo} to ${bar}, and then expand - # ${bar}... and so forth. This is fine as long as 'vars' comes from - # 'parse_makefile()', which takes care of such expansions eagerly, - # according to make's variable expansion semantics. - - while True: - m = re.search(_findvar1_rx, s) or re.search(_findvar2_rx, s) - if m: - (beg, end) = m.span() - s = s[0:beg] + vars.get(m.group(1)) + s[end:] - else: - break - return s - - -def _print_dict(title, data): - for index, (key, value) in enumerate(sorted(data.items())): - if index == 0: - print(f'{title}: ') - print(f'\t{key} = "{value}"') - - -def _main(): - """Display all information sysconfig detains.""" - if '--generate-posix-vars' in sys.argv: - _generate_posix_vars() - return - print(f'Platform: "{get_platform()}"') - print(f'Python version: "{get_python_version()}"') - print(f'Current installation scheme: "{get_default_scheme()}"') - print() - _print_dict('Paths', get_paths()) - print() - _print_dict('Variables', get_config_vars()) - - -if __name__ == '__main__': - _main() diff --git a/python/Lib/tabnanny.py b/python/Lib/tabnanny.py deleted file mode 100644 index 974cfd1..0000000 --- a/python/Lib/tabnanny.py +++ /dev/null @@ -1,331 +0,0 @@ -#! /usr/bin/env python3 - -"""The Tab Nanny despises ambiguous indentation. She knows no mercy. - -tabnanny -- Detection of ambiguous indentation - -For the time being this module is intended to be called as a script. -However it is possible to import it into an IDE and use the function -check() described below. - -Warning: The API provided by this module is likely to change in future -releases; such changes may not be backward compatible. -""" - -# Released to the public domain, by Tim Peters, 15 April 1998. - -# XXX Note: this is now a standard library module. -# XXX The API needs to undergo changes however; the current code is too -# XXX script-like. This will be addressed later. - -__version__ = "6" - -import os -import sys -import tokenize - -__all__ = ["check", "NannyNag", "process_tokens"] - -verbose = 0 -filename_only = 0 - -def errprint(*args): - sep = "" - for arg in args: - sys.stderr.write(sep + str(arg)) - sep = " " - sys.stderr.write("\n") - -def main(): - import getopt - - global verbose, filename_only - try: - opts, args = getopt.getopt(sys.argv[1:], "qv") - except getopt.error as msg: - errprint(msg) - return - for o, a in opts: - if o == '-q': - filename_only = filename_only + 1 - if o == '-v': - verbose = verbose + 1 - if not args: - errprint("Usage:", sys.argv[0], "[-v] file_or_directory ...") - return - for arg in args: - check(arg) - -class NannyNag(Exception): - """ - Raised by process_tokens() if detecting an ambiguous indent. - Captured and handled in check(). - """ - def __init__(self, lineno, msg, line): - self.lineno, self.msg, self.line = lineno, msg, line - def get_lineno(self): - return self.lineno - def get_msg(self): - return self.msg - def get_line(self): - return self.line - -def check(file): - """check(file_or_dir) - - If file_or_dir is a directory and not a symbolic link, then recursively - descend the directory tree named by file_or_dir, checking all .py files - along the way. If file_or_dir is an ordinary Python source file, it is - checked for whitespace related problems. The diagnostic messages are - written to standard output using the print statement. - """ - - if os.path.isdir(file) and not os.path.islink(file): - if verbose: - print("%r: listing directory" % (file,)) - names = os.listdir(file) - for name in names: - fullname = os.path.join(file, name) - if (os.path.isdir(fullname) and - not os.path.islink(fullname) or - os.path.normcase(name[-3:]) == ".py"): - check(fullname) - return - - try: - f = tokenize.open(file) - except OSError as msg: - errprint("%r: I/O Error: %s" % (file, msg)) - return - - if verbose > 1: - print("checking %r ..." % file) - - try: - process_tokens(tokenize.generate_tokens(f.readline)) - - except tokenize.TokenError as msg: - errprint("%r: Token Error: %s" % (file, msg)) - return - - except IndentationError as msg: - errprint("%r: Indentation Error: %s" % (file, msg)) - return - - except NannyNag as nag: - badline = nag.get_lineno() - line = nag.get_line() - if verbose: - print("%r: *** Line %d: trouble in tab city! ***" % (file, badline)) - print("offending line: %r" % (line,)) - print(nag.get_msg()) - else: - if ' ' in file: file = '"' + file + '"' - if filename_only: print(file) - else: print(file, badline, repr(line)) - return - - finally: - f.close() - - if verbose: - print("%r: Clean bill of health." % (file,)) - -class Whitespace: - # the characters used for space and tab - S, T = ' \t' - - # members: - # raw - # the original string - # n - # the number of leading whitespace characters in raw - # nt - # the number of tabs in raw[:n] - # norm - # the normal form as a pair (count, trailing), where: - # count - # a tuple such that raw[:n] contains count[i] - # instances of S * i + T - # trailing - # the number of trailing spaces in raw[:n] - # It's A Theorem that m.indent_level(t) == - # n.indent_level(t) for all t >= 1 iff m.norm == n.norm. - # is_simple - # true iff raw[:n] is of the form (T*)(S*) - - def __init__(self, ws): - self.raw = ws - S, T = Whitespace.S, Whitespace.T - count = [] - b = n = nt = 0 - for ch in self.raw: - if ch == S: - n = n + 1 - b = b + 1 - elif ch == T: - n = n + 1 - nt = nt + 1 - if b >= len(count): - count = count + [0] * (b - len(count) + 1) - count[b] = count[b] + 1 - b = 0 - else: - break - self.n = n - self.nt = nt - self.norm = tuple(count), b - self.is_simple = len(count) <= 1 - - # return length of longest contiguous run of spaces (whether or not - # preceding a tab) - def longest_run_of_spaces(self): - count, trailing = self.norm - return max(len(count)-1, trailing) - - def indent_level(self, tabsize): - # count, il = self.norm - # for i in range(len(count)): - # if count[i]: - # il = il + (i//tabsize + 1)*tabsize * count[i] - # return il - - # quicker: - # il = trailing + sum (i//ts + 1)*ts*count[i] = - # trailing + ts * sum (i//ts + 1)*count[i] = - # trailing + ts * sum i//ts*count[i] + count[i] = - # trailing + ts * [(sum i//ts*count[i]) + (sum count[i])] = - # trailing + ts * [(sum i//ts*count[i]) + num_tabs] - # and note that i//ts*count[i] is 0 when i < ts - - count, trailing = self.norm - il = 0 - for i in range(tabsize, len(count)): - il = il + i//tabsize * count[i] - return trailing + tabsize * (il + self.nt) - - # return true iff self.indent_level(t) == other.indent_level(t) - # for all t >= 1 - def equal(self, other): - return self.norm == other.norm - - # return a list of tuples (ts, i1, i2) such that - # i1 == self.indent_level(ts) != other.indent_level(ts) == i2. - # Intended to be used after not self.equal(other) is known, in which - # case it will return at least one witnessing tab size. - def not_equal_witness(self, other): - n = max(self.longest_run_of_spaces(), - other.longest_run_of_spaces()) + 1 - a = [] - for ts in range(1, n+1): - if self.indent_level(ts) != other.indent_level(ts): - a.append( (ts, - self.indent_level(ts), - other.indent_level(ts)) ) - return a - - # Return True iff self.indent_level(t) < other.indent_level(t) - # for all t >= 1. - # The algorithm is due to Vincent Broman. - # Easy to prove it's correct. - # XXXpost that. - # Trivial to prove n is sharp (consider T vs ST). - # Unknown whether there's a faster general way. I suspected so at - # first, but no longer. - # For the special (but common!) case where M and N are both of the - # form (T*)(S*), M.less(N) iff M.len() < N.len() and - # M.num_tabs() <= N.num_tabs(). Proof is easy but kinda long-winded. - # XXXwrite that up. - # Note that M is of the form (T*)(S*) iff len(M.norm[0]) <= 1. - def less(self, other): - if self.n >= other.n: - return False - if self.is_simple and other.is_simple: - return self.nt <= other.nt - n = max(self.longest_run_of_spaces(), - other.longest_run_of_spaces()) + 1 - # the self.n >= other.n test already did it for ts=1 - for ts in range(2, n+1): - if self.indent_level(ts) >= other.indent_level(ts): - return False - return True - - # return a list of tuples (ts, i1, i2) such that - # i1 == self.indent_level(ts) >= other.indent_level(ts) == i2. - # Intended to be used after not self.less(other) is known, in which - # case it will return at least one witnessing tab size. - def not_less_witness(self, other): - n = max(self.longest_run_of_spaces(), - other.longest_run_of_spaces()) + 1 - a = [] - for ts in range(1, n+1): - if self.indent_level(ts) >= other.indent_level(ts): - a.append( (ts, - self.indent_level(ts), - other.indent_level(ts)) ) - return a - -def format_witnesses(w): - firsts = (str(tup[0]) for tup in w) - prefix = "at tab size" - if len(w) > 1: - prefix = prefix + "s" - return prefix + " " + ', '.join(firsts) - -def process_tokens(tokens): - INDENT = tokenize.INDENT - DEDENT = tokenize.DEDENT - NEWLINE = tokenize.NEWLINE - JUNK = tokenize.COMMENT, tokenize.NL - indents = [Whitespace("")] - check_equal = 0 - - for (type, token, start, end, line) in tokens: - if type == NEWLINE: - # a program statement, or ENDMARKER, will eventually follow, - # after some (possibly empty) run of tokens of the form - # (NL | COMMENT)* (INDENT | DEDENT+)? - # If an INDENT appears, setting check_equal is wrong, and will - # be undone when we see the INDENT. - check_equal = 1 - - elif type == INDENT: - check_equal = 0 - thisguy = Whitespace(token) - if not indents[-1].less(thisguy): - witness = indents[-1].not_less_witness(thisguy) - msg = "indent not greater e.g. " + format_witnesses(witness) - raise NannyNag(start[0], msg, line) - indents.append(thisguy) - - elif type == DEDENT: - # there's nothing we need to check here! what's important is - # that when the run of DEDENTs ends, the indentation of the - # program statement (or ENDMARKER) that triggered the run is - # equal to what's left at the top of the indents stack - - # Ouch! This assert triggers if the last line of the source - # is indented *and* lacks a newline -- then DEDENTs pop out - # of thin air. - # assert check_equal # else no earlier NEWLINE, or an earlier INDENT - check_equal = 1 - - del indents[-1] - - elif check_equal and type not in JUNK: - # this is the first "real token" following a NEWLINE, so it - # must be the first token of the next program statement, or an - # ENDMARKER; the "line" argument exposes the leading whitespace - # for this statement; in the case of ENDMARKER, line is an empty - # string, so will properly match the empty string with which the - # "indents" stack was seeded - check_equal = 0 - thisguy = Whitespace(line) - if not indents[-1].equal(thisguy): - witness = indents[-1].not_equal_witness(thisguy) - msg = "indent not equal e.g. " + format_witnesses(witness) - raise NannyNag(start[0], msg, line) - - -if __name__ == '__main__': - main() diff --git a/python/Lib/tarfile.py b/python/Lib/tarfile.py deleted file mode 100644 index d19fb6d..0000000 --- a/python/Lib/tarfile.py +++ /dev/null @@ -1,2618 +0,0 @@ -#!/usr/bin/env python3 -#------------------------------------------------------------------- -# tarfile.py -#------------------------------------------------------------------- -# Copyright (C) 2002 Lars Gustaebel -# All rights reserved. -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following -# conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -"""Read from and write to tar format archives. -""" - -version = "0.9.0" -__author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)" -__credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend." - -#--------- -# Imports -#--------- -from builtins import open as bltn_open -import sys -import os -import io -import shutil -import stat -import time -import struct -import copy -import re - -try: - import pwd -except ImportError: - pwd = None -try: - import grp -except ImportError: - grp = None - -# os.symlink on Windows prior to 6.0 raises NotImplementedError -symlink_exception = (AttributeError, NotImplementedError) -try: - # OSError (winerror=1314) will be raised if the caller does not hold the - # SeCreateSymbolicLinkPrivilege privilege - symlink_exception += (OSError,) -except NameError: - pass - -# from tarfile import * -__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError", "ReadError", - "CompressionError", "StreamError", "ExtractError", "HeaderError", - "ENCODING", "USTAR_FORMAT", "GNU_FORMAT", "PAX_FORMAT", - "DEFAULT_FORMAT", "open"] - -#--------------------------------------------------------- -# tar constants -#--------------------------------------------------------- -NUL = b"\0" # the null character -BLOCKSIZE = 512 # length of processing blocks -RECORDSIZE = BLOCKSIZE * 20 # length of records -GNU_MAGIC = b"ustar \0" # magic gnu tar string -POSIX_MAGIC = b"ustar\x0000" # magic posix tar string - -LENGTH_NAME = 100 # maximum length of a filename -LENGTH_LINK = 100 # maximum length of a linkname -LENGTH_PREFIX = 155 # maximum length of the prefix field - -REGTYPE = b"0" # regular file -AREGTYPE = b"\0" # regular file -LNKTYPE = b"1" # link (inside tarfile) -SYMTYPE = b"2" # symbolic link -CHRTYPE = b"3" # character special device -BLKTYPE = b"4" # block special device -DIRTYPE = b"5" # directory -FIFOTYPE = b"6" # fifo special device -CONTTYPE = b"7" # contiguous file - -GNUTYPE_LONGNAME = b"L" # GNU tar longname -GNUTYPE_LONGLINK = b"K" # GNU tar longlink -GNUTYPE_SPARSE = b"S" # GNU tar sparse file - -XHDTYPE = b"x" # POSIX.1-2001 extended header -XGLTYPE = b"g" # POSIX.1-2001 global header -SOLARIS_XHDTYPE = b"X" # Solaris extended header - -USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format -GNU_FORMAT = 1 # GNU tar format -PAX_FORMAT = 2 # POSIX.1-2001 (pax) format -DEFAULT_FORMAT = PAX_FORMAT - -#--------------------------------------------------------- -# tarfile constants -#--------------------------------------------------------- -# File types that tarfile supports: -SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE, - SYMTYPE, DIRTYPE, FIFOTYPE, - CONTTYPE, CHRTYPE, BLKTYPE, - GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, - GNUTYPE_SPARSE) - -# File types that will be treated as a regular file. -REGULAR_TYPES = (REGTYPE, AREGTYPE, - CONTTYPE, GNUTYPE_SPARSE) - -# File types that are part of the GNU tar format. -GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, - GNUTYPE_SPARSE) - -# Fields from a pax header that override a TarInfo attribute. -PAX_FIELDS = ("path", "linkpath", "size", "mtime", - "uid", "gid", "uname", "gname") - -# Fields from a pax header that are affected by hdrcharset. -PAX_NAME_FIELDS = {"path", "linkpath", "uname", "gname"} - -# Fields in a pax header that are numbers, all other fields -# are treated as strings. -PAX_NUMBER_FIELDS = { - "atime": float, - "ctime": float, - "mtime": float, - "uid": int, - "gid": int, - "size": int -} - -#--------------------------------------------------------- -# initialization -#--------------------------------------------------------- -if os.name == "nt": - ENCODING = "utf-8" -else: - ENCODING = sys.getfilesystemencoding() - -#--------------------------------------------------------- -# Some useful functions -#--------------------------------------------------------- - -def stn(s, length, encoding, errors): - """Convert a string to a null-terminated bytes object. - """ - s = s.encode(encoding, errors) - return s[:length] + (length - len(s)) * NUL - -def nts(s, encoding, errors): - """Convert a null-terminated bytes object to a string. - """ - p = s.find(b"\0") - if p != -1: - s = s[:p] - return s.decode(encoding, errors) - -def nti(s): - """Convert a number field to a python number. - """ - # There are two possible encodings for a number field, see - # itn() below. - if s[0] in (0o200, 0o377): - n = 0 - for i in range(len(s) - 1): - n <<= 8 - n += s[i + 1] - if s[0] == 0o377: - n = -(256 ** (len(s) - 1) - n) - else: - try: - s = nts(s, "ascii", "strict") - n = int(s.strip() or "0", 8) - except ValueError: - raise InvalidHeaderError("invalid header") - return n - -def itn(n, digits=8, format=DEFAULT_FORMAT): - """Convert a python number to a number field. - """ - # POSIX 1003.1-1988 requires numbers to be encoded as a string of - # octal digits followed by a null-byte, this allows values up to - # (8**(digits-1))-1. GNU tar allows storing numbers greater than - # that if necessary. A leading 0o200 or 0o377 byte indicate this - # particular encoding, the following digits-1 bytes are a big-endian - # base-256 representation. This allows values up to (256**(digits-1))-1. - # A 0o200 byte indicates a positive number, a 0o377 byte a negative - # number. - original_n = n - n = int(n) - if 0 <= n < 8 ** (digits - 1): - s = bytes("%0*o" % (digits - 1, n), "ascii") + NUL - elif format == GNU_FORMAT and -256 ** (digits - 1) <= n < 256 ** (digits - 1): - if n >= 0: - s = bytearray([0o200]) - else: - s = bytearray([0o377]) - n = 256 ** digits + n - - for i in range(digits - 1): - s.insert(1, n & 0o377) - n >>= 8 - else: - raise ValueError("overflow in number field") - - return s - -def calc_chksums(buf): - """Calculate the checksum for a member's header by summing up all - characters except for the chksum field which is treated as if - it was filled with spaces. According to the GNU tar sources, - some tars (Sun and NeXT) calculate chksum with signed char, - which will be different if there are chars in the buffer with - the high bit set. So we calculate two checksums, unsigned and - signed. - """ - unsigned_chksum = 256 + sum(struct.unpack_from("148B8x356B", buf)) - signed_chksum = 256 + sum(struct.unpack_from("148b8x356b", buf)) - return unsigned_chksum, signed_chksum - -def copyfileobj(src, dst, length=None, exception=OSError, bufsize=None): - """Copy length bytes from fileobj src to fileobj dst. - If length is None, copy the entire content. - """ - bufsize = bufsize or 16 * 1024 - if length == 0: - return - if length is None: - shutil.copyfileobj(src, dst, bufsize) - return - - blocks, remainder = divmod(length, bufsize) - for b in range(blocks): - buf = src.read(bufsize) - if len(buf) < bufsize: - raise exception("unexpected end of data") - dst.write(buf) - - if remainder != 0: - buf = src.read(remainder) - if len(buf) < remainder: - raise exception("unexpected end of data") - dst.write(buf) - return - -def _safe_print(s): - encoding = getattr(sys.stdout, 'encoding', None) - if encoding is not None: - s = s.encode(encoding, 'backslashreplace').decode(encoding) - print(s, end=' ') - - -class TarError(Exception): - """Base exception.""" - pass -class ExtractError(TarError): - """General exception for extract errors.""" - pass -class ReadError(TarError): - """Exception for unreadable tar archives.""" - pass -class CompressionError(TarError): - """Exception for unavailable compression methods.""" - pass -class StreamError(TarError): - """Exception for unsupported operations on stream-like TarFiles.""" - pass -class HeaderError(TarError): - """Base exception for header errors.""" - pass -class EmptyHeaderError(HeaderError): - """Exception for empty headers.""" - pass -class TruncatedHeaderError(HeaderError): - """Exception for truncated headers.""" - pass -class EOFHeaderError(HeaderError): - """Exception for end of file headers.""" - pass -class InvalidHeaderError(HeaderError): - """Exception for invalid headers.""" - pass -class SubsequentHeaderError(HeaderError): - """Exception for missing and invalid extended headers.""" - pass - -#--------------------------- -# internal stream interface -#--------------------------- -class _LowLevelFile: - """Low-level file object. Supports reading and writing. - It is used instead of a regular file object for streaming - access. - """ - - def __init__(self, name, mode): - mode = { - "r": os.O_RDONLY, - "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC, - }[mode] - if hasattr(os, "O_BINARY"): - mode |= os.O_BINARY - self.fd = os.open(name, mode, 0o666) - - def close(self): - os.close(self.fd) - - def read(self, size): - return os.read(self.fd, size) - - def write(self, s): - os.write(self.fd, s) - -class _Stream: - """Class that serves as an adapter between TarFile and - a stream-like object. The stream-like object only - needs to have a read() or write() method and is accessed - blockwise. Use of gzip or bzip2 compression is possible. - A stream-like object could be for example: sys.stdin, - sys.stdout, a socket, a tape device etc. - - _Stream is intended to be used only internally. - """ - - def __init__(self, name, mode, comptype, fileobj, bufsize): - """Construct a _Stream object. - """ - self._extfileobj = True - if fileobj is None: - fileobj = _LowLevelFile(name, mode) - self._extfileobj = False - - if comptype == '*': - # Enable transparent compression detection for the - # stream interface - fileobj = _StreamProxy(fileobj) - comptype = fileobj.getcomptype() - - self.name = name or "" - self.mode = mode - self.comptype = comptype - self.fileobj = fileobj - self.bufsize = bufsize - self.buf = b"" - self.pos = 0 - self.closed = False - - try: - if comptype == "gz": - try: - import zlib - except ImportError: - raise CompressionError("zlib module is not available") from None - self.zlib = zlib - self.crc = zlib.crc32(b"") - if mode == "r": - self._init_read_gz() - self.exception = zlib.error - else: - self._init_write_gz() - - elif comptype == "bz2": - try: - import bz2 - except ImportError: - raise CompressionError("bz2 module is not available") from None - if mode == "r": - self.dbuf = b"" - self.cmp = bz2.BZ2Decompressor() - self.exception = OSError - else: - self.cmp = bz2.BZ2Compressor() - - elif comptype == "xz": - try: - import lzma - except ImportError: - raise CompressionError("lzma module is not available") from None - if mode == "r": - self.dbuf = b"" - self.cmp = lzma.LZMADecompressor() - self.exception = lzma.LZMAError - else: - self.cmp = lzma.LZMACompressor() - - elif comptype != "tar": - raise CompressionError("unknown compression type %r" % comptype) - - except: - if not self._extfileobj: - self.fileobj.close() - self.closed = True - raise - - def __del__(self): - if hasattr(self, "closed") and not self.closed: - self.close() - - def _init_write_gz(self): - """Initialize for writing with gzip compression. - """ - self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, - -self.zlib.MAX_WBITS, - self.zlib.DEF_MEM_LEVEL, - 0) - timestamp = struct.pack(" self.bufsize: - self.fileobj.write(self.buf[:self.bufsize]) - self.buf = self.buf[self.bufsize:] - - def close(self): - """Close the _Stream object. No operation should be - done on it afterwards. - """ - if self.closed: - return - - self.closed = True - try: - if self.mode == "w" and self.comptype != "tar": - self.buf += self.cmp.flush() - - if self.mode == "w" and self.buf: - self.fileobj.write(self.buf) - self.buf = b"" - if self.comptype == "gz": - self.fileobj.write(struct.pack("= 0: - blocks, remainder = divmod(pos - self.pos, self.bufsize) - for i in range(blocks): - self.read(self.bufsize) - self.read(remainder) - else: - raise StreamError("seeking backwards is not allowed") - return self.pos - - def read(self, size): - """Return the next size number of bytes from the stream.""" - assert size is not None - buf = self._read(size) - self.pos += len(buf) - return buf - - def _read(self, size): - """Return size bytes from the stream. - """ - if self.comptype == "tar": - return self.__read(size) - - c = len(self.dbuf) - t = [self.dbuf] - while c < size: - # Skip underlying buffer to avoid unaligned double buffering. - if self.buf: - buf = self.buf - self.buf = b"" - else: - buf = self.fileobj.read(self.bufsize) - if not buf: - break - try: - buf = self.cmp.decompress(buf) - except self.exception as e: - raise ReadError("invalid compressed data") from e - t.append(buf) - c += len(buf) - t = b"".join(t) - self.dbuf = t[size:] - return t[:size] - - def __read(self, size): - """Return size bytes from stream. If internal buffer is empty, - read another block from the stream. - """ - c = len(self.buf) - t = [self.buf] - while c < size: - buf = self.fileobj.read(self.bufsize) - if not buf: - break - t.append(buf) - c += len(buf) - t = b"".join(t) - self.buf = t[size:] - return t[:size] -# class _Stream - -class _StreamProxy(object): - """Small proxy class that enables transparent compression - detection for the Stream interface (mode 'r|*'). - """ - - def __init__(self, fileobj): - self.fileobj = fileobj - self.buf = self.fileobj.read(BLOCKSIZE) - - def read(self, size): - self.read = self.fileobj.read - return self.buf - - def getcomptype(self): - if self.buf.startswith(b"\x1f\x8b\x08"): - return "gz" - elif self.buf[0:3] == b"BZh" and self.buf[4:10] == b"1AY&SY": - return "bz2" - elif self.buf.startswith((b"\x5d\x00\x00\x80", b"\xfd7zXZ")): - return "xz" - else: - return "tar" - - def close(self): - self.fileobj.close() -# class StreamProxy - -#------------------------ -# Extraction file object -#------------------------ -class _FileInFile(object): - """A thin wrapper around an existing file object that - provides a part of its data as an individual file - object. - """ - - def __init__(self, fileobj, offset, size, blockinfo=None): - self.fileobj = fileobj - self.offset = offset - self.size = size - self.position = 0 - self.name = getattr(fileobj, "name", None) - self.closed = False - - if blockinfo is None: - blockinfo = [(0, size)] - - # Construct a map with data and zero blocks. - self.map_index = 0 - self.map = [] - lastpos = 0 - realpos = self.offset - for offset, size in blockinfo: - if offset > lastpos: - self.map.append((False, lastpos, offset, None)) - self.map.append((True, offset, offset + size, realpos)) - realpos += size - lastpos = offset + size - if lastpos < self.size: - self.map.append((False, lastpos, self.size, None)) - - def flush(self): - pass - - def readable(self): - return True - - def writable(self): - return False - - def seekable(self): - return self.fileobj.seekable() - - def tell(self): - """Return the current file position. - """ - return self.position - - def seek(self, position, whence=io.SEEK_SET): - """Seek to a position in the file. - """ - if whence == io.SEEK_SET: - self.position = min(max(position, 0), self.size) - elif whence == io.SEEK_CUR: - if position < 0: - self.position = max(self.position + position, 0) - else: - self.position = min(self.position + position, self.size) - elif whence == io.SEEK_END: - self.position = max(min(self.size + position, self.size), 0) - else: - raise ValueError("Invalid argument") - return self.position - - def read(self, size=None): - """Read data from the file. - """ - if size is None: - size = self.size - self.position - else: - size = min(size, self.size - self.position) - - buf = b"" - while size > 0: - while True: - data, start, stop, offset = self.map[self.map_index] - if start <= self.position < stop: - break - else: - self.map_index += 1 - if self.map_index == len(self.map): - self.map_index = 0 - length = min(size, stop - self.position) - if data: - self.fileobj.seek(offset + (self.position - start)) - b = self.fileobj.read(length) - if len(b) != length: - raise ReadError("unexpected end of data") - buf += b - else: - buf += NUL * length - size -= length - self.position += length - return buf - - def readinto(self, b): - buf = self.read(len(b)) - b[:len(buf)] = buf - return len(buf) - - def close(self): - self.closed = True -#class _FileInFile - -class ExFileObject(io.BufferedReader): - - def __init__(self, tarfile, tarinfo): - fileobj = _FileInFile(tarfile.fileobj, tarinfo.offset_data, - tarinfo.size, tarinfo.sparse) - super().__init__(fileobj) -#class ExFileObject - -#------------------ -# Exported Classes -#------------------ -class TarInfo(object): - """Informational class which holds the details about an - archive member given by a tar header block. - TarInfo objects are returned by TarFile.getmember(), - TarFile.getmembers() and TarFile.gettarinfo() and are - usually created internally. - """ - - __slots__ = dict( - name = 'Name of the archive member.', - mode = 'Permission bits.', - uid = 'User ID of the user who originally stored this member.', - gid = 'Group ID of the user who originally stored this member.', - size = 'Size in bytes.', - mtime = 'Time of last modification.', - chksum = 'Header checksum.', - type = ('File type. type is usually one of these constants: ' - 'REGTYPE, AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, ' - 'CONTTYPE, CHRTYPE, BLKTYPE, GNUTYPE_SPARSE.'), - linkname = ('Name of the target file name, which is only present ' - 'in TarInfo objects of type LNKTYPE and SYMTYPE.'), - uname = 'User name.', - gname = 'Group name.', - devmajor = 'Device major number.', - devminor = 'Device minor number.', - offset = 'The tar header starts here.', - offset_data = "The file's data starts here.", - pax_headers = ('A dictionary containing key-value pairs of an ' - 'associated pax extended header.'), - sparse = 'Sparse member information.', - tarfile = None, - _sparse_structs = None, - _link_target = None, - ) - - def __init__(self, name=""): - """Construct a TarInfo object. name is the optional name - of the member. - """ - self.name = name # member name - self.mode = 0o644 # file permissions - self.uid = 0 # user id - self.gid = 0 # group id - self.size = 0 # file size - self.mtime = 0 # modification time - self.chksum = 0 # header checksum - self.type = REGTYPE # member type - self.linkname = "" # link name - self.uname = "" # user name - self.gname = "" # group name - self.devmajor = 0 # device major number - self.devminor = 0 # device minor number - - self.offset = 0 # the tar header starts here - self.offset_data = 0 # the file's data starts here - - self.sparse = None # sparse member information - self.pax_headers = {} # pax header information - - @property - def path(self): - 'In pax headers, "name" is called "path".' - return self.name - - @path.setter - def path(self, name): - self.name = name - - @property - def linkpath(self): - 'In pax headers, "linkname" is called "linkpath".' - return self.linkname - - @linkpath.setter - def linkpath(self, linkname): - self.linkname = linkname - - def __repr__(self): - return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) - - def get_info(self): - """Return the TarInfo's attributes as a dictionary. - """ - info = { - "name": self.name, - "mode": self.mode & 0o7777, - "uid": self.uid, - "gid": self.gid, - "size": self.size, - "mtime": self.mtime, - "chksum": self.chksum, - "type": self.type, - "linkname": self.linkname, - "uname": self.uname, - "gname": self.gname, - "devmajor": self.devmajor, - "devminor": self.devminor - } - - if info["type"] == DIRTYPE and not info["name"].endswith("/"): - info["name"] += "/" - - return info - - def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="surrogateescape"): - """Return a tar header as a string of 512 byte blocks. - """ - info = self.get_info() - - if format == USTAR_FORMAT: - return self.create_ustar_header(info, encoding, errors) - elif format == GNU_FORMAT: - return self.create_gnu_header(info, encoding, errors) - elif format == PAX_FORMAT: - return self.create_pax_header(info, encoding) - else: - raise ValueError("invalid format") - - def create_ustar_header(self, info, encoding, errors): - """Return the object as a ustar header block. - """ - info["magic"] = POSIX_MAGIC - - if len(info["linkname"].encode(encoding, errors)) > LENGTH_LINK: - raise ValueError("linkname is too long") - - if len(info["name"].encode(encoding, errors)) > LENGTH_NAME: - info["prefix"], info["name"] = self._posix_split_name(info["name"], encoding, errors) - - return self._create_header(info, USTAR_FORMAT, encoding, errors) - - def create_gnu_header(self, info, encoding, errors): - """Return the object as a GNU header block sequence. - """ - info["magic"] = GNU_MAGIC - - buf = b"" - if len(info["linkname"].encode(encoding, errors)) > LENGTH_LINK: - buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors) - - if len(info["name"].encode(encoding, errors)) > LENGTH_NAME: - buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME, encoding, errors) - - return buf + self._create_header(info, GNU_FORMAT, encoding, errors) - - def create_pax_header(self, info, encoding): - """Return the object as a ustar header block. If it cannot be - represented this way, prepend a pax extended header sequence - with supplement information. - """ - info["magic"] = POSIX_MAGIC - pax_headers = self.pax_headers.copy() - - # Test string fields for values that exceed the field length or cannot - # be represented in ASCII encoding. - for name, hname, length in ( - ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK), - ("uname", "uname", 32), ("gname", "gname", 32)): - - if hname in pax_headers: - # The pax header has priority. - continue - - # Try to encode the string as ASCII. - try: - info[name].encode("ascii", "strict") - except UnicodeEncodeError: - pax_headers[hname] = info[name] - continue - - if len(info[name]) > length: - pax_headers[hname] = info[name] - - # Test number fields for values that exceed the field limit or values - # that like to be stored as float. - for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)): - needs_pax = False - - val = info[name] - val_is_float = isinstance(val, float) - val_int = round(val) if val_is_float else val - if not 0 <= val_int < 8 ** (digits - 1): - # Avoid overflow. - info[name] = 0 - needs_pax = True - elif val_is_float: - # Put rounded value in ustar header, and full - # precision value in pax header. - info[name] = val_int - needs_pax = True - - # The existing pax header has priority. - if needs_pax and name not in pax_headers: - pax_headers[name] = str(val) - - # Create a pax extended header if necessary. - if pax_headers: - buf = self._create_pax_generic_header(pax_headers, XHDTYPE, encoding) - else: - buf = b"" - - return buf + self._create_header(info, USTAR_FORMAT, "ascii", "replace") - - @classmethod - def create_pax_global_header(cls, pax_headers): - """Return the object as a pax global header block sequence. - """ - return cls._create_pax_generic_header(pax_headers, XGLTYPE, "utf-8") - - def _posix_split_name(self, name, encoding, errors): - """Split a name longer than 100 chars into a prefix - and a name part. - """ - components = name.split("/") - for i in range(1, len(components)): - prefix = "/".join(components[:i]) - name = "/".join(components[i:]) - if len(prefix.encode(encoding, errors)) <= LENGTH_PREFIX and \ - len(name.encode(encoding, errors)) <= LENGTH_NAME: - break - else: - raise ValueError("name is too long") - - return prefix, name - - @staticmethod - def _create_header(info, format, encoding, errors): - """Return a header block. info is a dictionary with file - information, format must be one of the *_FORMAT constants. - """ - has_device_fields = info.get("type") in (CHRTYPE, BLKTYPE) - if has_device_fields: - devmajor = itn(info.get("devmajor", 0), 8, format) - devminor = itn(info.get("devminor", 0), 8, format) - else: - devmajor = stn("", 8, encoding, errors) - devminor = stn("", 8, encoding, errors) - - parts = [ - stn(info.get("name", ""), 100, encoding, errors), - itn(info.get("mode", 0) & 0o7777, 8, format), - itn(info.get("uid", 0), 8, format), - itn(info.get("gid", 0), 8, format), - itn(info.get("size", 0), 12, format), - itn(info.get("mtime", 0), 12, format), - b" ", # checksum field - info.get("type", REGTYPE), - stn(info.get("linkname", ""), 100, encoding, errors), - info.get("magic", POSIX_MAGIC), - stn(info.get("uname", ""), 32, encoding, errors), - stn(info.get("gname", ""), 32, encoding, errors), - devmajor, - devminor, - stn(info.get("prefix", ""), 155, encoding, errors) - ] - - buf = struct.pack("%ds" % BLOCKSIZE, b"".join(parts)) - chksum = calc_chksums(buf[-BLOCKSIZE:])[0] - buf = buf[:-364] + bytes("%06o\0" % chksum, "ascii") + buf[-357:] - return buf - - @staticmethod - def _create_payload(payload): - """Return the string payload filled with zero bytes - up to the next 512 byte border. - """ - blocks, remainder = divmod(len(payload), BLOCKSIZE) - if remainder > 0: - payload += (BLOCKSIZE - remainder) * NUL - return payload - - @classmethod - def _create_gnu_long_header(cls, name, type, encoding, errors): - """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence - for name. - """ - name = name.encode(encoding, errors) + NUL - - info = {} - info["name"] = "././@LongLink" - info["type"] = type - info["size"] = len(name) - info["magic"] = GNU_MAGIC - - # create extended header + name blocks. - return cls._create_header(info, USTAR_FORMAT, encoding, errors) + \ - cls._create_payload(name) - - @classmethod - def _create_pax_generic_header(cls, pax_headers, type, encoding): - """Return a POSIX.1-2008 extended or global header sequence - that contains a list of keyword, value pairs. The values - must be strings. - """ - # Check if one of the fields contains surrogate characters and thereby - # forces hdrcharset=BINARY, see _proc_pax() for more information. - binary = False - for keyword, value in pax_headers.items(): - try: - value.encode("utf-8", "strict") - except UnicodeEncodeError: - binary = True - break - - records = b"" - if binary: - # Put the hdrcharset field at the beginning of the header. - records += b"21 hdrcharset=BINARY\n" - - for keyword, value in pax_headers.items(): - keyword = keyword.encode("utf-8") - if binary: - # Try to restore the original byte representation of `value'. - # Needless to say, that the encoding must match the string. - value = value.encode(encoding, "surrogateescape") - else: - value = value.encode("utf-8") - - l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n' - n = p = 0 - while True: - n = l + len(str(p)) - if n == p: - break - p = n - records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n" - - # We use a hardcoded "././@PaxHeader" name like star does - # instead of the one that POSIX recommends. - info = {} - info["name"] = "././@PaxHeader" - info["type"] = type - info["size"] = len(records) - info["magic"] = POSIX_MAGIC - - # Create pax header + record blocks. - return cls._create_header(info, USTAR_FORMAT, "ascii", "replace") + \ - cls._create_payload(records) - - @classmethod - def frombuf(cls, buf, encoding, errors): - """Construct a TarInfo object from a 512 byte bytes object. - """ - if len(buf) == 0: - raise EmptyHeaderError("empty header") - if len(buf) != BLOCKSIZE: - raise TruncatedHeaderError("truncated header") - if buf.count(NUL) == BLOCKSIZE: - raise EOFHeaderError("end of file header") - - chksum = nti(buf[148:156]) - if chksum not in calc_chksums(buf): - raise InvalidHeaderError("bad checksum") - - obj = cls() - obj.name = nts(buf[0:100], encoding, errors) - obj.mode = nti(buf[100:108]) - obj.uid = nti(buf[108:116]) - obj.gid = nti(buf[116:124]) - obj.size = nti(buf[124:136]) - obj.mtime = nti(buf[136:148]) - obj.chksum = chksum - obj.type = buf[156:157] - obj.linkname = nts(buf[157:257], encoding, errors) - obj.uname = nts(buf[265:297], encoding, errors) - obj.gname = nts(buf[297:329], encoding, errors) - obj.devmajor = nti(buf[329:337]) - obj.devminor = nti(buf[337:345]) - prefix = nts(buf[345:500], encoding, errors) - - # Old V7 tar format represents a directory as a regular - # file with a trailing slash. - if obj.type == AREGTYPE and obj.name.endswith("/"): - obj.type = DIRTYPE - - # The old GNU sparse format occupies some of the unused - # space in the buffer for up to 4 sparse structures. - # Save them for later processing in _proc_sparse(). - if obj.type == GNUTYPE_SPARSE: - pos = 386 - structs = [] - for i in range(4): - try: - offset = nti(buf[pos:pos + 12]) - numbytes = nti(buf[pos + 12:pos + 24]) - except ValueError: - break - structs.append((offset, numbytes)) - pos += 24 - isextended = bool(buf[482]) - origsize = nti(buf[483:495]) - obj._sparse_structs = (structs, isextended, origsize) - - # Remove redundant slashes from directories. - if obj.isdir(): - obj.name = obj.name.rstrip("/") - - # Reconstruct a ustar longname. - if prefix and obj.type not in GNU_TYPES: - obj.name = prefix + "/" + obj.name - return obj - - @classmethod - def fromtarfile(cls, tarfile): - """Return the next TarInfo object from TarFile object - tarfile. - """ - buf = tarfile.fileobj.read(BLOCKSIZE) - obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) - obj.offset = tarfile.fileobj.tell() - BLOCKSIZE - return obj._proc_member(tarfile) - - #-------------------------------------------------------------------------- - # The following are methods that are called depending on the type of a - # member. The entry point is _proc_member() which can be overridden in a - # subclass to add custom _proc_*() methods. A _proc_*() method MUST - # implement the following - # operations: - # 1. Set self.offset_data to the position where the data blocks begin, - # if there is data that follows. - # 2. Set tarfile.offset to the position where the next member's header will - # begin. - # 3. Return self or another valid TarInfo object. - def _proc_member(self, tarfile): - """Choose the right processing method depending on - the type and call it. - """ - if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK): - return self._proc_gnulong(tarfile) - elif self.type == GNUTYPE_SPARSE: - return self._proc_sparse(tarfile) - elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE): - return self._proc_pax(tarfile) - else: - return self._proc_builtin(tarfile) - - def _proc_builtin(self, tarfile): - """Process a builtin type or an unknown type which - will be treated as a regular file. - """ - self.offset_data = tarfile.fileobj.tell() - offset = self.offset_data - if self.isreg() or self.type not in SUPPORTED_TYPES: - # Skip the following data blocks. - offset += self._block(self.size) - tarfile.offset = offset - - # Patch the TarInfo object with saved global - # header information. - self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors) - - # Remove redundant slashes from directories. This is to be consistent - # with frombuf(). - if self.isdir(): - self.name = self.name.rstrip("/") - - return self - - def _proc_gnulong(self, tarfile): - """Process the blocks that hold a GNU longname - or longlink member. - """ - buf = tarfile.fileobj.read(self._block(self.size)) - - # Fetch the next header and process it. - try: - next = self.fromtarfile(tarfile) - except HeaderError as e: - raise SubsequentHeaderError(str(e)) from None - - # Patch the TarInfo object from the next header with - # the longname information. - next.offset = self.offset - if self.type == GNUTYPE_LONGNAME: - next.name = nts(buf, tarfile.encoding, tarfile.errors) - elif self.type == GNUTYPE_LONGLINK: - next.linkname = nts(buf, tarfile.encoding, tarfile.errors) - - # Remove redundant slashes from directories. This is to be consistent - # with frombuf(). - if next.isdir(): - next.name = next.name.removesuffix("/") - - return next - - def _proc_sparse(self, tarfile): - """Process a GNU sparse header plus extra headers. - """ - # We already collected some sparse structures in frombuf(). - structs, isextended, origsize = self._sparse_structs - del self._sparse_structs - - # Collect sparse structures from extended header blocks. - while isextended: - buf = tarfile.fileobj.read(BLOCKSIZE) - pos = 0 - for i in range(21): - try: - offset = nti(buf[pos:pos + 12]) - numbytes = nti(buf[pos + 12:pos + 24]) - except ValueError: - break - if offset and numbytes: - structs.append((offset, numbytes)) - pos += 24 - isextended = bool(buf[504]) - self.sparse = structs - - self.offset_data = tarfile.fileobj.tell() - tarfile.offset = self.offset_data + self._block(self.size) - self.size = origsize - return self - - def _proc_pax(self, tarfile): - """Process an extended or global header as described in - POSIX.1-2008. - """ - # Read the header information. - buf = tarfile.fileobj.read(self._block(self.size)) - - # A pax header stores supplemental information for either - # the following file (extended) or all following files - # (global). - if self.type == XGLTYPE: - pax_headers = tarfile.pax_headers - else: - pax_headers = tarfile.pax_headers.copy() - - # Check if the pax header contains a hdrcharset field. This tells us - # the encoding of the path, linkpath, uname and gname fields. Normally, - # these fields are UTF-8 encoded but since POSIX.1-2008 tar - # implementations are allowed to store them as raw binary strings if - # the translation to UTF-8 fails. - match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf) - if match is not None: - pax_headers["hdrcharset"] = match.group(1).decode("utf-8") - - # For the time being, we don't care about anything other than "BINARY". - # The only other value that is currently allowed by the standard is - # "ISO-IR 10646 2000 UTF-8" in other words UTF-8. - hdrcharset = pax_headers.get("hdrcharset") - if hdrcharset == "BINARY": - encoding = tarfile.encoding - else: - encoding = "utf-8" - - # Parse pax header information. A record looks like that: - # "%d %s=%s\n" % (length, keyword, value). length is the size - # of the complete record including the length field itself and - # the newline. keyword and value are both UTF-8 encoded strings. - regex = re.compile(br"(\d+) ([^=]+)=") - pos = 0 - while True: - match = regex.match(buf, pos) - if not match: - break - - length, keyword = match.groups() - length = int(length) - if length == 0: - raise InvalidHeaderError("invalid header") - value = buf[match.end(2) + 1:match.start(1) + length - 1] - - # Normally, we could just use "utf-8" as the encoding and "strict" - # as the error handler, but we better not take the risk. For - # example, GNU tar <= 1.23 is known to store filenames it cannot - # translate to UTF-8 as raw strings (unfortunately without a - # hdrcharset=BINARY header). - # We first try the strict standard encoding, and if that fails we - # fall back on the user's encoding and error handler. - keyword = self._decode_pax_field(keyword, "utf-8", "utf-8", - tarfile.errors) - if keyword in PAX_NAME_FIELDS: - value = self._decode_pax_field(value, encoding, tarfile.encoding, - tarfile.errors) - else: - value = self._decode_pax_field(value, "utf-8", "utf-8", - tarfile.errors) - - pax_headers[keyword] = value - pos += length - - # Fetch the next header. - try: - next = self.fromtarfile(tarfile) - except HeaderError as e: - raise SubsequentHeaderError(str(e)) from None - - # Process GNU sparse information. - if "GNU.sparse.map" in pax_headers: - # GNU extended sparse format version 0.1. - self._proc_gnusparse_01(next, pax_headers) - - elif "GNU.sparse.size" in pax_headers: - # GNU extended sparse format version 0.0. - self._proc_gnusparse_00(next, pax_headers, buf) - - elif pax_headers.get("GNU.sparse.major") == "1" and pax_headers.get("GNU.sparse.minor") == "0": - # GNU extended sparse format version 1.0. - self._proc_gnusparse_10(next, pax_headers, tarfile) - - if self.type in (XHDTYPE, SOLARIS_XHDTYPE): - # Patch the TarInfo object with the extended header info. - next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) - next.offset = self.offset - - if "size" in pax_headers: - # If the extended header replaces the size field, - # we need to recalculate the offset where the next - # header starts. - offset = next.offset_data - if next.isreg() or next.type not in SUPPORTED_TYPES: - offset += next._block(next.size) - tarfile.offset = offset - - return next - - def _proc_gnusparse_00(self, next, pax_headers, buf): - """Process a GNU tar extended sparse header, version 0.0. - """ - offsets = [] - for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf): - offsets.append(int(match.group(1))) - numbytes = [] - for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf): - numbytes.append(int(match.group(1))) - next.sparse = list(zip(offsets, numbytes)) - - def _proc_gnusparse_01(self, next, pax_headers): - """Process a GNU tar extended sparse header, version 0.1. - """ - sparse = [int(x) for x in pax_headers["GNU.sparse.map"].split(",")] - next.sparse = list(zip(sparse[::2], sparse[1::2])) - - def _proc_gnusparse_10(self, next, pax_headers, tarfile): - """Process a GNU tar extended sparse header, version 1.0. - """ - fields = None - sparse = [] - buf = tarfile.fileobj.read(BLOCKSIZE) - fields, buf = buf.split(b"\n", 1) - fields = int(fields) - while len(sparse) < fields * 2: - if b"\n" not in buf: - buf += tarfile.fileobj.read(BLOCKSIZE) - number, buf = buf.split(b"\n", 1) - sparse.append(int(number)) - next.offset_data = tarfile.fileobj.tell() - next.sparse = list(zip(sparse[::2], sparse[1::2])) - - def _apply_pax_info(self, pax_headers, encoding, errors): - """Replace fields with supplemental information from a previous - pax extended or global header. - """ - for keyword, value in pax_headers.items(): - if keyword == "GNU.sparse.name": - setattr(self, "path", value) - elif keyword == "GNU.sparse.size": - setattr(self, "size", int(value)) - elif keyword == "GNU.sparse.realsize": - setattr(self, "size", int(value)) - elif keyword in PAX_FIELDS: - if keyword in PAX_NUMBER_FIELDS: - try: - value = PAX_NUMBER_FIELDS[keyword](value) - except ValueError: - value = 0 - if keyword == "path": - value = value.rstrip("/") - setattr(self, keyword, value) - - self.pax_headers = pax_headers.copy() - - def _decode_pax_field(self, value, encoding, fallback_encoding, fallback_errors): - """Decode a single field from a pax record. - """ - try: - return value.decode(encoding, "strict") - except UnicodeDecodeError: - return value.decode(fallback_encoding, fallback_errors) - - def _block(self, count): - """Round up a byte count by BLOCKSIZE and return it, - e.g. _block(834) => 1024. - """ - blocks, remainder = divmod(count, BLOCKSIZE) - if remainder: - blocks += 1 - return blocks * BLOCKSIZE - - def isreg(self): - 'Return True if the Tarinfo object is a regular file.' - return self.type in REGULAR_TYPES - - def isfile(self): - 'Return True if the Tarinfo object is a regular file.' - return self.isreg() - - def isdir(self): - 'Return True if it is a directory.' - return self.type == DIRTYPE - - def issym(self): - 'Return True if it is a symbolic link.' - return self.type == SYMTYPE - - def islnk(self): - 'Return True if it is a hard link.' - return self.type == LNKTYPE - - def ischr(self): - 'Return True if it is a character device.' - return self.type == CHRTYPE - - def isblk(self): - 'Return True if it is a block device.' - return self.type == BLKTYPE - - def isfifo(self): - 'Return True if it is a FIFO.' - return self.type == FIFOTYPE - - def issparse(self): - return self.sparse is not None - - def isdev(self): - 'Return True if it is one of character device, block device or FIFO.' - return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE) -# class TarInfo - -class TarFile(object): - """The TarFile Class provides an interface to tar archives. - """ - - debug = 0 # May be set from 0 (no msgs) to 3 (all msgs) - - dereference = False # If true, add content of linked file to the - # tar file, else the link. - - ignore_zeros = False # If true, skips empty or invalid blocks and - # continues processing. - - errorlevel = 1 # If 0, fatal errors only appear in debug - # messages (if debug >= 0). If > 0, errors - # are passed to the caller as exceptions. - - format = DEFAULT_FORMAT # The format to use when creating an archive. - - encoding = ENCODING # Encoding for 8-bit character strings. - - errors = None # Error handler for unicode conversion. - - tarinfo = TarInfo # The default TarInfo class to use. - - fileobject = ExFileObject # The file-object for extractfile(). - - def __init__(self, name=None, mode="r", fileobj=None, format=None, - tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, - errors="surrogateescape", pax_headers=None, debug=None, - errorlevel=None, copybufsize=None): - """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to - read from an existing archive, 'a' to append data to an existing - file or 'w' to create a new file overwriting an existing one. `mode' - defaults to 'r'. - If `fileobj' is given, it is used for reading or writing data. If it - can be determined, `mode' is overridden by `fileobj's mode. - `fileobj' is not closed, when TarFile is closed. - """ - modes = {"r": "rb", "a": "r+b", "w": "wb", "x": "xb"} - if mode not in modes: - raise ValueError("mode must be 'r', 'a', 'w' or 'x'") - self.mode = mode - self._mode = modes[mode] - - if not fileobj: - if self.mode == "a" and not os.path.exists(name): - # Create nonexistent files in append mode. - self.mode = "w" - self._mode = "wb" - fileobj = bltn_open(name, self._mode) - self._extfileobj = False - else: - if (name is None and hasattr(fileobj, "name") and - isinstance(fileobj.name, (str, bytes))): - name = fileobj.name - if hasattr(fileobj, "mode"): - self._mode = fileobj.mode - self._extfileobj = True - self.name = os.path.abspath(name) if name else None - self.fileobj = fileobj - - # Init attributes. - if format is not None: - self.format = format - if tarinfo is not None: - self.tarinfo = tarinfo - if dereference is not None: - self.dereference = dereference - if ignore_zeros is not None: - self.ignore_zeros = ignore_zeros - if encoding is not None: - self.encoding = encoding - self.errors = errors - - if pax_headers is not None and self.format == PAX_FORMAT: - self.pax_headers = pax_headers - else: - self.pax_headers = {} - - if debug is not None: - self.debug = debug - if errorlevel is not None: - self.errorlevel = errorlevel - - # Init datastructures. - self.copybufsize = copybufsize - self.closed = False - self.members = [] # list of members as TarInfo objects - self._loaded = False # flag if all members have been read - self.offset = self.fileobj.tell() - # current position in the archive file - self.inodes = {} # dictionary caching the inodes of - # archive members already added - - try: - if self.mode == "r": - self.firstmember = None - self.firstmember = self.next() - - if self.mode == "a": - # Move to the end of the archive, - # before the first empty block. - while True: - self.fileobj.seek(self.offset) - try: - tarinfo = self.tarinfo.fromtarfile(self) - self.members.append(tarinfo) - except EOFHeaderError: - self.fileobj.seek(self.offset) - break - except HeaderError as e: - raise ReadError(str(e)) from None - - if self.mode in ("a", "w", "x"): - self._loaded = True - - if self.pax_headers: - buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) - self.fileobj.write(buf) - self.offset += len(buf) - except: - if not self._extfileobj: - self.fileobj.close() - self.closed = True - raise - - #-------------------------------------------------------------------------- - # Below are the classmethods which act as alternate constructors to the - # TarFile class. The open() method is the only one that is needed for - # public use; it is the "super"-constructor and is able to select an - # adequate "sub"-constructor for a particular compression using the mapping - # from OPEN_METH. - # - # This concept allows one to subclass TarFile without losing the comfort of - # the super-constructor. A sub-constructor is registered and made available - # by adding it to the mapping in OPEN_METH. - - @classmethod - def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): - """Open a tar archive for reading, writing or appending. Return - an appropriate TarFile class. - - mode: - 'r' or 'r:*' open for reading with transparent compression - 'r:' open for reading exclusively uncompressed - 'r:gz' open for reading with gzip compression - 'r:bz2' open for reading with bzip2 compression - 'r:xz' open for reading with lzma compression - 'a' or 'a:' open for appending, creating the file if necessary - 'w' or 'w:' open for writing without compression - 'w:gz' open for writing with gzip compression - 'w:bz2' open for writing with bzip2 compression - 'w:xz' open for writing with lzma compression - - 'x' or 'x:' create a tarfile exclusively without compression, raise - an exception if the file is already created - 'x:gz' create a gzip compressed tarfile, raise an exception - if the file is already created - 'x:bz2' create a bzip2 compressed tarfile, raise an exception - if the file is already created - 'x:xz' create an lzma compressed tarfile, raise an exception - if the file is already created - - 'r|*' open a stream of tar blocks with transparent compression - 'r|' open an uncompressed stream of tar blocks for reading - 'r|gz' open a gzip compressed stream of tar blocks - 'r|bz2' open a bzip2 compressed stream of tar blocks - 'r|xz' open an lzma compressed stream of tar blocks - 'w|' open an uncompressed stream for writing - 'w|gz' open a gzip compressed stream for writing - 'w|bz2' open a bzip2 compressed stream for writing - 'w|xz' open an lzma compressed stream for writing - """ - - if not name and not fileobj: - raise ValueError("nothing to open") - - if mode in ("r", "r:*"): - # Find out which *open() is appropriate for opening the file. - def not_compressed(comptype): - return cls.OPEN_METH[comptype] == 'taropen' - error_msgs = [] - for comptype in sorted(cls.OPEN_METH, key=not_compressed): - func = getattr(cls, cls.OPEN_METH[comptype]) - if fileobj is not None: - saved_pos = fileobj.tell() - try: - return func(name, "r", fileobj, **kwargs) - except (ReadError, CompressionError) as e: - error_msgs.append(f'- method {comptype}: {e!r}') - if fileobj is not None: - fileobj.seek(saved_pos) - continue - error_msgs_summary = '\n'.join(error_msgs) - raise ReadError(f"file could not be opened successfully:\n{error_msgs_summary}") - - elif ":" in mode: - filemode, comptype = mode.split(":", 1) - filemode = filemode or "r" - comptype = comptype or "tar" - - # Select the *open() function according to - # given compression. - if comptype in cls.OPEN_METH: - func = getattr(cls, cls.OPEN_METH[comptype]) - else: - raise CompressionError("unknown compression type %r" % comptype) - return func(name, filemode, fileobj, **kwargs) - - elif "|" in mode: - filemode, comptype = mode.split("|", 1) - filemode = filemode or "r" - comptype = comptype or "tar" - - if filemode not in ("r", "w"): - raise ValueError("mode must be 'r' or 'w'") - - stream = _Stream(name, filemode, comptype, fileobj, bufsize) - try: - t = cls(name, filemode, stream, **kwargs) - except: - stream.close() - raise - t._extfileobj = False - return t - - elif mode in ("a", "w", "x"): - return cls.taropen(name, mode, fileobj, **kwargs) - - raise ValueError("undiscernible mode") - - @classmethod - def taropen(cls, name, mode="r", fileobj=None, **kwargs): - """Open uncompressed tar archive name for reading or writing. - """ - if mode not in ("r", "a", "w", "x"): - raise ValueError("mode must be 'r', 'a', 'w' or 'x'") - return cls(name, mode, fileobj, **kwargs) - - @classmethod - def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): - """Open gzip compressed tar archive name for reading or writing. - Appending is not allowed. - """ - if mode not in ("r", "w", "x"): - raise ValueError("mode must be 'r', 'w' or 'x'") - - try: - from gzip import GzipFile - except ImportError: - raise CompressionError("gzip module is not available") from None - - try: - fileobj = GzipFile(name, mode + "b", compresslevel, fileobj) - except OSError as e: - if fileobj is not None and mode == 'r': - raise ReadError("not a gzip file") from e - raise - - try: - t = cls.taropen(name, mode, fileobj, **kwargs) - except OSError as e: - fileobj.close() - if mode == 'r': - raise ReadError("not a gzip file") from e - raise - except: - fileobj.close() - raise - t._extfileobj = False - return t - - @classmethod - def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): - """Open bzip2 compressed tar archive name for reading or writing. - Appending is not allowed. - """ - if mode not in ("r", "w", "x"): - raise ValueError("mode must be 'r', 'w' or 'x'") - - try: - from bz2 import BZ2File - except ImportError: - raise CompressionError("bz2 module is not available") from None - - fileobj = BZ2File(fileobj or name, mode, compresslevel=compresslevel) - - try: - t = cls.taropen(name, mode, fileobj, **kwargs) - except (OSError, EOFError) as e: - fileobj.close() - if mode == 'r': - raise ReadError("not a bzip2 file") from e - raise - except: - fileobj.close() - raise - t._extfileobj = False - return t - - @classmethod - def xzopen(cls, name, mode="r", fileobj=None, preset=None, **kwargs): - """Open lzma compressed tar archive name for reading or writing. - Appending is not allowed. - """ - if mode not in ("r", "w", "x"): - raise ValueError("mode must be 'r', 'w' or 'x'") - - try: - from lzma import LZMAFile, LZMAError - except ImportError: - raise CompressionError("lzma module is not available") from None - - fileobj = LZMAFile(fileobj or name, mode, preset=preset) - - try: - t = cls.taropen(name, mode, fileobj, **kwargs) - except (LZMAError, EOFError) as e: - fileobj.close() - if mode == 'r': - raise ReadError("not an lzma file") from e - raise - except: - fileobj.close() - raise - t._extfileobj = False - return t - - # All *open() methods are registered here. - OPEN_METH = { - "tar": "taropen", # uncompressed tar - "gz": "gzopen", # gzip compressed tar - "bz2": "bz2open", # bzip2 compressed tar - "xz": "xzopen" # lzma compressed tar - } - - #-------------------------------------------------------------------------- - # The public methods which TarFile provides: - - def close(self): - """Close the TarFile. In write-mode, two finishing zero blocks are - appended to the archive. - """ - if self.closed: - return - - self.closed = True - try: - if self.mode in ("a", "w", "x"): - self.fileobj.write(NUL * (BLOCKSIZE * 2)) - self.offset += (BLOCKSIZE * 2) - # fill up the end with zero-blocks - # (like option -b20 for tar does) - blocks, remainder = divmod(self.offset, RECORDSIZE) - if remainder > 0: - self.fileobj.write(NUL * (RECORDSIZE - remainder)) - finally: - if not self._extfileobj: - self.fileobj.close() - - def getmember(self, name): - """Return a TarInfo object for member `name'. If `name' can not be - found in the archive, KeyError is raised. If a member occurs more - than once in the archive, its last occurrence is assumed to be the - most up-to-date version. - """ - tarinfo = self._getmember(name.rstrip('/')) - if tarinfo is None: - raise KeyError("filename %r not found" % name) - return tarinfo - - def getmembers(self): - """Return the members of the archive as a list of TarInfo objects. The - list has the same order as the members in the archive. - """ - self._check() - if not self._loaded: # if we want to obtain a list of - self._load() # all members, we first have to - # scan the whole archive. - return self.members - - def getnames(self): - """Return the members of the archive as a list of their names. It has - the same order as the list returned by getmembers(). - """ - return [tarinfo.name for tarinfo in self.getmembers()] - - def gettarinfo(self, name=None, arcname=None, fileobj=None): - """Create a TarInfo object from the result of os.stat or equivalent - on an existing file. The file is either named by `name', or - specified as a file object `fileobj' with a file descriptor. If - given, `arcname' specifies an alternative name for the file in the - archive, otherwise, the name is taken from the 'name' attribute of - 'fileobj', or the 'name' argument. The name should be a text - string. - """ - self._check("awx") - - # When fileobj is given, replace name by - # fileobj's real name. - if fileobj is not None: - name = fileobj.name - - # Building the name of the member in the archive. - # Backward slashes are converted to forward slashes, - # Absolute paths are turned to relative paths. - if arcname is None: - arcname = name - drv, arcname = os.path.splitdrive(arcname) - arcname = arcname.replace(os.sep, "/") - arcname = arcname.lstrip("/") - - # Now, fill the TarInfo object with - # information specific for the file. - tarinfo = self.tarinfo() - tarinfo.tarfile = self # Not needed - - # Use os.stat or os.lstat, depending on if symlinks shall be resolved. - if fileobj is None: - if not self.dereference: - statres = os.lstat(name) - else: - statres = os.stat(name) - else: - statres = os.fstat(fileobj.fileno()) - linkname = "" - - stmd = statres.st_mode - if stat.S_ISREG(stmd): - inode = (statres.st_ino, statres.st_dev) - if not self.dereference and statres.st_nlink > 1 and \ - inode in self.inodes and arcname != self.inodes[inode]: - # Is it a hardlink to an already - # archived file? - type = LNKTYPE - linkname = self.inodes[inode] - else: - # The inode is added only if its valid. - # For win32 it is always 0. - type = REGTYPE - if inode[0]: - self.inodes[inode] = arcname - elif stat.S_ISDIR(stmd): - type = DIRTYPE - elif stat.S_ISFIFO(stmd): - type = FIFOTYPE - elif stat.S_ISLNK(stmd): - type = SYMTYPE - linkname = os.readlink(name) - elif stat.S_ISCHR(stmd): - type = CHRTYPE - elif stat.S_ISBLK(stmd): - type = BLKTYPE - else: - return None - - # Fill the TarInfo object with all - # information we can get. - tarinfo.name = arcname - tarinfo.mode = stmd - tarinfo.uid = statres.st_uid - tarinfo.gid = statres.st_gid - if type == REGTYPE: - tarinfo.size = statres.st_size - else: - tarinfo.size = 0 - tarinfo.mtime = statres.st_mtime - tarinfo.type = type - tarinfo.linkname = linkname - if pwd: - try: - tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0] - except KeyError: - pass - if grp: - try: - tarinfo.gname = grp.getgrgid(tarinfo.gid)[0] - except KeyError: - pass - - if type in (CHRTYPE, BLKTYPE): - if hasattr(os, "major") and hasattr(os, "minor"): - tarinfo.devmajor = os.major(statres.st_rdev) - tarinfo.devminor = os.minor(statres.st_rdev) - return tarinfo - - def list(self, verbose=True, *, members=None): - """Print a table of contents to sys.stdout. If `verbose' is False, only - the names of the members are printed. If it is True, an `ls -l'-like - output is produced. `members' is optional and must be a subset of the - list returned by getmembers(). - """ - self._check() - - if members is None: - members = self - for tarinfo in members: - if verbose: - _safe_print(stat.filemode(tarinfo.mode)) - _safe_print("%s/%s" % (tarinfo.uname or tarinfo.uid, - tarinfo.gname or tarinfo.gid)) - if tarinfo.ischr() or tarinfo.isblk(): - _safe_print("%10s" % - ("%d,%d" % (tarinfo.devmajor, tarinfo.devminor))) - else: - _safe_print("%10d" % tarinfo.size) - _safe_print("%d-%02d-%02d %02d:%02d:%02d" \ - % time.localtime(tarinfo.mtime)[:6]) - - _safe_print(tarinfo.name + ("/" if tarinfo.isdir() else "")) - - if verbose: - if tarinfo.issym(): - _safe_print("-> " + tarinfo.linkname) - if tarinfo.islnk(): - _safe_print("link to " + tarinfo.linkname) - print() - - def add(self, name, arcname=None, recursive=True, *, filter=None): - """Add the file `name' to the archive. `name' may be any type of file - (directory, fifo, symbolic link, etc.). If given, `arcname' - specifies an alternative name for the file in the archive. - Directories are added recursively by default. This can be avoided by - setting `recursive' to False. `filter' is a function - that expects a TarInfo object argument and returns the changed - TarInfo object, if it returns None the TarInfo object will be - excluded from the archive. - """ - self._check("awx") - - if arcname is None: - arcname = name - - # Skip if somebody tries to archive the archive... - if self.name is not None and os.path.abspath(name) == self.name: - self._dbg(2, "tarfile: Skipped %r" % name) - return - - self._dbg(1, name) - - # Create a TarInfo object from the file. - tarinfo = self.gettarinfo(name, arcname) - - if tarinfo is None: - self._dbg(1, "tarfile: Unsupported type %r" % name) - return - - # Change or exclude the TarInfo object. - if filter is not None: - tarinfo = filter(tarinfo) - if tarinfo is None: - self._dbg(2, "tarfile: Excluded %r" % name) - return - - # Append the tar header and data to the archive. - if tarinfo.isreg(): - with bltn_open(name, "rb") as f: - self.addfile(tarinfo, f) - - elif tarinfo.isdir(): - self.addfile(tarinfo) - if recursive: - for f in sorted(os.listdir(name)): - self.add(os.path.join(name, f), os.path.join(arcname, f), - recursive, filter=filter) - - else: - self.addfile(tarinfo) - - def addfile(self, tarinfo, fileobj=None): - """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is - given, it should be a binary file, and tarinfo.size bytes are read - from it and added to the archive. You can create TarInfo objects - directly, or by using gettarinfo(). - """ - self._check("awx") - - tarinfo = copy.copy(tarinfo) - - buf = tarinfo.tobuf(self.format, self.encoding, self.errors) - self.fileobj.write(buf) - self.offset += len(buf) - bufsize=self.copybufsize - # If there's data to follow, append it. - if fileobj is not None: - copyfileobj(fileobj, self.fileobj, tarinfo.size, bufsize=bufsize) - blocks, remainder = divmod(tarinfo.size, BLOCKSIZE) - if remainder > 0: - self.fileobj.write(NUL * (BLOCKSIZE - remainder)) - blocks += 1 - self.offset += blocks * BLOCKSIZE - - self.members.append(tarinfo) - - def extractall(self, path=".", members=None, *, numeric_owner=False): - """Extract all members from the archive to the current working - directory and set owner, modification time and permissions on - directories afterwards. `path' specifies a different directory - to extract to. `members' is optional and must be a subset of the - list returned by getmembers(). If `numeric_owner` is True, only - the numbers for user/group names are used and not the names. - """ - directories = [] - - if members is None: - members = self - - for tarinfo in members: - if tarinfo.isdir(): - # Extract directories with a safe mode. - directories.append(tarinfo) - tarinfo = copy.copy(tarinfo) - tarinfo.mode = 0o700 - # Do not set_attrs directories, as we will do that further down - self.extract(tarinfo, path, set_attrs=not tarinfo.isdir(), - numeric_owner=numeric_owner) - - # Reverse sort directories. - directories.sort(key=lambda a: a.name) - directories.reverse() - - # Set correct owner, mtime and filemode on directories. - for tarinfo in directories: - dirpath = os.path.join(path, tarinfo.name) - try: - self.chown(tarinfo, dirpath, numeric_owner=numeric_owner) - self.utime(tarinfo, dirpath) - self.chmod(tarinfo, dirpath) - except ExtractError as e: - if self.errorlevel > 1: - raise - else: - self._dbg(1, "tarfile: %s" % e) - - def extract(self, member, path="", set_attrs=True, *, numeric_owner=False): - """Extract a member from the archive to the current working directory, - using its full name. Its file information is extracted as accurately - as possible. `member' may be a filename or a TarInfo object. You can - specify a different directory using `path'. File attributes (owner, - mtime, mode) are set unless `set_attrs' is False. If `numeric_owner` - is True, only the numbers for user/group names are used and not - the names. - """ - self._check("r") - - if isinstance(member, str): - tarinfo = self.getmember(member) - else: - tarinfo = member - - # Prepare the link target for makelink(). - if tarinfo.islnk(): - tarinfo._link_target = os.path.join(path, tarinfo.linkname) - - try: - self._extract_member(tarinfo, os.path.join(path, tarinfo.name), - set_attrs=set_attrs, - numeric_owner=numeric_owner) - except OSError as e: - if self.errorlevel > 0: - raise - else: - if e.filename is None: - self._dbg(1, "tarfile: %s" % e.strerror) - else: - self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) - except ExtractError as e: - if self.errorlevel > 1: - raise - else: - self._dbg(1, "tarfile: %s" % e) - - def extractfile(self, member): - """Extract a member from the archive as a file object. `member' may be - a filename or a TarInfo object. If `member' is a regular file or - a link, an io.BufferedReader object is returned. For all other - existing members, None is returned. If `member' does not appear - in the archive, KeyError is raised. - """ - self._check("r") - - if isinstance(member, str): - tarinfo = self.getmember(member) - else: - tarinfo = member - - if tarinfo.isreg() or tarinfo.type not in SUPPORTED_TYPES: - # Members with unknown types are treated as regular files. - return self.fileobject(self, tarinfo) - - elif tarinfo.islnk() or tarinfo.issym(): - if isinstance(self.fileobj, _Stream): - # A small but ugly workaround for the case that someone tries - # to extract a (sym)link as a file-object from a non-seekable - # stream of tar blocks. - raise StreamError("cannot extract (sym)link as file object") - else: - # A (sym)link's file object is its target's file object. - return self.extractfile(self._find_link_target(tarinfo)) - else: - # If there's no data associated with the member (directory, chrdev, - # blkdev, etc.), return None instead of a file object. - return None - - def _extract_member(self, tarinfo, targetpath, set_attrs=True, - numeric_owner=False): - """Extract the TarInfo object tarinfo to a physical - file called targetpath. - """ - # Fetch the TarInfo object for the given name - # and build the destination pathname, replacing - # forward slashes to platform specific separators. - targetpath = targetpath.rstrip("/") - targetpath = targetpath.replace("/", os.sep) - - # Create all upper directories. - upperdirs = os.path.dirname(targetpath) - if upperdirs and not os.path.exists(upperdirs): - # Create directories that are not part of the archive with - # default permissions. - os.makedirs(upperdirs) - - if tarinfo.islnk() or tarinfo.issym(): - self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) - else: - self._dbg(1, tarinfo.name) - - if tarinfo.isreg(): - self.makefile(tarinfo, targetpath) - elif tarinfo.isdir(): - self.makedir(tarinfo, targetpath) - elif tarinfo.isfifo(): - self.makefifo(tarinfo, targetpath) - elif tarinfo.ischr() or tarinfo.isblk(): - self.makedev(tarinfo, targetpath) - elif tarinfo.islnk() or tarinfo.issym(): - self.makelink(tarinfo, targetpath) - elif tarinfo.type not in SUPPORTED_TYPES: - self.makeunknown(tarinfo, targetpath) - else: - self.makefile(tarinfo, targetpath) - - if set_attrs: - self.chown(tarinfo, targetpath, numeric_owner) - if not tarinfo.issym(): - self.chmod(tarinfo, targetpath) - self.utime(tarinfo, targetpath) - - #-------------------------------------------------------------------------- - # Below are the different file methods. They are called via - # _extract_member() when extract() is called. They can be replaced in a - # subclass to implement other functionality. - - def makedir(self, tarinfo, targetpath): - """Make a directory called targetpath. - """ - try: - # Use a safe mode for the directory, the real mode is set - # later in _extract_member(). - os.mkdir(targetpath, 0o700) - except FileExistsError: - pass - - def makefile(self, tarinfo, targetpath): - """Make a file called targetpath. - """ - source = self.fileobj - source.seek(tarinfo.offset_data) - bufsize = self.copybufsize - with bltn_open(targetpath, "wb") as target: - if tarinfo.sparse is not None: - for offset, size in tarinfo.sparse: - target.seek(offset) - copyfileobj(source, target, size, ReadError, bufsize) - target.seek(tarinfo.size) - target.truncate() - else: - copyfileobj(source, target, tarinfo.size, ReadError, bufsize) - - def makeunknown(self, tarinfo, targetpath): - """Make a file from a TarInfo object with an unknown type - at targetpath. - """ - self.makefile(tarinfo, targetpath) - self._dbg(1, "tarfile: Unknown file type %r, " \ - "extracted as regular file." % tarinfo.type) - - def makefifo(self, tarinfo, targetpath): - """Make a fifo called targetpath. - """ - if hasattr(os, "mkfifo"): - os.mkfifo(targetpath) - else: - raise ExtractError("fifo not supported by system") - - def makedev(self, tarinfo, targetpath): - """Make a character or block device called targetpath. - """ - if not hasattr(os, "mknod") or not hasattr(os, "makedev"): - raise ExtractError("special devices not supported by system") - - mode = tarinfo.mode - if tarinfo.isblk(): - mode |= stat.S_IFBLK - else: - mode |= stat.S_IFCHR - - os.mknod(targetpath, mode, - os.makedev(tarinfo.devmajor, tarinfo.devminor)) - - def makelink(self, tarinfo, targetpath): - """Make a (symbolic) link called targetpath. If it cannot be created - (platform limitation), we try to make a copy of the referenced file - instead of a link. - """ - try: - # For systems that support symbolic and hard links. - if tarinfo.issym(): - if os.path.lexists(targetpath): - # Avoid FileExistsError on following os.symlink. - os.unlink(targetpath) - os.symlink(tarinfo.linkname, targetpath) - else: - # See extract(). - if os.path.exists(tarinfo._link_target): - os.link(tarinfo._link_target, targetpath) - else: - self._extract_member(self._find_link_target(tarinfo), - targetpath) - except symlink_exception: - try: - self._extract_member(self._find_link_target(tarinfo), - targetpath) - except KeyError: - raise ExtractError("unable to resolve link inside archive") from None - - def chown(self, tarinfo, targetpath, numeric_owner): - """Set owner of targetpath according to tarinfo. If numeric_owner - is True, use .gid/.uid instead of .gname/.uname. If numeric_owner - is False, fall back to .gid/.uid when the search based on name - fails. - """ - if hasattr(os, "geteuid") and os.geteuid() == 0: - # We have to be root to do so. - g = tarinfo.gid - u = tarinfo.uid - if not numeric_owner: - try: - if grp: - g = grp.getgrnam(tarinfo.gname)[2] - except KeyError: - pass - try: - if pwd: - u = pwd.getpwnam(tarinfo.uname)[2] - except KeyError: - pass - try: - if tarinfo.issym() and hasattr(os, "lchown"): - os.lchown(targetpath, u, g) - else: - os.chown(targetpath, u, g) - except OSError as e: - raise ExtractError("could not change owner") from e - - def chmod(self, tarinfo, targetpath): - """Set file permissions of targetpath according to tarinfo. - """ - try: - os.chmod(targetpath, tarinfo.mode) - except OSError as e: - raise ExtractError("could not change mode") from e - - def utime(self, tarinfo, targetpath): - """Set modification time of targetpath according to tarinfo. - """ - if not hasattr(os, 'utime'): - return - try: - os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) - except OSError as e: - raise ExtractError("could not change modification time") from e - - #-------------------------------------------------------------------------- - def next(self): - """Return the next member of the archive as a TarInfo object, when - TarFile is opened for reading. Return None if there is no more - available. - """ - self._check("ra") - if self.firstmember is not None: - m = self.firstmember - self.firstmember = None - return m - - # Advance the file pointer. - if self.offset != self.fileobj.tell(): - if self.offset == 0: - return None - self.fileobj.seek(self.offset - 1) - if not self.fileobj.read(1): - raise ReadError("unexpected end of data") - - # Read the next block. - tarinfo = None - while True: - try: - tarinfo = self.tarinfo.fromtarfile(self) - except EOFHeaderError as e: - if self.ignore_zeros: - self._dbg(2, "0x%X: %s" % (self.offset, e)) - self.offset += BLOCKSIZE - continue - except InvalidHeaderError as e: - if self.ignore_zeros: - self._dbg(2, "0x%X: %s" % (self.offset, e)) - self.offset += BLOCKSIZE - continue - elif self.offset == 0: - raise ReadError(str(e)) from None - except EmptyHeaderError: - if self.offset == 0: - raise ReadError("empty file") from None - except TruncatedHeaderError as e: - if self.offset == 0: - raise ReadError(str(e)) from None - except SubsequentHeaderError as e: - raise ReadError(str(e)) from None - except Exception as e: - try: - import zlib - if isinstance(e, zlib.error): - raise ReadError(f'zlib error: {e}') from None - else: - raise e - except ImportError: - raise e - break - - if tarinfo is not None: - self.members.append(tarinfo) - else: - self._loaded = True - - return tarinfo - - #-------------------------------------------------------------------------- - # Little helper methods: - - def _getmember(self, name, tarinfo=None, normalize=False): - """Find an archive member by name from bottom to top. - If tarinfo is given, it is used as the starting point. - """ - # Ensure that all members have been loaded. - members = self.getmembers() - - # Limit the member search list up to tarinfo. - if tarinfo is not None: - members = members[:members.index(tarinfo)] - - if normalize: - name = os.path.normpath(name) - - for member in reversed(members): - if normalize: - member_name = os.path.normpath(member.name) - else: - member_name = member.name - - if name == member_name: - return member - - def _load(self): - """Read through the entire archive file and look for readable - members. - """ - while True: - tarinfo = self.next() - if tarinfo is None: - break - self._loaded = True - - def _check(self, mode=None): - """Check if TarFile is still open, and if the operation's mode - corresponds to TarFile's mode. - """ - if self.closed: - raise OSError("%s is closed" % self.__class__.__name__) - if mode is not None and self.mode not in mode: - raise OSError("bad operation for mode %r" % self.mode) - - def _find_link_target(self, tarinfo): - """Find the target member of a symlink or hardlink member in the - archive. - """ - if tarinfo.issym(): - # Always search the entire archive. - linkname = "/".join(filter(None, (os.path.dirname(tarinfo.name), tarinfo.linkname))) - limit = None - else: - # Search the archive before the link, because a hard link is - # just a reference to an already archived file. - linkname = tarinfo.linkname - limit = tarinfo - - member = self._getmember(linkname, tarinfo=limit, normalize=True) - if member is None: - raise KeyError("linkname %r not found" % linkname) - return member - - def __iter__(self): - """Provide an iterator object. - """ - if self._loaded: - yield from self.members - return - - # Yield items using TarFile's next() method. - # When all members have been read, set TarFile as _loaded. - index = 0 - # Fix for SF #1100429: Under rare circumstances it can - # happen that getmembers() is called during iteration, - # which will have already exhausted the next() method. - if self.firstmember is not None: - tarinfo = self.next() - index += 1 - yield tarinfo - - while True: - if index < len(self.members): - tarinfo = self.members[index] - elif not self._loaded: - tarinfo = self.next() - if not tarinfo: - self._loaded = True - return - else: - return - index += 1 - yield tarinfo - - def _dbg(self, level, msg): - """Write debugging output to sys.stderr. - """ - if level <= self.debug: - print(msg, file=sys.stderr) - - def __enter__(self): - self._check() - return self - - def __exit__(self, type, value, traceback): - if type is None: - self.close() - else: - # An exception occurred. We must not call close() because - # it would try to write end-of-archive blocks and padding. - if not self._extfileobj: - self.fileobj.close() - self.closed = True - -#-------------------- -# exported functions -#-------------------- -def is_tarfile(name): - """Return True if name points to a tar archive that we - are able to handle, else return False. - - 'name' should be a string, file, or file-like object. - """ - try: - if hasattr(name, "read"): - pos = name.tell() - t = open(fileobj=name) - name.seek(pos) - else: - t = open(name) - t.close() - return True - except TarError: - return False - -open = TarFile.open - - -def main(): - import argparse - - description = 'A simple command-line interface for tarfile module.' - parser = argparse.ArgumentParser(description=description) - parser.add_argument('-v', '--verbose', action='store_true', default=False, - help='Verbose output') - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('-l', '--list', metavar='', - help='Show listing of a tarfile') - group.add_argument('-e', '--extract', nargs='+', - metavar=('', ''), - help='Extract tarfile into target dir') - group.add_argument('-c', '--create', nargs='+', - metavar=('', ''), - help='Create tarfile from sources') - group.add_argument('-t', '--test', metavar='', - help='Test if a tarfile is valid') - args = parser.parse_args() - - if args.test is not None: - src = args.test - if is_tarfile(src): - with open(src, 'r') as tar: - tar.getmembers() - print(tar.getmembers(), file=sys.stderr) - if args.verbose: - print('{!r} is a tar archive.'.format(src)) - else: - parser.exit(1, '{!r} is not a tar archive.\n'.format(src)) - - elif args.list is not None: - src = args.list - if is_tarfile(src): - with TarFile.open(src, 'r:*') as tf: - tf.list(verbose=args.verbose) - else: - parser.exit(1, '{!r} is not a tar archive.\n'.format(src)) - - elif args.extract is not None: - if len(args.extract) == 1: - src = args.extract[0] - curdir = os.curdir - elif len(args.extract) == 2: - src, curdir = args.extract - else: - parser.exit(1, parser.format_help()) - - if is_tarfile(src): - with TarFile.open(src, 'r:*') as tf: - tf.extractall(path=curdir) - if args.verbose: - if curdir == '.': - msg = '{!r} file is extracted.'.format(src) - else: - msg = ('{!r} file is extracted ' - 'into {!r} directory.').format(src, curdir) - print(msg) - else: - parser.exit(1, '{!r} is not a tar archive.\n'.format(src)) - - elif args.create is not None: - tar_name = args.create.pop(0) - _, ext = os.path.splitext(tar_name) - compressions = { - # gz - '.gz': 'gz', - '.tgz': 'gz', - # xz - '.xz': 'xz', - '.txz': 'xz', - # bz2 - '.bz2': 'bz2', - '.tbz': 'bz2', - '.tbz2': 'bz2', - '.tb2': 'bz2', - } - tar_mode = 'w:' + compressions[ext] if ext in compressions else 'w' - tar_files = args.create - - with TarFile.open(tar_name, tar_mode) as tf: - for file_name in tar_files: - tf.add(file_name) - - if args.verbose: - print('{!r} file created.'.format(tar_name)) - -if __name__ == '__main__': - main() diff --git a/python/Lib/tempfile.py b/python/Lib/tempfile.py deleted file mode 100644 index dcb8cd0..0000000 --- a/python/Lib/tempfile.py +++ /dev/null @@ -1,910 +0,0 @@ -"""Temporary files. - -This module provides generic, low- and high-level interfaces for -creating temporary files and directories. All of the interfaces -provided by this module can be used without fear of race conditions -except for 'mktemp'. 'mktemp' is subject to race conditions and -should not be used; it is provided for backward compatibility only. - -The default path names are returned as str. If you supply bytes as -input, all return values will be in bytes. Ex: - - >>> tempfile.mkstemp() - (4, '/tmp/tmptpu9nin8') - >>> tempfile.mkdtemp(suffix=b'') - b'/tmp/tmppbi8f0hy' - -This module also provides some data items to the user: - - TMP_MAX - maximum number of names that will be tried before - giving up. - tempdir - If this is set to a string before the first use of - any routine from this module, it will be considered as - another candidate location to store temporary files. -""" - -__all__ = [ - "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces - "SpooledTemporaryFile", "TemporaryDirectory", - "mkstemp", "mkdtemp", # low level safe interfaces - "mktemp", # deprecated unsafe interface - "TMP_MAX", "gettempprefix", # constants - "tempdir", "gettempdir", - "gettempprefixb", "gettempdirb", - ] - - -# Imports. - -import functools as _functools -import warnings as _warnings -import io as _io -import os as _os -import shutil as _shutil -import errno as _errno -from random import Random as _Random -import sys as _sys -import types as _types -import weakref as _weakref -import _thread -_allocate_lock = _thread.allocate_lock - -_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL -if hasattr(_os, 'O_NOFOLLOW'): - _text_openflags |= _os.O_NOFOLLOW - -_bin_openflags = _text_openflags -if hasattr(_os, 'O_BINARY'): - _bin_openflags |= _os.O_BINARY - -if hasattr(_os, 'TMP_MAX'): - TMP_MAX = _os.TMP_MAX -else: - TMP_MAX = 10000 - -# This variable _was_ unused for legacy reasons, see issue 10354. -# But as of 3.5 we actually use it at runtime so changing it would -# have a possibly desirable side effect... But we do not want to support -# that as an API. It is undocumented on purpose. Do not depend on this. -template = "tmp" - -# Internal routines. - -_once_lock = _allocate_lock() - - -def _exists(fn): - try: - _os.lstat(fn) - except OSError: - return False - else: - return True - - -def _infer_return_type(*args): - """Look at the type of all args and divine their implied return type.""" - return_type = None - for arg in args: - if arg is None: - continue - - if isinstance(arg, _os.PathLike): - arg = _os.fspath(arg) - - if isinstance(arg, bytes): - if return_type is str: - raise TypeError("Can't mix bytes and non-bytes in " - "path components.") - return_type = bytes - else: - if return_type is bytes: - raise TypeError("Can't mix bytes and non-bytes in " - "path components.") - return_type = str - if return_type is None: - if tempdir is None or isinstance(tempdir, str): - return str # tempfile APIs return a str by default. - else: - # we could check for bytes but it'll fail later on anyway - return bytes - return return_type - - -def _sanitize_params(prefix, suffix, dir): - """Common parameter processing for most APIs in this module.""" - output_type = _infer_return_type(prefix, suffix, dir) - if suffix is None: - suffix = output_type() - if prefix is None: - if output_type is str: - prefix = template - else: - prefix = _os.fsencode(template) - if dir is None: - if output_type is str: - dir = gettempdir() - else: - dir = gettempdirb() - return prefix, suffix, dir, output_type - - -class _RandomNameSequence: - """An instance of _RandomNameSequence generates an endless - sequence of unpredictable strings which can safely be incorporated - into file names. Each string is eight characters long. Multiple - threads can safely use the same instance at the same time. - - _RandomNameSequence is an iterator.""" - - characters = "abcdefghijklmnopqrstuvwxyz0123456789_" - - @property - def rng(self): - cur_pid = _os.getpid() - if cur_pid != getattr(self, '_rng_pid', None): - self._rng = _Random() - self._rng_pid = cur_pid - return self._rng - - def __iter__(self): - return self - - def __next__(self): - return ''.join(self.rng.choices(self.characters, k=8)) - -def _candidate_tempdir_list(): - """Generate a list of candidate temporary directories which - _get_default_tempdir will try.""" - - dirlist = [] - - # First, try the environment. - for envname in 'TMPDIR', 'TEMP', 'TMP': - dirname = _os.getenv(envname) - if dirname: dirlist.append(dirname) - - # Failing that, try OS-specific locations. - if _os.name == 'nt': - dirlist.extend([ _os.path.expanduser(r'~\AppData\Local\Temp'), - _os.path.expandvars(r'%SYSTEMROOT%\Temp'), - r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ]) - else: - dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ]) - - # As a last resort, the current directory. - try: - dirlist.append(_os.getcwd()) - except (AttributeError, OSError): - dirlist.append(_os.curdir) - - return dirlist - -def _get_default_tempdir(): - """Calculate the default directory to use for temporary files. - This routine should be called exactly once. - - We determine whether or not a candidate temp dir is usable by - trying to create and write to a file in that directory. If this - is successful, the test file is deleted. To prevent denial of - service, the name of the test file must be randomized.""" - - namer = _RandomNameSequence() - dirlist = _candidate_tempdir_list() - - for dir in dirlist: - if dir != _os.curdir: - dir = _os.path.abspath(dir) - # Try only a few names per directory. - for seq in range(100): - name = next(namer) - filename = _os.path.join(dir, name) - try: - fd = _os.open(filename, _bin_openflags, 0o600) - try: - try: - _os.write(fd, b'blat') - finally: - _os.close(fd) - finally: - _os.unlink(filename) - return dir - except FileExistsError: - pass - except PermissionError: - # This exception is thrown when a directory with the chosen name - # already exists on windows. - if (_os.name == 'nt' and _os.path.isdir(dir) and - _os.access(dir, _os.W_OK)): - continue - break # no point trying more names in this directory - except OSError: - break # no point trying more names in this directory - raise FileNotFoundError(_errno.ENOENT, - "No usable temporary directory found in %s" % - dirlist) - -_name_sequence = None - -def _get_candidate_names(): - """Common setup sequence for all user-callable interfaces.""" - - global _name_sequence - if _name_sequence is None: - _once_lock.acquire() - try: - if _name_sequence is None: - _name_sequence = _RandomNameSequence() - finally: - _once_lock.release() - return _name_sequence - - -def _mkstemp_inner(dir, pre, suf, flags, output_type): - """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile.""" - - dir = _os.path.abspath(dir) - names = _get_candidate_names() - if output_type is bytes: - names = map(_os.fsencode, names) - - for seq in range(TMP_MAX): - name = next(names) - file = _os.path.join(dir, pre + name + suf) - _sys.audit("tempfile.mkstemp", file) - try: - fd = _os.open(file, flags, 0o600) - except FileExistsError: - continue # try again - except PermissionError: - # This exception is thrown when a directory with the chosen name - # already exists on windows. - if (_os.name == 'nt' and _os.path.isdir(dir) and - _os.access(dir, _os.W_OK)): - continue - else: - raise - return fd, file - - raise FileExistsError(_errno.EEXIST, - "No usable temporary file name found") - - -# User visible interfaces. - -def gettempprefix(): - """The default prefix for temporary directories as string.""" - return _os.fsdecode(template) - -def gettempprefixb(): - """The default prefix for temporary directories as bytes.""" - return _os.fsencode(template) - -tempdir = None - -def _gettempdir(): - """Private accessor for tempfile.tempdir.""" - global tempdir - if tempdir is None: - _once_lock.acquire() - try: - if tempdir is None: - tempdir = _get_default_tempdir() - finally: - _once_lock.release() - return tempdir - -def gettempdir(): - """Returns tempfile.tempdir as str.""" - return _os.fsdecode(_gettempdir()) - -def gettempdirb(): - """Returns tempfile.tempdir as bytes.""" - return _os.fsencode(_gettempdir()) - -def mkstemp(suffix=None, prefix=None, dir=None, text=False): - """User-callable function to create and return a unique temporary - file. The return value is a pair (fd, name) where fd is the - file descriptor returned by os.open, and name is the filename. - - If 'suffix' is not None, the file name will end with that suffix, - otherwise there will be no suffix. - - If 'prefix' is not None, the file name will begin with that prefix, - otherwise a default prefix is used. - - If 'dir' is not None, the file will be created in that directory, - otherwise a default directory is used. - - If 'text' is specified and true, the file is opened in text - mode. Else (the default) the file is opened in binary mode. - - If any of 'suffix', 'prefix' and 'dir' are not None, they must be the - same type. If they are bytes, the returned name will be bytes; str - otherwise. - - The file is readable and writable only by the creating user ID. - If the operating system uses permission bits to indicate whether a - file is executable, the file is executable by no one. The file - descriptor is not inherited by children of this process. - - Caller is responsible for deleting the file when done with it. - """ - - prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) - - if text: - flags = _text_openflags - else: - flags = _bin_openflags - - return _mkstemp_inner(dir, prefix, suffix, flags, output_type) - - -def mkdtemp(suffix=None, prefix=None, dir=None): - """User-callable function to create and return a unique temporary - directory. The return value is the pathname of the directory. - - Arguments are as for mkstemp, except that the 'text' argument is - not accepted. - - The directory is readable, writable, and searchable only by the - creating user. - - Caller is responsible for deleting the directory when done with it. - """ - - prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) - - names = _get_candidate_names() - if output_type is bytes: - names = map(_os.fsencode, names) - - for seq in range(TMP_MAX): - name = next(names) - file = _os.path.join(dir, prefix + name + suffix) - _sys.audit("tempfile.mkdtemp", file) - try: - _os.mkdir(file, 0o700) - except FileExistsError: - continue # try again - except PermissionError: - # This exception is thrown when a directory with the chosen name - # already exists on windows. - if (_os.name == 'nt' and _os.path.isdir(dir) and - _os.access(dir, _os.W_OK)): - continue - else: - raise - return file - - raise FileExistsError(_errno.EEXIST, - "No usable temporary directory name found") - -def mktemp(suffix="", prefix=template, dir=None): - """User-callable function to return a unique temporary file name. The - file is not created. - - Arguments are similar to mkstemp, except that the 'text' argument is - not accepted, and suffix=None, prefix=None and bytes file names are not - supported. - - THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED. The file name may - refer to a file that did not exist at some point, but by the time - you get around to creating it, someone else may have beaten you to - the punch. - """ - -## from warnings import warn as _warn -## _warn("mktemp is a potential security risk to your program", -## RuntimeWarning, stacklevel=2) - - if dir is None: - dir = gettempdir() - - names = _get_candidate_names() - for seq in range(TMP_MAX): - name = next(names) - file = _os.path.join(dir, prefix + name + suffix) - if not _exists(file): - return file - - raise FileExistsError(_errno.EEXIST, - "No usable temporary filename found") - - -class _TemporaryFileCloser: - """A separate object allowing proper closing of a temporary file's - underlying file object, without adding a __del__ method to the - temporary file.""" - - file = None # Set here since __del__ checks it - close_called = False - - def __init__(self, file, name, delete=True): - self.file = file - self.name = name - self.delete = delete - - # NT provides delete-on-close as a primitive, so we don't need - # the wrapper to do anything special. We still use it so that - # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. - if _os.name != 'nt': - # Cache the unlinker so we don't get spurious errors at - # shutdown when the module-level "os" is None'd out. Note - # that this must be referenced as self.unlink, because the - # name TemporaryFileWrapper may also get None'd out before - # __del__ is called. - - def close(self, unlink=_os.unlink): - if not self.close_called and self.file is not None: - self.close_called = True - try: - self.file.close() - finally: - if self.delete: - unlink(self.name) - - # Need to ensure the file is deleted on __del__ - def __del__(self): - self.close() - - else: - def close(self): - if not self.close_called: - self.close_called = True - self.file.close() - - -class _TemporaryFileWrapper: - """Temporary file wrapper - - This class provides a wrapper around files opened for - temporary use. In particular, it seeks to automatically - remove the file when it is no longer needed. - """ - - def __init__(self, file, name, delete=True): - self.file = file - self.name = name - self.delete = delete - self._closer = _TemporaryFileCloser(file, name, delete) - - def __getattr__(self, name): - # Attribute lookups are delegated to the underlying file - # and cached for non-numeric results - # (i.e. methods are cached, closed and friends are not) - file = self.__dict__['file'] - a = getattr(file, name) - if hasattr(a, '__call__'): - func = a - @_functools.wraps(func) - def func_wrapper(*args, **kwargs): - return func(*args, **kwargs) - # Avoid closing the file as long as the wrapper is alive, - # see issue #18879. - func_wrapper._closer = self._closer - a = func_wrapper - if not isinstance(a, int): - setattr(self, name, a) - return a - - # The underlying __enter__ method returns the wrong object - # (self.file) so override it to return the wrapper - def __enter__(self): - self.file.__enter__() - return self - - # Need to trap __exit__ as well to ensure the file gets - # deleted when used in a with statement - def __exit__(self, exc, value, tb): - result = self.file.__exit__(exc, value, tb) - self.close() - return result - - def close(self): - """ - Close the temporary file, possibly deleting it. - """ - self._closer.close() - - # iter() doesn't use __getattr__ to find the __iter__ method - def __iter__(self): - # Don't return iter(self.file), but yield from it to avoid closing - # file as long as it's being used as iterator (see issue #23700). We - # can't use 'yield from' here because iter(file) returns the file - # object itself, which has a close method, and thus the file would get - # closed when the generator is finalized, due to PEP380 semantics. - for line in self.file: - yield line - - -def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, - newline=None, suffix=None, prefix=None, - dir=None, delete=True, *, errors=None): - """Create and return a temporary file. - Arguments: - 'prefix', 'suffix', 'dir' -- as for mkstemp. - 'mode' -- the mode argument to io.open (default "w+b"). - 'buffering' -- the buffer size argument to io.open (default -1). - 'encoding' -- the encoding argument to io.open (default None) - 'newline' -- the newline argument to io.open (default None) - 'delete' -- whether the file is deleted on close (default True). - 'errors' -- the errors argument to io.open (default None) - The file is created as mkstemp() would do it. - - Returns an object with a file-like interface; the name of the file - is accessible as its 'name' attribute. The file will be automatically - deleted when it is closed unless the 'delete' argument is set to False. - - On POSIX, NamedTemporaryFiles cannot be automatically deleted if - the creating process is terminated abruptly with a SIGKILL signal. - Windows can delete the file even in this case. - """ - - prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) - - flags = _bin_openflags - - # Setting O_TEMPORARY in the flags causes the OS to delete - # the file when it is closed. This is only supported by Windows. - if _os.name == 'nt' and delete: - flags |= _os.O_TEMPORARY - - if "b" not in mode: - encoding = _io.text_encoding(encoding) - - name = None - def opener(*args): - nonlocal name - fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type) - return fd - try: - file = _io.open(dir, mode, buffering=buffering, - newline=newline, encoding=encoding, errors=errors, - opener=opener) - try: - raw = getattr(file, 'buffer', file) - raw = getattr(raw, 'raw', raw) - raw.name = name - return _TemporaryFileWrapper(file, name, delete) - except: - file.close() - raise - except: - if name is not None and not (_os.name == 'nt' and delete): - _os.unlink(name) - raise - -if _os.name != 'posix' or _sys.platform == 'cygwin': - # On non-POSIX and Cygwin systems, assume that we cannot unlink a file - # while it is open. - TemporaryFile = NamedTemporaryFile - -else: - # Is the O_TMPFILE flag available and does it work? - # The flag is set to False if os.open(dir, os.O_TMPFILE) raises an - # IsADirectoryError exception - _O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE') - - def TemporaryFile(mode='w+b', buffering=-1, encoding=None, - newline=None, suffix=None, prefix=None, - dir=None, *, errors=None): - """Create and return a temporary file. - Arguments: - 'prefix', 'suffix', 'dir' -- as for mkstemp. - 'mode' -- the mode argument to io.open (default "w+b"). - 'buffering' -- the buffer size argument to io.open (default -1). - 'encoding' -- the encoding argument to io.open (default None) - 'newline' -- the newline argument to io.open (default None) - 'errors' -- the errors argument to io.open (default None) - The file is created as mkstemp() would do it. - - Returns an object with a file-like interface. The file has no - name, and will cease to exist when it is closed. - """ - global _O_TMPFILE_WORKS - - if "b" not in mode: - encoding = _io.text_encoding(encoding) - - prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) - - flags = _bin_openflags - if _O_TMPFILE_WORKS: - fd = None - def opener(*args): - nonlocal fd - flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT - fd = _os.open(dir, flags2, 0o600) - return fd - try: - file = _io.open(dir, mode, buffering=buffering, - newline=newline, encoding=encoding, - errors=errors, opener=opener) - raw = getattr(file, 'buffer', file) - raw = getattr(raw, 'raw', raw) - raw.name = fd - return file - except IsADirectoryError: - # Linux kernel older than 3.11 ignores the O_TMPFILE flag: - # O_TMPFILE is read as O_DIRECTORY. Trying to open a directory - # with O_RDWR|O_DIRECTORY fails with IsADirectoryError, a - # directory cannot be open to write. Set flag to False to not - # try again. - _O_TMPFILE_WORKS = False - except OSError: - # The filesystem of the directory does not support O_TMPFILE. - # For example, OSError(95, 'Operation not supported'). - # - # On Linux kernel older than 3.11, trying to open a regular - # file (or a symbolic link to a regular file) with O_TMPFILE - # fails with NotADirectoryError, because O_TMPFILE is read as - # O_DIRECTORY. - pass - # Fallback to _mkstemp_inner(). - - fd = None - def opener(*args): - nonlocal fd - fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type) - try: - _os.unlink(name) - except BaseException as e: - _os.close(fd) - raise - return fd - file = _io.open(dir, mode, buffering=buffering, - newline=newline, encoding=encoding, errors=errors, - opener=opener) - raw = getattr(file, 'buffer', file) - raw = getattr(raw, 'raw', raw) - raw.name = fd - return file - -class SpooledTemporaryFile(_io.IOBase): - """Temporary file wrapper, specialized to switch from BytesIO - or StringIO to a real file when it exceeds a certain size or - when a fileno is needed. - """ - _rolled = False - - def __init__(self, max_size=0, mode='w+b', buffering=-1, - encoding=None, newline=None, - suffix=None, prefix=None, dir=None, *, errors=None): - if 'b' in mode: - self._file = _io.BytesIO() - else: - encoding = _io.text_encoding(encoding) - self._file = _io.TextIOWrapper(_io.BytesIO(), - encoding=encoding, errors=errors, - newline=newline) - self._max_size = max_size - self._rolled = False - self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering, - 'suffix': suffix, 'prefix': prefix, - 'encoding': encoding, 'newline': newline, - 'dir': dir, 'errors': errors} - - __class_getitem__ = classmethod(_types.GenericAlias) - - def _check(self, file): - if self._rolled: return - max_size = self._max_size - if max_size and file.tell() > max_size: - self.rollover() - - def rollover(self): - if self._rolled: return - file = self._file - newfile = self._file = TemporaryFile(**self._TemporaryFileArgs) - del self._TemporaryFileArgs - - pos = file.tell() - if hasattr(newfile, 'buffer'): - newfile.buffer.write(file.detach().getvalue()) - else: - newfile.write(file.getvalue()) - newfile.seek(pos, 0) - - self._rolled = True - - # The method caching trick from NamedTemporaryFile - # won't work here, because _file may change from a - # BytesIO/StringIO instance to a real file. So we list - # all the methods directly. - - # Context management protocol - def __enter__(self): - if self._file.closed: - raise ValueError("Cannot enter context with closed file") - return self - - def __exit__(self, exc, value, tb): - self._file.close() - - # file protocol - def __iter__(self): - return self._file.__iter__() - - def __del__(self): - if not self.closed: - _warnings.warn( - "Unclosed file {!r}".format(self), - ResourceWarning, - stacklevel=2, - source=self - ) - self.close() - - def close(self): - self._file.close() - - @property - def closed(self): - return self._file.closed - - @property - def encoding(self): - return self._file.encoding - - @property - def errors(self): - return self._file.errors - - def fileno(self): - self.rollover() - return self._file.fileno() - - def flush(self): - self._file.flush() - - def isatty(self): - return self._file.isatty() - - @property - def mode(self): - try: - return self._file.mode - except AttributeError: - return self._TemporaryFileArgs['mode'] - - @property - def name(self): - try: - return self._file.name - except AttributeError: - return None - - @property - def newlines(self): - return self._file.newlines - - def readable(self): - return self._file.readable() - - def read(self, *args): - return self._file.read(*args) - - def read1(self, *args): - return self._file.read1(*args) - - def readinto(self, b): - return self._file.readinto(b) - - def readinto1(self, b): - return self._file.readinto1(b) - - def readline(self, *args): - return self._file.readline(*args) - - def readlines(self, *args): - return self._file.readlines(*args) - - def seekable(self): - return self._file.seekable() - - def seek(self, *args): - return self._file.seek(*args) - - def tell(self): - return self._file.tell() - - def truncate(self, size=None): - if size is None: - return self._file.truncate() - else: - if size > self._max_size: - self.rollover() - return self._file.truncate(size) - - def writable(self): - return self._file.writable() - - def write(self, s): - file = self._file - rv = file.write(s) - self._check(file) - return rv - - def writelines(self, iterable): - file = self._file - rv = file.writelines(iterable) - self._check(file) - return rv - - def detach(self): - return self._file.detach() - - -class TemporaryDirectory: - """Create and return a temporary directory. This has the same - behavior as mkdtemp but can be used as a context manager. For - example: - - with TemporaryDirectory() as tmpdir: - ... - - Upon exiting the context, the directory and everything contained - in it are removed. - """ - - def __init__(self, suffix=None, prefix=None, dir=None, - ignore_cleanup_errors=False): - self.name = mkdtemp(suffix, prefix, dir) - self._ignore_cleanup_errors = ignore_cleanup_errors - self._finalizer = _weakref.finalize( - self, self._cleanup, self.name, - warn_message="Implicitly cleaning up {!r}".format(self), - ignore_errors=self._ignore_cleanup_errors) - - @classmethod - def _rmtree(cls, name, ignore_errors=False): - def onerror(func, path, exc_info): - if issubclass(exc_info[0], PermissionError): - def resetperms(path): - try: - _os.chflags(path, 0) - except AttributeError: - pass - _os.chmod(path, 0o700) - - try: - if path != name: - resetperms(_os.path.dirname(path)) - resetperms(path) - - try: - _os.unlink(path) - # PermissionError is raised on FreeBSD for directories - except (IsADirectoryError, PermissionError): - cls._rmtree(path, ignore_errors=ignore_errors) - except FileNotFoundError: - pass - elif issubclass(exc_info[0], FileNotFoundError): - pass - else: - if not ignore_errors: - raise - - _shutil.rmtree(name, onerror=onerror) - - @classmethod - def _cleanup(cls, name, warn_message, ignore_errors=False): - cls._rmtree(name, ignore_errors=ignore_errors) - _warnings.warn(warn_message, ResourceWarning) - - def __repr__(self): - return "<{} {!r}>".format(self.__class__.__name__, self.name) - - def __enter__(self): - return self.name - - def __exit__(self, exc, value, tb): - self.cleanup() - - def cleanup(self): - if self._finalizer.detach() or _os.path.exists(self.name): - self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors) - - __class_getitem__ = classmethod(_types.GenericAlias) diff --git a/python/Lib/textwrap.py b/python/Lib/textwrap.py deleted file mode 100644 index 07733df..0000000 --- a/python/Lib/textwrap.py +++ /dev/null @@ -1,491 +0,0 @@ -"""Text wrapping and filling. -""" - -# Copyright (C) 1999-2001 Gregory P. Ward. -# Copyright (C) 2002, 2003 Python Software Foundation. -# Written by Greg Ward - -import re - -__all__ = ['TextWrapper', 'wrap', 'fill', 'dedent', 'indent', 'shorten'] - -# Hardcode the recognized whitespace characters to the US-ASCII -# whitespace characters. The main reason for doing this is that -# some Unicode spaces (like \u00a0) are non-breaking whitespaces. -_whitespace = '\t\n\x0b\x0c\r ' - -class TextWrapper: - """ - Object for wrapping/filling text. The public interface consists of - the wrap() and fill() methods; the other methods are just there for - subclasses to override in order to tweak the default behaviour. - If you want to completely replace the main wrapping algorithm, - you'll probably have to override _wrap_chunks(). - - Several instance attributes control various aspects of wrapping: - width (default: 70) - the maximum width of wrapped lines (unless break_long_words - is false) - initial_indent (default: "") - string that will be prepended to the first line of wrapped - output. Counts towards the line's width. - subsequent_indent (default: "") - string that will be prepended to all lines save the first - of wrapped output; also counts towards each line's width. - expand_tabs (default: true) - Expand tabs in input text to spaces before further processing. - Each tab will become 0 .. 'tabsize' spaces, depending on its position - in its line. If false, each tab is treated as a single character. - tabsize (default: 8) - Expand tabs in input text to 0 .. 'tabsize' spaces, unless - 'expand_tabs' is false. - replace_whitespace (default: true) - Replace all whitespace characters in the input text by spaces - after tab expansion. Note that if expand_tabs is false and - replace_whitespace is true, every tab will be converted to a - single space! - fix_sentence_endings (default: false) - Ensure that sentence-ending punctuation is always followed - by two spaces. Off by default because the algorithm is - (unavoidably) imperfect. - break_long_words (default: true) - Break words longer than 'width'. If false, those words will not - be broken, and some lines might be longer than 'width'. - break_on_hyphens (default: true) - Allow breaking hyphenated words. If true, wrapping will occur - preferably on whitespaces and right after hyphens part of - compound words. - drop_whitespace (default: true) - Drop leading and trailing whitespace from lines. - max_lines (default: None) - Truncate wrapped lines. - placeholder (default: ' [...]') - Append to the last line of truncated text. - """ - - unicode_whitespace_trans = dict.fromkeys(map(ord, _whitespace), ord(' ')) - - # This funky little regex is just the trick for splitting - # text up into word-wrappable chunks. E.g. - # "Hello there -- you goof-ball, use the -b option!" - # splits into - # Hello/ /there/ /--/ /you/ /goof-/ball,/ /use/ /the/ /-b/ /option! - # (after stripping out empty strings). - word_punct = r'[\w!"\'&.,?]' - letter = r'[^\d\W]' - whitespace = r'[%s]' % re.escape(_whitespace) - nowhitespace = '[^' + whitespace[1:] - wordsep_re = re.compile(r''' - ( # any whitespace - %(ws)s+ - | # em-dash between words - (?<=%(wp)s) -{2,} (?=\w) - | # word, possibly hyphenated - %(nws)s+? (?: - # hyphenated word - -(?: (?<=%(lt)s{2}-) | (?<=%(lt)s-%(lt)s-)) - (?= %(lt)s -? %(lt)s) - | # end of word - (?=%(ws)s|\Z) - | # em-dash - (?<=%(wp)s) (?=-{2,}\w) - ) - )''' % {'wp': word_punct, 'lt': letter, - 'ws': whitespace, 'nws': nowhitespace}, - re.VERBOSE) - del word_punct, letter, nowhitespace - - # This less funky little regex just split on recognized spaces. E.g. - # "Hello there -- you goof-ball, use the -b option!" - # splits into - # Hello/ /there/ /--/ /you/ /goof-ball,/ /use/ /the/ /-b/ /option!/ - wordsep_simple_re = re.compile(r'(%s+)' % whitespace) - del whitespace - - # XXX this is not locale- or charset-aware -- string.lowercase - # is US-ASCII only (and therefore English-only) - sentence_end_re = re.compile(r'[a-z]' # lowercase letter - r'[\.\!\?]' # sentence-ending punct. - r'[\"\']?' # optional end-of-quote - r'\Z') # end of chunk - - def __init__(self, - width=70, - initial_indent="", - subsequent_indent="", - expand_tabs=True, - replace_whitespace=True, - fix_sentence_endings=False, - break_long_words=True, - drop_whitespace=True, - break_on_hyphens=True, - tabsize=8, - *, - max_lines=None, - placeholder=' [...]'): - self.width = width - self.initial_indent = initial_indent - self.subsequent_indent = subsequent_indent - self.expand_tabs = expand_tabs - self.replace_whitespace = replace_whitespace - self.fix_sentence_endings = fix_sentence_endings - self.break_long_words = break_long_words - self.drop_whitespace = drop_whitespace - self.break_on_hyphens = break_on_hyphens - self.tabsize = tabsize - self.max_lines = max_lines - self.placeholder = placeholder - - - # -- Private methods ----------------------------------------------- - # (possibly useful for subclasses to override) - - def _munge_whitespace(self, text): - """_munge_whitespace(text : string) -> string - - Munge whitespace in text: expand tabs and convert all other - whitespace characters to spaces. Eg. " foo\\tbar\\n\\nbaz" - becomes " foo bar baz". - """ - if self.expand_tabs: - text = text.expandtabs(self.tabsize) - if self.replace_whitespace: - text = text.translate(self.unicode_whitespace_trans) - return text - - - def _split(self, text): - """_split(text : string) -> [string] - - Split the text to wrap into indivisible chunks. Chunks are - not quite the same as words; see _wrap_chunks() for full - details. As an example, the text - Look, goof-ball -- use the -b option! - breaks into the following chunks: - 'Look,', ' ', 'goof-', 'ball', ' ', '--', ' ', - 'use', ' ', 'the', ' ', '-b', ' ', 'option!' - if break_on_hyphens is True, or in: - 'Look,', ' ', 'goof-ball', ' ', '--', ' ', - 'use', ' ', 'the', ' ', '-b', ' ', option!' - otherwise. - """ - if self.break_on_hyphens is True: - chunks = self.wordsep_re.split(text) - else: - chunks = self.wordsep_simple_re.split(text) - chunks = [c for c in chunks if c] - return chunks - - def _fix_sentence_endings(self, chunks): - """_fix_sentence_endings(chunks : [string]) - - Correct for sentence endings buried in 'chunks'. Eg. when the - original text contains "... foo.\\nBar ...", munge_whitespace() - and split() will convert that to [..., "foo.", " ", "Bar", ...] - which has one too few spaces; this method simply changes the one - space to two. - """ - i = 0 - patsearch = self.sentence_end_re.search - while i < len(chunks)-1: - if chunks[i+1] == " " and patsearch(chunks[i]): - chunks[i+1] = " " - i += 2 - else: - i += 1 - - def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width): - """_handle_long_word(chunks : [string], - cur_line : [string], - cur_len : int, width : int) - - Handle a chunk of text (most likely a word, not whitespace) that - is too long to fit in any line. - """ - # Figure out when indent is larger than the specified width, and make - # sure at least one character is stripped off on every pass - if width < 1: - space_left = 1 - else: - space_left = width - cur_len - - # If we're allowed to break long words, then do so: put as much - # of the next chunk onto the current line as will fit. - if self.break_long_words: - end = space_left - chunk = reversed_chunks[-1] - if self.break_on_hyphens and len(chunk) > space_left: - # break after last hyphen, but only if there are - # non-hyphens before it - hyphen = chunk.rfind('-', 0, space_left) - if hyphen > 0 and any(c != '-' for c in chunk[:hyphen]): - end = hyphen + 1 - cur_line.append(chunk[:end]) - reversed_chunks[-1] = chunk[end:] - - # Otherwise, we have to preserve the long word intact. Only add - # it to the current line if there's nothing already there -- - # that minimizes how much we violate the width constraint. - elif not cur_line: - cur_line.append(reversed_chunks.pop()) - - # If we're not allowed to break long words, and there's already - # text on the current line, do nothing. Next time through the - # main loop of _wrap_chunks(), we'll wind up here again, but - # cur_len will be zero, so the next line will be entirely - # devoted to the long word that we can't handle right now. - - def _wrap_chunks(self, chunks): - """_wrap_chunks(chunks : [string]) -> [string] - - Wrap a sequence of text chunks and return a list of lines of - length 'self.width' or less. (If 'break_long_words' is false, - some lines may be longer than this.) Chunks correspond roughly - to words and the whitespace between them: each chunk is - indivisible (modulo 'break_long_words'), but a line break can - come between any two chunks. Chunks should not have internal - whitespace; ie. a chunk is either all whitespace or a "word". - Whitespace chunks will be removed from the beginning and end of - lines, but apart from that whitespace is preserved. - """ - lines = [] - if self.width <= 0: - raise ValueError("invalid width %r (must be > 0)" % self.width) - if self.max_lines is not None: - if self.max_lines > 1: - indent = self.subsequent_indent - else: - indent = self.initial_indent - if len(indent) + len(self.placeholder.lstrip()) > self.width: - raise ValueError("placeholder too large for max width") - - # Arrange in reverse order so items can be efficiently popped - # from a stack of chucks. - chunks.reverse() - - while chunks: - - # Start the list of chunks that will make up the current line. - # cur_len is just the length of all the chunks in cur_line. - cur_line = [] - cur_len = 0 - - # Figure out which static string will prefix this line. - if lines: - indent = self.subsequent_indent - else: - indent = self.initial_indent - - # Maximum width for this line. - width = self.width - len(indent) - - # First chunk on line is whitespace -- drop it, unless this - # is the very beginning of the text (ie. no lines started yet). - if self.drop_whitespace and chunks[-1].strip() == '' and lines: - del chunks[-1] - - while chunks: - l = len(chunks[-1]) - - # Can at least squeeze this chunk onto the current line. - if cur_len + l <= width: - cur_line.append(chunks.pop()) - cur_len += l - - # Nope, this line is full. - else: - break - - # The current line is full, and the next chunk is too big to - # fit on *any* line (not just this one). - if chunks and len(chunks[-1]) > width: - self._handle_long_word(chunks, cur_line, cur_len, width) - cur_len = sum(map(len, cur_line)) - - # If the last chunk on this line is all whitespace, drop it. - if self.drop_whitespace and cur_line and cur_line[-1].strip() == '': - cur_len -= len(cur_line[-1]) - del cur_line[-1] - - if cur_line: - if (self.max_lines is None or - len(lines) + 1 < self.max_lines or - (not chunks or - self.drop_whitespace and - len(chunks) == 1 and - not chunks[0].strip()) and cur_len <= width): - # Convert current line back to a string and store it in - # list of all lines (return value). - lines.append(indent + ''.join(cur_line)) - else: - while cur_line: - if (cur_line[-1].strip() and - cur_len + len(self.placeholder) <= width): - cur_line.append(self.placeholder) - lines.append(indent + ''.join(cur_line)) - break - cur_len -= len(cur_line[-1]) - del cur_line[-1] - else: - if lines: - prev_line = lines[-1].rstrip() - if (len(prev_line) + len(self.placeholder) <= - self.width): - lines[-1] = prev_line + self.placeholder - break - lines.append(indent + self.placeholder.lstrip()) - break - - return lines - - def _split_chunks(self, text): - text = self._munge_whitespace(text) - return self._split(text) - - # -- Public interface ---------------------------------------------- - - def wrap(self, text): - """wrap(text : string) -> [string] - - Reformat the single paragraph in 'text' so it fits in lines of - no more than 'self.width' columns, and return a list of wrapped - lines. Tabs in 'text' are expanded with string.expandtabs(), - and all other whitespace characters (including newline) are - converted to space. - """ - chunks = self._split_chunks(text) - if self.fix_sentence_endings: - self._fix_sentence_endings(chunks) - return self._wrap_chunks(chunks) - - def fill(self, text): - """fill(text : string) -> string - - Reformat the single paragraph in 'text' to fit in lines of no - more than 'self.width' columns, and return a new string - containing the entire wrapped paragraph. - """ - return "\n".join(self.wrap(text)) - - -# -- Convenience interface --------------------------------------------- - -def wrap(text, width=70, **kwargs): - """Wrap a single paragraph of text, returning a list of wrapped lines. - - Reformat the single paragraph in 'text' so it fits in lines of no - more than 'width' columns, and return a list of wrapped lines. By - default, tabs in 'text' are expanded with string.expandtabs(), and - all other whitespace characters (including newline) are converted to - space. See TextWrapper class for available keyword args to customize - wrapping behaviour. - """ - w = TextWrapper(width=width, **kwargs) - return w.wrap(text) - -def fill(text, width=70, **kwargs): - """Fill a single paragraph of text, returning a new string. - - Reformat the single paragraph in 'text' to fit in lines of no more - than 'width' columns, and return a new string containing the entire - wrapped paragraph. As with wrap(), tabs are expanded and other - whitespace characters converted to space. See TextWrapper class for - available keyword args to customize wrapping behaviour. - """ - w = TextWrapper(width=width, **kwargs) - return w.fill(text) - -def shorten(text, width, **kwargs): - """Collapse and truncate the given text to fit in the given width. - - The text first has its whitespace collapsed. If it then fits in - the *width*, it is returned as is. Otherwise, as many words - as possible are joined and then the placeholder is appended:: - - >>> textwrap.shorten("Hello world!", width=12) - 'Hello world!' - >>> textwrap.shorten("Hello world!", width=11) - 'Hello [...]' - """ - w = TextWrapper(width=width, max_lines=1, **kwargs) - return w.fill(' '.join(text.strip().split())) - - -# -- Loosely related functionality ------------------------------------- - -_whitespace_only_re = re.compile('^[ \t]+$', re.MULTILINE) -_leading_whitespace_re = re.compile('(^[ \t]*)(?:[^ \t\n])', re.MULTILINE) - -def dedent(text): - """Remove any common leading whitespace from every line in `text`. - - This can be used to make triple-quoted strings line up with the left - edge of the display, while still presenting them in the source code - in indented form. - - Note that tabs and spaces are both treated as whitespace, but they - are not equal: the lines " hello" and "\\thello" are - considered to have no common leading whitespace. - - Entirely blank lines are normalized to a newline character. - """ - # Look for the longest leading string of spaces and tabs common to - # all lines. - margin = None - text = _whitespace_only_re.sub('', text) - indents = _leading_whitespace_re.findall(text) - for indent in indents: - if margin is None: - margin = indent - - # Current line more deeply indented than previous winner: - # no change (previous winner is still on top). - elif indent.startswith(margin): - pass - - # Current line consistent with and no deeper than previous winner: - # it's the new winner. - elif margin.startswith(indent): - margin = indent - - # Find the largest common whitespace between current line and previous - # winner. - else: - for i, (x, y) in enumerate(zip(margin, indent)): - if x != y: - margin = margin[:i] - break - - # sanity check (testing/debugging only) - if 0 and margin: - for line in text.split("\n"): - assert not line or line.startswith(margin), \ - "line = %r, margin = %r" % (line, margin) - - if margin: - text = re.sub(r'(?m)^' + margin, '', text) - return text - - -def indent(text, prefix, predicate=None): - """Adds 'prefix' to the beginning of selected lines in 'text'. - - If 'predicate' is provided, 'prefix' will only be added to the lines - where 'predicate(line)' is True. If 'predicate' is not provided, - it will default to adding 'prefix' to all non-empty lines that do not - consist solely of whitespace characters. - """ - if predicate is None: - def predicate(line): - return line.strip() - - def prefixed_lines(): - for line in text.splitlines(True): - yield (prefix + line if predicate(line) else line) - return ''.join(prefixed_lines()) - - -if __name__ == "__main__": - #print dedent("\tfoo\n\tbar") - #print dedent(" \thello there\n \t how are you?") - print(dedent("Hello there.\n This is indented.")) diff --git a/python/Lib/this.py b/python/Lib/this.py deleted file mode 100644 index 76f64a2..0000000 --- a/python/Lib/this.py +++ /dev/null @@ -1,28 +0,0 @@ -s = """Gur Mra bs Clguba, ol Gvz Crgref - -Ornhgvshy vf orggre guna htyl. -Rkcyvpvg vf orggre guna vzcyvpvg. -Fvzcyr vf orggre guna pbzcyrk. -Pbzcyrk vf orggre guna pbzcyvpngrq. -Syng vf orggre guna arfgrq. -Fcnefr vf orggre guna qrafr. -Ernqnovyvgl pbhagf. -Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf. -Nygubhtu cenpgvpnyvgl orngf chevgl. -Reebef fubhyq arire cnff fvyragyl. -Hayrff rkcyvpvgyl fvyraprq. -Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff. -Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg. -Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu. -Abj vf orggre guna arire. -Nygubhtu arire vf bsgra orggre guna *evtug* abj. -Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn. -Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn. -Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!""" - -d = {} -for c in (65, 97): - for i in range(26): - d[chr(i+c)] = chr((i+13) % 26 + c) - -print("".join([d.get(c, c) for c in s])) diff --git a/python/Lib/threading.py b/python/Lib/threading.py deleted file mode 100644 index 4994ea5..0000000 --- a/python/Lib/threading.py +++ /dev/null @@ -1,1661 +0,0 @@ -"""Thread module emulating a subset of Java's threading model.""" - -import os as _os -import sys as _sys -import _thread -import functools - -from time import monotonic as _time -from _weakrefset import WeakSet -from itertools import islice as _islice, count as _count -try: - from _collections import deque as _deque -except ImportError: - from collections import deque as _deque - -# Note regarding PEP 8 compliant names -# This threading model was originally inspired by Java, and inherited -# the convention of camelCase function and method names from that -# language. Those original names are not in any imminent danger of -# being deprecated (even for Py3k),so this module provides them as an -# alias for the PEP 8 compliant names -# Note that using the new PEP 8 compliant names facilitates substitution -# with the multiprocessing module, which doesn't provide the old -# Java inspired names. - -__all__ = ['get_ident', 'active_count', 'Condition', 'current_thread', - 'enumerate', 'main_thread', 'TIMEOUT_MAX', - 'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', - 'Barrier', 'BrokenBarrierError', 'Timer', 'ThreadError', - 'setprofile', 'settrace', 'local', 'stack_size', - 'excepthook', 'ExceptHookArgs', 'gettrace', 'getprofile'] - -# Rename some stuff so "from threading import *" is safe -_start_new_thread = _thread.start_new_thread -_allocate_lock = _thread.allocate_lock -_set_sentinel = _thread._set_sentinel -get_ident = _thread.get_ident -try: - get_native_id = _thread.get_native_id - _HAVE_THREAD_NATIVE_ID = True - __all__.append('get_native_id') -except AttributeError: - _HAVE_THREAD_NATIVE_ID = False -ThreadError = _thread.error -try: - _CRLock = _thread.RLock -except AttributeError: - _CRLock = None -TIMEOUT_MAX = _thread.TIMEOUT_MAX -del _thread - - -# Support for profile and trace hooks - -_profile_hook = None -_trace_hook = None - -def setprofile(func): - """Set a profile function for all threads started from the threading module. - - The func will be passed to sys.setprofile() for each thread, before its - run() method is called. - - """ - global _profile_hook - _profile_hook = func - -def getprofile(): - """Get the profiler function as set by threading.setprofile().""" - return _profile_hook - -def settrace(func): - """Set a trace function for all threads started from the threading module. - - The func will be passed to sys.settrace() for each thread, before its run() - method is called. - - """ - global _trace_hook - _trace_hook = func - -def gettrace(): - """Get the trace function as set by threading.settrace().""" - return _trace_hook - -# Synchronization classes - -Lock = _allocate_lock - -def RLock(*args, **kwargs): - """Factory function that returns a new reentrant lock. - - A reentrant lock must be released by the thread that acquired it. Once a - thread has acquired a reentrant lock, the same thread may acquire it again - without blocking; the thread must release it once for each time it has - acquired it. - - """ - if _CRLock is None: - return _PyRLock(*args, **kwargs) - return _CRLock(*args, **kwargs) - -class _RLock: - """This class implements reentrant lock objects. - - A reentrant lock must be released by the thread that acquired it. Once a - thread has acquired a reentrant lock, the same thread may acquire it - again without blocking; the thread must release it once for each time it - has acquired it. - - """ - - def __init__(self): - self._block = _allocate_lock() - self._owner = None - self._count = 0 - - def __repr__(self): - owner = self._owner - try: - owner = _active[owner].name - except KeyError: - pass - return "<%s %s.%s object owner=%r count=%d at %s>" % ( - "locked" if self._block.locked() else "unlocked", - self.__class__.__module__, - self.__class__.__qualname__, - owner, - self._count, - hex(id(self)) - ) - - def _at_fork_reinit(self): - self._block._at_fork_reinit() - self._owner = None - self._count = 0 - - def acquire(self, blocking=True, timeout=-1): - """Acquire a lock, blocking or non-blocking. - - When invoked without arguments: if this thread already owns the lock, - increment the recursion level by one, and return immediately. Otherwise, - if another thread owns the lock, block until the lock is unlocked. Once - the lock is unlocked (not owned by any thread), then grab ownership, set - the recursion level to one, and return. If more than one thread is - blocked waiting until the lock is unlocked, only one at a time will be - able to grab ownership of the lock. There is no return value in this - case. - - When invoked with the blocking argument set to true, do the same thing - as when called without arguments, and return true. - - When invoked with the blocking argument set to false, do not block. If a - call without an argument would block, return false immediately; - otherwise, do the same thing as when called without arguments, and - return true. - - When invoked with the floating-point timeout argument set to a positive - value, block for at most the number of seconds specified by timeout - and as long as the lock cannot be acquired. Return true if the lock has - been acquired, false if the timeout has elapsed. - - """ - me = get_ident() - if self._owner == me: - self._count += 1 - return 1 - rc = self._block.acquire(blocking, timeout) - if rc: - self._owner = me - self._count = 1 - return rc - - __enter__ = acquire - - def release(self): - """Release a lock, decrementing the recursion level. - - If after the decrement it is zero, reset the lock to unlocked (not owned - by any thread), and if any other threads are blocked waiting for the - lock to become unlocked, allow exactly one of them to proceed. If after - the decrement the recursion level is still nonzero, the lock remains - locked and owned by the calling thread. - - Only call this method when the calling thread owns the lock. A - RuntimeError is raised if this method is called when the lock is - unlocked. - - There is no return value. - - """ - if self._owner != get_ident(): - raise RuntimeError("cannot release un-acquired lock") - self._count = count = self._count - 1 - if not count: - self._owner = None - self._block.release() - - def __exit__(self, t, v, tb): - self.release() - - # Internal methods used by condition variables - - def _acquire_restore(self, state): - self._block.acquire() - self._count, self._owner = state - - def _release_save(self): - if self._count == 0: - raise RuntimeError("cannot release un-acquired lock") - count = self._count - self._count = 0 - owner = self._owner - self._owner = None - self._block.release() - return (count, owner) - - def _is_owned(self): - return self._owner == get_ident() - -_PyRLock = _RLock - - -class Condition: - """Class that implements a condition variable. - - A condition variable allows one or more threads to wait until they are - notified by another thread. - - If the lock argument is given and not None, it must be a Lock or RLock - object, and it is used as the underlying lock. Otherwise, a new RLock object - is created and used as the underlying lock. - - """ - - def __init__(self, lock=None): - if lock is None: - lock = RLock() - self._lock = lock - # Export the lock's acquire() and release() methods - self.acquire = lock.acquire - self.release = lock.release - # If the lock defines _release_save() and/or _acquire_restore(), - # these override the default implementations (which just call - # release() and acquire() on the lock). Ditto for _is_owned(). - try: - self._release_save = lock._release_save - except AttributeError: - pass - try: - self._acquire_restore = lock._acquire_restore - except AttributeError: - pass - try: - self._is_owned = lock._is_owned - except AttributeError: - pass - self._waiters = _deque() - - def _at_fork_reinit(self): - self._lock._at_fork_reinit() - self._waiters.clear() - - def __enter__(self): - return self._lock.__enter__() - - def __exit__(self, *args): - return self._lock.__exit__(*args) - - def __repr__(self): - return "" % (self._lock, len(self._waiters)) - - def _release_save(self): - self._lock.release() # No state to save - - def _acquire_restore(self, x): - self._lock.acquire() # Ignore saved state - - def _is_owned(self): - # Return True if lock is owned by current_thread. - # This method is called only if _lock doesn't have _is_owned(). - if self._lock.acquire(False): - self._lock.release() - return False - else: - return True - - def wait(self, timeout=None): - """Wait until notified or until a timeout occurs. - - If the calling thread has not acquired the lock when this method is - called, a RuntimeError is raised. - - This method releases the underlying lock, and then blocks until it is - awakened by a notify() or notify_all() call for the same condition - variable in another thread, or until the optional timeout occurs. Once - awakened or timed out, it re-acquires the lock and returns. - - When the timeout argument is present and not None, it should be a - floating point number specifying a timeout for the operation in seconds - (or fractions thereof). - - When the underlying lock is an RLock, it is not released using its - release() method, since this may not actually unlock the lock when it - was acquired multiple times recursively. Instead, an internal interface - of the RLock class is used, which really unlocks it even when it has - been recursively acquired several times. Another internal interface is - then used to restore the recursion level when the lock is reacquired. - - """ - if not self._is_owned(): - raise RuntimeError("cannot wait on un-acquired lock") - waiter = _allocate_lock() - waiter.acquire() - self._waiters.append(waiter) - saved_state = self._release_save() - gotit = False - try: # restore state no matter what (e.g., KeyboardInterrupt) - if timeout is None: - waiter.acquire() - gotit = True - else: - if timeout > 0: - gotit = waiter.acquire(True, timeout) - else: - gotit = waiter.acquire(False) - return gotit - finally: - self._acquire_restore(saved_state) - if not gotit: - try: - self._waiters.remove(waiter) - except ValueError: - pass - - def wait_for(self, predicate, timeout=None): - """Wait until a condition evaluates to True. - - predicate should be a callable which result will be interpreted as a - boolean value. A timeout may be provided giving the maximum time to - wait. - - """ - endtime = None - waittime = timeout - result = predicate() - while not result: - if waittime is not None: - if endtime is None: - endtime = _time() + waittime - else: - waittime = endtime - _time() - if waittime <= 0: - break - self.wait(waittime) - result = predicate() - return result - - def notify(self, n=1): - """Wake up one or more threads waiting on this condition, if any. - - If the calling thread has not acquired the lock when this method is - called, a RuntimeError is raised. - - This method wakes up at most n of the threads waiting for the condition - variable; it is a no-op if no threads are waiting. - - """ - if not self._is_owned(): - raise RuntimeError("cannot notify on un-acquired lock") - waiters = self._waiters - while waiters and n > 0: - waiter = waiters[0] - try: - waiter.release() - except RuntimeError: - # gh-92530: The previous call of notify() released the lock, - # but was interrupted before removing it from the queue. - # It can happen if a signal handler raises an exception, - # like CTRL+C which raises KeyboardInterrupt. - pass - else: - n -= 1 - try: - waiters.remove(waiter) - except ValueError: - pass - - def notify_all(self): - """Wake up all threads waiting on this condition. - - If the calling thread has not acquired the lock when this method - is called, a RuntimeError is raised. - - """ - self.notify(len(self._waiters)) - - def notifyAll(self): - """Wake up all threads waiting on this condition. - - This method is deprecated, use notify_all() instead. - - """ - import warnings - warnings.warn('notifyAll() is deprecated, use notify_all() instead', - DeprecationWarning, stacklevel=2) - self.notify_all() - - -class Semaphore: - """This class implements semaphore objects. - - Semaphores manage a counter representing the number of release() calls minus - the number of acquire() calls, plus an initial value. The acquire() method - blocks if necessary until it can return without making the counter - negative. If not given, value defaults to 1. - - """ - - # After Tim Peters' semaphore class, but not quite the same (no maximum) - - def __init__(self, value=1): - if value < 0: - raise ValueError("semaphore initial value must be >= 0") - self._cond = Condition(Lock()) - self._value = value - - def __repr__(self): - cls = self.__class__ - return (f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}:" - f" value={self._value}>") - - def acquire(self, blocking=True, timeout=None): - """Acquire a semaphore, decrementing the internal counter by one. - - When invoked without arguments: if the internal counter is larger than - zero on entry, decrement it by one and return immediately. If it is zero - on entry, block, waiting until some other thread has called release() to - make it larger than zero. This is done with proper interlocking so that - if multiple acquire() calls are blocked, release() will wake exactly one - of them up. The implementation may pick one at random, so the order in - which blocked threads are awakened should not be relied on. There is no - return value in this case. - - When invoked with blocking set to true, do the same thing as when called - without arguments, and return true. - - When invoked with blocking set to false, do not block. If a call without - an argument would block, return false immediately; otherwise, do the - same thing as when called without arguments, and return true. - - When invoked with a timeout other than None, it will block for at - most timeout seconds. If acquire does not complete successfully in - that interval, return false. Return true otherwise. - - """ - if not blocking and timeout is not None: - raise ValueError("can't specify timeout for non-blocking acquire") - rc = False - endtime = None - with self._cond: - while self._value == 0: - if not blocking: - break - if timeout is not None: - if endtime is None: - endtime = _time() + timeout - else: - timeout = endtime - _time() - if timeout <= 0: - break - self._cond.wait(timeout) - else: - self._value -= 1 - rc = True - return rc - - __enter__ = acquire - - def release(self, n=1): - """Release a semaphore, incrementing the internal counter by one or more. - - When the counter is zero on entry and another thread is waiting for it - to become larger than zero again, wake up that thread. - - """ - if n < 1: - raise ValueError('n must be one or more') - with self._cond: - self._value += n - for i in range(n): - self._cond.notify() - - def __exit__(self, t, v, tb): - self.release() - - -class BoundedSemaphore(Semaphore): - """Implements a bounded semaphore. - - A bounded semaphore checks to make sure its current value doesn't exceed its - initial value. If it does, ValueError is raised. In most situations - semaphores are used to guard resources with limited capacity. - - If the semaphore is released too many times it's a sign of a bug. If not - given, value defaults to 1. - - Like regular semaphores, bounded semaphores manage a counter representing - the number of release() calls minus the number of acquire() calls, plus an - initial value. The acquire() method blocks if necessary until it can return - without making the counter negative. If not given, value defaults to 1. - - """ - - def __init__(self, value=1): - Semaphore.__init__(self, value) - self._initial_value = value - - def __repr__(self): - cls = self.__class__ - return (f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}:" - f" value={self._value}/{self._initial_value}>") - - def release(self, n=1): - """Release a semaphore, incrementing the internal counter by one or more. - - When the counter is zero on entry and another thread is waiting for it - to become larger than zero again, wake up that thread. - - If the number of releases exceeds the number of acquires, - raise a ValueError. - - """ - if n < 1: - raise ValueError('n must be one or more') - with self._cond: - if self._value + n > self._initial_value: - raise ValueError("Semaphore released too many times") - self._value += n - for i in range(n): - self._cond.notify() - - -class Event: - """Class implementing event objects. - - Events manage a flag that can be set to true with the set() method and reset - to false with the clear() method. The wait() method blocks until the flag is - true. The flag is initially false. - - """ - - # After Tim Peters' event class (without is_posted()) - - def __init__(self): - self._cond = Condition(Lock()) - self._flag = False - - def __repr__(self): - cls = self.__class__ - status = 'set' if self._flag else 'unset' - return f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}: {status}>" - - def _at_fork_reinit(self): - # Private method called by Thread._reset_internal_locks() - self._cond._at_fork_reinit() - - def is_set(self): - """Return true if and only if the internal flag is true.""" - return self._flag - - def isSet(self): - """Return true if and only if the internal flag is true. - - This method is deprecated, use is_set() instead. - - """ - import warnings - warnings.warn('isSet() is deprecated, use is_set() instead', - DeprecationWarning, stacklevel=2) - return self.is_set() - - def set(self): - """Set the internal flag to true. - - All threads waiting for it to become true are awakened. Threads - that call wait() once the flag is true will not block at all. - - """ - with self._cond: - self._flag = True - self._cond.notify_all() - - def clear(self): - """Reset the internal flag to false. - - Subsequently, threads calling wait() will block until set() is called to - set the internal flag to true again. - - """ - with self._cond: - self._flag = False - - def wait(self, timeout=None): - """Block until the internal flag is true. - - If the internal flag is true on entry, return immediately. Otherwise, - block until another thread calls set() to set the flag to true, or until - the optional timeout occurs. - - When the timeout argument is present and not None, it should be a - floating point number specifying a timeout for the operation in seconds - (or fractions thereof). - - This method returns the internal flag on exit, so it will always return - True except if a timeout is given and the operation times out. - - """ - with self._cond: - signaled = self._flag - if not signaled: - signaled = self._cond.wait(timeout) - return signaled - - -# A barrier class. Inspired in part by the pthread_barrier_* api and -# the CyclicBarrier class from Java. See -# http://sourceware.org/pthreads-win32/manual/pthread_barrier_init.html and -# http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ -# CyclicBarrier.html -# for information. -# We maintain two main states, 'filling' and 'draining' enabling the barrier -# to be cyclic. Threads are not allowed into it until it has fully drained -# since the previous cycle. In addition, a 'resetting' state exists which is -# similar to 'draining' except that threads leave with a BrokenBarrierError, -# and a 'broken' state in which all threads get the exception. -class Barrier: - """Implements a Barrier. - - Useful for synchronizing a fixed number of threads at known synchronization - points. Threads block on 'wait()' and are simultaneously awoken once they - have all made that call. - - """ - - def __init__(self, parties, action=None, timeout=None): - """Create a barrier, initialised to 'parties' threads. - - 'action' is a callable which, when supplied, will be called by one of - the threads after they have all entered the barrier and just prior to - releasing them all. If a 'timeout' is provided, it is used as the - default for all subsequent 'wait()' calls. - - """ - self._cond = Condition(Lock()) - self._action = action - self._timeout = timeout - self._parties = parties - self._state = 0 # 0 filling, 1 draining, -1 resetting, -2 broken - self._count = 0 - - def __repr__(self): - cls = self.__class__ - if self.broken: - return f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}: broken>" - return (f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}:" - f" waiters={self.n_waiting}/{self.parties}>") - - def wait(self, timeout=None): - """Wait for the barrier. - - When the specified number of threads have started waiting, they are all - simultaneously awoken. If an 'action' was provided for the barrier, one - of the threads will have executed that callback prior to returning. - Returns an individual index number from 0 to 'parties-1'. - - """ - if timeout is None: - timeout = self._timeout - with self._cond: - self._enter() # Block while the barrier drains. - index = self._count - self._count += 1 - try: - if index + 1 == self._parties: - # We release the barrier - self._release() - else: - # We wait until someone releases us - self._wait(timeout) - return index - finally: - self._count -= 1 - # Wake up any threads waiting for barrier to drain. - self._exit() - - # Block until the barrier is ready for us, or raise an exception - # if it is broken. - def _enter(self): - while self._state in (-1, 1): - # It is draining or resetting, wait until done - self._cond.wait() - #see if the barrier is in a broken state - if self._state < 0: - raise BrokenBarrierError - assert self._state == 0 - - # Optionally run the 'action' and release the threads waiting - # in the barrier. - def _release(self): - try: - if self._action: - self._action() - # enter draining state - self._state = 1 - self._cond.notify_all() - except: - #an exception during the _action handler. Break and reraise - self._break() - raise - - # Wait in the barrier until we are released. Raise an exception - # if the barrier is reset or broken. - def _wait(self, timeout): - if not self._cond.wait_for(lambda : self._state != 0, timeout): - #timed out. Break the barrier - self._break() - raise BrokenBarrierError - if self._state < 0: - raise BrokenBarrierError - assert self._state == 1 - - # If we are the last thread to exit the barrier, signal any threads - # waiting for the barrier to drain. - def _exit(self): - if self._count == 0: - if self._state in (-1, 1): - #resetting or draining - self._state = 0 - self._cond.notify_all() - - def reset(self): - """Reset the barrier to the initial state. - - Any threads currently waiting will get the BrokenBarrier exception - raised. - - """ - with self._cond: - if self._count > 0: - if self._state == 0: - #reset the barrier, waking up threads - self._state = -1 - elif self._state == -2: - #was broken, set it to reset state - #which clears when the last thread exits - self._state = -1 - else: - self._state = 0 - self._cond.notify_all() - - def abort(self): - """Place the barrier into a 'broken' state. - - Useful in case of error. Any currently waiting threads and threads - attempting to 'wait()' will have BrokenBarrierError raised. - - """ - with self._cond: - self._break() - - def _break(self): - # An internal error was detected. The barrier is set to - # a broken state all parties awakened. - self._state = -2 - self._cond.notify_all() - - @property - def parties(self): - """Return the number of threads required to trip the barrier.""" - return self._parties - - @property - def n_waiting(self): - """Return the number of threads currently waiting at the barrier.""" - # We don't need synchronization here since this is an ephemeral result - # anyway. It returns the correct value in the steady state. - if self._state == 0: - return self._count - return 0 - - @property - def broken(self): - """Return True if the barrier is in a broken state.""" - return self._state == -2 - -# exception raised by the Barrier class -class BrokenBarrierError(RuntimeError): - pass - - -# Helper to generate new thread names -_counter = _count(1).__next__ -def _newname(name_template): - return name_template % _counter() - -# Active thread administration. -# -# bpo-44422: Use a reentrant lock to allow reentrant calls to functions like -# threading.enumerate(). -_active_limbo_lock = RLock() -_active = {} # maps thread id to Thread object -_limbo = {} -_dangling = WeakSet() - -# Set of Thread._tstate_lock locks of non-daemon threads used by _shutdown() -# to wait until all Python thread states get deleted: -# see Thread._set_tstate_lock(). -_shutdown_locks_lock = _allocate_lock() -_shutdown_locks = set() - -def _maintain_shutdown_locks(): - """ - Drop any shutdown locks that don't correspond to running threads anymore. - - Calling this from time to time avoids an ever-growing _shutdown_locks - set when Thread objects are not joined explicitly. See bpo-37788. - - This must be called with _shutdown_locks_lock acquired. - """ - # If a lock was released, the corresponding thread has exited - to_remove = [lock for lock in _shutdown_locks if not lock.locked()] - _shutdown_locks.difference_update(to_remove) - - -# Main class for threads - -class Thread: - """A class that represents a thread of control. - - This class can be safely subclassed in a limited fashion. There are two ways - to specify the activity: by passing a callable object to the constructor, or - by overriding the run() method in a subclass. - - """ - - _initialized = False - - def __init__(self, group=None, target=None, name=None, - args=(), kwargs=None, *, daemon=None): - """This constructor should always be called with keyword arguments. Arguments are: - - *group* should be None; reserved for future extension when a ThreadGroup - class is implemented. - - *target* is the callable object to be invoked by the run() - method. Defaults to None, meaning nothing is called. - - *name* is the thread name. By default, a unique name is constructed of - the form "Thread-N" where N is a small decimal number. - - *args* is a list or tuple of arguments for the target invocation. Defaults to (). - - *kwargs* is a dictionary of keyword arguments for the target - invocation. Defaults to {}. - - If a subclass overrides the constructor, it must make sure to invoke - the base class constructor (Thread.__init__()) before doing anything - else to the thread. - - """ - assert group is None, "group argument must be None for now" - if kwargs is None: - kwargs = {} - if name: - name = str(name) - else: - name = _newname("Thread-%d") - if target is not None: - try: - target_name = target.__name__ - name += f" ({target_name})" - except AttributeError: - pass - - self._target = target - self._name = name - self._args = args - self._kwargs = kwargs - if daemon is not None: - self._daemonic = daemon - else: - self._daemonic = current_thread().daemon - self._ident = None - if _HAVE_THREAD_NATIVE_ID: - self._native_id = None - self._tstate_lock = None - self._started = Event() - self._is_stopped = False - self._initialized = True - # Copy of sys.stderr used by self._invoke_excepthook() - self._stderr = _sys.stderr - self._invoke_excepthook = _make_invoke_excepthook() - # For debugging and _after_fork() - _dangling.add(self) - - def _reset_internal_locks(self, is_alive): - # private! Called by _after_fork() to reset our internal locks as - # they may be in an invalid state leading to a deadlock or crash. - self._started._at_fork_reinit() - if is_alive: - # bpo-42350: If the fork happens when the thread is already stopped - # (ex: after threading._shutdown() has been called), _tstate_lock - # is None. Do nothing in this case. - if self._tstate_lock is not None: - self._tstate_lock._at_fork_reinit() - self._tstate_lock.acquire() - else: - # The thread isn't alive after fork: it doesn't have a tstate - # anymore. - self._is_stopped = True - self._tstate_lock = None - - def __repr__(self): - assert self._initialized, "Thread.__init__() was not called" - status = "initial" - if self._started.is_set(): - status = "started" - self.is_alive() # easy way to get ._is_stopped set when appropriate - if self._is_stopped: - status = "stopped" - if self._daemonic: - status += " daemon" - if self._ident is not None: - status += " %s" % self._ident - return "<%s(%s, %s)>" % (self.__class__.__name__, self._name, status) - - def start(self): - """Start the thread's activity. - - It must be called at most once per thread object. It arranges for the - object's run() method to be invoked in a separate thread of control. - - This method will raise a RuntimeError if called more than once on the - same thread object. - - """ - if not self._initialized: - raise RuntimeError("thread.__init__() not called") - - if self._started.is_set(): - raise RuntimeError("threads can only be started once") - - with _active_limbo_lock: - _limbo[self] = self - try: - _start_new_thread(self._bootstrap, ()) - except Exception: - with _active_limbo_lock: - del _limbo[self] - raise - self._started.wait() - - def run(self): - """Method representing the thread's activity. - - You may override this method in a subclass. The standard run() method - invokes the callable object passed to the object's constructor as the - target argument, if any, with sequential and keyword arguments taken - from the args and kwargs arguments, respectively. - - """ - try: - if self._target is not None: - self._target(*self._args, **self._kwargs) - finally: - # Avoid a refcycle if the thread is running a function with - # an argument that has a member that points to the thread. - del self._target, self._args, self._kwargs - - def _bootstrap(self): - # Wrapper around the real bootstrap code that ignores - # exceptions during interpreter cleanup. Those typically - # happen when a daemon thread wakes up at an unfortunate - # moment, finds the world around it destroyed, and raises some - # random exception *** while trying to report the exception in - # _bootstrap_inner() below ***. Those random exceptions - # don't help anybody, and they confuse users, so we suppress - # them. We suppress them only when it appears that the world - # indeed has already been destroyed, so that exceptions in - # _bootstrap_inner() during normal business hours are properly - # reported. Also, we only suppress them for daemonic threads; - # if a non-daemonic encounters this, something else is wrong. - try: - self._bootstrap_inner() - except: - if self._daemonic and _sys is None: - return - raise - - def _set_ident(self): - self._ident = get_ident() - - if _HAVE_THREAD_NATIVE_ID: - def _set_native_id(self): - self._native_id = get_native_id() - - def _set_tstate_lock(self): - """ - Set a lock object which will be released by the interpreter when - the underlying thread state (see pystate.h) gets deleted. - """ - self._tstate_lock = _set_sentinel() - self._tstate_lock.acquire() - - if not self.daemon: - with _shutdown_locks_lock: - _maintain_shutdown_locks() - _shutdown_locks.add(self._tstate_lock) - - def _bootstrap_inner(self): - try: - self._set_ident() - self._set_tstate_lock() - if _HAVE_THREAD_NATIVE_ID: - self._set_native_id() - self._started.set() - with _active_limbo_lock: - _active[self._ident] = self - del _limbo[self] - - if _trace_hook: - _sys.settrace(_trace_hook) - if _profile_hook: - _sys.setprofile(_profile_hook) - - try: - self.run() - except: - self._invoke_excepthook(self) - finally: - self._delete() - - def _stop(self): - # After calling ._stop(), .is_alive() returns False and .join() returns - # immediately. ._tstate_lock must be released before calling ._stop(). - # - # Normal case: C code at the end of the thread's life - # (release_sentinel in _threadmodule.c) releases ._tstate_lock, and - # that's detected by our ._wait_for_tstate_lock(), called by .join() - # and .is_alive(). Any number of threads _may_ call ._stop() - # simultaneously (for example, if multiple threads are blocked in - # .join() calls), and they're not serialized. That's harmless - - # they'll just make redundant rebindings of ._is_stopped and - # ._tstate_lock. Obscure: we rebind ._tstate_lock last so that the - # "assert self._is_stopped" in ._wait_for_tstate_lock() always works - # (the assert is executed only if ._tstate_lock is None). - # - # Special case: _main_thread releases ._tstate_lock via this - # module's _shutdown() function. - lock = self._tstate_lock - if lock is not None: - assert not lock.locked() - self._is_stopped = True - self._tstate_lock = None - if not self.daemon: - with _shutdown_locks_lock: - # Remove our lock and other released locks from _shutdown_locks - _maintain_shutdown_locks() - - def _delete(self): - "Remove current thread from the dict of currently running threads." - with _active_limbo_lock: - del _active[get_ident()] - # There must not be any python code between the previous line - # and after the lock is released. Otherwise a tracing function - # could try to acquire the lock again in the same thread, (in - # current_thread()), and would block. - - def join(self, timeout=None): - """Wait until the thread terminates. - - This blocks the calling thread until the thread whose join() method is - called terminates -- either normally or through an unhandled exception - or until the optional timeout occurs. - - When the timeout argument is present and not None, it should be a - floating point number specifying a timeout for the operation in seconds - (or fractions thereof). As join() always returns None, you must call - is_alive() after join() to decide whether a timeout happened -- if the - thread is still alive, the join() call timed out. - - When the timeout argument is not present or None, the operation will - block until the thread terminates. - - A thread can be join()ed many times. - - join() raises a RuntimeError if an attempt is made to join the current - thread as that would cause a deadlock. It is also an error to join() a - thread before it has been started and attempts to do so raises the same - exception. - - """ - if not self._initialized: - raise RuntimeError("Thread.__init__() not called") - if not self._started.is_set(): - raise RuntimeError("cannot join thread before it is started") - if self is current_thread(): - raise RuntimeError("cannot join current thread") - - if timeout is None: - self._wait_for_tstate_lock() - else: - # the behavior of a negative timeout isn't documented, but - # historically .join(timeout=x) for x<0 has acted as if timeout=0 - self._wait_for_tstate_lock(timeout=max(timeout, 0)) - - def _wait_for_tstate_lock(self, block=True, timeout=-1): - # Issue #18808: wait for the thread state to be gone. - # At the end of the thread's life, after all knowledge of the thread - # is removed from C data structures, C code releases our _tstate_lock. - # This method passes its arguments to _tstate_lock.acquire(). - # If the lock is acquired, the C code is done, and self._stop() is - # called. That sets ._is_stopped to True, and ._tstate_lock to None. - lock = self._tstate_lock - if lock is None: - # already determined that the C code is done - assert self._is_stopped - return - - try: - if lock.acquire(block, timeout): - lock.release() - self._stop() - except: - if lock.locked(): - # bpo-45274: lock.acquire() acquired the lock, but the function - # was interrupted with an exception before reaching the - # lock.release(). It can happen if a signal handler raises an - # exception, like CTRL+C which raises KeyboardInterrupt. - lock.release() - self._stop() - raise - - @property - def name(self): - """A string used for identification purposes only. - - It has no semantics. Multiple threads may be given the same name. The - initial name is set by the constructor. - - """ - assert self._initialized, "Thread.__init__() not called" - return self._name - - @name.setter - def name(self, name): - assert self._initialized, "Thread.__init__() not called" - self._name = str(name) - - @property - def ident(self): - """Thread identifier of this thread or None if it has not been started. - - This is a nonzero integer. See the get_ident() function. Thread - identifiers may be recycled when a thread exits and another thread is - created. The identifier is available even after the thread has exited. - - """ - assert self._initialized, "Thread.__init__() not called" - return self._ident - - if _HAVE_THREAD_NATIVE_ID: - @property - def native_id(self): - """Native integral thread ID of this thread, or None if it has not been started. - - This is a non-negative integer. See the get_native_id() function. - This represents the Thread ID as reported by the kernel. - - """ - assert self._initialized, "Thread.__init__() not called" - return self._native_id - - def is_alive(self): - """Return whether the thread is alive. - - This method returns True just before the run() method starts until just - after the run() method terminates. See also the module function - enumerate(). - - """ - assert self._initialized, "Thread.__init__() not called" - if self._is_stopped or not self._started.is_set(): - return False - self._wait_for_tstate_lock(False) - return not self._is_stopped - - @property - def daemon(self): - """A boolean value indicating whether this thread is a daemon thread. - - This must be set before start() is called, otherwise RuntimeError is - raised. Its initial value is inherited from the creating thread; the - main thread is not a daemon thread and therefore all threads created in - the main thread default to daemon = False. - - The entire Python program exits when only daemon threads are left. - - """ - assert self._initialized, "Thread.__init__() not called" - return self._daemonic - - @daemon.setter - def daemon(self, daemonic): - if not self._initialized: - raise RuntimeError("Thread.__init__() not called") - if self._started.is_set(): - raise RuntimeError("cannot set daemon status of active thread") - self._daemonic = daemonic - - def isDaemon(self): - """Return whether this thread is a daemon. - - This method is deprecated, use the daemon attribute instead. - - """ - import warnings - warnings.warn('isDaemon() is deprecated, get the daemon attribute instead', - DeprecationWarning, stacklevel=2) - return self.daemon - - def setDaemon(self, daemonic): - """Set whether this thread is a daemon. - - This method is deprecated, use the .daemon property instead. - - """ - import warnings - warnings.warn('setDaemon() is deprecated, set the daemon attribute instead', - DeprecationWarning, stacklevel=2) - self.daemon = daemonic - - def getName(self): - """Return a string used for identification purposes only. - - This method is deprecated, use the name attribute instead. - - """ - import warnings - warnings.warn('getName() is deprecated, get the name attribute instead', - DeprecationWarning, stacklevel=2) - return self.name - - def setName(self, name): - """Set the name string for this thread. - - This method is deprecated, use the name attribute instead. - - """ - import warnings - warnings.warn('setName() is deprecated, set the name attribute instead', - DeprecationWarning, stacklevel=2) - self.name = name - - -try: - from _thread import (_excepthook as excepthook, - _ExceptHookArgs as ExceptHookArgs) -except ImportError: - # Simple Python implementation if _thread._excepthook() is not available - from traceback import print_exception as _print_exception - from collections import namedtuple - - _ExceptHookArgs = namedtuple( - 'ExceptHookArgs', - 'exc_type exc_value exc_traceback thread') - - def ExceptHookArgs(args): - return _ExceptHookArgs(*args) - - def excepthook(args, /): - """ - Handle uncaught Thread.run() exception. - """ - if args.exc_type == SystemExit: - # silently ignore SystemExit - return - - if _sys is not None and _sys.stderr is not None: - stderr = _sys.stderr - elif args.thread is not None: - stderr = args.thread._stderr - if stderr is None: - # do nothing if sys.stderr is None and sys.stderr was None - # when the thread was created - return - else: - # do nothing if sys.stderr is None and args.thread is None - return - - if args.thread is not None: - name = args.thread.name - else: - name = get_ident() - print(f"Exception in thread {name}:", - file=stderr, flush=True) - _print_exception(args.exc_type, args.exc_value, args.exc_traceback, - file=stderr) - stderr.flush() - - -# Original value of threading.excepthook -__excepthook__ = excepthook - - -def _make_invoke_excepthook(): - # Create a local namespace to ensure that variables remain alive - # when _invoke_excepthook() is called, even if it is called late during - # Python shutdown. It is mostly needed for daemon threads. - - old_excepthook = excepthook - old_sys_excepthook = _sys.excepthook - if old_excepthook is None: - raise RuntimeError("threading.excepthook is None") - if old_sys_excepthook is None: - raise RuntimeError("sys.excepthook is None") - - sys_exc_info = _sys.exc_info - local_print = print - local_sys = _sys - - def invoke_excepthook(thread): - global excepthook - try: - hook = excepthook - if hook is None: - hook = old_excepthook - - args = ExceptHookArgs([*sys_exc_info(), thread]) - - hook(args) - except Exception as exc: - exc.__suppress_context__ = True - del exc - - if local_sys is not None and local_sys.stderr is not None: - stderr = local_sys.stderr - else: - stderr = thread._stderr - - local_print("Exception in threading.excepthook:", - file=stderr, flush=True) - - if local_sys is not None and local_sys.excepthook is not None: - sys_excepthook = local_sys.excepthook - else: - sys_excepthook = old_sys_excepthook - - sys_excepthook(*sys_exc_info()) - finally: - # Break reference cycle (exception stored in a variable) - args = None - - return invoke_excepthook - - -# The timer class was contributed by Itamar Shtull-Trauring - -class Timer(Thread): - """Call a function after a specified number of seconds: - - t = Timer(30.0, f, args=None, kwargs=None) - t.start() - t.cancel() # stop the timer's action if it's still waiting - - """ - - def __init__(self, interval, function, args=None, kwargs=None): - Thread.__init__(self) - self.interval = interval - self.function = function - self.args = args if args is not None else [] - self.kwargs = kwargs if kwargs is not None else {} - self.finished = Event() - - def cancel(self): - """Stop the timer if it hasn't finished yet.""" - self.finished.set() - - def run(self): - self.finished.wait(self.interval) - if not self.finished.is_set(): - self.function(*self.args, **self.kwargs) - self.finished.set() - - -# Special thread class to represent the main thread - -class _MainThread(Thread): - - def __init__(self): - Thread.__init__(self, name="MainThread", daemon=False) - self._set_tstate_lock() - self._started.set() - self._set_ident() - if _HAVE_THREAD_NATIVE_ID: - self._set_native_id() - with _active_limbo_lock: - _active[self._ident] = self - - -# Dummy thread class to represent threads not started here. -# These aren't garbage collected when they die, nor can they be waited for. -# If they invoke anything in threading.py that calls current_thread(), they -# leave an entry in the _active dict forever after. -# Their purpose is to return *something* from current_thread(). -# They are marked as daemon threads so we won't wait for them -# when we exit (conform previous semantics). - -class _DummyThread(Thread): - - def __init__(self): - Thread.__init__(self, name=_newname("Dummy-%d"), daemon=True) - - self._started.set() - self._set_ident() - if _HAVE_THREAD_NATIVE_ID: - self._set_native_id() - with _active_limbo_lock: - _active[self._ident] = self - - def _stop(self): - pass - - def is_alive(self): - assert not self._is_stopped and self._started.is_set() - return True - - def join(self, timeout=None): - assert False, "cannot join a dummy thread" - - -# Global API functions - -def current_thread(): - """Return the current Thread object, corresponding to the caller's thread of control. - - If the caller's thread of control was not created through the threading - module, a dummy thread object with limited functionality is returned. - - """ - try: - return _active[get_ident()] - except KeyError: - return _DummyThread() - -def currentThread(): - """Return the current Thread object, corresponding to the caller's thread of control. - - This function is deprecated, use current_thread() instead. - - """ - import warnings - warnings.warn('currentThread() is deprecated, use current_thread() instead', - DeprecationWarning, stacklevel=2) - return current_thread() - -def active_count(): - """Return the number of Thread objects currently alive. - - The returned count is equal to the length of the list returned by - enumerate(). - - """ - with _active_limbo_lock: - return len(_active) + len(_limbo) - -def activeCount(): - """Return the number of Thread objects currently alive. - - This function is deprecated, use active_count() instead. - - """ - import warnings - warnings.warn('activeCount() is deprecated, use active_count() instead', - DeprecationWarning, stacklevel=2) - return active_count() - -def _enumerate(): - # Same as enumerate(), but without the lock. Internal use only. - return list(_active.values()) + list(_limbo.values()) - -def enumerate(): - """Return a list of all Thread objects currently alive. - - The list includes daemonic threads, dummy thread objects created by - current_thread(), and the main thread. It excludes terminated threads and - threads that have not yet been started. - - """ - with _active_limbo_lock: - return list(_active.values()) + list(_limbo.values()) - - -_threading_atexits = [] -_SHUTTING_DOWN = False - -def _register_atexit(func, *arg, **kwargs): - """CPython internal: register *func* to be called before joining threads. - - The registered *func* is called with its arguments just before all - non-daemon threads are joined in `_shutdown()`. It provides a similar - purpose to `atexit.register()`, but its functions are called prior to - threading shutdown instead of interpreter shutdown. - - For similarity to atexit, the registered functions are called in reverse. - """ - if _SHUTTING_DOWN: - raise RuntimeError("can't register atexit after shutdown") - - call = functools.partial(func, *arg, **kwargs) - _threading_atexits.append(call) - - -from _thread import stack_size - -# Create the main thread object, -# and make it available for the interpreter -# (Py_Main) as threading._shutdown. - -_main_thread = _MainThread() - -def _shutdown(): - """ - Wait until the Python thread state of all non-daemon threads get deleted. - """ - # Obscure: other threads may be waiting to join _main_thread. That's - # dubious, but some code does it. We can't wait for C code to release - # the main thread's tstate_lock - that won't happen until the interpreter - # is nearly dead. So we release it here. Note that just calling _stop() - # isn't enough: other threads may already be waiting on _tstate_lock. - if _main_thread._is_stopped: - # _shutdown() was already called - return - - global _SHUTTING_DOWN - _SHUTTING_DOWN = True - - # Call registered threading atexit functions before threads are joined. - # Order is reversed, similar to atexit. - for atexit_call in reversed(_threading_atexits): - atexit_call() - - # Main thread - if _main_thread.ident == get_ident(): - tlock = _main_thread._tstate_lock - # The main thread isn't finished yet, so its thread state lock can't - # have been released. - assert tlock is not None - assert tlock.locked() - tlock.release() - _main_thread._stop() - else: - # bpo-1596321: _shutdown() must be called in the main thread. - # If the threading module was not imported by the main thread, - # _main_thread is the thread which imported the threading module. - # In this case, ignore _main_thread, similar behavior than for threads - # spawned by C libraries or using _thread.start_new_thread(). - pass - - # Join all non-deamon threads - while True: - with _shutdown_locks_lock: - locks = list(_shutdown_locks) - _shutdown_locks.clear() - - if not locks: - break - - for lock in locks: - # mimic Thread.join() - lock.acquire() - lock.release() - - # new threads can be spawned while we were waiting for the other - # threads to complete - - -def main_thread(): - """Return the main thread object. - - In normal conditions, the main thread is the thread from which the - Python interpreter was started. - """ - return _main_thread - -# get thread-local implementation, either from the thread -# module, or from the python fallback - -try: - from _thread import _local as local -except ImportError: - from _threading_local import local - - -def _after_fork(): - """ - Cleanup threading module state that should not exist after a fork. - """ - # Reset _active_limbo_lock, in case we forked while the lock was held - # by another (non-forked) thread. http://bugs.python.org/issue874900 - global _active_limbo_lock, _main_thread - global _shutdown_locks_lock, _shutdown_locks - _active_limbo_lock = RLock() - - # fork() only copied the current thread; clear references to others. - new_active = {} - - try: - current = _active[get_ident()] - except KeyError: - # fork() was called in a thread which was not spawned - # by threading.Thread. For example, a thread spawned - # by thread.start_new_thread(). - current = _MainThread() - - _main_thread = current - - # reset _shutdown() locks: threads re-register their _tstate_lock below - _shutdown_locks_lock = _allocate_lock() - _shutdown_locks = set() - - with _active_limbo_lock: - # Dangling thread instances must still have their locks reset, - # because someone may join() them. - threads = set(_enumerate()) - threads.update(_dangling) - for thread in threads: - # Any lock/condition variable may be currently locked or in an - # invalid state, so we reinitialize them. - if thread is current: - # There is only one active thread. We reset the ident to - # its new value since it can have changed. - thread._reset_internal_locks(True) - ident = get_ident() - thread._ident = ident - new_active[ident] = thread - else: - # All the others are already stopped. - thread._reset_internal_locks(False) - thread._stop() - - _limbo.clear() - _active.clear() - _active.update(new_active) - assert len(_active) == 1 - - -if hasattr(_os, "register_at_fork"): - _os.register_at_fork(after_in_child=_after_fork) diff --git a/python/Lib/token.py b/python/Lib/token.py deleted file mode 100644 index d420b67..0000000 --- a/python/Lib/token.py +++ /dev/null @@ -1,137 +0,0 @@ -"""Token constants.""" -# Auto-generated by Tools/scripts/generate_token.py - -__all__ = ['tok_name', 'ISTERMINAL', 'ISNONTERMINAL', 'ISEOF'] - -ENDMARKER = 0 -NAME = 1 -NUMBER = 2 -STRING = 3 -NEWLINE = 4 -INDENT = 5 -DEDENT = 6 -LPAR = 7 -RPAR = 8 -LSQB = 9 -RSQB = 10 -COLON = 11 -COMMA = 12 -SEMI = 13 -PLUS = 14 -MINUS = 15 -STAR = 16 -SLASH = 17 -VBAR = 18 -AMPER = 19 -LESS = 20 -GREATER = 21 -EQUAL = 22 -DOT = 23 -PERCENT = 24 -LBRACE = 25 -RBRACE = 26 -EQEQUAL = 27 -NOTEQUAL = 28 -LESSEQUAL = 29 -GREATEREQUAL = 30 -TILDE = 31 -CIRCUMFLEX = 32 -LEFTSHIFT = 33 -RIGHTSHIFT = 34 -DOUBLESTAR = 35 -PLUSEQUAL = 36 -MINEQUAL = 37 -STAREQUAL = 38 -SLASHEQUAL = 39 -PERCENTEQUAL = 40 -AMPEREQUAL = 41 -VBAREQUAL = 42 -CIRCUMFLEXEQUAL = 43 -LEFTSHIFTEQUAL = 44 -RIGHTSHIFTEQUAL = 45 -DOUBLESTAREQUAL = 46 -DOUBLESLASH = 47 -DOUBLESLASHEQUAL = 48 -AT = 49 -ATEQUAL = 50 -RARROW = 51 -ELLIPSIS = 52 -COLONEQUAL = 53 -OP = 54 -AWAIT = 55 -ASYNC = 56 -TYPE_IGNORE = 57 -TYPE_COMMENT = 58 -SOFT_KEYWORD = 59 -# These aren't used by the C tokenizer but are needed for tokenize.py -ERRORTOKEN = 60 -COMMENT = 61 -NL = 62 -ENCODING = 63 -N_TOKENS = 64 -# Special definitions for cooperation with parser -NT_OFFSET = 256 - -tok_name = {value: name - for name, value in globals().items() - if isinstance(value, int) and not name.startswith('_')} -__all__.extend(tok_name.values()) - -EXACT_TOKEN_TYPES = { - '!=': NOTEQUAL, - '%': PERCENT, - '%=': PERCENTEQUAL, - '&': AMPER, - '&=': AMPEREQUAL, - '(': LPAR, - ')': RPAR, - '*': STAR, - '**': DOUBLESTAR, - '**=': DOUBLESTAREQUAL, - '*=': STAREQUAL, - '+': PLUS, - '+=': PLUSEQUAL, - ',': COMMA, - '-': MINUS, - '-=': MINEQUAL, - '->': RARROW, - '.': DOT, - '...': ELLIPSIS, - '/': SLASH, - '//': DOUBLESLASH, - '//=': DOUBLESLASHEQUAL, - '/=': SLASHEQUAL, - ':': COLON, - ':=': COLONEQUAL, - ';': SEMI, - '<': LESS, - '<<': LEFTSHIFT, - '<<=': LEFTSHIFTEQUAL, - '<=': LESSEQUAL, - '=': EQUAL, - '==': EQEQUAL, - '>': GREATER, - '>=': GREATEREQUAL, - '>>': RIGHTSHIFT, - '>>=': RIGHTSHIFTEQUAL, - '@': AT, - '@=': ATEQUAL, - '[': LSQB, - ']': RSQB, - '^': CIRCUMFLEX, - '^=': CIRCUMFLEXEQUAL, - '{': LBRACE, - '|': VBAR, - '|=': VBAREQUAL, - '}': RBRACE, - '~': TILDE, -} - -def ISTERMINAL(x): - return x < NT_OFFSET - -def ISNONTERMINAL(x): - return x >= NT_OFFSET - -def ISEOF(x): - return x == ENDMARKER diff --git a/python/Lib/tokenize.py b/python/Lib/tokenize.py deleted file mode 100644 index 40fe1e8..0000000 --- a/python/Lib/tokenize.py +++ /dev/null @@ -1,694 +0,0 @@ -"""Tokenization help for Python programs. - -tokenize(readline) is a generator that breaks a stream of bytes into -Python tokens. It decodes the bytes according to PEP-0263 for -determining source file encoding. - -It accepts a readline-like method which is called repeatedly to get the -next line of input (or b"" for EOF). It generates 5-tuples with these -members: - - the token type (see token.py) - the token (a string) - the starting (row, column) indices of the token (a 2-tuple of ints) - the ending (row, column) indices of the token (a 2-tuple of ints) - the original line (string) - -It is designed to match the working of the Python tokenizer exactly, except -that it produces COMMENT tokens for comments and gives type OP for all -operators. Additionally, all token lists start with an ENCODING token -which tells you which encoding was used to decode the bytes stream. -""" - -__author__ = 'Ka-Ping Yee ' -__credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, ' - 'Skip Montanaro, Raymond Hettinger, Trent Nelson, ' - 'Michael Foord') -from builtins import open as _builtin_open -from codecs import lookup, BOM_UTF8 -import collections -import functools -from io import TextIOWrapper -import itertools as _itertools -import re -import sys -from token import * -from token import EXACT_TOKEN_TYPES - -cookie_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII) -blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) - -import token -__all__ = token.__all__ + ["tokenize", "generate_tokens", "detect_encoding", - "untokenize", "TokenInfo"] -del token - -class TokenInfo(collections.namedtuple('TokenInfo', 'type string start end line')): - def __repr__(self): - annotated_type = '%d (%s)' % (self.type, tok_name[self.type]) - return ('TokenInfo(type=%s, string=%r, start=%r, end=%r, line=%r)' % - self._replace(type=annotated_type)) - - @property - def exact_type(self): - if self.type == OP and self.string in EXACT_TOKEN_TYPES: - return EXACT_TOKEN_TYPES[self.string] - else: - return self.type - -def group(*choices): return '(' + '|'.join(choices) + ')' -def any(*choices): return group(*choices) + '*' -def maybe(*choices): return group(*choices) + '?' - -# Note: we use unicode matching for names ("\w") but ascii matching for -# number literals. -Whitespace = r'[ \f\t]*' -Comment = r'#[^\r\n]*' -Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment) -Name = r'\w+' - -Hexnumber = r'0[xX](?:_?[0-9a-fA-F])+' -Binnumber = r'0[bB](?:_?[01])+' -Octnumber = r'0[oO](?:_?[0-7])+' -Decnumber = r'(?:0(?:_?0)*|[1-9](?:_?[0-9])*)' -Intnumber = group(Hexnumber, Binnumber, Octnumber, Decnumber) -Exponent = r'[eE][-+]?[0-9](?:_?[0-9])*' -Pointfloat = group(r'[0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?', - r'\.[0-9](?:_?[0-9])*') + maybe(Exponent) -Expfloat = r'[0-9](?:_?[0-9])*' + Exponent -Floatnumber = group(Pointfloat, Expfloat) -Imagnumber = group(r'[0-9](?:_?[0-9])*[jJ]', Floatnumber + r'[jJ]') -Number = group(Imagnumber, Floatnumber, Intnumber) - -# Return the empty string, plus all of the valid string prefixes. -def _all_string_prefixes(): - # The valid string prefixes. Only contain the lower case versions, - # and don't contain any permutations (include 'fr', but not - # 'rf'). The various permutations will be generated. - _valid_string_prefixes = ['b', 'r', 'u', 'f', 'br', 'fr'] - # if we add binary f-strings, add: ['fb', 'fbr'] - result = {''} - for prefix in _valid_string_prefixes: - for t in _itertools.permutations(prefix): - # create a list with upper and lower versions of each - # character - for u in _itertools.product(*[(c, c.upper()) for c in t]): - result.add(''.join(u)) - return result - -@functools.lru_cache -def _compile(expr): - return re.compile(expr, re.UNICODE) - -# Note that since _all_string_prefixes includes the empty string, -# StringPrefix can be the empty string (making it optional). -StringPrefix = group(*_all_string_prefixes()) - -# Tail end of ' string. -Single = r"[^'\\]*(?:\\.[^'\\]*)*'" -# Tail end of " string. -Double = r'[^"\\]*(?:\\.[^"\\]*)*"' -# Tail end of ''' string. -Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''" -# Tail end of """ string. -Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""' -Triple = group(StringPrefix + "'''", StringPrefix + '"""') -# Single-line ' or " string. -String = group(StringPrefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*'", - StringPrefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*"') - -# Sorting in reverse order puts the long operators before their prefixes. -# Otherwise if = came before ==, == would get recognized as two instances -# of =. -Special = group(*map(re.escape, sorted(EXACT_TOKEN_TYPES, reverse=True))) -Funny = group(r'\r?\n', Special) - -PlainToken = group(Number, Funny, String, Name) -Token = Ignore + PlainToken - -# First (or only) line of ' or " string. -ContStr = group(StringPrefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*" + - group("'", r'\\\r?\n'), - StringPrefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*' + - group('"', r'\\\r?\n')) -PseudoExtras = group(r'\\\r?\n|\Z', Comment, Triple) -PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name) - -# For a given string prefix plus quotes, endpats maps it to a regex -# to match the remainder of that string. _prefix can be empty, for -# a normal single or triple quoted string (with no prefix). -endpats = {} -for _prefix in _all_string_prefixes(): - endpats[_prefix + "'"] = Single - endpats[_prefix + '"'] = Double - endpats[_prefix + "'''"] = Single3 - endpats[_prefix + '"""'] = Double3 -del _prefix - -# A set of all of the single and triple quoted string prefixes, -# including the opening quotes. -single_quoted = set() -triple_quoted = set() -for t in _all_string_prefixes(): - for u in (t + '"', t + "'"): - single_quoted.add(u) - for u in (t + '"""', t + "'''"): - triple_quoted.add(u) -del t, u - -tabsize = 8 - -class TokenError(Exception): pass - -class StopTokenizing(Exception): pass - - -class Untokenizer: - - def __init__(self): - self.tokens = [] - self.prev_row = 1 - self.prev_col = 0 - self.encoding = None - - def add_whitespace(self, start): - row, col = start - if row < self.prev_row or row == self.prev_row and col < self.prev_col: - raise ValueError("start ({},{}) precedes previous end ({},{})" - .format(row, col, self.prev_row, self.prev_col)) - row_offset = row - self.prev_row - if row_offset: - self.tokens.append("\\\n" * row_offset) - self.prev_col = 0 - col_offset = col - self.prev_col - if col_offset: - self.tokens.append(" " * col_offset) - - def untokenize(self, iterable): - it = iter(iterable) - indents = [] - startline = False - for t in it: - if len(t) == 2: - self.compat(t, it) - break - tok_type, token, start, end, line = t - if tok_type == ENCODING: - self.encoding = token - continue - if tok_type == ENDMARKER: - break - if tok_type == INDENT: - indents.append(token) - continue - elif tok_type == DEDENT: - indents.pop() - self.prev_row, self.prev_col = end - continue - elif tok_type in (NEWLINE, NL): - startline = True - elif startline and indents: - indent = indents[-1] - if start[1] >= len(indent): - self.tokens.append(indent) - self.prev_col = len(indent) - startline = False - self.add_whitespace(start) - self.tokens.append(token) - self.prev_row, self.prev_col = end - if tok_type in (NEWLINE, NL): - self.prev_row += 1 - self.prev_col = 0 - return "".join(self.tokens) - - def compat(self, token, iterable): - indents = [] - toks_append = self.tokens.append - startline = token[0] in (NEWLINE, NL) - prevstring = False - - for tok in _itertools.chain([token], iterable): - toknum, tokval = tok[:2] - if toknum == ENCODING: - self.encoding = tokval - continue - - if toknum in (NAME, NUMBER): - tokval += ' ' - - # Insert a space between two consecutive strings - if toknum == STRING: - if prevstring: - tokval = ' ' + tokval - prevstring = True - else: - prevstring = False - - if toknum == INDENT: - indents.append(tokval) - continue - elif toknum == DEDENT: - indents.pop() - continue - elif toknum in (NEWLINE, NL): - startline = True - elif startline and indents: - toks_append(indents[-1]) - startline = False - toks_append(tokval) - - -def untokenize(iterable): - """Transform tokens back into Python source code. - It returns a bytes object, encoded using the ENCODING - token, which is the first token sequence output by tokenize. - - Each element returned by the iterable must be a token sequence - with at least two elements, a token number and token value. If - only two tokens are passed, the resulting output is poor. - - Round-trip invariant for full input: - Untokenized source will match input source exactly - - Round-trip invariant for limited input: - # Output bytes will tokenize back to the input - t1 = [tok[:2] for tok in tokenize(f.readline)] - newcode = untokenize(t1) - readline = BytesIO(newcode).readline - t2 = [tok[:2] for tok in tokenize(readline)] - assert t1 == t2 - """ - ut = Untokenizer() - out = ut.untokenize(iterable) - if ut.encoding is not None: - out = out.encode(ut.encoding) - return out - - -def _get_normal_name(orig_enc): - """Imitates get_normal_name in tokenizer.c.""" - # Only care about the first 12 characters. - enc = orig_enc[:12].lower().replace("_", "-") - if enc == "utf-8" or enc.startswith("utf-8-"): - return "utf-8" - if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ - enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): - return "iso-8859-1" - return orig_enc - -def detect_encoding(readline): - """ - The detect_encoding() function is used to detect the encoding that should - be used to decode a Python source file. It requires one argument, readline, - in the same way as the tokenize() generator. - - It will call readline a maximum of twice, and return the encoding used - (as a string) and a list of any lines (left as bytes) it has read in. - - It detects the encoding from the presence of a utf-8 bom or an encoding - cookie as specified in pep-0263. If both a bom and a cookie are present, - but disagree, a SyntaxError will be raised. If the encoding cookie is an - invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, - 'utf-8-sig' is returned. - - If no encoding is specified, then the default of 'utf-8' will be returned. - """ - try: - filename = readline.__self__.name - except AttributeError: - filename = None - bom_found = False - encoding = None - default = 'utf-8' - def read_or_stop(): - try: - return readline() - except StopIteration: - return b'' - - def find_cookie(line): - try: - # Decode as UTF-8. Either the line is an encoding declaration, - # in which case it should be pure ASCII, or it must be UTF-8 - # per default encoding. - line_string = line.decode('utf-8') - except UnicodeDecodeError: - msg = "invalid or missing encoding declaration" - if filename is not None: - msg = '{} for {!r}'.format(msg, filename) - raise SyntaxError(msg) - - match = cookie_re.match(line_string) - if not match: - return None - encoding = _get_normal_name(match.group(1)) - try: - codec = lookup(encoding) - except LookupError: - # This behaviour mimics the Python interpreter - if filename is None: - msg = "unknown encoding: " + encoding - else: - msg = "unknown encoding for {!r}: {}".format(filename, - encoding) - raise SyntaxError(msg) - - if bom_found: - if encoding != 'utf-8': - # This behaviour mimics the Python interpreter - if filename is None: - msg = 'encoding problem: utf-8' - else: - msg = 'encoding problem for {!r}: utf-8'.format(filename) - raise SyntaxError(msg) - encoding += '-sig' - return encoding - - first = read_or_stop() - if first.startswith(BOM_UTF8): - bom_found = True - first = first[3:] - default = 'utf-8-sig' - if not first: - return default, [] - - encoding = find_cookie(first) - if encoding: - return encoding, [first] - if not blank_re.match(first): - return default, [first] - - second = read_or_stop() - if not second: - return default, [first] - - encoding = find_cookie(second) - if encoding: - return encoding, [first, second] - - return default, [first, second] - - -def open(filename): - """Open a file in read only mode using the encoding detected by - detect_encoding(). - """ - buffer = _builtin_open(filename, 'rb') - try: - encoding, lines = detect_encoding(buffer.readline) - buffer.seek(0) - text = TextIOWrapper(buffer, encoding, line_buffering=True) - text.mode = 'r' - return text - except: - buffer.close() - raise - - -def tokenize(readline): - """ - The tokenize() generator requires one argument, readline, which - must be a callable object which provides the same interface as the - readline() method of built-in file objects. Each call to the function - should return one line of input as bytes. Alternatively, readline - can be a callable function terminating with StopIteration: - readline = open(myfile, 'rb').__next__ # Example of alternate readline - - The generator produces 5-tuples with these members: the token type; the - token string; a 2-tuple (srow, scol) of ints specifying the row and - column where the token begins in the source; a 2-tuple (erow, ecol) of - ints specifying the row and column where the token ends in the source; - and the line on which the token was found. The line passed is the - physical line. - - The first token sequence will always be an ENCODING token - which tells you which encoding was used to decode the bytes stream. - """ - encoding, consumed = detect_encoding(readline) - empty = _itertools.repeat(b"") - rl_gen = _itertools.chain(consumed, iter(readline, b""), empty) - return _tokenize(rl_gen.__next__, encoding) - - -def _tokenize(readline, encoding): - lnum = parenlev = continued = 0 - numchars = '0123456789' - contstr, needcont = '', 0 - contline = None - indents = [0] - - if encoding is not None: - if encoding == "utf-8-sig": - # BOM will already have been stripped. - encoding = "utf-8" - yield TokenInfo(ENCODING, encoding, (0, 0), (0, 0), '') - last_line = b'' - line = b'' - while True: # loop over lines in stream - try: - # We capture the value of the line variable here because - # readline uses the empty string '' to signal end of input, - # hence `line` itself will always be overwritten at the end - # of this loop. - last_line = line - line = readline() - except StopIteration: - line = b'' - - if encoding is not None: - line = line.decode(encoding) - lnum += 1 - pos, max = 0, len(line) - - if contstr: # continued string - if not line: - raise TokenError("EOF in multi-line string", strstart) - endmatch = endprog.match(line) - if endmatch: - pos = end = endmatch.end(0) - yield TokenInfo(STRING, contstr + line[:end], - strstart, (lnum, end), contline + line) - contstr, needcont = '', 0 - contline = None - elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': - yield TokenInfo(ERRORTOKEN, contstr + line, - strstart, (lnum, len(line)), contline) - contstr = '' - contline = None - continue - else: - contstr = contstr + line - contline = contline + line - continue - - elif parenlev == 0 and not continued: # new statement - if not line: break - column = 0 - while pos < max: # measure leading whitespace - if line[pos] == ' ': - column += 1 - elif line[pos] == '\t': - column = (column//tabsize + 1)*tabsize - elif line[pos] == '\f': - column = 0 - else: - break - pos += 1 - if pos == max: - break - - if line[pos] in '#\r\n': # skip comments or blank lines - if line[pos] == '#': - comment_token = line[pos:].rstrip('\r\n') - yield TokenInfo(COMMENT, comment_token, - (lnum, pos), (lnum, pos + len(comment_token)), line) - pos += len(comment_token) - - yield TokenInfo(NL, line[pos:], - (lnum, pos), (lnum, len(line)), line) - continue - - if column > indents[-1]: # count indents or dedents - indents.append(column) - yield TokenInfo(INDENT, line[:pos], (lnum, 0), (lnum, pos), line) - while column < indents[-1]: - if column not in indents: - raise IndentationError( - "unindent does not match any outer indentation level", - ("", lnum, pos, line)) - indents = indents[:-1] - - yield TokenInfo(DEDENT, '', (lnum, pos), (lnum, pos), line) - - else: # continued statement - if not line: - raise TokenError("EOF in multi-line statement", (lnum, 0)) - continued = 0 - - while pos < max: - pseudomatch = _compile(PseudoToken).match(line, pos) - if pseudomatch: # scan for tokens - start, end = pseudomatch.span(1) - spos, epos, pos = (lnum, start), (lnum, end), end - if start == end: - continue - token, initial = line[start:end], line[start] - - if (initial in numchars or # ordinary number - (initial == '.' and token != '.' and token != '...')): - yield TokenInfo(NUMBER, token, spos, epos, line) - elif initial in '\r\n': - if parenlev > 0: - yield TokenInfo(NL, token, spos, epos, line) - else: - yield TokenInfo(NEWLINE, token, spos, epos, line) - - elif initial == '#': - assert not token.endswith("\n") - yield TokenInfo(COMMENT, token, spos, epos, line) - - elif token in triple_quoted: - endprog = _compile(endpats[token]) - endmatch = endprog.match(line, pos) - if endmatch: # all on one line - pos = endmatch.end(0) - token = line[start:pos] - yield TokenInfo(STRING, token, spos, (lnum, pos), line) - else: - strstart = (lnum, start) # multiple lines - contstr = line[start:] - contline = line - break - - # Check up to the first 3 chars of the token to see if - # they're in the single_quoted set. If so, they start - # a string. - # We're using the first 3, because we're looking for - # "rb'" (for example) at the start of the token. If - # we switch to longer prefixes, this needs to be - # adjusted. - # Note that initial == token[:1]. - # Also note that single quote checking must come after - # triple quote checking (above). - elif (initial in single_quoted or - token[:2] in single_quoted or - token[:3] in single_quoted): - if token[-1] == '\n': # continued string - strstart = (lnum, start) - # Again, using the first 3 chars of the - # token. This is looking for the matching end - # regex for the correct type of quote - # character. So it's really looking for - # endpats["'"] or endpats['"'], by trying to - # skip string prefix characters, if any. - endprog = _compile(endpats.get(initial) or - endpats.get(token[1]) or - endpats.get(token[2])) - contstr, needcont = line[start:], 1 - contline = line - break - else: # ordinary string - yield TokenInfo(STRING, token, spos, epos, line) - - elif initial.isidentifier(): # ordinary name - yield TokenInfo(NAME, token, spos, epos, line) - elif initial == '\\': # continued stmt - continued = 1 - else: - if initial in '([{': - parenlev += 1 - elif initial in ')]}': - parenlev -= 1 - yield TokenInfo(OP, token, spos, epos, line) - else: - yield TokenInfo(ERRORTOKEN, line[pos], - (lnum, pos), (lnum, pos+1), line) - pos += 1 - - # Add an implicit NEWLINE if the input doesn't end in one - if last_line and last_line[-1] not in '\r\n' and not last_line.strip().startswith("#"): - yield TokenInfo(NEWLINE, '', (lnum - 1, len(last_line)), (lnum - 1, len(last_line) + 1), '') - for indent in indents[1:]: # pop remaining indent levels - yield TokenInfo(DEDENT, '', (lnum, 0), (lnum, 0), '') - yield TokenInfo(ENDMARKER, '', (lnum, 0), (lnum, 0), '') - - -def generate_tokens(readline): - """Tokenize a source reading Python code as unicode strings. - - This has the same API as tokenize(), except that it expects the *readline* - callable to return str objects instead of bytes. - """ - return _tokenize(readline, None) - -def main(): - import argparse - - # Helper error handling routines - def perror(message): - sys.stderr.write(message) - sys.stderr.write('\n') - - def error(message, filename=None, location=None): - if location: - args = (filename,) + location + (message,) - perror("%s:%d:%d: error: %s" % args) - elif filename: - perror("%s: error: %s" % (filename, message)) - else: - perror("error: %s" % message) - sys.exit(1) - - # Parse the arguments and options - parser = argparse.ArgumentParser(prog='python -m tokenize') - parser.add_argument(dest='filename', nargs='?', - metavar='filename.py', - help='the file to tokenize; defaults to stdin') - parser.add_argument('-e', '--exact', dest='exact', action='store_true', - help='display token names using the exact type') - args = parser.parse_args() - - try: - # Tokenize the input - if args.filename: - filename = args.filename - with _builtin_open(filename, 'rb') as f: - tokens = list(tokenize(f.readline)) - else: - filename = "" - tokens = _tokenize(sys.stdin.readline, None) - - # Output the tokenization - for token in tokens: - token_type = token.type - if args.exact: - token_type = token.exact_type - token_range = "%d,%d-%d,%d:" % (token.start + token.end) - print("%-20s%-15s%-15r" % - (token_range, tok_name[token_type], token.string)) - except IndentationError as err: - line, column = err.args[1][1:3] - error(err.args[0], filename, (line, column)) - except TokenError as err: - line, column = err.args[1] - error(err.args[0], filename, (line, column)) - except SyntaxError as err: - error(err, filename) - except OSError as err: - error(err) - except KeyboardInterrupt: - print("interrupted\n") - except Exception as err: - perror("unexpected error: %s" % err) - raise - -def _generate_tokens_from_c_tokenizer(source): - """Tokenize a source reading Python code as unicode strings using the internal C tokenizer""" - import _tokenize as c_tokenizer - for info in c_tokenizer.TokenizerIter(source): - tok, type, lineno, end_lineno, col_off, end_col_off, line = info - yield TokenInfo(type, tok, (lineno, col_off), (end_lineno, end_col_off), line) - - -if __name__ == "__main__": - main() diff --git a/python/Lib/trace.py b/python/Lib/trace.py deleted file mode 100644 index 1be4ec5..0000000 --- a/python/Lib/trace.py +++ /dev/null @@ -1,740 +0,0 @@ -#!/usr/bin/env python3 - -# portions copyright 2001, Autonomous Zones Industries, Inc., all rights... -# err... reserved and offered to the public under the terms of the -# Python 2.2 license. -# Author: Zooko O'Whielacronx -# http://zooko.com/ -# mailto:zooko@zooko.com -# -# Copyright 2000, Mojam Media, Inc., all rights reserved. -# Author: Skip Montanaro -# -# Copyright 1999, Bioreason, Inc., all rights reserved. -# Author: Andrew Dalke -# -# Copyright 1995-1997, Automatrix, Inc., all rights reserved. -# Author: Skip Montanaro -# -# Copyright 1991-1995, Stichting Mathematisch Centrum, all rights reserved. -# -# -# Permission to use, copy, modify, and distribute this Python software and -# its associated documentation for any purpose without fee is hereby -# granted, provided that the above copyright notice appears in all copies, -# and that both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of neither Automatrix, -# Bioreason or Mojam Media be used in advertising or publicity pertaining to -# distribution of the software without specific, written prior permission. -# -"""program/module to trace Python program or function execution - -Sample use, command line: - trace.py -c -f counts --ignore-dir '$prefix' spam.py eggs - trace.py -t --ignore-dir '$prefix' spam.py eggs - trace.py --trackcalls spam.py eggs - -Sample use, programmatically - import sys - - # create a Trace object, telling it what to ignore, and whether to - # do tracing or line-counting or both. - tracer = trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix,], - trace=0, count=1) - # run the new command using the given tracer - tracer.run('main()') - # make a report, placing output in /tmp - r = tracer.results() - r.write_results(show_missing=True, coverdir="/tmp") -""" -__all__ = ['Trace', 'CoverageResults'] - -import linecache -import os -import sys -import sysconfig -import token -import tokenize -import inspect -import gc -import dis -import pickle -from time import monotonic as _time - -import threading - -PRAGMA_NOCOVER = "#pragma NO COVER" - -class _Ignore: - def __init__(self, modules=None, dirs=None): - self._mods = set() if not modules else set(modules) - self._dirs = [] if not dirs else [os.path.normpath(d) - for d in dirs] - self._ignore = { '': 1 } - - def names(self, filename, modulename): - if modulename in self._ignore: - return self._ignore[modulename] - - # haven't seen this one before, so see if the module name is - # on the ignore list. - if modulename in self._mods: # Identical names, so ignore - self._ignore[modulename] = 1 - return 1 - - # check if the module is a proper submodule of something on - # the ignore list - for mod in self._mods: - # Need to take some care since ignoring - # "cmp" mustn't mean ignoring "cmpcache" but ignoring - # "Spam" must also mean ignoring "Spam.Eggs". - if modulename.startswith(mod + '.'): - self._ignore[modulename] = 1 - return 1 - - # Now check that filename isn't in one of the directories - if filename is None: - # must be a built-in, so we must ignore - self._ignore[modulename] = 1 - return 1 - - # Ignore a file when it contains one of the ignorable paths - for d in self._dirs: - # The '+ os.sep' is to ensure that d is a parent directory, - # as compared to cases like: - # d = "/usr/local" - # filename = "/usr/local.py" - # or - # d = "/usr/local.py" - # filename = "/usr/local.py" - if filename.startswith(d + os.sep): - self._ignore[modulename] = 1 - return 1 - - # Tried the different ways, so we don't ignore this module - self._ignore[modulename] = 0 - return 0 - -def _modname(path): - """Return a plausible module name for the path.""" - - base = os.path.basename(path) - filename, ext = os.path.splitext(base) - return filename - -def _fullmodname(path): - """Return a plausible module name for the path.""" - - # If the file 'path' is part of a package, then the filename isn't - # enough to uniquely identify it. Try to do the right thing by - # looking in sys.path for the longest matching prefix. We'll - # assume that the rest is the package name. - - comparepath = os.path.normcase(path) - longest = "" - for dir in sys.path: - dir = os.path.normcase(dir) - if comparepath.startswith(dir) and comparepath[len(dir)] == os.sep: - if len(dir) > len(longest): - longest = dir - - if longest: - base = path[len(longest) + 1:] - else: - base = path - # the drive letter is never part of the module name - drive, base = os.path.splitdrive(base) - base = base.replace(os.sep, ".") - if os.altsep: - base = base.replace(os.altsep, ".") - filename, ext = os.path.splitext(base) - return filename.lstrip(".") - -class CoverageResults: - def __init__(self, counts=None, calledfuncs=None, infile=None, - callers=None, outfile=None): - self.counts = counts - if self.counts is None: - self.counts = {} - self.counter = self.counts.copy() # map (filename, lineno) to count - self.calledfuncs = calledfuncs - if self.calledfuncs is None: - self.calledfuncs = {} - self.calledfuncs = self.calledfuncs.copy() - self.callers = callers - if self.callers is None: - self.callers = {} - self.callers = self.callers.copy() - self.infile = infile - self.outfile = outfile - if self.infile: - # Try to merge existing counts file. - try: - with open(self.infile, 'rb') as f: - counts, calledfuncs, callers = pickle.load(f) - self.update(self.__class__(counts, calledfuncs, callers=callers)) - except (OSError, EOFError, ValueError) as err: - print(("Skipping counts file %r: %s" - % (self.infile, err)), file=sys.stderr) - - def is_ignored_filename(self, filename): - """Return True if the filename does not refer to a file - we want to have reported. - """ - return filename.startswith('<') and filename.endswith('>') - - def update(self, other): - """Merge in the data from another CoverageResults""" - counts = self.counts - calledfuncs = self.calledfuncs - callers = self.callers - other_counts = other.counts - other_calledfuncs = other.calledfuncs - other_callers = other.callers - - for key in other_counts: - counts[key] = counts.get(key, 0) + other_counts[key] - - for key in other_calledfuncs: - calledfuncs[key] = 1 - - for key in other_callers: - callers[key] = 1 - - def write_results(self, show_missing=True, summary=False, coverdir=None): - """ - Write the coverage results. - - :param show_missing: Show lines that had no hits. - :param summary: Include coverage summary per module. - :param coverdir: If None, the results of each module are placed in its - directory, otherwise it is included in the directory - specified. - """ - if self.calledfuncs: - print() - print("functions called:") - calls = self.calledfuncs - for filename, modulename, funcname in sorted(calls): - print(("filename: %s, modulename: %s, funcname: %s" - % (filename, modulename, funcname))) - - if self.callers: - print() - print("calling relationships:") - lastfile = lastcfile = "" - for ((pfile, pmod, pfunc), (cfile, cmod, cfunc)) \ - in sorted(self.callers): - if pfile != lastfile: - print() - print("***", pfile, "***") - lastfile = pfile - lastcfile = "" - if cfile != pfile and lastcfile != cfile: - print(" -->", cfile) - lastcfile = cfile - print(" %s.%s -> %s.%s" % (pmod, pfunc, cmod, cfunc)) - - # turn the counts data ("(filename, lineno) = count") into something - # accessible on a per-file basis - per_file = {} - for filename, lineno in self.counts: - lines_hit = per_file[filename] = per_file.get(filename, {}) - lines_hit[lineno] = self.counts[(filename, lineno)] - - # accumulate summary info, if needed - sums = {} - - for filename, count in per_file.items(): - if self.is_ignored_filename(filename): - continue - - if filename.endswith(".pyc"): - filename = filename[:-1] - - if coverdir is None: - dir = os.path.dirname(os.path.abspath(filename)) - modulename = _modname(filename) - else: - dir = coverdir - if not os.path.exists(dir): - os.makedirs(dir) - modulename = _fullmodname(filename) - - # If desired, get a list of the line numbers which represent - # executable content (returned as a dict for better lookup speed) - if show_missing: - lnotab = _find_executable_linenos(filename) - else: - lnotab = {} - source = linecache.getlines(filename) - coverpath = os.path.join(dir, modulename + ".cover") - with open(filename, 'rb') as fp: - encoding, _ = tokenize.detect_encoding(fp.readline) - n_hits, n_lines = self.write_results_file(coverpath, source, - lnotab, count, encoding) - if summary and n_lines: - percent = int(100 * n_hits / n_lines) - sums[modulename] = n_lines, percent, modulename, filename - - - if summary and sums: - print("lines cov% module (path)") - for m in sorted(sums): - n_lines, percent, modulename, filename = sums[m] - print("%5d %3d%% %s (%s)" % sums[m]) - - if self.outfile: - # try and store counts and module info into self.outfile - try: - with open(self.outfile, 'wb') as f: - pickle.dump((self.counts, self.calledfuncs, self.callers), - f, 1) - except OSError as err: - print("Can't save counts files because %s" % err, file=sys.stderr) - - def write_results_file(self, path, lines, lnotab, lines_hit, encoding=None): - """Return a coverage results file in path.""" - # ``lnotab`` is a dict of executable lines, or a line number "table" - - try: - outfile = open(path, "w", encoding=encoding) - except OSError as err: - print(("trace: Could not open %r for writing: %s " - "- skipping" % (path, err)), file=sys.stderr) - return 0, 0 - - n_lines = 0 - n_hits = 0 - with outfile: - for lineno, line in enumerate(lines, 1): - # do the blank/comment match to try to mark more lines - # (help the reader find stuff that hasn't been covered) - if lineno in lines_hit: - outfile.write("%5d: " % lines_hit[lineno]) - n_hits += 1 - n_lines += 1 - elif lineno in lnotab and not PRAGMA_NOCOVER in line: - # Highlight never-executed lines, unless the line contains - # #pragma: NO COVER - outfile.write(">>>>>> ") - n_lines += 1 - else: - outfile.write(" ") - outfile.write(line.expandtabs(8)) - - return n_hits, n_lines - -def _find_lines_from_code(code, strs): - """Return dict where keys are lines in the line number table.""" - linenos = {} - - for _, lineno in dis.findlinestarts(code): - if lineno not in strs: - linenos[lineno] = 1 - - return linenos - -def _find_lines(code, strs): - """Return lineno dict for all code objects reachable from code.""" - # get all of the lineno information from the code of this scope level - linenos = _find_lines_from_code(code, strs) - - # and check the constants for references to other code objects - for c in code.co_consts: - if inspect.iscode(c): - # find another code object, so recurse into it - linenos.update(_find_lines(c, strs)) - return linenos - -def _find_strings(filename, encoding=None): - """Return a dict of possible docstring positions. - - The dict maps line numbers to strings. There is an entry for - line that contains only a string or a part of a triple-quoted - string. - """ - d = {} - # If the first token is a string, then it's the module docstring. - # Add this special case so that the test in the loop passes. - prev_ttype = token.INDENT - with open(filename, encoding=encoding) as f: - tok = tokenize.generate_tokens(f.readline) - for ttype, tstr, start, end, line in tok: - if ttype == token.STRING: - if prev_ttype == token.INDENT: - sline, scol = start - eline, ecol = end - for i in range(sline, eline + 1): - d[i] = 1 - prev_ttype = ttype - return d - -def _find_executable_linenos(filename): - """Return dict where keys are line numbers in the line number table.""" - try: - with tokenize.open(filename) as f: - prog = f.read() - encoding = f.encoding - except OSError as err: - print(("Not printing coverage data for %r: %s" - % (filename, err)), file=sys.stderr) - return {} - code = compile(prog, filename, "exec") - strs = _find_strings(filename, encoding) - return _find_lines(code, strs) - -class Trace: - def __init__(self, count=1, trace=1, countfuncs=0, countcallers=0, - ignoremods=(), ignoredirs=(), infile=None, outfile=None, - timing=False): - """ - @param count true iff it should count number of times each - line is executed - @param trace true iff it should print out each line that is - being counted - @param countfuncs true iff it should just output a list of - (filename, modulename, funcname,) for functions - that were called at least once; This overrides - `count' and `trace' - @param ignoremods a list of the names of modules to ignore - @param ignoredirs a list of the names of directories to ignore - all of the (recursive) contents of - @param infile file from which to read stored counts to be - added into the results - @param outfile file in which to write the results - @param timing true iff timing information be displayed - """ - self.infile = infile - self.outfile = outfile - self.ignore = _Ignore(ignoremods, ignoredirs) - self.counts = {} # keys are (filename, linenumber) - self.pathtobasename = {} # for memoizing os.path.basename - self.donothing = 0 - self.trace = trace - self._calledfuncs = {} - self._callers = {} - self._caller_cache = {} - self.start_time = None - if timing: - self.start_time = _time() - if countcallers: - self.globaltrace = self.globaltrace_trackcallers - elif countfuncs: - self.globaltrace = self.globaltrace_countfuncs - elif trace and count: - self.globaltrace = self.globaltrace_lt - self.localtrace = self.localtrace_trace_and_count - elif trace: - self.globaltrace = self.globaltrace_lt - self.localtrace = self.localtrace_trace - elif count: - self.globaltrace = self.globaltrace_lt - self.localtrace = self.localtrace_count - else: - # Ahem -- do nothing? Okay. - self.donothing = 1 - - def run(self, cmd): - import __main__ - dict = __main__.__dict__ - self.runctx(cmd, dict, dict) - - def runctx(self, cmd, globals=None, locals=None): - if globals is None: globals = {} - if locals is None: locals = {} - if not self.donothing: - threading.settrace(self.globaltrace) - sys.settrace(self.globaltrace) - try: - exec(cmd, globals, locals) - finally: - if not self.donothing: - sys.settrace(None) - threading.settrace(None) - - def runfunc(self, func, /, *args, **kw): - result = None - if not self.donothing: - sys.settrace(self.globaltrace) - try: - result = func(*args, **kw) - finally: - if not self.donothing: - sys.settrace(None) - return result - - def file_module_function_of(self, frame): - code = frame.f_code - filename = code.co_filename - if filename: - modulename = _modname(filename) - else: - modulename = None - - funcname = code.co_name - clsname = None - if code in self._caller_cache: - if self._caller_cache[code] is not None: - clsname = self._caller_cache[code] - else: - self._caller_cache[code] = None - ## use of gc.get_referrers() was suggested by Michael Hudson - # all functions which refer to this code object - funcs = [f for f in gc.get_referrers(code) - if inspect.isfunction(f)] - # require len(func) == 1 to avoid ambiguity caused by calls to - # new.function(): "In the face of ambiguity, refuse the - # temptation to guess." - if len(funcs) == 1: - dicts = [d for d in gc.get_referrers(funcs[0]) - if isinstance(d, dict)] - if len(dicts) == 1: - classes = [c for c in gc.get_referrers(dicts[0]) - if hasattr(c, "__bases__")] - if len(classes) == 1: - # ditto for new.classobj() - clsname = classes[0].__name__ - # cache the result - assumption is that new.* is - # not called later to disturb this relationship - # _caller_cache could be flushed if functions in - # the new module get called. - self._caller_cache[code] = clsname - if clsname is not None: - funcname = "%s.%s" % (clsname, funcname) - - return filename, modulename, funcname - - def globaltrace_trackcallers(self, frame, why, arg): - """Handler for call events. - - Adds information about who called who to the self._callers dict. - """ - if why == 'call': - # XXX Should do a better job of identifying methods - this_func = self.file_module_function_of(frame) - parent_func = self.file_module_function_of(frame.f_back) - self._callers[(parent_func, this_func)] = 1 - - def globaltrace_countfuncs(self, frame, why, arg): - """Handler for call events. - - Adds (filename, modulename, funcname) to the self._calledfuncs dict. - """ - if why == 'call': - this_func = self.file_module_function_of(frame) - self._calledfuncs[this_func] = 1 - - def globaltrace_lt(self, frame, why, arg): - """Handler for call events. - - If the code block being entered is to be ignored, returns `None', - else returns self.localtrace. - """ - if why == 'call': - code = frame.f_code - filename = frame.f_globals.get('__file__', None) - if filename: - # XXX _modname() doesn't work right for packages, so - # the ignore support won't work right for packages - modulename = _modname(filename) - if modulename is not None: - ignore_it = self.ignore.names(filename, modulename) - if not ignore_it: - if self.trace: - print((" --- modulename: %s, funcname: %s" - % (modulename, code.co_name))) - return self.localtrace - else: - return None - - def localtrace_trace_and_count(self, frame, why, arg): - if why == "line": - # record the file name and line number of every trace - filename = frame.f_code.co_filename - lineno = frame.f_lineno - key = filename, lineno - self.counts[key] = self.counts.get(key, 0) + 1 - - if self.start_time: - print('%.2f' % (_time() - self.start_time), end=' ') - bname = os.path.basename(filename) - print("%s(%d): %s" % (bname, lineno, - linecache.getline(filename, lineno)), end='') - return self.localtrace - - def localtrace_trace(self, frame, why, arg): - if why == "line": - # record the file name and line number of every trace - filename = frame.f_code.co_filename - lineno = frame.f_lineno - - if self.start_time: - print('%.2f' % (_time() - self.start_time), end=' ') - bname = os.path.basename(filename) - print("%s(%d): %s" % (bname, lineno, - linecache.getline(filename, lineno)), end='') - return self.localtrace - - def localtrace_count(self, frame, why, arg): - if why == "line": - filename = frame.f_code.co_filename - lineno = frame.f_lineno - key = filename, lineno - self.counts[key] = self.counts.get(key, 0) + 1 - return self.localtrace - - def results(self): - return CoverageResults(self.counts, infile=self.infile, - outfile=self.outfile, - calledfuncs=self._calledfuncs, - callers=self._callers) - -def main(): - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument('--version', action='version', version='trace 2.0') - - grp = parser.add_argument_group('Main options', - 'One of these (or --report) must be given') - - grp.add_argument('-c', '--count', action='store_true', - help='Count the number of times each line is executed and write ' - 'the counts to .cover for each module executed, in ' - 'the module\'s directory. See also --coverdir, --file, ' - '--no-report below.') - grp.add_argument('-t', '--trace', action='store_true', - help='Print each line to sys.stdout before it is executed') - grp.add_argument('-l', '--listfuncs', action='store_true', - help='Keep track of which functions are executed at least once ' - 'and write the results to sys.stdout after the program exits. ' - 'Cannot be specified alongside --trace or --count.') - grp.add_argument('-T', '--trackcalls', action='store_true', - help='Keep track of caller/called pairs and write the results to ' - 'sys.stdout after the program exits.') - - grp = parser.add_argument_group('Modifiers') - - _grp = grp.add_mutually_exclusive_group() - _grp.add_argument('-r', '--report', action='store_true', - help='Generate a report from a counts file; does not execute any ' - 'code. --file must specify the results file to read, which ' - 'must have been created in a previous run with --count ' - '--file=FILE') - _grp.add_argument('-R', '--no-report', action='store_true', - help='Do not generate the coverage report files. ' - 'Useful if you want to accumulate over several runs.') - - grp.add_argument('-f', '--file', - help='File to accumulate counts over several runs') - grp.add_argument('-C', '--coverdir', - help='Directory where the report files go. The coverage report ' - 'for . will be written to file ' - '//.cover') - grp.add_argument('-m', '--missing', action='store_true', - help='Annotate executable lines that were not executed with ' - '">>>>>> "') - grp.add_argument('-s', '--summary', action='store_true', - help='Write a brief summary for each file to sys.stdout. ' - 'Can only be used with --count or --report') - grp.add_argument('-g', '--timing', action='store_true', - help='Prefix each line with the time since the program started. ' - 'Only used while tracing') - - grp = parser.add_argument_group('Filters', - 'Can be specified multiple times') - grp.add_argument('--ignore-module', action='append', default=[], - help='Ignore the given module(s) and its submodules ' - '(if it is a package). Accepts comma separated list of ' - 'module names.') - grp.add_argument('--ignore-dir', action='append', default=[], - help='Ignore files in the given directory ' - '(multiple directories can be joined by os.pathsep).') - - parser.add_argument('--module', action='store_true', default=False, - help='Trace a module. ') - parser.add_argument('progname', nargs='?', - help='file to run as main program') - parser.add_argument('arguments', nargs=argparse.REMAINDER, - help='arguments to the program') - - opts = parser.parse_args() - - if opts.ignore_dir: - _prefix = sysconfig.get_path("stdlib") - _exec_prefix = sysconfig.get_path("platstdlib") - - def parse_ignore_dir(s): - s = os.path.expanduser(os.path.expandvars(s)) - s = s.replace('$prefix', _prefix).replace('$exec_prefix', _exec_prefix) - return os.path.normpath(s) - - opts.ignore_module = [mod.strip() - for i in opts.ignore_module for mod in i.split(',')] - opts.ignore_dir = [parse_ignore_dir(s) - for i in opts.ignore_dir for s in i.split(os.pathsep)] - - if opts.report: - if not opts.file: - parser.error('-r/--report requires -f/--file') - results = CoverageResults(infile=opts.file, outfile=opts.file) - return results.write_results(opts.missing, opts.summary, opts.coverdir) - - if not any([opts.trace, opts.count, opts.listfuncs, opts.trackcalls]): - parser.error('must specify one of --trace, --count, --report, ' - '--listfuncs, or --trackcalls') - - if opts.listfuncs and (opts.count or opts.trace): - parser.error('cannot specify both --listfuncs and (--trace or --count)') - - if opts.summary and not opts.count: - parser.error('--summary can only be used with --count or --report') - - if opts.progname is None: - parser.error('progname is missing: required with the main options') - - t = Trace(opts.count, opts.trace, countfuncs=opts.listfuncs, - countcallers=opts.trackcalls, ignoremods=opts.ignore_module, - ignoredirs=opts.ignore_dir, infile=opts.file, - outfile=opts.file, timing=opts.timing) - try: - if opts.module: - import runpy - module_name = opts.progname - mod_name, mod_spec, code = runpy._get_module_details(module_name) - sys.argv = [code.co_filename, *opts.arguments] - globs = { - '__name__': '__main__', - '__file__': code.co_filename, - '__package__': mod_spec.parent, - '__loader__': mod_spec.loader, - '__spec__': mod_spec, - '__cached__': None, - } - else: - sys.argv = [opts.progname, *opts.arguments] - sys.path[0] = os.path.dirname(opts.progname) - - with open(opts.progname, 'rb') as fp: - code = compile(fp.read(), opts.progname, 'exec') - # try to emulate __main__ namespace as much as possible - globs = { - '__file__': opts.progname, - '__name__': '__main__', - '__package__': None, - '__cached__': None, - } - t.runctx(code, globs, globs) - except OSError as err: - sys.exit("Cannot run file %r because: %s" % (sys.argv[0], err)) - except SystemExit: - pass - - results = t.results() - - if not opts.no_report: - results.write_results(opts.missing, opts.summary, opts.coverdir) - -if __name__=='__main__': - main() diff --git a/python/Lib/traceback.py b/python/Lib/traceback.py deleted file mode 100644 index 2105b63..0000000 --- a/python/Lib/traceback.py +++ /dev/null @@ -1,980 +0,0 @@ -"""Extract, format and print information about Python stack traces.""" - -import collections.abc -import itertools -import linecache -import sys -import textwrap -from contextlib import suppress - -__all__ = ['extract_stack', 'extract_tb', 'format_exception', - 'format_exception_only', 'format_list', 'format_stack', - 'format_tb', 'print_exc', 'format_exc', 'print_exception', - 'print_last', 'print_stack', 'print_tb', 'clear_frames', - 'FrameSummary', 'StackSummary', 'TracebackException', - 'walk_stack', 'walk_tb'] - -# -# Formatting and printing lists of traceback lines. -# - -def print_list(extracted_list, file=None): - """Print the list of tuples as returned by extract_tb() or - extract_stack() as a formatted stack trace to the given file.""" - if file is None: - file = sys.stderr - for item in StackSummary.from_list(extracted_list).format(): - print(item, file=file, end="") - -def format_list(extracted_list): - """Format a list of tuples or FrameSummary objects for printing. - - Given a list of tuples or FrameSummary objects as returned by - extract_tb() or extract_stack(), return a list of strings ready - for printing. - - Each string in the resulting list corresponds to the item with the - same index in the argument list. Each string ends in a newline; - the strings may contain internal newlines as well, for those items - whose source text line is not None. - """ - return StackSummary.from_list(extracted_list).format() - -# -# Printing and Extracting Tracebacks. -# - -def print_tb(tb, limit=None, file=None): - """Print up to 'limit' stack trace entries from the traceback 'tb'. - - If 'limit' is omitted or None, all entries are printed. If 'file' - is omitted or None, the output goes to sys.stderr; otherwise - 'file' should be an open file or file-like object with a write() - method. - """ - print_list(extract_tb(tb, limit=limit), file=file) - -def format_tb(tb, limit=None): - """A shorthand for 'format_list(extract_tb(tb, limit))'.""" - return extract_tb(tb, limit=limit).format() - -def extract_tb(tb, limit=None): - """ - Return a StackSummary object representing a list of - pre-processed entries from traceback. - - This is useful for alternate formatting of stack traces. If - 'limit' is omitted or None, all entries are extracted. A - pre-processed stack trace entry is a FrameSummary object - containing attributes filename, lineno, name, and line - representing the information that is usually printed for a stack - trace. The line is a string with leading and trailing - whitespace stripped; if the source is not available it is None. - """ - return StackSummary._extract_from_extended_frame_gen( - _walk_tb_with_full_positions(tb), limit=limit) - -# -# Exception formatting and output. -# - -_cause_message = ( - "\nThe above exception was the direct cause " - "of the following exception:\n\n") - -_context_message = ( - "\nDuring handling of the above exception, " - "another exception occurred:\n\n") - - -class _Sentinel: - def __repr__(self): - return "" - -_sentinel = _Sentinel() - -def _parse_value_tb(exc, value, tb): - if (value is _sentinel) != (tb is _sentinel): - raise ValueError("Both or neither of value and tb must be given") - if value is tb is _sentinel: - if exc is not None: - if isinstance(exc, BaseException): - return exc, exc.__traceback__ - - raise TypeError(f'Exception expected for value, ' - f'{type(exc).__name__} found') - else: - return None, None - return value, tb - - -def print_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \ - file=None, chain=True): - """Print exception up to 'limit' stack trace entries from 'tb' to 'file'. - - This differs from print_tb() in the following ways: (1) if - traceback is not None, it prints a header "Traceback (most recent - call last):"; (2) it prints the exception type and value after the - stack trace; (3) if type is SyntaxError and value has the - appropriate format, it prints the line where the syntax error - occurred with a caret on the next line indicating the approximate - position of the error. - """ - value, tb = _parse_value_tb(exc, value, tb) - te = TracebackException(type(value), value, tb, limit=limit, compact=True) - te.print(file=file, chain=chain) - - -def format_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \ - chain=True): - """Format a stack trace and the exception information. - - The arguments have the same meaning as the corresponding arguments - to print_exception(). The return value is a list of strings, each - ending in a newline and some containing internal newlines. When - these lines are concatenated and printed, exactly the same text is - printed as does print_exception(). - """ - value, tb = _parse_value_tb(exc, value, tb) - te = TracebackException(type(value), value, tb, limit=limit, compact=True) - return list(te.format(chain=chain)) - - -def format_exception_only(exc, /, value=_sentinel): - """Format the exception part of a traceback. - - The return value is a list of strings, each ending in a newline. - - Normally, the list contains a single string; however, for - SyntaxError exceptions, it contains several lines that (when - printed) display detailed information about where the syntax - error occurred. - - The message indicating which exception occurred is always the last - string in the list. - - """ - if value is _sentinel: - value = exc - te = TracebackException(type(value), value, None, compact=True) - return list(te.format_exception_only()) - - -# -- not official API but folk probably use these two functions. - -def _format_final_exc_line(etype, value): - valuestr = _safe_string(value, 'exception') - if value is None or not valuestr: - line = "%s\n" % etype - else: - line = "%s: %s\n" % (etype, valuestr) - return line - -def _safe_string(value, what, func=str): - try: - return func(value) - except: - return f'<{what} {func.__name__}() failed>' - -# -- - -def print_exc(limit=None, file=None, chain=True): - """Shorthand for 'print_exception(*sys.exc_info(), limit, file)'.""" - print_exception(*sys.exc_info(), limit=limit, file=file, chain=chain) - -def format_exc(limit=None, chain=True): - """Like print_exc() but return a string.""" - return "".join(format_exception(*sys.exc_info(), limit=limit, chain=chain)) - -def print_last(limit=None, file=None, chain=True): - """This is a shorthand for 'print_exception(sys.last_type, - sys.last_value, sys.last_traceback, limit, file)'.""" - if not hasattr(sys, "last_type"): - raise ValueError("no last exception") - print_exception(sys.last_type, sys.last_value, sys.last_traceback, - limit, file, chain) - -# -# Printing and Extracting Stacks. -# - -def print_stack(f=None, limit=None, file=None): - """Print a stack trace from its invocation point. - - The optional 'f' argument can be used to specify an alternate - stack frame at which to start. The optional 'limit' and 'file' - arguments have the same meaning as for print_exception(). - """ - if f is None: - f = sys._getframe().f_back - print_list(extract_stack(f, limit=limit), file=file) - - -def format_stack(f=None, limit=None): - """Shorthand for 'format_list(extract_stack(f, limit))'.""" - if f is None: - f = sys._getframe().f_back - return format_list(extract_stack(f, limit=limit)) - - -def extract_stack(f=None, limit=None): - """Extract the raw traceback from the current stack frame. - - The return value has the same format as for extract_tb(). The - optional 'f' and 'limit' arguments have the same meaning as for - print_stack(). Each item in the list is a quadruple (filename, - line number, function name, text), and the entries are in order - from oldest to newest stack frame. - """ - if f is None: - f = sys._getframe().f_back - stack = StackSummary.extract(walk_stack(f), limit=limit) - stack.reverse() - return stack - - -def clear_frames(tb): - "Clear all references to local variables in the frames of a traceback." - while tb is not None: - try: - tb.tb_frame.clear() - except RuntimeError: - # Ignore the exception raised if the frame is still executing. - pass - tb = tb.tb_next - - -class FrameSummary: - """Information about a single frame from a traceback. - - - :attr:`filename` The filename for the frame. - - :attr:`lineno` The line within filename for the frame that was - active when the frame was captured. - - :attr:`name` The name of the function or method that was executing - when the frame was captured. - - :attr:`line` The text from the linecache module for the - of code that was running when the frame was captured. - - :attr:`locals` Either None if locals were not supplied, or a dict - mapping the name to the repr() of the variable. - """ - - __slots__ = ('filename', 'lineno', 'end_lineno', 'colno', 'end_colno', - 'name', '_line', 'locals') - - def __init__(self, filename, lineno, name, *, lookup_line=True, - locals=None, line=None, - end_lineno=None, colno=None, end_colno=None): - """Construct a FrameSummary. - - :param lookup_line: If True, `linecache` is consulted for the source - code line. Otherwise, the line will be looked up when first needed. - :param locals: If supplied the frame locals, which will be captured as - object representations. - :param line: If provided, use this instead of looking up the line in - the linecache. - """ - self.filename = filename - self.lineno = lineno - self.name = name - self._line = line - if lookup_line: - self.line - self.locals = {k: repr(v) for k, v in locals.items()} if locals else None - self.end_lineno = end_lineno - self.colno = colno - self.end_colno = end_colno - - def __eq__(self, other): - if isinstance(other, FrameSummary): - return (self.filename == other.filename and - self.lineno == other.lineno and - self.name == other.name and - self.locals == other.locals) - if isinstance(other, tuple): - return (self.filename, self.lineno, self.name, self.line) == other - return NotImplemented - - def __getitem__(self, pos): - return (self.filename, self.lineno, self.name, self.line)[pos] - - def __iter__(self): - return iter([self.filename, self.lineno, self.name, self.line]) - - def __repr__(self): - return "".format( - filename=self.filename, lineno=self.lineno, name=self.name) - - def __len__(self): - return 4 - - @property - def _original_line(self): - # Returns the line as-is from the source, without modifying whitespace. - self.line - return self._line - - @property - def line(self): - if self._line is None: - if self.lineno is None: - return None - self._line = linecache.getline(self.filename, self.lineno) - return self._line.strip() - - -def walk_stack(f): - """Walk a stack yielding the frame and line number for each frame. - - This will follow f.f_back from the given frame. If no frame is given, the - current stack is used. Usually used with StackSummary.extract. - """ - if f is None: - f = sys._getframe().f_back.f_back.f_back.f_back - while f is not None: - yield f, f.f_lineno - f = f.f_back - - -def walk_tb(tb): - """Walk a traceback yielding the frame and line number for each frame. - - This will follow tb.tb_next (and thus is in the opposite order to - walk_stack). Usually used with StackSummary.extract. - """ - while tb is not None: - yield tb.tb_frame, tb.tb_lineno - tb = tb.tb_next - - -def _walk_tb_with_full_positions(tb): - # Internal version of walk_tb that yields full code positions including - # end line and column information. - while tb is not None: - positions = _get_code_position(tb.tb_frame.f_code, tb.tb_lasti) - # Yield tb_lineno when co_positions does not have a line number to - # maintain behavior with walk_tb. - if positions[0] is None: - yield tb.tb_frame, (tb.tb_lineno, ) + positions[1:] - else: - yield tb.tb_frame, positions - tb = tb.tb_next - - -def _get_code_position(code, instruction_index): - if instruction_index < 0: - return (None, None, None, None) - positions_gen = code.co_positions() - return next(itertools.islice(positions_gen, instruction_index // 2, None)) - - -_RECURSIVE_CUTOFF = 3 # Also hardcoded in traceback.c. - -class StackSummary(list): - """A list of FrameSummary objects, representing a stack of frames.""" - - @classmethod - def extract(klass, frame_gen, *, limit=None, lookup_lines=True, - capture_locals=False): - """Create a StackSummary from a traceback or stack object. - - :param frame_gen: A generator that yields (frame, lineno) tuples - whose summaries are to be included in the stack. - :param limit: None to include all frames or the number of frames to - include. - :param lookup_lines: If True, lookup lines for each frame immediately, - otherwise lookup is deferred until the frame is rendered. - :param capture_locals: If True, the local variables from each frame will - be captured as object representations into the FrameSummary. - """ - def extended_frame_gen(): - for f, lineno in frame_gen: - yield f, (lineno, None, None, None) - - return klass._extract_from_extended_frame_gen( - extended_frame_gen(), limit=limit, lookup_lines=lookup_lines, - capture_locals=capture_locals) - - @classmethod - def _extract_from_extended_frame_gen(klass, frame_gen, *, limit=None, - lookup_lines=True, capture_locals=False): - # Same as extract but operates on a frame generator that yields - # (frame, (lineno, end_lineno, colno, end_colno)) in the stack. - # Only lineno is required, the remaining fields can be None if the - # information is not available. - if limit is None: - limit = getattr(sys, 'tracebacklimit', None) - if limit is not None and limit < 0: - limit = 0 - if limit is not None: - if limit >= 0: - frame_gen = itertools.islice(frame_gen, limit) - else: - frame_gen = collections.deque(frame_gen, maxlen=-limit) - - result = klass() - fnames = set() - for f, (lineno, end_lineno, colno, end_colno) in frame_gen: - co = f.f_code - filename = co.co_filename - name = co.co_name - - fnames.add(filename) - linecache.lazycache(filename, f.f_globals) - # Must defer line lookups until we have called checkcache. - if capture_locals: - f_locals = f.f_locals - else: - f_locals = None - result.append(FrameSummary( - filename, lineno, name, lookup_line=False, locals=f_locals, - end_lineno=end_lineno, colno=colno, end_colno=end_colno)) - for filename in fnames: - linecache.checkcache(filename) - # If immediate lookup was desired, trigger lookups now. - if lookup_lines: - for f in result: - f.line - return result - - @classmethod - def from_list(klass, a_list): - """ - Create a StackSummary object from a supplied list of - FrameSummary objects or old-style list of tuples. - """ - # While doing a fast-path check for isinstance(a_list, StackSummary) is - # appealing, idlelib.run.cleanup_traceback and other similar code may - # break this by making arbitrary frames plain tuples, so we need to - # check on a frame by frame basis. - result = StackSummary() - for frame in a_list: - if isinstance(frame, FrameSummary): - result.append(frame) - else: - filename, lineno, name, line = frame - result.append(FrameSummary(filename, lineno, name, line=line)) - return result - - def format_frame_summary(self, frame_summary): - """Format the lines for a single FrameSummary. - - Returns a string representing one frame involved in the stack. This - gets called for every frame to be printed in the stack summary. - """ - row = [] - row.append(' File "{}", line {}, in {}\n'.format( - frame_summary.filename, frame_summary.lineno, frame_summary.name)) - if frame_summary.line: - stripped_line = frame_summary.line.strip() - row.append(' {}\n'.format(stripped_line)) - - orig_line_len = len(frame_summary._original_line) - frame_line_len = len(frame_summary.line.lstrip()) - stripped_characters = orig_line_len - frame_line_len - if ( - frame_summary.colno is not None - and frame_summary.end_colno is not None - ): - start_offset = _byte_offset_to_character_offset( - frame_summary._original_line, frame_summary.colno) + 1 - end_offset = _byte_offset_to_character_offset( - frame_summary._original_line, frame_summary.end_colno) + 1 - - anchors = None - if frame_summary.lineno == frame_summary.end_lineno: - with suppress(Exception): - anchors = _extract_caret_anchors_from_line_segment( - frame_summary._original_line[start_offset - 1:end_offset - 1] - ) - else: - end_offset = stripped_characters + len(stripped_line) - - # show indicators if primary char doesn't span the frame line - if end_offset - start_offset < len(stripped_line) or ( - anchors and anchors.right_start_offset - anchors.left_end_offset > 0): - row.append(' ') - row.append(' ' * (start_offset - stripped_characters)) - - if anchors: - row.append(anchors.primary_char * (anchors.left_end_offset)) - row.append(anchors.secondary_char * (anchors.right_start_offset - anchors.left_end_offset)) - row.append(anchors.primary_char * (end_offset - start_offset - anchors.right_start_offset)) - else: - row.append('^' * (end_offset - start_offset)) - - row.append('\n') - - if frame_summary.locals: - for name, value in sorted(frame_summary.locals.items()): - row.append(' {name} = {value}\n'.format(name=name, value=value)) - - return ''.join(row) - - def format(self): - """Format the stack ready for printing. - - Returns a list of strings ready for printing. Each string in the - resulting list corresponds to a single frame from the stack. - Each string ends in a newline; the strings may contain internal - newlines as well, for those items with source text lines. - - For long sequences of the same frame and line, the first few - repetitions are shown, followed by a summary line stating the exact - number of further repetitions. - """ - result = [] - last_file = None - last_line = None - last_name = None - count = 0 - for frame_summary in self: - formatted_frame = self.format_frame_summary(frame_summary) - if formatted_frame is None: - continue - if (last_file is None or last_file != frame_summary.filename or - last_line is None or last_line != frame_summary.lineno or - last_name is None or last_name != frame_summary.name): - if count > _RECURSIVE_CUTOFF: - count -= _RECURSIVE_CUTOFF - result.append( - f' [Previous line repeated {count} more ' - f'time{"s" if count > 1 else ""}]\n' - ) - last_file = frame_summary.filename - last_line = frame_summary.lineno - last_name = frame_summary.name - count = 0 - count += 1 - if count > _RECURSIVE_CUTOFF: - continue - result.append(formatted_frame) - - if count > _RECURSIVE_CUTOFF: - count -= _RECURSIVE_CUTOFF - result.append( - f' [Previous line repeated {count} more ' - f'time{"s" if count > 1 else ""}]\n' - ) - return result - - -def _byte_offset_to_character_offset(str, offset): - as_utf8 = str.encode('utf-8') - return len(as_utf8[:offset].decode("utf-8", errors="replace")) - - -_Anchors = collections.namedtuple( - "_Anchors", - [ - "left_end_offset", - "right_start_offset", - "primary_char", - "secondary_char", - ], - defaults=["~", "^"] -) - -def _extract_caret_anchors_from_line_segment(segment): - import ast - - try: - tree = ast.parse(segment) - except SyntaxError: - return None - - if len(tree.body) != 1: - return None - - normalize = lambda offset: _byte_offset_to_character_offset(segment, offset) - statement = tree.body[0] - match statement: - case ast.Expr(expr): - match expr: - case ast.BinOp(): - operator_start = normalize(expr.left.end_col_offset) - operator_end = normalize(expr.right.col_offset) - operator_str = segment[operator_start:operator_end] - operator_offset = len(operator_str) - len(operator_str.lstrip()) - - left_anchor = expr.left.end_col_offset + operator_offset - right_anchor = left_anchor + 1 - if ( - operator_offset + 1 < len(operator_str) - and not operator_str[operator_offset + 1].isspace() - ): - right_anchor += 1 - return _Anchors(normalize(left_anchor), normalize(right_anchor)) - case ast.Subscript(): - subscript_start = normalize(expr.value.end_col_offset) - subscript_end = normalize(expr.slice.end_col_offset + 1) - return _Anchors(subscript_start, subscript_end) - - return None - - -class _ExceptionPrintContext: - def __init__(self): - self.seen = set() - self.exception_group_depth = 0 - self.need_close = False - - def indent(self): - return ' ' * (2 * self.exception_group_depth) - - def emit(self, text_gen, margin_char=None): - if margin_char is None: - margin_char = '|' - indent_str = self.indent() - if self.exception_group_depth: - indent_str += margin_char + ' ' - - if isinstance(text_gen, str): - yield textwrap.indent(text_gen, indent_str, lambda line: True) - else: - for text in text_gen: - yield textwrap.indent(text, indent_str, lambda line: True) - - -class TracebackException: - """An exception ready for rendering. - - The traceback module captures enough attributes from the original exception - to this intermediary form to ensure that no references are held, while - still being able to fully print or format it. - - max_group_width and max_group_depth control the formatting of exception - groups. The depth refers to the nesting level of the group, and the width - refers to the size of a single exception group's exceptions array. The - formatted output is truncated when either limit is exceeded. - - Use `from_exception` to create TracebackException instances from exception - objects, or the constructor to create TracebackException instances from - individual components. - - - :attr:`__cause__` A TracebackException of the original *__cause__*. - - :attr:`__context__` A TracebackException of the original *__context__*. - - :attr:`__suppress_context__` The *__suppress_context__* value from the - original exception. - - :attr:`stack` A `StackSummary` representing the traceback. - - :attr:`exc_type` The class of the original traceback. - - :attr:`filename` For syntax errors - the filename where the error - occurred. - - :attr:`lineno` For syntax errors - the linenumber where the error - occurred. - - :attr:`end_lineno` For syntax errors - the end linenumber where the error - occurred. Can be `None` if not present. - - :attr:`text` For syntax errors - the text where the error - occurred. - - :attr:`offset` For syntax errors - the offset into the text where the - error occurred. - - :attr:`end_offset` For syntax errors - the offset into the text where the - error occurred. Can be `None` if not present. - - :attr:`msg` For syntax errors - the compiler error message. - """ - - def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, - lookup_lines=True, capture_locals=False, compact=False, - max_group_width=15, max_group_depth=10, _seen=None): - # NB: we need to accept exc_traceback, exc_value, exc_traceback to - # permit backwards compat with the existing API, otherwise we - # need stub thunk objects just to glue it together. - # Handle loops in __cause__ or __context__. - is_recursive_call = _seen is not None - if _seen is None: - _seen = set() - _seen.add(id(exc_value)) - - self.max_group_width = max_group_width - self.max_group_depth = max_group_depth - - self.stack = StackSummary._extract_from_extended_frame_gen( - _walk_tb_with_full_positions(exc_traceback), - limit=limit, lookup_lines=lookup_lines, - capture_locals=capture_locals) - self.exc_type = exc_type - # Capture now to permit freeing resources: only complication is in the - # unofficial API _format_final_exc_line - self._str = _safe_string(exc_value, 'exception') - self.__notes__ = getattr(exc_value, '__notes__', None) - - if exc_type and issubclass(exc_type, SyntaxError): - # Handle SyntaxError's specially - self.filename = exc_value.filename - lno = exc_value.lineno - self.lineno = str(lno) if lno is not None else None - end_lno = exc_value.end_lineno - self.end_lineno = str(end_lno) if end_lno is not None else None - self.text = exc_value.text - self.offset = exc_value.offset - self.end_offset = exc_value.end_offset - self.msg = exc_value.msg - if lookup_lines: - self._load_lines() - self.__suppress_context__ = \ - exc_value.__suppress_context__ if exc_value is not None else False - - # Convert __cause__ and __context__ to `TracebackExceptions`s, use a - # queue to avoid recursion (only the top-level call gets _seen == None) - if not is_recursive_call: - queue = [(self, exc_value)] - while queue: - te, e = queue.pop() - if (e and e.__cause__ is not None - and id(e.__cause__) not in _seen): - cause = TracebackException( - type(e.__cause__), - e.__cause__, - e.__cause__.__traceback__, - limit=limit, - lookup_lines=lookup_lines, - capture_locals=capture_locals, - max_group_width=max_group_width, - max_group_depth=max_group_depth, - _seen=_seen) - else: - cause = None - - if compact: - need_context = (cause is None and - e is not None and - not e.__suppress_context__) - else: - need_context = True - if (e and e.__context__ is not None - and need_context and id(e.__context__) not in _seen): - context = TracebackException( - type(e.__context__), - e.__context__, - e.__context__.__traceback__, - limit=limit, - lookup_lines=lookup_lines, - capture_locals=capture_locals, - max_group_width=max_group_width, - max_group_depth=max_group_depth, - _seen=_seen) - else: - context = None - - if e and isinstance(e, BaseExceptionGroup): - exceptions = [] - for exc in e.exceptions: - texc = TracebackException( - type(exc), - exc, - exc.__traceback__, - limit=limit, - lookup_lines=lookup_lines, - capture_locals=capture_locals, - max_group_width=max_group_width, - max_group_depth=max_group_depth, - _seen=_seen) - exceptions.append(texc) - else: - exceptions = None - - te.__cause__ = cause - te.__context__ = context - te.exceptions = exceptions - if cause: - queue.append((te.__cause__, e.__cause__)) - if context: - queue.append((te.__context__, e.__context__)) - if exceptions: - queue.extend(zip(te.exceptions, e.exceptions)) - - @classmethod - def from_exception(cls, exc, *args, **kwargs): - """Create a TracebackException from an exception.""" - return cls(type(exc), exc, exc.__traceback__, *args, **kwargs) - - def _load_lines(self): - """Private API. force all lines in the stack to be loaded.""" - for frame in self.stack: - frame.line - - def __eq__(self, other): - if isinstance(other, TracebackException): - return self.__dict__ == other.__dict__ - return NotImplemented - - def __str__(self): - return self._str - - def format_exception_only(self): - """Format the exception part of the traceback. - - The return value is a generator of strings, each ending in a newline. - - Normally, the generator emits a single string; however, for - SyntaxError exceptions, it emits several lines that (when - printed) display detailed information about where the syntax - error occurred. - - The message indicating which exception occurred is always the last - string in the output. - """ - if self.exc_type is None: - yield _format_final_exc_line(None, self._str) - return - - stype = self.exc_type.__qualname__ - smod = self.exc_type.__module__ - if smod not in ("__main__", "builtins"): - if not isinstance(smod, str): - smod = "" - stype = smod + '.' + stype - - if not issubclass(self.exc_type, SyntaxError): - yield _format_final_exc_line(stype, self._str) - else: - yield from self._format_syntax_error(stype) - if isinstance(self.__notes__, collections.abc.Sequence): - for note in self.__notes__: - note = _safe_string(note, 'note') - yield from [l + '\n' for l in note.split('\n')] - elif self.__notes__ is not None: - yield _safe_string(self.__notes__, '__notes__', func=repr) - - def _format_syntax_error(self, stype): - """Format SyntaxError exceptions (internal helper).""" - # Show exactly where the problem was found. - filename_suffix = '' - if self.lineno is not None: - yield ' File "{}", line {}\n'.format( - self.filename or "", self.lineno) - elif self.filename is not None: - filename_suffix = ' ({})'.format(self.filename) - - text = self.text - if text is not None: - # text = " foo\n" - # rtext = " foo" - # ltext = "foo" - rtext = text.rstrip('\n') - ltext = rtext.lstrip(' \n\f') - spaces = len(rtext) - len(ltext) - yield ' {}\n'.format(ltext) - - if self.offset is not None: - offset = self.offset - end_offset = self.end_offset if self.end_offset not in {None, 0} else offset - if offset == end_offset or end_offset == -1: - end_offset = offset + 1 - - # Convert 1-based column offset to 0-based index into stripped text - colno = offset - 1 - spaces - end_colno = end_offset - 1 - spaces - if colno >= 0: - # non-space whitespace (likes tabs) must be kept for alignment - caretspace = ((c if c.isspace() else ' ') for c in ltext[:colno]) - yield ' {}{}'.format("".join(caretspace), ('^' * (end_colno - colno) + "\n")) - msg = self.msg or "" - yield "{}: {}{}\n".format(stype, msg, filename_suffix) - - def format(self, *, chain=True, _ctx=None): - """Format the exception. - - If chain is not *True*, *__cause__* and *__context__* will not be formatted. - - The return value is a generator of strings, each ending in a newline and - some containing internal newlines. `print_exception` is a wrapper around - this method which just prints the lines to a file. - - The message indicating which exception occurred is always the last - string in the output. - """ - - if _ctx is None: - _ctx = _ExceptionPrintContext() - - output = [] - exc = self - if chain: - while exc: - if exc.__cause__ is not None: - chained_msg = _cause_message - chained_exc = exc.__cause__ - elif (exc.__context__ is not None and - not exc.__suppress_context__): - chained_msg = _context_message - chained_exc = exc.__context__ - else: - chained_msg = None - chained_exc = None - - output.append((chained_msg, exc)) - exc = chained_exc - else: - output.append((None, exc)) - - for msg, exc in reversed(output): - if msg is not None: - yield from _ctx.emit(msg) - if exc.exceptions is None: - if exc.stack: - yield from _ctx.emit('Traceback (most recent call last):\n') - yield from _ctx.emit(exc.stack.format()) - yield from _ctx.emit(exc.format_exception_only()) - elif _ctx.exception_group_depth > self.max_group_depth: - # exception group, but depth exceeds limit - yield from _ctx.emit( - f"... (max_group_depth is {self.max_group_depth})\n") - else: - # format exception group - is_toplevel = (_ctx.exception_group_depth == 0) - if is_toplevel: - _ctx.exception_group_depth += 1 - - if exc.stack: - yield from _ctx.emit( - 'Exception Group Traceback (most recent call last):\n', - margin_char = '+' if is_toplevel else None) - yield from _ctx.emit(exc.stack.format()) - - yield from _ctx.emit(exc.format_exception_only()) - num_excs = len(exc.exceptions) - if num_excs <= self.max_group_width: - n = num_excs - else: - n = self.max_group_width + 1 - _ctx.need_close = False - for i in range(n): - last_exc = (i == n-1) - if last_exc: - # The closing frame may be added by a recursive call - _ctx.need_close = True - - if self.max_group_width is not None: - truncated = (i >= self.max_group_width) - else: - truncated = False - title = f'{i+1}' if not truncated else '...' - yield (_ctx.indent() + - ('+-' if i==0 else ' ') + - f'+---------------- {title} ----------------\n') - _ctx.exception_group_depth += 1 - if not truncated: - yield from exc.exceptions[i].format(chain=chain, _ctx=_ctx) - else: - remaining = num_excs - self.max_group_width - plural = 's' if remaining > 1 else '' - yield from _ctx.emit( - f"and {remaining} more exception{plural}\n") - - if last_exc and _ctx.need_close: - yield (_ctx.indent() + - "+------------------------------------\n") - _ctx.need_close = False - _ctx.exception_group_depth -= 1 - - if is_toplevel: - assert _ctx.exception_group_depth == 1 - _ctx.exception_group_depth = 0 - - - def print(self, *, file=None, chain=True): - """Print the result of self.format(chain=chain) to 'file'.""" - if file is None: - file = sys.stderr - for line in self.format(chain=chain): - print(line, file=file, end="") diff --git a/python/Lib/tracemalloc.py b/python/Lib/tracemalloc.py deleted file mode 100644 index 8224ef8..0000000 --- a/python/Lib/tracemalloc.py +++ /dev/null @@ -1,560 +0,0 @@ -from collections.abc import Sequence, Iterable -from functools import total_ordering -import fnmatch -import linecache -import os.path -import pickle - -# Import types and functions implemented in C -from _tracemalloc import * -from _tracemalloc import _get_object_traceback, _get_traces - - -def _format_size(size, sign): - for unit in ('B', 'KiB', 'MiB', 'GiB', 'TiB'): - if abs(size) < 100 and unit != 'B': - # 3 digits (xx.x UNIT) - if sign: - return "%+.1f %s" % (size, unit) - else: - return "%.1f %s" % (size, unit) - if abs(size) < 10 * 1024 or unit == 'TiB': - # 4 or 5 digits (xxxx UNIT) - if sign: - return "%+.0f %s" % (size, unit) - else: - return "%.0f %s" % (size, unit) - size /= 1024 - - -class Statistic: - """ - Statistic difference on memory allocations between two Snapshot instance. - """ - - __slots__ = ('traceback', 'size', 'count') - - def __init__(self, traceback, size, count): - self.traceback = traceback - self.size = size - self.count = count - - def __hash__(self): - return hash((self.traceback, self.size, self.count)) - - def __eq__(self, other): - if not isinstance(other, Statistic): - return NotImplemented - return (self.traceback == other.traceback - and self.size == other.size - and self.count == other.count) - - def __str__(self): - text = ("%s: size=%s, count=%i" - % (self.traceback, - _format_size(self.size, False), - self.count)) - if self.count: - average = self.size / self.count - text += ", average=%s" % _format_size(average, False) - return text - - def __repr__(self): - return ('' - % (self.traceback, self.size, self.count)) - - def _sort_key(self): - return (self.size, self.count, self.traceback) - - -class StatisticDiff: - """ - Statistic difference on memory allocations between an old and a new - Snapshot instance. - """ - __slots__ = ('traceback', 'size', 'size_diff', 'count', 'count_diff') - - def __init__(self, traceback, size, size_diff, count, count_diff): - self.traceback = traceback - self.size = size - self.size_diff = size_diff - self.count = count - self.count_diff = count_diff - - def __hash__(self): - return hash((self.traceback, self.size, self.size_diff, - self.count, self.count_diff)) - - def __eq__(self, other): - if not isinstance(other, StatisticDiff): - return NotImplemented - return (self.traceback == other.traceback - and self.size == other.size - and self.size_diff == other.size_diff - and self.count == other.count - and self.count_diff == other.count_diff) - - def __str__(self): - text = ("%s: size=%s (%s), count=%i (%+i)" - % (self.traceback, - _format_size(self.size, False), - _format_size(self.size_diff, True), - self.count, - self.count_diff)) - if self.count: - average = self.size / self.count - text += ", average=%s" % _format_size(average, False) - return text - - def __repr__(self): - return ('' - % (self.traceback, self.size, self.size_diff, - self.count, self.count_diff)) - - def _sort_key(self): - return (abs(self.size_diff), self.size, - abs(self.count_diff), self.count, - self.traceback) - - -def _compare_grouped_stats(old_group, new_group): - statistics = [] - for traceback, stat in new_group.items(): - previous = old_group.pop(traceback, None) - if previous is not None: - stat = StatisticDiff(traceback, - stat.size, stat.size - previous.size, - stat.count, stat.count - previous.count) - else: - stat = StatisticDiff(traceback, - stat.size, stat.size, - stat.count, stat.count) - statistics.append(stat) - - for traceback, stat in old_group.items(): - stat = StatisticDiff(traceback, 0, -stat.size, 0, -stat.count) - statistics.append(stat) - return statistics - - -@total_ordering -class Frame: - """ - Frame of a traceback. - """ - __slots__ = ("_frame",) - - def __init__(self, frame): - # frame is a tuple: (filename: str, lineno: int) - self._frame = frame - - @property - def filename(self): - return self._frame[0] - - @property - def lineno(self): - return self._frame[1] - - def __eq__(self, other): - if not isinstance(other, Frame): - return NotImplemented - return (self._frame == other._frame) - - def __lt__(self, other): - if not isinstance(other, Frame): - return NotImplemented - return (self._frame < other._frame) - - def __hash__(self): - return hash(self._frame) - - def __str__(self): - return "%s:%s" % (self.filename, self.lineno) - - def __repr__(self): - return "" % (self.filename, self.lineno) - - -@total_ordering -class Traceback(Sequence): - """ - Sequence of Frame instances sorted from the oldest frame - to the most recent frame. - """ - __slots__ = ("_frames", '_total_nframe') - - def __init__(self, frames, total_nframe=None): - Sequence.__init__(self) - # frames is a tuple of frame tuples: see Frame constructor for the - # format of a frame tuple; it is reversed, because _tracemalloc - # returns frames sorted from most recent to oldest, but the - # Python API expects oldest to most recent - self._frames = tuple(reversed(frames)) - self._total_nframe = total_nframe - - @property - def total_nframe(self): - return self._total_nframe - - def __len__(self): - return len(self._frames) - - def __getitem__(self, index): - if isinstance(index, slice): - return tuple(Frame(trace) for trace in self._frames[index]) - else: - return Frame(self._frames[index]) - - def __contains__(self, frame): - return frame._frame in self._frames - - def __hash__(self): - return hash(self._frames) - - def __eq__(self, other): - if not isinstance(other, Traceback): - return NotImplemented - return (self._frames == other._frames) - - def __lt__(self, other): - if not isinstance(other, Traceback): - return NotImplemented - return (self._frames < other._frames) - - def __str__(self): - return str(self[0]) - - def __repr__(self): - s = f"" - return s - - def format(self, limit=None, most_recent_first=False): - lines = [] - if limit is not None: - if limit > 0: - frame_slice = self[-limit:] - else: - frame_slice = self[:limit] - else: - frame_slice = self - - if most_recent_first: - frame_slice = reversed(frame_slice) - for frame in frame_slice: - lines.append(' File "%s", line %s' - % (frame.filename, frame.lineno)) - line = linecache.getline(frame.filename, frame.lineno).strip() - if line: - lines.append(' %s' % line) - return lines - - -def get_object_traceback(obj): - """ - Get the traceback where the Python object *obj* was allocated. - Return a Traceback instance. - - Return None if the tracemalloc module is not tracing memory allocations or - did not trace the allocation of the object. - """ - frames = _get_object_traceback(obj) - if frames is not None: - return Traceback(frames) - else: - return None - - -class Trace: - """ - Trace of a memory block. - """ - __slots__ = ("_trace",) - - def __init__(self, trace): - # trace is a tuple: (domain: int, size: int, traceback: tuple). - # See Traceback constructor for the format of the traceback tuple. - self._trace = trace - - @property - def domain(self): - return self._trace[0] - - @property - def size(self): - return self._trace[1] - - @property - def traceback(self): - return Traceback(*self._trace[2:]) - - def __eq__(self, other): - if not isinstance(other, Trace): - return NotImplemented - return (self._trace == other._trace) - - def __hash__(self): - return hash(self._trace) - - def __str__(self): - return "%s: %s" % (self.traceback, _format_size(self.size, False)) - - def __repr__(self): - return ("" - % (self.domain, _format_size(self.size, False), self.traceback)) - - -class _Traces(Sequence): - def __init__(self, traces): - Sequence.__init__(self) - # traces is a tuple of trace tuples: see Trace constructor - self._traces = traces - - def __len__(self): - return len(self._traces) - - def __getitem__(self, index): - if isinstance(index, slice): - return tuple(Trace(trace) for trace in self._traces[index]) - else: - return Trace(self._traces[index]) - - def __contains__(self, trace): - return trace._trace in self._traces - - def __eq__(self, other): - if not isinstance(other, _Traces): - return NotImplemented - return (self._traces == other._traces) - - def __repr__(self): - return "" % len(self) - - -def _normalize_filename(filename): - filename = os.path.normcase(filename) - if filename.endswith('.pyc'): - filename = filename[:-1] - return filename - - -class BaseFilter: - def __init__(self, inclusive): - self.inclusive = inclusive - - def _match(self, trace): - raise NotImplementedError - - -class Filter(BaseFilter): - def __init__(self, inclusive, filename_pattern, - lineno=None, all_frames=False, domain=None): - super().__init__(inclusive) - self.inclusive = inclusive - self._filename_pattern = _normalize_filename(filename_pattern) - self.lineno = lineno - self.all_frames = all_frames - self.domain = domain - - @property - def filename_pattern(self): - return self._filename_pattern - - def _match_frame_impl(self, filename, lineno): - filename = _normalize_filename(filename) - if not fnmatch.fnmatch(filename, self._filename_pattern): - return False - if self.lineno is None: - return True - else: - return (lineno == self.lineno) - - def _match_frame(self, filename, lineno): - return self._match_frame_impl(filename, lineno) ^ (not self.inclusive) - - def _match_traceback(self, traceback): - if self.all_frames: - if any(self._match_frame_impl(filename, lineno) - for filename, lineno in traceback): - return self.inclusive - else: - return (not self.inclusive) - else: - filename, lineno = traceback[0] - return self._match_frame(filename, lineno) - - def _match(self, trace): - domain, size, traceback, total_nframe = trace - res = self._match_traceback(traceback) - if self.domain is not None: - if self.inclusive: - return res and (domain == self.domain) - else: - return res or (domain != self.domain) - return res - - -class DomainFilter(BaseFilter): - def __init__(self, inclusive, domain): - super().__init__(inclusive) - self._domain = domain - - @property - def domain(self): - return self._domain - - def _match(self, trace): - domain, size, traceback, total_nframe = trace - return (domain == self.domain) ^ (not self.inclusive) - - -class Snapshot: - """ - Snapshot of traces of memory blocks allocated by Python. - """ - - def __init__(self, traces, traceback_limit): - # traces is a tuple of trace tuples: see _Traces constructor for - # the exact format - self.traces = _Traces(traces) - self.traceback_limit = traceback_limit - - def dump(self, filename): - """ - Write the snapshot into a file. - """ - with open(filename, "wb") as fp: - pickle.dump(self, fp, pickle.HIGHEST_PROTOCOL) - - @staticmethod - def load(filename): - """ - Load a snapshot from a file. - """ - with open(filename, "rb") as fp: - return pickle.load(fp) - - def _filter_trace(self, include_filters, exclude_filters, trace): - if include_filters: - if not any(trace_filter._match(trace) - for trace_filter in include_filters): - return False - if exclude_filters: - if any(not trace_filter._match(trace) - for trace_filter in exclude_filters): - return False - return True - - def filter_traces(self, filters): - """ - Create a new Snapshot instance with a filtered traces sequence, filters - is a list of Filter or DomainFilter instances. If filters is an empty - list, return a new Snapshot instance with a copy of the traces. - """ - if not isinstance(filters, Iterable): - raise TypeError("filters must be a list of filters, not %s" - % type(filters).__name__) - if filters: - include_filters = [] - exclude_filters = [] - for trace_filter in filters: - if trace_filter.inclusive: - include_filters.append(trace_filter) - else: - exclude_filters.append(trace_filter) - new_traces = [trace for trace in self.traces._traces - if self._filter_trace(include_filters, - exclude_filters, - trace)] - else: - new_traces = self.traces._traces.copy() - return Snapshot(new_traces, self.traceback_limit) - - def _group_by(self, key_type, cumulative): - if key_type not in ('traceback', 'filename', 'lineno'): - raise ValueError("unknown key_type: %r" % (key_type,)) - if cumulative and key_type not in ('lineno', 'filename'): - raise ValueError("cumulative mode cannot by used " - "with key type %r" % key_type) - - stats = {} - tracebacks = {} - if not cumulative: - for trace in self.traces._traces: - domain, size, trace_traceback, total_nframe = trace - try: - traceback = tracebacks[trace_traceback] - except KeyError: - if key_type == 'traceback': - frames = trace_traceback - elif key_type == 'lineno': - frames = trace_traceback[:1] - else: # key_type == 'filename': - frames = ((trace_traceback[0][0], 0),) - traceback = Traceback(frames) - tracebacks[trace_traceback] = traceback - try: - stat = stats[traceback] - stat.size += size - stat.count += 1 - except KeyError: - stats[traceback] = Statistic(traceback, size, 1) - else: - # cumulative statistics - for trace in self.traces._traces: - domain, size, trace_traceback, total_nframe = trace - for frame in trace_traceback: - try: - traceback = tracebacks[frame] - except KeyError: - if key_type == 'lineno': - frames = (frame,) - else: # key_type == 'filename': - frames = ((frame[0], 0),) - traceback = Traceback(frames) - tracebacks[frame] = traceback - try: - stat = stats[traceback] - stat.size += size - stat.count += 1 - except KeyError: - stats[traceback] = Statistic(traceback, size, 1) - return stats - - def statistics(self, key_type, cumulative=False): - """ - Group statistics by key_type. Return a sorted list of Statistic - instances. - """ - grouped = self._group_by(key_type, cumulative) - statistics = list(grouped.values()) - statistics.sort(reverse=True, key=Statistic._sort_key) - return statistics - - def compare_to(self, old_snapshot, key_type, cumulative=False): - """ - Compute the differences with an old snapshot old_snapshot. Get - statistics as a sorted list of StatisticDiff instances, grouped by - group_by. - """ - new_group = self._group_by(key_type, cumulative) - old_group = old_snapshot._group_by(key_type, cumulative) - statistics = _compare_grouped_stats(old_group, new_group) - statistics.sort(reverse=True, key=StatisticDiff._sort_key) - return statistics - - -def take_snapshot(): - """ - Take a snapshot of traces of memory blocks allocated by Python. - """ - if not is_tracing(): - raise RuntimeError("the tracemalloc module must be tracing memory " - "allocations to take a snapshot") - traces = _get_traces() - traceback_limit = get_traceback_limit() - return Snapshot(traces, traceback_limit) diff --git a/python/Lib/types.py b/python/Lib/types.py deleted file mode 100644 index 63e2b31..0000000 --- a/python/Lib/types.py +++ /dev/null @@ -1,305 +0,0 @@ -""" -Define names for built-in types that aren't directly accessible as a builtin. -""" -import sys - -# Iterators in Python aren't a matter of type but of protocol. A large -# and changing number of builtin types implement *some* flavor of -# iterator. Don't check the type! Use hasattr to check for both -# "__iter__" and "__next__" attributes instead. - -def _f(): pass -FunctionType = type(_f) -LambdaType = type(lambda: None) # Same as FunctionType -CodeType = type(_f.__code__) -MappingProxyType = type(type.__dict__) -SimpleNamespace = type(sys.implementation) - -def _cell_factory(): - a = 1 - def f(): - nonlocal a - return f.__closure__[0] -CellType = type(_cell_factory()) - -def _g(): - yield 1 -GeneratorType = type(_g()) - -async def _c(): pass -_c = _c() -CoroutineType = type(_c) -_c.close() # Prevent ResourceWarning - -async def _ag(): - yield -_ag = _ag() -AsyncGeneratorType = type(_ag) - -class _C: - def _m(self): pass -MethodType = type(_C()._m) - -BuiltinFunctionType = type(len) -BuiltinMethodType = type([].append) # Same as BuiltinFunctionType - -WrapperDescriptorType = type(object.__init__) -MethodWrapperType = type(object().__str__) -MethodDescriptorType = type(str.join) -ClassMethodDescriptorType = type(dict.__dict__['fromkeys']) - -ModuleType = type(sys) - -try: - raise TypeError -except TypeError as exc: - TracebackType = type(exc.__traceback__) - FrameType = type(exc.__traceback__.tb_frame) - -# For Jython, the following two types are identical -GetSetDescriptorType = type(FunctionType.__code__) -MemberDescriptorType = type(FunctionType.__globals__) - -del sys, _f, _g, _C, _c, _ag # Not for export - - -# Provide a PEP 3115 compliant mechanism for class creation -def new_class(name, bases=(), kwds=None, exec_body=None): - """Create a class object dynamically using the appropriate metaclass.""" - resolved_bases = resolve_bases(bases) - meta, ns, kwds = prepare_class(name, resolved_bases, kwds) - if exec_body is not None: - exec_body(ns) - if resolved_bases is not bases: - ns['__orig_bases__'] = bases - return meta(name, resolved_bases, ns, **kwds) - -def resolve_bases(bases): - """Resolve MRO entries dynamically as specified by PEP 560.""" - new_bases = list(bases) - updated = False - shift = 0 - for i, base in enumerate(bases): - if isinstance(base, type): - continue - if not hasattr(base, "__mro_entries__"): - continue - new_base = base.__mro_entries__(bases) - updated = True - if not isinstance(new_base, tuple): - raise TypeError("__mro_entries__ must return a tuple") - else: - new_bases[i+shift:i+shift+1] = new_base - shift += len(new_base) - 1 - if not updated: - return bases - return tuple(new_bases) - -def prepare_class(name, bases=(), kwds=None): - """Call the __prepare__ method of the appropriate metaclass. - - Returns (metaclass, namespace, kwds) as a 3-tuple - - *metaclass* is the appropriate metaclass - *namespace* is the prepared class namespace - *kwds* is an updated copy of the passed in kwds argument with any - 'metaclass' entry removed. If no kwds argument is passed in, this will - be an empty dict. - """ - if kwds is None: - kwds = {} - else: - kwds = dict(kwds) # Don't alter the provided mapping - if 'metaclass' in kwds: - meta = kwds.pop('metaclass') - else: - if bases: - meta = type(bases[0]) - else: - meta = type - if isinstance(meta, type): - # when meta is a type, we first determine the most-derived metaclass - # instead of invoking the initial candidate directly - meta = _calculate_meta(meta, bases) - if hasattr(meta, '__prepare__'): - ns = meta.__prepare__(name, bases, **kwds) - else: - ns = {} - return meta, ns, kwds - -def _calculate_meta(meta, bases): - """Calculate the most derived metaclass.""" - winner = meta - for base in bases: - base_meta = type(base) - if issubclass(winner, base_meta): - continue - if issubclass(base_meta, winner): - winner = base_meta - continue - # else: - raise TypeError("metaclass conflict: " - "the metaclass of a derived class " - "must be a (non-strict) subclass " - "of the metaclasses of all its bases") - return winner - -class DynamicClassAttribute: - """Route attribute access on a class to __getattr__. - - This is a descriptor, used to define attributes that act differently when - accessed through an instance and through a class. Instance access remains - normal, but access to an attribute through a class will be routed to the - class's __getattr__ method; this is done by raising AttributeError. - - This allows one to have properties active on an instance, and have virtual - attributes on the class with the same name. (Enum used this between Python - versions 3.4 - 3.9 .) - - Subclass from this to use a different method of accessing virtual attributes - and still be treated properly by the inspect module. (Enum uses this since - Python 3.10 .) - - """ - def __init__(self, fget=None, fset=None, fdel=None, doc=None): - self.fget = fget - self.fset = fset - self.fdel = fdel - # next two lines make DynamicClassAttribute act the same as property - self.__doc__ = doc or fget.__doc__ - self.overwrite_doc = doc is None - # support for abstract methods - self.__isabstractmethod__ = bool(getattr(fget, '__isabstractmethod__', False)) - - def __get__(self, instance, ownerclass=None): - if instance is None: - if self.__isabstractmethod__: - return self - raise AttributeError() - elif self.fget is None: - raise AttributeError("unreadable attribute") - return self.fget(instance) - - def __set__(self, instance, value): - if self.fset is None: - raise AttributeError("can't set attribute") - self.fset(instance, value) - - def __delete__(self, instance): - if self.fdel is None: - raise AttributeError("can't delete attribute") - self.fdel(instance) - - def getter(self, fget): - fdoc = fget.__doc__ if self.overwrite_doc else None - result = type(self)(fget, self.fset, self.fdel, fdoc or self.__doc__) - result.overwrite_doc = self.overwrite_doc - return result - - def setter(self, fset): - result = type(self)(self.fget, fset, self.fdel, self.__doc__) - result.overwrite_doc = self.overwrite_doc - return result - - def deleter(self, fdel): - result = type(self)(self.fget, self.fset, fdel, self.__doc__) - result.overwrite_doc = self.overwrite_doc - return result - - -class _GeneratorWrapper: - # TODO: Implement this in C. - def __init__(self, gen): - self.__wrapped = gen - self.__isgen = gen.__class__ is GeneratorType - self.__name__ = getattr(gen, '__name__', None) - self.__qualname__ = getattr(gen, '__qualname__', None) - def send(self, val): - return self.__wrapped.send(val) - def throw(self, tp, *rest): - return self.__wrapped.throw(tp, *rest) - def close(self): - return self.__wrapped.close() - @property - def gi_code(self): - return self.__wrapped.gi_code - @property - def gi_frame(self): - return self.__wrapped.gi_frame - @property - def gi_running(self): - return self.__wrapped.gi_running - @property - def gi_yieldfrom(self): - return self.__wrapped.gi_yieldfrom - cr_code = gi_code - cr_frame = gi_frame - cr_running = gi_running - cr_await = gi_yieldfrom - def __next__(self): - return next(self.__wrapped) - def __iter__(self): - if self.__isgen: - return self.__wrapped - return self - __await__ = __iter__ - -def coroutine(func): - """Convert regular generator function to a coroutine.""" - - if not callable(func): - raise TypeError('types.coroutine() expects a callable') - - if (func.__class__ is FunctionType and - getattr(func, '__code__', None).__class__ is CodeType): - - co_flags = func.__code__.co_flags - - # Check if 'func' is a coroutine function. - # (0x180 == CO_COROUTINE | CO_ITERABLE_COROUTINE) - if co_flags & 0x180: - return func - - # Check if 'func' is a generator function. - # (0x20 == CO_GENERATOR) - if co_flags & 0x20: - # TODO: Implement this in C. - co = func.__code__ - # 0x100 == CO_ITERABLE_COROUTINE - func.__code__ = co.replace(co_flags=co.co_flags | 0x100) - return func - - # The following code is primarily to support functions that - # return generator-like objects (for instance generators - # compiled with Cython). - - # Delay functools and _collections_abc import for speeding up types import. - import functools - import _collections_abc - @functools.wraps(func) - def wrapped(*args, **kwargs): - coro = func(*args, **kwargs) - if (coro.__class__ is CoroutineType or - coro.__class__ is GeneratorType and coro.gi_code.co_flags & 0x100): - # 'coro' is a native coroutine object or an iterable coroutine - return coro - if (isinstance(coro, _collections_abc.Generator) and - not isinstance(coro, _collections_abc.Coroutine)): - # 'coro' is either a pure Python generator iterator, or it - # implements collections.abc.Generator (and does not implement - # collections.abc.Coroutine). - return _GeneratorWrapper(coro) - # 'coro' is either an instance of collections.abc.Coroutine or - # some other object -- pass it through. - return coro - - return wrapped - -GenericAlias = type(list[int]) -UnionType = type(int | str) - -EllipsisType = type(Ellipsis) -NoneType = type(None) -NotImplementedType = type(NotImplemented) - -__all__ = [n for n in globals() if n[:1] != '_'] diff --git a/python/Lib/typing.py b/python/Lib/typing.py deleted file mode 100644 index b1dcd4f..0000000 --- a/python/Lib/typing.py +++ /dev/null @@ -1,3416 +0,0 @@ -""" -The typing module: Support for gradual typing as defined by PEP 484. - -At large scale, the structure of the module is following: -* Imports and exports, all public names should be explicitly added to __all__. -* Internal helper functions: these should never be used in code outside this module. -* _SpecialForm and its instances (special forms): - Any, NoReturn, Never, ClassVar, Union, Optional, Concatenate, Unpack -* Classes whose instances can be type arguments in addition to types: - ForwardRef, TypeVar and ParamSpec -* The core of internal generics API: _GenericAlias and _VariadicGenericAlias, the latter is - currently only used by Tuple and Callable. All subscripted types like X[int], Union[int, str], - etc., are instances of either of these classes. -* The public counterpart of the generics API consists of two classes: Generic and Protocol. -* Public helper functions: get_type_hints, overload, cast, no_type_check, - no_type_check_decorator. -* Generic aliases for collections.abc ABCs and few additional protocols. -* Special types: NewType, NamedTuple, TypedDict. -* Wrapper submodules for re and io related types. -""" - -from abc import abstractmethod, ABCMeta -import collections -from collections import defaultdict -import collections.abc -import contextlib -import functools -import operator -import re as stdlib_re # Avoid confusion with the re we export. -import sys -import types -import warnings -from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType, GenericAlias - - -try: - from _typing import _idfunc -except ImportError: - def _idfunc(_, x): - return x - -# Please keep __all__ alphabetized within each category. -__all__ = [ - # Super-special typing primitives. - 'Annotated', - 'Any', - 'Callable', - 'ClassVar', - 'Concatenate', - 'Final', - 'ForwardRef', - 'Generic', - 'Literal', - 'Optional', - 'ParamSpec', - 'Protocol', - 'Tuple', - 'Type', - 'TypeVar', - 'TypeVarTuple', - 'Union', - - # ABCs (from collections.abc). - 'AbstractSet', # collections.abc.Set. - 'ByteString', - 'Container', - 'ContextManager', - 'Hashable', - 'ItemsView', - 'Iterable', - 'Iterator', - 'KeysView', - 'Mapping', - 'MappingView', - 'MutableMapping', - 'MutableSequence', - 'MutableSet', - 'Sequence', - 'Sized', - 'ValuesView', - 'Awaitable', - 'AsyncIterator', - 'AsyncIterable', - 'Coroutine', - 'Collection', - 'AsyncGenerator', - 'AsyncContextManager', - - # Structural checks, a.k.a. protocols. - 'Reversible', - 'SupportsAbs', - 'SupportsBytes', - 'SupportsComplex', - 'SupportsFloat', - 'SupportsIndex', - 'SupportsInt', - 'SupportsRound', - - # Concrete collection types. - 'ChainMap', - 'Counter', - 'Deque', - 'Dict', - 'DefaultDict', - 'List', - 'OrderedDict', - 'Set', - 'FrozenSet', - 'NamedTuple', # Not really a type. - 'TypedDict', # Not really a type. - 'Generator', - - # Other concrete types. - 'BinaryIO', - 'IO', - 'Match', - 'Pattern', - 'TextIO', - - # One-off things. - 'AnyStr', - 'assert_type', - 'assert_never', - 'cast', - 'clear_overloads', - 'dataclass_transform', - 'final', - 'get_args', - 'get_origin', - 'get_overloads', - 'get_type_hints', - 'is_typeddict', - 'LiteralString', - 'Never', - 'NewType', - 'no_type_check', - 'no_type_check_decorator', - 'NoReturn', - 'NotRequired', - 'overload', - 'ParamSpecArgs', - 'ParamSpecKwargs', - 'Required', - 'reveal_type', - 'runtime_checkable', - 'Self', - 'Text', - 'TYPE_CHECKING', - 'TypeAlias', - 'TypeGuard', - 'Unpack', -] - -# The pseudo-submodules 're' and 'io' are part of the public -# namespace, but excluded from __all__ because they might stomp on -# legitimate imports of those modules. - - -def _type_convert(arg, module=None, *, allow_special_forms=False): - """For converting None to type(None), and strings to ForwardRef.""" - if arg is None: - return type(None) - if isinstance(arg, str): - return ForwardRef(arg, module=module, is_class=allow_special_forms) - return arg - - -def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms=False): - """Check that the argument is a type, and return it (internal helper). - - As a special case, accept None and return type(None) instead. Also wrap strings - into ForwardRef instances. Consider several corner cases, for example plain - special forms like Union are not valid, while Union[int, str] is OK, etc. - The msg argument is a human-readable error message, e.g:: - - "Union[arg, ...]: arg should be a type." - - We append the repr() of the actual value (truncated to 100 chars). - """ - invalid_generic_forms = (Generic, Protocol) - if not allow_special_forms: - invalid_generic_forms += (ClassVar,) - if is_argument: - invalid_generic_forms += (Final,) - - arg = _type_convert(arg, module=module, allow_special_forms=allow_special_forms) - if (isinstance(arg, _GenericAlias) and - arg.__origin__ in invalid_generic_forms): - raise TypeError(f"{arg} is not valid as type argument") - if arg in (Any, LiteralString, NoReturn, Never, Self, TypeAlias): - return arg - if allow_special_forms and arg in (ClassVar, Final): - return arg - if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol): - raise TypeError(f"Plain {arg} is not valid as type argument") - if type(arg) is tuple: - raise TypeError(f"{msg} Got {arg!r:.100}.") - return arg - - -def _is_param_expr(arg): - return arg is ... or isinstance(arg, - (tuple, list, ParamSpec, _ConcatenateGenericAlias)) - - -def _should_unflatten_callable_args(typ, args): - """Internal helper for munging collections.abc.Callable's __args__. - - The canonical representation for a Callable's __args__ flattens the - argument types, see https://bugs.python.org/issue42195. For example: - - collections.abc.Callable[[int, int], str].__args__ == (int, int, str) - collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str) - - As a result, if we need to reconstruct the Callable from its __args__, - we need to unflatten it. - """ - return ( - typ.__origin__ is collections.abc.Callable - and not (len(args) == 2 and _is_param_expr(args[0])) - ) - - -def _type_repr(obj): - """Return the repr() of an object, special-casing types (internal helper). - - If obj is a type, we return a shorter version than the default - type.__repr__, based on the module and qualified name, which is - typically enough to uniquely identify a type. For everything - else, we fall back on repr(obj). - """ - if isinstance(obj, types.GenericAlias): - return repr(obj) - if isinstance(obj, type): - if obj.__module__ == 'builtins': - return obj.__qualname__ - return f'{obj.__module__}.{obj.__qualname__}' - if obj is ...: - return('...') - if isinstance(obj, types.FunctionType): - return obj.__name__ - return repr(obj) - - -def _collect_parameters(args): - """Collect all type variables and parameter specifications in args - in order of first appearance (lexicographic order). For example:: - - _collect_parameters((T, Callable[P, T])) == (T, P) - """ - parameters = [] - for t in args: - # We don't want __parameters__ descriptor of a bare Python class. - if isinstance(t, type): - continue - if hasattr(t, '__typing_subst__'): - if t not in parameters: - parameters.append(t) - else: - for x in getattr(t, '__parameters__', ()): - if x not in parameters: - parameters.append(x) - return tuple(parameters) - - -def _check_generic(cls, parameters, elen): - """Check correct count for parameters of a generic cls (internal helper). - This gives a nice error message in case of count mismatch. - """ - if not elen: - raise TypeError(f"{cls} is not a generic class") - alen = len(parameters) - if alen != elen: - raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments for {cls};" - f" actual {alen}, expected {elen}") - -def _unpack_args(args): - newargs = [] - for arg in args: - subargs = getattr(arg, '__typing_unpacked_tuple_args__', None) - if subargs is not None and not (subargs and subargs[-1] is ...): - newargs.extend(subargs) - else: - newargs.append(arg) - return newargs - -def _deduplicate(params): - # Weed out strict duplicates, preserving the first of each occurrence. - all_params = set(params) - if len(all_params) < len(params): - new_params = [] - for t in params: - if t in all_params: - new_params.append(t) - all_params.remove(t) - params = new_params - assert not all_params, all_params - return params - - -def _remove_dups_flatten(parameters): - """An internal helper for Union creation and substitution: flatten Unions - among parameters, then remove duplicates. - """ - # Flatten out Union[Union[...], ...]. - params = [] - for p in parameters: - if isinstance(p, (_UnionGenericAlias, types.UnionType)): - params.extend(p.__args__) - else: - params.append(p) - - return tuple(_deduplicate(params)) - - -def _flatten_literal_params(parameters): - """An internal helper for Literal creation: flatten Literals among parameters""" - params = [] - for p in parameters: - if isinstance(p, _LiteralGenericAlias): - params.extend(p.__args__) - else: - params.append(p) - return tuple(params) - - -_cleanups = [] - - -def _tp_cache(func=None, /, *, typed=False): - """Internal wrapper caching __getitem__ of generic types with a fallback to - original function for non-hashable arguments. - """ - def decorator(func): - cached = functools.lru_cache(typed=typed)(func) - _cleanups.append(cached.cache_clear) - - @functools.wraps(func) - def inner(*args, **kwds): - try: - return cached(*args, **kwds) - except TypeError: - pass # All real errors (not unhashable args) are raised below. - return func(*args, **kwds) - return inner - - if func is not None: - return decorator(func) - - return decorator - -def _eval_type(t, globalns, localns, recursive_guard=frozenset()): - """Evaluate all forward references in the given type t. - For use of globalns and localns see the docstring for get_type_hints(). - recursive_guard is used to prevent infinite recursion with a recursive - ForwardRef. - """ - if isinstance(t, ForwardRef): - return t._evaluate(globalns, localns, recursive_guard) - if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)): - if isinstance(t, GenericAlias): - args = tuple( - ForwardRef(arg) if isinstance(arg, str) else arg - for arg in t.__args__ - ) - if _should_unflatten_callable_args(t, args): - t = t.__origin__[(args[:-1], args[-1])] - else: - t = t.__origin__[args] - ev_args = tuple(_eval_type(a, globalns, localns, recursive_guard) for a in t.__args__) - if ev_args == t.__args__: - return t - if isinstance(t, GenericAlias): - return GenericAlias(t.__origin__, ev_args) - if isinstance(t, types.UnionType): - return functools.reduce(operator.or_, ev_args) - else: - return t.copy_with(ev_args) - return t - - -class _Final: - """Mixin to prohibit subclassing""" - - __slots__ = ('__weakref__',) - - def __init_subclass__(cls, /, *args, **kwds): - if '_root' not in kwds: - raise TypeError("Cannot subclass special typing classes") - -class _Immutable: - """Mixin to indicate that object should not be copied.""" - __slots__ = () - - def __copy__(self): - return self - - def __deepcopy__(self, memo): - return self - - -class _NotIterable: - """Mixin to prevent iteration, without being compatible with Iterable. - - That is, we could do: - def __iter__(self): raise TypeError() - But this would make users of this mixin duck type-compatible with - collections.abc.Iterable - isinstance(foo, Iterable) would be True. - - Luckily, we can instead prevent iteration by setting __iter__ to None, which - is treated specially. - """ - - __slots__ = () - __iter__ = None - - -# Internal indicator of special typing constructs. -# See __doc__ instance attribute for specific docs. -class _SpecialForm(_Final, _NotIterable, _root=True): - __slots__ = ('_name', '__doc__', '_getitem') - - def __init__(self, getitem): - self._getitem = getitem - self._name = getitem.__name__ - self.__doc__ = getitem.__doc__ - - def __getattr__(self, item): - if item in {'__name__', '__qualname__'}: - return self._name - - raise AttributeError(item) - - def __mro_entries__(self, bases): - raise TypeError(f"Cannot subclass {self!r}") - - def __repr__(self): - return 'typing.' + self._name - - def __reduce__(self): - return self._name - - def __call__(self, *args, **kwds): - raise TypeError(f"Cannot instantiate {self!r}") - - def __or__(self, other): - return Union[self, other] - - def __ror__(self, other): - return Union[other, self] - - def __instancecheck__(self, obj): - raise TypeError(f"{self} cannot be used with isinstance()") - - def __subclasscheck__(self, cls): - raise TypeError(f"{self} cannot be used with issubclass()") - - @_tp_cache - def __getitem__(self, parameters): - return self._getitem(self, parameters) - - -class _LiteralSpecialForm(_SpecialForm, _root=True): - def __getitem__(self, parameters): - if not isinstance(parameters, tuple): - parameters = (parameters,) - return self._getitem(self, *parameters) - - -class _AnyMeta(type): - def __instancecheck__(self, obj): - if self is Any: - raise TypeError("typing.Any cannot be used with isinstance()") - return super().__instancecheck__(obj) - - def __repr__(self): - if self is Any: - return "typing.Any" - return super().__repr__() # respect to subclasses - - -class Any(metaclass=_AnyMeta): - """Special type indicating an unconstrained type. - - - Any is compatible with every type. - - Any assumed to have all methods. - - All values assumed to be instances of Any. - - Note that all the above statements are true from the point of view of - static type checkers. At runtime, Any should not be used with instance - checks. - """ - def __new__(cls, *args, **kwargs): - if cls is Any: - raise TypeError("Any cannot be instantiated") - return super().__new__(cls, *args, **kwargs) - - -@_SpecialForm -def NoReturn(self, parameters): - """Special type indicating functions that never return. - Example:: - - from typing import NoReturn - - def stop() -> NoReturn: - raise Exception('no way') - - NoReturn can also be used as a bottom type, a type that - has no values. Starting in Python 3.11, the Never type should - be used for this concept instead. Type checkers should treat the two - equivalently. - - """ - raise TypeError(f"{self} is not subscriptable") - -# This is semantically identical to NoReturn, but it is implemented -# separately so that type checkers can distinguish between the two -# if they want. -@_SpecialForm -def Never(self, parameters): - """The bottom type, a type that has no members. - - This can be used to define a function that should never be - called, or a function that never returns:: - - from typing import Never - - def never_call_me(arg: Never) -> None: - pass - - def int_or_str(arg: int | str) -> None: - never_call_me(arg) # type checker error - match arg: - case int(): - print("It's an int") - case str(): - print("It's a str") - case _: - never_call_me(arg) # ok, arg is of type Never - - """ - raise TypeError(f"{self} is not subscriptable") - - -@_SpecialForm -def Self(self, parameters): - """Used to spell the type of "self" in classes. - - Example:: - - from typing import Self - - class Foo: - def return_self(self) -> Self: - ... - return self - - This is especially useful for: - - classmethods that are used as alternative constructors - - annotating an `__enter__` method which returns self - """ - raise TypeError(f"{self} is not subscriptable") - - -@_SpecialForm -def LiteralString(self, parameters): - """Represents an arbitrary literal string. - - Example:: - - from typing import LiteralString - - def run_query(sql: LiteralString) -> ... - ... - - def caller(arbitrary_string: str, literal_string: LiteralString) -> None: - run_query("SELECT * FROM students") # ok - run_query(literal_string) # ok - run_query("SELECT * FROM " + literal_string) # ok - run_query(arbitrary_string) # type checker error - run_query( # type checker error - f"SELECT * FROM students WHERE name = {arbitrary_string}" - ) - - Only string literals and other LiteralStrings are compatible - with LiteralString. This provides a tool to help prevent - security issues such as SQL injection. - - """ - raise TypeError(f"{self} is not subscriptable") - - -@_SpecialForm -def ClassVar(self, parameters): - """Special type construct to mark class variables. - - An annotation wrapped in ClassVar indicates that a given - attribute is intended to be used as a class variable and - should not be set on instances of that class. Usage:: - - class Starship: - stats: ClassVar[Dict[str, int]] = {} # class variable - damage: int = 10 # instance variable - - ClassVar accepts only types and cannot be further subscribed. - - Note that ClassVar is not a class itself, and should not - be used with isinstance() or issubclass(). - """ - item = _type_check(parameters, f'{self} accepts only single type.') - return _GenericAlias(self, (item,)) - -@_SpecialForm -def Final(self, parameters): - """Special typing construct to indicate final names to type checkers. - - A final name cannot be re-assigned or overridden in a subclass. - For example: - - MAX_SIZE: Final = 9000 - MAX_SIZE += 1 # Error reported by type checker - - class Connection: - TIMEOUT: Final[int] = 10 - - class FastConnector(Connection): - TIMEOUT = 1 # Error reported by type checker - - There is no runtime checking of these properties. - """ - item = _type_check(parameters, f'{self} accepts only single type.') - return _GenericAlias(self, (item,)) - -@_SpecialForm -def Union(self, parameters): - """Union type; Union[X, Y] means either X or Y. - - To define a union, use e.g. Union[int, str]. Details: - - The arguments must be types and there must be at least one. - - None as an argument is a special case and is replaced by - type(None). - - Unions of unions are flattened, e.g.:: - - Union[Union[int, str], float] == Union[int, str, float] - - - Unions of a single argument vanish, e.g.:: - - Union[int] == int # The constructor actually returns int - - - Redundant arguments are skipped, e.g.:: - - Union[int, str, int] == Union[int, str] - - - When comparing unions, the argument order is ignored, e.g.:: - - Union[int, str] == Union[str, int] - - - You cannot subclass or instantiate a union. - - You can use Optional[X] as a shorthand for Union[X, None]. - """ - if parameters == (): - raise TypeError("Cannot take a Union of no types.") - if not isinstance(parameters, tuple): - parameters = (parameters,) - msg = "Union[arg, ...]: each arg must be a type." - parameters = tuple(_type_check(p, msg) for p in parameters) - parameters = _remove_dups_flatten(parameters) - if len(parameters) == 1: - return parameters[0] - if len(parameters) == 2 and type(None) in parameters: - return _UnionGenericAlias(self, parameters, name="Optional") - return _UnionGenericAlias(self, parameters) - -@_SpecialForm -def Optional(self, parameters): - """Optional type. - - Optional[X] is equivalent to Union[X, None]. - """ - arg = _type_check(parameters, f"{self} requires a single type.") - return Union[arg, type(None)] - -@_LiteralSpecialForm -@_tp_cache(typed=True) -def Literal(self, *parameters): - """Special typing form to define literal types (a.k.a. value types). - - This form can be used to indicate to type checkers that the corresponding - variable or function parameter has a value equivalent to the provided - literal (or one of several literals): - - def validate_simple(data: Any) -> Literal[True]: # always returns True - ... - - MODE = Literal['r', 'rb', 'w', 'wb'] - def open_helper(file: str, mode: MODE) -> str: - ... - - open_helper('/some/path', 'r') # Passes type check - open_helper('/other/path', 'typo') # Error in type checker - - Literal[...] cannot be subclassed. At runtime, an arbitrary value - is allowed as type argument to Literal[...], but type checkers may - impose restrictions. - """ - # There is no '_type_check' call because arguments to Literal[...] are - # values, not types. - parameters = _flatten_literal_params(parameters) - - try: - parameters = tuple(p for p, _ in _deduplicate(list(_value_and_type_iter(parameters)))) - except TypeError: # unhashable parameters - pass - - return _LiteralGenericAlias(self, parameters) - - -@_SpecialForm -def TypeAlias(self, parameters): - """Special marker indicating that an assignment should - be recognized as a proper type alias definition by type - checkers. - - For example:: - - Predicate: TypeAlias = Callable[..., bool] - - It's invalid when used anywhere except as in the example above. - """ - raise TypeError(f"{self} is not subscriptable") - - -@_SpecialForm -def Concatenate(self, parameters): - """Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a - higher order function which adds, removes or transforms parameters of a - callable. - - For example:: - - Callable[Concatenate[int, P], int] - - See PEP 612 for detailed information. - """ - if parameters == (): - raise TypeError("Cannot take a Concatenate of no types.") - if not isinstance(parameters, tuple): - parameters = (parameters,) - if not (parameters[-1] is ... or isinstance(parameters[-1], ParamSpec)): - raise TypeError("The last parameter to Concatenate should be a " - "ParamSpec variable or ellipsis.") - msg = "Concatenate[arg, ...]: each arg must be a type." - parameters = (*(_type_check(p, msg) for p in parameters[:-1]), parameters[-1]) - return _ConcatenateGenericAlias(self, parameters, - _paramspec_tvars=True) - - -@_SpecialForm -def TypeGuard(self, parameters): - """Special typing form used to annotate the return type of a user-defined - type guard function. ``TypeGuard`` only accepts a single type argument. - At runtime, functions marked this way should return a boolean. - - ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static - type checkers to determine a more precise type of an expression within a - program's code flow. Usually type narrowing is done by analyzing - conditional code flow and applying the narrowing to a block of code. The - conditional expression here is sometimes referred to as a "type guard". - - Sometimes it would be convenient to use a user-defined boolean function - as a type guard. Such a function should use ``TypeGuard[...]`` as its - return type to alert static type checkers to this intention. - - Using ``-> TypeGuard`` tells the static type checker that for a given - function: - - 1. The return value is a boolean. - 2. If the return value is ``True``, the type of its argument - is the type inside ``TypeGuard``. - - For example:: - - def is_str(val: Union[str, float]): - # "isinstance" type guard - if isinstance(val, str): - # Type of ``val`` is narrowed to ``str`` - ... - else: - # Else, type of ``val`` is narrowed to ``float``. - ... - - Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower - form of ``TypeA`` (it can even be a wider form) and this may lead to - type-unsafe results. The main reason is to allow for things like - narrowing ``List[object]`` to ``List[str]`` even though the latter is not - a subtype of the former, since ``List`` is invariant. The responsibility of - writing type-safe type guards is left to the user. - - ``TypeGuard`` also works with type variables. For more information, see - PEP 647 (User-Defined Type Guards). - """ - item = _type_check(parameters, f'{self} accepts only single type.') - return _GenericAlias(self, (item,)) - - -class ForwardRef(_Final, _root=True): - """Internal wrapper to hold a forward reference.""" - - __slots__ = ('__forward_arg__', '__forward_code__', - '__forward_evaluated__', '__forward_value__', - '__forward_is_argument__', '__forward_is_class__', - '__forward_module__') - - def __init__(self, arg, is_argument=True, module=None, *, is_class=False): - if not isinstance(arg, str): - raise TypeError(f"Forward reference must be a string -- got {arg!r}") - - # If we do `def f(*args: *Ts)`, then we'll have `arg = '*Ts'`. - # Unfortunately, this isn't a valid expression on its own, so we - # do the unpacking manually. - if arg[0] == '*': - arg_to_compile = f'({arg},)[0]' # E.g. (*Ts,)[0] - else: - arg_to_compile = arg - try: - code = compile(arg_to_compile, '', 'eval') - except SyntaxError: - raise SyntaxError(f"Forward reference must be an expression -- got {arg!r}") - - self.__forward_arg__ = arg - self.__forward_code__ = code - self.__forward_evaluated__ = False - self.__forward_value__ = None - self.__forward_is_argument__ = is_argument - self.__forward_is_class__ = is_class - self.__forward_module__ = module - - def _evaluate(self, globalns, localns, recursive_guard): - if self.__forward_arg__ in recursive_guard: - return self - if not self.__forward_evaluated__ or localns is not globalns: - if globalns is None and localns is None: - globalns = localns = {} - elif globalns is None: - globalns = localns - elif localns is None: - localns = globalns - if self.__forward_module__ is not None: - globalns = getattr( - sys.modules.get(self.__forward_module__, None), '__dict__', globalns - ) - type_ = _type_check( - eval(self.__forward_code__, globalns, localns), - "Forward references must evaluate to types.", - is_argument=self.__forward_is_argument__, - allow_special_forms=self.__forward_is_class__, - ) - self.__forward_value__ = _eval_type( - type_, globalns, localns, recursive_guard | {self.__forward_arg__} - ) - self.__forward_evaluated__ = True - return self.__forward_value__ - - def __eq__(self, other): - if not isinstance(other, ForwardRef): - return NotImplemented - if self.__forward_evaluated__ and other.__forward_evaluated__: - return (self.__forward_arg__ == other.__forward_arg__ and - self.__forward_value__ == other.__forward_value__) - return (self.__forward_arg__ == other.__forward_arg__ and - self.__forward_module__ == other.__forward_module__) - - def __hash__(self): - return hash((self.__forward_arg__, self.__forward_module__)) - - def __or__(self, other): - return Union[self, other] - - def __ror__(self, other): - return Union[other, self] - - def __repr__(self): - if self.__forward_module__ is None: - module_repr = '' - else: - module_repr = f', module={self.__forward_module__!r}' - return f'ForwardRef({self.__forward_arg__!r}{module_repr})' - - -def _is_unpacked_typevartuple(x: Any) -> bool: - return ((not isinstance(x, type)) and - getattr(x, '__typing_is_unpacked_typevartuple__', False)) - - -def _is_typevar_like(x: Any) -> bool: - return isinstance(x, (TypeVar, ParamSpec)) or _is_unpacked_typevartuple(x) - - -class _PickleUsingNameMixin: - """Mixin enabling pickling based on self.__name__.""" - - def __reduce__(self): - return self.__name__ - - -class _BoundVarianceMixin: - """Mixin giving __init__ bound and variance arguments. - - This is used by TypeVar and ParamSpec, which both employ the notions of - a type 'bound' (restricting type arguments to be a subtype of some - specified type) and type 'variance' (determining subtype relations between - generic types). - """ - def __init__(self, bound, covariant, contravariant): - """Used to setup TypeVars and ParamSpec's bound, covariant and - contravariant attributes. - """ - if covariant and contravariant: - raise ValueError("Bivariant types are not supported.") - self.__covariant__ = bool(covariant) - self.__contravariant__ = bool(contravariant) - if bound: - self.__bound__ = _type_check(bound, "Bound must be a type.") - else: - self.__bound__ = None - - def __or__(self, right): - return Union[self, right] - - def __ror__(self, left): - return Union[left, self] - - def __repr__(self): - if self.__covariant__: - prefix = '+' - elif self.__contravariant__: - prefix = '-' - else: - prefix = '~' - return prefix + self.__name__ - - -class TypeVar(_Final, _Immutable, _BoundVarianceMixin, _PickleUsingNameMixin, - _root=True): - """Type variable. - - Usage:: - - T = TypeVar('T') # Can be anything - A = TypeVar('A', str, bytes) # Must be str or bytes - - Type variables exist primarily for the benefit of static type - checkers. They serve as the parameters for generic types as well - as for generic function definitions. See class Generic for more - information on generic types. Generic functions work as follows: - - def repeat(x: T, n: int) -> List[T]: - '''Return a list containing n references to x.''' - return [x]*n - - def longest(x: A, y: A) -> A: - '''Return the longest of two strings.''' - return x if len(x) >= len(y) else y - - The latter example's signature is essentially the overloading - of (str, str) -> str and (bytes, bytes) -> bytes. Also note - that if the arguments are instances of some subclass of str, - the return type is still plain str. - - At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError. - - Type variables defined with covariant=True or contravariant=True - can be used to declare covariant or contravariant generic types. - See PEP 484 for more details. By default generic types are invariant - in all type variables. - - Type variables can be introspected. e.g.: - - T.__name__ == 'T' - T.__constraints__ == () - T.__covariant__ == False - T.__contravariant__ = False - A.__constraints__ == (str, bytes) - - Note that only type variables defined in global scope can be pickled. - """ - - def __init__(self, name, *constraints, bound=None, - covariant=False, contravariant=False): - self.__name__ = name - super().__init__(bound, covariant, contravariant) - if constraints and bound is not None: - raise TypeError("Constraints cannot be combined with bound=...") - if constraints and len(constraints) == 1: - raise TypeError("A single constraint is not allowed") - msg = "TypeVar(name, constraint, ...): constraints must be types." - self.__constraints__ = tuple(_type_check(t, msg) for t in constraints) - def_mod = _caller() - if def_mod != 'typing': - self.__module__ = def_mod - - def __typing_subst__(self, arg): - msg = "Parameters to generic types must be types." - arg = _type_check(arg, msg, is_argument=True) - if ((isinstance(arg, _GenericAlias) and arg.__origin__ is Unpack) or - (isinstance(arg, GenericAlias) and getattr(arg, '__unpacked__', False))): - raise TypeError(f"{arg} is not valid as type argument") - return arg - - -class TypeVarTuple(_Final, _Immutable, _PickleUsingNameMixin, _root=True): - """Type variable tuple. - - Usage: - - Ts = TypeVarTuple('Ts') # Can be given any name - - Just as a TypeVar (type variable) is a placeholder for a single type, - a TypeVarTuple is a placeholder for an *arbitrary* number of types. For - example, if we define a generic class using a TypeVarTuple: - - class C(Generic[*Ts]): ... - - Then we can parameterize that class with an arbitrary number of type - arguments: - - C[int] # Fine - C[int, str] # Also fine - C[()] # Even this is fine - - For more details, see PEP 646. - - Note that only TypeVarTuples defined in global scope can be pickled. - """ - - def __init__(self, name): - self.__name__ = name - - # Used for pickling. - def_mod = _caller() - if def_mod != 'typing': - self.__module__ = def_mod - - def __iter__(self): - yield Unpack[self] - - def __repr__(self): - return self.__name__ - - def __typing_subst__(self, arg): - raise TypeError("Substitution of bare TypeVarTuple is not supported") - - def __typing_prepare_subst__(self, alias, args): - params = alias.__parameters__ - typevartuple_index = params.index(self) - for param in params[typevartuple_index + 1:]: - if isinstance(param, TypeVarTuple): - raise TypeError(f"More than one TypeVarTuple parameter in {alias}") - - alen = len(args) - plen = len(params) - left = typevartuple_index - right = plen - typevartuple_index - 1 - var_tuple_index = None - fillarg = None - for k, arg in enumerate(args): - if not isinstance(arg, type): - subargs = getattr(arg, '__typing_unpacked_tuple_args__', None) - if subargs and len(subargs) == 2 and subargs[-1] is ...: - if var_tuple_index is not None: - raise TypeError("More than one unpacked arbitrary-length tuple argument") - var_tuple_index = k - fillarg = subargs[0] - if var_tuple_index is not None: - left = min(left, var_tuple_index) - right = min(right, alen - var_tuple_index - 1) - elif left + right > alen: - raise TypeError(f"Too few arguments for {alias};" - f" actual {alen}, expected at least {plen-1}") - - return ( - *args[:left], - *([fillarg]*(typevartuple_index - left)), - tuple(args[left: alen - right]), - *([fillarg]*(plen - right - left - typevartuple_index - 1)), - *args[alen - right:], - ) - - -class ParamSpecArgs(_Final, _Immutable, _root=True): - """The args for a ParamSpec object. - - Given a ParamSpec object P, P.args is an instance of ParamSpecArgs. - - ParamSpecArgs objects have a reference back to their ParamSpec: - - P.args.__origin__ is P - - This type is meant for runtime introspection and has no special meaning to - static type checkers. - """ - def __init__(self, origin): - self.__origin__ = origin - - def __repr__(self): - return f"{self.__origin__.__name__}.args" - - def __eq__(self, other): - if not isinstance(other, ParamSpecArgs): - return NotImplemented - return self.__origin__ == other.__origin__ - - -class ParamSpecKwargs(_Final, _Immutable, _root=True): - """The kwargs for a ParamSpec object. - - Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs. - - ParamSpecKwargs objects have a reference back to their ParamSpec: - - P.kwargs.__origin__ is P - - This type is meant for runtime introspection and has no special meaning to - static type checkers. - """ - def __init__(self, origin): - self.__origin__ = origin - - def __repr__(self): - return f"{self.__origin__.__name__}.kwargs" - - def __eq__(self, other): - if not isinstance(other, ParamSpecKwargs): - return NotImplemented - return self.__origin__ == other.__origin__ - - -class ParamSpec(_Final, _Immutable, _BoundVarianceMixin, _PickleUsingNameMixin, - _root=True): - """Parameter specification variable. - - Usage:: - - P = ParamSpec('P') - - Parameter specification variables exist primarily for the benefit of static - type checkers. They are used to forward the parameter types of one - callable to another callable, a pattern commonly found in higher order - functions and decorators. They are only valid when used in ``Concatenate``, - or as the first argument to ``Callable``, or as parameters for user-defined - Generics. See class Generic for more information on generic types. An - example for annotating a decorator:: - - T = TypeVar('T') - P = ParamSpec('P') - - def add_logging(f: Callable[P, T]) -> Callable[P, T]: - '''A type-safe decorator to add logging to a function.''' - def inner(*args: P.args, **kwargs: P.kwargs) -> T: - logging.info(f'{f.__name__} was called') - return f(*args, **kwargs) - return inner - - @add_logging - def add_two(x: float, y: float) -> float: - '''Add two numbers together.''' - return x + y - - Parameter specification variables defined with covariant=True or - contravariant=True can be used to declare covariant or contravariant - generic types. These keyword arguments are valid, but their actual semantics - are yet to be decided. See PEP 612 for details. - - Parameter specification variables can be introspected. e.g.: - - P.__name__ == 'T' - P.__bound__ == None - P.__covariant__ == False - P.__contravariant__ == False - - Note that only parameter specification variables defined in global scope can - be pickled. - """ - - @property - def args(self): - return ParamSpecArgs(self) - - @property - def kwargs(self): - return ParamSpecKwargs(self) - - def __init__(self, name, *, bound=None, covariant=False, contravariant=False): - self.__name__ = name - super().__init__(bound, covariant, contravariant) - def_mod = _caller() - if def_mod != 'typing': - self.__module__ = def_mod - - def __typing_subst__(self, arg): - if isinstance(arg, (list, tuple)): - arg = tuple(_type_check(a, "Expected a type.") for a in arg) - elif not _is_param_expr(arg): - raise TypeError(f"Expected a list of types, an ellipsis, " - f"ParamSpec, or Concatenate. Got {arg}") - return arg - - def __typing_prepare_subst__(self, alias, args): - params = alias.__parameters__ - i = params.index(self) - if i >= len(args): - raise TypeError(f"Too few arguments for {alias}") - # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612. - if len(params) == 1 and not _is_param_expr(args[0]): - assert i == 0 - args = (args,) - # Convert lists to tuples to help other libraries cache the results. - elif isinstance(args[i], list): - args = (*args[:i], tuple(args[i]), *args[i+1:]) - return args - -def _is_dunder(attr): - return attr.startswith('__') and attr.endswith('__') - -class _BaseGenericAlias(_Final, _root=True): - """The central part of internal API. - - This represents a generic version of type 'origin' with type arguments 'params'. - There are two kind of these aliases: user defined and special. The special ones - are wrappers around builtin collections and ABCs in collections.abc. These must - have 'name' always set. If 'inst' is False, then the alias can't be instantiated, - this is used by e.g. typing.List and typing.Dict. - """ - def __init__(self, origin, *, inst=True, name=None): - self._inst = inst - self._name = name - self.__origin__ = origin - self.__slots__ = None # This is not documented. - - def __call__(self, *args, **kwargs): - if not self._inst: - raise TypeError(f"Type {self._name} cannot be instantiated; " - f"use {self.__origin__.__name__}() instead") - result = self.__origin__(*args, **kwargs) - try: - result.__orig_class__ = self - except AttributeError: - pass - return result - - def __mro_entries__(self, bases): - res = [] - if self.__origin__ not in bases: - res.append(self.__origin__) - i = bases.index(self) - for b in bases[i+1:]: - if isinstance(b, _BaseGenericAlias) or issubclass(b, Generic): - break - else: - res.append(Generic) - return tuple(res) - - def __getattr__(self, attr): - if attr in {'__name__', '__qualname__'}: - return self._name or self.__origin__.__name__ - - # We are careful for copy and pickle. - # Also for simplicity we don't relay any dunder names - if '__origin__' in self.__dict__ and not _is_dunder(attr): - return getattr(self.__origin__, attr) - raise AttributeError(attr) - - def __setattr__(self, attr, val): - if _is_dunder(attr) or attr in {'_name', '_inst', '_nparams', - '_paramspec_tvars'}: - super().__setattr__(attr, val) - else: - setattr(self.__origin__, attr, val) - - def __instancecheck__(self, obj): - return self.__subclasscheck__(type(obj)) - - def __subclasscheck__(self, cls): - raise TypeError("Subscripted generics cannot be used with" - " class and instance checks") - - def __dir__(self): - return list(set(super().__dir__() - + [attr for attr in dir(self.__origin__) if not _is_dunder(attr)])) - - -# Special typing constructs Union, Optional, Generic, Callable and Tuple -# use three special attributes for internal bookkeeping of generic types: -# * __parameters__ is a tuple of unique free type parameters of a generic -# type, for example, Dict[T, T].__parameters__ == (T,); -# * __origin__ keeps a reference to a type that was subscripted, -# e.g., Union[T, int].__origin__ == Union, or the non-generic version of -# the type. -# * __args__ is a tuple of all arguments used in subscripting, -# e.g., Dict[T, int].__args__ == (T, int). - - -class _GenericAlias(_BaseGenericAlias, _root=True): - # The type of parameterized generics. - # - # That is, for example, `type(List[int])` is `_GenericAlias`. - # - # Objects which are instances of this class include: - # * Parameterized container types, e.g. `Tuple[int]`, `List[int]`. - # * Note that native container types, e.g. `tuple`, `list`, use - # `types.GenericAlias` instead. - # * Parameterized classes: - # T = TypeVar('T') - # class C(Generic[T]): pass - # # C[int] is a _GenericAlias - # * `Callable` aliases, generic `Callable` aliases, and - # parameterized `Callable` aliases: - # T = TypeVar('T') - # # _CallableGenericAlias inherits from _GenericAlias. - # A = Callable[[], None] # _CallableGenericAlias - # B = Callable[[T], None] # _CallableGenericAlias - # C = B[int] # _CallableGenericAlias - # * Parameterized `Final`, `ClassVar` and `TypeGuard`: - # # All _GenericAlias - # Final[int] - # ClassVar[float] - # TypeVar[bool] - - def __init__(self, origin, args, *, inst=True, name=None, - _paramspec_tvars=False): - super().__init__(origin, inst=inst, name=name) - if not isinstance(args, tuple): - args = (args,) - self.__args__ = tuple(... if a is _TypingEllipsis else - a for a in args) - self.__parameters__ = _collect_parameters(args) - self._paramspec_tvars = _paramspec_tvars - if not name: - self.__module__ = origin.__module__ - - def __eq__(self, other): - if not isinstance(other, _GenericAlias): - return NotImplemented - return (self.__origin__ == other.__origin__ - and self.__args__ == other.__args__) - - def __hash__(self): - return hash((self.__origin__, self.__args__)) - - def __or__(self, right): - return Union[self, right] - - def __ror__(self, left): - return Union[left, self] - - @_tp_cache - def __getitem__(self, args): - # Parameterizes an already-parameterized object. - # - # For example, we arrive here doing something like: - # T1 = TypeVar('T1') - # T2 = TypeVar('T2') - # T3 = TypeVar('T3') - # class A(Generic[T1]): pass - # B = A[T2] # B is a _GenericAlias - # C = B[T3] # Invokes _GenericAlias.__getitem__ - # - # We also arrive here when parameterizing a generic `Callable` alias: - # T = TypeVar('T') - # C = Callable[[T], None] - # C[int] # Invokes _GenericAlias.__getitem__ - - if self.__origin__ in (Generic, Protocol): - # Can't subscript Generic[...] or Protocol[...]. - raise TypeError(f"Cannot subscript already-subscripted {self}") - if not self.__parameters__: - raise TypeError(f"{self} is not a generic class") - - # Preprocess `args`. - if not isinstance(args, tuple): - args = (args,) - args = tuple(_type_convert(p) for p in args) - args = _unpack_args(args) - new_args = self._determine_new_args(args) - r = self.copy_with(new_args) - return r - - def _determine_new_args(self, args): - # Determines new __args__ for __getitem__. - # - # For example, suppose we had: - # T1 = TypeVar('T1') - # T2 = TypeVar('T2') - # class A(Generic[T1, T2]): pass - # T3 = TypeVar('T3') - # B = A[int, T3] - # C = B[str] - # `B.__args__` is `(int, T3)`, so `C.__args__` should be `(int, str)`. - # Unfortunately, this is harder than it looks, because if `T3` is - # anything more exotic than a plain `TypeVar`, we need to consider - # edge cases. - - params = self.__parameters__ - # In the example above, this would be {T3: str} - for param in params: - prepare = getattr(param, '__typing_prepare_subst__', None) - if prepare is not None: - args = prepare(self, args) - alen = len(args) - plen = len(params) - if alen != plen: - raise TypeError(f"Too {'many' if alen > plen else 'few'} arguments for {self};" - f" actual {alen}, expected {plen}") - new_arg_by_param = dict(zip(params, args)) - - new_args = [] - for old_arg in self.__args__: - - if isinstance(old_arg, type): - new_args.append(old_arg) - continue - - substfunc = getattr(old_arg, '__typing_subst__', None) - if substfunc: - new_arg = substfunc(new_arg_by_param[old_arg]) - else: - subparams = getattr(old_arg, '__parameters__', ()) - if not subparams: - new_arg = old_arg - else: - subargs = [] - for x in subparams: - if isinstance(x, TypeVarTuple): - subargs.extend(new_arg_by_param[x]) - else: - subargs.append(new_arg_by_param[x]) - new_arg = old_arg[tuple(subargs)] - - if self.__origin__ == collections.abc.Callable and isinstance(new_arg, tuple): - # Consider the following `Callable`. - # C = Callable[[int], str] - # Here, `C.__args__` should be (int, str) - NOT ([int], str). - # That means that if we had something like... - # P = ParamSpec('P') - # T = TypeVar('T') - # C = Callable[P, T] - # D = C[[int, str], float] - # ...we need to be careful; `new_args` should end up as - # `(int, str, float)` rather than `([int, str], float)`. - new_args.extend(new_arg) - elif _is_unpacked_typevartuple(old_arg): - # Consider the following `_GenericAlias`, `B`: - # class A(Generic[*Ts]): ... - # B = A[T, *Ts] - # If we then do: - # B[float, int, str] - # The `new_arg` corresponding to `T` will be `float`, and the - # `new_arg` corresponding to `*Ts` will be `(int, str)`. We - # should join all these types together in a flat list - # `(float, int, str)` - so again, we should `extend`. - new_args.extend(new_arg) - else: - new_args.append(new_arg) - - return tuple(new_args) - - def copy_with(self, args): - return self.__class__(self.__origin__, args, name=self._name, inst=self._inst, - _paramspec_tvars=self._paramspec_tvars) - - def __repr__(self): - if self._name: - name = 'typing.' + self._name - else: - name = _type_repr(self.__origin__) - if self.__args__: - args = ", ".join([_type_repr(a) for a in self.__args__]) - else: - # To ensure the repr is eval-able. - args = "()" - return f'{name}[{args}]' - - def __reduce__(self): - if self._name: - origin = globals()[self._name] - else: - origin = self.__origin__ - args = tuple(self.__args__) - if len(args) == 1 and not isinstance(args[0], tuple): - args, = args - return operator.getitem, (origin, args) - - def __mro_entries__(self, bases): - if isinstance(self.__origin__, _SpecialForm): - raise TypeError(f"Cannot subclass {self!r}") - - if self._name: # generic version of an ABC or built-in class - return super().__mro_entries__(bases) - if self.__origin__ is Generic: - if Protocol in bases: - return () - i = bases.index(self) - for b in bases[i+1:]: - if isinstance(b, _BaseGenericAlias) and b is not self: - return () - return (self.__origin__,) - - def __iter__(self): - yield Unpack[self] - - -# _nparams is the number of accepted parameters, e.g. 0 for Hashable, -# 1 for List and 2 for Dict. It may be -1 if variable number of -# parameters are accepted (needs custom __getitem__). - -class _SpecialGenericAlias(_NotIterable, _BaseGenericAlias, _root=True): - def __init__(self, origin, nparams, *, inst=True, name=None): - if name is None: - name = origin.__name__ - super().__init__(origin, inst=inst, name=name) - self._nparams = nparams - if origin.__module__ == 'builtins': - self.__doc__ = f'A generic version of {origin.__qualname__}.' - else: - self.__doc__ = f'A generic version of {origin.__module__}.{origin.__qualname__}.' - - @_tp_cache - def __getitem__(self, params): - if not isinstance(params, tuple): - params = (params,) - msg = "Parameters to generic types must be types." - params = tuple(_type_check(p, msg) for p in params) - _check_generic(self, params, self._nparams) - return self.copy_with(params) - - def copy_with(self, params): - return _GenericAlias(self.__origin__, params, - name=self._name, inst=self._inst) - - def __repr__(self): - return 'typing.' + self._name - - def __subclasscheck__(self, cls): - if isinstance(cls, _SpecialGenericAlias): - return issubclass(cls.__origin__, self.__origin__) - if not isinstance(cls, _GenericAlias): - return issubclass(cls, self.__origin__) - return super().__subclasscheck__(cls) - - def __reduce__(self): - return self._name - - def __or__(self, right): - return Union[self, right] - - def __ror__(self, left): - return Union[left, self] - -class _CallableGenericAlias(_NotIterable, _GenericAlias, _root=True): - def __repr__(self): - assert self._name == 'Callable' - args = self.__args__ - if len(args) == 2 and _is_param_expr(args[0]): - return super().__repr__() - return (f'typing.Callable' - f'[[{", ".join([_type_repr(a) for a in args[:-1]])}], ' - f'{_type_repr(args[-1])}]') - - def __reduce__(self): - args = self.__args__ - if not (len(args) == 2 and _is_param_expr(args[0])): - args = list(args[:-1]), args[-1] - return operator.getitem, (Callable, args) - - -class _CallableType(_SpecialGenericAlias, _root=True): - def copy_with(self, params): - return _CallableGenericAlias(self.__origin__, params, - name=self._name, inst=self._inst, - _paramspec_tvars=True) - - def __getitem__(self, params): - if not isinstance(params, tuple) or len(params) != 2: - raise TypeError("Callable must be used as " - "Callable[[arg, ...], result].") - args, result = params - # This relaxes what args can be on purpose to allow things like - # PEP 612 ParamSpec. Responsibility for whether a user is using - # Callable[...] properly is deferred to static type checkers. - if isinstance(args, list): - params = (tuple(args), result) - else: - params = (args, result) - return self.__getitem_inner__(params) - - @_tp_cache - def __getitem_inner__(self, params): - args, result = params - msg = "Callable[args, result]: result must be a type." - result = _type_check(result, msg) - if args is Ellipsis: - return self.copy_with((_TypingEllipsis, result)) - if not isinstance(args, tuple): - args = (args,) - args = tuple(_type_convert(arg) for arg in args) - params = args + (result,) - return self.copy_with(params) - - -class _TupleType(_SpecialGenericAlias, _root=True): - @_tp_cache - def __getitem__(self, params): - if not isinstance(params, tuple): - params = (params,) - if len(params) >= 2 and params[-1] is ...: - msg = "Tuple[t, ...]: t must be a type." - params = tuple(_type_check(p, msg) for p in params[:-1]) - return self.copy_with((*params, _TypingEllipsis)) - msg = "Tuple[t0, t1, ...]: each t must be a type." - params = tuple(_type_check(p, msg) for p in params) - return self.copy_with(params) - - -class _UnionGenericAlias(_NotIterable, _GenericAlias, _root=True): - def copy_with(self, params): - return Union[params] - - def __eq__(self, other): - if not isinstance(other, (_UnionGenericAlias, types.UnionType)): - return NotImplemented - return set(self.__args__) == set(other.__args__) - - def __hash__(self): - return hash(frozenset(self.__args__)) - - def __repr__(self): - args = self.__args__ - if len(args) == 2: - if args[0] is type(None): - return f'typing.Optional[{_type_repr(args[1])}]' - elif args[1] is type(None): - return f'typing.Optional[{_type_repr(args[0])}]' - return super().__repr__() - - def __instancecheck__(self, obj): - return self.__subclasscheck__(type(obj)) - - def __subclasscheck__(self, cls): - for arg in self.__args__: - if issubclass(cls, arg): - return True - - def __reduce__(self): - func, (origin, args) = super().__reduce__() - return func, (Union, args) - - -def _value_and_type_iter(parameters): - return ((p, type(p)) for p in parameters) - - -class _LiteralGenericAlias(_GenericAlias, _root=True): - - def __eq__(self, other): - if not isinstance(other, _LiteralGenericAlias): - return NotImplemented - - return set(_value_and_type_iter(self.__args__)) == set(_value_and_type_iter(other.__args__)) - - def __hash__(self): - return hash(frozenset(_value_and_type_iter(self.__args__))) - - -class _ConcatenateGenericAlias(_GenericAlias, _root=True): - def copy_with(self, params): - if isinstance(params[-1], (list, tuple)): - return (*params[:-1], *params[-1]) - if isinstance(params[-1], _ConcatenateGenericAlias): - params = (*params[:-1], *params[-1].__args__) - return super().copy_with(params) - - -@_SpecialForm -def Unpack(self, parameters): - """Type unpack operator. - - The type unpack operator takes the child types from some container type, - such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. For - example: - - # For some generic class `Foo`: - Foo[Unpack[tuple[int, str]]] # Equivalent to Foo[int, str] - - Ts = TypeVarTuple('Ts') - # Specifies that `Bar` is generic in an arbitrary number of types. - # (Think of `Ts` as a tuple of an arbitrary number of individual - # `TypeVar`s, which the `Unpack` is 'pulling out' directly into the - # `Generic[]`.) - class Bar(Generic[Unpack[Ts]]): ... - Bar[int] # Valid - Bar[int, str] # Also valid - - From Python 3.11, this can also be done using the `*` operator: - - Foo[*tuple[int, str]] - class Bar(Generic[*Ts]): ... - - Note that there is only some runtime checking of this operator. Not - everything the runtime allows may be accepted by static type checkers. - - For more information, see PEP 646. - """ - item = _type_check(parameters, f'{self} accepts only single type.') - return _UnpackGenericAlias(origin=self, args=(item,)) - - -class _UnpackGenericAlias(_GenericAlias, _root=True): - - def __repr__(self): - # `Unpack` only takes one argument, so __args__ should contain only - # a single item. - return '*' + repr(self.__args__[0]) - - def __getitem__(self, args): - if self.__typing_is_unpacked_typevartuple__: - return args - return super().__getitem__(args) - - @property - def __typing_unpacked_tuple_args__(self): - assert self.__origin__ is Unpack - assert len(self.__args__) == 1 - arg, = self.__args__ - if isinstance(arg, _GenericAlias): - assert arg.__origin__ is tuple - return arg.__args__ - return None - - @property - def __typing_is_unpacked_typevartuple__(self): - assert self.__origin__ is Unpack - assert len(self.__args__) == 1 - return isinstance(self.__args__[0], TypeVarTuple) - - -class Generic: - """Abstract base class for generic types. - - A generic type is typically declared by inheriting from - this class parameterized with one or more type variables. - For example, a generic mapping type might be defined as:: - - class Mapping(Generic[KT, VT]): - def __getitem__(self, key: KT) -> VT: - ... - # Etc. - - This class can then be used as follows:: - - def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: - try: - return mapping[key] - except KeyError: - return default - """ - __slots__ = () - _is_protocol = False - - @_tp_cache - def __class_getitem__(cls, params): - """Parameterizes a generic class. - - At least, parameterizing a generic class is the *main* thing this method - does. For example, for some generic class `Foo`, this is called when we - do `Foo[int]` - there, with `cls=Foo` and `params=int`. - - However, note that this method is also called when defining generic - classes in the first place with `class Foo(Generic[T]): ...`. - """ - if not isinstance(params, tuple): - params = (params,) - - params = tuple(_type_convert(p) for p in params) - if cls in (Generic, Protocol): - # Generic and Protocol can only be subscripted with unique type variables. - if not params: - raise TypeError( - f"Parameter list to {cls.__qualname__}[...] cannot be empty" - ) - if not all(_is_typevar_like(p) for p in params): - raise TypeError( - f"Parameters to {cls.__name__}[...] must all be type variables " - f"or parameter specification variables.") - if len(set(params)) != len(params): - raise TypeError( - f"Parameters to {cls.__name__}[...] must all be unique") - else: - # Subscripting a regular Generic subclass. - for param in cls.__parameters__: - prepare = getattr(param, '__typing_prepare_subst__', None) - if prepare is not None: - params = prepare(cls, params) - _check_generic(cls, params, len(cls.__parameters__)) - - new_args = [] - for param, new_arg in zip(cls.__parameters__, params): - if isinstance(param, TypeVarTuple): - new_args.extend(new_arg) - else: - new_args.append(new_arg) - params = tuple(new_args) - - return _GenericAlias(cls, params, - _paramspec_tvars=True) - - def __init_subclass__(cls, *args, **kwargs): - super().__init_subclass__(*args, **kwargs) - tvars = [] - if '__orig_bases__' in cls.__dict__: - error = Generic in cls.__orig_bases__ - else: - error = (Generic in cls.__bases__ and - cls.__name__ != 'Protocol' and - type(cls) != _TypedDictMeta) - if error: - raise TypeError("Cannot inherit from plain Generic") - if '__orig_bases__' in cls.__dict__: - tvars = _collect_parameters(cls.__orig_bases__) - # Look for Generic[T1, ..., Tn]. - # If found, tvars must be a subset of it. - # If not found, tvars is it. - # Also check for and reject plain Generic, - # and reject multiple Generic[...]. - gvars = None - for base in cls.__orig_bases__: - if (isinstance(base, _GenericAlias) and - base.__origin__ is Generic): - if gvars is not None: - raise TypeError( - "Cannot inherit from Generic[...] multiple types.") - gvars = base.__parameters__ - if gvars is not None: - tvarset = set(tvars) - gvarset = set(gvars) - if not tvarset <= gvarset: - s_vars = ', '.join(str(t) for t in tvars if t not in gvarset) - s_args = ', '.join(str(g) for g in gvars) - raise TypeError(f"Some type variables ({s_vars}) are" - f" not listed in Generic[{s_args}]") - tvars = gvars - cls.__parameters__ = tuple(tvars) - - -class _TypingEllipsis: - """Internal placeholder for ... (ellipsis).""" - - -_TYPING_INTERNALS = ['__parameters__', '__orig_bases__', '__orig_class__', - '_is_protocol', '_is_runtime_protocol'] - -_SPECIAL_NAMES = ['__abstractmethods__', '__annotations__', '__dict__', '__doc__', - '__init__', '__module__', '__new__', '__slots__', - '__subclasshook__', '__weakref__', '__class_getitem__'] - -# These special attributes will be not collected as protocol members. -EXCLUDED_ATTRIBUTES = _TYPING_INTERNALS + _SPECIAL_NAMES + ['_MutableMapping__marker'] - - -def _get_protocol_attrs(cls): - """Collect protocol members from a protocol class objects. - - This includes names actually defined in the class dictionary, as well - as names that appear in annotations. Special names (above) are skipped. - """ - attrs = set() - for base in cls.__mro__[:-1]: # without object - if base.__name__ in ('Protocol', 'Generic'): - continue - annotations = getattr(base, '__annotations__', {}) - for attr in list(base.__dict__.keys()) + list(annotations.keys()): - if not attr.startswith('_abc_') and attr not in EXCLUDED_ATTRIBUTES: - attrs.add(attr) - return attrs - - -def _is_callable_members_only(cls): - # PEP 544 prohibits using issubclass() with protocols that have non-method members. - return all(callable(getattr(cls, attr, None)) for attr in _get_protocol_attrs(cls)) - - -def _no_init_or_replace_init(self, *args, **kwargs): - cls = type(self) - - if cls._is_protocol: - raise TypeError('Protocols cannot be instantiated') - - # Already using a custom `__init__`. No need to calculate correct - # `__init__` to call. This can lead to RecursionError. See bpo-45121. - if cls.__init__ is not _no_init_or_replace_init: - return - - # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`. - # The first instantiation of the subclass will call `_no_init_or_replace_init` which - # searches for a proper new `__init__` in the MRO. The new `__init__` - # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent - # instantiation of the protocol subclass will thus use the new - # `__init__` and no longer call `_no_init_or_replace_init`. - for base in cls.__mro__: - init = base.__dict__.get('__init__', _no_init_or_replace_init) - if init is not _no_init_or_replace_init: - cls.__init__ = init - break - else: - # should not happen - cls.__init__ = object.__init__ - - cls.__init__(self, *args, **kwargs) - - -def _caller(depth=1, default='__main__'): - try: - return sys._getframe(depth + 1).f_globals.get('__name__', default) - except (AttributeError, ValueError): # For platforms without _getframe() - return None - - -def _allow_reckless_class_checks(depth=3): - """Allow instance and class checks for special stdlib modules. - - The abc and functools modules indiscriminately call isinstance() and - issubclass() on the whole MRO of a user class, which may contain protocols. - """ - return _caller(depth) in {'abc', 'functools', None} - - -_PROTO_ALLOWLIST = { - 'collections.abc': [ - 'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable', - 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', - ], - 'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'], -} - - -class _ProtocolMeta(ABCMeta): - # This metaclass is really unfortunate and exists only because of - # the lack of __instancehook__. - def __instancecheck__(cls, instance): - # We need this method for situations where attributes are - # assigned in __init__. - if ( - getattr(cls, '_is_protocol', False) and - not getattr(cls, '_is_runtime_protocol', False) and - not _allow_reckless_class_checks(depth=2) - ): - raise TypeError("Instance and class checks can only be used with" - " @runtime_checkable protocols") - - if ((not getattr(cls, '_is_protocol', False) or - _is_callable_members_only(cls)) and - issubclass(instance.__class__, cls)): - return True - if cls._is_protocol: - if all(hasattr(instance, attr) and - # All *methods* can be blocked by setting them to None. - (not callable(getattr(cls, attr, None)) or - getattr(instance, attr) is not None) - for attr in _get_protocol_attrs(cls)): - return True - return super().__instancecheck__(instance) - - -class Protocol(Generic, metaclass=_ProtocolMeta): - """Base class for protocol classes. - - Protocol classes are defined as:: - - class Proto(Protocol): - def meth(self) -> int: - ... - - Such classes are primarily used with static type checkers that recognize - structural subtyping (static duck-typing), for example:: - - class C: - def meth(self) -> int: - return 0 - - def func(x: Proto) -> int: - return x.meth() - - func(C()) # Passes static type check - - See PEP 544 for details. Protocol classes decorated with - @typing.runtime_checkable act as simple-minded runtime protocols that check - only the presence of given attributes, ignoring their type signatures. - Protocol classes can be generic, they are defined as:: - - class GenProto(Protocol[T]): - def meth(self) -> T: - ... - """ - __slots__ = () - _is_protocol = True - _is_runtime_protocol = False - - def __init_subclass__(cls, *args, **kwargs): - super().__init_subclass__(*args, **kwargs) - - # Determine if this is a protocol or a concrete subclass. - if not cls.__dict__.get('_is_protocol', False): - cls._is_protocol = any(b is Protocol for b in cls.__bases__) - - # Set (or override) the protocol subclass hook. - def _proto_hook(other): - if not cls.__dict__.get('_is_protocol', False): - return NotImplemented - - # First, perform various sanity checks. - if not getattr(cls, '_is_runtime_protocol', False): - if _allow_reckless_class_checks(): - return NotImplemented - raise TypeError("Instance and class checks can only be used with" - " @runtime_checkable protocols") - if not _is_callable_members_only(cls): - if _allow_reckless_class_checks(): - return NotImplemented - raise TypeError("Protocols with non-method members" - " don't support issubclass()") - if not isinstance(other, type): - # Same error message as for issubclass(1, int). - raise TypeError('issubclass() arg 1 must be a class') - - # Second, perform the actual structural compatibility check. - for attr in _get_protocol_attrs(cls): - for base in other.__mro__: - # Check if the members appears in the class dictionary... - if attr in base.__dict__: - if base.__dict__[attr] is None: - return NotImplemented - break - - # ...or in annotations, if it is a sub-protocol. - annotations = getattr(base, '__annotations__', {}) - if (isinstance(annotations, collections.abc.Mapping) and - attr in annotations and - issubclass(other, Generic) and other._is_protocol): - break - else: - return NotImplemented - return True - - if '__subclasshook__' not in cls.__dict__: - cls.__subclasshook__ = _proto_hook - - # We have nothing more to do for non-protocols... - if not cls._is_protocol: - return - - # ... otherwise check consistency of bases, and prohibit instantiation. - for base in cls.__bases__: - if not (base in (object, Generic) or - base.__module__ in _PROTO_ALLOWLIST and - base.__name__ in _PROTO_ALLOWLIST[base.__module__] or - issubclass(base, Generic) and base._is_protocol): - raise TypeError('Protocols can only inherit from other' - ' protocols, got %r' % base) - if cls.__init__ is Protocol.__init__: - cls.__init__ = _no_init_or_replace_init - - -class _AnnotatedAlias(_NotIterable, _GenericAlias, _root=True): - """Runtime representation of an annotated type. - - At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't' - with extra annotations. The alias behaves like a normal typing alias, - instantiating is the same as instantiating the underlying type, binding - it to types is also the same. - """ - def __init__(self, origin, metadata): - if isinstance(origin, _AnnotatedAlias): - metadata = origin.__metadata__ + metadata - origin = origin.__origin__ - super().__init__(origin, origin) - self.__metadata__ = metadata - - def copy_with(self, params): - assert len(params) == 1 - new_type = params[0] - return _AnnotatedAlias(new_type, self.__metadata__) - - def __repr__(self): - return "typing.Annotated[{}, {}]".format( - _type_repr(self.__origin__), - ", ".join(repr(a) for a in self.__metadata__) - ) - - def __reduce__(self): - return operator.getitem, ( - Annotated, (self.__origin__,) + self.__metadata__ - ) - - def __eq__(self, other): - if not isinstance(other, _AnnotatedAlias): - return NotImplemented - return (self.__origin__ == other.__origin__ - and self.__metadata__ == other.__metadata__) - - def __hash__(self): - return hash((self.__origin__, self.__metadata__)) - - def __getattr__(self, attr): - if attr in {'__name__', '__qualname__'}: - return 'Annotated' - return super().__getattr__(attr) - - -class Annotated: - """Add context specific metadata to a type. - - Example: Annotated[int, runtime_check.Unsigned] indicates to the - hypothetical runtime_check module that this type is an unsigned int. - Every other consumer of this type can ignore this metadata and treat - this type as int. - - The first argument to Annotated must be a valid type. - - Details: - - - It's an error to call `Annotated` with less than two arguments. - - Nested Annotated are flattened:: - - Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3] - - - Instantiating an annotated type is equivalent to instantiating the - underlying type:: - - Annotated[C, Ann1](5) == C(5) - - - Annotated can be used as a generic type alias:: - - Optimized = Annotated[T, runtime.Optimize()] - Optimized[int] == Annotated[int, runtime.Optimize()] - - OptimizedList = Annotated[List[T], runtime.Optimize()] - OptimizedList[int] == Annotated[List[int], runtime.Optimize()] - - - Annotated cannot be used with an unpacked TypeVarTuple:: - - Annotated[*Ts, Ann1] # NOT valid - - This would be equivalent to - - Annotated[T1, T2, T3, ..., Ann1] - - where T1, T2 etc. are TypeVars, which would be invalid, because - only one type should be passed to Annotated. - """ - - __slots__ = () - - def __new__(cls, *args, **kwargs): - raise TypeError("Type Annotated cannot be instantiated.") - - @_tp_cache - def __class_getitem__(cls, params): - if not isinstance(params, tuple) or len(params) < 2: - raise TypeError("Annotated[...] should be used " - "with at least two arguments (a type and an " - "annotation).") - if _is_unpacked_typevartuple(params[0]): - raise TypeError("Annotated[...] should not be used with an " - "unpacked TypeVarTuple") - msg = "Annotated[t, ...]: t must be a type." - origin = _type_check(params[0], msg, allow_special_forms=True) - metadata = tuple(params[1:]) - return _AnnotatedAlias(origin, metadata) - - def __init_subclass__(cls, *args, **kwargs): - raise TypeError( - "Cannot subclass {}.Annotated".format(cls.__module__) - ) - - -def runtime_checkable(cls): - """Mark a protocol class as a runtime protocol. - - Such protocol can be used with isinstance() and issubclass(). - Raise TypeError if applied to a non-protocol class. - This allows a simple-minded structural check very similar to - one trick ponies in collections.abc such as Iterable. - For example:: - - @runtime_checkable - class Closable(Protocol): - def close(self): ... - - assert isinstance(open('/some/file'), Closable) - - Warning: this will check only the presence of the required methods, - not their type signatures! - """ - if not issubclass(cls, Generic) or not cls._is_protocol: - raise TypeError('@runtime_checkable can be only applied to protocol classes,' - ' got %r' % cls) - cls._is_runtime_protocol = True - return cls - - -def cast(typ, val): - """Cast a value to a type. - - This returns the value unchanged. To the type checker this - signals that the return value has the designated type, but at - runtime we intentionally don't check anything (we want this - to be as fast as possible). - """ - return val - - -def assert_type(val, typ, /): - """Ask a static type checker to confirm that the value is of the given type. - - When the type checker encounters a call to assert_type(), it - emits an error if the value is not of the specified type:: - - def greet(name: str) -> None: - assert_type(name, str) # ok - assert_type(name, int) # type checker error - - At runtime this returns the first argument unchanged and otherwise - does nothing. - """ - return val - - -_allowed_types = (types.FunctionType, types.BuiltinFunctionType, - types.MethodType, types.ModuleType, - WrapperDescriptorType, MethodWrapperType, MethodDescriptorType) - - -def get_type_hints(obj, globalns=None, localns=None, include_extras=False): - """Return type hints for an object. - - This is often the same as obj.__annotations__, but it handles - forward references encoded as string literals and recursively replaces all - 'Annotated[T, ...]' with 'T' (unless 'include_extras=True'). - - The argument may be a module, class, method, or function. The annotations - are returned as a dictionary. For classes, annotations include also - inherited members. - - TypeError is raised if the argument is not of a type that can contain - annotations, and an empty dictionary is returned if no annotations are - present. - - BEWARE -- the behavior of globalns and localns is counterintuitive - (unless you are familiar with how eval() and exec() work). The - search order is locals first, then globals. - - - If no dict arguments are passed, an attempt is made to use the - globals from obj (or the respective module's globals for classes), - and these are also used as the locals. If the object does not appear - to have globals, an empty dictionary is used. For classes, the search - order is globals first then locals. - - - If one dict argument is passed, it is used for both globals and - locals. - - - If two dict arguments are passed, they specify globals and - locals, respectively. - """ - - if getattr(obj, '__no_type_check__', None): - return {} - # Classes require a special treatment. - if isinstance(obj, type): - hints = {} - for base in reversed(obj.__mro__): - if globalns is None: - base_globals = getattr(sys.modules.get(base.__module__, None), '__dict__', {}) - else: - base_globals = globalns - ann = base.__dict__.get('__annotations__', {}) - if isinstance(ann, types.GetSetDescriptorType): - ann = {} - base_locals = dict(vars(base)) if localns is None else localns - if localns is None and globalns is None: - # This is surprising, but required. Before Python 3.10, - # get_type_hints only evaluated the globalns of - # a class. To maintain backwards compatibility, we reverse - # the globalns and localns order so that eval() looks into - # *base_globals* first rather than *base_locals*. - # This only affects ForwardRefs. - base_globals, base_locals = base_locals, base_globals - for name, value in ann.items(): - if value is None: - value = type(None) - if isinstance(value, str): - value = ForwardRef(value, is_argument=False, is_class=True) - value = _eval_type(value, base_globals, base_locals) - hints[name] = value - return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()} - - if globalns is None: - if isinstance(obj, types.ModuleType): - globalns = obj.__dict__ - else: - nsobj = obj - # Find globalns for the unwrapped object. - while hasattr(nsobj, '__wrapped__'): - nsobj = nsobj.__wrapped__ - globalns = getattr(nsobj, '__globals__', {}) - if localns is None: - localns = globalns - elif localns is None: - localns = globalns - hints = getattr(obj, '__annotations__', None) - if hints is None: - # Return empty annotations for something that _could_ have them. - if isinstance(obj, _allowed_types): - return {} - else: - raise TypeError('{!r} is not a module, class, method, ' - 'or function.'.format(obj)) - hints = dict(hints) - for name, value in hints.items(): - if value is None: - value = type(None) - if isinstance(value, str): - # class-level forward refs were handled above, this must be either - # a module-level annotation or a function argument annotation - value = ForwardRef( - value, - is_argument=not isinstance(obj, types.ModuleType), - is_class=False, - ) - hints[name] = _eval_type(value, globalns, localns) - return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()} - - -def _strip_annotations(t): - """Strips the annotations from a given type. - """ - if isinstance(t, _AnnotatedAlias): - return _strip_annotations(t.__origin__) - if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired): - return _strip_annotations(t.__args__[0]) - if isinstance(t, _GenericAlias): - stripped_args = tuple(_strip_annotations(a) for a in t.__args__) - if stripped_args == t.__args__: - return t - return t.copy_with(stripped_args) - if isinstance(t, GenericAlias): - stripped_args = tuple(_strip_annotations(a) for a in t.__args__) - if stripped_args == t.__args__: - return t - return GenericAlias(t.__origin__, stripped_args) - if isinstance(t, types.UnionType): - stripped_args = tuple(_strip_annotations(a) for a in t.__args__) - if stripped_args == t.__args__: - return t - return functools.reduce(operator.or_, stripped_args) - - return t - - -def get_origin(tp): - """Get the unsubscripted version of a type. - - This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar - and Annotated. Return None for unsupported types. Examples:: - - get_origin(Literal[42]) is Literal - get_origin(int) is None - get_origin(ClassVar[int]) is ClassVar - get_origin(Generic) is Generic - get_origin(Generic[T]) is Generic - get_origin(Union[T, int]) is Union - get_origin(List[Tuple[T, T]][int]) == list - get_origin(P.args) is P - """ - if isinstance(tp, _AnnotatedAlias): - return Annotated - if isinstance(tp, (_BaseGenericAlias, GenericAlias, - ParamSpecArgs, ParamSpecKwargs)): - return tp.__origin__ - if tp is Generic: - return Generic - if isinstance(tp, types.UnionType): - return types.UnionType - return None - - -def get_args(tp): - """Get type arguments with all substitutions performed. - - For unions, basic simplifications used by Union constructor are performed. - Examples:: - get_args(Dict[str, int]) == (str, int) - get_args(int) == () - get_args(Union[int, Union[T, int], str][int]) == (int, str) - get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) - get_args(Callable[[], T][int]) == ([], int) - """ - if isinstance(tp, _AnnotatedAlias): - return (tp.__origin__,) + tp.__metadata__ - if isinstance(tp, (_GenericAlias, GenericAlias)): - res = tp.__args__ - if _should_unflatten_callable_args(tp, res): - res = (list(res[:-1]), res[-1]) - return res - if isinstance(tp, types.UnionType): - return tp.__args__ - return () - - -def is_typeddict(tp): - """Check if an annotation is a TypedDict class - - For example:: - class Film(TypedDict): - title: str - year: int - - is_typeddict(Film) # => True - is_typeddict(Union[list, str]) # => False - """ - return isinstance(tp, _TypedDictMeta) - - -_ASSERT_NEVER_REPR_MAX_LENGTH = 100 - - -def assert_never(arg: Never, /) -> Never: - """Statically assert that a line of code is unreachable. - - Example:: - - def int_or_str(arg: int | str) -> None: - match arg: - case int(): - print("It's an int") - case str(): - print("It's a str") - case _: - assert_never(arg) - - If a type checker finds that a call to assert_never() is - reachable, it will emit an error. - - At runtime, this throws an exception when called. - - """ - value = repr(arg) - if len(value) > _ASSERT_NEVER_REPR_MAX_LENGTH: - value = value[:_ASSERT_NEVER_REPR_MAX_LENGTH] + '...' - raise AssertionError(f"Expected code to be unreachable, but got: {value}") - - -def no_type_check(arg): - """Decorator to indicate that annotations are not type hints. - - The argument must be a class or function; if it is a class, it - applies recursively to all methods and classes defined in that class - (but not to methods defined in its superclasses or subclasses). - - This mutates the function(s) or class(es) in place. - """ - if isinstance(arg, type): - for key in dir(arg): - obj = getattr(arg, key) - if ( - not hasattr(obj, '__qualname__') - or obj.__qualname__ != f'{arg.__qualname__}.{obj.__name__}' - or getattr(obj, '__module__', None) != arg.__module__ - ): - # We only modify objects that are defined in this type directly. - # If classes / methods are nested in multiple layers, - # we will modify them when processing their direct holders. - continue - # Instance, class, and static methods: - if isinstance(obj, types.FunctionType): - obj.__no_type_check__ = True - if isinstance(obj, types.MethodType): - obj.__func__.__no_type_check__ = True - # Nested types: - if isinstance(obj, type): - no_type_check(obj) - try: - arg.__no_type_check__ = True - except TypeError: # built-in classes - pass - return arg - - -def no_type_check_decorator(decorator): - """Decorator to give another decorator the @no_type_check effect. - - This wraps the decorator with something that wraps the decorated - function in @no_type_check. - """ - - @functools.wraps(decorator) - def wrapped_decorator(*args, **kwds): - func = decorator(*args, **kwds) - func = no_type_check(func) - return func - - return wrapped_decorator - - -def _overload_dummy(*args, **kwds): - """Helper for @overload to raise when called.""" - raise NotImplementedError( - "You should not call an overloaded function. " - "A series of @overload-decorated functions " - "outside a stub module should always be followed " - "by an implementation that is not @overload-ed.") - - -# {module: {qualname: {firstlineno: func}}} -_overload_registry = defaultdict(functools.partial(defaultdict, dict)) - - -def overload(func): - """Decorator for overloaded functions/methods. - - In a stub file, place two or more stub definitions for the same - function in a row, each decorated with @overload. For example: - - @overload - def utf8(value: None) -> None: ... - @overload - def utf8(value: bytes) -> bytes: ... - @overload - def utf8(value: str) -> bytes: ... - - In a non-stub file (i.e. a regular .py file), do the same but - follow it with an implementation. The implementation should *not* - be decorated with @overload. For example: - - @overload - def utf8(value: None) -> None: ... - @overload - def utf8(value: bytes) -> bytes: ... - @overload - def utf8(value: str) -> bytes: ... - def utf8(value): - # implementation goes here - - The overloads for a function can be retrieved at runtime using the - get_overloads() function. - """ - # classmethod and staticmethod - f = getattr(func, "__func__", func) - try: - _overload_registry[f.__module__][f.__qualname__][f.__code__.co_firstlineno] = func - except AttributeError: - # Not a normal function; ignore. - pass - return _overload_dummy - - -def get_overloads(func): - """Return all defined overloads for *func* as a sequence.""" - # classmethod and staticmethod - f = getattr(func, "__func__", func) - if f.__module__ not in _overload_registry: - return [] - mod_dict = _overload_registry[f.__module__] - if f.__qualname__ not in mod_dict: - return [] - return list(mod_dict[f.__qualname__].values()) - - -def clear_overloads(): - """Clear all overloads in the registry.""" - _overload_registry.clear() - - -def final(f): - """A decorator to indicate final methods and final classes. - - Use this decorator to indicate to type checkers that the decorated - method cannot be overridden, and decorated class cannot be subclassed. - For example: - - class Base: - @final - def done(self) -> None: - ... - class Sub(Base): - def done(self) -> None: # Error reported by type checker - ... - - @final - class Leaf: - ... - class Other(Leaf): # Error reported by type checker - ... - - There is no runtime checking of these properties. The decorator - sets the ``__final__`` attribute to ``True`` on the decorated object - to allow runtime introspection. - """ - try: - f.__final__ = True - except (AttributeError, TypeError): - # Skip the attribute silently if it is not writable. - # AttributeError happens if the object has __slots__ or a - # read-only property, TypeError if it's a builtin class. - pass - return f - - -# Some unconstrained type variables. These are used by the container types. -# (These are not for export.) -T = TypeVar('T') # Any type. -KT = TypeVar('KT') # Key type. -VT = TypeVar('VT') # Value type. -T_co = TypeVar('T_co', covariant=True) # Any type covariant containers. -V_co = TypeVar('V_co', covariant=True) # Any type covariant containers. -VT_co = TypeVar('VT_co', covariant=True) # Value type covariant containers. -T_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant. -# Internal type variable used for Type[]. -CT_co = TypeVar('CT_co', covariant=True, bound=type) - -# A useful type variable with constraints. This represents string types. -# (This one *is* for export!) -AnyStr = TypeVar('AnyStr', bytes, str) - - -# Various ABCs mimicking those in collections.abc. -_alias = _SpecialGenericAlias - -Hashable = _alias(collections.abc.Hashable, 0) # Not generic. -Awaitable = _alias(collections.abc.Awaitable, 1) -Coroutine = _alias(collections.abc.Coroutine, 3) -AsyncIterable = _alias(collections.abc.AsyncIterable, 1) -AsyncIterator = _alias(collections.abc.AsyncIterator, 1) -Iterable = _alias(collections.abc.Iterable, 1) -Iterator = _alias(collections.abc.Iterator, 1) -Reversible = _alias(collections.abc.Reversible, 1) -Sized = _alias(collections.abc.Sized, 0) # Not generic. -Container = _alias(collections.abc.Container, 1) -Collection = _alias(collections.abc.Collection, 1) -Callable = _CallableType(collections.abc.Callable, 2) -Callable.__doc__ = \ - """Callable type; Callable[[int], str] is a function of (int) -> str. - - The subscription syntax must always be used with exactly two - values: the argument list and the return type. The argument list - must be a list of types or ellipsis; the return type must be a single type. - - There is no syntax to indicate optional or keyword arguments, - such function types are rarely used as callback types. - """ -AbstractSet = _alias(collections.abc.Set, 1, name='AbstractSet') -MutableSet = _alias(collections.abc.MutableSet, 1) -# NOTE: Mapping is only covariant in the value type. -Mapping = _alias(collections.abc.Mapping, 2) -MutableMapping = _alias(collections.abc.MutableMapping, 2) -Sequence = _alias(collections.abc.Sequence, 1) -MutableSequence = _alias(collections.abc.MutableSequence, 1) -ByteString = _alias(collections.abc.ByteString, 0) # Not generic -# Tuple accepts variable number of parameters. -Tuple = _TupleType(tuple, -1, inst=False, name='Tuple') -Tuple.__doc__ = \ - """Tuple type; Tuple[X, Y] is the cross-product type of X and Y. - - Example: Tuple[T1, T2] is a tuple of two elements corresponding - to type variables T1 and T2. Tuple[int, float, str] is a tuple - of an int, a float and a string. - - To specify a variable-length tuple of homogeneous type, use Tuple[T, ...]. - """ -List = _alias(list, 1, inst=False, name='List') -Deque = _alias(collections.deque, 1, name='Deque') -Set = _alias(set, 1, inst=False, name='Set') -FrozenSet = _alias(frozenset, 1, inst=False, name='FrozenSet') -MappingView = _alias(collections.abc.MappingView, 1) -KeysView = _alias(collections.abc.KeysView, 1) -ItemsView = _alias(collections.abc.ItemsView, 2) -ValuesView = _alias(collections.abc.ValuesView, 1) -ContextManager = _alias(contextlib.AbstractContextManager, 1, name='ContextManager') -AsyncContextManager = _alias(contextlib.AbstractAsyncContextManager, 1, name='AsyncContextManager') -Dict = _alias(dict, 2, inst=False, name='Dict') -DefaultDict = _alias(collections.defaultdict, 2, name='DefaultDict') -OrderedDict = _alias(collections.OrderedDict, 2) -Counter = _alias(collections.Counter, 1) -ChainMap = _alias(collections.ChainMap, 2) -Generator = _alias(collections.abc.Generator, 3) -AsyncGenerator = _alias(collections.abc.AsyncGenerator, 2) -Type = _alias(type, 1, inst=False, name='Type') -Type.__doc__ = \ - """A special construct usable to annotate class objects. - - For example, suppose we have the following classes:: - - class User: ... # Abstract base for User classes - class BasicUser(User): ... - class ProUser(User): ... - class TeamUser(User): ... - - And a function that takes a class argument that's a subclass of - User and returns an instance of the corresponding class:: - - U = TypeVar('U', bound=User) - def new_user(user_class: Type[U]) -> U: - user = user_class() - # (Here we could write the user object to a database) - return user - - joe = new_user(BasicUser) - - At this point the type checker knows that joe has type BasicUser. - """ - - -@runtime_checkable -class SupportsInt(Protocol): - """An ABC with one abstract method __int__.""" - __slots__ = () - - @abstractmethod - def __int__(self) -> int: - pass - - -@runtime_checkable -class SupportsFloat(Protocol): - """An ABC with one abstract method __float__.""" - __slots__ = () - - @abstractmethod - def __float__(self) -> float: - pass - - -@runtime_checkable -class SupportsComplex(Protocol): - """An ABC with one abstract method __complex__.""" - __slots__ = () - - @abstractmethod - def __complex__(self) -> complex: - pass - - -@runtime_checkable -class SupportsBytes(Protocol): - """An ABC with one abstract method __bytes__.""" - __slots__ = () - - @abstractmethod - def __bytes__(self) -> bytes: - pass - - -@runtime_checkable -class SupportsIndex(Protocol): - """An ABC with one abstract method __index__.""" - __slots__ = () - - @abstractmethod - def __index__(self) -> int: - pass - - -@runtime_checkable -class SupportsAbs(Protocol[T_co]): - """An ABC with one abstract method __abs__ that is covariant in its return type.""" - __slots__ = () - - @abstractmethod - def __abs__(self) -> T_co: - pass - - -@runtime_checkable -class SupportsRound(Protocol[T_co]): - """An ABC with one abstract method __round__ that is covariant in its return type.""" - __slots__ = () - - @abstractmethod - def __round__(self, ndigits: int = 0) -> T_co: - pass - - -def _make_nmtuple(name, types, module, defaults = ()): - fields = [n for n, t in types] - types = {n: _type_check(t, f"field {n} annotation must be a type") - for n, t in types} - nm_tpl = collections.namedtuple(name, fields, - defaults=defaults, module=module) - nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = types - return nm_tpl - - -# attributes prohibited to set in NamedTuple class syntax -_prohibited = frozenset({'__new__', '__init__', '__slots__', '__getnewargs__', - '_fields', '_field_defaults', - '_make', '_replace', '_asdict', '_source'}) - -_special = frozenset({'__module__', '__name__', '__annotations__'}) - - -class NamedTupleMeta(type): - - def __new__(cls, typename, bases, ns): - assert _NamedTuple in bases - for base in bases: - if base is not _NamedTuple and base is not Generic: - raise TypeError( - 'can only inherit from a NamedTuple type and Generic') - bases = tuple(tuple if base is _NamedTuple else base for base in bases) - types = ns.get('__annotations__', {}) - default_names = [] - for field_name in types: - if field_name in ns: - default_names.append(field_name) - elif default_names: - raise TypeError(f"Non-default namedtuple field {field_name} " - f"cannot follow default field" - f"{'s' if len(default_names) > 1 else ''} " - f"{', '.join(default_names)}") - nm_tpl = _make_nmtuple(typename, types.items(), - defaults=[ns[n] for n in default_names], - module=ns['__module__']) - nm_tpl.__bases__ = bases - if Generic in bases: - class_getitem = Generic.__class_getitem__.__func__ - nm_tpl.__class_getitem__ = classmethod(class_getitem) - # update from user namespace without overriding special namedtuple attributes - for key in ns: - if key in _prohibited: - raise AttributeError("Cannot overwrite NamedTuple attribute " + key) - elif key not in _special and key not in nm_tpl._fields: - setattr(nm_tpl, key, ns[key]) - if Generic in bases: - nm_tpl.__init_subclass__() - return nm_tpl - - -def NamedTuple(typename, fields=None, /, **kwargs): - """Typed version of namedtuple. - - Usage in Python versions >= 3.6:: - - class Employee(NamedTuple): - name: str - id: int - - This is equivalent to:: - - Employee = collections.namedtuple('Employee', ['name', 'id']) - - The resulting class has an extra __annotations__ attribute, giving a - dict that maps field names to types. (The field names are also in - the _fields attribute, which is part of the namedtuple API.) - Alternative equivalent keyword syntax is also accepted:: - - Employee = NamedTuple('Employee', name=str, id=int) - - In Python versions <= 3.5 use:: - - Employee = NamedTuple('Employee', [('name', str), ('id', int)]) - """ - if fields is None: - fields = kwargs.items() - elif kwargs: - raise TypeError("Either list of fields or keywords" - " can be provided to NamedTuple, not both") - return _make_nmtuple(typename, fields, module=_caller()) - -_NamedTuple = type.__new__(NamedTupleMeta, 'NamedTuple', (), {}) - -def _namedtuple_mro_entries(bases): - assert NamedTuple in bases - return (_NamedTuple,) - -NamedTuple.__mro_entries__ = _namedtuple_mro_entries - - -class _TypedDictMeta(type): - def __new__(cls, name, bases, ns, total=True): - """Create new typed dict class object. - - This method is called when TypedDict is subclassed, - or when TypedDict is instantiated. This way - TypedDict supports all three syntax forms described in its docstring. - Subclasses and instances of TypedDict return actual dictionaries. - """ - for base in bases: - if type(base) is not _TypedDictMeta and base is not Generic: - raise TypeError('cannot inherit from both a TypedDict type ' - 'and a non-TypedDict base class') - - if any(issubclass(b, Generic) for b in bases): - generic_base = (Generic,) - else: - generic_base = () - - tp_dict = type.__new__(_TypedDictMeta, name, (*generic_base, dict), ns) - - annotations = {} - own_annotations = ns.get('__annotations__', {}) - msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" - own_annotations = { - n: _type_check(tp, msg, module=tp_dict.__module__) - for n, tp in own_annotations.items() - } - required_keys = set() - optional_keys = set() - - for base in bases: - annotations.update(base.__dict__.get('__annotations__', {})) - required_keys.update(base.__dict__.get('__required_keys__', ())) - optional_keys.update(base.__dict__.get('__optional_keys__', ())) - - annotations.update(own_annotations) - for annotation_key, annotation_type in own_annotations.items(): - annotation_origin = get_origin(annotation_type) - if annotation_origin is Annotated: - annotation_args = get_args(annotation_type) - if annotation_args: - annotation_type = annotation_args[0] - annotation_origin = get_origin(annotation_type) - - if annotation_origin is Required: - required_keys.add(annotation_key) - elif annotation_origin is NotRequired: - optional_keys.add(annotation_key) - elif total: - required_keys.add(annotation_key) - else: - optional_keys.add(annotation_key) - - tp_dict.__annotations__ = annotations - tp_dict.__required_keys__ = frozenset(required_keys) - tp_dict.__optional_keys__ = frozenset(optional_keys) - if not hasattr(tp_dict, '__total__'): - tp_dict.__total__ = total - return tp_dict - - __call__ = dict # static method - - def __subclasscheck__(cls, other): - # Typed dicts are only for static structural subtyping. - raise TypeError('TypedDict does not support instance and class checks') - - __instancecheck__ = __subclasscheck__ - - -def TypedDict(typename, fields=None, /, *, total=True, **kwargs): - """A simple typed namespace. At runtime it is equivalent to a plain dict. - - TypedDict creates a dictionary type that expects all of its - instances to have a certain set of keys, where each key is - associated with a value of a consistent type. This expectation - is not checked at runtime but is only enforced by type checkers. - Usage:: - - class Point2D(TypedDict): - x: int - y: int - label: str - - a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK - b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check - - assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') - - The type info can be accessed via the Point2D.__annotations__ dict, and - the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets. - TypedDict supports an additional equivalent form:: - - Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) - - By default, all keys must be present in a TypedDict. It is possible - to override this by specifying totality. - Usage:: - - class point2D(TypedDict, total=False): - x: int - y: int - - This means that a point2D TypedDict can have any of the keys omitted.A type - checker is only expected to support a literal False or True as the value of - the total argument. True is the default, and makes all items defined in the - class body be required. - - The class syntax is only supported in Python 3.6+, while the other - syntax form works for Python 2.7 and 3.2+ - """ - if fields is None: - fields = kwargs - elif kwargs: - raise TypeError("TypedDict takes either a dict or keyword arguments," - " but not both") - if kwargs: - warnings.warn( - "The kwargs-based syntax for TypedDict definitions is deprecated " - "in Python 3.11, will be removed in Python 3.13, and may not be " - "understood by third-party type checkers.", - DeprecationWarning, - stacklevel=2, - ) - - ns = {'__annotations__': dict(fields)} - module = _caller() - if module is not None: - # Setting correct module is necessary to make typed dict classes pickleable. - ns['__module__'] = module - - return _TypedDictMeta(typename, (), ns, total=total) - -_TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {}) -TypedDict.__mro_entries__ = lambda bases: (_TypedDict,) - - -@_SpecialForm -def Required(self, parameters): - """A special typing construct to mark a key of a total=False TypedDict - as required. For example: - - class Movie(TypedDict, total=False): - title: Required[str] - year: int - - m = Movie( - title='The Matrix', # typechecker error if key is omitted - year=1999, - ) - - There is no runtime checking that a required key is actually provided - when instantiating a related TypedDict. - """ - item = _type_check(parameters, f'{self._name} accepts only a single type.') - return _GenericAlias(self, (item,)) - - -@_SpecialForm -def NotRequired(self, parameters): - """A special typing construct to mark a key of a TypedDict as - potentially missing. For example: - - class Movie(TypedDict): - title: str - year: NotRequired[int] - - m = Movie( - title='The Matrix', # typechecker error if key is omitted - year=1999, - ) - """ - item = _type_check(parameters, f'{self._name} accepts only a single type.') - return _GenericAlias(self, (item,)) - - -class NewType: - """NewType creates simple unique types with almost zero - runtime overhead. NewType(name, tp) is considered a subtype of tp - by static type checkers. At runtime, NewType(name, tp) returns - a dummy callable that simply returns its argument. Usage:: - - UserId = NewType('UserId', int) - - def name_by_id(user_id: UserId) -> str: - ... - - UserId('user') # Fails type check - - name_by_id(42) # Fails type check - name_by_id(UserId(42)) # OK - - num = UserId(5) + 1 # type: int - """ - - __call__ = _idfunc - - def __init__(self, name, tp): - self.__qualname__ = name - if '.' in name: - name = name.rpartition('.')[-1] - self.__name__ = name - self.__supertype__ = tp - def_mod = _caller() - if def_mod != 'typing': - self.__module__ = def_mod - - def __mro_entries__(self, bases): - # We defined __mro_entries__ to get a better error message - # if a user attempts to subclass a NewType instance. bpo-46170 - superclass_name = self.__name__ - - class Dummy: - def __init_subclass__(cls): - subclass_name = cls.__name__ - raise TypeError( - f"Cannot subclass an instance of NewType. Perhaps you were looking for: " - f"`{subclass_name} = NewType({subclass_name!r}, {superclass_name})`" - ) - - return (Dummy,) - - def __repr__(self): - return f'{self.__module__}.{self.__qualname__}' - - def __reduce__(self): - return self.__qualname__ - - def __or__(self, other): - return Union[self, other] - - def __ror__(self, other): - return Union[other, self] - - -# Python-version-specific alias (Python 2: unicode; Python 3: str) -Text = str - - -# Constant that's True when type checking, but False here. -TYPE_CHECKING = False - - -class IO(Generic[AnyStr]): - """Generic base class for TextIO and BinaryIO. - - This is an abstract, generic version of the return of open(). - - NOTE: This does not distinguish between the different possible - classes (text vs. binary, read vs. write vs. read/write, - append-only, unbuffered). The TextIO and BinaryIO subclasses - below capture the distinctions between text vs. binary, which is - pervasive in the interface; however we currently do not offer a - way to track the other distinctions in the type system. - """ - - __slots__ = () - - @property - @abstractmethod - def mode(self) -> str: - pass - - @property - @abstractmethod - def name(self) -> str: - pass - - @abstractmethod - def close(self) -> None: - pass - - @property - @abstractmethod - def closed(self) -> bool: - pass - - @abstractmethod - def fileno(self) -> int: - pass - - @abstractmethod - def flush(self) -> None: - pass - - @abstractmethod - def isatty(self) -> bool: - pass - - @abstractmethod - def read(self, n: int = -1) -> AnyStr: - pass - - @abstractmethod - def readable(self) -> bool: - pass - - @abstractmethod - def readline(self, limit: int = -1) -> AnyStr: - pass - - @abstractmethod - def readlines(self, hint: int = -1) -> List[AnyStr]: - pass - - @abstractmethod - def seek(self, offset: int, whence: int = 0) -> int: - pass - - @abstractmethod - def seekable(self) -> bool: - pass - - @abstractmethod - def tell(self) -> int: - pass - - @abstractmethod - def truncate(self, size: int = None) -> int: - pass - - @abstractmethod - def writable(self) -> bool: - pass - - @abstractmethod - def write(self, s: AnyStr) -> int: - pass - - @abstractmethod - def writelines(self, lines: List[AnyStr]) -> None: - pass - - @abstractmethod - def __enter__(self) -> 'IO[AnyStr]': - pass - - @abstractmethod - def __exit__(self, type, value, traceback) -> None: - pass - - -class BinaryIO(IO[bytes]): - """Typed version of the return of open() in binary mode.""" - - __slots__ = () - - @abstractmethod - def write(self, s: Union[bytes, bytearray]) -> int: - pass - - @abstractmethod - def __enter__(self) -> 'BinaryIO': - pass - - -class TextIO(IO[str]): - """Typed version of the return of open() in text mode.""" - - __slots__ = () - - @property - @abstractmethod - def buffer(self) -> BinaryIO: - pass - - @property - @abstractmethod - def encoding(self) -> str: - pass - - @property - @abstractmethod - def errors(self) -> Optional[str]: - pass - - @property - @abstractmethod - def line_buffering(self) -> bool: - pass - - @property - @abstractmethod - def newlines(self) -> Any: - pass - - @abstractmethod - def __enter__(self) -> 'TextIO': - pass - - -class _DeprecatedType(type): - def __getattribute__(cls, name): - if name not in ("__dict__", "__module__") and name in cls.__dict__: - warnings.warn( - f"{cls.__name__} is deprecated, import directly " - f"from typing instead. {cls.__name__} will be removed " - "in Python 3.12.", - DeprecationWarning, - stacklevel=2, - ) - return super().__getattribute__(name) - - -class io(metaclass=_DeprecatedType): - """Wrapper namespace for IO generic classes.""" - - __all__ = ['IO', 'TextIO', 'BinaryIO'] - IO = IO - TextIO = TextIO - BinaryIO = BinaryIO - - -io.__name__ = __name__ + '.io' -sys.modules[io.__name__] = io - -Pattern = _alias(stdlib_re.Pattern, 1) -Match = _alias(stdlib_re.Match, 1) - -class re(metaclass=_DeprecatedType): - """Wrapper namespace for re type aliases.""" - - __all__ = ['Pattern', 'Match'] - Pattern = Pattern - Match = Match - - -re.__name__ = __name__ + '.re' -sys.modules[re.__name__] = re - - -def reveal_type(obj: T, /) -> T: - """Reveal the inferred type of a variable. - - When a static type checker encounters a call to ``reveal_type()``, - it will emit the inferred type of the argument:: - - x: int = 1 - reveal_type(x) - - Running a static type checker (e.g., ``mypy``) on this example - will produce output similar to 'Revealed type is "builtins.int"'. - - At runtime, the function prints the runtime type of the - argument and returns it unchanged. - - """ - print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr) - return obj - - -def dataclass_transform( - *, - eq_default: bool = True, - order_default: bool = False, - kw_only_default: bool = False, - field_specifiers: tuple[type[Any] | Callable[..., Any], ...] = (), - **kwargs: Any, -) -> Callable[[T], T]: - """Decorator that marks a function, class, or metaclass as providing - dataclass-like behavior. - - Example usage with a decorator function: - - T = TypeVar("T") - - @dataclass_transform() - def create_model(cls: type[T]) -> type[T]: - ... - return cls - - @create_model - class CustomerModel: - id: int - name: str - - On a base class: - - @dataclass_transform() - class ModelBase: ... - - class CustomerModel(ModelBase): - id: int - name: str - - On a metaclass: - - @dataclass_transform() - class ModelMeta(type): ... - - class ModelBase(metaclass=ModelMeta): ... - - class CustomerModel(ModelBase): - id: int - name: str - - The ``CustomerModel`` classes defined above will - be treated by type checkers similarly to classes created with - ``@dataclasses.dataclass``. - For example, type checkers will assume these classes have - ``__init__`` methods that accept ``id`` and ``name``. - - The arguments to this decorator can be used to customize this behavior: - - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be - ``True`` or ``False`` if it is omitted by the caller. - - ``order_default`` indicates whether the ``order`` parameter is - assumed to be True or False if it is omitted by the caller. - - ``kw_only_default`` indicates whether the ``kw_only`` parameter is - assumed to be True or False if it is omitted by the caller. - - ``field_specifiers`` specifies a static list of supported classes - or functions that describe fields, similar to ``dataclasses.field()``. - - Arbitrary other keyword arguments are accepted in order to allow for - possible future extensions. - - At runtime, this decorator records its arguments in the - ``__dataclass_transform__`` attribute on the decorated object. - It has no other runtime effect. - - See PEP 681 for more details. - """ - def decorator(cls_or_fn): - cls_or_fn.__dataclass_transform__ = { - "eq_default": eq_default, - "order_default": order_default, - "kw_only_default": kw_only_default, - "field_specifiers": field_specifiers, - "kwargs": kwargs, - } - return cls_or_fn - return decorator diff --git a/python/Lib/uuid.py b/python/Lib/uuid.py deleted file mode 100644 index 66de0e3..0000000 --- a/python/Lib/uuid.py +++ /dev/null @@ -1,736 +0,0 @@ -r"""UUID objects (universally unique identifiers) according to RFC 4122. - -This module provides immutable UUID objects (class UUID) and the functions -uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5 -UUIDs as specified in RFC 4122. - -If all you want is a unique ID, you should probably call uuid1() or uuid4(). -Note that uuid1() may compromise privacy since it creates a UUID containing -the computer's network address. uuid4() creates a random UUID. - -Typical usage: - - >>> import uuid - - # make a UUID based on the host ID and current time - >>> uuid.uuid1() # doctest: +SKIP - UUID('a8098c1a-f86e-11da-bd1a-00112444be1e') - - # make a UUID using an MD5 hash of a namespace UUID and a name - >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org') - UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e') - - # make a random UUID - >>> uuid.uuid4() # doctest: +SKIP - UUID('16fd2706-8baf-433b-82eb-8c7fada847da') - - # make a UUID using a SHA-1 hash of a namespace UUID and a name - >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org') - UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d') - - # make a UUID from a string of hex digits (braces and hyphens ignored) - >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}') - - # convert a UUID to a string of hex digits in standard form - >>> str(x) - '00010203-0405-0607-0809-0a0b0c0d0e0f' - - # get the raw 16 bytes of the UUID - >>> x.bytes - b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f' - - # make a UUID from a 16-byte string - >>> uuid.UUID(bytes=x.bytes) - UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') -""" - -import os -import sys - -from enum import Enum, _simple_enum - - -__author__ = 'Ka-Ping Yee ' - -# The recognized platforms - known behaviors -if sys.platform in ('win32', 'darwin'): - _AIX = _LINUX = False -else: - import platform - _platform_system = platform.system() - _AIX = _platform_system == 'AIX' - _LINUX = _platform_system == 'Linux' - -_MAC_DELIM = b':' -_MAC_OMITS_LEADING_ZEROES = False -if _AIX: - _MAC_DELIM = b'.' - _MAC_OMITS_LEADING_ZEROES = True - -RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ - 'reserved for NCS compatibility', 'specified in RFC 4122', - 'reserved for Microsoft compatibility', 'reserved for future definition'] - -int_ = int # The built-in int type -bytes_ = bytes # The built-in bytes type - - -@_simple_enum(Enum) -class SafeUUID: - safe = 0 - unsafe = -1 - unknown = None - - -class UUID: - """Instances of the UUID class represent UUIDs as specified in RFC 4122. - UUID objects are immutable, hashable, and usable as dictionary keys. - Converting a UUID to a string with str() yields something in the form - '12345678-1234-1234-1234-123456789abc'. The UUID constructor accepts - five possible forms: a similar string of hexadecimal digits, or a tuple - of six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and - 48-bit values respectively) as an argument named 'fields', or a string - of 16 bytes (with all the integer fields in big-endian order) as an - argument named 'bytes', or a string of 16 bytes (with the first three - fields in little-endian order) as an argument named 'bytes_le', or a - single 128-bit integer as an argument named 'int'. - - UUIDs have these read-only attributes: - - bytes the UUID as a 16-byte string (containing the six - integer fields in big-endian byte order) - - bytes_le the UUID as a 16-byte string (with time_low, time_mid, - and time_hi_version in little-endian byte order) - - fields a tuple of the six integer fields of the UUID, - which are also available as six individual attributes - and two derived attributes: - - time_low the first 32 bits of the UUID - time_mid the next 16 bits of the UUID - time_hi_version the next 16 bits of the UUID - clock_seq_hi_variant the next 8 bits of the UUID - clock_seq_low the next 8 bits of the UUID - node the last 48 bits of the UUID - - time the 60-bit timestamp - clock_seq the 14-bit sequence number - - hex the UUID as a 32-character hexadecimal string - - int the UUID as a 128-bit integer - - urn the UUID as a URN as specified in RFC 4122 - - variant the UUID variant (one of the constants RESERVED_NCS, - RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE) - - version the UUID version number (1 through 5, meaningful only - when the variant is RFC_4122) - - is_safe An enum indicating whether the UUID has been generated in - a way that is safe for multiprocessing applications, via - uuid_generate_time_safe(3). - """ - - __slots__ = ('int', 'is_safe', '__weakref__') - - def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None, - int=None, version=None, - *, is_safe=SafeUUID.unknown): - r"""Create a UUID from either a string of 32 hexadecimal digits, - a string of 16 bytes as the 'bytes' argument, a string of 16 bytes - in little-endian order as the 'bytes_le' argument, a tuple of six - integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version, - 8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as - the 'fields' argument, or a single 128-bit integer as the 'int' - argument. When a string of hex digits is given, curly braces, - hyphens, and a URN prefix are all optional. For example, these - expressions all yield the same UUID: - - UUID('{12345678-1234-5678-1234-567812345678}') - UUID('12345678123456781234567812345678') - UUID('urn:uuid:12345678-1234-5678-1234-567812345678') - UUID(bytes='\x12\x34\x56\x78'*4) - UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' + - '\x12\x34\x56\x78\x12\x34\x56\x78') - UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678)) - UUID(int=0x12345678123456781234567812345678) - - Exactly one of 'hex', 'bytes', 'bytes_le', 'fields', or 'int' must - be given. The 'version' argument is optional; if given, the resulting - UUID will have its variant and version set according to RFC 4122, - overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. - - is_safe is an enum exposed as an attribute on the instance. It - indicates whether the UUID has been generated in a way that is safe - for multiprocessing applications, via uuid_generate_time_safe(3). - """ - - if [hex, bytes, bytes_le, fields, int].count(None) != 4: - raise TypeError('one of the hex, bytes, bytes_le, fields, ' - 'or int arguments must be given') - if hex is not None: - hex = hex.replace('urn:', '').replace('uuid:', '') - hex = hex.strip('{}').replace('-', '') - if len(hex) != 32: - raise ValueError('badly formed hexadecimal UUID string') - int = int_(hex, 16) - if bytes_le is not None: - if len(bytes_le) != 16: - raise ValueError('bytes_le is not a 16-char string') - bytes = (bytes_le[4-1::-1] + bytes_le[6-1:4-1:-1] + - bytes_le[8-1:6-1:-1] + bytes_le[8:]) - if bytes is not None: - if len(bytes) != 16: - raise ValueError('bytes is not a 16-char string') - assert isinstance(bytes, bytes_), repr(bytes) - int = int_.from_bytes(bytes) # big endian - if fields is not None: - if len(fields) != 6: - raise ValueError('fields is not a 6-tuple') - (time_low, time_mid, time_hi_version, - clock_seq_hi_variant, clock_seq_low, node) = fields - if not 0 <= time_low < 1<<32: - raise ValueError('field 1 out of range (need a 32-bit value)') - if not 0 <= time_mid < 1<<16: - raise ValueError('field 2 out of range (need a 16-bit value)') - if not 0 <= time_hi_version < 1<<16: - raise ValueError('field 3 out of range (need a 16-bit value)') - if not 0 <= clock_seq_hi_variant < 1<<8: - raise ValueError('field 4 out of range (need an 8-bit value)') - if not 0 <= clock_seq_low < 1<<8: - raise ValueError('field 5 out of range (need an 8-bit value)') - if not 0 <= node < 1<<48: - raise ValueError('field 6 out of range (need a 48-bit value)') - clock_seq = (clock_seq_hi_variant << 8) | clock_seq_low - int = ((time_low << 96) | (time_mid << 80) | - (time_hi_version << 64) | (clock_seq << 48) | node) - if int is not None: - if not 0 <= int < 1<<128: - raise ValueError('int is out of range (need a 128-bit value)') - if version is not None: - if not 1 <= version <= 5: - raise ValueError('illegal version number') - # Set the variant to RFC 4122. - int &= ~(0xc000 << 48) - int |= 0x8000 << 48 - # Set the version number. - int &= ~(0xf000 << 64) - int |= version << 76 - object.__setattr__(self, 'int', int) - object.__setattr__(self, 'is_safe', is_safe) - - def __getstate__(self): - d = {'int': self.int} - if self.is_safe != SafeUUID.unknown: - # is_safe is a SafeUUID instance. Return just its value, so that - # it can be un-pickled in older Python versions without SafeUUID. - d['is_safe'] = self.is_safe.value - return d - - def __setstate__(self, state): - object.__setattr__(self, 'int', state['int']) - # is_safe was added in 3.7; it is also omitted when it is "unknown" - object.__setattr__(self, 'is_safe', - SafeUUID(state['is_safe']) - if 'is_safe' in state else SafeUUID.unknown) - - def __eq__(self, other): - if isinstance(other, UUID): - return self.int == other.int - return NotImplemented - - # Q. What's the value of being able to sort UUIDs? - # A. Use them as keys in a B-Tree or similar mapping. - - def __lt__(self, other): - if isinstance(other, UUID): - return self.int < other.int - return NotImplemented - - def __gt__(self, other): - if isinstance(other, UUID): - return self.int > other.int - return NotImplemented - - def __le__(self, other): - if isinstance(other, UUID): - return self.int <= other.int - return NotImplemented - - def __ge__(self, other): - if isinstance(other, UUID): - return self.int >= other.int - return NotImplemented - - def __hash__(self): - return hash(self.int) - - def __int__(self): - return self.int - - def __repr__(self): - return '%s(%r)' % (self.__class__.__name__, str(self)) - - def __setattr__(self, name, value): - raise TypeError('UUID objects are immutable') - - def __str__(self): - hex = '%032x' % self.int - return '%s-%s-%s-%s-%s' % ( - hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:]) - - @property - def bytes(self): - return self.int.to_bytes(16) # big endian - - @property - def bytes_le(self): - bytes = self.bytes - return (bytes[4-1::-1] + bytes[6-1:4-1:-1] + bytes[8-1:6-1:-1] + - bytes[8:]) - - @property - def fields(self): - return (self.time_low, self.time_mid, self.time_hi_version, - self.clock_seq_hi_variant, self.clock_seq_low, self.node) - - @property - def time_low(self): - return self.int >> 96 - - @property - def time_mid(self): - return (self.int >> 80) & 0xffff - - @property - def time_hi_version(self): - return (self.int >> 64) & 0xffff - - @property - def clock_seq_hi_variant(self): - return (self.int >> 56) & 0xff - - @property - def clock_seq_low(self): - return (self.int >> 48) & 0xff - - @property - def time(self): - return (((self.time_hi_version & 0x0fff) << 48) | - (self.time_mid << 32) | self.time_low) - - @property - def clock_seq(self): - return (((self.clock_seq_hi_variant & 0x3f) << 8) | - self.clock_seq_low) - - @property - def node(self): - return self.int & 0xffffffffffff - - @property - def hex(self): - return '%032x' % self.int - - @property - def urn(self): - return 'urn:uuid:' + str(self) - - @property - def variant(self): - if not self.int & (0x8000 << 48): - return RESERVED_NCS - elif not self.int & (0x4000 << 48): - return RFC_4122 - elif not self.int & (0x2000 << 48): - return RESERVED_MICROSOFT - else: - return RESERVED_FUTURE - - @property - def version(self): - # The version bits are only meaningful for RFC 4122 UUIDs. - if self.variant == RFC_4122: - return int((self.int >> 76) & 0xf) - - -def _get_command_stdout(command, *args): - import io, os, shutil, subprocess - - try: - path_dirs = os.environ.get('PATH', os.defpath).split(os.pathsep) - path_dirs.extend(['/sbin', '/usr/sbin']) - executable = shutil.which(command, path=os.pathsep.join(path_dirs)) - if executable is None: - return None - # LC_ALL=C to ensure English output, stderr=DEVNULL to prevent output - # on stderr (Note: we don't have an example where the words we search - # for are actually localized, but in theory some system could do so.) - env = dict(os.environ) - env['LC_ALL'] = 'C' - # Empty strings will be quoted by popen so we should just ommit it - if args != ('',): - command = (executable, *args) - else: - command = (executable,) - proc = subprocess.Popen(command, - stdout=subprocess.PIPE, - stderr=subprocess.DEVNULL, - env=env) - if not proc: - return None - stdout, stderr = proc.communicate() - return io.BytesIO(stdout) - except (OSError, subprocess.SubprocessError): - return None - - -# For MAC (a.k.a. IEEE 802, or EUI-48) addresses, the second least significant -# bit of the first octet signifies whether the MAC address is universally (0) -# or locally (1) administered. Network cards from hardware manufacturers will -# always be universally administered to guarantee global uniqueness of the MAC -# address, but any particular machine may have other interfaces which are -# locally administered. An example of the latter is the bridge interface to -# the Touch Bar on MacBook Pros. -# -# This bit works out to be the 42nd bit counting from 1 being the least -# significant, or 1<<41. We'll prefer universally administered MAC addresses -# over locally administered ones since the former are globally unique, but -# we'll return the first of the latter found if that's all the machine has. -# -# See https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local - -def _is_universal(mac): - return not (mac & (1 << 41)) - - -def _find_mac_near_keyword(command, args, keywords, get_word_index): - """Searches a command's output for a MAC address near a keyword. - - Each line of words in the output is case-insensitively searched for - any of the given keywords. Upon a match, get_word_index is invoked - to pick a word from the line, given the index of the match. For - example, lambda i: 0 would get the first word on the line, while - lambda i: i - 1 would get the word preceding the keyword. - """ - stdout = _get_command_stdout(command, args) - if stdout is None: - return None - - first_local_mac = None - for line in stdout: - words = line.lower().rstrip().split() - for i in range(len(words)): - if words[i] in keywords: - try: - word = words[get_word_index(i)] - mac = int(word.replace(_MAC_DELIM, b''), 16) - except (ValueError, IndexError): - # Virtual interfaces, such as those provided by - # VPNs, do not have a colon-delimited MAC address - # as expected, but a 16-byte HWAddr separated by - # dashes. These should be ignored in favor of a - # real MAC address - pass - else: - if _is_universal(mac): - return mac - first_local_mac = first_local_mac or mac - return first_local_mac or None - - -def _parse_mac(word): - # Accept 'HH:HH:HH:HH:HH:HH' MAC address (ex: '52:54:00:9d:0e:67'), - # but reject IPv6 address (ex: 'fe80::5054:ff:fe9' or '123:2:3:4:5:6:7:8'). - # - # Virtual interfaces, such as those provided by VPNs, do not have a - # colon-delimited MAC address as expected, but a 16-byte HWAddr separated - # by dashes. These should be ignored in favor of a real MAC address - parts = word.split(_MAC_DELIM) - if len(parts) != 6: - return - if _MAC_OMITS_LEADING_ZEROES: - # (Only) on AIX the macaddr value given is not prefixed by 0, e.g. - # en0 1500 link#2 fa.bc.de.f7.62.4 110854824 0 160133733 0 0 - # not - # en0 1500 link#2 fa.bc.de.f7.62.04 110854824 0 160133733 0 0 - if not all(1 <= len(part) <= 2 for part in parts): - return - hexstr = b''.join(part.rjust(2, b'0') for part in parts) - else: - if not all(len(part) == 2 for part in parts): - return - hexstr = b''.join(parts) - try: - return int(hexstr, 16) - except ValueError: - return - - -def _find_mac_under_heading(command, args, heading): - """Looks for a MAC address under a heading in a command's output. - - The first line of words in the output is searched for the given - heading. Words at the same word index as the heading in subsequent - lines are then examined to see if they look like MAC addresses. - """ - stdout = _get_command_stdout(command, args) - if stdout is None: - return None - - keywords = stdout.readline().rstrip().split() - try: - column_index = keywords.index(heading) - except ValueError: - return None - - first_local_mac = None - for line in stdout: - words = line.rstrip().split() - try: - word = words[column_index] - except IndexError: - continue - - mac = _parse_mac(word) - if mac is None: - continue - if _is_universal(mac): - return mac - if first_local_mac is None: - first_local_mac = mac - - return first_local_mac - - -# The following functions call external programs to 'get' a macaddr value to -# be used as basis for an uuid -def _ifconfig_getnode(): - """Get the hardware address on Unix by running ifconfig.""" - # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes. - keywords = (b'hwaddr', b'ether', b'address:', b'lladdr') - for args in ('', '-a', '-av'): - mac = _find_mac_near_keyword('ifconfig', args, keywords, lambda i: i+1) - if mac: - return mac - return None - -def _ip_getnode(): - """Get the hardware address on Unix by running ip.""" - # This works on Linux with iproute2. - mac = _find_mac_near_keyword('ip', 'link', [b'link/ether'], lambda i: i+1) - if mac: - return mac - return None - -def _arp_getnode(): - """Get the hardware address on Unix by running arp.""" - import os, socket - if not hasattr(socket, "gethostbyname"): - return None - try: - ip_addr = socket.gethostbyname(socket.gethostname()) - except OSError: - return None - - # Try getting the MAC addr from arp based on our IP address (Solaris). - mac = _find_mac_near_keyword('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1) - if mac: - return mac - - # This works on OpenBSD - mac = _find_mac_near_keyword('arp', '-an', [os.fsencode(ip_addr)], lambda i: i+1) - if mac: - return mac - - # This works on Linux, FreeBSD and NetBSD - mac = _find_mac_near_keyword('arp', '-an', [os.fsencode('(%s)' % ip_addr)], - lambda i: i+2) - # Return None instead of 0. - if mac: - return mac - return None - -def _lanscan_getnode(): - """Get the hardware address on Unix by running lanscan.""" - # This might work on HP-UX. - return _find_mac_near_keyword('lanscan', '-ai', [b'lan0'], lambda i: 0) - -def _netstat_getnode(): - """Get the hardware address on Unix by running netstat.""" - # This works on AIX and might work on Tru64 UNIX. - return _find_mac_under_heading('netstat', '-ian', b'Address') - -def _ipconfig_getnode(): - """[DEPRECATED] Get the hardware address on Windows.""" - # bpo-40501: UuidCreateSequential() is now the only supported approach - return _windll_getnode() - -def _netbios_getnode(): - """[DEPRECATED] Get the hardware address on Windows.""" - # bpo-40501: UuidCreateSequential() is now the only supported approach - return _windll_getnode() - - -# Import optional C extension at toplevel, to help disabling it when testing -try: - import _uuid - _generate_time_safe = getattr(_uuid, "generate_time_safe", None) - _UuidCreate = getattr(_uuid, "UuidCreate", None) - _has_uuid_generate_time_safe = _uuid.has_uuid_generate_time_safe -except ImportError: - _uuid = None - _generate_time_safe = None - _UuidCreate = None - _has_uuid_generate_time_safe = None - - -def _load_system_functions(): - """[DEPRECATED] Platform-specific functions loaded at import time""" - - -def _unix_getnode(): - """Get the hardware address on Unix using the _uuid extension module.""" - if _generate_time_safe: - uuid_time, _ = _generate_time_safe() - return UUID(bytes=uuid_time).node - -def _windll_getnode(): - """Get the hardware address on Windows using the _uuid extension module.""" - if _UuidCreate: - uuid_bytes = _UuidCreate() - return UUID(bytes_le=uuid_bytes).node - -def _random_getnode(): - """Get a random node ID.""" - # RFC 4122, $4.1.6 says "For systems with no IEEE address, a randomly or - # pseudo-randomly generated value may be used; see Section 4.5. The - # multicast bit must be set in such addresses, in order that they will - # never conflict with addresses obtained from network cards." - # - # The "multicast bit" of a MAC address is defined to be "the least - # significant bit of the first octet". This works out to be the 41st bit - # counting from 1 being the least significant bit, or 1<<40. - # - # See https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast - import random - return random.getrandbits(48) | (1 << 40) - - -# _OS_GETTERS, when known, are targeted for a specific OS or platform. -# The order is by 'common practice' on the specified platform. -# Note: 'posix' and 'windows' _OS_GETTERS are prefixed by a dll/dlload() method -# which, when successful, means none of these "external" methods are called. -# _GETTERS is (also) used by test_uuid.py to SkipUnless(), e.g., -# @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS, ...) -if _LINUX: - _OS_GETTERS = [_ip_getnode, _ifconfig_getnode] -elif sys.platform == 'darwin': - _OS_GETTERS = [_ifconfig_getnode, _arp_getnode, _netstat_getnode] -elif sys.platform == 'win32': - # bpo-40201: _windll_getnode will always succeed, so these are not needed - _OS_GETTERS = [] -elif _AIX: - _OS_GETTERS = [_netstat_getnode] -else: - _OS_GETTERS = [_ifconfig_getnode, _ip_getnode, _arp_getnode, - _netstat_getnode, _lanscan_getnode] -if os.name == 'posix': - _GETTERS = [_unix_getnode] + _OS_GETTERS -elif os.name == 'nt': - _GETTERS = [_windll_getnode] + _OS_GETTERS -else: - _GETTERS = _OS_GETTERS - -_node = None - -def getnode(): - """Get the hardware address as a 48-bit positive integer. - - The first time this runs, it may launch a separate program, which could - be quite slow. If all attempts to obtain the hardware address fail, we - choose a random 48-bit number with its eighth bit set to 1 as recommended - in RFC 4122. - """ - global _node - if _node is not None: - return _node - - for getter in _GETTERS + [_random_getnode]: - try: - _node = getter() - except: - continue - if (_node is not None) and (0 <= _node < (1 << 48)): - return _node - assert False, '_random_getnode() returned invalid value: {}'.format(_node) - - -_last_timestamp = None - -def uuid1(node=None, clock_seq=None): - """Generate a UUID from a host ID, sequence number, and the current time. - If 'node' is not given, getnode() is used to obtain the hardware - address. If 'clock_seq' is given, it is used as the sequence number; - otherwise a random 14-bit sequence number is chosen.""" - - # When the system provides a version-1 UUID generator, use it (but don't - # use UuidCreate here because its UUIDs don't conform to RFC 4122). - if _generate_time_safe is not None and node is clock_seq is None: - uuid_time, safely_generated = _generate_time_safe() - try: - is_safe = SafeUUID(safely_generated) - except ValueError: - is_safe = SafeUUID.unknown - return UUID(bytes=uuid_time, is_safe=is_safe) - - global _last_timestamp - import time - nanoseconds = time.time_ns() - # 0x01b21dd213814000 is the number of 100-ns intervals between the - # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00. - timestamp = nanoseconds // 100 + 0x01b21dd213814000 - if _last_timestamp is not None and timestamp <= _last_timestamp: - timestamp = _last_timestamp + 1 - _last_timestamp = timestamp - if clock_seq is None: - import random - clock_seq = random.getrandbits(14) # instead of stable storage - time_low = timestamp & 0xffffffff - time_mid = (timestamp >> 32) & 0xffff - time_hi_version = (timestamp >> 48) & 0x0fff - clock_seq_low = clock_seq & 0xff - clock_seq_hi_variant = (clock_seq >> 8) & 0x3f - if node is None: - node = getnode() - return UUID(fields=(time_low, time_mid, time_hi_version, - clock_seq_hi_variant, clock_seq_low, node), version=1) - -def uuid3(namespace, name): - """Generate a UUID from the MD5 hash of a namespace UUID and a name.""" - from hashlib import md5 - digest = md5( - namespace.bytes + bytes(name, "utf-8"), - usedforsecurity=False - ).digest() - return UUID(bytes=digest[:16], version=3) - -def uuid4(): - """Generate a random UUID.""" - return UUID(bytes=os.urandom(16), version=4) - -def uuid5(namespace, name): - """Generate a UUID from the SHA-1 hash of a namespace UUID and a name.""" - from hashlib import sha1 - hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest() - return UUID(bytes=hash[:16], version=5) - -# The following standard UUIDs are for use with uuid3() or uuid5(). - -NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8') -NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8') -NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8') -NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8') diff --git a/python/Lib/warnings.py b/python/Lib/warnings.py deleted file mode 100644 index 49f28d2..0000000 --- a/python/Lib/warnings.py +++ /dev/null @@ -1,580 +0,0 @@ -"""Python part of the warnings subsystem.""" - -import sys - - -__all__ = ["warn", "warn_explicit", "showwarning", - "formatwarning", "filterwarnings", "simplefilter", - "resetwarnings", "catch_warnings"] - -def showwarning(message, category, filename, lineno, file=None, line=None): - """Hook to write a warning to a file; replace if you like.""" - msg = WarningMessage(message, category, filename, lineno, file, line) - _showwarnmsg_impl(msg) - -def formatwarning(message, category, filename, lineno, line=None): - """Function to format a warning the standard way.""" - msg = WarningMessage(message, category, filename, lineno, None, line) - return _formatwarnmsg_impl(msg) - -def _showwarnmsg_impl(msg): - file = msg.file - if file is None: - file = sys.stderr - if file is None: - # sys.stderr is None when run with pythonw.exe: - # warnings get lost - return - text = _formatwarnmsg(msg) - try: - file.write(text) - except OSError: - # the file (probably stderr) is invalid - this warning gets lost. - pass - -def _formatwarnmsg_impl(msg): - category = msg.category.__name__ - s = f"{msg.filename}:{msg.lineno}: {category}: {msg.message}\n" - - if msg.line is None: - try: - import linecache - line = linecache.getline(msg.filename, msg.lineno) - except Exception: - # When a warning is logged during Python shutdown, linecache - # and the import machinery don't work anymore - line = None - linecache = None - else: - line = msg.line - if line: - line = line.strip() - s += " %s\n" % line - - if msg.source is not None: - try: - import tracemalloc - # Logging a warning should not raise a new exception: - # catch Exception, not only ImportError and RecursionError. - except Exception: - # don't suggest to enable tracemalloc if it's not available - tracing = True - tb = None - else: - tracing = tracemalloc.is_tracing() - try: - tb = tracemalloc.get_object_traceback(msg.source) - except Exception: - # When a warning is logged during Python shutdown, tracemalloc - # and the import machinery don't work anymore - tb = None - - if tb is not None: - s += 'Object allocated at (most recent call last):\n' - for frame in tb: - s += (' File "%s", lineno %s\n' - % (frame.filename, frame.lineno)) - - try: - if linecache is not None: - line = linecache.getline(frame.filename, frame.lineno) - else: - line = None - except Exception: - line = None - if line: - line = line.strip() - s += ' %s\n' % line - elif not tracing: - s += (f'{category}: Enable tracemalloc to get the object ' - f'allocation traceback\n') - return s - -# Keep a reference to check if the function was replaced -_showwarning_orig = showwarning - -def _showwarnmsg(msg): - """Hook to write a warning to a file; replace if you like.""" - try: - sw = showwarning - except NameError: - pass - else: - if sw is not _showwarning_orig: - # warnings.showwarning() was replaced - if not callable(sw): - raise TypeError("warnings.showwarning() must be set to a " - "function or method") - - sw(msg.message, msg.category, msg.filename, msg.lineno, - msg.file, msg.line) - return - _showwarnmsg_impl(msg) - -# Keep a reference to check if the function was replaced -_formatwarning_orig = formatwarning - -def _formatwarnmsg(msg): - """Function to format a warning the standard way.""" - try: - fw = formatwarning - except NameError: - pass - else: - if fw is not _formatwarning_orig: - # warnings.formatwarning() was replaced - return fw(msg.message, msg.category, - msg.filename, msg.lineno, msg.line) - return _formatwarnmsg_impl(msg) - -def filterwarnings(action, message="", category=Warning, module="", lineno=0, - append=False): - """Insert an entry into the list of warnings filters (at the front). - - 'action' -- one of "error", "ignore", "always", "default", "module", - or "once" - 'message' -- a regex that the warning message must match - 'category' -- a class that the warning must be a subclass of - 'module' -- a regex that the module name must match - 'lineno' -- an integer line number, 0 matches all warnings - 'append' -- if true, append to the list of filters - """ - assert action in ("error", "ignore", "always", "default", "module", - "once"), "invalid action: %r" % (action,) - assert isinstance(message, str), "message must be a string" - assert isinstance(category, type), "category must be a class" - assert issubclass(category, Warning), "category must be a Warning subclass" - assert isinstance(module, str), "module must be a string" - assert isinstance(lineno, int) and lineno >= 0, \ - "lineno must be an int >= 0" - - if message or module: - import re - - if message: - message = re.compile(message, re.I) - else: - message = None - if module: - module = re.compile(module) - else: - module = None - - _add_filter(action, message, category, module, lineno, append=append) - -def simplefilter(action, category=Warning, lineno=0, append=False): - """Insert a simple entry into the list of warnings filters (at the front). - - A simple filter matches all modules and messages. - 'action' -- one of "error", "ignore", "always", "default", "module", - or "once" - 'category' -- a class that the warning must be a subclass of - 'lineno' -- an integer line number, 0 matches all warnings - 'append' -- if true, append to the list of filters - """ - assert action in ("error", "ignore", "always", "default", "module", - "once"), "invalid action: %r" % (action,) - assert isinstance(lineno, int) and lineno >= 0, \ - "lineno must be an int >= 0" - _add_filter(action, None, category, None, lineno, append=append) - -def _add_filter(*item, append): - # Remove possible duplicate filters, so new one will be placed - # in correct place. If append=True and duplicate exists, do nothing. - if not append: - try: - filters.remove(item) - except ValueError: - pass - filters.insert(0, item) - else: - if item not in filters: - filters.append(item) - _filters_mutated() - -def resetwarnings(): - """Clear the list of warning filters, so that no filters are active.""" - filters[:] = [] - _filters_mutated() - -class _OptionError(Exception): - """Exception used by option processing helpers.""" - pass - -# Helper to process -W options passed via sys.warnoptions -def _processoptions(args): - for arg in args: - try: - _setoption(arg) - except _OptionError as msg: - print("Invalid -W option ignored:", msg, file=sys.stderr) - -# Helper for _processoptions() -def _setoption(arg): - parts = arg.split(':') - if len(parts) > 5: - raise _OptionError("too many fields (max 5): %r" % (arg,)) - while len(parts) < 5: - parts.append('') - action, message, category, module, lineno = [s.strip() - for s in parts] - action = _getaction(action) - category = _getcategory(category) - if message or module: - import re - if message: - message = re.escape(message) - if module: - module = re.escape(module) + r'\Z' - if lineno: - try: - lineno = int(lineno) - if lineno < 0: - raise ValueError - except (ValueError, OverflowError): - raise _OptionError("invalid lineno %r" % (lineno,)) from None - else: - lineno = 0 - filterwarnings(action, message, category, module, lineno) - -# Helper for _setoption() -def _getaction(action): - if not action: - return "default" - if action == "all": return "always" # Alias - for a in ('default', 'always', 'ignore', 'module', 'once', 'error'): - if a.startswith(action): - return a - raise _OptionError("invalid action: %r" % (action,)) - -# Helper for _setoption() -def _getcategory(category): - if not category: - return Warning - if '.' not in category: - import builtins as m - klass = category - else: - module, _, klass = category.rpartition('.') - try: - m = __import__(module, None, None, [klass]) - except ImportError: - raise _OptionError("invalid module name: %r" % (module,)) from None - try: - cat = getattr(m, klass) - except AttributeError: - raise _OptionError("unknown warning category: %r" % (category,)) from None - if not issubclass(cat, Warning): - raise _OptionError("invalid warning category: %r" % (category,)) - return cat - - -def _is_internal_frame(frame): - """Signal whether the frame is an internal CPython implementation detail.""" - filename = frame.f_code.co_filename - return 'importlib' in filename and '_bootstrap' in filename - - -def _next_external_frame(frame): - """Find the next frame that doesn't involve CPython internals.""" - frame = frame.f_back - while frame is not None and _is_internal_frame(frame): - frame = frame.f_back - return frame - - -# Code typically replaced by _warnings -def warn(message, category=None, stacklevel=1, source=None): - """Issue a warning, or maybe ignore it or raise an exception.""" - # Check if message is already a Warning object - if isinstance(message, Warning): - category = message.__class__ - # Check category argument - if category is None: - category = UserWarning - if not (isinstance(category, type) and issubclass(category, Warning)): - raise TypeError("category must be a Warning subclass, " - "not '{:s}'".format(type(category).__name__)) - # Get context information - try: - if stacklevel <= 1 or _is_internal_frame(sys._getframe(1)): - # If frame is too small to care or if the warning originated in - # internal code, then do not try to hide any frames. - frame = sys._getframe(stacklevel) - else: - frame = sys._getframe(1) - # Look for one frame less since the above line starts us off. - for x in range(stacklevel-1): - frame = _next_external_frame(frame) - if frame is None: - raise ValueError - except ValueError: - globals = sys.__dict__ - filename = "sys" - lineno = 1 - else: - globals = frame.f_globals - filename = frame.f_code.co_filename - lineno = frame.f_lineno - if '__name__' in globals: - module = globals['__name__'] - else: - module = "" - registry = globals.setdefault("__warningregistry__", {}) - warn_explicit(message, category, filename, lineno, module, registry, - globals, source) - -def warn_explicit(message, category, filename, lineno, - module=None, registry=None, module_globals=None, - source=None): - lineno = int(lineno) - if module is None: - module = filename or "" - if module[-3:].lower() == ".py": - module = module[:-3] # XXX What about leading pathname? - if registry is None: - registry = {} - if registry.get('version', 0) != _filters_version: - registry.clear() - registry['version'] = _filters_version - if isinstance(message, Warning): - text = str(message) - category = message.__class__ - else: - text = message - message = category(message) - key = (text, category, lineno) - # Quick test for common case - if registry.get(key): - return - # Search the filters - for item in filters: - action, msg, cat, mod, ln = item - if ((msg is None or msg.match(text)) and - issubclass(category, cat) and - (mod is None or mod.match(module)) and - (ln == 0 or lineno == ln)): - break - else: - action = defaultaction - # Early exit actions - if action == "ignore": - return - - # Prime the linecache for formatting, in case the - # "file" is actually in a zipfile or something. - import linecache - linecache.getlines(filename, module_globals) - - if action == "error": - raise message - # Other actions - if action == "once": - registry[key] = 1 - oncekey = (text, category) - if onceregistry.get(oncekey): - return - onceregistry[oncekey] = 1 - elif action == "always": - pass - elif action == "module": - registry[key] = 1 - altkey = (text, category, 0) - if registry.get(altkey): - return - registry[altkey] = 1 - elif action == "default": - registry[key] = 1 - else: - # Unrecognized actions are errors - raise RuntimeError( - "Unrecognized action (%r) in warnings.filters:\n %s" % - (action, item)) - # Print message and context - msg = WarningMessage(message, category, filename, lineno, source) - _showwarnmsg(msg) - - -class WarningMessage(object): - - _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file", - "line", "source") - - def __init__(self, message, category, filename, lineno, file=None, - line=None, source=None): - self.message = message - self.category = category - self.filename = filename - self.lineno = lineno - self.file = file - self.line = line - self.source = source - self._category_name = category.__name__ if category else None - - def __str__(self): - return ("{message : %r, category : %r, filename : %r, lineno : %s, " - "line : %r}" % (self.message, self._category_name, - self.filename, self.lineno, self.line)) - - -class catch_warnings(object): - - """A context manager that copies and restores the warnings filter upon - exiting the context. - - The 'record' argument specifies whether warnings should be captured by a - custom implementation of warnings.showwarning() and be appended to a list - returned by the context manager. Otherwise None is returned by the context - manager. The objects appended to the list are arguments whose attributes - mirror the arguments to showwarning(). - - The 'module' argument is to specify an alternative module to the module - named 'warnings' and imported under that name. This argument is only useful - when testing the warnings module itself. - - If the 'action' argument is not None, the remaining arguments are passed - to warnings.simplefilter() as if it were called immediately on entering the - context. - """ - - def __init__(self, *, record=False, module=None, - action=None, category=Warning, lineno=0, append=False): - """Specify whether to record warnings and if an alternative module - should be used other than sys.modules['warnings']. - - For compatibility with Python 3.0, please consider all arguments to be - keyword-only. - - """ - self._record = record - self._module = sys.modules['warnings'] if module is None else module - self._entered = False - if action is None: - self._filter = None - else: - self._filter = (action, category, lineno, append) - - def __repr__(self): - args = [] - if self._record: - args.append("record=True") - if self._module is not sys.modules['warnings']: - args.append("module=%r" % self._module) - name = type(self).__name__ - return "%s(%s)" % (name, ", ".join(args)) - - def __enter__(self): - if self._entered: - raise RuntimeError("Cannot enter %r twice" % self) - self._entered = True - self._filters = self._module.filters - self._module.filters = self._filters[:] - self._module._filters_mutated() - self._showwarning = self._module.showwarning - self._showwarnmsg_impl = self._module._showwarnmsg_impl - if self._filter is not None: - simplefilter(*self._filter) - if self._record: - log = [] - self._module._showwarnmsg_impl = log.append - # Reset showwarning() to the default implementation to make sure - # that _showwarnmsg() calls _showwarnmsg_impl() - self._module.showwarning = self._module._showwarning_orig - return log - else: - return None - - def __exit__(self, *exc_info): - if not self._entered: - raise RuntimeError("Cannot exit %r without entering first" % self) - self._module.filters = self._filters - self._module._filters_mutated() - self._module.showwarning = self._showwarning - self._module._showwarnmsg_impl = self._showwarnmsg_impl - - -_DEPRECATED_MSG = "{name!r} is deprecated and slated for removal in Python {remove}" - -def _deprecated(name, message=_DEPRECATED_MSG, *, remove, _version=sys.version_info): - """Warn that *name* is deprecated or should be removed. - - RuntimeError is raised if *remove* specifies a major/minor tuple older than - the current Python version or the same version but past the alpha. - - The *message* argument is formatted with *name* and *remove* as a Python - version (e.g. "3.11"). - - """ - remove_formatted = f"{remove[0]}.{remove[1]}" - if (_version[:2] > remove) or (_version[:2] == remove and _version[3] != "alpha"): - msg = f"{name!r} was slated for removal after Python {remove_formatted} alpha" - raise RuntimeError(msg) - else: - msg = message.format(name=name, remove=remove_formatted) - warn(msg, DeprecationWarning, stacklevel=3) - - -# Private utility function called by _PyErr_WarnUnawaitedCoroutine -def _warn_unawaited_coroutine(coro): - msg_lines = [ - f"coroutine '{coro.__qualname__}' was never awaited\n" - ] - if coro.cr_origin is not None: - import linecache, traceback - def extract(): - for filename, lineno, funcname in reversed(coro.cr_origin): - line = linecache.getline(filename, lineno) - yield (filename, lineno, funcname, line) - msg_lines.append("Coroutine created at (most recent call last)\n") - msg_lines += traceback.format_list(list(extract())) - msg = "".join(msg_lines).rstrip("\n") - # Passing source= here means that if the user happens to have tracemalloc - # enabled and tracking where the coroutine was created, the warning will - # contain that traceback. This does mean that if they have *both* - # coroutine origin tracking *and* tracemalloc enabled, they'll get two - # partially-redundant tracebacks. If we wanted to be clever we could - # probably detect this case and avoid it, but for now we don't bother. - warn(msg, category=RuntimeWarning, stacklevel=2, source=coro) - - -# filters contains a sequence of filter 5-tuples -# The components of the 5-tuple are: -# - an action: error, ignore, always, default, module, or once -# - a compiled regex that must match the warning message -# - a class representing the warning category -# - a compiled regex that must match the module that is being warned -# - a line number for the line being warning, or 0 to mean any line -# If either if the compiled regexs are None, match anything. -try: - from _warnings import (filters, _defaultaction, _onceregistry, - warn, warn_explicit, _filters_mutated) - defaultaction = _defaultaction - onceregistry = _onceregistry - _warnings_defaults = True -except ImportError: - filters = [] - defaultaction = "default" - onceregistry = {} - - _filters_version = 1 - - def _filters_mutated(): - global _filters_version - _filters_version += 1 - - _warnings_defaults = False - - -# Module initialization -_processoptions(sys.warnoptions) -if not _warnings_defaults: - # Several warning categories are ignored by default in regular builds - if not hasattr(sys, 'gettotalrefcount'): - filterwarnings("default", category=DeprecationWarning, - module="__main__", append=1) - simplefilter("ignore", category=DeprecationWarning, append=1) - simplefilter("ignore", category=PendingDeprecationWarning, append=1) - simplefilter("ignore", category=ImportWarning, append=1) - simplefilter("ignore", category=ResourceWarning, append=1) - -del _warnings_defaults diff --git a/python/Lib/weakref.py b/python/Lib/weakref.py deleted file mode 100644 index 6c6eaba..0000000 --- a/python/Lib/weakref.py +++ /dev/null @@ -1,674 +0,0 @@ -"""Weak reference support for Python. - -This module is an implementation of PEP 205: - -https://peps.python.org/pep-0205/ -""" - -# Naming convention: Variables named "wr" are weak reference objects; -# they are called this instead of "ref" to avoid name collisions with -# the module-global ref() function imported from _weakref. - -from _weakref import ( - getweakrefcount, - getweakrefs, - ref, - proxy, - CallableProxyType, - ProxyType, - ReferenceType, - _remove_dead_weakref) - -from _weakrefset import WeakSet, _IterationGuard - -import _collections_abc # Import after _weakref to avoid circular import. -import sys -import itertools - -ProxyTypes = (ProxyType, CallableProxyType) - -__all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs", - "WeakKeyDictionary", "ReferenceType", "ProxyType", - "CallableProxyType", "ProxyTypes", "WeakValueDictionary", - "WeakSet", "WeakMethod", "finalize"] - - -_collections_abc.MutableSet.register(WeakSet) - -class WeakMethod(ref): - """ - A custom `weakref.ref` subclass which simulates a weak reference to - a bound method, working around the lifetime problem of bound methods. - """ - - __slots__ = "_func_ref", "_meth_type", "_alive", "__weakref__" - - def __new__(cls, meth, callback=None): - try: - obj = meth.__self__ - func = meth.__func__ - except AttributeError: - raise TypeError("argument should be a bound method, not {}" - .format(type(meth))) from None - def _cb(arg): - # The self-weakref trick is needed to avoid creating a reference - # cycle. - self = self_wr() - if self._alive: - self._alive = False - if callback is not None: - callback(self) - self = ref.__new__(cls, obj, _cb) - self._func_ref = ref(func, _cb) - self._meth_type = type(meth) - self._alive = True - self_wr = ref(self) - return self - - def __call__(self): - obj = super().__call__() - func = self._func_ref() - if obj is None or func is None: - return None - return self._meth_type(func, obj) - - def __eq__(self, other): - if isinstance(other, WeakMethod): - if not self._alive or not other._alive: - return self is other - return ref.__eq__(self, other) and self._func_ref == other._func_ref - return NotImplemented - - def __ne__(self, other): - if isinstance(other, WeakMethod): - if not self._alive or not other._alive: - return self is not other - return ref.__ne__(self, other) or self._func_ref != other._func_ref - return NotImplemented - - __hash__ = ref.__hash__ - - -class WeakValueDictionary(_collections_abc.MutableMapping): - """Mapping class that references values weakly. - - Entries in the dictionary will be discarded when no strong - reference to the value exists anymore - """ - # We inherit the constructor without worrying about the input - # dictionary; since it uses our .update() method, we get the right - # checks (if the other dictionary is a WeakValueDictionary, - # objects are unwrapped on the way out, and we always wrap on the - # way in). - - def __init__(self, other=(), /, **kw): - def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref): - self = selfref() - if self is not None: - if self._iterating: - self._pending_removals.append(wr.key) - else: - # Atomic removal is necessary since this function - # can be called asynchronously by the GC - _atomic_removal(self.data, wr.key) - self._remove = remove - # A list of keys to be removed - self._pending_removals = [] - self._iterating = set() - self.data = {} - self.update(other, **kw) - - def _commit_removals(self, _atomic_removal=_remove_dead_weakref): - pop = self._pending_removals.pop - d = self.data - # We shouldn't encounter any KeyError, because this method should - # always be called *before* mutating the dict. - while True: - try: - key = pop() - except IndexError: - return - _atomic_removal(d, key) - - def __getitem__(self, key): - if self._pending_removals: - self._commit_removals() - o = self.data[key]() - if o is None: - raise KeyError(key) - else: - return o - - def __delitem__(self, key): - if self._pending_removals: - self._commit_removals() - del self.data[key] - - def __len__(self): - if self._pending_removals: - self._commit_removals() - return len(self.data) - - def __contains__(self, key): - if self._pending_removals: - self._commit_removals() - try: - o = self.data[key]() - except KeyError: - return False - return o is not None - - def __repr__(self): - return "<%s at %#x>" % (self.__class__.__name__, id(self)) - - def __setitem__(self, key, value): - if self._pending_removals: - self._commit_removals() - self.data[key] = KeyedRef(value, self._remove, key) - - def copy(self): - if self._pending_removals: - self._commit_removals() - new = WeakValueDictionary() - with _IterationGuard(self): - for key, wr in self.data.items(): - o = wr() - if o is not None: - new[key] = o - return new - - __copy__ = copy - - def __deepcopy__(self, memo): - from copy import deepcopy - if self._pending_removals: - self._commit_removals() - new = self.__class__() - with _IterationGuard(self): - for key, wr in self.data.items(): - o = wr() - if o is not None: - new[deepcopy(key, memo)] = o - return new - - def get(self, key, default=None): - if self._pending_removals: - self._commit_removals() - try: - wr = self.data[key] - except KeyError: - return default - else: - o = wr() - if o is None: - # This should only happen - return default - else: - return o - - def items(self): - if self._pending_removals: - self._commit_removals() - with _IterationGuard(self): - for k, wr in self.data.items(): - v = wr() - if v is not None: - yield k, v - - def keys(self): - if self._pending_removals: - self._commit_removals() - with _IterationGuard(self): - for k, wr in self.data.items(): - if wr() is not None: - yield k - - __iter__ = keys - - def itervaluerefs(self): - """Return an iterator that yields the weak references to the values. - - The references are not guaranteed to be 'live' at the time - they are used, so the result of calling the references needs - to be checked before being used. This can be used to avoid - creating references that will cause the garbage collector to - keep the values around longer than needed. - - """ - if self._pending_removals: - self._commit_removals() - with _IterationGuard(self): - yield from self.data.values() - - def values(self): - if self._pending_removals: - self._commit_removals() - with _IterationGuard(self): - for wr in self.data.values(): - obj = wr() - if obj is not None: - yield obj - - def popitem(self): - if self._pending_removals: - self._commit_removals() - while True: - key, wr = self.data.popitem() - o = wr() - if o is not None: - return key, o - - def pop(self, key, *args): - if self._pending_removals: - self._commit_removals() - try: - o = self.data.pop(key)() - except KeyError: - o = None - if o is None: - if args: - return args[0] - else: - raise KeyError(key) - else: - return o - - def setdefault(self, key, default=None): - try: - o = self.data[key]() - except KeyError: - o = None - if o is None: - if self._pending_removals: - self._commit_removals() - self.data[key] = KeyedRef(default, self._remove, key) - return default - else: - return o - - def update(self, other=None, /, **kwargs): - if self._pending_removals: - self._commit_removals() - d = self.data - if other is not None: - if not hasattr(other, "items"): - other = dict(other) - for key, o in other.items(): - d[key] = KeyedRef(o, self._remove, key) - for key, o in kwargs.items(): - d[key] = KeyedRef(o, self._remove, key) - - def valuerefs(self): - """Return a list of weak references to the values. - - The references are not guaranteed to be 'live' at the time - they are used, so the result of calling the references needs - to be checked before being used. This can be used to avoid - creating references that will cause the garbage collector to - keep the values around longer than needed. - - """ - if self._pending_removals: - self._commit_removals() - return list(self.data.values()) - - def __ior__(self, other): - self.update(other) - return self - - def __or__(self, other): - if isinstance(other, _collections_abc.Mapping): - c = self.copy() - c.update(other) - return c - return NotImplemented - - def __ror__(self, other): - if isinstance(other, _collections_abc.Mapping): - c = self.__class__() - c.update(other) - c.update(self) - return c - return NotImplemented - - -class KeyedRef(ref): - """Specialized reference that includes a key corresponding to the value. - - This is used in the WeakValueDictionary to avoid having to create - a function object for each key stored in the mapping. A shared - callback object can use the 'key' attribute of a KeyedRef instead - of getting a reference to the key from an enclosing scope. - - """ - - __slots__ = "key", - - def __new__(type, ob, callback, key): - self = ref.__new__(type, ob, callback) - self.key = key - return self - - def __init__(self, ob, callback, key): - super().__init__(ob, callback) - - -class WeakKeyDictionary(_collections_abc.MutableMapping): - """ Mapping class that references keys weakly. - - Entries in the dictionary will be discarded when there is no - longer a strong reference to the key. This can be used to - associate additional data with an object owned by other parts of - an application without adding attributes to those objects. This - can be especially useful with objects that override attribute - accesses. - """ - - def __init__(self, dict=None): - self.data = {} - def remove(k, selfref=ref(self)): - self = selfref() - if self is not None: - if self._iterating: - self._pending_removals.append(k) - else: - try: - del self.data[k] - except KeyError: - pass - self._remove = remove - # A list of dead weakrefs (keys to be removed) - self._pending_removals = [] - self._iterating = set() - self._dirty_len = False - if dict is not None: - self.update(dict) - - def _commit_removals(self): - # NOTE: We don't need to call this method before mutating the dict, - # because a dead weakref never compares equal to a live weakref, - # even if they happened to refer to equal objects. - # However, it means keys may already have been removed. - pop = self._pending_removals.pop - d = self.data - while True: - try: - key = pop() - except IndexError: - return - - try: - del d[key] - except KeyError: - pass - - def _scrub_removals(self): - d = self.data - self._pending_removals = [k for k in self._pending_removals if k in d] - self._dirty_len = False - - def __delitem__(self, key): - self._dirty_len = True - del self.data[ref(key)] - - def __getitem__(self, key): - return self.data[ref(key)] - - def __len__(self): - if self._dirty_len and self._pending_removals: - # self._pending_removals may still contain keys which were - # explicitly removed, we have to scrub them (see issue #21173). - self._scrub_removals() - return len(self.data) - len(self._pending_removals) - - def __repr__(self): - return "<%s at %#x>" % (self.__class__.__name__, id(self)) - - def __setitem__(self, key, value): - self.data[ref(key, self._remove)] = value - - def copy(self): - new = WeakKeyDictionary() - with _IterationGuard(self): - for key, value in self.data.items(): - o = key() - if o is not None: - new[o] = value - return new - - __copy__ = copy - - def __deepcopy__(self, memo): - from copy import deepcopy - new = self.__class__() - with _IterationGuard(self): - for key, value in self.data.items(): - o = key() - if o is not None: - new[o] = deepcopy(value, memo) - return new - - def get(self, key, default=None): - return self.data.get(ref(key),default) - - def __contains__(self, key): - try: - wr = ref(key) - except TypeError: - return False - return wr in self.data - - def items(self): - with _IterationGuard(self): - for wr, value in self.data.items(): - key = wr() - if key is not None: - yield key, value - - def keys(self): - with _IterationGuard(self): - for wr in self.data: - obj = wr() - if obj is not None: - yield obj - - __iter__ = keys - - def values(self): - with _IterationGuard(self): - for wr, value in self.data.items(): - if wr() is not None: - yield value - - def keyrefs(self): - """Return a list of weak references to the keys. - - The references are not guaranteed to be 'live' at the time - they are used, so the result of calling the references needs - to be checked before being used. This can be used to avoid - creating references that will cause the garbage collector to - keep the keys around longer than needed. - - """ - return list(self.data) - - def popitem(self): - self._dirty_len = True - while True: - key, value = self.data.popitem() - o = key() - if o is not None: - return o, value - - def pop(self, key, *args): - self._dirty_len = True - return self.data.pop(ref(key), *args) - - def setdefault(self, key, default=None): - return self.data.setdefault(ref(key, self._remove),default) - - def update(self, dict=None, /, **kwargs): - d = self.data - if dict is not None: - if not hasattr(dict, "items"): - dict = type({})(dict) - for key, value in dict.items(): - d[ref(key, self._remove)] = value - if len(kwargs): - self.update(kwargs) - - def __ior__(self, other): - self.update(other) - return self - - def __or__(self, other): - if isinstance(other, _collections_abc.Mapping): - c = self.copy() - c.update(other) - return c - return NotImplemented - - def __ror__(self, other): - if isinstance(other, _collections_abc.Mapping): - c = self.__class__() - c.update(other) - c.update(self) - return c - return NotImplemented - - -class finalize: - """Class for finalization of weakrefable objects - - finalize(obj, func, *args, **kwargs) returns a callable finalizer - object which will be called when obj is garbage collected. The - first time the finalizer is called it evaluates func(*arg, **kwargs) - and returns the result. After this the finalizer is dead, and - calling it just returns None. - - When the program exits any remaining finalizers for which the - atexit attribute is true will be run in reverse order of creation. - By default atexit is true. - """ - - # Finalizer objects don't have any state of their own. They are - # just used as keys to lookup _Info objects in the registry. This - # ensures that they cannot be part of a ref-cycle. - - __slots__ = () - _registry = {} - _shutdown = False - _index_iter = itertools.count() - _dirty = False - _registered_with_atexit = False - - class _Info: - __slots__ = ("weakref", "func", "args", "kwargs", "atexit", "index") - - def __init__(self, obj, func, /, *args, **kwargs): - if not self._registered_with_atexit: - # We may register the exit function more than once because - # of a thread race, but that is harmless - import atexit - atexit.register(self._exitfunc) - finalize._registered_with_atexit = True - info = self._Info() - info.weakref = ref(obj, self) - info.func = func - info.args = args - info.kwargs = kwargs or None - info.atexit = True - info.index = next(self._index_iter) - self._registry[self] = info - finalize._dirty = True - - def __call__(self, _=None): - """If alive then mark as dead and return func(*args, **kwargs); - otherwise return None""" - info = self._registry.pop(self, None) - if info and not self._shutdown: - return info.func(*info.args, **(info.kwargs or {})) - - def detach(self): - """If alive then mark as dead and return (obj, func, args, kwargs); - otherwise return None""" - info = self._registry.get(self) - obj = info and info.weakref() - if obj is not None and self._registry.pop(self, None): - return (obj, info.func, info.args, info.kwargs or {}) - - def peek(self): - """If alive then return (obj, func, args, kwargs); - otherwise return None""" - info = self._registry.get(self) - obj = info and info.weakref() - if obj is not None: - return (obj, info.func, info.args, info.kwargs or {}) - - @property - def alive(self): - """Whether finalizer is alive""" - return self in self._registry - - @property - def atexit(self): - """Whether finalizer should be called at exit""" - info = self._registry.get(self) - return bool(info) and info.atexit - - @atexit.setter - def atexit(self, value): - info = self._registry.get(self) - if info: - info.atexit = bool(value) - - def __repr__(self): - info = self._registry.get(self) - obj = info and info.weakref() - if obj is None: - return '<%s object at %#x; dead>' % (type(self).__name__, id(self)) - else: - return '<%s object at %#x; for %r at %#x>' % \ - (type(self).__name__, id(self), type(obj).__name__, id(obj)) - - @classmethod - def _select_for_exit(cls): - # Return live finalizers marked for exit, oldest first - L = [(f,i) for (f,i) in cls._registry.items() if i.atexit] - L.sort(key=lambda item:item[1].index) - return [f for (f,i) in L] - - @classmethod - def _exitfunc(cls): - # At shutdown invoke finalizers for which atexit is true. - # This is called once all other non-daemonic threads have been - # joined. - reenable_gc = False - try: - if cls._registry: - import gc - if gc.isenabled(): - reenable_gc = True - gc.disable() - pending = None - while True: - if pending is None or finalize._dirty: - pending = cls._select_for_exit() - finalize._dirty = False - if not pending: - break - f = pending.pop() - try: - # gc is disabled, so (assuming no daemonic - # threads) the following is the only line in - # this function which might trigger creation - # of a new finalizer - f() - except Exception: - sys.excepthook(*sys.exc_info()) - assert f not in cls._registry - finally: - # prevent any more finalizers from executing during shutdown - finalize._shutdown = True - if reenable_gc: - gc.enable() diff --git a/python/Lib/zipapp.py b/python/Lib/zipapp.py deleted file mode 100644 index 5807c7d..0000000 --- a/python/Lib/zipapp.py +++ /dev/null @@ -1,206 +0,0 @@ -import contextlib -import os -import pathlib -import shutil -import stat -import sys -import zipfile - -__all__ = ['ZipAppError', 'create_archive', 'get_interpreter'] - - -# The __main__.py used if the users specifies "-m module:fn". -# Note that this will always be written as UTF-8 (module and -# function names can be non-ASCII in Python 3). -# We add a coding cookie even though UTF-8 is the default in Python 3 -# because the resulting archive may be intended to be run under Python 2. -MAIN_TEMPLATE = """\ -# -*- coding: utf-8 -*- -import {module} -{module}.{fn}() -""" - - -# The Windows launcher defaults to UTF-8 when parsing shebang lines if the -# file has no BOM. So use UTF-8 on Windows. -# On Unix, use the filesystem encoding. -if sys.platform.startswith('win'): - shebang_encoding = 'utf-8' -else: - shebang_encoding = sys.getfilesystemencoding() - - -class ZipAppError(ValueError): - pass - - -@contextlib.contextmanager -def _maybe_open(archive, mode): - if isinstance(archive, (str, os.PathLike)): - with open(archive, mode) as f: - yield f - else: - yield archive - - -def _write_file_prefix(f, interpreter): - """Write a shebang line.""" - if interpreter: - shebang = b'#!' + interpreter.encode(shebang_encoding) + b'\n' - f.write(shebang) - - -def _copy_archive(archive, new_archive, interpreter=None): - """Copy an application archive, modifying the shebang line.""" - with _maybe_open(archive, 'rb') as src: - # Skip the shebang line from the source. - # Read 2 bytes of the source and check if they are #!. - first_2 = src.read(2) - if first_2 == b'#!': - # Discard the initial 2 bytes and the rest of the shebang line. - first_2 = b'' - src.readline() - - with _maybe_open(new_archive, 'wb') as dst: - _write_file_prefix(dst, interpreter) - # If there was no shebang, "first_2" contains the first 2 bytes - # of the source file, so write them before copying the rest - # of the file. - dst.write(first_2) - shutil.copyfileobj(src, dst) - - if interpreter and isinstance(new_archive, str): - os.chmod(new_archive, os.stat(new_archive).st_mode | stat.S_IEXEC) - - -def create_archive(source, target=None, interpreter=None, main=None, - filter=None, compressed=False): - """Create an application archive from SOURCE. - - The SOURCE can be the name of a directory, or a filename or a file-like - object referring to an existing archive. - - The content of SOURCE is packed into an application archive in TARGET, - which can be a filename or a file-like object. If SOURCE is a directory, - TARGET can be omitted and will default to the name of SOURCE with .pyz - appended. - - The created application archive will have a shebang line specifying - that it should run with INTERPRETER (there will be no shebang line if - INTERPRETER is None), and a __main__.py which runs MAIN (if MAIN is - not specified, an existing __main__.py will be used). It is an error - to specify MAIN for anything other than a directory source with no - __main__.py, and it is an error to omit MAIN if the directory has no - __main__.py. - """ - # Are we copying an existing archive? - source_is_file = False - if hasattr(source, 'read') and hasattr(source, 'readline'): - source_is_file = True - else: - source = pathlib.Path(source) - if source.is_file(): - source_is_file = True - - if source_is_file: - _copy_archive(source, target, interpreter) - return - - # We are creating a new archive from a directory. - if not source.exists(): - raise ZipAppError("Source does not exist") - has_main = (source / '__main__.py').is_file() - if main and has_main: - raise ZipAppError( - "Cannot specify entry point if the source has __main__.py") - if not (main or has_main): - raise ZipAppError("Archive has no entry point") - - main_py = None - if main: - # Check that main has the right format. - mod, sep, fn = main.partition(':') - mod_ok = all(part.isidentifier() for part in mod.split('.')) - fn_ok = all(part.isidentifier() for part in fn.split('.')) - if not (sep == ':' and mod_ok and fn_ok): - raise ZipAppError("Invalid entry point: " + main) - main_py = MAIN_TEMPLATE.format(module=mod, fn=fn) - - if target is None: - target = source.with_suffix('.pyz') - elif not hasattr(target, 'write'): - target = pathlib.Path(target) - - with _maybe_open(target, 'wb') as fd: - _write_file_prefix(fd, interpreter) - compression = (zipfile.ZIP_DEFLATED if compressed else - zipfile.ZIP_STORED) - with zipfile.ZipFile(fd, 'w', compression=compression) as z: - for child in source.rglob('*'): - arcname = child.relative_to(source) - if filter is None or filter(arcname): - z.write(child, arcname.as_posix()) - if main_py: - z.writestr('__main__.py', main_py.encode('utf-8')) - - if interpreter and not hasattr(target, 'write'): - target.chmod(target.stat().st_mode | stat.S_IEXEC) - - -def get_interpreter(archive): - with _maybe_open(archive, 'rb') as f: - if f.read(2) == b'#!': - return f.readline().strip().decode(shebang_encoding) - - -def main(args=None): - """Run the zipapp command line interface. - - The ARGS parameter lets you specify the argument list directly. - Omitting ARGS (or setting it to None) works as for argparse, using - sys.argv[1:] as the argument list. - """ - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument('--output', '-o', default=None, - help="The name of the output archive. " - "Required if SOURCE is an archive.") - parser.add_argument('--python', '-p', default=None, - help="The name of the Python interpreter to use " - "(default: no shebang line).") - parser.add_argument('--main', '-m', default=None, - help="The main function of the application " - "(default: use an existing __main__.py).") - parser.add_argument('--compress', '-c', action='store_true', - help="Compress files with the deflate method. " - "Files are stored uncompressed by default.") - parser.add_argument('--info', default=False, action='store_true', - help="Display the interpreter from the archive.") - parser.add_argument('source', - help="Source directory (or existing archive).") - - args = parser.parse_args(args) - - # Handle `python -m zipapp archive.pyz --info`. - if args.info: - if not os.path.isfile(args.source): - raise SystemExit("Can only get info for an archive file") - interpreter = get_interpreter(args.source) - print("Interpreter: {}".format(interpreter or "")) - sys.exit(0) - - if os.path.isfile(args.source): - if args.output is None or (os.path.exists(args.output) and - os.path.samefile(args.source, args.output)): - raise SystemExit("In-place editing of archives is not supported") - if args.main: - raise SystemExit("Cannot change the main function when copying") - - create_archive(args.source, args.output, - interpreter=args.python, main=args.main, - compressed=args.compress) - - -if __name__ == '__main__': - main() diff --git a/python/Lib/zipfile.py b/python/Lib/zipfile.py deleted file mode 100644 index 6543506..0000000 --- a/python/Lib/zipfile.py +++ /dev/null @@ -1,2546 +0,0 @@ -""" -Read and write ZIP files. - -XXX references to utf-8 need further investigation. -""" -import binascii -import importlib.util -import io -import itertools -import os -import posixpath -import shutil -import stat -import struct -import sys -import threading -import time -import contextlib -import pathlib - -try: - import zlib # We may need its compression method - crc32 = zlib.crc32 -except ImportError: - zlib = None - crc32 = binascii.crc32 - -try: - import bz2 # We may need its compression method -except ImportError: - bz2 = None - -try: - import lzma # We may need its compression method -except ImportError: - lzma = None - -__all__ = ["BadZipFile", "BadZipfile", "error", - "ZIP_STORED", "ZIP_DEFLATED", "ZIP_BZIP2", "ZIP_LZMA", - "is_zipfile", "ZipInfo", "ZipFile", "PyZipFile", "LargeZipFile", - "Path"] - -class BadZipFile(Exception): - pass - - -class LargeZipFile(Exception): - """ - Raised when writing a zipfile, the zipfile requires ZIP64 extensions - and those extensions are disabled. - """ - -error = BadZipfile = BadZipFile # Pre-3.2 compatibility names - - -ZIP64_LIMIT = (1 << 31) - 1 -ZIP_FILECOUNT_LIMIT = (1 << 16) - 1 -ZIP_MAX_COMMENT = (1 << 16) - 1 - -# constants for Zip file compression methods -ZIP_STORED = 0 -ZIP_DEFLATED = 8 -ZIP_BZIP2 = 12 -ZIP_LZMA = 14 -# Other ZIP compression methods not supported - -DEFAULT_VERSION = 20 -ZIP64_VERSION = 45 -BZIP2_VERSION = 46 -LZMA_VERSION = 63 -# we recognize (but not necessarily support) all features up to that version -MAX_EXTRACT_VERSION = 63 - -# Below are some formats and associated data for reading/writing headers using -# the struct module. The names and structures of headers/records are those used -# in the PKWARE description of the ZIP file format: -# http://www.pkware.com/documents/casestudies/APPNOTE.TXT -# (URL valid as of January 2008) - -# The "end of central directory" structure, magic number, size, and indices -# (section V.I in the format document) -structEndArchive = b"<4s4H2LH" -stringEndArchive = b"PK\005\006" -sizeEndCentDir = struct.calcsize(structEndArchive) - -_ECD_SIGNATURE = 0 -_ECD_DISK_NUMBER = 1 -_ECD_DISK_START = 2 -_ECD_ENTRIES_THIS_DISK = 3 -_ECD_ENTRIES_TOTAL = 4 -_ECD_SIZE = 5 -_ECD_OFFSET = 6 -_ECD_COMMENT_SIZE = 7 -# These last two indices are not part of the structure as defined in the -# spec, but they are used internally by this module as a convenience -_ECD_COMMENT = 8 -_ECD_LOCATION = 9 - -# The "central directory" structure, magic number, size, and indices -# of entries in the structure (section V.F in the format document) -structCentralDir = "<4s4B4HL2L5H2L" -stringCentralDir = b"PK\001\002" -sizeCentralDir = struct.calcsize(structCentralDir) - -# indexes of entries in the central directory structure -_CD_SIGNATURE = 0 -_CD_CREATE_VERSION = 1 -_CD_CREATE_SYSTEM = 2 -_CD_EXTRACT_VERSION = 3 -_CD_EXTRACT_SYSTEM = 4 -_CD_FLAG_BITS = 5 -_CD_COMPRESS_TYPE = 6 -_CD_TIME = 7 -_CD_DATE = 8 -_CD_CRC = 9 -_CD_COMPRESSED_SIZE = 10 -_CD_UNCOMPRESSED_SIZE = 11 -_CD_FILENAME_LENGTH = 12 -_CD_EXTRA_FIELD_LENGTH = 13 -_CD_COMMENT_LENGTH = 14 -_CD_DISK_NUMBER_START = 15 -_CD_INTERNAL_FILE_ATTRIBUTES = 16 -_CD_EXTERNAL_FILE_ATTRIBUTES = 17 -_CD_LOCAL_HEADER_OFFSET = 18 - -# General purpose bit flags -# Zip Appnote: 4.4.4 general purpose bit flag: (2 bytes) -_MASK_ENCRYPTED = 1 << 0 -# Bits 1 and 2 have different meanings depending on the compression used. -_MASK_COMPRESS_OPTION_1 = 1 << 1 -# _MASK_COMPRESS_OPTION_2 = 1 << 2 -# _MASK_USE_DATA_DESCRIPTOR: If set, crc-32, compressed size and uncompressed -# size are zero in the local header and the real values are written in the data -# descriptor immediately following the compressed data. -_MASK_USE_DATA_DESCRIPTOR = 1 << 3 -# Bit 4: Reserved for use with compression method 8, for enhanced deflating. -# _MASK_RESERVED_BIT_4 = 1 << 4 -_MASK_COMPRESSED_PATCH = 1 << 5 -_MASK_STRONG_ENCRYPTION = 1 << 6 -# _MASK_UNUSED_BIT_7 = 1 << 7 -# _MASK_UNUSED_BIT_8 = 1 << 8 -# _MASK_UNUSED_BIT_9 = 1 << 9 -# _MASK_UNUSED_BIT_10 = 1 << 10 -_MASK_UTF_FILENAME = 1 << 11 -# Bit 12: Reserved by PKWARE for enhanced compression. -# _MASK_RESERVED_BIT_12 = 1 << 12 -# _MASK_ENCRYPTED_CENTRAL_DIR = 1 << 13 -# Bit 14, 15: Reserved by PKWARE -# _MASK_RESERVED_BIT_14 = 1 << 14 -# _MASK_RESERVED_BIT_15 = 1 << 15 - -# The "local file header" structure, magic number, size, and indices -# (section V.A in the format document) -structFileHeader = "<4s2B4HL2L2H" -stringFileHeader = b"PK\003\004" -sizeFileHeader = struct.calcsize(structFileHeader) - -_FH_SIGNATURE = 0 -_FH_EXTRACT_VERSION = 1 -_FH_EXTRACT_SYSTEM = 2 -_FH_GENERAL_PURPOSE_FLAG_BITS = 3 -_FH_COMPRESSION_METHOD = 4 -_FH_LAST_MOD_TIME = 5 -_FH_LAST_MOD_DATE = 6 -_FH_CRC = 7 -_FH_COMPRESSED_SIZE = 8 -_FH_UNCOMPRESSED_SIZE = 9 -_FH_FILENAME_LENGTH = 10 -_FH_EXTRA_FIELD_LENGTH = 11 - -# The "Zip64 end of central directory locator" structure, magic number, and size -structEndArchive64Locator = "<4sLQL" -stringEndArchive64Locator = b"PK\x06\x07" -sizeEndCentDir64Locator = struct.calcsize(structEndArchive64Locator) - -# The "Zip64 end of central directory" record, magic number, size, and indices -# (section V.G in the format document) -structEndArchive64 = "<4sQ2H2L4Q" -stringEndArchive64 = b"PK\x06\x06" -sizeEndCentDir64 = struct.calcsize(structEndArchive64) - -_CD64_SIGNATURE = 0 -_CD64_DIRECTORY_RECSIZE = 1 -_CD64_CREATE_VERSION = 2 -_CD64_EXTRACT_VERSION = 3 -_CD64_DISK_NUMBER = 4 -_CD64_DISK_NUMBER_START = 5 -_CD64_NUMBER_ENTRIES_THIS_DISK = 6 -_CD64_NUMBER_ENTRIES_TOTAL = 7 -_CD64_DIRECTORY_SIZE = 8 -_CD64_OFFSET_START_CENTDIR = 9 - -_DD_SIGNATURE = 0x08074b50 - -_EXTRA_FIELD_STRUCT = struct.Struct(' 1: - raise BadZipFile("zipfiles that span multiple disks are not supported") - - # Assume no 'zip64 extensible data' - fpin.seek(offset - sizeEndCentDir64Locator - sizeEndCentDir64, 2) - data = fpin.read(sizeEndCentDir64) - if len(data) != sizeEndCentDir64: - return endrec - sig, sz, create_version, read_version, disk_num, disk_dir, \ - dircount, dircount2, dirsize, diroffset = \ - struct.unpack(structEndArchive64, data) - if sig != stringEndArchive64: - return endrec - - # Update the original endrec using data from the ZIP64 record - endrec[_ECD_SIGNATURE] = sig - endrec[_ECD_DISK_NUMBER] = disk_num - endrec[_ECD_DISK_START] = disk_dir - endrec[_ECD_ENTRIES_THIS_DISK] = dircount - endrec[_ECD_ENTRIES_TOTAL] = dircount2 - endrec[_ECD_SIZE] = dirsize - endrec[_ECD_OFFSET] = diroffset - return endrec - - -def _EndRecData(fpin): - """Return data from the "End of Central Directory" record, or None. - - The data is a list of the nine items in the ZIP "End of central dir" - record followed by a tenth item, the file seek offset of this record.""" - - # Determine file size - fpin.seek(0, 2) - filesize = fpin.tell() - - # Check to see if this is ZIP file with no archive comment (the - # "end of central directory" structure should be the last item in the - # file if this is the case). - try: - fpin.seek(-sizeEndCentDir, 2) - except OSError: - return None - data = fpin.read() - if (len(data) == sizeEndCentDir and - data[0:4] == stringEndArchive and - data[-2:] == b"\000\000"): - # the signature is correct and there's no comment, unpack structure - endrec = struct.unpack(structEndArchive, data) - endrec=list(endrec) - - # Append a blank comment and record start offset - endrec.append(b"") - endrec.append(filesize - sizeEndCentDir) - - # Try to read the "Zip64 end of central directory" structure - return _EndRecData64(fpin, -sizeEndCentDir, endrec) - - # Either this is not a ZIP file, or it is a ZIP file with an archive - # comment. Search the end of the file for the "end of central directory" - # record signature. The comment is the last item in the ZIP file and may be - # up to 64K long. It is assumed that the "end of central directory" magic - # number does not appear in the comment. - maxCommentStart = max(filesize - (1 << 16) - sizeEndCentDir, 0) - fpin.seek(maxCommentStart, 0) - data = fpin.read() - start = data.rfind(stringEndArchive) - if start >= 0: - # found the magic number; attempt to unpack and interpret - recData = data[start:start+sizeEndCentDir] - if len(recData) != sizeEndCentDir: - # Zip file is corrupted. - return None - endrec = list(struct.unpack(structEndArchive, recData)) - commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file - comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize] - endrec.append(comment) - endrec.append(maxCommentStart + start) - - # Try to read the "Zip64 end of central directory" structure - return _EndRecData64(fpin, maxCommentStart + start - filesize, - endrec) - - # Unable to find a valid end of central directory structure - return None - - -class ZipInfo (object): - """Class with attributes describing each file in the ZIP archive.""" - - __slots__ = ( - 'orig_filename', - 'filename', - 'date_time', - 'compress_type', - '_compresslevel', - 'comment', - 'extra', - 'create_system', - 'create_version', - 'extract_version', - 'reserved', - 'flag_bits', - 'volume', - 'internal_attr', - 'external_attr', - 'header_offset', - 'CRC', - 'compress_size', - 'file_size', - '_raw_time', - ) - - def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)): - self.orig_filename = filename # Original file name in archive - - # Terminate the file name at the first null byte. Null bytes in file - # names are used as tricks by viruses in archives. - null_byte = filename.find(chr(0)) - if null_byte >= 0: - filename = filename[0:null_byte] - # This is used to ensure paths in generated ZIP files always use - # forward slashes as the directory separator, as required by the - # ZIP format specification. - if os.sep != "/" and os.sep in filename: - filename = filename.replace(os.sep, "/") - - self.filename = filename # Normalized file name - self.date_time = date_time # year, month, day, hour, min, sec - - if date_time[0] < 1980: - raise ValueError('ZIP does not support timestamps before 1980') - - # Standard values: - self.compress_type = ZIP_STORED # Type of compression for the file - self._compresslevel = None # Level for the compressor - self.comment = b"" # Comment for each file - self.extra = b"" # ZIP extra data - if sys.platform == 'win32': - self.create_system = 0 # System which created ZIP archive - else: - # Assume everything else is unix-y - self.create_system = 3 # System which created ZIP archive - self.create_version = DEFAULT_VERSION # Version which created ZIP archive - self.extract_version = DEFAULT_VERSION # Version needed to extract archive - self.reserved = 0 # Must be zero - self.flag_bits = 0 # ZIP flag bits - self.volume = 0 # Volume number of file header - self.internal_attr = 0 # Internal attributes - self.external_attr = 0 # External file attributes - self.compress_size = 0 # Size of the compressed file - self.file_size = 0 # Size of the uncompressed file - # Other attributes are set by class ZipFile: - # header_offset Byte offset to the file header - # CRC CRC-32 of the uncompressed file - - def __repr__(self): - result = ['<%s filename=%r' % (self.__class__.__name__, self.filename)] - if self.compress_type != ZIP_STORED: - result.append(' compress_type=%s' % - compressor_names.get(self.compress_type, - self.compress_type)) - hi = self.external_attr >> 16 - lo = self.external_attr & 0xFFFF - if hi: - result.append(' filemode=%r' % stat.filemode(hi)) - if lo: - result.append(' external_attr=%#x' % lo) - isdir = self.is_dir() - if not isdir or self.file_size: - result.append(' file_size=%r' % self.file_size) - if ((not isdir or self.compress_size) and - (self.compress_type != ZIP_STORED or - self.file_size != self.compress_size)): - result.append(' compress_size=%r' % self.compress_size) - result.append('>') - return ''.join(result) - - def FileHeader(self, zip64=None): - """Return the per-file header as a bytes object.""" - dt = self.date_time - dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2] - dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2) - if self.flag_bits & _MASK_USE_DATA_DESCRIPTOR: - # Set these to zero because we write them after the file data - CRC = compress_size = file_size = 0 - else: - CRC = self.CRC - compress_size = self.compress_size - file_size = self.file_size - - extra = self.extra - - min_version = 0 - if zip64 is None: - zip64 = file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT - if zip64: - fmt = ' ZIP64_LIMIT or compress_size > ZIP64_LIMIT: - if not zip64: - raise LargeZipFile("Filesize would require ZIP64 extensions") - # File is larger than what fits into a 4 byte integer, - # fall back to the ZIP64 extension - file_size = 0xffffffff - compress_size = 0xffffffff - min_version = ZIP64_VERSION - - if self.compress_type == ZIP_BZIP2: - min_version = max(BZIP2_VERSION, min_version) - elif self.compress_type == ZIP_LZMA: - min_version = max(LZMA_VERSION, min_version) - - self.extract_version = max(min_version, self.extract_version) - self.create_version = max(min_version, self.create_version) - filename, flag_bits = self._encodeFilenameFlags() - header = struct.pack(structFileHeader, stringFileHeader, - self.extract_version, self.reserved, flag_bits, - self.compress_type, dostime, dosdate, CRC, - compress_size, file_size, - len(filename), len(extra)) - return header + filename + extra - - def _encodeFilenameFlags(self): - try: - return self.filename.encode('ascii'), self.flag_bits - except UnicodeEncodeError: - return self.filename.encode('utf-8'), self.flag_bits | _MASK_UTF_FILENAME - - def _decodeExtra(self): - # Try to decode the extra field. - extra = self.extra - unpack = struct.unpack - while len(extra) >= 4: - tp, ln = unpack(' len(extra): - raise BadZipFile("Corrupt extra field %04x (size=%d)" % (tp, ln)) - if tp == 0x0001: - data = extra[4:ln+4] - # ZIP64 extension (large files and/or large archives) - try: - if self.file_size in (0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF): - field = "File size" - self.file_size, = unpack(' 2107: - date_time = (2107, 12, 31, 23, 59, 59) - # Create ZipInfo instance to store file information - if arcname is None: - arcname = filename - arcname = os.path.normpath(os.path.splitdrive(arcname)[1]) - while arcname[0] in (os.sep, os.altsep): - arcname = arcname[1:] - if isdir: - arcname += '/' - zinfo = cls(arcname, date_time) - zinfo.external_attr = (st.st_mode & 0xFFFF) << 16 # Unix attributes - if isdir: - zinfo.file_size = 0 - zinfo.external_attr |= 0x10 # MS-DOS directory flag - else: - zinfo.file_size = st.st_size - - return zinfo - - def is_dir(self): - """Return True if this archive member is a directory.""" - return self.filename[-1] == '/' - - -# ZIP encryption uses the CRC32 one-byte primitive for scrambling some -# internal keys. We noticed that a direct implementation is faster than -# relying on binascii.crc32(). - -_crctable = None -def _gen_crc(crc): - for j in range(8): - if crc & 1: - crc = (crc >> 1) ^ 0xEDB88320 - else: - crc >>= 1 - return crc - -# ZIP supports a password-based form of encryption. Even though known -# plaintext attacks have been found against it, it is still useful -# to be able to get data out of such a file. -# -# Usage: -# zd = _ZipDecrypter(mypwd) -# plain_bytes = zd(cypher_bytes) - -def _ZipDecrypter(pwd): - key0 = 305419896 - key1 = 591751049 - key2 = 878082192 - - global _crctable - if _crctable is None: - _crctable = list(map(_gen_crc, range(256))) - crctable = _crctable - - def crc32(ch, crc): - """Compute the CRC32 primitive on one byte.""" - return (crc >> 8) ^ crctable[(crc ^ ch) & 0xFF] - - def update_keys(c): - nonlocal key0, key1, key2 - key0 = crc32(c, key0) - key1 = (key1 + (key0 & 0xFF)) & 0xFFFFFFFF - key1 = (key1 * 134775813 + 1) & 0xFFFFFFFF - key2 = crc32(key1 >> 24, key2) - - for p in pwd: - update_keys(p) - - def decrypter(data): - """Decrypt a bytes object.""" - result = bytearray() - append = result.append - for c in data: - k = key2 | 2 - c ^= ((k * (k^1)) >> 8) & 0xFF - update_keys(c) - append(c) - return bytes(result) - - return decrypter - - -class LZMACompressor: - - def __init__(self): - self._comp = None - - def _init(self): - props = lzma._encode_filter_properties({'id': lzma.FILTER_LZMA1}) - self._comp = lzma.LZMACompressor(lzma.FORMAT_RAW, filters=[ - lzma._decode_filter_properties(lzma.FILTER_LZMA1, props) - ]) - return struct.pack('> 8) & 0xff - else: - # compare against the CRC otherwise - check_byte = (zipinfo.CRC >> 24) & 0xff - h = self._init_decrypter() - if h != check_byte: - raise RuntimeError("Bad password for file %r" % zipinfo.orig_filename) - - - def _init_decrypter(self): - self._decrypter = _ZipDecrypter(self._pwd) - # The first 12 bytes in the cypher stream is an encryption header - # used to strengthen the algorithm. The first 11 bytes are - # completely random, while the 12th contains the MSB of the CRC, - # or the MSB of the file time depending on the header type - # and is used to check the correctness of the password. - header = self._fileobj.read(12) - self._compress_left -= 12 - return self._decrypter(header)[11] - - def __repr__(self): - result = ['<%s.%s' % (self.__class__.__module__, - self.__class__.__qualname__)] - if not self.closed: - result.append(' name=%r mode=%r' % (self.name, self.mode)) - if self._compress_type != ZIP_STORED: - result.append(' compress_type=%s' % - compressor_names.get(self._compress_type, - self._compress_type)) - else: - result.append(' [closed]') - result.append('>') - return ''.join(result) - - def readline(self, limit=-1): - """Read and return a line from the stream. - - If limit is specified, at most limit bytes will be read. - """ - - if limit < 0: - # Shortcut common case - newline found in buffer. - i = self._readbuffer.find(b'\n', self._offset) + 1 - if i > 0: - line = self._readbuffer[self._offset: i] - self._offset = i - return line - - return io.BufferedIOBase.readline(self, limit) - - def peek(self, n=1): - """Returns buffered bytes without advancing the position.""" - if n > len(self._readbuffer) - self._offset: - chunk = self.read(n) - if len(chunk) > self._offset: - self._readbuffer = chunk + self._readbuffer[self._offset:] - self._offset = 0 - else: - self._offset -= len(chunk) - - # Return up to 512 bytes to reduce allocation overhead for tight loops. - return self._readbuffer[self._offset: self._offset + 512] - - def readable(self): - if self.closed: - raise ValueError("I/O operation on closed file.") - return True - - def read(self, n=-1): - """Read and return up to n bytes. - If the argument is omitted, None, or negative, data is read and returned until EOF is reached. - """ - if self.closed: - raise ValueError("read from closed file.") - if n is None or n < 0: - buf = self._readbuffer[self._offset:] - self._readbuffer = b'' - self._offset = 0 - while not self._eof: - buf += self._read1(self.MAX_N) - return buf - - end = n + self._offset - if end < len(self._readbuffer): - buf = self._readbuffer[self._offset:end] - self._offset = end - return buf - - n = end - len(self._readbuffer) - buf = self._readbuffer[self._offset:] - self._readbuffer = b'' - self._offset = 0 - while n > 0 and not self._eof: - data = self._read1(n) - if n < len(data): - self._readbuffer = data - self._offset = n - buf += data[:n] - break - buf += data - n -= len(data) - return buf - - def _update_crc(self, newdata): - # Update the CRC using the given data. - if self._expected_crc is None: - # No need to compute the CRC if we don't have a reference value - return - self._running_crc = crc32(newdata, self._running_crc) - # Check the CRC if we're at the end of the file - if self._eof and self._running_crc != self._expected_crc: - raise BadZipFile("Bad CRC-32 for file %r" % self.name) - - def read1(self, n): - """Read up to n bytes with at most one read() system call.""" - - if n is None or n < 0: - buf = self._readbuffer[self._offset:] - self._readbuffer = b'' - self._offset = 0 - while not self._eof: - data = self._read1(self.MAX_N) - if data: - buf += data - break - return buf - - end = n + self._offset - if end < len(self._readbuffer): - buf = self._readbuffer[self._offset:end] - self._offset = end - return buf - - n = end - len(self._readbuffer) - buf = self._readbuffer[self._offset:] - self._readbuffer = b'' - self._offset = 0 - if n > 0: - while not self._eof: - data = self._read1(n) - if n < len(data): - self._readbuffer = data - self._offset = n - buf += data[:n] - break - if data: - buf += data - break - return buf - - def _read1(self, n): - # Read up to n compressed bytes with at most one read() system call, - # decrypt and decompress them. - if self._eof or n <= 0: - return b'' - - # Read from file. - if self._compress_type == ZIP_DEFLATED: - ## Handle unconsumed data. - data = self._decompressor.unconsumed_tail - if n > len(data): - data += self._read2(n - len(data)) - else: - data = self._read2(n) - - if self._compress_type == ZIP_STORED: - self._eof = self._compress_left <= 0 - elif self._compress_type == ZIP_DEFLATED: - n = max(n, self.MIN_READ_SIZE) - data = self._decompressor.decompress(data, n) - self._eof = (self._decompressor.eof or - self._compress_left <= 0 and - not self._decompressor.unconsumed_tail) - if self._eof: - data += self._decompressor.flush() - else: - data = self._decompressor.decompress(data) - self._eof = self._decompressor.eof or self._compress_left <= 0 - - data = data[:self._left] - self._left -= len(data) - if self._left <= 0: - self._eof = True - self._update_crc(data) - return data - - def _read2(self, n): - if self._compress_left <= 0: - return b'' - - n = max(n, self.MIN_READ_SIZE) - n = min(n, self._compress_left) - - data = self._fileobj.read(n) - self._compress_left -= len(data) - if not data: - raise EOFError - - if self._decrypter is not None: - data = self._decrypter(data) - return data - - def close(self): - try: - if self._close_fileobj: - self._fileobj.close() - finally: - super().close() - - def seekable(self): - if self.closed: - raise ValueError("I/O operation on closed file.") - return self._seekable - - def seek(self, offset, whence=0): - if self.closed: - raise ValueError("seek on closed file.") - if not self._seekable: - raise io.UnsupportedOperation("underlying stream is not seekable") - curr_pos = self.tell() - if whence == 0: # Seek from start of file - new_pos = offset - elif whence == 1: # Seek from current position - new_pos = curr_pos + offset - elif whence == 2: # Seek from EOF - new_pos = self._orig_file_size + offset - else: - raise ValueError("whence must be os.SEEK_SET (0), " - "os.SEEK_CUR (1), or os.SEEK_END (2)") - - if new_pos > self._orig_file_size: - new_pos = self._orig_file_size - - if new_pos < 0: - new_pos = 0 - - read_offset = new_pos - curr_pos - buff_offset = read_offset + self._offset - - if buff_offset >= 0 and buff_offset < len(self._readbuffer): - # Just move the _offset index if the new position is in the _readbuffer - self._offset = buff_offset - read_offset = 0 - elif read_offset < 0: - # Position is before the current position. Reset the ZipExtFile - self._fileobj.seek(self._orig_compress_start) - self._running_crc = self._orig_start_crc - self._compress_left = self._orig_compress_size - self._left = self._orig_file_size - self._readbuffer = b'' - self._offset = 0 - self._decompressor = _get_decompressor(self._compress_type) - self._eof = False - read_offset = new_pos - if self._decrypter is not None: - self._init_decrypter() - - while read_offset > 0: - read_len = min(self.MAX_SEEK_READ, read_offset) - self.read(read_len) - read_offset -= read_len - - return self.tell() - - def tell(self): - if self.closed: - raise ValueError("tell on closed file.") - if not self._seekable: - raise io.UnsupportedOperation("underlying stream is not seekable") - filepos = self._orig_file_size - self._left - len(self._readbuffer) + self._offset - return filepos - - -class _ZipWriteFile(io.BufferedIOBase): - def __init__(self, zf, zinfo, zip64): - self._zinfo = zinfo - self._zip64 = zip64 - self._zipfile = zf - self._compressor = _get_compressor(zinfo.compress_type, - zinfo._compresslevel) - self._file_size = 0 - self._compress_size = 0 - self._crc = 0 - - @property - def _fileobj(self): - return self._zipfile.fp - - def writable(self): - return True - - def write(self, data): - if self.closed: - raise ValueError('I/O operation on closed file.') - - # Accept any data that supports the buffer protocol - if isinstance(data, (bytes, bytearray)): - nbytes = len(data) - else: - data = memoryview(data) - nbytes = data.nbytes - self._file_size += nbytes - - self._crc = crc32(data, self._crc) - if self._compressor: - data = self._compressor.compress(data) - self._compress_size += len(data) - self._fileobj.write(data) - return nbytes - - def close(self): - if self.closed: - return - try: - super().close() - # Flush any data from the compressor, and update header info - if self._compressor: - buf = self._compressor.flush() - self._compress_size += len(buf) - self._fileobj.write(buf) - self._zinfo.compress_size = self._compress_size - else: - self._zinfo.compress_size = self._file_size - self._zinfo.CRC = self._crc - self._zinfo.file_size = self._file_size - - # Write updated header info - if self._zinfo.flag_bits & _MASK_USE_DATA_DESCRIPTOR: - # Write CRC and file sizes after the file data - fmt = ' ZIP64_LIMIT: - raise RuntimeError( - 'File size unexpectedly exceeded ZIP64 limit') - if self._compress_size > ZIP64_LIMIT: - raise RuntimeError( - 'Compressed size unexpectedly exceeded ZIP64 limit') - # Seek backwards and write file header (which will now include - # correct CRC and file sizes) - - # Preserve current position in file - self._zipfile.start_dir = self._fileobj.tell() - self._fileobj.seek(self._zinfo.header_offset) - self._fileobj.write(self._zinfo.FileHeader(self._zip64)) - self._fileobj.seek(self._zipfile.start_dir) - - # Successfully written: Add file to our caches - self._zipfile.filelist.append(self._zinfo) - self._zipfile.NameToInfo[self._zinfo.filename] = self._zinfo - finally: - self._zipfile._writing = False - - - -class ZipFile: - """ Class with methods to open, read, write, close, list zip files. - - z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=True, - compresslevel=None) - - file: Either the path to the file, or a file-like object. - If it is a path, the file will be opened and closed by ZipFile. - mode: The mode can be either read 'r', write 'w', exclusive create 'x', - or append 'a'. - compression: ZIP_STORED (no compression), ZIP_DEFLATED (requires zlib), - ZIP_BZIP2 (requires bz2) or ZIP_LZMA (requires lzma). - allowZip64: if True ZipFile will create files with ZIP64 extensions when - needed, otherwise it will raise an exception when this would - be necessary. - compresslevel: None (default for the given compression type) or an integer - specifying the level to pass to the compressor. - When using ZIP_STORED or ZIP_LZMA this keyword has no effect. - When using ZIP_DEFLATED integers 0 through 9 are accepted. - When using ZIP_BZIP2 integers 1 through 9 are accepted. - - """ - - fp = None # Set here since __del__ checks it - _windows_illegal_name_trans_table = None - - def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True, - compresslevel=None, *, strict_timestamps=True, metadata_encoding=None): - """Open the ZIP file with mode read 'r', write 'w', exclusive create 'x', - or append 'a'.""" - if mode not in ('r', 'w', 'x', 'a'): - raise ValueError("ZipFile requires mode 'r', 'w', 'x', or 'a'") - - _check_compression(compression) - - self._allowZip64 = allowZip64 - self._didModify = False - self.debug = 0 # Level of printing: 0 through 3 - self.NameToInfo = {} # Find file info given name - self.filelist = [] # List of ZipInfo instances for archive - self.compression = compression # Method of compression - self.compresslevel = compresslevel - self.mode = mode - self.pwd = None - self._comment = b'' - self._strict_timestamps = strict_timestamps - self.metadata_encoding = metadata_encoding - - # Check that we don't try to write with nonconforming codecs - if self.metadata_encoding and mode != 'r': - raise ValueError( - "metadata_encoding is only supported for reading files") - - # Check if we were passed a file-like object - if isinstance(file, os.PathLike): - file = os.fspath(file) - if isinstance(file, str): - # No, it's a filename - self._filePassed = 0 - self.filename = file - modeDict = {'r' : 'rb', 'w': 'w+b', 'x': 'x+b', 'a' : 'r+b', - 'r+b': 'w+b', 'w+b': 'wb', 'x+b': 'xb'} - filemode = modeDict[mode] - while True: - try: - self.fp = io.open(file, filemode) - except OSError: - if filemode in modeDict: - filemode = modeDict[filemode] - continue - raise - break - else: - self._filePassed = 1 - self.fp = file - self.filename = getattr(file, 'name', None) - self._fileRefCnt = 1 - self._lock = threading.RLock() - self._seekable = True - self._writing = False - - try: - if mode == 'r': - self._RealGetContents() - elif mode in ('w', 'x'): - # set the modified flag so central directory gets written - # even if no files are added to the archive - self._didModify = True - try: - self.start_dir = self.fp.tell() - except (AttributeError, OSError): - self.fp = _Tellable(self.fp) - self.start_dir = 0 - self._seekable = False - else: - # Some file-like objects can provide tell() but not seek() - try: - self.fp.seek(self.start_dir) - except (AttributeError, OSError): - self._seekable = False - elif mode == 'a': - try: - # See if file is a zip file - self._RealGetContents() - # seek to start of directory and overwrite - self.fp.seek(self.start_dir) - except BadZipFile: - # file is not a zip file, just append - self.fp.seek(0, 2) - - # set the modified flag so central directory gets written - # even if no files are added to the archive - self._didModify = True - self.start_dir = self.fp.tell() - else: - raise ValueError("Mode must be 'r', 'w', 'x', or 'a'") - except: - fp = self.fp - self.fp = None - self._fpclose(fp) - raise - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - self.close() - - def __repr__(self): - result = ['<%s.%s' % (self.__class__.__module__, - self.__class__.__qualname__)] - if self.fp is not None: - if self._filePassed: - result.append(' file=%r' % self.fp) - elif self.filename is not None: - result.append(' filename=%r' % self.filename) - result.append(' mode=%r' % self.mode) - else: - result.append(' [closed]') - result.append('>') - return ''.join(result) - - def _RealGetContents(self): - """Read in the table of contents for the ZIP file.""" - fp = self.fp - try: - endrec = _EndRecData(fp) - except OSError: - raise BadZipFile("File is not a zip file") - if not endrec: - raise BadZipFile("File is not a zip file") - if self.debug > 1: - print(endrec) - size_cd = endrec[_ECD_SIZE] # bytes in central directory - offset_cd = endrec[_ECD_OFFSET] # offset of central directory - self._comment = endrec[_ECD_COMMENT] # archive comment - - # "concat" is zero, unless zip was concatenated to another file - concat = endrec[_ECD_LOCATION] - size_cd - offset_cd - if endrec[_ECD_SIGNATURE] == stringEndArchive64: - # If Zip64 extension structures are present, account for them - concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator) - - if self.debug > 2: - inferred = concat + offset_cd - print("given, inferred, offset", offset_cd, inferred, concat) - # self.start_dir: Position of start of central directory - self.start_dir = offset_cd + concat - if self.start_dir < 0: - raise BadZipFile("Bad offset for central directory") - fp.seek(self.start_dir, 0) - data = fp.read(size_cd) - fp = io.BytesIO(data) - total = 0 - while total < size_cd: - centdir = fp.read(sizeCentralDir) - if len(centdir) != sizeCentralDir: - raise BadZipFile("Truncated central directory") - centdir = struct.unpack(structCentralDir, centdir) - if centdir[_CD_SIGNATURE] != stringCentralDir: - raise BadZipFile("Bad magic number for central directory") - if self.debug > 2: - print(centdir) - filename = fp.read(centdir[_CD_FILENAME_LENGTH]) - flags = centdir[_CD_FLAG_BITS] - if flags & _MASK_UTF_FILENAME: - # UTF-8 file names extension - filename = filename.decode('utf-8') - else: - # Historical ZIP filename encoding - filename = filename.decode(self.metadata_encoding or 'cp437') - # Create ZipInfo instance to store file information - x = ZipInfo(filename) - x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH]) - x.comment = fp.read(centdir[_CD_COMMENT_LENGTH]) - x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET] - (x.create_version, x.create_system, x.extract_version, x.reserved, - x.flag_bits, x.compress_type, t, d, - x.CRC, x.compress_size, x.file_size) = centdir[1:12] - if x.extract_version > MAX_EXTRACT_VERSION: - raise NotImplementedError("zip file version %.1f" % - (x.extract_version / 10)) - x.volume, x.internal_attr, x.external_attr = centdir[15:18] - # Convert date/time code to (year, month, day, hour, min, sec) - x._raw_time = t - x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F, - t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) - - x._decodeExtra() - x.header_offset = x.header_offset + concat - self.filelist.append(x) - self.NameToInfo[x.filename] = x - - # update total bytes read from central directory - total = (total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH] - + centdir[_CD_EXTRA_FIELD_LENGTH] - + centdir[_CD_COMMENT_LENGTH]) - - if self.debug > 2: - print("total", total) - - - def namelist(self): - """Return a list of file names in the archive.""" - return [data.filename for data in self.filelist] - - def infolist(self): - """Return a list of class ZipInfo instances for files in the - archive.""" - return self.filelist - - def printdir(self, file=None): - """Print a table of contents for the zip file.""" - print("%-46s %19s %12s" % ("File Name", "Modified ", "Size"), - file=file) - for zinfo in self.filelist: - date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time[:6] - print("%-46s %s %12d" % (zinfo.filename, date, zinfo.file_size), - file=file) - - def testzip(self): - """Read all the files and check the CRC.""" - chunk_size = 2 ** 20 - for zinfo in self.filelist: - try: - # Read by chunks, to avoid an OverflowError or a - # MemoryError with very large embedded files. - with self.open(zinfo.filename, "r") as f: - while f.read(chunk_size): # Check CRC-32 - pass - except BadZipFile: - return zinfo.filename - - def getinfo(self, name): - """Return the instance of ZipInfo given 'name'.""" - info = self.NameToInfo.get(name) - if info is None: - raise KeyError( - 'There is no item named %r in the archive' % name) - - return info - - def setpassword(self, pwd): - """Set default password for encrypted files.""" - if pwd and not isinstance(pwd, bytes): - raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__) - if pwd: - self.pwd = pwd - else: - self.pwd = None - - @property - def comment(self): - """The comment text associated with the ZIP file.""" - return self._comment - - @comment.setter - def comment(self, comment): - if not isinstance(comment, bytes): - raise TypeError("comment: expected bytes, got %s" % type(comment).__name__) - # check for valid comment length - if len(comment) > ZIP_MAX_COMMENT: - import warnings - warnings.warn('Archive comment is too long; truncating to %d bytes' - % ZIP_MAX_COMMENT, stacklevel=2) - comment = comment[:ZIP_MAX_COMMENT] - self._comment = comment - self._didModify = True - - def read(self, name, pwd=None): - """Return file bytes for name.""" - with self.open(name, "r", pwd) as fp: - return fp.read() - - def open(self, name, mode="r", pwd=None, *, force_zip64=False): - """Return file-like object for 'name'. - - name is a string for the file name within the ZIP file, or a ZipInfo - object. - - mode should be 'r' to read a file already in the ZIP file, or 'w' to - write to a file newly added to the archive. - - pwd is the password to decrypt files (only used for reading). - - When writing, if the file size is not known in advance but may exceed - 2 GiB, pass force_zip64 to use the ZIP64 format, which can handle large - files. If the size is known in advance, it is best to pass a ZipInfo - instance for name, with zinfo.file_size set. - """ - if mode not in {"r", "w"}: - raise ValueError('open() requires mode "r" or "w"') - if pwd and (mode == "w"): - raise ValueError("pwd is only supported for reading files") - if not self.fp: - raise ValueError( - "Attempt to use ZIP archive that was already closed") - - # Make sure we have an info object - if isinstance(name, ZipInfo): - # 'name' is already an info object - zinfo = name - elif mode == 'w': - zinfo = ZipInfo(name) - zinfo.compress_type = self.compression - zinfo._compresslevel = self.compresslevel - else: - # Get info object for name - zinfo = self.getinfo(name) - - if mode == 'w': - return self._open_to_write(zinfo, force_zip64=force_zip64) - - if self._writing: - raise ValueError("Can't read from the ZIP file while there " - "is an open writing handle on it. " - "Close the writing handle before trying to read.") - - # Open for reading: - self._fileRefCnt += 1 - zef_file = _SharedFile(self.fp, zinfo.header_offset, - self._fpclose, self._lock, lambda: self._writing) - try: - # Skip the file header: - fheader = zef_file.read(sizeFileHeader) - if len(fheader) != sizeFileHeader: - raise BadZipFile("Truncated file header") - fheader = struct.unpack(structFileHeader, fheader) - if fheader[_FH_SIGNATURE] != stringFileHeader: - raise BadZipFile("Bad magic number for file header") - - fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) - if fheader[_FH_EXTRA_FIELD_LENGTH]: - zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) - - if zinfo.flag_bits & _MASK_COMPRESSED_PATCH: - # Zip 2.7: compressed patched data - raise NotImplementedError("compressed patched data (flag bit 5)") - - if zinfo.flag_bits & _MASK_STRONG_ENCRYPTION: - # strong encryption - raise NotImplementedError("strong encryption (flag bit 6)") - - if fheader[_FH_GENERAL_PURPOSE_FLAG_BITS] & _MASK_UTF_FILENAME: - # UTF-8 filename - fname_str = fname.decode("utf-8") - else: - fname_str = fname.decode(self.metadata_encoding or "cp437") - - if fname_str != zinfo.orig_filename: - raise BadZipFile( - 'File name in directory %r and header %r differ.' - % (zinfo.orig_filename, fname)) - - # check for encrypted flag & handle password - is_encrypted = zinfo.flag_bits & _MASK_ENCRYPTED - if is_encrypted: - if not pwd: - pwd = self.pwd - if pwd and not isinstance(pwd, bytes): - raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__) - if not pwd: - raise RuntimeError("File %r is encrypted, password " - "required for extraction" % name) - else: - pwd = None - - return ZipExtFile(zef_file, mode, zinfo, pwd, True) - except: - zef_file.close() - raise - - def _open_to_write(self, zinfo, force_zip64=False): - if force_zip64 and not self._allowZip64: - raise ValueError( - "force_zip64 is True, but allowZip64 was False when opening " - "the ZIP file." - ) - if self._writing: - raise ValueError("Can't write to the ZIP file while there is " - "another write handle open on it. " - "Close the first handle before opening another.") - - # Size and CRC are overwritten with correct data after processing the file - zinfo.compress_size = 0 - zinfo.CRC = 0 - - zinfo.flag_bits = 0x00 - if zinfo.compress_type == ZIP_LZMA: - # Compressed data includes an end-of-stream (EOS) marker - zinfo.flag_bits |= _MASK_COMPRESS_OPTION_1 - if not self._seekable: - zinfo.flag_bits |= _MASK_USE_DATA_DESCRIPTOR - - if not zinfo.external_attr: - zinfo.external_attr = 0o600 << 16 # permissions: ?rw------- - - # Compressed size can be larger than uncompressed size - zip64 = self._allowZip64 and \ - (force_zip64 or zinfo.file_size * 1.05 > ZIP64_LIMIT) - - if self._seekable: - self.fp.seek(self.start_dir) - zinfo.header_offset = self.fp.tell() - - self._writecheck(zinfo) - self._didModify = True - - self.fp.write(zinfo.FileHeader(zip64)) - - self._writing = True - return _ZipWriteFile(self, zinfo, zip64) - - def extract(self, member, path=None, pwd=None): - """Extract a member from the archive to the current working directory, - using its full name. Its file information is extracted as accurately - as possible. `member' may be a filename or a ZipInfo object. You can - specify a different directory using `path'. - """ - if path is None: - path = os.getcwd() - else: - path = os.fspath(path) - - return self._extract_member(member, path, pwd) - - def extractall(self, path=None, members=None, pwd=None): - """Extract all members from the archive to the current working - directory. `path' specifies a different directory to extract to. - `members' is optional and must be a subset of the list returned - by namelist(). - """ - if members is None: - members = self.namelist() - - if path is None: - path = os.getcwd() - else: - path = os.fspath(path) - - for zipinfo in members: - self._extract_member(zipinfo, path, pwd) - - @classmethod - def _sanitize_windows_name(cls, arcname, pathsep): - """Replace bad characters and remove trailing dots from parts.""" - table = cls._windows_illegal_name_trans_table - if not table: - illegal = ':<>|"?*' - table = str.maketrans(illegal, '_' * len(illegal)) - cls._windows_illegal_name_trans_table = table - arcname = arcname.translate(table) - # remove trailing dots - arcname = (x.rstrip('.') for x in arcname.split(pathsep)) - # rejoin, removing empty parts. - arcname = pathsep.join(x for x in arcname if x) - return arcname - - def _extract_member(self, member, targetpath, pwd): - """Extract the ZipInfo object 'member' to a physical - file on the path targetpath. - """ - if not isinstance(member, ZipInfo): - member = self.getinfo(member) - - # build the destination pathname, replacing - # forward slashes to platform specific separators. - arcname = member.filename.replace('/', os.path.sep) - - if os.path.altsep: - arcname = arcname.replace(os.path.altsep, os.path.sep) - # interpret absolute pathname as relative, remove drive letter or - # UNC path, redundant separators, "." and ".." components. - arcname = os.path.splitdrive(arcname)[1] - invalid_path_parts = ('', os.path.curdir, os.path.pardir) - arcname = os.path.sep.join(x for x in arcname.split(os.path.sep) - if x not in invalid_path_parts) - if os.path.sep == '\\': - # filter illegal characters on Windows - arcname = self._sanitize_windows_name(arcname, os.path.sep) - - targetpath = os.path.join(targetpath, arcname) - targetpath = os.path.normpath(targetpath) - - # Create all upper directories if necessary. - upperdirs = os.path.dirname(targetpath) - if upperdirs and not os.path.exists(upperdirs): - os.makedirs(upperdirs) - - if member.is_dir(): - if not os.path.isdir(targetpath): - os.mkdir(targetpath) - return targetpath - - with self.open(member, pwd=pwd) as source, \ - open(targetpath, "wb") as target: - shutil.copyfileobj(source, target) - - return targetpath - - def _writecheck(self, zinfo): - """Check for errors before writing a file to the archive.""" - if zinfo.filename in self.NameToInfo: - import warnings - warnings.warn('Duplicate name: %r' % zinfo.filename, stacklevel=3) - if self.mode not in ('w', 'x', 'a'): - raise ValueError("write() requires mode 'w', 'x', or 'a'") - if not self.fp: - raise ValueError( - "Attempt to write ZIP archive that was already closed") - _check_compression(zinfo.compress_type) - if not self._allowZip64: - requires_zip64 = None - if len(self.filelist) >= ZIP_FILECOUNT_LIMIT: - requires_zip64 = "Files count" - elif zinfo.file_size > ZIP64_LIMIT: - requires_zip64 = "Filesize" - elif zinfo.header_offset > ZIP64_LIMIT: - requires_zip64 = "Zipfile size" - if requires_zip64: - raise LargeZipFile(requires_zip64 + - " would require ZIP64 extensions") - - def write(self, filename, arcname=None, - compress_type=None, compresslevel=None): - """Put the bytes from filename into the archive under the name - arcname.""" - if not self.fp: - raise ValueError( - "Attempt to write to ZIP archive that was already closed") - if self._writing: - raise ValueError( - "Can't write to ZIP archive while an open writing handle exists" - ) - - zinfo = ZipInfo.from_file(filename, arcname, - strict_timestamps=self._strict_timestamps) - - if zinfo.is_dir(): - zinfo.compress_size = 0 - zinfo.CRC = 0 - self.mkdir(zinfo) - else: - if compress_type is not None: - zinfo.compress_type = compress_type - else: - zinfo.compress_type = self.compression - - if compresslevel is not None: - zinfo._compresslevel = compresslevel - else: - zinfo._compresslevel = self.compresslevel - - with open(filename, "rb") as src, self.open(zinfo, 'w') as dest: - shutil.copyfileobj(src, dest, 1024*8) - - def writestr(self, zinfo_or_arcname, data, - compress_type=None, compresslevel=None): - """Write a file into the archive. The contents is 'data', which - may be either a 'str' or a 'bytes' instance; if it is a 'str', - it is encoded as UTF-8 first. - 'zinfo_or_arcname' is either a ZipInfo instance or - the name of the file in the archive.""" - if isinstance(data, str): - data = data.encode("utf-8") - if not isinstance(zinfo_or_arcname, ZipInfo): - zinfo = ZipInfo(filename=zinfo_or_arcname, - date_time=time.localtime(time.time())[:6]) - zinfo.compress_type = self.compression - zinfo._compresslevel = self.compresslevel - if zinfo.filename[-1] == '/': - zinfo.external_attr = 0o40775 << 16 # drwxrwxr-x - zinfo.external_attr |= 0x10 # MS-DOS directory flag - else: - zinfo.external_attr = 0o600 << 16 # ?rw------- - else: - zinfo = zinfo_or_arcname - - if not self.fp: - raise ValueError( - "Attempt to write to ZIP archive that was already closed") - if self._writing: - raise ValueError( - "Can't write to ZIP archive while an open writing handle exists." - ) - - if compress_type is not None: - zinfo.compress_type = compress_type - - if compresslevel is not None: - zinfo._compresslevel = compresslevel - - zinfo.file_size = len(data) # Uncompressed size - with self._lock: - with self.open(zinfo, mode='w') as dest: - dest.write(data) - - def mkdir(self, zinfo_or_directory_name, mode=511): - """Creates a directory inside the zip archive.""" - if isinstance(zinfo_or_directory_name, ZipInfo): - zinfo = zinfo_or_directory_name - if not zinfo.is_dir(): - raise ValueError("The given ZipInfo does not describe a directory") - elif isinstance(zinfo_or_directory_name, str): - directory_name = zinfo_or_directory_name - if not directory_name.endswith("/"): - directory_name += "/" - zinfo = ZipInfo(directory_name) - zinfo.compress_size = 0 - zinfo.CRC = 0 - zinfo.external_attr = ((0o40000 | mode) & 0xFFFF) << 16 - zinfo.file_size = 0 - zinfo.external_attr |= 0x10 - else: - raise TypeError("Expected type str or ZipInfo") - - with self._lock: - if self._seekable: - self.fp.seek(self.start_dir) - zinfo.header_offset = self.fp.tell() # Start of header bytes - if zinfo.compress_type == ZIP_LZMA: - # Compressed data includes an end-of-stream (EOS) marker - zinfo.flag_bits |= _MASK_COMPRESS_OPTION_1 - - self._writecheck(zinfo) - self._didModify = True - - self.filelist.append(zinfo) - self.NameToInfo[zinfo.filename] = zinfo - self.fp.write(zinfo.FileHeader(False)) - self.start_dir = self.fp.tell() - - def __del__(self): - """Call the "close()" method in case the user forgot.""" - self.close() - - def close(self): - """Close the file, and for mode 'w', 'x' and 'a' write the ending - records.""" - if self.fp is None: - return - - if self._writing: - raise ValueError("Can't close the ZIP file while there is " - "an open writing handle on it. " - "Close the writing handle before closing the zip.") - - try: - if self.mode in ('w', 'x', 'a') and self._didModify: # write ending records - with self._lock: - if self._seekable: - self.fp.seek(self.start_dir) - self._write_end_record() - finally: - fp = self.fp - self.fp = None - self._fpclose(fp) - - def _write_end_record(self): - for zinfo in self.filelist: # write central directory - dt = zinfo.date_time - dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2] - dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2) - extra = [] - if zinfo.file_size > ZIP64_LIMIT \ - or zinfo.compress_size > ZIP64_LIMIT: - extra.append(zinfo.file_size) - extra.append(zinfo.compress_size) - file_size = 0xffffffff - compress_size = 0xffffffff - else: - file_size = zinfo.file_size - compress_size = zinfo.compress_size - - if zinfo.header_offset > ZIP64_LIMIT: - extra.append(zinfo.header_offset) - header_offset = 0xffffffff - else: - header_offset = zinfo.header_offset - - extra_data = zinfo.extra - min_version = 0 - if extra: - # Append a ZIP64 field to the extra's - extra_data = _strip_extra(extra_data, (1,)) - extra_data = struct.pack( - ' ZIP_FILECOUNT_LIMIT: - requires_zip64 = "Files count" - elif centDirOffset > ZIP64_LIMIT: - requires_zip64 = "Central directory offset" - elif centDirSize > ZIP64_LIMIT: - requires_zip64 = "Central directory size" - if requires_zip64: - # Need to write the ZIP64 end-of-archive records - if not self._allowZip64: - raise LargeZipFile(requires_zip64 + - " would require ZIP64 extensions") - zip64endrec = struct.pack( - structEndArchive64, stringEndArchive64, - 44, 45, 45, 0, 0, centDirCount, centDirCount, - centDirSize, centDirOffset) - self.fp.write(zip64endrec) - - zip64locrec = struct.pack( - structEndArchive64Locator, - stringEndArchive64Locator, 0, pos2, 1) - self.fp.write(zip64locrec) - centDirCount = min(centDirCount, 0xFFFF) - centDirSize = min(centDirSize, 0xFFFFFFFF) - centDirOffset = min(centDirOffset, 0xFFFFFFFF) - - endrec = struct.pack(structEndArchive, stringEndArchive, - 0, 0, centDirCount, centDirCount, - centDirSize, centDirOffset, len(self._comment)) - self.fp.write(endrec) - self.fp.write(self._comment) - if self.mode == "a": - self.fp.truncate() - self.fp.flush() - - def _fpclose(self, fp): - assert self._fileRefCnt > 0 - self._fileRefCnt -= 1 - if not self._fileRefCnt and not self._filePassed: - fp.close() - - -class PyZipFile(ZipFile): - """Class to create ZIP archives with Python library files and packages.""" - - def __init__(self, file, mode="r", compression=ZIP_STORED, - allowZip64=True, optimize=-1): - ZipFile.__init__(self, file, mode=mode, compression=compression, - allowZip64=allowZip64) - self._optimize = optimize - - def writepy(self, pathname, basename="", filterfunc=None): - """Add all files from "pathname" to the ZIP archive. - - If pathname is a package directory, search the directory and - all package subdirectories recursively for all *.py and enter - the modules into the archive. If pathname is a plain - directory, listdir *.py and enter all modules. Else, pathname - must be a Python *.py file and the module will be put into the - archive. Added modules are always module.pyc. - This method will compile the module.py into module.pyc if - necessary. - If filterfunc(pathname) is given, it is called with every argument. - When it is False, the file or directory is skipped. - """ - pathname = os.fspath(pathname) - if filterfunc and not filterfunc(pathname): - if self.debug: - label = 'path' if os.path.isdir(pathname) else 'file' - print('%s %r skipped by filterfunc' % (label, pathname)) - return - dir, name = os.path.split(pathname) - if os.path.isdir(pathname): - initname = os.path.join(pathname, "__init__.py") - if os.path.isfile(initname): - # This is a package directory, add it - if basename: - basename = "%s/%s" % (basename, name) - else: - basename = name - if self.debug: - print("Adding package in", pathname, "as", basename) - fname, arcname = self._get_codename(initname[0:-3], basename) - if self.debug: - print("Adding", arcname) - self.write(fname, arcname) - dirlist = sorted(os.listdir(pathname)) - dirlist.remove("__init__.py") - # Add all *.py files and package subdirectories - for filename in dirlist: - path = os.path.join(pathname, filename) - root, ext = os.path.splitext(filename) - if os.path.isdir(path): - if os.path.isfile(os.path.join(path, "__init__.py")): - # This is a package directory, add it - self.writepy(path, basename, - filterfunc=filterfunc) # Recursive call - elif ext == ".py": - if filterfunc and not filterfunc(path): - if self.debug: - print('file %r skipped by filterfunc' % path) - continue - fname, arcname = self._get_codename(path[0:-3], - basename) - if self.debug: - print("Adding", arcname) - self.write(fname, arcname) - else: - # This is NOT a package directory, add its files at top level - if self.debug: - print("Adding files from directory", pathname) - for filename in sorted(os.listdir(pathname)): - path = os.path.join(pathname, filename) - root, ext = os.path.splitext(filename) - if ext == ".py": - if filterfunc and not filterfunc(path): - if self.debug: - print('file %r skipped by filterfunc' % path) - continue - fname, arcname = self._get_codename(path[0:-3], - basename) - if self.debug: - print("Adding", arcname) - self.write(fname, arcname) - else: - if pathname[-3:] != ".py": - raise RuntimeError( - 'Files added with writepy() must end with ".py"') - fname, arcname = self._get_codename(pathname[0:-3], basename) - if self.debug: - print("Adding file", arcname) - self.write(fname, arcname) - - def _get_codename(self, pathname, basename): - """Return (filename, archivename) for the path. - - Given a module name path, return the correct file path and - archive name, compiling if necessary. For example, given - /python/lib/string, return (/python/lib/string.pyc, string). - """ - def _compile(file, optimize=-1): - import py_compile - if self.debug: - print("Compiling", file) - try: - py_compile.compile(file, doraise=True, optimize=optimize) - except py_compile.PyCompileError as err: - print(err.msg) - return False - return True - - file_py = pathname + ".py" - file_pyc = pathname + ".pyc" - pycache_opt0 = importlib.util.cache_from_source(file_py, optimization='') - pycache_opt1 = importlib.util.cache_from_source(file_py, optimization=1) - pycache_opt2 = importlib.util.cache_from_source(file_py, optimization=2) - if self._optimize == -1: - # legacy mode: use whatever file is present - if (os.path.isfile(file_pyc) and - os.stat(file_pyc).st_mtime >= os.stat(file_py).st_mtime): - # Use .pyc file. - arcname = fname = file_pyc - elif (os.path.isfile(pycache_opt0) and - os.stat(pycache_opt0).st_mtime >= os.stat(file_py).st_mtime): - # Use the __pycache__/*.pyc file, but write it to the legacy pyc - # file name in the archive. - fname = pycache_opt0 - arcname = file_pyc - elif (os.path.isfile(pycache_opt1) and - os.stat(pycache_opt1).st_mtime >= os.stat(file_py).st_mtime): - # Use the __pycache__/*.pyc file, but write it to the legacy pyc - # file name in the archive. - fname = pycache_opt1 - arcname = file_pyc - elif (os.path.isfile(pycache_opt2) and - os.stat(pycache_opt2).st_mtime >= os.stat(file_py).st_mtime): - # Use the __pycache__/*.pyc file, but write it to the legacy pyc - # file name in the archive. - fname = pycache_opt2 - arcname = file_pyc - else: - # Compile py into PEP 3147 pyc file. - if _compile(file_py): - if sys.flags.optimize == 0: - fname = pycache_opt0 - elif sys.flags.optimize == 1: - fname = pycache_opt1 - else: - fname = pycache_opt2 - arcname = file_pyc - else: - fname = arcname = file_py - else: - # new mode: use given optimization level - if self._optimize == 0: - fname = pycache_opt0 - arcname = file_pyc - else: - arcname = file_pyc - if self._optimize == 1: - fname = pycache_opt1 - elif self._optimize == 2: - fname = pycache_opt2 - else: - msg = "invalid value for 'optimize': {!r}".format(self._optimize) - raise ValueError(msg) - if not (os.path.isfile(fname) and - os.stat(fname).st_mtime >= os.stat(file_py).st_mtime): - if not _compile(file_py, optimize=self._optimize): - fname = arcname = file_py - archivename = os.path.split(arcname)[1] - if basename: - archivename = "%s/%s" % (basename, archivename) - return (fname, archivename) - - -def _parents(path): - """ - Given a path with elements separated by - posixpath.sep, generate all parents of that path. - - >>> list(_parents('b/d')) - ['b'] - >>> list(_parents('/b/d/')) - ['/b'] - >>> list(_parents('b/d/f/')) - ['b/d', 'b'] - >>> list(_parents('b')) - [] - >>> list(_parents('')) - [] - """ - return itertools.islice(_ancestry(path), 1, None) - - -def _ancestry(path): - """ - Given a path with elements separated by - posixpath.sep, generate all elements of that path - - >>> list(_ancestry('b/d')) - ['b/d', 'b'] - >>> list(_ancestry('/b/d/')) - ['/b/d', '/b'] - >>> list(_ancestry('b/d/f/')) - ['b/d/f', 'b/d', 'b'] - >>> list(_ancestry('b')) - ['b'] - >>> list(_ancestry('')) - [] - """ - path = path.rstrip(posixpath.sep) - while path and path != posixpath.sep: - yield path - path, tail = posixpath.split(path) - - -_dedupe = dict.fromkeys -"""Deduplicate an iterable in original order""" - - -def _difference(minuend, subtrahend): - """ - Return items in minuend not in subtrahend, retaining order - with O(1) lookup. - """ - return itertools.filterfalse(set(subtrahend).__contains__, minuend) - - -class CompleteDirs(ZipFile): - """ - A ZipFile subclass that ensures that implied directories - are always included in the namelist. - """ - - @staticmethod - def _implied_dirs(names): - parents = itertools.chain.from_iterable(map(_parents, names)) - as_dirs = (p + posixpath.sep for p in parents) - return _dedupe(_difference(as_dirs, names)) - - def namelist(self): - names = super(CompleteDirs, self).namelist() - return names + list(self._implied_dirs(names)) - - def _name_set(self): - return set(self.namelist()) - - def resolve_dir(self, name): - """ - If the name represents a directory, return that name - as a directory (with the trailing slash). - """ - names = self._name_set() - dirname = name + '/' - dir_match = name not in names and dirname in names - return dirname if dir_match else name - - @classmethod - def make(cls, source): - """ - Given a source (filename or zipfile), return an - appropriate CompleteDirs subclass. - """ - if isinstance(source, CompleteDirs): - return source - - if not isinstance(source, ZipFile): - return cls(source) - - # Only allow for FastLookup when supplied zipfile is read-only - if 'r' not in source.mode: - cls = CompleteDirs - - source.__class__ = cls - return source - - -class FastLookup(CompleteDirs): - """ - ZipFile subclass to ensure implicit - dirs exist and are resolved rapidly. - """ - - def namelist(self): - with contextlib.suppress(AttributeError): - return self.__names - self.__names = super(FastLookup, self).namelist() - return self.__names - - def _name_set(self): - with contextlib.suppress(AttributeError): - return self.__lookup - self.__lookup = super(FastLookup, self)._name_set() - return self.__lookup - - -class Path: - """ - A pathlib-compatible interface for zip files. - - Consider a zip file with this structure:: - - . - ├── a.txt - └── b - ├── c.txt - └── d - └── e.txt - - >>> data = io.BytesIO() - >>> zf = ZipFile(data, 'w') - >>> zf.writestr('a.txt', 'content of a') - >>> zf.writestr('b/c.txt', 'content of c') - >>> zf.writestr('b/d/e.txt', 'content of e') - >>> zf.filename = 'mem/abcde.zip' - - Path accepts the zipfile object itself or a filename - - >>> root = Path(zf) - - From there, several path operations are available. - - Directory iteration (including the zip file itself): - - >>> a, b = root.iterdir() - >>> a - Path('mem/abcde.zip', 'a.txt') - >>> b - Path('mem/abcde.zip', 'b/') - - name property: - - >>> b.name - 'b' - - join with divide operator: - - >>> c = b / 'c.txt' - >>> c - Path('mem/abcde.zip', 'b/c.txt') - >>> c.name - 'c.txt' - - Read text: - - >>> c.read_text() - 'content of c' - - existence: - - >>> c.exists() - True - >>> (b / 'missing.txt').exists() - False - - Coercion to string: - - >>> import os - >>> str(c).replace(os.sep, posixpath.sep) - 'mem/abcde.zip/b/c.txt' - - At the root, ``name``, ``filename``, and ``parent`` - resolve to the zipfile. Note these attributes are not - valid and will raise a ``ValueError`` if the zipfile - has no filename. - - >>> root.name - 'abcde.zip' - >>> str(root.filename).replace(os.sep, posixpath.sep) - 'mem/abcde.zip' - >>> str(root.parent) - 'mem' - """ - - __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" - - def __init__(self, root, at=""): - """ - Construct a Path from a ZipFile or filename. - - Note: When the source is an existing ZipFile object, - its type (__class__) will be mutated to a - specialized type. If the caller wishes to retain the - original type, the caller should either create a - separate ZipFile object or pass a filename. - """ - self.root = FastLookup.make(root) - self.at = at - - def open(self, mode='r', *args, pwd=None, **kwargs): - """ - Open this entry as text or binary following the semantics - of ``pathlib.Path.open()`` by passing arguments through - to io.TextIOWrapper(). - """ - if self.is_dir(): - raise IsADirectoryError(self) - zip_mode = mode[0] - if not self.exists() and zip_mode == 'r': - raise FileNotFoundError(self) - stream = self.root.open(self.at, zip_mode, pwd=pwd) - if 'b' in mode: - if args or kwargs: - raise ValueError("encoding args invalid for binary operation") - return stream - else: - kwargs["encoding"] = io.text_encoding(kwargs.get("encoding")) - return io.TextIOWrapper(stream, *args, **kwargs) - - @property - def name(self): - return pathlib.Path(self.at).name or self.filename.name - - @property - def suffix(self): - return pathlib.Path(self.at).suffix or self.filename.suffix - - @property - def suffixes(self): - return pathlib.Path(self.at).suffixes or self.filename.suffixes - - @property - def stem(self): - return pathlib.Path(self.at).stem or self.filename.stem - - @property - def filename(self): - return pathlib.Path(self.root.filename).joinpath(self.at) - - def read_text(self, *args, **kwargs): - kwargs["encoding"] = io.text_encoding(kwargs.get("encoding")) - with self.open('r', *args, **kwargs) as strm: - return strm.read() - - def read_bytes(self): - with self.open('rb') as strm: - return strm.read() - - def _is_child(self, path): - return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") - - def _next(self, at): - return self.__class__(self.root, at) - - def is_dir(self): - return not self.at or self.at.endswith("/") - - def is_file(self): - return self.exists() and not self.is_dir() - - def exists(self): - return self.at in self.root._name_set() - - def iterdir(self): - if not self.is_dir(): - raise ValueError("Can't listdir a file") - subs = map(self._next, self.root.namelist()) - return filter(self._is_child, subs) - - def __str__(self): - return posixpath.join(self.root.filename, self.at) - - def __repr__(self): - return self.__repr.format(self=self) - - def joinpath(self, *other): - next = posixpath.join(self.at, *other) - return self._next(self.root.resolve_dir(next)) - - __truediv__ = joinpath - - @property - def parent(self): - if not self.at: - return self.filename.parent - parent_at = posixpath.dirname(self.at.rstrip('/')) - if parent_at: - parent_at += '/' - return self._next(parent_at) - - -def main(args=None): - import argparse - - description = 'A simple command-line interface for zipfile module.' - parser = argparse.ArgumentParser(description=description) - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('-l', '--list', metavar='', - help='Show listing of a zipfile') - group.add_argument('-e', '--extract', nargs=2, - metavar=('', ''), - help='Extract zipfile into target dir') - group.add_argument('-c', '--create', nargs='+', - metavar=('', ''), - help='Create zipfile from sources') - group.add_argument('-t', '--test', metavar='', - help='Test if a zipfile is valid') - parser.add_argument('--metadata-encoding', metavar='', - help='Specify encoding of member names for -l, -e and -t') - args = parser.parse_args(args) - - encoding = args.metadata_encoding - - if args.test is not None: - src = args.test - with ZipFile(src, 'r', metadata_encoding=encoding) as zf: - badfile = zf.testzip() - if badfile: - print("The following enclosed file is corrupted: {!r}".format(badfile)) - print("Done testing") - - elif args.list is not None: - src = args.list - with ZipFile(src, 'r', metadata_encoding=encoding) as zf: - zf.printdir() - - elif args.extract is not None: - src, curdir = args.extract - with ZipFile(src, 'r', metadata_encoding=encoding) as zf: - zf.extractall(curdir) - - elif args.create is not None: - if encoding: - print("Non-conforming encodings not supported with -c.", - file=sys.stderr) - sys.exit(1) - - zip_name = args.create.pop(0) - files = args.create - - def addToZip(zf, path, zippath): - if os.path.isfile(path): - zf.write(path, zippath, ZIP_DEFLATED) - elif os.path.isdir(path): - if zippath: - zf.write(path, zippath) - for nm in sorted(os.listdir(path)): - addToZip(zf, - os.path.join(path, nm), os.path.join(zippath, nm)) - # else: ignore - - with ZipFile(zip_name, 'w') as zf: - for path in files: - zippath = os.path.basename(path) - if not zippath: - zippath = os.path.basename(os.path.dirname(path)) - if zippath in ('', os.curdir, os.pardir): - zippath = '' - addToZip(zf, path, zippath) - - -if __name__ == "__main__": - main() diff --git a/python/Lib/zipimport.py b/python/Lib/zipimport.py deleted file mode 100644 index 3835a27..0000000 --- a/python/Lib/zipimport.py +++ /dev/null @@ -1,778 +0,0 @@ -"""zipimport provides support for importing Python modules from Zip archives. - -This module exports three objects: -- zipimporter: a class; its constructor takes a path to a Zip archive. -- ZipImportError: exception raised by zipimporter objects. It's a - subclass of ImportError, so it can be caught as ImportError, too. -- _zip_directory_cache: a dict, mapping archive paths to zip directory - info dicts, as used in zipimporter._files. - -It is usually not needed to use the zipimport module explicitly; it is -used by the builtin import mechanism for sys.path items that are paths -to Zip archives. -""" - -#from importlib import _bootstrap_external -#from importlib import _bootstrap # for _verbose_message -import _frozen_importlib_external as _bootstrap_external -from _frozen_importlib_external import _unpack_uint16, _unpack_uint32 -import _frozen_importlib as _bootstrap # for _verbose_message -import _imp # for check_hash_based_pycs -import _io # for open -import marshal # for loads -import sys # for modules -import time # for mktime -import _warnings # For warn() - -__all__ = ['ZipImportError', 'zipimporter'] - - -path_sep = _bootstrap_external.path_sep -alt_path_sep = _bootstrap_external.path_separators[1:] - - -class ZipImportError(ImportError): - pass - -# _read_directory() cache -_zip_directory_cache = {} - -_module_type = type(sys) - -END_CENTRAL_DIR_SIZE = 22 -STRING_END_ARCHIVE = b'PK\x05\x06' -MAX_COMMENT_LEN = (1 << 16) - 1 - -class zipimporter(_bootstrap_external._LoaderBasics): - """zipimporter(archivepath) -> zipimporter object - - Create a new zipimporter instance. 'archivepath' must be a path to - a zipfile, or to a specific path inside a zipfile. For example, it can be - '/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a - valid directory inside the archive. - - 'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip - archive. - - The 'archive' attribute of zipimporter objects contains the name of the - zipfile targeted. - """ - - # Split the "subdirectory" from the Zip archive path, lookup a matching - # entry in sys.path_importer_cache, fetch the file directory from there - # if found, or else read it from the archive. - def __init__(self, path): - if not isinstance(path, str): - raise TypeError(f"expected str, not {type(path)!r}") - if not path: - raise ZipImportError('archive path is empty', path=path) - if alt_path_sep: - path = path.replace(alt_path_sep, path_sep) - - prefix = [] - while True: - try: - st = _bootstrap_external._path_stat(path) - except (OSError, ValueError): - # On Windows a ValueError is raised for too long paths. - # Back up one path element. - dirname, basename = _bootstrap_external._path_split(path) - if dirname == path: - raise ZipImportError('not a Zip file', path=path) - path = dirname - prefix.append(basename) - else: - # it exists - if (st.st_mode & 0o170000) != 0o100000: # stat.S_ISREG - # it's a not file - raise ZipImportError('not a Zip file', path=path) - break - - try: - files = _zip_directory_cache[path] - except KeyError: - files = _read_directory(path) - _zip_directory_cache[path] = files - self._files = files - self.archive = path - # a prefix directory following the ZIP file path. - self.prefix = _bootstrap_external._path_join(*prefix[::-1]) - if self.prefix: - self.prefix += path_sep - - - # Check whether we can satisfy the import of the module named by - # 'fullname', or whether it could be a portion of a namespace - # package. Return self if we can load it, a string containing the - # full path if it's a possible namespace portion, None if we - # can't load it. - def find_loader(self, fullname, path=None): - """find_loader(fullname, path=None) -> self, str or None. - - Search for a module specified by 'fullname'. 'fullname' must be the - fully qualified (dotted) module name. It returns the zipimporter - instance itself if the module was found, a string containing the - full path name if it's possibly a portion of a namespace package, - or None otherwise. The optional 'path' argument is ignored -- it's - there for compatibility with the importer protocol. - - Deprecated since Python 3.10. Use find_spec() instead. - """ - _warnings.warn("zipimporter.find_loader() is deprecated and slated for " - "removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - mi = _get_module_info(self, fullname) - if mi is not None: - # This is a module or package. - return self, [] - - # Not a module or regular package. See if this is a directory, and - # therefore possibly a portion of a namespace package. - - # We're only interested in the last path component of fullname - # earlier components are recorded in self.prefix. - modpath = _get_module_path(self, fullname) - if _is_dir(self, modpath): - # This is possibly a portion of a namespace - # package. Return the string representing its path, - # without a trailing separator. - return None, [f'{self.archive}{path_sep}{modpath}'] - - return None, [] - - - # Check whether we can satisfy the import of the module named by - # 'fullname'. Return self if we can, None if we can't. - def find_module(self, fullname, path=None): - """find_module(fullname, path=None) -> self or None. - - Search for a module specified by 'fullname'. 'fullname' must be the - fully qualified (dotted) module name. It returns the zipimporter - instance itself if the module was found, or None if it wasn't. - The optional 'path' argument is ignored -- it's there for compatibility - with the importer protocol. - - Deprecated since Python 3.10. Use find_spec() instead. - """ - _warnings.warn("zipimporter.find_module() is deprecated and slated for " - "removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - return self.find_loader(fullname, path)[0] - - def find_spec(self, fullname, target=None): - """Create a ModuleSpec for the specified module. - - Returns None if the module cannot be found. - """ - module_info = _get_module_info(self, fullname) - if module_info is not None: - return _bootstrap.spec_from_loader(fullname, self, is_package=module_info) - else: - # Not a module or regular package. See if this is a directory, and - # therefore possibly a portion of a namespace package. - - # We're only interested in the last path component of fullname - # earlier components are recorded in self.prefix. - modpath = _get_module_path(self, fullname) - if _is_dir(self, modpath): - # This is possibly a portion of a namespace - # package. Return the string representing its path, - # without a trailing separator. - path = f'{self.archive}{path_sep}{modpath}' - spec = _bootstrap.ModuleSpec(name=fullname, loader=None, - is_package=True) - spec.submodule_search_locations.append(path) - return spec - else: - return None - - def get_code(self, fullname): - """get_code(fullname) -> code object. - - Return the code object for the specified module. Raise ZipImportError - if the module couldn't be imported. - """ - code, ispackage, modpath = _get_module_code(self, fullname) - return code - - - def get_data(self, pathname): - """get_data(pathname) -> string with file data. - - Return the data associated with 'pathname'. Raise OSError if - the file wasn't found. - """ - if alt_path_sep: - pathname = pathname.replace(alt_path_sep, path_sep) - - key = pathname - if pathname.startswith(self.archive + path_sep): - key = pathname[len(self.archive + path_sep):] - - try: - toc_entry = self._files[key] - except KeyError: - raise OSError(0, '', key) - return _get_data(self.archive, toc_entry) - - - # Return a string matching __file__ for the named module - def get_filename(self, fullname): - """get_filename(fullname) -> filename string. - - Return the filename for the specified module or raise ZipImportError - if it couldn't be imported. - """ - # Deciding the filename requires working out where the code - # would come from if the module was actually loaded - code, ispackage, modpath = _get_module_code(self, fullname) - return modpath - - - def get_source(self, fullname): - """get_source(fullname) -> source string. - - Return the source code for the specified module. Raise ZipImportError - if the module couldn't be found, return None if the archive does - contain the module, but has no source for it. - """ - mi = _get_module_info(self, fullname) - if mi is None: - raise ZipImportError(f"can't find module {fullname!r}", name=fullname) - - path = _get_module_path(self, fullname) - if mi: - fullpath = _bootstrap_external._path_join(path, '__init__.py') - else: - fullpath = f'{path}.py' - - try: - toc_entry = self._files[fullpath] - except KeyError: - # we have the module, but no source - return None - return _get_data(self.archive, toc_entry).decode() - - - # Return a bool signifying whether the module is a package or not. - def is_package(self, fullname): - """is_package(fullname) -> bool. - - Return True if the module specified by fullname is a package. - Raise ZipImportError if the module couldn't be found. - """ - mi = _get_module_info(self, fullname) - if mi is None: - raise ZipImportError(f"can't find module {fullname!r}", name=fullname) - return mi - - - # Load and return the module named by 'fullname'. - def load_module(self, fullname): - """load_module(fullname) -> module. - - Load the module specified by 'fullname'. 'fullname' must be the - fully qualified (dotted) module name. It returns the imported - module, or raises ZipImportError if it could not be imported. - - Deprecated since Python 3.10. Use exec_module() instead. - """ - msg = ("zipimport.zipimporter.load_module() is deprecated and slated for " - "removal in Python 3.12; use exec_module() instead") - _warnings.warn(msg, DeprecationWarning) - code, ispackage, modpath = _get_module_code(self, fullname) - mod = sys.modules.get(fullname) - if mod is None or not isinstance(mod, _module_type): - mod = _module_type(fullname) - sys.modules[fullname] = mod - mod.__loader__ = self - - try: - if ispackage: - # add __path__ to the module *before* the code gets - # executed - path = _get_module_path(self, fullname) - fullpath = _bootstrap_external._path_join(self.archive, path) - mod.__path__ = [fullpath] - - if not hasattr(mod, '__builtins__'): - mod.__builtins__ = __builtins__ - _bootstrap_external._fix_up_module(mod.__dict__, fullname, modpath) - exec(code, mod.__dict__) - except: - del sys.modules[fullname] - raise - - try: - mod = sys.modules[fullname] - except KeyError: - raise ImportError(f'Loaded module {fullname!r} not found in sys.modules') - _bootstrap._verbose_message('import {} # loaded from Zip {}', fullname, modpath) - return mod - - - def get_resource_reader(self, fullname): - """Return the ResourceReader for a package in a zip file. - - If 'fullname' is a package within the zip file, return the - 'ResourceReader' object for the package. Otherwise return None. - """ - try: - if not self.is_package(fullname): - return None - except ZipImportError: - return None - from importlib.readers import ZipReader - return ZipReader(self, fullname) - - - def invalidate_caches(self): - """Reload the file data of the archive path.""" - try: - self._files = _read_directory(self.archive) - _zip_directory_cache[self.archive] = self._files - except ZipImportError: - _zip_directory_cache.pop(self.archive, None) - self._files = {} - - - def __repr__(self): - return f'' - - -# _zip_searchorder defines how we search for a module in the Zip -# archive: we first search for a package __init__, then for -# non-package .pyc, and .py entries. The .pyc entries -# are swapped by initzipimport() if we run in optimized mode. Also, -# '/' is replaced by path_sep there. -_zip_searchorder = ( - (path_sep + '__init__.pyc', True, True), - (path_sep + '__init__.py', False, True), - ('.pyc', True, False), - ('.py', False, False), -) - -# Given a module name, return the potential file path in the -# archive (without extension). -def _get_module_path(self, fullname): - return self.prefix + fullname.rpartition('.')[2] - -# Does this path represent a directory? -def _is_dir(self, path): - # See if this is a "directory". If so, it's eligible to be part - # of a namespace package. We test by seeing if the name, with an - # appended path separator, exists. - dirpath = path + path_sep - # If dirpath is present in self._files, we have a directory. - return dirpath in self._files - -# Return some information about a module. -def _get_module_info(self, fullname): - path = _get_module_path(self, fullname) - for suffix, isbytecode, ispackage in _zip_searchorder: - fullpath = path + suffix - if fullpath in self._files: - return ispackage - return None - - -# implementation - -# _read_directory(archive) -> files dict (new reference) -# -# Given a path to a Zip archive, build a dict, mapping file names -# (local to the archive, using SEP as a separator) to toc entries. -# -# A toc_entry is a tuple: -# -# (__file__, # value to use for __file__, available for all files, -# # encoded to the filesystem encoding -# compress, # compression kind; 0 for uncompressed -# data_size, # size of compressed data on disk -# file_size, # size of decompressed data -# file_offset, # offset of file header from start of archive -# time, # mod time of file (in dos format) -# date, # mod data of file (in dos format) -# crc, # crc checksum of the data -# ) -# -# Directories can be recognized by the trailing path_sep in the name, -# data_size and file_offset are 0. -def _read_directory(archive): - try: - fp = _io.open_code(archive) - except OSError: - raise ZipImportError(f"can't open Zip file: {archive!r}", path=archive) - - with fp: - # GH-87235: On macOS all file descriptors for /dev/fd/N share the same - # file offset, reset the file offset after scanning the zipfile diretory - # to not cause problems when some runs 'python3 /dev/fd/9 9 header_offset: - raise ZipImportError(f'bad local header offset: {archive!r}', path=archive) - file_offset += arc_offset - - try: - name = fp.read(name_size) - except OSError: - raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) - if len(name) != name_size: - raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) - # On Windows, calling fseek to skip over the fields we don't use is - # slower than reading the data because fseek flushes stdio's - # internal buffers. See issue #8745. - try: - if len(fp.read(header_size - name_size)) != header_size - name_size: - raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) - except OSError: - raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) - - if flags & 0x800: - # UTF-8 file names extension - name = name.decode() - else: - # Historical ZIP filename encoding - try: - name = name.decode('ascii') - except UnicodeDecodeError: - name = name.decode('latin1').translate(cp437_table) - - name = name.replace('/', path_sep) - path = _bootstrap_external._path_join(archive, name) - t = (path, compress, data_size, file_size, file_offset, time, date, crc) - files[name] = t - count += 1 - finally: - fp.seek(start_offset) - _bootstrap._verbose_message('zipimport: found {} names in {!r}', count, archive) - return files - -# During bootstrap, we may need to load the encodings -# package from a ZIP file. But the cp437 encoding is implemented -# in Python in the encodings package. -# -# Break out of this dependency by using the translation table for -# the cp437 encoding. -cp437_table = ( - # ASCII part, 8 rows x 16 chars - '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f' - '\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f' - ' !"#$%&\'()*+,-./' - '0123456789:;<=>?' - '@ABCDEFGHIJKLMNO' - 'PQRSTUVWXYZ[\\]^_' - '`abcdefghijklmno' - 'pqrstuvwxyz{|}~\x7f' - # non-ASCII part, 16 rows x 8 chars - '\xc7\xfc\xe9\xe2\xe4\xe0\xe5\xe7' - '\xea\xeb\xe8\xef\xee\xec\xc4\xc5' - '\xc9\xe6\xc6\xf4\xf6\xf2\xfb\xf9' - '\xff\xd6\xdc\xa2\xa3\xa5\u20a7\u0192' - '\xe1\xed\xf3\xfa\xf1\xd1\xaa\xba' - '\xbf\u2310\xac\xbd\xbc\xa1\xab\xbb' - '\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556' - '\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510' - '\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f' - '\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567' - '\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b' - '\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580' - '\u03b1\xdf\u0393\u03c0\u03a3\u03c3\xb5\u03c4' - '\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229' - '\u2261\xb1\u2265\u2264\u2320\u2321\xf7\u2248' - '\xb0\u2219\xb7\u221a\u207f\xb2\u25a0\xa0' -) - -_importing_zlib = False - -# Return the zlib.decompress function object, or NULL if zlib couldn't -# be imported. The function is cached when found, so subsequent calls -# don't import zlib again. -def _get_decompress_func(): - global _importing_zlib - if _importing_zlib: - # Someone has a zlib.py[co] in their Zip file - # let's avoid a stack overflow. - _bootstrap._verbose_message('zipimport: zlib UNAVAILABLE') - raise ZipImportError("can't decompress data; zlib not available") - - _importing_zlib = True - try: - from zlib import decompress - except Exception: - _bootstrap._verbose_message('zipimport: zlib UNAVAILABLE') - raise ZipImportError("can't decompress data; zlib not available") - finally: - _importing_zlib = False - - _bootstrap._verbose_message('zipimport: zlib available') - return decompress - -# Given a path to a Zip file and a toc_entry, return the (uncompressed) data. -def _get_data(archive, toc_entry): - datapath, compress, data_size, file_size, file_offset, time, date, crc = toc_entry - if data_size < 0: - raise ZipImportError('negative data size') - - with _io.open_code(archive) as fp: - # Check to make sure the local file header is correct - try: - fp.seek(file_offset) - except OSError: - raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) - buffer = fp.read(30) - if len(buffer) != 30: - raise EOFError('EOF read where not expected') - - if buffer[:4] != b'PK\x03\x04': - # Bad: Local File Header - raise ZipImportError(f'bad local file header: {archive!r}', path=archive) - - name_size = _unpack_uint16(buffer[26:28]) - extra_size = _unpack_uint16(buffer[28:30]) - header_size = 30 + name_size + extra_size - file_offset += header_size # Start of file data - try: - fp.seek(file_offset) - except OSError: - raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) - raw_data = fp.read(data_size) - if len(raw_data) != data_size: - raise OSError("zipimport: can't read data") - - if compress == 0: - # data is not compressed - return raw_data - - # Decompress with zlib - try: - decompress = _get_decompress_func() - except Exception: - raise ZipImportError("can't decompress data; zlib not available") - return decompress(raw_data, -15) - - -# Lenient date/time comparison function. The precision of the mtime -# in the archive is lower than the mtime stored in a .pyc: we -# must allow a difference of at most one second. -def _eq_mtime(t1, t2): - # dostime only stores even seconds, so be lenient - return abs(t1 - t2) <= 1 - - -# Given the contents of a .py[co] file, unmarshal the data -# and return the code object. Raises ImportError it the magic word doesn't -# match, or if the recorded .py[co] metadata does not match the source. -def _unmarshal_code(self, pathname, fullpath, fullname, data): - exc_details = { - 'name': fullname, - 'path': fullpath, - } - - flags = _bootstrap_external._classify_pyc(data, fullname, exc_details) - - hash_based = flags & 0b1 != 0 - if hash_based: - check_source = flags & 0b10 != 0 - if (_imp.check_hash_based_pycs != 'never' and - (check_source or _imp.check_hash_based_pycs == 'always')): - source_bytes = _get_pyc_source(self, fullpath) - if source_bytes is not None: - source_hash = _imp.source_hash( - _bootstrap_external._RAW_MAGIC_NUMBER, - source_bytes, - ) - - _bootstrap_external._validate_hash_pyc( - data, source_hash, fullname, exc_details) - else: - source_mtime, source_size = \ - _get_mtime_and_size_of_source(self, fullpath) - - if source_mtime: - # We don't use _bootstrap_external._validate_timestamp_pyc - # to allow for a more lenient timestamp check. - if (not _eq_mtime(_unpack_uint32(data[8:12]), source_mtime) or - _unpack_uint32(data[12:16]) != source_size): - _bootstrap._verbose_message( - f'bytecode is stale for {fullname!r}') - return None - - code = marshal.loads(data[16:]) - if not isinstance(code, _code_type): - raise TypeError(f'compiled module {pathname!r} is not a code object') - return code - -_code_type = type(_unmarshal_code.__code__) - - -# Replace any occurrences of '\r\n?' in the input string with '\n'. -# This converts DOS and Mac line endings to Unix line endings. -def _normalize_line_endings(source): - source = source.replace(b'\r\n', b'\n') - source = source.replace(b'\r', b'\n') - return source - -# Given a string buffer containing Python source code, compile it -# and return a code object. -def _compile_source(pathname, source): - source = _normalize_line_endings(source) - return compile(source, pathname, 'exec', dont_inherit=True) - -# Convert the date/time values found in the Zip archive to a value -# that's compatible with the time stamp stored in .pyc files. -def _parse_dostime(d, t): - return time.mktime(( - (d >> 9) + 1980, # bits 9..15: year - (d >> 5) & 0xF, # bits 5..8: month - d & 0x1F, # bits 0..4: day - t >> 11, # bits 11..15: hours - (t >> 5) & 0x3F, # bits 8..10: minutes - (t & 0x1F) * 2, # bits 0..7: seconds / 2 - -1, -1, -1)) - -# Given a path to a .pyc file in the archive, return the -# modification time of the matching .py file and its size, -# or (0, 0) if no source is available. -def _get_mtime_and_size_of_source(self, path): - try: - # strip 'c' or 'o' from *.py[co] - assert path[-1:] in ('c', 'o') - path = path[:-1] - toc_entry = self._files[path] - # fetch the time stamp of the .py file for comparison - # with an embedded pyc time stamp - time = toc_entry[5] - date = toc_entry[6] - uncompressed_size = toc_entry[3] - return _parse_dostime(date, time), uncompressed_size - except (KeyError, IndexError, TypeError): - return 0, 0 - - -# Given a path to a .pyc file in the archive, return the -# contents of the matching .py file, or None if no source -# is available. -def _get_pyc_source(self, path): - # strip 'c' or 'o' from *.py[co] - assert path[-1:] in ('c', 'o') - path = path[:-1] - - try: - toc_entry = self._files[path] - except KeyError: - return None - else: - return _get_data(self.archive, toc_entry) - - -# Get the code object associated with the module specified by -# 'fullname'. -def _get_module_code(self, fullname): - path = _get_module_path(self, fullname) - import_error = None - for suffix, isbytecode, ispackage in _zip_searchorder: - fullpath = path + suffix - _bootstrap._verbose_message('trying {}{}{}', self.archive, path_sep, fullpath, verbosity=2) - try: - toc_entry = self._files[fullpath] - except KeyError: - pass - else: - modpath = toc_entry[0] - data = _get_data(self.archive, toc_entry) - code = None - if isbytecode: - try: - code = _unmarshal_code(self, modpath, fullpath, fullname, data) - except ImportError as exc: - import_error = exc - else: - code = _compile_source(modpath, data) - if code is None: - # bad magic number or non-matching mtime - # in byte code, try next - continue - modpath = toc_entry[0] - return code, ispackage, modpath - else: - if import_error: - msg = f"module load failed: {import_error}" - raise ZipImportError(msg, name=fullname) from import_error - else: - raise ZipImportError(f"can't find module {fullname!r}", name=fullname) diff --git a/python/Lib/zoneinfo/__init__.py b/python/Lib/zoneinfo/__init__.py deleted file mode 100644 index 384ca5f..0000000 --- a/python/Lib/zoneinfo/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -__all__ = [ - "ZoneInfo", - "reset_tzpath", - "available_timezones", - "TZPATH", - "ZoneInfoNotFoundError", - "InvalidTZPathWarning", -] - -from . import _tzpath -from ._common import ZoneInfoNotFoundError - -try: - from _zoneinfo import ZoneInfo -except ImportError: # pragma: nocover - from ._zoneinfo import ZoneInfo - -reset_tzpath = _tzpath.reset_tzpath -available_timezones = _tzpath.available_timezones -InvalidTZPathWarning = _tzpath.InvalidTZPathWarning - - -def __getattr__(name): - if name == "TZPATH": - return _tzpath.TZPATH - else: - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") - - -def __dir__(): - return sorted(list(globals()) + ["TZPATH"]) diff --git a/python/Lib/zoneinfo/_common.py b/python/Lib/zoneinfo/_common.py deleted file mode 100644 index 1709a96..0000000 --- a/python/Lib/zoneinfo/_common.py +++ /dev/null @@ -1,164 +0,0 @@ -import struct - - -def load_tzdata(key): - from importlib import resources - - components = key.split("/") - package_name = ".".join(["tzdata.zoneinfo"] + components[:-1]) - resource_name = components[-1] - - try: - return resources.files(package_name).joinpath(resource_name).open("rb") - except (ImportError, FileNotFoundError, UnicodeEncodeError): - # There are three types of exception that can be raised that all amount - # to "we cannot find this key": - # - # ImportError: If package_name doesn't exist (e.g. if tzdata is not - # installed, or if there's an error in the folder name like - # Amrica/New_York) - # FileNotFoundError: If resource_name doesn't exist in the package - # (e.g. Europe/Krasnoy) - # UnicodeEncodeError: If package_name or resource_name are not UTF-8, - # such as keys containing a surrogate character. - raise ZoneInfoNotFoundError(f"No time zone found with key {key}") - - -def load_data(fobj): - header = _TZifHeader.from_file(fobj) - - if header.version == 1: - time_size = 4 - time_type = "l" - else: - # Version 2+ has 64-bit integer transition times - time_size = 8 - time_type = "q" - - # Version 2+ also starts with a Version 1 header and data, which - # we need to skip now - skip_bytes = ( - header.timecnt * 5 # Transition times and types - + header.typecnt * 6 # Local time type records - + header.charcnt # Time zone designations - + header.leapcnt * 8 # Leap second records - + header.isstdcnt # Standard/wall indicators - + header.isutcnt # UT/local indicators - ) - - fobj.seek(skip_bytes, 1) - - # Now we need to read the second header, which is not the same - # as the first - header = _TZifHeader.from_file(fobj) - - typecnt = header.typecnt - timecnt = header.timecnt - charcnt = header.charcnt - - # The data portion starts with timecnt transitions and indices - if timecnt: - trans_list_utc = struct.unpack( - f">{timecnt}{time_type}", fobj.read(timecnt * time_size) - ) - trans_idx = struct.unpack(f">{timecnt}B", fobj.read(timecnt)) - else: - trans_list_utc = () - trans_idx = () - - # Read the ttinfo struct, (utoff, isdst, abbrind) - if typecnt: - utcoff, isdst, abbrind = zip( - *(struct.unpack(">lbb", fobj.read(6)) for i in range(typecnt)) - ) - else: - utcoff = () - isdst = () - abbrind = () - - # Now read the abbreviations. They are null-terminated strings, indexed - # not by position in the array but by position in the unsplit - # abbreviation string. I suppose this makes more sense in C, which uses - # null to terminate the strings, but it's inconvenient here... - abbr_vals = {} - abbr_chars = fobj.read(charcnt) - - def get_abbr(idx): - # Gets a string starting at idx and running until the next \x00 - # - # We cannot pre-populate abbr_vals by splitting on \x00 because there - # are some zones that use subsets of longer abbreviations, like so: - # - # LMT\x00AHST\x00HDT\x00 - # - # Where the idx to abbr mapping should be: - # - # {0: "LMT", 4: "AHST", 5: "HST", 9: "HDT"} - if idx not in abbr_vals: - span_end = abbr_chars.find(b"\x00", idx) - abbr_vals[idx] = abbr_chars[idx:span_end].decode() - - return abbr_vals[idx] - - abbr = tuple(get_abbr(idx) for idx in abbrind) - - # The remainder of the file consists of leap seconds (currently unused) and - # the standard/wall and ut/local indicators, which are metadata we don't need. - # In version 2 files, we need to skip the unnecessary data to get at the TZ string: - if header.version >= 2: - # Each leap second record has size (time_size + 4) - skip_bytes = header.isutcnt + header.isstdcnt + header.leapcnt * 12 - fobj.seek(skip_bytes, 1) - - c = fobj.read(1) # Should be \n - assert c == b"\n", c - - tz_bytes = b"" - while (c := fobj.read(1)) != b"\n": - tz_bytes += c - - tz_str = tz_bytes - else: - tz_str = None - - return trans_idx, trans_list_utc, utcoff, isdst, abbr, tz_str - - -class _TZifHeader: - __slots__ = [ - "version", - "isutcnt", - "isstdcnt", - "leapcnt", - "timecnt", - "typecnt", - "charcnt", - ] - - def __init__(self, *args): - for attr, val in zip(self.__slots__, args, strict=True): - setattr(self, attr, val) - - @classmethod - def from_file(cls, stream): - # The header starts with a 4-byte "magic" value - if stream.read(4) != b"TZif": - raise ValueError("Invalid TZif file: magic not found") - - _version = stream.read(1) - if _version == b"\x00": - version = 1 - else: - version = int(_version) - stream.read(15) - - args = (version,) - - # Slots are defined in the order that the bytes are arranged - args = args + struct.unpack(">6l", stream.read(24)) - - return cls(*args) - - -class ZoneInfoNotFoundError(KeyError): - """Exception raised when a ZoneInfo key is not found.""" diff --git a/python/Lib/zoneinfo/_tzpath.py b/python/Lib/zoneinfo/_tzpath.py deleted file mode 100644 index 040b98c..0000000 --- a/python/Lib/zoneinfo/_tzpath.py +++ /dev/null @@ -1,175 +0,0 @@ -import os -import sysconfig - - -def reset_tzpath(to=None): - global TZPATH - - tzpaths = to - if tzpaths is not None: - if isinstance(tzpaths, (str, bytes)): - raise TypeError( - f"tzpaths must be a list or tuple, " - + f"not {type(tzpaths)}: {tzpaths!r}" - ) - - if not all(map(os.path.isabs, tzpaths)): - raise ValueError(_get_invalid_paths_message(tzpaths)) - base_tzpath = tzpaths - else: - env_var = os.environ.get("PYTHONTZPATH", None) - if env_var is not None: - base_tzpath = _parse_python_tzpath(env_var) - else: - base_tzpath = _parse_python_tzpath( - sysconfig.get_config_var("TZPATH") - ) - - TZPATH = tuple(base_tzpath) - - -def _parse_python_tzpath(env_var): - if not env_var: - return () - - raw_tzpath = env_var.split(os.pathsep) - new_tzpath = tuple(filter(os.path.isabs, raw_tzpath)) - - # If anything has been filtered out, we will warn about it - if len(new_tzpath) != len(raw_tzpath): - import warnings - - msg = _get_invalid_paths_message(raw_tzpath) - - warnings.warn( - "Invalid paths specified in PYTHONTZPATH environment variable. " - + msg, - InvalidTZPathWarning, - ) - - return new_tzpath - - -def _get_invalid_paths_message(tzpaths): - invalid_paths = (path for path in tzpaths if not os.path.isabs(path)) - - prefix = "\n " - indented_str = prefix + prefix.join(invalid_paths) - - return ( - "Paths should be absolute but found the following relative paths:" - + indented_str - ) - - -def find_tzfile(key): - """Retrieve the path to a TZif file from a key.""" - _validate_tzfile_path(key) - for search_path in TZPATH: - filepath = os.path.join(search_path, key) - if os.path.isfile(filepath): - return filepath - - return None - - -_TEST_PATH = os.path.normpath(os.path.join("_", "_"))[:-1] - - -def _validate_tzfile_path(path, _base=_TEST_PATH): - if os.path.isabs(path): - raise ValueError( - f"ZoneInfo keys may not be absolute paths, got: {path}" - ) - - # We only care about the kinds of path normalizations that would change the - # length of the key - e.g. a/../b -> a/b, or a/b/ -> a/b. On Windows, - # normpath will also change from a/b to a\b, but that would still preserve - # the length. - new_path = os.path.normpath(path) - if len(new_path) != len(path): - raise ValueError( - f"ZoneInfo keys must be normalized relative paths, got: {path}" - ) - - resolved = os.path.normpath(os.path.join(_base, new_path)) - if not resolved.startswith(_base): - raise ValueError( - f"ZoneInfo keys must refer to subdirectories of TZPATH, got: {path}" - ) - - -del _TEST_PATH - - -def available_timezones(): - """Returns a set containing all available time zones. - - .. caution:: - - This may attempt to open a large number of files, since the best way to - determine if a given file on the time zone search path is to open it - and check for the "magic string" at the beginning. - """ - from importlib import resources - - valid_zones = set() - - # Start with loading from the tzdata package if it exists: this has a - # pre-assembled list of zones that only requires opening one file. - try: - with resources.files("tzdata").joinpath("zones").open("r") as f: - for zone in f: - zone = zone.strip() - if zone: - valid_zones.add(zone) - except (ImportError, FileNotFoundError): - pass - - def valid_key(fpath): - try: - with open(fpath, "rb") as f: - return f.read(4) == b"TZif" - except Exception: # pragma: nocover - return False - - for tz_root in TZPATH: - if not os.path.exists(tz_root): - continue - - for root, dirnames, files in os.walk(tz_root): - if root == tz_root: - # right/ and posix/ are special directories and shouldn't be - # included in the output of available zones - if "right" in dirnames: - dirnames.remove("right") - if "posix" in dirnames: - dirnames.remove("posix") - - for file in files: - fpath = os.path.join(root, file) - - key = os.path.relpath(fpath, start=tz_root) - if os.sep != "/": # pragma: nocover - key = key.replace(os.sep, "/") - - if not key or key in valid_zones: - continue - - if valid_key(fpath): - valid_zones.add(key) - - if "posixrules" in valid_zones: - # posixrules is a special symlink-only time zone where it exists, it - # should not be included in the output - valid_zones.remove("posixrules") - - return valid_zones - - -class InvalidTZPathWarning(RuntimeWarning): - """Warning raised if an invalid path is specified in PYTHONTZPATH.""" - - -TZPATH = () -reset_tzpath() diff --git a/python/Lib/zoneinfo/_zoneinfo.py b/python/Lib/zoneinfo/_zoneinfo.py deleted file mode 100644 index c3d999f..0000000 --- a/python/Lib/zoneinfo/_zoneinfo.py +++ /dev/null @@ -1,752 +0,0 @@ -import bisect -import calendar -import collections -import functools -import re -import weakref -from datetime import datetime, timedelta, tzinfo - -from . import _common, _tzpath - -EPOCH = datetime(1970, 1, 1) -EPOCHORDINAL = datetime(1970, 1, 1).toordinal() - -# It is relatively expensive to construct new timedelta objects, and in most -# cases we're looking at the same deltas, like integer numbers of hours, etc. -# To improve speed and memory use, we'll keep a dictionary with references -# to the ones we've already used so far. -# -# Loading every time zone in the 2020a version of the time zone database -# requires 447 timedeltas, which requires approximately the amount of space -# that ZoneInfo("America/New_York") with 236 transitions takes up, so we will -# set the cache size to 512 so that in the common case we always get cache -# hits, but specifically crafted ZoneInfo objects don't leak arbitrary amounts -# of memory. -@functools.lru_cache(maxsize=512) -def _load_timedelta(seconds): - return timedelta(seconds=seconds) - - -class ZoneInfo(tzinfo): - _strong_cache_size = 8 - _strong_cache = collections.OrderedDict() - _weak_cache = weakref.WeakValueDictionary() - __module__ = "zoneinfo" - - def __init_subclass__(cls): - cls._strong_cache = collections.OrderedDict() - cls._weak_cache = weakref.WeakValueDictionary() - - def __new__(cls, key): - instance = cls._weak_cache.get(key, None) - if instance is None: - instance = cls._weak_cache.setdefault(key, cls._new_instance(key)) - instance._from_cache = True - - # Update the "strong" cache - cls._strong_cache[key] = cls._strong_cache.pop(key, instance) - - if len(cls._strong_cache) > cls._strong_cache_size: - cls._strong_cache.popitem(last=False) - - return instance - - @classmethod - def no_cache(cls, key): - obj = cls._new_instance(key) - obj._from_cache = False - - return obj - - @classmethod - def _new_instance(cls, key): - obj = super().__new__(cls) - obj._key = key - obj._file_path = obj._find_tzfile(key) - - if obj._file_path is not None: - file_obj = open(obj._file_path, "rb") - else: - file_obj = _common.load_tzdata(key) - - with file_obj as f: - obj._load_file(f) - - return obj - - @classmethod - def from_file(cls, fobj, /, key=None): - obj = super().__new__(cls) - obj._key = key - obj._file_path = None - obj._load_file(fobj) - obj._file_repr = repr(fobj) - - # Disable pickling for objects created from files - obj.__reduce__ = obj._file_reduce - - return obj - - @classmethod - def clear_cache(cls, *, only_keys=None): - if only_keys is not None: - for key in only_keys: - cls._weak_cache.pop(key, None) - cls._strong_cache.pop(key, None) - - else: - cls._weak_cache.clear() - cls._strong_cache.clear() - - @property - def key(self): - return self._key - - def utcoffset(self, dt): - return self._find_trans(dt).utcoff - - def dst(self, dt): - return self._find_trans(dt).dstoff - - def tzname(self, dt): - return self._find_trans(dt).tzname - - def fromutc(self, dt): - """Convert from datetime in UTC to datetime in local time""" - - if not isinstance(dt, datetime): - raise TypeError("fromutc() requires a datetime argument") - if dt.tzinfo is not self: - raise ValueError("dt.tzinfo is not self") - - timestamp = self._get_local_timestamp(dt) - num_trans = len(self._trans_utc) - - if num_trans >= 1 and timestamp < self._trans_utc[0]: - tti = self._tti_before - fold = 0 - elif ( - num_trans == 0 or timestamp > self._trans_utc[-1] - ) and not isinstance(self._tz_after, _ttinfo): - tti, fold = self._tz_after.get_trans_info_fromutc( - timestamp, dt.year - ) - elif num_trans == 0: - tti = self._tz_after - fold = 0 - else: - idx = bisect.bisect_right(self._trans_utc, timestamp) - - if num_trans > 1 and timestamp >= self._trans_utc[1]: - tti_prev, tti = self._ttinfos[idx - 2 : idx] - elif timestamp > self._trans_utc[-1]: - tti_prev = self._ttinfos[-1] - tti = self._tz_after - else: - tti_prev = self._tti_before - tti = self._ttinfos[0] - - # Detect fold - shift = tti_prev.utcoff - tti.utcoff - fold = shift.total_seconds() > timestamp - self._trans_utc[idx - 1] - dt += tti.utcoff - if fold: - return dt.replace(fold=1) - else: - return dt - - def _find_trans(self, dt): - if dt is None: - if self._fixed_offset: - return self._tz_after - else: - return _NO_TTINFO - - ts = self._get_local_timestamp(dt) - - lt = self._trans_local[dt.fold] - - num_trans = len(lt) - - if num_trans and ts < lt[0]: - return self._tti_before - elif not num_trans or ts > lt[-1]: - if isinstance(self._tz_after, _TZStr): - return self._tz_after.get_trans_info(ts, dt.year, dt.fold) - else: - return self._tz_after - else: - # idx is the transition that occurs after this timestamp, so we - # subtract off 1 to get the current ttinfo - idx = bisect.bisect_right(lt, ts) - 1 - assert idx >= 0 - return self._ttinfos[idx] - - def _get_local_timestamp(self, dt): - return ( - (dt.toordinal() - EPOCHORDINAL) * 86400 - + dt.hour * 3600 - + dt.minute * 60 - + dt.second - ) - - def __str__(self): - if self._key is not None: - return f"{self._key}" - else: - return repr(self) - - def __repr__(self): - if self._key is not None: - return f"{self.__class__.__name__}(key={self._key!r})" - else: - return f"{self.__class__.__name__}.from_file({self._file_repr})" - - def __reduce__(self): - return (self.__class__._unpickle, (self._key, self._from_cache)) - - def _file_reduce(self): - import pickle - - raise pickle.PicklingError( - "Cannot pickle a ZoneInfo file created from a file stream." - ) - - @classmethod - def _unpickle(cls, key, from_cache, /): - if from_cache: - return cls(key) - else: - return cls.no_cache(key) - - def _find_tzfile(self, key): - return _tzpath.find_tzfile(key) - - def _load_file(self, fobj): - # Retrieve all the data as it exists in the zoneinfo file - trans_idx, trans_utc, utcoff, isdst, abbr, tz_str = _common.load_data( - fobj - ) - - # Infer the DST offsets (needed for .dst()) from the data - dstoff = self._utcoff_to_dstoff(trans_idx, utcoff, isdst) - - # Convert all the transition times (UTC) into "seconds since 1970-01-01 local time" - trans_local = self._ts_to_local(trans_idx, trans_utc, utcoff) - - # Construct `_ttinfo` objects for each transition in the file - _ttinfo_list = [ - _ttinfo( - _load_timedelta(utcoffset), _load_timedelta(dstoffset), tzname - ) - for utcoffset, dstoffset, tzname in zip(utcoff, dstoff, abbr) - ] - - self._trans_utc = trans_utc - self._trans_local = trans_local - self._ttinfos = [_ttinfo_list[idx] for idx in trans_idx] - - # Find the first non-DST transition - for i in range(len(isdst)): - if not isdst[i]: - self._tti_before = _ttinfo_list[i] - break - else: - if self._ttinfos: - self._tti_before = self._ttinfos[0] - else: - self._tti_before = None - - # Set the "fallback" time zone - if tz_str is not None and tz_str != b"": - self._tz_after = _parse_tz_str(tz_str.decode()) - else: - if not self._ttinfos and not _ttinfo_list: - raise ValueError("No time zone information found.") - - if self._ttinfos: - self._tz_after = self._ttinfos[-1] - else: - self._tz_after = _ttinfo_list[-1] - - # Determine if this is a "fixed offset" zone, meaning that the output - # of the utcoffset, dst and tzname functions does not depend on the - # specific datetime passed. - # - # We make three simplifying assumptions here: - # - # 1. If _tz_after is not a _ttinfo, it has transitions that might - # actually occur (it is possible to construct TZ strings that - # specify STD and DST but no transitions ever occur, such as - # AAA0BBB,0/0,J365/25). - # 2. If _ttinfo_list contains more than one _ttinfo object, the objects - # represent different offsets. - # 3. _ttinfo_list contains no unused _ttinfos (in which case an - # otherwise fixed-offset zone with extra _ttinfos defined may - # appear to *not* be a fixed offset zone). - # - # Violations to these assumptions would be fairly exotic, and exotic - # zones should almost certainly not be used with datetime.time (the - # only thing that would be affected by this). - if len(_ttinfo_list) > 1 or not isinstance(self._tz_after, _ttinfo): - self._fixed_offset = False - elif not _ttinfo_list: - self._fixed_offset = True - else: - self._fixed_offset = _ttinfo_list[0] == self._tz_after - - @staticmethod - def _utcoff_to_dstoff(trans_idx, utcoffsets, isdsts): - # Now we must transform our ttis and abbrs into `_ttinfo` objects, - # but there is an issue: .dst() must return a timedelta with the - # difference between utcoffset() and the "standard" offset, but - # the "base offset" and "DST offset" are not encoded in the file; - # we can infer what they are from the isdst flag, but it is not - # sufficient to to just look at the last standard offset, because - # occasionally countries will shift both DST offset and base offset. - - typecnt = len(isdsts) - dstoffs = [0] * typecnt # Provisionally assign all to 0. - dst_cnt = sum(isdsts) - dst_found = 0 - - for i in range(1, len(trans_idx)): - if dst_cnt == dst_found: - break - - idx = trans_idx[i] - - dst = isdsts[idx] - - # We're only going to look at daylight saving time - if not dst: - continue - - # Skip any offsets that have already been assigned - if dstoffs[idx] != 0: - continue - - dstoff = 0 - utcoff = utcoffsets[idx] - - comp_idx = trans_idx[i - 1] - - if not isdsts[comp_idx]: - dstoff = utcoff - utcoffsets[comp_idx] - - if not dstoff and idx < (typecnt - 1): - comp_idx = trans_idx[i + 1] - - # If the following transition is also DST and we couldn't - # find the DST offset by this point, we're going to have to - # skip it and hope this transition gets assigned later - if isdsts[comp_idx]: - continue - - dstoff = utcoff - utcoffsets[comp_idx] - - if dstoff: - dst_found += 1 - dstoffs[idx] = dstoff - else: - # If we didn't find a valid value for a given index, we'll end up - # with dstoff = 0 for something where `isdst=1`. This is obviously - # wrong - one hour will be a much better guess than 0 - for idx in range(typecnt): - if not dstoffs[idx] and isdsts[idx]: - dstoffs[idx] = 3600 - - return dstoffs - - @staticmethod - def _ts_to_local(trans_idx, trans_list_utc, utcoffsets): - """Generate number of seconds since 1970 *in the local time*. - - This is necessary to easily find the transition times in local time""" - if not trans_list_utc: - return [[], []] - - # Start with the timestamps and modify in-place - trans_list_wall = [list(trans_list_utc), list(trans_list_utc)] - - if len(utcoffsets) > 1: - offset_0 = utcoffsets[0] - offset_1 = utcoffsets[trans_idx[0]] - if offset_1 > offset_0: - offset_1, offset_0 = offset_0, offset_1 - else: - offset_0 = offset_1 = utcoffsets[0] - - trans_list_wall[0][0] += offset_0 - trans_list_wall[1][0] += offset_1 - - for i in range(1, len(trans_idx)): - offset_0 = utcoffsets[trans_idx[i - 1]] - offset_1 = utcoffsets[trans_idx[i]] - - if offset_1 > offset_0: - offset_1, offset_0 = offset_0, offset_1 - - trans_list_wall[0][i] += offset_0 - trans_list_wall[1][i] += offset_1 - - return trans_list_wall - - -class _ttinfo: - __slots__ = ["utcoff", "dstoff", "tzname"] - - def __init__(self, utcoff, dstoff, tzname): - self.utcoff = utcoff - self.dstoff = dstoff - self.tzname = tzname - - def __eq__(self, other): - return ( - self.utcoff == other.utcoff - and self.dstoff == other.dstoff - and self.tzname == other.tzname - ) - - def __repr__(self): # pragma: nocover - return ( - f"{self.__class__.__name__}" - + f"({self.utcoff}, {self.dstoff}, {self.tzname})" - ) - - -_NO_TTINFO = _ttinfo(None, None, None) - - -class _TZStr: - __slots__ = ( - "std", - "dst", - "start", - "end", - "get_trans_info", - "get_trans_info_fromutc", - "dst_diff", - ) - - def __init__( - self, std_abbr, std_offset, dst_abbr, dst_offset, start=None, end=None - ): - self.dst_diff = dst_offset - std_offset - std_offset = _load_timedelta(std_offset) - self.std = _ttinfo( - utcoff=std_offset, dstoff=_load_timedelta(0), tzname=std_abbr - ) - - self.start = start - self.end = end - - dst_offset = _load_timedelta(dst_offset) - delta = _load_timedelta(self.dst_diff) - self.dst = _ttinfo(utcoff=dst_offset, dstoff=delta, tzname=dst_abbr) - - # These are assertions because the constructor should only be called - # by functions that would fail before passing start or end - assert start is not None, "No transition start specified" - assert end is not None, "No transition end specified" - - self.get_trans_info = self._get_trans_info - self.get_trans_info_fromutc = self._get_trans_info_fromutc - - def transitions(self, year): - start = self.start.year_to_epoch(year) - end = self.end.year_to_epoch(year) - return start, end - - def _get_trans_info(self, ts, year, fold): - """Get the information about the current transition - tti""" - start, end = self.transitions(year) - - # With fold = 0, the period (denominated in local time) with the - # smaller offset starts at the end of the gap and ends at the end of - # the fold; with fold = 1, it runs from the start of the gap to the - # beginning of the fold. - # - # So in order to determine the DST boundaries we need to know both - # the fold and whether DST is positive or negative (rare), and it - # turns out that this boils down to fold XOR is_positive. - if fold == (self.dst_diff >= 0): - end -= self.dst_diff - else: - start += self.dst_diff - - if start < end: - isdst = start <= ts < end - else: - isdst = not (end <= ts < start) - - return self.dst if isdst else self.std - - def _get_trans_info_fromutc(self, ts, year): - start, end = self.transitions(year) - start -= self.std.utcoff.total_seconds() - end -= self.dst.utcoff.total_seconds() - - if start < end: - isdst = start <= ts < end - else: - isdst = not (end <= ts < start) - - # For positive DST, the ambiguous period is one dst_diff after the end - # of DST; for negative DST, the ambiguous period is one dst_diff before - # the start of DST. - if self.dst_diff > 0: - ambig_start = end - ambig_end = end + self.dst_diff - else: - ambig_start = start - ambig_end = start - self.dst_diff - - fold = ambig_start <= ts < ambig_end - - return (self.dst if isdst else self.std, fold) - - -def _post_epoch_days_before_year(year): - """Get the number of days between 1970-01-01 and YEAR-01-01""" - y = year - 1 - return y * 365 + y // 4 - y // 100 + y // 400 - EPOCHORDINAL - - -class _DayOffset: - __slots__ = ["d", "julian", "hour", "minute", "second"] - - def __init__(self, d, julian, hour=2, minute=0, second=0): - if not (0 + julian) <= d <= 365: - min_day = 0 + julian - raise ValueError(f"d must be in [{min_day}, 365], not: {d}") - - self.d = d - self.julian = julian - self.hour = hour - self.minute = minute - self.second = second - - def year_to_epoch(self, year): - days_before_year = _post_epoch_days_before_year(year) - - d = self.d - if self.julian and d >= 59 and calendar.isleap(year): - d += 1 - - epoch = (days_before_year + d) * 86400 - epoch += self.hour * 3600 + self.minute * 60 + self.second - - return epoch - - -class _CalendarOffset: - __slots__ = ["m", "w", "d", "hour", "minute", "second"] - - _DAYS_BEFORE_MONTH = ( - -1, - 0, - 31, - 59, - 90, - 120, - 151, - 181, - 212, - 243, - 273, - 304, - 334, - ) - - def __init__(self, m, w, d, hour=2, minute=0, second=0): - if not 0 < m <= 12: - raise ValueError("m must be in (0, 12]") - - if not 0 < w <= 5: - raise ValueError("w must be in (0, 5]") - - if not 0 <= d <= 6: - raise ValueError("d must be in [0, 6]") - - self.m = m - self.w = w - self.d = d - self.hour = hour - self.minute = minute - self.second = second - - @classmethod - def _ymd2ord(cls, year, month, day): - return ( - _post_epoch_days_before_year(year) - + cls._DAYS_BEFORE_MONTH[month] - + (month > 2 and calendar.isleap(year)) - + day - ) - - # TODO: These are not actually epoch dates as they are expressed in local time - def year_to_epoch(self, year): - """Calculates the datetime of the occurrence from the year""" - # We know year and month, we need to convert w, d into day of month - # - # Week 1 is the first week in which day `d` (where 0 = Sunday) appears. - # Week 5 represents the last occurrence of day `d`, so we need to know - # the range of the month. - first_day, days_in_month = calendar.monthrange(year, self.m) - - # This equation seems magical, so I'll break it down: - # 1. calendar says 0 = Monday, POSIX says 0 = Sunday - # so we need first_day + 1 to get 1 = Monday -> 7 = Sunday, - # which is still equivalent because this math is mod 7 - # 2. Get first day - desired day mod 7: -1 % 7 = 6, so we don't need - # to do anything to adjust negative numbers. - # 3. Add 1 because month days are a 1-based index. - month_day = (self.d - (first_day + 1)) % 7 + 1 - - # Now use a 0-based index version of `w` to calculate the w-th - # occurrence of `d` - month_day += (self.w - 1) * 7 - - # month_day will only be > days_in_month if w was 5, and `w` means - # "last occurrence of `d`", so now we just check if we over-shot the - # end of the month and if so knock off 1 week. - if month_day > days_in_month: - month_day -= 7 - - ordinal = self._ymd2ord(year, self.m, month_day) - epoch = ordinal * 86400 - epoch += self.hour * 3600 + self.minute * 60 + self.second - return epoch - - -def _parse_tz_str(tz_str): - # The tz string has the format: - # - # std[offset[dst[offset],start[/time],end[/time]]] - # - # std and dst must be 3 or more characters long and must not contain - # a leading colon, embedded digits, commas, nor a plus or minus signs; - # The spaces between "std" and "offset" are only for display and are - # not actually present in the string. - # - # The format of the offset is ``[+|-]hh[:mm[:ss]]`` - - offset_str, *start_end_str = tz_str.split(",", 1) - - # fmt: off - parser_re = re.compile( - r"(?P[^<0-9:.+-]+|<[a-zA-Z0-9+\-]+>)" + - r"((?P[+-]?\d{1,2}(:\d{2}(:\d{2})?)?)" + - r"((?P[^0-9:.+-]+|<[a-zA-Z0-9+\-]+>)" + - r"((?P[+-]?\d{1,2}(:\d{2}(:\d{2})?)?))?" + - r")?" + # dst - r")?$" # stdoff - ) - # fmt: on - - m = parser_re.match(offset_str) - - if m is None: - raise ValueError(f"{tz_str} is not a valid TZ string") - - std_abbr = m.group("std") - dst_abbr = m.group("dst") - dst_offset = None - - std_abbr = std_abbr.strip("<>") - - if dst_abbr: - dst_abbr = dst_abbr.strip("<>") - - if std_offset := m.group("stdoff"): - try: - std_offset = _parse_tz_delta(std_offset) - except ValueError as e: - raise ValueError(f"Invalid STD offset in {tz_str}") from e - else: - std_offset = 0 - - if dst_abbr is not None: - if dst_offset := m.group("dstoff"): - try: - dst_offset = _parse_tz_delta(dst_offset) - except ValueError as e: - raise ValueError(f"Invalid DST offset in {tz_str}") from e - else: - dst_offset = std_offset + 3600 - - if not start_end_str: - raise ValueError(f"Missing transition rules: {tz_str}") - - start_end_strs = start_end_str[0].split(",", 1) - try: - start, end = (_parse_dst_start_end(x) for x in start_end_strs) - except ValueError as e: - raise ValueError(f"Invalid TZ string: {tz_str}") from e - - return _TZStr(std_abbr, std_offset, dst_abbr, dst_offset, start, end) - elif start_end_str: - raise ValueError(f"Transition rule present without DST: {tz_str}") - else: - # This is a static ttinfo, don't return _TZStr - return _ttinfo( - _load_timedelta(std_offset), _load_timedelta(0), std_abbr - ) - - -def _parse_dst_start_end(dststr): - date, *time = dststr.split("/") - if date[0] == "M": - n_is_julian = False - m = re.match(r"M(\d{1,2})\.(\d).(\d)$", date) - if m is None: - raise ValueError(f"Invalid dst start/end date: {dststr}") - date_offset = tuple(map(int, m.groups())) - offset = _CalendarOffset(*date_offset) - else: - if date[0] == "J": - n_is_julian = True - date = date[1:] - else: - n_is_julian = False - - doy = int(date) - offset = _DayOffset(doy, n_is_julian) - - if time: - time_components = list(map(int, time[0].split(":"))) - n_components = len(time_components) - if n_components < 3: - time_components.extend([0] * (3 - n_components)) - offset.hour, offset.minute, offset.second = time_components - - return offset - - -def _parse_tz_delta(tz_delta): - match = re.match( - r"(?P[+-])?(?P\d{1,2})(:(?P\d{2})(:(?P\d{2}))?)?", - tz_delta, - ) - # Anything passed to this function should already have hit an equivalent - # regular expression to find the section to parse. - assert match is not None, tz_delta - - h, m, s = ( - int(v) if v is not None else 0 - for v in map(match.group, ("h", "m", "s")) - ) - - total = h * 3600 + m * 60 + s - - if not -86400 < total < 86400: - raise ValueError( - f"Offset must be strictly between -24h and +24h: {tz_delta}" - ) - - # Yes, +5 maps to an offset of -5h - if match.group("sign") != "-": - total *= -1 - - return total diff --git a/python/include/Python.h b/python/include/Python.h deleted file mode 100644 index fa1c418..0000000 --- a/python/include/Python.h +++ /dev/null @@ -1,109 +0,0 @@ -// Entry point of the Python C API. -// C extensions should only #include , and not include directly -// the other Python header files included by . - -#ifndef Py_PYTHON_H -#define Py_PYTHON_H - -// Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { - -// Include Python header files -#include "patchlevel.h" -#include "pyconfig.h" -#include "pymacconfig.h" - -#if defined(__sgi) && !defined(_SGI_MP_SOURCE) -# define _SGI_MP_SOURCE -#endif - -// stdlib.h, stdio.h, errno.h and string.h headers are not used by Python -// headers, but kept for backward compatibility. They are excluded from the -// limited C API of Python 3.11. -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# include -# include // FILE* -# include // errno -# include // memcpy() -#endif -#ifndef MS_WINDOWS -# include -#endif -#ifdef HAVE_STDDEF_H -# include // size_t -#endif - -#include // assert() -#include // wchar_t - -#include "pyport.h" -#include "pymacro.h" -#include "pymath.h" -#include "pymem.h" -#include "pytypedefs.h" -#include "pybuffer.h" -#include "object.h" -#include "objimpl.h" -#include "typeslots.h" -#include "pyhash.h" -#include "cpython/pydebug.h" -#include "bytearrayobject.h" -#include "bytesobject.h" -#include "unicodeobject.h" -#include "longobject.h" -#include "cpython/longintrepr.h" -#include "boolobject.h" -#include "floatobject.h" -#include "complexobject.h" -#include "rangeobject.h" -#include "memoryobject.h" -#include "tupleobject.h" -#include "listobject.h" -#include "dictobject.h" -#include "cpython/odictobject.h" -#include "enumobject.h" -#include "setobject.h" -#include "methodobject.h" -#include "moduleobject.h" -#include "cpython/funcobject.h" -#include "cpython/classobject.h" -#include "fileobject.h" -#include "pycapsule.h" -#include "cpython/code.h" -#include "pyframe.h" -#include "traceback.h" -#include "sliceobject.h" -#include "cpython/cellobject.h" -#include "iterobject.h" -#include "cpython/initconfig.h" -#include "pystate.h" -#include "cpython/genobject.h" -#include "descrobject.h" -#include "genericaliasobject.h" -#include "warnings.h" -#include "weakrefobject.h" -#include "structseq.h" -#include "cpython/picklebufobject.h" -#include "cpython/pytime.h" -#include "codecs.h" -#include "pyerrors.h" -#include "pythread.h" -#include "cpython/context.h" -#include "modsupport.h" -#include "compile.h" -#include "pythonrun.h" -#include "pylifecycle.h" -#include "ceval.h" -#include "sysmodule.h" -#include "osmodule.h" -#include "intrcheck.h" -#include "import.h" -#include "abstract.h" -#include "bltinmodule.h" -#include "cpython/pyctype.h" -#include "pystrtod.h" -#include "pystrcmp.h" -#include "fileutils.h" -#include "cpython/pyfpe.h" -#include "tracemalloc.h" - -#endif /* !Py_PYTHON_H */ diff --git a/python/include/abstract.h b/python/include/abstract.h deleted file mode 100644 index 1c6ef36..0000000 --- a/python/include/abstract.h +++ /dev/null @@ -1,873 +0,0 @@ -/* Abstract Object Interface (many thanks to Jim Fulton) */ - -#ifndef Py_ABSTRACTOBJECT_H -#define Py_ABSTRACTOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -/* === Object Protocol ================================================== */ - -/* Implemented elsewhere: - - int PyObject_Print(PyObject *o, FILE *fp, int flags); - - Print an object 'o' on file 'fp'. Returns -1 on error. The flags argument - is used to enable certain printing options. The only option currently - supported is Py_Print_RAW. - - (What should be said about Py_Print_RAW?). */ - - -/* Implemented elsewhere: - - int PyObject_HasAttrString(PyObject *o, const char *attr_name); - - Returns 1 if object 'o' has the attribute attr_name, and 0 otherwise. - - This is equivalent to the Python expression: hasattr(o,attr_name). - - This function always succeeds. */ - - -/* Implemented elsewhere: - - PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name); - - Retrieve an attributed named attr_name form object o. - Returns the attribute value on success, or NULL on failure. - - This is the equivalent of the Python expression: o.attr_name. */ - - -/* Implemented elsewhere: - - int PyObject_HasAttr(PyObject *o, PyObject *attr_name); - - Returns 1 if o has the attribute attr_name, and 0 otherwise. - - This is equivalent to the Python expression: hasattr(o,attr_name). - - This function always succeeds. */ - -/* Implemented elsewhere: - - PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name); - - Retrieve an attributed named 'attr_name' form object 'o'. - Returns the attribute value on success, or NULL on failure. - - This is the equivalent of the Python expression: o.attr_name. */ - - -/* Implemented elsewhere: - - int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v); - - Set the value of the attribute named attr_name, for object 'o', - to the value 'v'. Raise an exception and return -1 on failure; return 0 on - success. - - This is the equivalent of the Python statement o.attr_name=v. */ - - -/* Implemented elsewhere: - - int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v); - - Set the value of the attribute named attr_name, for object 'o', to the value - 'v'. an exception and return -1 on failure; return 0 on success. - - This is the equivalent of the Python statement o.attr_name=v. */ - -/* Implemented as a macro: - - int PyObject_DelAttrString(PyObject *o, const char *attr_name); - - Delete attribute named attr_name, for object o. Returns - -1 on failure. - - This is the equivalent of the Python statement: del o.attr_name. */ -#define PyObject_DelAttrString(O,A) PyObject_SetAttrString((O),(A), NULL) - - -/* Implemented as a macro: - - int PyObject_DelAttr(PyObject *o, PyObject *attr_name); - - Delete attribute named attr_name, for object o. Returns -1 - on failure. This is the equivalent of the Python - statement: del o.attr_name. */ -#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A), NULL) - - -/* Implemented elsewhere: - - PyObject *PyObject_Repr(PyObject *o); - - Compute the string representation of object 'o'. Returns the - string representation on success, NULL on failure. - - This is the equivalent of the Python expression: repr(o). - - Called by the repr() built-in function. */ - - -/* Implemented elsewhere: - - PyObject *PyObject_Str(PyObject *o); - - Compute the string representation of object, o. Returns the - string representation on success, NULL on failure. - - This is the equivalent of the Python expression: str(o). - - Called by the str() and print() built-in functions. */ - - -/* Declared elsewhere - - PyAPI_FUNC(int) PyCallable_Check(PyObject *o); - - Determine if the object, o, is callable. Return 1 if the object is callable - and 0 otherwise. - - This function always succeeds. */ - - -#ifdef PY_SSIZE_T_CLEAN -# define PyObject_CallFunction _PyObject_CallFunction_SizeT -# define PyObject_CallMethod _PyObject_CallMethod_SizeT -#endif - - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 -/* Call a callable Python object without any arguments */ -PyAPI_FUNC(PyObject *) PyObject_CallNoArgs(PyObject *func); -#endif - - -/* Call a callable Python object 'callable' with arguments given by the - tuple 'args' and keywords arguments given by the dictionary 'kwargs'. - - 'args' must not be NULL, use an empty tuple if no arguments are - needed. If no named arguments are needed, 'kwargs' can be NULL. - - This is the equivalent of the Python expression: - callable(*args, **kwargs). */ -PyAPI_FUNC(PyObject *) PyObject_Call(PyObject *callable, - PyObject *args, PyObject *kwargs); - - -/* Call a callable Python object 'callable', with arguments given by the - tuple 'args'. If no arguments are needed, then 'args' can be NULL. - - Returns the result of the call on success, or NULL on failure. - - This is the equivalent of the Python expression: - callable(*args). */ -PyAPI_FUNC(PyObject *) PyObject_CallObject(PyObject *callable, - PyObject *args); - -/* Call a callable Python object, callable, with a variable number of C - arguments. The C arguments are described using a mkvalue-style format - string. - - The format may be NULL, indicating that no arguments are provided. - - Returns the result of the call on success, or NULL on failure. - - This is the equivalent of the Python expression: - callable(arg1, arg2, ...). */ -PyAPI_FUNC(PyObject *) PyObject_CallFunction(PyObject *callable, - const char *format, ...); - -/* Call the method named 'name' of object 'obj' with a variable number of - C arguments. The C arguments are described by a mkvalue format string. - - The format can be NULL, indicating that no arguments are provided. - - Returns the result of the call on success, or NULL on failure. - - This is the equivalent of the Python expression: - obj.name(arg1, arg2, ...). */ -PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *obj, - const char *name, - const char *format, ...); - -PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable, - const char *format, - ...); - -PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *obj, - const char *name, - const char *format, - ...); - -/* Call a callable Python object 'callable' with a variable number of C - arguments. The C arguments are provided as PyObject* values, terminated - by a NULL. - - Returns the result of the call on success, or NULL on failure. - - This is the equivalent of the Python expression: - callable(arg1, arg2, ...). */ -PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable, - ...); - -/* Call the method named 'name' of object 'obj' with a variable number of - C arguments. The C arguments are provided as PyObject* values, terminated - by NULL. - - Returns the result of the call on success, or NULL on failure. - - This is the equivalent of the Python expression: obj.name(*args). */ - -PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs( - PyObject *obj, - PyObject *name, - ...); - - -/* Implemented elsewhere: - - Py_hash_t PyObject_Hash(PyObject *o); - - Compute and return the hash, hash_value, of an object, o. On - failure, return -1. - - This is the equivalent of the Python expression: hash(o). */ - - -/* Implemented elsewhere: - - int PyObject_IsTrue(PyObject *o); - - Returns 1 if the object, o, is considered to be true, 0 if o is - considered to be false and -1 on failure. - - This is equivalent to the Python expression: not not o. */ - - -/* Implemented elsewhere: - - int PyObject_Not(PyObject *o); - - Returns 0 if the object, o, is considered to be true, 1 if o is - considered to be false and -1 on failure. - - This is equivalent to the Python expression: not o. */ - - -/* Get the type of an object. - - On success, returns a type object corresponding to the object type of object - 'o'. On failure, returns NULL. - - This is equivalent to the Python expression: type(o) */ -PyAPI_FUNC(PyObject *) PyObject_Type(PyObject *o); - - -/* Return the size of object 'o'. If the object 'o' provides both sequence and - mapping protocols, the sequence size is returned. - - On error, -1 is returned. - - This is the equivalent to the Python expression: len(o) */ -PyAPI_FUNC(Py_ssize_t) PyObject_Size(PyObject *o); - - -/* For DLL compatibility */ -#undef PyObject_Length -PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o); -#define PyObject_Length PyObject_Size - -/* Return element of 'o' corresponding to the object 'key'. Return NULL - on failure. - - This is the equivalent of the Python expression: o[key] */ -PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key); - - -/* Map the object 'key' to the value 'v' into 'o'. - - Raise an exception and return -1 on failure; return 0 on success. - - This is the equivalent of the Python statement: o[key]=v. */ -PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v); - -/* Remove the mapping for the string 'key' from the object 'o'. - Returns -1 on failure. - - This is equivalent to the Python statement: del o[key]. */ -PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, const char *key); - -/* Delete the mapping for the object 'key' from the object 'o'. - Returns -1 on failure. - - This is the equivalent of the Python statement: del o[key]. */ -PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key); - - -/* === Old Buffer API ============================================ */ - -/* FIXME: usage of these should all be replaced in Python itself - but for backwards compatibility we will implement them. - Their usage without a corresponding "unlock" mechanism - may create issues (but they would already be there). */ - -/* Takes an arbitrary object which must support the (character, single segment) - buffer interface and returns a pointer to a read-only memory location - usable as character based input for subsequent processing. - - Return 0 on success. buffer and buffer_len are only set in case no error - occurs. Otherwise, -1 is returned and an exception set. */ -Py_DEPRECATED(3.0) -PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj, - const char **buffer, - Py_ssize_t *buffer_len); - -/* Checks whether an arbitrary object supports the (character, single segment) - buffer interface. - - Returns 1 on success, 0 on failure. */ -Py_DEPRECATED(3.0) PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj); - -/* Same as PyObject_AsCharBuffer() except that this API expects (readable, - single segment) buffer interface and returns a pointer to a read-only memory - location which can contain arbitrary data. - - 0 is returned on success. buffer and buffer_len are only set in case no - error occurs. Otherwise, -1 is returned and an exception set. */ -Py_DEPRECATED(3.0) -PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj, - const void **buffer, - Py_ssize_t *buffer_len); - -/* Takes an arbitrary object which must support the (writable, single segment) - buffer interface and returns a pointer to a writable memory location in - buffer of size 'buffer_len'. - - Return 0 on success. buffer and buffer_len are only set in case no error - occurs. Otherwise, -1 is returned and an exception set. */ -Py_DEPRECATED(3.0) -PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj, - void **buffer, - Py_ssize_t *buffer_len); - - -/* === New Buffer API ============================================ */ - -/* Takes an arbitrary object and returns the result of calling - obj.__format__(format_spec). */ -PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj, - PyObject *format_spec); - - -/* ==== Iterators ================================================ */ - -/* Takes an object and returns an iterator for it. - This is typically a new iterator but if the argument is an iterator, this - returns itself. */ -PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *); - -/* Takes an AsyncIterable object and returns an AsyncIterator for it. - This is typically a new iterator but if the argument is an AsyncIterator, - this returns itself. */ -PyAPI_FUNC(PyObject *) PyObject_GetAIter(PyObject *); - -/* Returns non-zero if the object 'obj' provides iterator protocols, and 0 otherwise. - - This function always succeeds. */ -PyAPI_FUNC(int) PyIter_Check(PyObject *); - -/* Returns non-zero if the object 'obj' provides AsyncIterator protocols, and 0 otherwise. - - This function always succeeds. */ -PyAPI_FUNC(int) PyAIter_Check(PyObject *); - -/* Takes an iterator object and calls its tp_iternext slot, - returning the next value. - - If the iterator is exhausted, this returns NULL without setting an - exception. - - NULL with an exception means an error occurred. */ -PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 - -/* Takes generator, coroutine or iterator object and sends the value into it. - Returns: - - PYGEN_RETURN (0) if generator has returned. - 'result' parameter is filled with return value - - PYGEN_ERROR (-1) if exception was raised. - 'result' parameter is NULL - - PYGEN_NEXT (1) if generator has yielded. - 'result' parameter is filled with yielded value. */ -PyAPI_FUNC(PySendResult) PyIter_Send(PyObject *, PyObject *, PyObject **); -#endif - - -/* === Number Protocol ================================================== */ - -/* Returns 1 if the object 'o' provides numeric protocols, and 0 otherwise. - - This function always succeeds. */ -PyAPI_FUNC(int) PyNumber_Check(PyObject *o); - -/* Returns the result of adding o1 and o2, or NULL on failure. - - This is the equivalent of the Python expression: o1 + o2. */ -PyAPI_FUNC(PyObject *) PyNumber_Add(PyObject *o1, PyObject *o2); - -/* Returns the result of subtracting o2 from o1, or NULL on failure. - - This is the equivalent of the Python expression: o1 - o2. */ -PyAPI_FUNC(PyObject *) PyNumber_Subtract(PyObject *o1, PyObject *o2); - -/* Returns the result of multiplying o1 and o2, or NULL on failure. - - This is the equivalent of the Python expression: o1 * o2. */ -PyAPI_FUNC(PyObject *) PyNumber_Multiply(PyObject *o1, PyObject *o2); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -/* This is the equivalent of the Python expression: o1 @ o2. */ -PyAPI_FUNC(PyObject *) PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2); -#endif - -/* Returns the result of dividing o1 by o2 giving an integral result, - or NULL on failure. - - This is the equivalent of the Python expression: o1 // o2. */ -PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2); - -/* Returns the result of dividing o1 by o2 giving a float result, or NULL on - failure. - - This is the equivalent of the Python expression: o1 / o2. */ -PyAPI_FUNC(PyObject *) PyNumber_TrueDivide(PyObject *o1, PyObject *o2); - -/* Returns the remainder of dividing o1 by o2, or NULL on failure. - - This is the equivalent of the Python expression: o1 % o2. */ -PyAPI_FUNC(PyObject *) PyNumber_Remainder(PyObject *o1, PyObject *o2); - -/* See the built-in function divmod. - - Returns NULL on failure. - - This is the equivalent of the Python expression: divmod(o1, o2). */ -PyAPI_FUNC(PyObject *) PyNumber_Divmod(PyObject *o1, PyObject *o2); - -/* See the built-in function pow. Returns NULL on failure. - - This is the equivalent of the Python expression: pow(o1, o2, o3), - where o3 is optional. */ -PyAPI_FUNC(PyObject *) PyNumber_Power(PyObject *o1, PyObject *o2, - PyObject *o3); - -/* Returns the negation of o on success, or NULL on failure. - - This is the equivalent of the Python expression: -o. */ -PyAPI_FUNC(PyObject *) PyNumber_Negative(PyObject *o); - -/* Returns the positive of o on success, or NULL on failure. - - This is the equivalent of the Python expression: +o. */ -PyAPI_FUNC(PyObject *) PyNumber_Positive(PyObject *o); - -/* Returns the absolute value of 'o', or NULL on failure. - - This is the equivalent of the Python expression: abs(o). */ -PyAPI_FUNC(PyObject *) PyNumber_Absolute(PyObject *o); - -/* Returns the bitwise negation of 'o' on success, or NULL on failure. - - This is the equivalent of the Python expression: ~o. */ -PyAPI_FUNC(PyObject *) PyNumber_Invert(PyObject *o); - -/* Returns the result of left shifting o1 by o2 on success, or NULL on failure. - - This is the equivalent of the Python expression: o1 << o2. */ -PyAPI_FUNC(PyObject *) PyNumber_Lshift(PyObject *o1, PyObject *o2); - -/* Returns the result of right shifting o1 by o2 on success, or NULL on - failure. - - This is the equivalent of the Python expression: o1 >> o2. */ -PyAPI_FUNC(PyObject *) PyNumber_Rshift(PyObject *o1, PyObject *o2); - -/* Returns the result of bitwise and of o1 and o2 on success, or NULL on - failure. - - This is the equivalent of the Python expression: o1 & o2. */ -PyAPI_FUNC(PyObject *) PyNumber_And(PyObject *o1, PyObject *o2); - -/* Returns the bitwise exclusive or of o1 by o2 on success, or NULL on failure. - - This is the equivalent of the Python expression: o1 ^ o2. */ -PyAPI_FUNC(PyObject *) PyNumber_Xor(PyObject *o1, PyObject *o2); - -/* Returns the result of bitwise or on o1 and o2 on success, or NULL on - failure. - - This is the equivalent of the Python expression: o1 | o2. */ -PyAPI_FUNC(PyObject *) PyNumber_Or(PyObject *o1, PyObject *o2); - -/* Returns 1 if obj is an index integer (has the nb_index slot of the - tp_as_number structure filled in), and 0 otherwise. */ -PyAPI_FUNC(int) PyIndex_Check(PyObject *); - -/* Returns the object 'o' converted to a Python int, or NULL with an exception - raised on failure. */ -PyAPI_FUNC(PyObject *) PyNumber_Index(PyObject *o); - -/* Returns the object 'o' converted to Py_ssize_t by going through - PyNumber_Index() first. - - If an overflow error occurs while converting the int to Py_ssize_t, then the - second argument 'exc' is the error-type to return. If it is NULL, then the - overflow error is cleared and the value is clipped. */ -PyAPI_FUNC(Py_ssize_t) PyNumber_AsSsize_t(PyObject *o, PyObject *exc); - -/* Returns the object 'o' converted to an integer object on success, or NULL - on failure. - - This is the equivalent of the Python expression: int(o). */ -PyAPI_FUNC(PyObject *) PyNumber_Long(PyObject *o); - -/* Returns the object 'o' converted to a float object on success, or NULL - on failure. - - This is the equivalent of the Python expression: float(o). */ -PyAPI_FUNC(PyObject *) PyNumber_Float(PyObject *o); - - -/* --- In-place variants of (some of) the above number protocol functions -- */ - -/* Returns the result of adding o2 to o1, possibly in-place, or NULL - on failure. - - This is the equivalent of the Python expression: o1 += o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2); - -/* Returns the result of subtracting o2 from o1, possibly in-place or - NULL on failure. - - This is the equivalent of the Python expression: o1 -= o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2); - -/* Returns the result of multiplying o1 by o2, possibly in-place, or NULL on - failure. - - This is the equivalent of the Python expression: o1 *= o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -/* This is the equivalent of the Python expression: o1 @= o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2); -#endif - -/* Returns the result of dividing o1 by o2 giving an integral result, possibly - in-place, or NULL on failure. - - This is the equivalent of the Python expression: o1 /= o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1, - PyObject *o2); - -/* Returns the result of dividing o1 by o2 giving a float result, possibly - in-place, or null on failure. - - This is the equivalent of the Python expression: o1 /= o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceTrueDivide(PyObject *o1, - PyObject *o2); - -/* Returns the remainder of dividing o1 by o2, possibly in-place, or NULL on - failure. - - This is the equivalent of the Python expression: o1 %= o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2); - -/* Returns the result of raising o1 to the power of o2, possibly in-place, - or NULL on failure. - - This is the equivalent of the Python expression: o1 **= o2, - or o1 = pow(o1, o2, o3) if o3 is present. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlacePower(PyObject *o1, PyObject *o2, - PyObject *o3); - -/* Returns the result of left shifting o1 by o2, possibly in-place, or NULL - on failure. - - This is the equivalent of the Python expression: o1 <<= o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2); - -/* Returns the result of right shifting o1 by o2, possibly in-place or NULL - on failure. - - This is the equivalent of the Python expression: o1 >>= o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2); - -/* Returns the result of bitwise and of o1 and o2, possibly in-place, or NULL - on failure. - - This is the equivalent of the Python expression: o1 &= o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2); - -/* Returns the bitwise exclusive or of o1 by o2, possibly in-place, or NULL - on failure. - - This is the equivalent of the Python expression: o1 ^= o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceXor(PyObject *o1, PyObject *o2); - -/* Returns the result of bitwise or of o1 and o2, possibly in-place, - or NULL on failure. - - This is the equivalent of the Python expression: o1 |= o2. */ -PyAPI_FUNC(PyObject *) PyNumber_InPlaceOr(PyObject *o1, PyObject *o2); - -/* Returns the integer n converted to a string with a base, with a base - marker of 0b, 0o or 0x prefixed if applicable. - - If n is not an int object, it is converted with PyNumber_Index first. */ -PyAPI_FUNC(PyObject *) PyNumber_ToBase(PyObject *n, int base); - - -/* === Sequence protocol ================================================ */ - -/* Return 1 if the object provides sequence protocol, and zero - otherwise. - - This function always succeeds. */ -PyAPI_FUNC(int) PySequence_Check(PyObject *o); - -/* Return the size of sequence object o, or -1 on failure. */ -PyAPI_FUNC(Py_ssize_t) PySequence_Size(PyObject *o); - -/* For DLL compatibility */ -#undef PySequence_Length -PyAPI_FUNC(Py_ssize_t) PySequence_Length(PyObject *o); -#define PySequence_Length PySequence_Size - - -/* Return the concatenation of o1 and o2 on success, and NULL on failure. - - This is the equivalent of the Python expression: o1 + o2. */ -PyAPI_FUNC(PyObject *) PySequence_Concat(PyObject *o1, PyObject *o2); - -/* Return the result of repeating sequence object 'o' 'count' times, - or NULL on failure. - - This is the equivalent of the Python expression: o * count. */ -PyAPI_FUNC(PyObject *) PySequence_Repeat(PyObject *o, Py_ssize_t count); - -/* Return the ith element of o, or NULL on failure. - - This is the equivalent of the Python expression: o[i]. */ -PyAPI_FUNC(PyObject *) PySequence_GetItem(PyObject *o, Py_ssize_t i); - -/* Return the slice of sequence object o between i1 and i2, or NULL on failure. - - This is the equivalent of the Python expression: o[i1:i2]. */ -PyAPI_FUNC(PyObject *) PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2); - -/* Assign object 'v' to the ith element of the sequence 'o'. Raise an exception - and return -1 on failure; return 0 on success. - - This is the equivalent of the Python statement o[i] = v. */ -PyAPI_FUNC(int) PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v); - -/* Delete the 'i'-th element of the sequence 'v'. Returns -1 on failure. - - This is the equivalent of the Python statement: del o[i]. */ -PyAPI_FUNC(int) PySequence_DelItem(PyObject *o, Py_ssize_t i); - -/* Assign the sequence object 'v' to the slice in sequence object 'o', - from 'i1' to 'i2'. Returns -1 on failure. - - This is the equivalent of the Python statement: o[i1:i2] = v. */ -PyAPI_FUNC(int) PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, - PyObject *v); - -/* Delete the slice in sequence object 'o' from 'i1' to 'i2'. - Returns -1 on failure. - - This is the equivalent of the Python statement: del o[i1:i2]. */ -PyAPI_FUNC(int) PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2); - -/* Returns the sequence 'o' as a tuple on success, and NULL on failure. - - This is equivalent to the Python expression: tuple(o). */ -PyAPI_FUNC(PyObject *) PySequence_Tuple(PyObject *o); - -/* Returns the sequence 'o' as a list on success, and NULL on failure. - This is equivalent to the Python expression: list(o) */ -PyAPI_FUNC(PyObject *) PySequence_List(PyObject *o); - -/* Return the sequence 'o' as a list, unless it's already a tuple or list. - - Use PySequence_Fast_GET_ITEM to access the members of this list, and - PySequence_Fast_GET_SIZE to get its length. - - Returns NULL on failure. If the object does not support iteration, raises a - TypeError exception with 'm' as the message text. */ -PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); - -/* Return the size of the sequence 'o', assuming that 'o' was returned by - PySequence_Fast and is not NULL. */ -#define PySequence_Fast_GET_SIZE(o) \ - (PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o)) - -/* Return the 'i'-th element of the sequence 'o', assuming that o was returned - by PySequence_Fast, and that i is within bounds. */ -#define PySequence_Fast_GET_ITEM(o, i)\ - (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) - -/* Return a pointer to the underlying item array for - an object returned by PySequence_Fast */ -#define PySequence_Fast_ITEMS(sf) \ - (PyList_Check(sf) ? ((PyListObject *)(sf))->ob_item \ - : ((PyTupleObject *)(sf))->ob_item) - -/* Return the number of occurrences on value on 'o', that is, return - the number of keys for which o[key] == value. - - On failure, return -1. This is equivalent to the Python expression: - o.count(value). */ -PyAPI_FUNC(Py_ssize_t) PySequence_Count(PyObject *o, PyObject *value); - -/* Return 1 if 'ob' is in the sequence 'seq'; 0 if 'ob' is not in the sequence - 'seq'; -1 on error. - - Use __contains__ if possible, else _PySequence_IterSearch(). */ -PyAPI_FUNC(int) PySequence_Contains(PyObject *seq, PyObject *ob); - -/* For DLL-level backwards compatibility */ -#undef PySequence_In -/* Determine if the sequence 'o' contains 'value'. If an item in 'o' is equal - to 'value', return 1, otherwise return 0. On error, return -1. - - This is equivalent to the Python expression: value in o. */ -PyAPI_FUNC(int) PySequence_In(PyObject *o, PyObject *value); - -/* For source-level backwards compatibility */ -#define PySequence_In PySequence_Contains - - -/* Return the first index for which o[i] == value. - On error, return -1. - - This is equivalent to the Python expression: o.index(value). */ -PyAPI_FUNC(Py_ssize_t) PySequence_Index(PyObject *o, PyObject *value); - - -/* --- In-place versions of some of the above Sequence functions --- */ - -/* Append sequence 'o2' to sequence 'o1', in-place when possible. Return the - resulting object, which could be 'o1', or NULL on failure. - - This is the equivalent of the Python expression: o1 += o2. */ -PyAPI_FUNC(PyObject *) PySequence_InPlaceConcat(PyObject *o1, PyObject *o2); - -/* Repeat sequence 'o' by 'count', in-place when possible. Return the resulting - object, which could be 'o', or NULL on failure. - - This is the equivalent of the Python expression: o1 *= count. */ -PyAPI_FUNC(PyObject *) PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count); - - -/* === Mapping protocol ================================================= */ - -/* Return 1 if the object provides mapping protocol, and 0 otherwise. - - This function always succeeds. */ -PyAPI_FUNC(int) PyMapping_Check(PyObject *o); - -/* Returns the number of keys in mapping object 'o' on success, and -1 on - failure. This is equivalent to the Python expression: len(o). */ -PyAPI_FUNC(Py_ssize_t) PyMapping_Size(PyObject *o); - -/* For DLL compatibility */ -#undef PyMapping_Length -PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o); -#define PyMapping_Length PyMapping_Size - - -/* Implemented as a macro: - - int PyMapping_DelItemString(PyObject *o, const char *key); - - Remove the mapping for the string 'key' from the mapping 'o'. Returns -1 on - failure. - - This is equivalent to the Python statement: del o[key]. */ -#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K)) - -/* Implemented as a macro: - - int PyMapping_DelItem(PyObject *o, PyObject *key); - - Remove the mapping for the object 'key' from the mapping object 'o'. - Returns -1 on failure. - - This is equivalent to the Python statement: del o[key]. */ -#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K)) - -/* On success, return 1 if the mapping object 'o' has the key 'key', - and 0 otherwise. - - This is equivalent to the Python expression: key in o. - - This function always succeeds. */ -PyAPI_FUNC(int) PyMapping_HasKeyString(PyObject *o, const char *key); - -/* Return 1 if the mapping object has the key 'key', and 0 otherwise. - - This is equivalent to the Python expression: key in o. - - This function always succeeds. */ -PyAPI_FUNC(int) PyMapping_HasKey(PyObject *o, PyObject *key); - -/* On success, return a list or tuple of the keys in mapping object 'o'. - On failure, return NULL. */ -PyAPI_FUNC(PyObject *) PyMapping_Keys(PyObject *o); - -/* On success, return a list or tuple of the values in mapping object 'o'. - On failure, return NULL. */ -PyAPI_FUNC(PyObject *) PyMapping_Values(PyObject *o); - -/* On success, return a list or tuple of the items in mapping object 'o', - where each item is a tuple containing a key-value pair. On failure, return - NULL. */ -PyAPI_FUNC(PyObject *) PyMapping_Items(PyObject *o); - -/* Return element of 'o' corresponding to the string 'key' or NULL on failure. - - This is the equivalent of the Python expression: o[key]. */ -PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o, - const char *key); - -/* Map the string 'key' to the value 'v' in the mapping 'o'. - Returns -1 on failure. - - This is the equivalent of the Python statement: o[key]=v. */ -PyAPI_FUNC(int) PyMapping_SetItemString(PyObject *o, const char *key, - PyObject *value); - -/* isinstance(object, typeorclass) */ -PyAPI_FUNC(int) PyObject_IsInstance(PyObject *object, PyObject *typeorclass); - -/* issubclass(object, typeorclass) */ -PyAPI_FUNC(int) PyObject_IsSubclass(PyObject *object, PyObject *typeorclass); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_ABSTRACTOBJECT_H -# include "cpython/abstract.h" -# undef Py_CPYTHON_ABSTRACTOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* Py_ABSTRACTOBJECT_H */ diff --git a/python/include/bltinmodule.h b/python/include/bltinmodule.h deleted file mode 100644 index c04acea..0000000 --- a/python/include/bltinmodule.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef Py_BLTINMODULE_H -#define Py_BLTINMODULE_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_DATA(PyTypeObject) PyFilter_Type; -PyAPI_DATA(PyTypeObject) PyMap_Type; -PyAPI_DATA(PyTypeObject) PyZip_Type; - -#ifdef __cplusplus -} -#endif -#endif /* !Py_BLTINMODULE_H */ diff --git a/python/include/boolobject.h b/python/include/boolobject.h deleted file mode 100644 index e42d60f..0000000 --- a/python/include/boolobject.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Boolean object interface */ - -#ifndef Py_BOOLOBJECT_H -#define Py_BOOLOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - - -PyAPI_DATA(PyTypeObject) PyBool_Type; - -#define PyBool_Check(x) Py_IS_TYPE(x, &PyBool_Type) - -/* Py_False and Py_True are the only two bools in existence. -Don't forget to apply Py_INCREF() when returning either!!! */ - -/* Don't use these directly */ -PyAPI_DATA(PyLongObject) _Py_FalseStruct; -PyAPI_DATA(PyLongObject) _Py_TrueStruct; - -/* Use these macros */ -#define Py_False ((PyObject *) &_Py_FalseStruct) -#define Py_True ((PyObject *) &_Py_TrueStruct) - -// Test if an object is the True singleton, the same as "x is True" in Python. -PyAPI_FUNC(int) Py_IsTrue(PyObject *x); -#define Py_IsTrue(x) Py_Is((x), Py_True) - -// Test if an object is the False singleton, the same as "x is False" in Python. -PyAPI_FUNC(int) Py_IsFalse(PyObject *x); -#define Py_IsFalse(x) Py_Is((x), Py_False) - -/* Macros for returning Py_True or Py_False, respectively */ -#define Py_RETURN_TRUE return Py_NewRef(Py_True) -#define Py_RETURN_FALSE return Py_NewRef(Py_False) - -/* Function to return a bool from a C long */ -PyAPI_FUNC(PyObject *) PyBool_FromLong(long); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_BOOLOBJECT_H */ diff --git a/python/include/bytearrayobject.h b/python/include/bytearrayobject.h deleted file mode 100644 index bc69fe2..0000000 --- a/python/include/bytearrayobject.h +++ /dev/null @@ -1,44 +0,0 @@ -/* ByteArray object interface */ - -#ifndef Py_BYTEARRAYOBJECT_H -#define Py_BYTEARRAYOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Type PyByteArrayObject represents a mutable array of bytes. - * The Python API is that of a sequence; - * the bytes are mapped to ints in [0, 256). - * Bytes are not characters; they may be used to encode characters. - * The only way to go between bytes and str/unicode is via encoding - * and decoding. - * For the convenience of C programmers, the bytes type is considered - * to contain a char pointer, not an unsigned char pointer. - */ - -/* Type object */ -PyAPI_DATA(PyTypeObject) PyByteArray_Type; -PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type; - -/* Type check macros */ -#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type) -#define PyByteArray_CheckExact(self) Py_IS_TYPE(self, &PyByteArray_Type) - -/* Direct API functions */ -PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *); -PyAPI_FUNC(PyObject *) PyByteArray_Concat(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyByteArray_FromStringAndSize(const char *, Py_ssize_t); -PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *); -PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *); -PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_BYTEARRAYOBJECT_H -# include "cpython/bytearrayobject.h" -# undef Py_CPYTHON_BYTEARRAYOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_BYTEARRAYOBJECT_H */ diff --git a/python/include/bytesobject.h b/python/include/bytesobject.h deleted file mode 100644 index b2128dd..0000000 --- a/python/include/bytesobject.h +++ /dev/null @@ -1,69 +0,0 @@ - -/* Bytes object interface */ - -#ifndef Py_BYTESOBJECT_H -#define Py_BYTESOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#include // va_list - -/* -Type PyBytesObject represents a byte string. An extra zero byte is -reserved at the end to ensure it is zero-terminated, but a size is -present so strings with null bytes in them can be represented. This -is an immutable object type. - -There are functions to create new bytes objects, to test -an object for bytes-ness, and to get the -byte string value. The latter function returns a null pointer -if the object is not of the proper type. -There is a variant that takes an explicit size as well as a -variant that assumes a zero-terminated string. Note that none of the -functions should be applied to NULL pointer. -*/ - -PyAPI_DATA(PyTypeObject) PyBytes_Type; -PyAPI_DATA(PyTypeObject) PyBytesIter_Type; - -#define PyBytes_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) -#define PyBytes_CheckExact(op) Py_IS_TYPE(op, &PyBytes_Type) - -PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t); -PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *); -PyAPI_FUNC(PyObject *) PyBytes_FromObject(PyObject *); -PyAPI_FUNC(PyObject *) PyBytes_FromFormatV(const char*, va_list) - Py_GCC_ATTRIBUTE((format(printf, 1, 0))); -PyAPI_FUNC(PyObject *) PyBytes_FromFormat(const char*, ...) - Py_GCC_ATTRIBUTE((format(printf, 1, 2))); -PyAPI_FUNC(Py_ssize_t) PyBytes_Size(PyObject *); -PyAPI_FUNC(char *) PyBytes_AsString(PyObject *); -PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int); -PyAPI_FUNC(void) PyBytes_Concat(PyObject **, PyObject *); -PyAPI_FUNC(void) PyBytes_ConcatAndDel(PyObject **, PyObject *); -PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t, - const char *, Py_ssize_t, - const char *); - -/* Provides access to the internal data buffer and size of a bytes object. - Passing NULL as len parameter will force the string buffer to be - 0-terminated (passing a string with embedded NUL characters will - cause an exception). */ -PyAPI_FUNC(int) PyBytes_AsStringAndSize( - PyObject *obj, /* bytes object */ - char **s, /* pointer to buffer variable */ - Py_ssize_t *len /* pointer to length variable or NULL */ - ); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_BYTESOBJECT_H -# include "cpython/bytesobject.h" -# undef Py_CPYTHON_BYTESOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_BYTESOBJECT_H */ diff --git a/python/include/ceval.h b/python/include/ceval.h deleted file mode 100644 index da1e442..0000000 --- a/python/include/ceval.h +++ /dev/null @@ -1,168 +0,0 @@ -/* Interface to random parts in ceval.c */ - -#ifndef Py_CEVAL_H -#define Py_CEVAL_H -#ifdef __cplusplus -extern "C" { -#endif - - -PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyObject *, PyObject *, PyObject *); - -PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyObject *co, - PyObject *globals, - PyObject *locals, - PyObject *const *args, int argc, - PyObject *const *kwds, int kwdc, - PyObject *const *defs, int defc, - PyObject *kwdefs, PyObject *closure); - -/* PyEval_CallObjectWithKeywords(), PyEval_CallObject(), PyEval_CallFunction - * and PyEval_CallMethod are deprecated. Since they are officially part of the - * stable ABI (PEP 384), they must be kept for backward compatibility. - * PyObject_Call(), PyObject_CallFunction() and PyObject_CallMethod() are - * recommended to call a callable object. - */ - -Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( - PyObject *callable, - PyObject *args, - PyObject *kwargs); - -/* Deprecated since PyEval_CallObjectWithKeywords is deprecated */ -#define PyEval_CallObject(callable, arg) \ - PyEval_CallObjectWithKeywords(callable, arg, (PyObject *)NULL) - -Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallFunction( - PyObject *callable, const char *format, ...); -Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallMethod( - PyObject *obj, const char *name, const char *format, ...); - -PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void); -PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void); -PyAPI_FUNC(PyObject *) PyEval_GetLocals(void); -PyAPI_FUNC(PyFrameObject *) PyEval_GetFrame(void); - -PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg); -PyAPI_FUNC(int) Py_MakePendingCalls(void); - -/* Protection against deeply nested recursive calls - - In Python 3.0, this protection has two levels: - * normal anti-recursion protection is triggered when the recursion level - exceeds the current recursion limit. It raises a RecursionError, and sets - the "overflowed" flag in the thread state structure. This flag - temporarily *disables* the normal protection; this allows cleanup code - to potentially outgrow the recursion limit while processing the - RecursionError. - * "last chance" anti-recursion protection is triggered when the recursion - level exceeds "current recursion limit + 50". By construction, this - protection can only be triggered when the "overflowed" flag is set. It - means the cleanup code has itself gone into an infinite loop, or the - RecursionError has been mistakingly ignored. When this protection is - triggered, the interpreter aborts with a Fatal Error. - - In addition, the "overflowed" flag is automatically reset when the - recursion level drops below "current recursion limit - 50". This heuristic - is meant to ensure that the normal anti-recursion protection doesn't get - disabled too long. - - Please note: this scheme has its own limitations. See: - http://mail.python.org/pipermail/python-dev/2008-August/082106.html - for some observations. -*/ -PyAPI_FUNC(void) Py_SetRecursionLimit(int); -PyAPI_FUNC(int) Py_GetRecursionLimit(void); - -PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where); -PyAPI_FUNC(void) Py_LeaveRecursiveCall(void); - -PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); -PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); - -PyAPI_FUNC(PyObject *) PyEval_EvalFrame(PyFrameObject *); -PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(PyFrameObject *f, int exc); - -/* Interface for threads. - - A module that plans to do a blocking system call (or something else - that lasts a long time and doesn't touch Python data) can allow other - threads to run as follows: - - ...preparations here... - Py_BEGIN_ALLOW_THREADS - ...blocking system call here... - Py_END_ALLOW_THREADS - ...interpret result here... - - The Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS pair expands to a - {}-surrounded block. - To leave the block in the middle (e.g., with return), you must insert - a line containing Py_BLOCK_THREADS before the return, e.g. - - if (...premature_exit...) { - Py_BLOCK_THREADS - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - An alternative is: - - Py_BLOCK_THREADS - if (...premature_exit...) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - Py_UNBLOCK_THREADS - - For convenience, that the value of 'errno' is restored across - Py_END_ALLOW_THREADS and Py_BLOCK_THREADS. - - WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND - Py_END_ALLOW_THREADS!!! - - Note that not yet all candidates have been converted to use this - mechanism! -*/ - -PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void); -PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); - -Py_DEPRECATED(3.9) PyAPI_FUNC(int) PyEval_ThreadsInitialized(void); -Py_DEPRECATED(3.9) PyAPI_FUNC(void) PyEval_InitThreads(void); -/* PyEval_AcquireLock() and PyEval_ReleaseLock() are part of stable ABI. - * They will be removed from this header file in the future version. - * But they will be remained in ABI until Python 4.0. - */ -Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_AcquireLock(void); -Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_ReleaseLock(void); -PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); -PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); - -#define Py_BEGIN_ALLOW_THREADS { \ - PyThreadState *_save; \ - _save = PyEval_SaveThread(); -#define Py_BLOCK_THREADS PyEval_RestoreThread(_save); -#define Py_UNBLOCK_THREADS _save = PyEval_SaveThread(); -#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ - } - -/* Masks and values used by FORMAT_VALUE opcode. */ -#define FVC_MASK 0x3 -#define FVC_NONE 0x0 -#define FVC_STR 0x1 -#define FVC_REPR 0x2 -#define FVC_ASCII 0x3 -#define FVS_MASK 0x4 -#define FVS_HAVE_SPEC 0x4 - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_CEVAL_H -# include "cpython/ceval.h" -# undef Py_CPYTHON_CEVAL_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_CEVAL_H */ diff --git a/python/include/codecs.h b/python/include/codecs.h deleted file mode 100644 index cc2a776..0000000 --- a/python/include/codecs.h +++ /dev/null @@ -1,248 +0,0 @@ -#ifndef Py_CODECREGISTRY_H -#define Py_CODECREGISTRY_H -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------------------------------------------------------------ - - Python Codec Registry and support functions - - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -Copyright (c) Corporation for National Research Initiatives. - - ------------------------------------------------------------------------ */ - -/* Register a new codec search function. - - As side effect, this tries to load the encodings package, if not - yet done, to make sure that it is always first in the list of - search functions. - - The search_function's refcount is incremented by this function. */ - -PyAPI_FUNC(int) PyCodec_Register( - PyObject *search_function - ); - -/* Unregister a codec search function and clear the registry's cache. - If the search function is not registered, do nothing. - Return 0 on success. Raise an exception and return -1 on error. */ - -PyAPI_FUNC(int) PyCodec_Unregister( - PyObject *search_function - ); - -/* Codec registry lookup API. - - Looks up the given encoding and returns a CodecInfo object with - function attributes which implement the different aspects of - processing the encoding. - - The encoding string is looked up converted to all lower-case - characters. This makes encodings looked up through this mechanism - effectively case-insensitive. - - If no codec is found, a KeyError is set and NULL returned. - - As side effect, this tries to load the encodings package, if not - yet done. This is part of the lazy load strategy for the encodings - package. - - */ - -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyCodec_Lookup( - const char *encoding - ); - -PyAPI_FUNC(int) _PyCodec_Forget( - const char *encoding - ); -#endif - -/* Codec registry encoding check API. - - Returns 1/0 depending on whether there is a registered codec for - the given encoding. - -*/ - -PyAPI_FUNC(int) PyCodec_KnownEncoding( - const char *encoding - ); - -/* Generic codec based encoding API. - - object is passed through the encoder function found for the given - encoding using the error handling method defined by errors. errors - may be NULL to use the default method defined for the codec. - - Raises a LookupError in case no encoder can be found. - - */ - -PyAPI_FUNC(PyObject *) PyCodec_Encode( - PyObject *object, - const char *encoding, - const char *errors - ); - -/* Generic codec based decoding API. - - object is passed through the decoder function found for the given - encoding using the error handling method defined by errors. errors - may be NULL to use the default method defined for the codec. - - Raises a LookupError in case no encoder can be found. - - */ - -PyAPI_FUNC(PyObject *) PyCodec_Decode( - PyObject *object, - const char *encoding, - const char *errors - ); - -#ifndef Py_LIMITED_API -/* Text codec specific encoding and decoding API. - - Checks the encoding against a list of codecs which do not - implement a str<->bytes encoding before attempting the - operation. - - Please note that these APIs are internal and should not - be used in Python C extensions. - - XXX (ncoghlan): should we make these, or something like them, public - in Python 3.5+? - - */ -PyAPI_FUNC(PyObject *) _PyCodec_LookupTextEncoding( - const char *encoding, - const char *alternate_command - ); - -PyAPI_FUNC(PyObject *) _PyCodec_EncodeText( - PyObject *object, - const char *encoding, - const char *errors - ); - -PyAPI_FUNC(PyObject *) _PyCodec_DecodeText( - PyObject *object, - const char *encoding, - const char *errors - ); - -/* These two aren't actually text encoding specific, but _io.TextIOWrapper - * is the only current API consumer. - */ -PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalDecoder( - PyObject *codec_info, - const char *errors - ); - -PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalEncoder( - PyObject *codec_info, - const char *errors - ); -#endif - - - -/* --- Codec Lookup APIs -------------------------------------------------- - - All APIs return a codec object with incremented refcount and are - based on _PyCodec_Lookup(). The same comments w/r to the encoding - name also apply to these APIs. - -*/ - -/* Get an encoder function for the given encoding. */ - -PyAPI_FUNC(PyObject *) PyCodec_Encoder( - const char *encoding - ); - -/* Get a decoder function for the given encoding. */ - -PyAPI_FUNC(PyObject *) PyCodec_Decoder( - const char *encoding - ); - -/* Get an IncrementalEncoder object for the given encoding. */ - -PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder( - const char *encoding, - const char *errors - ); - -/* Get an IncrementalDecoder object function for the given encoding. */ - -PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder( - const char *encoding, - const char *errors - ); - -/* Get a StreamReader factory function for the given encoding. */ - -PyAPI_FUNC(PyObject *) PyCodec_StreamReader( - const char *encoding, - PyObject *stream, - const char *errors - ); - -/* Get a StreamWriter factory function for the given encoding. */ - -PyAPI_FUNC(PyObject *) PyCodec_StreamWriter( - const char *encoding, - PyObject *stream, - const char *errors - ); - -/* Unicode encoding error handling callback registry API */ - -/* Register the error handling callback function error under the given - name. This function will be called by the codec when it encounters - unencodable characters/undecodable bytes and doesn't know the - callback name, when name is specified as the error parameter - in the call to the encode/decode function. - Return 0 on success, -1 on error */ -PyAPI_FUNC(int) PyCodec_RegisterError(const char *name, PyObject *error); - -/* Lookup the error handling callback function registered under the given - name. As a special case NULL can be passed, in which case - the error handling callback for "strict" will be returned. */ -PyAPI_FUNC(PyObject *) PyCodec_LookupError(const char *name); - -/* raise exc as an exception */ -PyAPI_FUNC(PyObject *) PyCodec_StrictErrors(PyObject *exc); - -/* ignore the unicode error, skipping the faulty input */ -PyAPI_FUNC(PyObject *) PyCodec_IgnoreErrors(PyObject *exc); - -/* replace the unicode encode error with ? or U+FFFD */ -PyAPI_FUNC(PyObject *) PyCodec_ReplaceErrors(PyObject *exc); - -/* replace the unicode encode error with XML character references */ -PyAPI_FUNC(PyObject *) PyCodec_XMLCharRefReplaceErrors(PyObject *exc); - -/* replace the unicode encode error with backslash escapes (\x, \u and \U) */ -PyAPI_FUNC(PyObject *) PyCodec_BackslashReplaceErrors(PyObject *exc); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -/* replace the unicode encode error with backslash escapes (\N, \x, \u and \U) */ -PyAPI_FUNC(PyObject *) PyCodec_NameReplaceErrors(PyObject *exc); -#endif - -#ifndef Py_LIMITED_API -PyAPI_DATA(const char *) Py_hexdigits; -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_CODECREGISTRY_H */ diff --git a/python/include/compile.h b/python/include/compile.h deleted file mode 100644 index f33fc53..0000000 --- a/python/include/compile.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef Py_COMPILE_H -#define Py_COMPILE_H -#ifdef __cplusplus -extern "C" { -#endif - -/* These definitions must match corresponding definitions in graminit.h. */ -#define Py_single_input 256 -#define Py_file_input 257 -#define Py_eval_input 258 -#define Py_func_type_input 345 - -/* This doesn't need to match anything */ -#define Py_fstring_input 800 - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_COMPILE_H -# include "cpython/compile.h" -# undef Py_CPYTHON_COMPILE_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_COMPILE_H */ diff --git a/python/include/complexobject.h b/python/include/complexobject.h deleted file mode 100644 index 8525f85..0000000 --- a/python/include/complexobject.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Complex number structure */ - -#ifndef Py_COMPLEXOBJECT_H -#define Py_COMPLEXOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Complex object interface */ - -PyAPI_DATA(PyTypeObject) PyComplex_Type; - -#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) -#define PyComplex_CheckExact(op) Py_IS_TYPE(op, &PyComplex_Type) - -PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag); - -PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op); -PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_COMPLEXOBJECT_H -# include "cpython/complexobject.h" -# undef Py_CPYTHON_COMPLEXOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_COMPLEXOBJECT_H */ diff --git a/python/include/cpython/abstract.h b/python/include/cpython/abstract.h deleted file mode 100644 index adbe268..0000000 --- a/python/include/cpython/abstract.h +++ /dev/null @@ -1,219 +0,0 @@ -#ifndef Py_CPYTHON_ABSTRACTOBJECT_H -# error "this header file must not be included directly" -#endif - -/* === Object Protocol ================================================== */ - -#ifdef PY_SSIZE_T_CLEAN -# define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT -#endif - -/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple) - format to a Python dictionary ("kwargs" dict). - - The type of kwnames keys is not checked. The final function getting - arguments is responsible to check if all keys are strings, for example using - PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments(). - - Duplicate keys are merged using the last value. If duplicate keys must raise - an exception, the caller is responsible to implement an explicit keys on - kwnames. */ -PyAPI_FUNC(PyObject *) _PyStack_AsDict( - PyObject *const *values, - PyObject *kwnames); - -/* Suggested size (number of positional arguments) for arrays of PyObject* - allocated on a C stack to avoid allocating memory on the heap memory. Such - array is used to pass positional arguments to call functions of the - PyObject_Vectorcall() family. - - The size is chosen to not abuse the C stack and so limit the risk of stack - overflow. The size is also chosen to allow using the small stack for most - function calls of the Python standard library. On 64-bit CPU, it allocates - 40 bytes on the stack. */ -#define _PY_FASTCALL_SMALL_STACK 5 - -PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult( - PyThreadState *tstate, - PyObject *callable, - PyObject *result, - const char *where); - -/* === Vectorcall protocol (PEP 590) ============================= */ - -/* Call callable using tp_call. Arguments are like PyObject_Vectorcall() - or PyObject_FastCallDict() (both forms are supported), - except that nargs is plainly the number of arguments without flags. */ -PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( - PyThreadState *tstate, - PyObject *callable, - PyObject *const *args, Py_ssize_t nargs, - PyObject *keywords); - -#define PY_VECTORCALL_ARGUMENTS_OFFSET \ - (_Py_STATIC_CAST(size_t, 1) << (8 * sizeof(size_t) - 1)) - -static inline Py_ssize_t -PyVectorcall_NARGS(size_t n) -{ - return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; -} - -PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable); - -PyAPI_FUNC(PyObject *) PyObject_Vectorcall( - PyObject *callable, - PyObject *const *args, - size_t nargsf, - PyObject *kwnames); - -// Backwards compatibility aliases for API that was provisional in Python 3.8 -#define _PyObject_Vectorcall PyObject_Vectorcall -#define _PyObject_VectorcallMethod PyObject_VectorcallMethod -#define _PyObject_FastCallDict PyObject_VectorcallDict -#define _PyVectorcall_Function PyVectorcall_Function -#define _PyObject_CallOneArg PyObject_CallOneArg -#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs -#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg - -/* Same as PyObject_Vectorcall except that keyword arguments are passed as - dict, which may be NULL if there are no keyword arguments. */ -PyAPI_FUNC(PyObject *) PyObject_VectorcallDict( - PyObject *callable, - PyObject *const *args, - size_t nargsf, - PyObject *kwargs); - -/* Call "callable" (which must support vectorcall) with positional arguments - "tuple" and keyword arguments "dict". "dict" may also be NULL */ -PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); - -// Same as PyObject_Vectorcall(), except without keyword arguments -PyAPI_FUNC(PyObject *) _PyObject_FastCall( - PyObject *func, - PyObject *const *args, - Py_ssize_t nargs); - -PyAPI_FUNC(PyObject *) PyObject_CallOneArg(PyObject *func, PyObject *arg); - -PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod( - PyObject *name, PyObject *const *args, - size_t nargsf, PyObject *kwnames); - -static inline PyObject * -PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) -{ - size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; - return PyObject_VectorcallMethod(name, &self, nargsf, _Py_NULL); -} - -static inline PyObject * -PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) -{ - PyObject *args[2] = {self, arg}; - size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET; - assert(arg != NULL); - return PyObject_VectorcallMethod(name, args, nargsf, _Py_NULL); -} - -PyAPI_FUNC(PyObject *) _PyObject_CallMethod(PyObject *obj, - PyObject *name, - const char *format, ...); - -/* Like PyObject_CallMethod(), but expect a _Py_Identifier* - as the method name. */ -PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj, - _Py_Identifier *name, - const char *format, ...); - -PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj, - _Py_Identifier *name, - const char *format, - ...); - -PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs( - PyObject *obj, - _Py_Identifier *name, - ...); - -static inline PyObject * -_PyObject_VectorcallMethodId( - _Py_Identifier *name, PyObject *const *args, - size_t nargsf, PyObject *kwnames) -{ - PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ - if (!oname) { - return _Py_NULL; - } - return PyObject_VectorcallMethod(oname, args, nargsf, kwnames); -} - -static inline PyObject * -_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name) -{ - size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; - return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL); -} - -static inline PyObject * -_PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg) -{ - PyObject *args[2] = {self, arg}; - size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET; - assert(arg != NULL); - return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL); -} - -PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); - -/* Guess the size of object 'o' using len(o) or o.__length_hint__(). - If neither of those return a non-negative value, then return the default - value. If one of the calls fails, this function returns -1. */ -PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); - -/* === Sequence protocol ================================================ */ - -/* Assume tp_as_sequence and sq_item exist and that 'i' does not - need to be corrected for a negative index. */ -#define PySequence_ITEM(o, i)\ - ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) ) - -#define PY_ITERSEARCH_COUNT 1 -#define PY_ITERSEARCH_INDEX 2 -#define PY_ITERSEARCH_CONTAINS 3 - -/* Iterate over seq. - - Result depends on the operation: - - PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if - error. - PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of - obj in seq; set ValueError and return -1 if none found; - also return -1 on error. - PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on - error. */ -PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq, - PyObject *obj, int operation); - -/* === Mapping protocol ================================================= */ - -PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls); - -PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls); - -PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self); - -PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]); - -/* For internal use by buffer API functions */ -PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index, - const Py_ssize_t *shape); -PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index, - const Py_ssize_t *shape); - -/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */ -PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *); - -/* Same as PyNumber_Index but can return an instance of a subclass of int. */ -PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o); diff --git a/python/include/cpython/bytearrayobject.h b/python/include/cpython/bytearrayobject.h deleted file mode 100644 index 90c06c5..0000000 --- a/python/include/cpython/bytearrayobject.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef Py_CPYTHON_BYTEARRAYOBJECT_H -# error "this header file must not be included directly" -#endif - -/* Object layout */ -typedef struct { - PyObject_VAR_HEAD - Py_ssize_t ob_alloc; /* How many bytes allocated in ob_bytes */ - char *ob_bytes; /* Physical backing buffer */ - char *ob_start; /* Logical start inside ob_bytes */ - Py_ssize_t ob_exports; /* How many buffer exports */ -} PyByteArrayObject; - -PyAPI_DATA(char) _PyByteArray_empty_string[]; - -/* Macros and static inline functions, trading safety for speed */ -#define _PyByteArray_CAST(op) \ - (assert(PyByteArray_Check(op)), _Py_CAST(PyByteArrayObject*, op)) - -static inline char* PyByteArray_AS_STRING(PyObject *op) -{ - PyByteArrayObject *self = _PyByteArray_CAST(op); - if (Py_SIZE(self)) { - return self->ob_start; - } - return _PyByteArray_empty_string; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyByteArray_AS_STRING(self) PyByteArray_AS_STRING(_PyObject_CAST(self)) -#endif - -static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) { - PyByteArrayObject *self = _PyByteArray_CAST(op); - return Py_SIZE(self); -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self)) -#endif diff --git a/python/include/cpython/bytesobject.h b/python/include/cpython/bytesobject.h deleted file mode 100644 index 6f8e9ff..0000000 --- a/python/include/cpython/bytesobject.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef Py_CPYTHON_BYTESOBJECT_H -# error "this header file must not be included directly" -#endif - -typedef struct { - PyObject_VAR_HEAD - Py_DEPRECATED(3.11) Py_hash_t ob_shash; - char ob_sval[1]; - - /* Invariants: - * ob_sval contains space for 'ob_size+1' elements. - * ob_sval[ob_size] == 0. - * ob_shash is the hash of the byte string or -1 if not computed yet. - */ -} PyBytesObject; - -PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t); -PyAPI_FUNC(PyObject*) _PyBytes_FormatEx( - const char *format, - Py_ssize_t format_len, - PyObject *args, - int use_bytearray); -PyAPI_FUNC(PyObject*) _PyBytes_FromHex( - PyObject *string, - int use_bytearray); - -/* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */ -PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t, - const char *, const char **); - -/* Macros and static inline functions, trading safety for speed */ -#define _PyBytes_CAST(op) \ - (assert(PyBytes_Check(op)), _Py_CAST(PyBytesObject*, op)) - -static inline char* PyBytes_AS_STRING(PyObject *op) -{ - return _PyBytes_CAST(op)->ob_sval; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op)) -#endif - -static inline Py_ssize_t PyBytes_GET_SIZE(PyObject *op) { - PyBytesObject *self = _PyBytes_CAST(op); - return Py_SIZE(self); -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self)) -#endif - -/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, - x must be an iterable object. */ -PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x); - - -/* The _PyBytesWriter structure is big: it contains an embedded "stack buffer". - A _PyBytesWriter variable must be declared at the end of variables in a - function to optimize the memory allocation on the stack. */ -typedef struct { - /* bytes, bytearray or NULL (when the small buffer is used) */ - PyObject *buffer; - - /* Number of allocated size. */ - Py_ssize_t allocated; - - /* Minimum number of allocated bytes, - incremented by _PyBytesWriter_Prepare() */ - Py_ssize_t min_size; - - /* If non-zero, use a bytearray instead of a bytes object for buffer. */ - int use_bytearray; - - /* If non-zero, overallocate the buffer (default: 0). - This flag must be zero if use_bytearray is non-zero. */ - int overallocate; - - /* Stack buffer */ - int use_small_buffer; - char small_buffer[512]; -} _PyBytesWriter; - -/* Initialize a bytes writer - - By default, the overallocation is disabled. Set the overallocate attribute - to control the allocation of the buffer. */ -PyAPI_FUNC(void) _PyBytesWriter_Init(_PyBytesWriter *writer); - -/* Get the buffer content and reset the writer. - Return a bytes object, or a bytearray object if use_bytearray is non-zero. - Raise an exception and return NULL on error. */ -PyAPI_FUNC(PyObject *) _PyBytesWriter_Finish(_PyBytesWriter *writer, - void *str); - -/* Deallocate memory of a writer (clear its internal buffer). */ -PyAPI_FUNC(void) _PyBytesWriter_Dealloc(_PyBytesWriter *writer); - -/* Allocate the buffer to write size bytes. - Return the pointer to the beginning of buffer data. - Raise an exception and return NULL on error. */ -PyAPI_FUNC(void*) _PyBytesWriter_Alloc(_PyBytesWriter *writer, - Py_ssize_t size); - -/* Ensure that the buffer is large enough to write *size* bytes. - Add size to the writer minimum size (min_size attribute). - - str is the current pointer inside the buffer. - Return the updated current pointer inside the buffer. - Raise an exception and return NULL on error. */ -PyAPI_FUNC(void*) _PyBytesWriter_Prepare(_PyBytesWriter *writer, - void *str, - Py_ssize_t size); - -/* Resize the buffer to make it larger. - The new buffer may be larger than size bytes because of overallocation. - Return the updated current pointer inside the buffer. - Raise an exception and return NULL on error. - - Note: size must be greater than the number of allocated bytes in the writer. - - This function doesn't use the writer minimum size (min_size attribute). - - See also _PyBytesWriter_Prepare(). - */ -PyAPI_FUNC(void*) _PyBytesWriter_Resize(_PyBytesWriter *writer, - void *str, - Py_ssize_t size); - -/* Write bytes. - Raise an exception and return NULL on error. */ -PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer, - void *str, - const void *bytes, - Py_ssize_t size); diff --git a/python/include/cpython/cellobject.h b/python/include/cpython/cellobject.h deleted file mode 100644 index e9405e1..0000000 --- a/python/include/cpython/cellobject.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Cell object interface */ - -#ifndef Py_LIMITED_API -#ifndef Py_CELLOBJECT_H -#define Py_CELLOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - PyObject_HEAD - /* Content of the cell or NULL when empty */ - PyObject *ob_ref; -} PyCellObject; - -PyAPI_DATA(PyTypeObject) PyCell_Type; - -#define PyCell_Check(op) Py_IS_TYPE(op, &PyCell_Type) - -PyAPI_FUNC(PyObject *) PyCell_New(PyObject *); -PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *); -PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *); - -#define PyCell_GET(op) (((PyCellObject *)(op))->ob_ref) -#define PyCell_SET(op, v) _Py_RVALUE(((PyCellObject *)(op))->ob_ref = (v)) - -#ifdef __cplusplus -} -#endif -#endif /* !Py_TUPLEOBJECT_H */ -#endif /* Py_LIMITED_API */ diff --git a/python/include/cpython/ceval.h b/python/include/cpython/ceval.h deleted file mode 100644 index e63f0a9..0000000 --- a/python/include/cpython/ceval.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef Py_CPYTHON_CEVAL_H -# error "this header file must not be included directly" -#endif - -PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); -PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); -PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); -PyAPI_FUNC(int) _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); - -/* Helper to look up a builtin object */ -PyAPI_FUNC(PyObject *) _PyEval_GetBuiltin(PyObject *); -PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *); -/* Look at the current frame's (if any) code's co_flags, and turn on - the corresponding compiler flags in cf->cf_flags. Return 1 if any - flag was set, else return 0. */ -PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); - -PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc); - -PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); -PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); - -PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc); - -PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); -PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); diff --git a/python/include/cpython/classobject.h b/python/include/cpython/classobject.h deleted file mode 100644 index 9541f1d..0000000 --- a/python/include/cpython/classobject.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Former class object interface -- now only bound methods are here */ - -/* Revealing some structures (not for general use) */ - -#ifndef Py_LIMITED_API -#ifndef Py_CLASSOBJECT_H -#define Py_CLASSOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - PyObject_HEAD - PyObject *im_func; /* The callable object implementing the method */ - PyObject *im_self; /* The instance it is bound to */ - PyObject *im_weakreflist; /* List of weak references */ - vectorcallfunc vectorcall; -} PyMethodObject; - -PyAPI_DATA(PyTypeObject) PyMethod_Type; - -#define PyMethod_Check(op) Py_IS_TYPE(op, &PyMethod_Type) - -PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *); - -PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *); -PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *); - -/* Macros for direct access to these values. Type checks are *not* - done, so use with care. */ -#define PyMethod_GET_FUNCTION(meth) \ - (((PyMethodObject *)meth) -> im_func) -#define PyMethod_GET_SELF(meth) \ - (((PyMethodObject *)meth) -> im_self) - -typedef struct { - PyObject_HEAD - PyObject *func; -} PyInstanceMethodObject; - -PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type; - -#define PyInstanceMethod_Check(op) Py_IS_TYPE(op, &PyInstanceMethod_Type) - -PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *); -PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *); - -/* Macros for direct access to these values. Type checks are *not* - done, so use with care. */ -#define PyInstanceMethod_GET_FUNCTION(meth) \ - (((PyInstanceMethodObject *)meth) -> func) - -#ifdef __cplusplus -} -#endif -#endif // !Py_CLASSOBJECT_H -#endif // !Py_LIMITED_API diff --git a/python/include/cpython/code.h b/python/include/cpython/code.h deleted file mode 100644 index 3cacfb6..0000000 --- a/python/include/cpython/code.h +++ /dev/null @@ -1,236 +0,0 @@ -/* Definitions for bytecode */ - -#ifndef Py_LIMITED_API -#ifndef Py_CODE_H -#define Py_CODE_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Each instruction in a code object is a fixed-width value, - * currently 2 bytes: 1-byte opcode + 1-byte oparg. The EXTENDED_ARG - * opcode allows for larger values but the current limit is 3 uses - * of EXTENDED_ARG (see Python/compile.c), for a maximum - * 32-bit value. This aligns with the note in Python/compile.c - * (compiler_addop_i_line) indicating that the max oparg value is - * 2**32 - 1, rather than INT_MAX. - */ - -typedef uint16_t _Py_CODEUNIT; - -#ifdef WORDS_BIGENDIAN -# define _Py_OPCODE(word) ((word) >> 8) -# define _Py_OPARG(word) ((word) & 255) -# define _Py_MAKECODEUNIT(opcode, oparg) (((opcode)<<8)|(oparg)) -#else -# define _Py_OPCODE(word) ((word) & 255) -# define _Py_OPARG(word) ((word) >> 8) -# define _Py_MAKECODEUNIT(opcode, oparg) ((opcode)|((oparg)<<8)) -#endif - -// Use "unsigned char" instead of "uint8_t" here to avoid illegal aliasing: -#define _Py_SET_OPCODE(word, opcode) (((unsigned char *)&(word))[0] = (opcode)) - -// To avoid repeating ourselves in deepfreeze.py, all PyCodeObject members are -// defined in this macro: -#define _PyCode_DEF(SIZE) { \ - PyObject_VAR_HEAD \ - \ - /* Note only the following fields are used in hash and/or comparisons \ - * \ - * - co_name \ - * - co_argcount \ - * - co_posonlyargcount \ - * - co_kwonlyargcount \ - * - co_nlocals \ - * - co_stacksize \ - * - co_flags \ - * - co_firstlineno \ - * - co_consts \ - * - co_names \ - * - co_localsplusnames \ - * This is done to preserve the name and line number for tracebacks \ - * and debuggers; otherwise, constant de-duplication would collapse \ - * identical functions/lambdas defined on different lines. \ - */ \ - \ - /* These fields are set with provided values on new code objects. */ \ - \ - /* The hottest fields (in the eval loop) are grouped here at the top. */ \ - PyObject *co_consts; /* list (constants used) */ \ - PyObject *co_names; /* list of strings (names used) */ \ - PyObject *co_exceptiontable; /* Byte string encoding exception handling \ - table */ \ - int co_flags; /* CO_..., see below */ \ - short co_warmup; /* Warmup counter for quickening */ \ - short _co_linearray_entry_size; /* Size of each entry in _co_linearray */ \ - \ - /* The rest are not so impactful on performance. */ \ - int co_argcount; /* #arguments, except *args */ \ - int co_posonlyargcount; /* #positional only arguments */ \ - int co_kwonlyargcount; /* #keyword only arguments */ \ - int co_stacksize; /* #entries needed for evaluation stack */ \ - int co_firstlineno; /* first source line number */ \ - \ - /* redundant values (derived from co_localsplusnames and \ - co_localspluskinds) */ \ - int co_nlocalsplus; /* number of local + cell + free variables \ - */ \ - int co_nlocals; /* number of local variables */ \ - int co_nplaincellvars; /* number of non-arg cell variables */ \ - int co_ncellvars; /* total number of cell variables */ \ - int co_nfreevars; /* number of free variables */ \ - \ - PyObject *co_localsplusnames; /* tuple mapping offsets to names */ \ - PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte \ - per variable) */ \ - PyObject *co_filename; /* unicode (where it was loaded from) */ \ - PyObject *co_name; /* unicode (name, for reference) */ \ - PyObject *co_qualname; /* unicode (qualname, for reference) */ \ - PyObject *co_linetable; /* bytes object that holds location info */ \ - PyObject *co_weakreflist; /* to support weakrefs to code objects */ \ - PyObject *_co_code; /* cached co_code object/attribute */ \ - char *_co_linearray; /* array of line offsets */ \ - int _co_firsttraceable; /* index of first traceable instruction */ \ - /* Scratch space for extra data relating to the code object. \ - Type is a void* to keep the format private in codeobject.c to force \ - people to go through the proper APIs. */ \ - void *co_extra; \ - char co_code_adaptive[(SIZE)]; \ -} - -/* Bytecode object */ -struct PyCodeObject _PyCode_DEF(1); - -/* Masks for co_flags above */ -#define CO_OPTIMIZED 0x0001 -#define CO_NEWLOCALS 0x0002 -#define CO_VARARGS 0x0004 -#define CO_VARKEYWORDS 0x0008 -#define CO_NESTED 0x0010 -#define CO_GENERATOR 0x0020 - -/* The CO_COROUTINE flag is set for coroutine functions (defined with - ``async def`` keywords) */ -#define CO_COROUTINE 0x0080 -#define CO_ITERABLE_COROUTINE 0x0100 -#define CO_ASYNC_GENERATOR 0x0200 - -/* bpo-39562: These constant values are changed in Python 3.9 - to prevent collision with compiler flags. CO_FUTURE_ and PyCF_ - constants must be kept unique. PyCF_ constants can use bits from - 0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */ -#define CO_FUTURE_DIVISION 0x20000 -#define CO_FUTURE_ABSOLUTE_IMPORT 0x40000 /* do absolute imports by default */ -#define CO_FUTURE_WITH_STATEMENT 0x80000 -#define CO_FUTURE_PRINT_FUNCTION 0x100000 -#define CO_FUTURE_UNICODE_LITERALS 0x200000 - -#define CO_FUTURE_BARRY_AS_BDFL 0x400000 -#define CO_FUTURE_GENERATOR_STOP 0x800000 -#define CO_FUTURE_ANNOTATIONS 0x1000000 - -/* This should be defined if a future statement modifies the syntax. - For example, when a keyword is added. -*/ -#define PY_PARSER_REQUIRES_FUTURE_KEYWORD - -#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */ - -PyAPI_DATA(PyTypeObject) PyCode_Type; - -#define PyCode_Check(op) Py_IS_TYPE(op, &PyCode_Type) -#define PyCode_GetNumFree(op) ((op)->co_nfreevars) -#define _PyCode_CODE(CO) ((_Py_CODEUNIT *)(CO)->co_code_adaptive) -#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT)) - -/* Public interface */ -PyAPI_FUNC(PyCodeObject *) PyCode_New( - int, int, int, int, int, PyObject *, PyObject *, - PyObject *, PyObject *, PyObject *, PyObject *, - PyObject *, PyObject *, PyObject *, int, PyObject *, - PyObject *); - -PyAPI_FUNC(PyCodeObject *) PyCode_NewWithPosOnlyArgs( - int, int, int, int, int, int, PyObject *, PyObject *, - PyObject *, PyObject *, PyObject *, PyObject *, - PyObject *, PyObject *, PyObject *, int, PyObject *, - PyObject *); - /* same as struct above */ - -/* Creates a new empty code object with the specified source location. */ -PyAPI_FUNC(PyCodeObject *) -PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno); - -/* Return the line number associated with the specified bytecode index - in this code object. If you just need the line number of a frame, - use PyFrame_GetLineNumber() instead. */ -PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int); - -PyAPI_FUNC(int) PyCode_Addr2Location(PyCodeObject *, int, int *, int *, int *, int *); - -/* for internal use only */ -struct _opaque { - int computed_line; - const uint8_t *lo_next; - const uint8_t *limit; -}; - -typedef struct _line_offsets { - int ar_start; - int ar_end; - int ar_line; - struct _opaque opaque; -} PyCodeAddressRange; - -/* Update *bounds to describe the first and one-past-the-last instructions in the - same line as lasti. Return the number of that line. -*/ -PyAPI_FUNC(int) _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds); - -/* Create a comparable key used to compare constants taking in account the - * object type. It is used to make sure types are not coerced (e.g., float and - * complex) _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms - * - * Return (type(obj), obj, ...): a tuple with variable size (at least 2 items) - * depending on the type and the value. The type is the first item to not - * compare bytes and str which can raise a BytesWarning exception. */ -PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj); - -PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts, - PyObject *names, PyObject *lnotab); - - -PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index, - void **extra); -PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index, - void *extra); - -/* Equivalent to getattr(code, 'co_code') in Python. - Returns a strong reference to a bytes object. */ -PyAPI_FUNC(PyObject *) PyCode_GetCode(PyCodeObject *code); -/* Equivalent to getattr(code, 'co_varnames') in Python. */ -PyAPI_FUNC(PyObject *) PyCode_GetVarnames(PyCodeObject *code); -/* Equivalent to getattr(code, 'co_cellvars') in Python. */ -PyAPI_FUNC(PyObject *) PyCode_GetCellvars(PyCodeObject *code); -/* Equivalent to getattr(code, 'co_freevars') in Python. */ -PyAPI_FUNC(PyObject *) PyCode_GetFreevars(PyCodeObject *code); - -typedef enum _PyCodeLocationInfoKind { - /* short forms are 0 to 9 */ - PY_CODE_LOCATION_INFO_SHORT0 = 0, - /* one lineforms are 10 to 12 */ - PY_CODE_LOCATION_INFO_ONE_LINE0 = 10, - PY_CODE_LOCATION_INFO_ONE_LINE1 = 11, - PY_CODE_LOCATION_INFO_ONE_LINE2 = 12, - - PY_CODE_LOCATION_INFO_NO_COLUMNS = 13, - PY_CODE_LOCATION_INFO_LONG = 14, - PY_CODE_LOCATION_INFO_NONE = 15 -} _PyCodeLocationInfoKind; - -#ifdef __cplusplus -} -#endif -#endif // !Py_CODE_H -#endif // !Py_LIMITED_API diff --git a/python/include/cpython/compile.h b/python/include/cpython/compile.h deleted file mode 100644 index 7cfbe71..0000000 --- a/python/include/cpython/compile.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef Py_CPYTHON_COMPILE_H -# error "this header file must not be included directly" -#endif - -/* Public interface */ -#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \ - CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \ - CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ - CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS) -#define PyCF_MASK_OBSOLETE (CO_NESTED) - -/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique. - PyCF_ constants can use bits from 0x0100 to 0x10000. - CO_FUTURE_ constants use bits starting at 0x20000. */ -#define PyCF_SOURCE_IS_UTF8 0x0100 -#define PyCF_DONT_IMPLY_DEDENT 0x0200 -#define PyCF_ONLY_AST 0x0400 -#define PyCF_IGNORE_COOKIE 0x0800 -#define PyCF_TYPE_COMMENTS 0x1000 -#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 -#define PyCF_ALLOW_INCOMPLETE_INPUT 0x4000 -#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \ - PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT | \ - PyCF_ALLOW_INCOMPLETE_INPUT) - -typedef struct { - int cf_flags; /* bitmask of CO_xxx flags relevant to future */ - int cf_feature_version; /* minor Python version (PyCF_ONLY_AST) */ -} PyCompilerFlags; - -#define _PyCompilerFlags_INIT \ - (PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION} - -/* Future feature support */ - -typedef struct { - int ff_features; /* flags set by future statements */ - int ff_lineno; /* line number of last future statement */ -} PyFutureFeatures; - -#define FUTURE_NESTED_SCOPES "nested_scopes" -#define FUTURE_GENERATORS "generators" -#define FUTURE_DIVISION "division" -#define FUTURE_ABSOLUTE_IMPORT "absolute_import" -#define FUTURE_WITH_STATEMENT "with_statement" -#define FUTURE_PRINT_FUNCTION "print_function" -#define FUTURE_UNICODE_LITERALS "unicode_literals" -#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL" -#define FUTURE_GENERATOR_STOP "generator_stop" -#define FUTURE_ANNOTATIONS "annotations" - -#define PY_INVALID_STACK_EFFECT INT_MAX -PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg); -PyAPI_FUNC(int) PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump); diff --git a/python/include/cpython/complexobject.h b/python/include/cpython/complexobject.h deleted file mode 100644 index e1c2c2d..0000000 --- a/python/include/cpython/complexobject.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef Py_CPYTHON_COMPLEXOBJECT_H -# error "this header file must not be included directly" -#endif - -typedef struct { - double real; - double imag; -} Py_complex; - -/* Operations on complex numbers from complexmodule.c */ - -PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex); -PyAPI_FUNC(double) _Py_c_abs(Py_complex); - -/* Complex object interface */ - -/* -PyComplexObject represents a complex number with double-precision -real and imaginary parts. -*/ -typedef struct { - PyObject_HEAD - Py_complex cval; -} PyComplexObject; - -PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex); - -PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); - -#ifdef Py_BUILD_CORE -/* Format the object based on the format_spec, as defined in PEP 3101 - (Advanced String Formatting). */ -extern int _PyComplex_FormatAdvancedWriter( - _PyUnicodeWriter *writer, - PyObject *obj, - PyObject *format_spec, - Py_ssize_t start, - Py_ssize_t end); -#endif // Py_BUILD_CORE diff --git a/python/include/cpython/context.h b/python/include/cpython/context.h deleted file mode 100644 index aebba95..0000000 --- a/python/include/cpython/context.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_CONTEXT_H -#define Py_CONTEXT_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_DATA(PyTypeObject) PyContext_Type; -typedef struct _pycontextobject PyContext; - -PyAPI_DATA(PyTypeObject) PyContextVar_Type; -typedef struct _pycontextvarobject PyContextVar; - -PyAPI_DATA(PyTypeObject) PyContextToken_Type; -typedef struct _pycontexttokenobject PyContextToken; - - -#define PyContext_CheckExact(o) Py_IS_TYPE(o, &PyContext_Type) -#define PyContextVar_CheckExact(o) Py_IS_TYPE(o, &PyContextVar_Type) -#define PyContextToken_CheckExact(o) Py_IS_TYPE(o, &PyContextToken_Type) - - -PyAPI_FUNC(PyObject *) PyContext_New(void); -PyAPI_FUNC(PyObject *) PyContext_Copy(PyObject *); -PyAPI_FUNC(PyObject *) PyContext_CopyCurrent(void); - -PyAPI_FUNC(int) PyContext_Enter(PyObject *); -PyAPI_FUNC(int) PyContext_Exit(PyObject *); - - -/* Create a new context variable. - - default_value can be NULL. -*/ -PyAPI_FUNC(PyObject *) PyContextVar_New( - const char *name, PyObject *default_value); - - -/* Get a value for the variable. - - Returns -1 if an error occurred during lookup. - - Returns 0 if value either was or was not found. - - If value was found, *value will point to it. - If not, it will point to: - - - default_value, if not NULL; - - the default value of "var", if not NULL; - - NULL. - - '*value' will be a new ref, if not NULL. -*/ -PyAPI_FUNC(int) PyContextVar_Get( - PyObject *var, PyObject *default_value, PyObject **value); - - -/* Set a new value for the variable. - Returns NULL if an error occurs. -*/ -PyAPI_FUNC(PyObject *) PyContextVar_Set(PyObject *var, PyObject *value); - - -/* Reset a variable to its previous value. - Returns 0 on success, -1 on error. -*/ -PyAPI_FUNC(int) PyContextVar_Reset(PyObject *var, PyObject *token); - - -/* This method is exposed only for CPython tests. Don not use it. */ -PyAPI_FUNC(PyObject *) _PyContext_NewHamtForTests(void); - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_CONTEXT_H */ -#endif /* !Py_LIMITED_API */ diff --git a/python/include/cpython/descrobject.h b/python/include/cpython/descrobject.h deleted file mode 100644 index 8f249d9..0000000 --- a/python/include/cpython/descrobject.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef Py_CPYTHON_DESCROBJECT_H -# error "this header file must not be included directly" -#endif - -typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, - void *wrapped); - -typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args, - void *wrapped, PyObject *kwds); - -struct wrapperbase { - const char *name; - int offset; - void *function; - wrapperfunc wrapper; - const char *doc; - int flags; - PyObject *name_strobj; -}; - -/* Flags for above struct */ -#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */ - -/* Various kinds of descriptor objects */ - -typedef struct { - PyObject_HEAD - PyTypeObject *d_type; - PyObject *d_name; - PyObject *d_qualname; -} PyDescrObject; - -#define PyDescr_COMMON PyDescrObject d_common - -#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) -#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) - -typedef struct { - PyDescr_COMMON; - PyMethodDef *d_method; - vectorcallfunc vectorcall; -} PyMethodDescrObject; - -typedef struct { - PyDescr_COMMON; - PyMemberDef *d_member; -} PyMemberDescrObject; - -typedef struct { - PyDescr_COMMON; - PyGetSetDef *d_getset; -} PyGetSetDescrObject; - -typedef struct { - PyDescr_COMMON; - struct wrapperbase *d_base; - void *d_wrapped; /* This can be any function pointer */ -} PyWrapperDescrObject; - -PyAPI_DATA(PyTypeObject) _PyMethodWrapper_Type; - -PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, - struct wrapperbase *, void *); -PyAPI_FUNC(int) PyDescr_IsData(PyObject *); diff --git a/python/include/cpython/dictobject.h b/python/include/cpython/dictobject.h deleted file mode 100644 index 9aebdbe..0000000 --- a/python/include/cpython/dictobject.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef Py_CPYTHON_DICTOBJECT_H -# error "this header file must not be included directly" -#endif - -typedef struct _dictkeysobject PyDictKeysObject; -typedef struct _dictvalues PyDictValues; - -/* The ma_values pointer is NULL for a combined table - * or points to an array of PyObject* for a split table - */ -typedef struct { - PyObject_HEAD - - /* Number of items in the dictionary */ - Py_ssize_t ma_used; - - /* Dictionary version: globally unique, value change each time - the dictionary is modified */ - uint64_t ma_version_tag; - - PyDictKeysObject *ma_keys; - - /* If ma_values is NULL, the table is "combined": keys and values - are stored in ma_keys. - - If ma_values is not NULL, the table is split: - keys are stored in ma_keys and values are stored in ma_values */ - PyDictValues *ma_values; -} PyDictObject; - -PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, - Py_hash_t hash); -PyAPI_FUNC(PyObject *) _PyDict_GetItemWithError(PyObject *dp, PyObject *key); -PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp, - _Py_Identifier *key); -PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *); -PyAPI_FUNC(PyObject *) PyDict_SetDefault( - PyObject *mp, PyObject *key, PyObject *defaultobj); -PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key, - PyObject *item, Py_hash_t hash); -PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key, - Py_hash_t hash); -PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key, - int (*predicate)(PyObject *value)); -PyAPI_FUNC(int) _PyDict_Next( - PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash); - -/* Get the number of items of a dictionary. */ -#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),((PyDictObject *)mp)->ma_used) -PyAPI_FUNC(int) _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t); -PyAPI_FUNC(int) _PyDict_ContainsId(PyObject *, _Py_Identifier *); -PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); -PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); -PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp); -PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *); -PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *); -#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) - -/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0, - the first occurrence of a key wins, if override is 1, the last occurrence - of a key wins, if override is 2, a KeyError with conflicting key as - argument is raised. -*/ -PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override); -PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, _Py_Identifier *key, PyObject *item); - -PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, _Py_Identifier *key); -PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out); - -/* _PyDictView */ - -typedef struct { - PyObject_HEAD - PyDictObject *dv_dict; -} _PyDictViewObject; - -PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *); -PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); diff --git a/python/include/cpython/fileobject.h b/python/include/cpython/fileobject.h deleted file mode 100644 index e077bb3..0000000 --- a/python/include/cpython/fileobject.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef Py_CPYTHON_FILEOBJECT_H -# error "this header file must not be included directly" -#endif - -PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); - -/* The std printer acts as a preliminary sys.stderr until the new io - infrastructure is in place. */ -PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int); -PyAPI_DATA(PyTypeObject) PyStdPrinter_Type; - -typedef PyObject * (*Py_OpenCodeHookFunction)(PyObject *, void *); - -PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path); -PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path); -PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData); - -PyAPI_FUNC(int) _PyLong_FileDescriptor_Converter(PyObject *, void *); diff --git a/python/include/cpython/fileutils.h b/python/include/cpython/fileutils.h deleted file mode 100644 index 57a09c9..0000000 --- a/python/include/cpython/fileutils.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef Py_CPYTHON_FILEUTILS_H -# error "this header file must not be included directly" -#endif - -// Used by _testcapi which must not use the internal C API -PyAPI_FUNC(FILE*) _Py_fopen_obj( - PyObject *path, - const char *mode); diff --git a/python/include/cpython/floatobject.h b/python/include/cpython/floatobject.h deleted file mode 100644 index d9a34f7..0000000 --- a/python/include/cpython/floatobject.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef Py_CPYTHON_FLOATOBJECT_H -# error "this header file must not be included directly" -#endif - -typedef struct { - PyObject_HEAD - double ob_fval; -} PyFloatObject; - -// Macro version of PyFloat_AsDouble() trading safety for speed. -// It doesn't check if op is a double object. -#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) - - -PyAPI_FUNC(int) PyFloat_Pack2(double x, char *p, int le); -PyAPI_FUNC(int) PyFloat_Pack4(double x, char *p, int le); -PyAPI_FUNC(int) PyFloat_Pack8(double x, char *p, int le); - -PyAPI_FUNC(double) PyFloat_Unpack2(const char *p, int le); -PyAPI_FUNC(double) PyFloat_Unpack4(const char *p, int le); -PyAPI_FUNC(double) PyFloat_Unpack8(const char *p, int le); diff --git a/python/include/cpython/frameobject.h b/python/include/cpython/frameobject.h deleted file mode 100644 index f4e1417..0000000 --- a/python/include/cpython/frameobject.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Frame object interface */ - -#ifndef Py_CPYTHON_FRAMEOBJECT_H -# error "this header file must not be included directly" -#endif - -/* Standard object interface */ - -PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, - PyObject *, PyObject *); - -/* The rest of the interface is specific for frame objects */ - -/* Conversions between "fast locals" and locals in dictionary */ - -PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int); - -/* -- Caveat emptor -- - * The concept of entry frames is an implementation detail of the CPython - * interpreter. This API is considered unstable and is provided for the - * convenience of debuggers, profilers and state-inspecting tools. Notice that - * this API can be changed in future minor versions if the underlying frame - * mechanism change or the concept of an 'entry frame' or its semantics becomes - * obsolete or outdated. */ - -PyAPI_FUNC(int) _PyFrame_IsEntryFrame(PyFrameObject *frame); - -PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f); -PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); diff --git a/python/include/cpython/funcobject.h b/python/include/cpython/funcobject.h deleted file mode 100644 index 517d72a..0000000 --- a/python/include/cpython/funcobject.h +++ /dev/null @@ -1,113 +0,0 @@ -/* Function object interface */ - -#ifndef Py_LIMITED_API -#ifndef Py_FUNCOBJECT_H -#define Py_FUNCOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - - -#define COMMON_FIELDS(PREFIX) \ - PyObject *PREFIX ## globals; \ - PyObject *PREFIX ## builtins; \ - PyObject *PREFIX ## name; \ - PyObject *PREFIX ## qualname; \ - PyObject *PREFIX ## code; /* A code object, the __code__ attribute */ \ - PyObject *PREFIX ## defaults; /* NULL or a tuple */ \ - PyObject *PREFIX ## kwdefaults; /* NULL or a dict */ \ - PyObject *PREFIX ## closure; /* NULL or a tuple of cell objects */ - -typedef struct { - COMMON_FIELDS(fc_) -} PyFrameConstructor; - -/* Function objects and code objects should not be confused with each other: - * - * Function objects are created by the execution of the 'def' statement. - * They reference a code object in their __code__ attribute, which is a - * purely syntactic object, i.e. nothing more than a compiled version of some - * source code lines. There is one code object per source code "fragment", - * but each code object can be referenced by zero or many function objects - * depending only on how many times the 'def' statement in the source was - * executed so far. - */ - -typedef struct { - PyObject_HEAD - COMMON_FIELDS(func_) - PyObject *func_doc; /* The __doc__ attribute, can be anything */ - PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */ - PyObject *func_weakreflist; /* List of weak references */ - PyObject *func_module; /* The __module__ attribute, can be anything */ - PyObject *func_annotations; /* Annotations, a dict or NULL */ - vectorcallfunc vectorcall; - /* Version number for use by specializer. - * Can set to non-zero when we want to specialize. - * Will be set to zero if any of these change: - * defaults - * kwdefaults (only if the object changes, not the contents of the dict) - * code - * annotations */ - uint32_t func_version; - - /* Invariant: - * func_closure contains the bindings for func_code->co_freevars, so - * PyTuple_Size(func_closure) == PyCode_GetNumFree(func_code) - * (func_closure may be NULL if PyCode_GetNumFree(func_code) == 0). - */ -} PyFunctionObject; - -PyAPI_DATA(PyTypeObject) PyFunction_Type; - -#define PyFunction_Check(op) Py_IS_TYPE(op, &PyFunction_Type) - -PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyFunction_NewWithQualName(PyObject *, PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *); -PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *); -PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *); -PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *); -PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyFunction_GetKwDefaults(PyObject *); -PyAPI_FUNC(int) PyFunction_SetKwDefaults(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *); -PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyFunction_GetAnnotations(PyObject *); -PyAPI_FUNC(int) PyFunction_SetAnnotations(PyObject *, PyObject *); - -PyAPI_FUNC(PyObject *) _PyFunction_Vectorcall( - PyObject *func, - PyObject *const *stack, - size_t nargsf, - PyObject *kwnames); - -/* Macros for direct access to these values. Type checks are *not* - done, so use with care. */ -#define PyFunction_GET_CODE(func) \ - (((PyFunctionObject *)func) -> func_code) -#define PyFunction_GET_GLOBALS(func) \ - (((PyFunctionObject *)func) -> func_globals) -#define PyFunction_GET_MODULE(func) \ - (((PyFunctionObject *)func) -> func_module) -#define PyFunction_GET_DEFAULTS(func) \ - (((PyFunctionObject *)func) -> func_defaults) -#define PyFunction_GET_KW_DEFAULTS(func) \ - (((PyFunctionObject *)func) -> func_kwdefaults) -#define PyFunction_GET_CLOSURE(func) \ - (((PyFunctionObject *)func) -> func_closure) -#define PyFunction_GET_ANNOTATIONS(func) \ - (((PyFunctionObject *)func) -> func_annotations) - -/* The classmethod and staticmethod types lives here, too */ -PyAPI_DATA(PyTypeObject) PyClassMethod_Type; -PyAPI_DATA(PyTypeObject) PyStaticMethod_Type; - -PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *); -PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_FUNCOBJECT_H */ -#endif /* Py_LIMITED_API */ diff --git a/python/include/cpython/genobject.h b/python/include/cpython/genobject.h deleted file mode 100644 index 8c52b90..0000000 --- a/python/include/cpython/genobject.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Generator object interface */ - -#ifndef Py_LIMITED_API -#ifndef Py_GENOBJECT_H -#define Py_GENOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -/* --- Generators --------------------------------------------------------- */ - -/* _PyGenObject_HEAD defines the initial segment of generator - and coroutine objects. */ -#define _PyGenObject_HEAD(prefix) \ - PyObject_HEAD \ - /* The code object backing the generator */ \ - PyCodeObject *prefix##_code; \ - /* List of weak reference. */ \ - PyObject *prefix##_weakreflist; \ - /* Name of the generator. */ \ - PyObject *prefix##_name; \ - /* Qualified name of the generator. */ \ - PyObject *prefix##_qualname; \ - _PyErr_StackItem prefix##_exc_state; \ - PyObject *prefix##_origin_or_finalizer; \ - char prefix##_hooks_inited; \ - char prefix##_closed; \ - char prefix##_running_async; \ - /* The frame */ \ - int8_t prefix##_frame_state; \ - PyObject *prefix##_iframe[1]; - -typedef struct { - /* The gi_ prefix is intended to remind of generator-iterator. */ - _PyGenObject_HEAD(gi) -} PyGenObject; - -PyAPI_DATA(PyTypeObject) PyGen_Type; - -#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type) -#define PyGen_CheckExact(op) Py_IS_TYPE(op, &PyGen_Type) - -PyAPI_FUNC(PyObject *) PyGen_New(PyFrameObject *); -PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *, - PyObject *name, PyObject *qualname); -PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *); -PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); -PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); - - -/* --- PyCoroObject ------------------------------------------------------- */ - -typedef struct { - _PyGenObject_HEAD(cr) -} PyCoroObject; - -PyAPI_DATA(PyTypeObject) PyCoro_Type; -PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type; - -#define PyCoro_CheckExact(op) Py_IS_TYPE(op, &PyCoro_Type) -PyAPI_FUNC(PyObject *) PyCoro_New(PyFrameObject *, - PyObject *name, PyObject *qualname); - - -/* --- Asynchronous Generators -------------------------------------------- */ - -typedef struct { - _PyGenObject_HEAD(ag) -} PyAsyncGenObject; - -PyAPI_DATA(PyTypeObject) PyAsyncGen_Type; -PyAPI_DATA(PyTypeObject) _PyAsyncGenASend_Type; -PyAPI_DATA(PyTypeObject) _PyAsyncGenWrappedValue_Type; -PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type; - -PyAPI_FUNC(PyObject *) PyAsyncGen_New(PyFrameObject *, - PyObject *name, PyObject *qualname); - -#define PyAsyncGen_CheckExact(op) Py_IS_TYPE(op, &PyAsyncGen_Type) - - -#undef _PyGenObject_HEAD - -#ifdef __cplusplus -} -#endif -#endif /* !Py_GENOBJECT_H */ -#endif /* Py_LIMITED_API */ diff --git a/python/include/cpython/import.h b/python/include/cpython/import.h deleted file mode 100644 index 31e1f17..0000000 --- a/python/include/cpython/import.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef Py_CPYTHON_IMPORT_H -# error "this header file must not be included directly" -#endif - -PyMODINIT_FUNC PyInit__imp(void); - -PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *); - -PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(_Py_Identifier *name); -PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module); -PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module); - -PyAPI_FUNC(void) _PyImport_AcquireLock(void); -PyAPI_FUNC(int) _PyImport_ReleaseLock(void); - -PyAPI_FUNC(int) _PyImport_FixupBuiltin( - PyObject *mod, - const char *name, /* UTF-8 encoded string */ - PyObject *modules - ); -PyAPI_FUNC(int) _PyImport_FixupExtensionObject(PyObject*, PyObject *, - PyObject *, PyObject *); - -struct _inittab { - const char *name; /* ASCII encoded string */ - PyObject* (*initfunc)(void); -}; -PyAPI_DATA(struct _inittab *) PyImport_Inittab; -PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); - -struct _frozen { - const char *name; /* ASCII encoded string */ - const unsigned char *code; - int size; - int is_package; - PyObject *(*get_code)(void); -}; - -/* Embedding apps may change this pointer to point to their favorite - collection of frozen modules: */ - -PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules; - -PyAPI_DATA(PyObject *) _PyImport_GetModuleAttr(PyObject *, PyObject *); -PyAPI_DATA(PyObject *) _PyImport_GetModuleAttrString(const char *, const char *); diff --git a/python/include/cpython/initconfig.h b/python/include/cpython/initconfig.h deleted file mode 100644 index bec872b..0000000 --- a/python/include/cpython/initconfig.h +++ /dev/null @@ -1,257 +0,0 @@ -#ifndef Py_PYCORECONFIG_H -#define Py_PYCORECONFIG_H -#ifndef Py_LIMITED_API -#ifdef __cplusplus -extern "C" { -#endif - -/* --- PyStatus ----------------------------------------------- */ - -typedef struct { - enum { - _PyStatus_TYPE_OK=0, - _PyStatus_TYPE_ERROR=1, - _PyStatus_TYPE_EXIT=2 - } _type; - const char *func; - const char *err_msg; - int exitcode; -} PyStatus; - -PyAPI_FUNC(PyStatus) PyStatus_Ok(void); -PyAPI_FUNC(PyStatus) PyStatus_Error(const char *err_msg); -PyAPI_FUNC(PyStatus) PyStatus_NoMemory(void); -PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode); -PyAPI_FUNC(int) PyStatus_IsError(PyStatus err); -PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err); -PyAPI_FUNC(int) PyStatus_Exception(PyStatus err); - -/* --- PyWideStringList ------------------------------------------------ */ - -typedef struct { - /* If length is greater than zero, items must be non-NULL - and all items strings must be non-NULL */ - Py_ssize_t length; - wchar_t **items; -} PyWideStringList; - -PyAPI_FUNC(PyStatus) PyWideStringList_Append(PyWideStringList *list, - const wchar_t *item); -PyAPI_FUNC(PyStatus) PyWideStringList_Insert(PyWideStringList *list, - Py_ssize_t index, - const wchar_t *item); - - -/* --- PyPreConfig ----------------------------------------------- */ - -typedef struct PyPreConfig { - int _config_init; /* _PyConfigInitEnum value */ - - /* Parse Py_PreInitializeFromBytesArgs() arguments? - See PyConfig.parse_argv */ - int parse_argv; - - /* If greater than 0, enable isolated mode: sys.path contains - neither the script's directory nor the user's site-packages directory. - - Set to 1 by the -I command line option. If set to -1 (default), inherit - Py_IsolatedFlag value. */ - int isolated; - - /* If greater than 0: use environment variables. - Set to 0 by -E command line option. If set to -1 (default), it is - set to !Py_IgnoreEnvironmentFlag. */ - int use_environment; - - /* Set the LC_CTYPE locale to the user preferred locale? If equals to 0, - set coerce_c_locale and coerce_c_locale_warn to 0. */ - int configure_locale; - - /* Coerce the LC_CTYPE locale if it's equal to "C"? (PEP 538) - - Set to 0 by PYTHONCOERCECLOCALE=0. Set to 1 by PYTHONCOERCECLOCALE=1. - Set to 2 if the user preferred LC_CTYPE locale is "C". - - If it is equal to 1, LC_CTYPE locale is read to decide if it should be - coerced or not (ex: PYTHONCOERCECLOCALE=1). Internally, it is set to 2 - if the LC_CTYPE locale must be coerced. - - Disable by default (set to 0). Set it to -1 to let Python decide if it - should be enabled or not. */ - int coerce_c_locale; - - /* Emit a warning if the LC_CTYPE locale is coerced? - - Set to 1 by PYTHONCOERCECLOCALE=warn. - - Disable by default (set to 0). Set it to -1 to let Python decide if it - should be enabled or not. */ - int coerce_c_locale_warn; - -#ifdef MS_WINDOWS - /* If greater than 1, use the "mbcs" encoding instead of the UTF-8 - encoding for the filesystem encoding. - - Set to 1 if the PYTHONLEGACYWINDOWSFSENCODING environment variable is - set to a non-empty string. If set to -1 (default), inherit - Py_LegacyWindowsFSEncodingFlag value. - - See PEP 529 for more details. */ - int legacy_windows_fs_encoding; -#endif - - /* Enable UTF-8 mode? (PEP 540) - - Disabled by default (equals to 0). - - Set to 1 by "-X utf8" and "-X utf8=1" command line options. - Set to 1 by PYTHONUTF8=1 environment variable. - - Set to 0 by "-X utf8=0" and PYTHONUTF8=0. - - If equals to -1, it is set to 1 if the LC_CTYPE locale is "C" or - "POSIX", otherwise it is set to 0. Inherit Py_UTF8Mode value value. */ - int utf8_mode; - - /* If non-zero, enable the Python Development Mode. - - Set to 1 by the -X dev command line option. Set by the PYTHONDEVMODE - environment variable. */ - int dev_mode; - - /* Memory allocator: PYTHONMALLOC env var. - See PyMemAllocatorName for valid values. */ - int allocator; -} PyPreConfig; - -PyAPI_FUNC(void) PyPreConfig_InitPythonConfig(PyPreConfig *config); -PyAPI_FUNC(void) PyPreConfig_InitIsolatedConfig(PyPreConfig *config); - - -/* --- PyConfig ---------------------------------------------- */ - -/* This structure is best documented in the Doc/c-api/init_config.rst file. */ -typedef struct PyConfig { - int _config_init; /* _PyConfigInitEnum value */ - - int isolated; - int use_environment; - int dev_mode; - int install_signal_handlers; - int use_hash_seed; - unsigned long hash_seed; - int faulthandler; - int tracemalloc; - int import_time; - int code_debug_ranges; - int show_ref_count; - int dump_refs; - wchar_t *dump_refs_file; - int malloc_stats; - wchar_t *filesystem_encoding; - wchar_t *filesystem_errors; - wchar_t *pycache_prefix; - int parse_argv; - PyWideStringList orig_argv; - PyWideStringList argv; - PyWideStringList xoptions; - PyWideStringList warnoptions; - int site_import; - int bytes_warning; - int warn_default_encoding; - int inspect; - int interactive; - int optimization_level; - int parser_debug; - int write_bytecode; - int verbose; - int quiet; - int user_site_directory; - int configure_c_stdio; - int buffered_stdio; - wchar_t *stdio_encoding; - wchar_t *stdio_errors; -#ifdef MS_WINDOWS - int legacy_windows_stdio; -#endif - wchar_t *check_hash_pycs_mode; - int use_frozen_modules; - int safe_path; - - /* --- Path configuration inputs ------------ */ - int pathconfig_warnings; - wchar_t *program_name; - wchar_t *pythonpath_env; - wchar_t *home; - wchar_t *platlibdir; - - /* --- Path configuration outputs ----------- */ - int module_search_paths_set; - PyWideStringList module_search_paths; - wchar_t *stdlib_dir; - wchar_t *executable; - wchar_t *base_executable; - wchar_t *prefix; - wchar_t *base_prefix; - wchar_t *exec_prefix; - wchar_t *base_exec_prefix; - - /* --- Parameter only used by Py_Main() ---------- */ - int skip_source_first_line; - wchar_t *run_command; - wchar_t *run_module; - wchar_t *run_filename; - - /* --- Private fields ---------------------------- */ - - // Install importlib? If equals to 0, importlib is not initialized at all. - // Needed by freeze_importlib. - int _install_importlib; - - // If equal to 0, stop Python initialization before the "main" phase. - int _init_main; - - // If non-zero, disallow threads, subprocesses, and fork. - // Default: 0. - int _isolated_interpreter; - - // If non-zero, we believe we're running from a source tree. - int _is_python_build; -} PyConfig; - -PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config); -PyAPI_FUNC(void) PyConfig_InitIsolatedConfig(PyConfig *config); -PyAPI_FUNC(void) PyConfig_Clear(PyConfig *); -PyAPI_FUNC(PyStatus) PyConfig_SetString( - PyConfig *config, - wchar_t **config_str, - const wchar_t *str); -PyAPI_FUNC(PyStatus) PyConfig_SetBytesString( - PyConfig *config, - wchar_t **config_str, - const char *str); -PyAPI_FUNC(PyStatus) PyConfig_Read(PyConfig *config); -PyAPI_FUNC(PyStatus) PyConfig_SetBytesArgv( - PyConfig *config, - Py_ssize_t argc, - char * const *argv); -PyAPI_FUNC(PyStatus) PyConfig_SetArgv(PyConfig *config, - Py_ssize_t argc, - wchar_t * const *argv); -PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config, - PyWideStringList *list, - Py_ssize_t length, wchar_t **items); - - -/* --- Helper functions --------------------------------------- */ - -/* Get the original command line arguments, before Python modified them. - - See also PyConfig.orig_argv. */ -PyAPI_FUNC(void) Py_GetArgcArgv(int *argc, wchar_t ***argv); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_LIMITED_API */ -#endif /* !Py_PYCORECONFIG_H */ diff --git a/python/include/cpython/listobject.h b/python/include/cpython/listobject.h deleted file mode 100644 index 14681c0..0000000 --- a/python/include/cpython/listobject.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef Py_CPYTHON_LISTOBJECT_H -# error "this header file must not be included directly" -#endif - -typedef struct { - PyObject_VAR_HEAD - /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ - PyObject **ob_item; - - /* ob_item contains space for 'allocated' elements. The number - * currently in use is ob_size. - * Invariants: - * 0 <= ob_size <= allocated - * len(list) == ob_size - * ob_item == NULL implies ob_size == allocated == 0 - * list.sort() temporarily sets allocated to -1 to detect mutations. - * - * Items must normally not be NULL, except during construction when - * the list is not yet visible outside the function that builds it. - */ - Py_ssize_t allocated; -} PyListObject; - -PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); -PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); - -/* Cast argument to PyListObject* type. */ -#define _PyList_CAST(op) \ - (assert(PyList_Check(op)), _Py_CAST(PyListObject*, (op))) - -// Macros and static inline functions, trading safety for speed - -static inline Py_ssize_t PyList_GET_SIZE(PyObject *op) { - PyListObject *list = _PyList_CAST(op); - return Py_SIZE(list); -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op)) -#endif - -#define PyList_GET_ITEM(op, index) (_PyList_CAST(op)->ob_item[index]) - -static inline void -PyList_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) { - PyListObject *list = _PyList_CAST(op); - list->ob_item[index] = value; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -#define PyList_SET_ITEM(op, index, value) \ - PyList_SET_ITEM(_PyObject_CAST(op), index, _PyObject_CAST(value)) -#endif diff --git a/python/include/cpython/longintrepr.h b/python/include/cpython/longintrepr.h deleted file mode 100644 index 0e5e447..0000000 --- a/python/include/cpython/longintrepr.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_LONGINTREPR_H -#define Py_LONGINTREPR_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* This is published for the benefit of "friends" marshal.c and _decimal.c. */ - -/* Parameters of the integer representation. There are two different - sets of parameters: one set for 30-bit digits, stored in an unsigned 32-bit - integer type, and one set for 15-bit digits with each digit stored in an - unsigned short. The value of PYLONG_BITS_IN_DIGIT, defined either at - configure time or in pyport.h, is used to decide which digit size to use. - - Type 'digit' should be able to hold 2*PyLong_BASE-1, and type 'twodigits' - should be an unsigned integer type able to hold all integers up to - PyLong_BASE*PyLong_BASE-1. x_sub assumes that 'digit' is an unsigned type, - and that overflow is handled by taking the result modulo 2**N for some N > - PyLong_SHIFT. The majority of the code doesn't care about the precise - value of PyLong_SHIFT, but there are some notable exceptions: - - - PyLong_{As,From}ByteArray require that PyLong_SHIFT be at least 8 - - - long_hash() requires that PyLong_SHIFT is *strictly* less than the number - of bits in an unsigned long, as do the PyLong <-> long (or unsigned long) - conversion functions - - - the Python int <-> size_t/Py_ssize_t conversion functions expect that - PyLong_SHIFT is strictly less than the number of bits in a size_t - - - the marshal code currently expects that PyLong_SHIFT is a multiple of 15 - - - NSMALLNEGINTS and NSMALLPOSINTS should be small enough to fit in a single - digit; with the current values this forces PyLong_SHIFT >= 9 - - The values 15 and 30 should fit all of the above requirements, on any - platform. -*/ - -#if PYLONG_BITS_IN_DIGIT == 30 -typedef uint32_t digit; -typedef int32_t sdigit; /* signed variant of digit */ -typedef uint64_t twodigits; -typedef int64_t stwodigits; /* signed variant of twodigits */ -#define PyLong_SHIFT 30 -#define _PyLong_DECIMAL_SHIFT 9 /* max(e such that 10**e fits in a digit) */ -#define _PyLong_DECIMAL_BASE ((digit)1000000000) /* 10 ** DECIMAL_SHIFT */ -#elif PYLONG_BITS_IN_DIGIT == 15 -typedef unsigned short digit; -typedef short sdigit; /* signed variant of digit */ -typedef unsigned long twodigits; -typedef long stwodigits; /* signed variant of twodigits */ -#define PyLong_SHIFT 15 -#define _PyLong_DECIMAL_SHIFT 4 /* max(e such that 10**e fits in a digit) */ -#define _PyLong_DECIMAL_BASE ((digit)10000) /* 10 ** DECIMAL_SHIFT */ -#else -#error "PYLONG_BITS_IN_DIGIT should be 15 or 30" -#endif -#define PyLong_BASE ((digit)1 << PyLong_SHIFT) -#define PyLong_MASK ((digit)(PyLong_BASE - 1)) - -/* Long integer representation. - The absolute value of a number is equal to - SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) - Negative numbers are represented with ob_size < 0; - zero is represented by ob_size == 0. - In a normalized number, ob_digit[abs(ob_size)-1] (the most significant - digit) is never zero. Also, in all cases, for all valid i, - 0 <= ob_digit[i] <= MASK. - The allocation function takes care of allocating extra memory - so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available. - - CAUTION: Generic code manipulating subtypes of PyVarObject has to - aware that ints abuse ob_size's sign bit. -*/ - -struct _longobject { - PyObject_VAR_HEAD - digit ob_digit[1]; -}; - -PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t); - -/* Return a copy of src. */ -PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_LONGINTREPR_H */ -#endif /* Py_LIMITED_API */ diff --git a/python/include/cpython/longobject.h b/python/include/cpython/longobject.h deleted file mode 100644 index d5239a2..0000000 --- a/python/include/cpython/longobject.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef Py_CPYTHON_LONGOBJECT_H -# error "this header file must not be included directly" -#endif - -PyAPI_FUNC(int) _PyLong_AsInt(PyObject *); - -PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *); -PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *); -PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *); -PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *); -PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *); - -/* _PyLong_Frexp returns a double x and an exponent e such that the - true value is approximately equal to x * 2**e. e is >= 0. x is - 0.0 if and only if the input is 0 (in which case, e and x are both - zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is - possible if the number of bits doesn't fit into a Py_ssize_t, sets - OverflowError and returns -1.0 for x, 0 for e. */ -PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e); - -PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base); -PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int); - -/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0. - v must not be NULL, and must be a normalized long. - There are no error cases. -*/ -PyAPI_FUNC(int) _PyLong_Sign(PyObject *v); - -/* _PyLong_NumBits. Return the number of bits needed to represent the - absolute value of a long. For example, this returns 1 for 1 and -1, 2 - for 2 and -2, and 2 for 3 and -3. It returns 0 for 0. - v must not be NULL, and must be a normalized long. - (size_t)-1 is returned and OverflowError set if the true result doesn't - fit in a size_t. -*/ -PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); - -/* _PyLong_DivmodNear. Given integers a and b, compute the nearest - integer q to the exact quotient a / b, rounding to the nearest even integer - in the case of a tie. Return (q, r), where r = a - q*b. The remainder r - will satisfy abs(r) <= abs(b)/2, with equality possible only if q is - even. -*/ -PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *); - -/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in - base 256, and return a Python int with the same numeric value. - If n is 0, the integer is 0. Else: - If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB; - else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the - LSB. - If is_signed is 0/false, view the bytes as a non-negative integer. - If is_signed is 1/true, view the bytes as a 2's-complement integer, - non-negative if bit 0x80 of the MSB is clear, negative if set. - Error returns: - + Return NULL with the appropriate exception set if there's not - enough memory to create the Python int. -*/ -PyAPI_FUNC(PyObject *) _PyLong_FromByteArray( - const unsigned char* bytes, size_t n, - int little_endian, int is_signed); - -/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long - v to a base-256 integer, stored in array bytes. Normally return 0, - return -1 on error. - If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at - bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and - the LSB at bytes[n-1]. - If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes - are filled and there's nothing special about bit 0x80 of the MSB. - If is_signed is 1/true, bytes is filled with the 2's-complement - representation of v's value. Bit 0x80 of the MSB is the sign bit. - Error returns (-1): - + is_signed is 0 and v < 0. TypeError is set in this case, and bytes - isn't altered. - + n isn't big enough to hold the full mathematical value of v. For - example, if is_signed is 0 and there are more digits in the v than - fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of - being large enough to hold a sign bit. OverflowError is set in this - case, but bytes holds the least-significant n bytes of the true value. -*/ -PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v, - unsigned char* bytes, size_t n, - int little_endian, int is_signed); - -/* _PyLong_Format: Convert the long to a string object with given base, - appending a base prefix of 0[box] if base is 2, 8 or 16. */ -PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base); - -/* For use by the gcd function in mathmodule.c */ -PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *); - -PyAPI_FUNC(PyObject *) _PyLong_Rshift(PyObject *, size_t); -PyAPI_FUNC(PyObject *) _PyLong_Lshift(PyObject *, size_t); diff --git a/python/include/cpython/methodobject.h b/python/include/cpython/methodobject.h deleted file mode 100644 index da90254..0000000 --- a/python/include/cpython/methodobject.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef Py_CPYTHON_METHODOBJECT_H -# error "this header file must not be included directly" -#endif - -// PyCFunctionObject structure - -typedef struct { - PyObject_HEAD - PyMethodDef *m_ml; /* Description of the C function to call */ - PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ - PyObject *m_module; /* The __module__ attribute, can be anything */ - PyObject *m_weakreflist; /* List of weak references */ - vectorcallfunc vectorcall; -} PyCFunctionObject; - -#define _PyCFunctionObject_CAST(func) \ - (assert(PyCFunction_Check(func)), \ - _Py_CAST(PyCFunctionObject*, (func))) - - -// PyCMethodObject structure - -typedef struct { - PyCFunctionObject func; - PyTypeObject *mm_class; /* Class that defines this method */ -} PyCMethodObject; - -#define _PyCMethodObject_CAST(func) \ - (assert(PyCMethod_Check(func)), \ - _Py_CAST(PyCMethodObject*, (func))) - -PyAPI_DATA(PyTypeObject) PyCMethod_Type; - -#define PyCMethod_CheckExact(op) Py_IS_TYPE(op, &PyCMethod_Type) -#define PyCMethod_Check(op) PyObject_TypeCheck(op, &PyCMethod_Type) - - -/* Static inline functions for direct access to these values. - Type checks are *not* done, so use with care. */ -static inline PyCFunction PyCFunction_GET_FUNCTION(PyObject *func) { - return _PyCFunctionObject_CAST(func)->m_ml->ml_meth; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(_PyObject_CAST(func)) -#endif - -static inline PyObject* PyCFunction_GET_SELF(PyObject *func_obj) { - PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj); - if (func->m_ml->ml_flags & METH_STATIC) { - return _Py_NULL; - } - return func->m_self; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyCFunction_GET_SELF(func) PyCFunction_GET_SELF(_PyObject_CAST(func)) -#endif - -static inline int PyCFunction_GET_FLAGS(PyObject *func) { - return _PyCFunctionObject_CAST(func)->m_ml->ml_flags; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyCFunction_GET_FLAGS(func) PyCFunction_GET_FLAGS(_PyObject_CAST(func)) -#endif - -static inline PyTypeObject* PyCFunction_GET_CLASS(PyObject *func_obj) { - PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj); - if (func->m_ml->ml_flags & METH_METHOD) { - return _PyCMethodObject_CAST(func)->mm_class; - } - return _Py_NULL; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyCFunction_GET_CLASS(func) PyCFunction_GET_CLASS(_PyObject_CAST(func)) -#endif diff --git a/python/include/cpython/modsupport.h b/python/include/cpython/modsupport.h deleted file mode 100644 index 28ccc9a..0000000 --- a/python/include/cpython/modsupport.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef Py_CPYTHON_MODSUPPORT_H -# error "this header file must not be included directly" -#endif - -/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier - to mean Py_ssize_t */ -#ifdef PY_SSIZE_T_CLEAN -#define _Py_VaBuildStack _Py_VaBuildStack_SizeT -#else -PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list); -PyAPI_FUNC(PyObject **) _Py_VaBuildStack_SizeT( - PyObject **small_stack, - Py_ssize_t small_stack_len, - const char *format, - va_list va, - Py_ssize_t *p_nargs); -#endif - -PyAPI_FUNC(int) _PyArg_UnpackStack( - PyObject *const *args, - Py_ssize_t nargs, - const char *name, - Py_ssize_t min, - Py_ssize_t max, - ...); - -PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs); -PyAPI_FUNC(int) _PyArg_NoKwnames(const char *funcname, PyObject *kwnames); -PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); -#define _PyArg_NoKeywords(funcname, kwargs) \ - ((kwargs) == NULL || _PyArg_NoKeywords((funcname), (kwargs))) -#define _PyArg_NoKwnames(funcname, kwnames) \ - ((kwnames) == NULL || _PyArg_NoKwnames((funcname), (kwnames))) -#define _PyArg_NoPositional(funcname, args) \ - ((args) == NULL || _PyArg_NoPositional((funcname), (args))) - -PyAPI_FUNC(void) _PyArg_BadArgument(const char *, const char *, const char *, PyObject *); -PyAPI_FUNC(int) _PyArg_CheckPositional(const char *, Py_ssize_t, - Py_ssize_t, Py_ssize_t); -#define _PyArg_CheckPositional(funcname, nargs, min, max) \ - ((!ANY_VARARGS(max) && (min) <= (nargs) && (nargs) <= (max)) \ - || _PyArg_CheckPositional((funcname), (nargs), (min), (max))) - -PyAPI_FUNC(PyObject **) _Py_VaBuildStack( - PyObject **small_stack, - Py_ssize_t small_stack_len, - const char *format, - va_list va, - Py_ssize_t *p_nargs); - -typedef struct _PyArg_Parser { - const char *format; - const char * const *keywords; - const char *fname; - const char *custom_msg; - int pos; /* number of positional-only arguments */ - int min; /* minimal number of arguments */ - int max; /* maximal number of positional arguments */ - PyObject *kwtuple; /* tuple of keyword parameter names */ - struct _PyArg_Parser *next; -} _PyArg_Parser; - -#ifdef PY_SSIZE_T_CLEAN -#define _PyArg_ParseTupleAndKeywordsFast _PyArg_ParseTupleAndKeywordsFast_SizeT -#define _PyArg_ParseStack _PyArg_ParseStack_SizeT -#define _PyArg_ParseStackAndKeywords _PyArg_ParseStackAndKeywords_SizeT -#define _PyArg_VaParseTupleAndKeywordsFast _PyArg_VaParseTupleAndKeywordsFast_SizeT -#endif - -PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, - struct _PyArg_Parser *, ...); -PyAPI_FUNC(int) _PyArg_ParseStack( - PyObject *const *args, - Py_ssize_t nargs, - const char *format, - ...); -PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords( - PyObject *const *args, - Py_ssize_t nargs, - PyObject *kwnames, - struct _PyArg_Parser *, - ...); -PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, - struct _PyArg_Parser *, va_list); -PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords( - PyObject *const *args, Py_ssize_t nargs, - PyObject *kwargs, PyObject *kwnames, - struct _PyArg_Parser *parser, - int minpos, int maxpos, int minkw, - PyObject **buf); - -PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsWithVararg( - PyObject *const *args, Py_ssize_t nargs, - PyObject *kwargs, PyObject *kwnames, - struct _PyArg_Parser *parser, - int minpos, int maxpos, int minkw, - int vararg, PyObject **buf); - -#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \ - (((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \ - (minpos) <= (nargs) && (nargs) <= (maxpos) && args != NULL) ? (args) : \ - _PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \ - (minpos), (maxpos), (minkw), (buf))) - -PyAPI_FUNC(PyObject *) _PyModule_CreateInitialized(PyModuleDef*, int apiver); - -PyAPI_DATA(const char *) _Py_PackageContext; diff --git a/python/include/cpython/object.h b/python/include/cpython/object.h deleted file mode 100644 index 936ce06..0000000 --- a/python/include/cpython/object.h +++ /dev/null @@ -1,511 +0,0 @@ -#ifndef Py_CPYTHON_OBJECT_H -# error "this header file must not be included directly" -#endif - -PyAPI_FUNC(void) _Py_NewReference(PyObject *op); - -#ifdef Py_TRACE_REFS -/* Py_TRACE_REFS is such major surgery that we call external routines. */ -PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); -#endif - -#ifdef Py_REF_DEBUG -PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); -#endif - - -/********************* String Literals ****************************************/ -/* This structure helps managing static strings. The basic usage goes like this: - Instead of doing - - r = PyObject_CallMethod(o, "foo", "args", ...); - - do - - _Py_IDENTIFIER(foo); - ... - r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...); - - PyId_foo is a static variable, either on block level or file level. On first - usage, the string "foo" is interned, and the structures are linked. On interpreter - shutdown, all strings are released. - - Alternatively, _Py_static_string allows choosing the variable name. - _PyUnicode_FromId returns a borrowed reference to the interned string. - _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*. -*/ -typedef struct _Py_Identifier { - const char* string; - // Index in PyInterpreterState.unicode.ids.array. It is process-wide - // unique and must be initialized to -1. - Py_ssize_t index; -} _Py_Identifier; - -#if defined(NEEDS_PY_IDENTIFIER) || !defined(Py_BUILD_CORE) -// For now we are keeping _Py_IDENTIFIER for continued use -// in non-builtin extensions (and naughty PyPI modules). - -#define _Py_static_string_init(value) { .string = value, .index = -1 } -#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value) -#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) - -#endif /* NEEDS_PY_IDENTIFIER */ - -typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); -typedef void (*releasebufferproc)(PyObject *, Py_buffer *); - -typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwnames); - - -typedef struct { - /* Number implementations must check *both* - arguments for proper type and implement the necessary conversions - in the slot functions themselves. */ - - binaryfunc nb_add; - binaryfunc nb_subtract; - binaryfunc nb_multiply; - binaryfunc nb_remainder; - binaryfunc nb_divmod; - ternaryfunc nb_power; - unaryfunc nb_negative; - unaryfunc nb_positive; - unaryfunc nb_absolute; - inquiry nb_bool; - unaryfunc nb_invert; - binaryfunc nb_lshift; - binaryfunc nb_rshift; - binaryfunc nb_and; - binaryfunc nb_xor; - binaryfunc nb_or; - unaryfunc nb_int; - void *nb_reserved; /* the slot formerly known as nb_long */ - unaryfunc nb_float; - - binaryfunc nb_inplace_add; - binaryfunc nb_inplace_subtract; - binaryfunc nb_inplace_multiply; - binaryfunc nb_inplace_remainder; - ternaryfunc nb_inplace_power; - binaryfunc nb_inplace_lshift; - binaryfunc nb_inplace_rshift; - binaryfunc nb_inplace_and; - binaryfunc nb_inplace_xor; - binaryfunc nb_inplace_or; - - binaryfunc nb_floor_divide; - binaryfunc nb_true_divide; - binaryfunc nb_inplace_floor_divide; - binaryfunc nb_inplace_true_divide; - - unaryfunc nb_index; - - binaryfunc nb_matrix_multiply; - binaryfunc nb_inplace_matrix_multiply; -} PyNumberMethods; - -typedef struct { - lenfunc sq_length; - binaryfunc sq_concat; - ssizeargfunc sq_repeat; - ssizeargfunc sq_item; - void *was_sq_slice; - ssizeobjargproc sq_ass_item; - void *was_sq_ass_slice; - objobjproc sq_contains; - - binaryfunc sq_inplace_concat; - ssizeargfunc sq_inplace_repeat; -} PySequenceMethods; - -typedef struct { - lenfunc mp_length; - binaryfunc mp_subscript; - objobjargproc mp_ass_subscript; -} PyMappingMethods; - -typedef PySendResult (*sendfunc)(PyObject *iter, PyObject *value, PyObject **result); - -typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - sendfunc am_send; -} PyAsyncMethods; - -typedef struct { - getbufferproc bf_getbuffer; - releasebufferproc bf_releasebuffer; -} PyBufferProcs; - -/* Allow printfunc in the tp_vectorcall_offset slot for - * backwards-compatibility */ -typedef Py_ssize_t printfunc; - -// If this structure is modified, Doc/includes/typestruct.h should be updated -// as well. -struct _typeobject { - PyObject_VAR_HEAD - const char *tp_name; /* For printing, in format "." */ - Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ - - /* Methods to implement standard operations */ - - destructor tp_dealloc; - Py_ssize_t tp_vectorcall_offset; - getattrfunc tp_getattr; - setattrfunc tp_setattr; - PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2) - or tp_reserved (Python 3) */ - reprfunc tp_repr; - - /* Method suites for standard classes */ - - PyNumberMethods *tp_as_number; - PySequenceMethods *tp_as_sequence; - PyMappingMethods *tp_as_mapping; - - /* More standard operations (here for binary compatibility) */ - - hashfunc tp_hash; - ternaryfunc tp_call; - reprfunc tp_str; - getattrofunc tp_getattro; - setattrofunc tp_setattro; - - /* Functions to access object as input/output buffer */ - PyBufferProcs *tp_as_buffer; - - /* Flags to define presence of optional/expanded features */ - unsigned long tp_flags; - - const char *tp_doc; /* Documentation string */ - - /* Assigned meaning in release 2.0 */ - /* call function for all accessible objects */ - traverseproc tp_traverse; - - /* delete references to contained objects */ - inquiry tp_clear; - - /* Assigned meaning in release 2.1 */ - /* rich comparisons */ - richcmpfunc tp_richcompare; - - /* weak reference enabler */ - Py_ssize_t tp_weaklistoffset; - - /* Iterators */ - getiterfunc tp_iter; - iternextfunc tp_iternext; - - /* Attribute descriptor and subclassing stuff */ - PyMethodDef *tp_methods; - PyMemberDef *tp_members; - PyGetSetDef *tp_getset; - // Strong reference on a heap type, borrowed reference on a static type - PyTypeObject *tp_base; - PyObject *tp_dict; - descrgetfunc tp_descr_get; - descrsetfunc tp_descr_set; - Py_ssize_t tp_dictoffset; - initproc tp_init; - allocfunc tp_alloc; - newfunc tp_new; - freefunc tp_free; /* Low-level free-memory routine */ - inquiry tp_is_gc; /* For PyObject_IS_GC */ - PyObject *tp_bases; - PyObject *tp_mro; /* method resolution order */ - PyObject *tp_cache; - PyObject *tp_subclasses; - PyObject *tp_weaklist; - destructor tp_del; - - /* Type attribute cache version tag. Added in version 2.6 */ - unsigned int tp_version_tag; - - destructor tp_finalize; - vectorcallfunc tp_vectorcall; -}; - -/* This struct is used by the specializer - * It should should be treated as an opaque blob - * by code other than the specializer and interpreter. */ -struct _specialization_cache { - PyObject *getitem; -}; - -/* The *real* layout of a type object when allocated on the heap */ -typedef struct _heaptypeobject { - /* Note: there's a dependency on the order of these members - in slotptr() in typeobject.c . */ - PyTypeObject ht_type; - PyAsyncMethods as_async; - PyNumberMethods as_number; - PyMappingMethods as_mapping; - PySequenceMethods as_sequence; /* as_sequence comes after as_mapping, - so that the mapping wins when both - the mapping and the sequence define - a given operator (e.g. __getitem__). - see add_operators() in typeobject.c . */ - PyBufferProcs as_buffer; - PyObject *ht_name, *ht_slots, *ht_qualname; - struct _dictkeysobject *ht_cached_keys; - PyObject *ht_module; - char *_ht_tpname; // Storage for "tp_name"; see PyType_FromModuleAndSpec - struct _specialization_cache _spec_cache; // For use by the specializer. - /* here are optional user slots, followed by the members. */ -} PyHeapTypeObject; - -PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *); -PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); -PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *); -PyAPI_FUNC(PyObject *) _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *); -#ifndef Py_BUILD_CORE -// Backward compatibility for 3rd-party extensions -// that may be using the old name. -#define _PyObject_LookupSpecial _PyObject_LookupSpecialId -#endif -PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *); -PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *); -PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *); -PyAPI_FUNC(PyObject *) PyType_GetModuleByDef(PyTypeObject *, PyModuleDef *); - -PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); -PyAPI_FUNC(void) _Py_BreakPoint(void); -PyAPI_FUNC(void) _PyObject_Dump(PyObject *); -PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); - -PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *); -PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, _Py_Identifier *); -PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *); -/* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which - don't raise AttributeError. - - Return 1 and set *result != NULL if an attribute is found. - Return 0 and set *result == NULL if an attribute is not found; - an AttributeError is silenced. - Return -1 and set *result == NULL if an error other than AttributeError - is raised. -*/ -PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **); -PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, _Py_Identifier *, PyObject **); - -PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); - -PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); -PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *); -PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); -PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *); - -/* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes - dict as the last parameter. */ -PyAPI_FUNC(PyObject *) -_PyObject_GenericGetAttrWithDict(PyObject *, PyObject *, PyObject *, int); -PyAPI_FUNC(int) -_PyObject_GenericSetAttrWithDict(PyObject *, PyObject *, - PyObject *, PyObject *); - -PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *); - -/* Safely decref `op` and set `op` to `op2`. - * - * As in case of Py_CLEAR "the obvious" code can be deadly: - * - * Py_DECREF(op); - * op = op2; - * - * The safe way is: - * - * Py_SETREF(op, op2); - * - * That arranges to set `op` to `op2` _before_ decref'ing, so that any code - * triggered as a side-effect of `op` getting torn down no longer believes - * `op` points to a valid object. - * - * Py_XSETREF is a variant of Py_SETREF that uses Py_XDECREF instead of - * Py_DECREF. - */ - -#define Py_SETREF(op, op2) \ - do { \ - PyObject *_py_tmp = _PyObject_CAST(op); \ - (op) = (op2); \ - Py_DECREF(_py_tmp); \ - } while (0) - -#define Py_XSETREF(op, op2) \ - do { \ - PyObject *_py_tmp = _PyObject_CAST(op); \ - (op) = (op2); \ - Py_XDECREF(_py_tmp); \ - } while (0) - - -PyAPI_DATA(PyTypeObject) _PyNone_Type; -PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type; - -/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE. - * Defined in object.c. - */ -PyAPI_DATA(int) _Py_SwappedOp[]; - -PyAPI_FUNC(void) -_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks, - size_t sizeof_block); -PyAPI_FUNC(void) -_PyObject_DebugTypeStats(FILE *out); - -/* Define a pair of assertion macros: - _PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT(). - - These work like the regular C assert(), in that they will abort the - process with a message on stderr if the given condition fails to hold, - but compile away to nothing if NDEBUG is defined. - - However, before aborting, Python will also try to call _PyObject_Dump() on - the given object. This may be of use when investigating bugs in which a - particular object is corrupt (e.g. buggy a tp_visit method in an extension - module breaking the garbage collector), to help locate the broken objects. - - The WITH_MSG variant allows you to supply an additional message that Python - will attempt to print to stderr, after the object dump. */ -#ifdef NDEBUG - /* No debugging: compile away the assertions: */ -# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \ - ((void)0) -#else - /* With debugging: generate checks: */ -# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \ - ((expr) \ - ? (void)(0) \ - : _PyObject_AssertFailed((obj), Py_STRINGIFY(expr), \ - (msg), (filename), (lineno), (func))) -#endif - -#define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \ - _PyObject_ASSERT_FROM(obj, expr, msg, __FILE__, __LINE__, __func__) -#define _PyObject_ASSERT(obj, expr) \ - _PyObject_ASSERT_WITH_MSG(obj, expr, NULL) - -#define _PyObject_ASSERT_FAILED_MSG(obj, msg) \ - _PyObject_AssertFailed((obj), NULL, (msg), __FILE__, __LINE__, __func__) - -/* Declare and define _PyObject_AssertFailed() even when NDEBUG is defined, - to avoid causing compiler/linker errors when building extensions without - NDEBUG against a Python built with NDEBUG defined. - - msg, expr and function can be NULL. */ -PyAPI_FUNC(void) _Py_NO_RETURN _PyObject_AssertFailed( - PyObject *obj, - const char *expr, - const char *msg, - const char *file, - int line, - const char *function); - -/* Check if an object is consistent. For example, ensure that the reference - counter is greater than or equal to 1, and ensure that ob_type is not NULL. - - Call _PyObject_AssertFailed() if the object is inconsistent. - - If check_content is zero, only check header fields: reduce the overhead. - - The function always return 1. The return value is just here to be able to - write: - - assert(_PyObject_CheckConsistency(obj, 1)); */ -PyAPI_FUNC(int) _PyObject_CheckConsistency( - PyObject *op, - int check_content); - - -/* Trashcan mechanism, thanks to Christian Tismer. - -When deallocating a container object, it's possible to trigger an unbounded -chain of deallocations, as each Py_DECREF in turn drops the refcount on "the -next" object in the chain to 0. This can easily lead to stack overflows, -especially in threads (which typically have less stack space to work with). - -A container object can avoid this by bracketing the body of its tp_dealloc -function with a pair of macros: - -static void -mytype_dealloc(mytype *p) -{ - ... declarations go here ... - - PyObject_GC_UnTrack(p); // must untrack first - Py_TRASHCAN_BEGIN(p, mytype_dealloc) - ... The body of the deallocator goes here, including all calls ... - ... to Py_DECREF on contained objects. ... - Py_TRASHCAN_END // there should be no code after this -} - -CAUTION: Never return from the middle of the body! If the body needs to -"get out early", put a label immediately before the Py_TRASHCAN_END -call, and goto it. Else the call-depth counter (see below) will stay -above 0 forever, and the trashcan will never get emptied. - -How it works: The BEGIN macro increments a call-depth counter. So long -as this counter is small, the body of the deallocator is run directly without -further ado. But if the counter gets large, it instead adds p to a list of -objects to be deallocated later, skips the body of the deallocator, and -resumes execution after the END macro. The tp_dealloc routine then returns -without deallocating anything (and so unbounded call-stack depth is avoided). - -When the call stack finishes unwinding again, code generated by the END macro -notices this, and calls another routine to deallocate all the objects that -may have been added to the list of deferred deallocations. In effect, a -chain of N deallocations is broken into (N-1)/(_PyTrash_UNWIND_LEVEL-1) pieces, -with the call stack never exceeding a depth of _PyTrash_UNWIND_LEVEL. - -Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base -class, we need to ensure that the trashcan is only triggered on the tp_dealloc -of the actual class being deallocated. Otherwise we might end up with a -partially-deallocated object. To check this, the tp_dealloc function must be -passed as second argument to Py_TRASHCAN_BEGIN(). -*/ - -/* Python 3.9 private API, invoked by the macros below. */ -PyAPI_FUNC(int) _PyTrash_begin(PyThreadState *tstate, PyObject *op); -PyAPI_FUNC(void) _PyTrash_end(PyThreadState *tstate); -/* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */ -PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc); - -#define Py_TRASHCAN_BEGIN_CONDITION(op, cond) \ - do { \ - PyThreadState *_tstate = NULL; \ - /* If "cond" is false, then _tstate remains NULL and the deallocator \ - * is run normally without involving the trashcan */ \ - if (cond) { \ - _tstate = PyThreadState_Get(); \ - if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \ - break; \ - } \ - } - /* The body of the deallocator is here. */ -#define Py_TRASHCAN_END \ - if (_tstate) { \ - _PyTrash_end(_tstate); \ - } \ - } while (0); - -#define Py_TRASHCAN_BEGIN(op, dealloc) \ - Py_TRASHCAN_BEGIN_CONDITION(op, \ - _PyTrash_cond(_PyObject_CAST(op), (destructor)dealloc)) - -/* The following two macros, Py_TRASHCAN_SAFE_BEGIN and - * Py_TRASHCAN_SAFE_END, are deprecated since version 3.11 and - * will be removed in the future. - * Use Py_TRASHCAN_BEGIN and Py_TRASHCAN_END instead. - */ -Py_DEPRECATED(3.11) typedef int UsingDeprecatedTrashcanMacro; -#define Py_TRASHCAN_SAFE_BEGIN(op) \ - do { \ - UsingDeprecatedTrashcanMacro cond=1; \ - Py_TRASHCAN_BEGIN_CONDITION(op, cond); -#define Py_TRASHCAN_SAFE_END(op) \ - Py_TRASHCAN_END; \ - } while(0); diff --git a/python/include/cpython/objimpl.h b/python/include/cpython/objimpl.h deleted file mode 100644 index a269332..0000000 --- a/python/include/cpython/objimpl.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef Py_CPYTHON_OBJIMPL_H -# error "this header file must not be included directly" -#endif - -#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) - -/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a - vrbl-size object with nitems items, exclusive of gc overhead (if any). The - value is rounded up to the closest multiple of sizeof(void *), in order to - ensure that pointer fields at the end of the object are correctly aligned - for the platform (this is of special importance for subclasses of, e.g., - str or int, so that pointers can be stored after the embedded data). - - Note that there's no memory wastage in doing this, as malloc has to - return (at worst) pointer-aligned memory anyway. -*/ -#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0 -# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2" -#endif - -#define _PyObject_VAR_SIZE(typeobj, nitems) \ - _Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \ - (nitems)*(typeobj)->tp_itemsize, \ - SIZEOF_VOID_P) - - -/* This example code implements an object constructor with a custom - allocator, where PyObject_New is inlined, and shows the important - distinction between two steps (at least): - 1) the actual allocation of the object storage; - 2) the initialization of the Python specific fields - in this storage with PyObject_{Init, InitVar}. - - PyObject * - YourObject_New(...) - { - PyObject *op; - - op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct)); - if (op == NULL) { - return PyErr_NoMemory(); - } - - PyObject_Init(op, &YourTypeStruct); - - op->ob_field = value; - ... - return op; - } - - Note that in C++, the use of the new operator usually implies that - the 1st step is performed automatically for you, so in a C++ class - constructor you would start directly with PyObject_Init/InitVar. */ - - -typedef struct { - /* user context passed as the first argument to the 2 functions */ - void *ctx; - - /* allocate an arena of size bytes */ - void* (*alloc) (void *ctx, size_t size); - - /* free an arena */ - void (*free) (void *ctx, void *ptr, size_t size); -} PyObjectArenaAllocator; - -/* Get the arena allocator. */ -PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator); - -/* Set the arena allocator. */ -PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator); - - -/* Test if an object implements the garbage collector protocol */ -PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj); - - -/* Code built with Py_BUILD_CORE must include pycore_gc.h instead which - defines a different _PyGC_FINALIZED() macro. */ -#ifndef Py_BUILD_CORE - // Kept for backward compatibility with Python 3.8 -# define _PyGC_FINALIZED(o) PyObject_GC_IsFinalized(o) -#endif - - -// Test if a type supports weak references -PyAPI_FUNC(int) PyType_SUPPORTS_WEAKREFS(PyTypeObject *type); - -PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op); diff --git a/python/include/cpython/odictobject.h b/python/include/cpython/odictobject.h deleted file mode 100644 index 881e7eb..0000000 --- a/python/include/cpython/odictobject.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef Py_ODICTOBJECT_H -#define Py_ODICTOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* OrderedDict */ -/* This API is optional and mostly redundant. */ - -#ifndef Py_LIMITED_API - -typedef struct _odictobject PyODictObject; - -PyAPI_DATA(PyTypeObject) PyODict_Type; -PyAPI_DATA(PyTypeObject) PyODictIter_Type; -PyAPI_DATA(PyTypeObject) PyODictKeys_Type; -PyAPI_DATA(PyTypeObject) PyODictItems_Type; -PyAPI_DATA(PyTypeObject) PyODictValues_Type; - -#define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type) -#define PyODict_CheckExact(op) Py_IS_TYPE(op, &PyODict_Type) -#define PyODict_SIZE(op) PyDict_GET_SIZE((op)) - -PyAPI_FUNC(PyObject *) PyODict_New(void); -PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item); -PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key); - -/* wrappers around PyDict* functions */ -#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), key) -#define PyODict_GetItemWithError(od, key) \ - PyDict_GetItemWithError(_PyObject_CAST(od), key) -#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), key) -#define PyODict_Size(od) PyDict_Size(_PyObject_CAST(od)) -#define PyODict_GetItemString(od, key) \ - PyDict_GetItemString(_PyObject_CAST(od), key) - -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_ODICTOBJECT_H */ diff --git a/python/include/cpython/picklebufobject.h b/python/include/cpython/picklebufobject.h deleted file mode 100644 index 5d0b0cf..0000000 --- a/python/include/cpython/picklebufobject.h +++ /dev/null @@ -1,31 +0,0 @@ -/* PickleBuffer object. This is built-in for ease of use from third-party - * C extensions. - */ - -#ifndef Py_PICKLEBUFOBJECT_H -#define Py_PICKLEBUFOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_LIMITED_API - -PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type; - -#define PyPickleBuffer_Check(op) Py_IS_TYPE(op, &PyPickleBuffer_Type) - -/* Create a PickleBuffer redirecting to the given buffer-enabled object */ -PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *); -/* Get the PickleBuffer's underlying view to the original object - * (NULL if released) - */ -PyAPI_FUNC(const Py_buffer *) PyPickleBuffer_GetBuffer(PyObject *); -/* Release the PickleBuffer. Returns 0 on success, -1 on error. */ -PyAPI_FUNC(int) PyPickleBuffer_Release(PyObject *); - -#endif /* !Py_LIMITED_API */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PICKLEBUFOBJECT_H */ diff --git a/python/include/cpython/pthread_stubs.h b/python/include/cpython/pthread_stubs.h deleted file mode 100644 index 3509f1f..0000000 --- a/python/include/cpython/pthread_stubs.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef Py_CPYTHON_PTRHEAD_STUBS_H -#define Py_CPYTHON_PTRHEAD_STUBS_H - -#if !defined(HAVE_PTHREAD_STUBS) -# error "this header file requires stubbed pthreads." -#endif - -#ifndef _POSIX_THREADS -# define _POSIX_THREADS 1 -#endif - -/* Minimal pthread stubs for CPython. - * - * The stubs implement the minimum pthread API for CPython. - * - pthread_create() fails. - * - pthread_exit() calls exit(0). - * - pthread_key_*() functions implement minimal TSS without destructor. - * - all other functions do nothing and return 0. - */ - -#ifdef __wasi__ -// WASI's bits/alltypes.h provides type definitions when __NEED_ is set. -// The header file can be included multiple times. -# define __NEED_pthread_cond_t 1 -# define __NEED_pthread_condattr_t 1 -# define __NEED_pthread_mutex_t 1 -# define __NEED_pthread_mutexattr_t 1 -# define __NEED_pthread_key_t 1 -# define __NEED_pthread_t 1 -# define __NEED_pthread_attr_t 1 -# include -#else -typedef struct { void *__x; } pthread_cond_t; -typedef struct { unsigned __attr; } pthread_condattr_t; -typedef struct { void *__x; } pthread_mutex_t; -typedef struct { unsigned __attr; } pthread_mutexattr_t; -typedef unsigned pthread_key_t; -typedef unsigned pthread_t; -typedef struct { unsigned __attr; } pthread_attr_t; -#endif - -// mutex -PyAPI_FUNC(int) pthread_mutex_init(pthread_mutex_t *restrict mutex, - const pthread_mutexattr_t *restrict attr); -PyAPI_FUNC(int) pthread_mutex_destroy(pthread_mutex_t *mutex); -PyAPI_FUNC(int) pthread_mutex_trylock(pthread_mutex_t *mutex); -PyAPI_FUNC(int) pthread_mutex_lock(pthread_mutex_t *mutex); -PyAPI_FUNC(int) pthread_mutex_unlock(pthread_mutex_t *mutex); - -// condition -PyAPI_FUNC(int) pthread_cond_init(pthread_cond_t *restrict cond, - const pthread_condattr_t *restrict attr); -PyAPI_FUNC(int) pthread_cond_destroy(pthread_cond_t *cond); -PyAPI_FUNC(int) pthread_cond_wait(pthread_cond_t *restrict cond, - pthread_mutex_t *restrict mutex); -PyAPI_FUNC(int) pthread_cond_timedwait(pthread_cond_t *restrict cond, - pthread_mutex_t *restrict mutex, - const struct timespec *restrict abstime); -PyAPI_FUNC(int) pthread_cond_signal(pthread_cond_t *cond); -PyAPI_FUNC(int) pthread_condattr_init(pthread_condattr_t *attr); -PyAPI_FUNC(int) pthread_condattr_setclock( - pthread_condattr_t *attr, clockid_t clock_id); - -// pthread -PyAPI_FUNC(int) pthread_create(pthread_t *restrict thread, - const pthread_attr_t *restrict attr, - void *(*start_routine)(void *), - void *restrict arg); -PyAPI_FUNC(int) pthread_detach(pthread_t thread); -PyAPI_FUNC(pthread_t) pthread_self(void); -PyAPI_FUNC(int) pthread_exit(void *retval) __attribute__ ((__noreturn__)); -PyAPI_FUNC(int) pthread_attr_init(pthread_attr_t *attr); -PyAPI_FUNC(int) pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); -PyAPI_FUNC(int) pthread_attr_destroy(pthread_attr_t *attr); - - -// pthread_key -#ifndef PTHREAD_KEYS_MAX -# define PTHREAD_KEYS_MAX 128 -#endif - -PyAPI_FUNC(int) pthread_key_create(pthread_key_t *key, - void (*destr_function)(void *)); -PyAPI_FUNC(int) pthread_key_delete(pthread_key_t key); -PyAPI_FUNC(void *) pthread_getspecific(pthread_key_t key); -PyAPI_FUNC(int) pthread_setspecific(pthread_key_t key, const void *value); - -#endif // Py_CPYTHON_PTRHEAD_STUBS_H diff --git a/python/include/cpython/pyctype.h b/python/include/cpython/pyctype.h deleted file mode 100644 index 8f4bd79..0000000 --- a/python/include/cpython/pyctype.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef PYCTYPE_H -#define PYCTYPE_H -#ifdef __cplusplus -extern "C" { -#endif - -#define PY_CTF_LOWER 0x01 -#define PY_CTF_UPPER 0x02 -#define PY_CTF_ALPHA (PY_CTF_LOWER|PY_CTF_UPPER) -#define PY_CTF_DIGIT 0x04 -#define PY_CTF_ALNUM (PY_CTF_ALPHA|PY_CTF_DIGIT) -#define PY_CTF_SPACE 0x08 -#define PY_CTF_XDIGIT 0x10 - -PyAPI_DATA(const unsigned int) _Py_ctype_table[256]; - -/* Unlike their C counterparts, the following macros are not meant to - * handle an int with any of the values [EOF, 0-UCHAR_MAX]. The argument - * must be a signed/unsigned char. */ -#define Py_ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_LOWER) -#define Py_ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_UPPER) -#define Py_ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALPHA) -#define Py_ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_DIGIT) -#define Py_ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_XDIGIT) -#define Py_ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALNUM) -#define Py_ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_SPACE) - -PyAPI_DATA(const unsigned char) _Py_ctype_tolower[256]; -PyAPI_DATA(const unsigned char) _Py_ctype_toupper[256]; - -#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) -#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) - -#ifdef __cplusplus -} -#endif -#endif /* !PYCTYPE_H */ -#endif /* !Py_LIMITED_API */ diff --git a/python/include/cpython/pydebug.h b/python/include/cpython/pydebug.h deleted file mode 100644 index 5b26a6e..0000000 --- a/python/include/cpython/pydebug.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_PYDEBUG_H -#define Py_PYDEBUG_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_DATA(int) Py_DebugFlag; -PyAPI_DATA(int) Py_VerboseFlag; -PyAPI_DATA(int) Py_QuietFlag; -PyAPI_DATA(int) Py_InteractiveFlag; -PyAPI_DATA(int) Py_InspectFlag; -PyAPI_DATA(int) Py_OptimizeFlag; -PyAPI_DATA(int) Py_NoSiteFlag; -PyAPI_DATA(int) Py_BytesWarningFlag; -PyAPI_DATA(int) Py_FrozenFlag; -PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; -PyAPI_DATA(int) Py_DontWriteBytecodeFlag; -PyAPI_DATA(int) Py_NoUserSiteDirectory; -PyAPI_DATA(int) Py_UnbufferedStdioFlag; -PyAPI_DATA(int) Py_HashRandomizationFlag; -PyAPI_DATA(int) Py_IsolatedFlag; - -#ifdef MS_WINDOWS -PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag; -PyAPI_DATA(int) Py_LegacyWindowsStdioFlag; -#endif - -/* this is a wrapper around getenv() that pays attention to - Py_IgnoreEnvironmentFlag. It should be used for getting variables like - PYTHONPATH and PYTHONHOME from the environment */ -PyAPI_DATA(char*) Py_GETENV(const char *name); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PYDEBUG_H */ -#endif /* Py_LIMITED_API */ diff --git a/python/include/cpython/pyerrors.h b/python/include/cpython/pyerrors.h deleted file mode 100644 index b9c6b32..0000000 --- a/python/include/cpython/pyerrors.h +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef Py_CPYTHON_ERRORS_H -# error "this header file must not be included directly" -#endif - -/* Error objects */ - -/* PyException_HEAD defines the initial segment of every exception class. */ -#define PyException_HEAD PyObject_HEAD PyObject *dict;\ - PyObject *args; PyObject *notes; PyObject *traceback;\ - PyObject *context; PyObject *cause;\ - char suppress_context; - -typedef struct { - PyException_HEAD -} PyBaseExceptionObject; - -typedef struct { - PyException_HEAD - PyObject *msg; - PyObject *excs; -} PyBaseExceptionGroupObject; - -typedef struct { - PyException_HEAD - PyObject *msg; - PyObject *filename; - PyObject *lineno; - PyObject *offset; - PyObject *end_lineno; - PyObject *end_offset; - PyObject *text; - PyObject *print_file_and_line; -} PySyntaxErrorObject; - -typedef struct { - PyException_HEAD - PyObject *msg; - PyObject *name; - PyObject *path; -} PyImportErrorObject; - -typedef struct { - PyException_HEAD - PyObject *encoding; - PyObject *object; - Py_ssize_t start; - Py_ssize_t end; - PyObject *reason; -} PyUnicodeErrorObject; - -typedef struct { - PyException_HEAD - PyObject *code; -} PySystemExitObject; - -typedef struct { - PyException_HEAD - PyObject *myerrno; - PyObject *strerror; - PyObject *filename; - PyObject *filename2; -#ifdef MS_WINDOWS - PyObject *winerror; -#endif - Py_ssize_t written; /* only for BlockingIOError, -1 otherwise */ -} PyOSErrorObject; - -typedef struct { - PyException_HEAD - PyObject *value; -} PyStopIterationObject; - -typedef struct { - PyException_HEAD - PyObject *name; -} PyNameErrorObject; - -typedef struct { - PyException_HEAD - PyObject *obj; - PyObject *name; -} PyAttributeErrorObject; - -/* Compatibility typedefs */ -typedef PyOSErrorObject PyEnvironmentErrorObject; -#ifdef MS_WINDOWS -typedef PyOSErrorObject PyWindowsErrorObject; -#endif - -/* Error handling definitions */ - -PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *); -PyAPI_FUNC(_PyErr_StackItem*) _PyErr_GetTopmostException(PyThreadState *tstate); -PyAPI_FUNC(PyObject*) _PyErr_GetHandledException(PyThreadState *); -PyAPI_FUNC(void) _PyErr_SetHandledException(PyThreadState *, PyObject *); -PyAPI_FUNC(void) _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, PyObject **); - -/* Context manipulation (PEP 3134) */ - -PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); - -/* Like PyErr_Format(), but saves current exception as __context__ and - __cause__. - */ -PyAPI_FUNC(PyObject *) _PyErr_FormatFromCause( - PyObject *exception, - const char *format, /* ASCII-encoded string */ - ... - ); - -/* In exceptions.c */ - -/* Helper that attempts to replace the current exception with one of the - * same type but with a prefix added to the exception text. The resulting - * exception description looks like: - * - * prefix (exc_type: original_exc_str) - * - * Only some exceptions can be safely replaced. If the function determines - * it isn't safe to perform the replacement, it will leave the original - * unmodified exception in place. - * - * Returns a borrowed reference to the new exception (if any), NULL if the - * existing exception was left in place. - */ -PyAPI_FUNC(PyObject *) _PyErr_TrySetFromCause( - const char *prefix_format, /* ASCII-encoded string */ - ... - ); - -/* In signalmodule.c */ - -int PySignal_SetWakeupFd(int fd); -PyAPI_FUNC(int) _PyErr_CheckSignals(void); - -/* Support for adding program text to SyntaxErrors */ - -PyAPI_FUNC(void) PyErr_SyntaxLocationObject( - PyObject *filename, - int lineno, - int col_offset); - -PyAPI_FUNC(void) PyErr_RangedSyntaxLocationObject( - PyObject *filename, - int lineno, - int col_offset, - int end_lineno, - int end_col_offset); - -PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( - PyObject *filename, - int lineno); - -PyAPI_FUNC(PyObject *) _PyErr_ProgramDecodedTextObject( - PyObject *filename, - int lineno, - const char* encoding); - -PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create( - PyObject *object, - Py_ssize_t start, - Py_ssize_t end, - const char *reason /* UTF-8 encoded string */ - ); - -PyAPI_FUNC(void) _PyErr_WriteUnraisableMsg( - const char *err_msg, - PyObject *obj); - -PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFunc( - const char *func, - const char *message); - -PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFormat( - const char *func, - const char *format, - ...); - -#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, message) diff --git a/python/include/cpython/pyfpe.h b/python/include/cpython/pyfpe.h deleted file mode 100644 index d5a5261..0000000 --- a/python/include/cpython/pyfpe.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef Py_PYFPE_H -#define Py_PYFPE_H -/* Header excluded from the stable API */ -#ifndef Py_LIMITED_API - -/* These macros used to do something when Python was built with --with-fpectl, - * but support for that was dropped in 3.7. We continue to define them though, - * to avoid breaking API users. - */ - -#define PyFPE_START_PROTECT(err_string, leave_stmt) -#define PyFPE_END_PROTECT(v) - -#endif /* !defined(Py_LIMITED_API) */ -#endif /* !Py_PYFPE_H */ diff --git a/python/include/cpython/pyframe.h b/python/include/cpython/pyframe.h deleted file mode 100644 index 54100e0..0000000 --- a/python/include/cpython/pyframe.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef Py_CPYTHON_PYFRAME_H -# error "this header file must not be included directly" -#endif - -PyAPI_DATA(PyTypeObject) PyFrame_Type; - -#define PyFrame_Check(op) Py_IS_TYPE((op), &PyFrame_Type) - -PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame); -PyAPI_FUNC(PyObject *) PyFrame_GetLocals(PyFrameObject *frame); - -PyAPI_FUNC(PyObject *) PyFrame_GetGlobals(PyFrameObject *frame); -PyAPI_FUNC(PyObject *) PyFrame_GetBuiltins(PyFrameObject *frame); - -PyAPI_FUNC(PyObject *) PyFrame_GetGenerator(PyFrameObject *frame); -PyAPI_FUNC(int) PyFrame_GetLasti(PyFrameObject *frame); - diff --git a/python/include/cpython/pylifecycle.h b/python/include/cpython/pylifecycle.h deleted file mode 100644 index 139b955..0000000 --- a/python/include/cpython/pylifecycle.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef Py_CPYTHON_PYLIFECYCLE_H -# error "this header file must not be included directly" -#endif - -/* Py_FrozenMain is kept out of the Limited API until documented and present - in all builds of Python */ -PyAPI_FUNC(int) Py_FrozenMain(int argc, char **argv); - -/* Only used by applications that embed the interpreter and need to - * override the standard encoding determination mechanism - */ -Py_DEPRECATED(3.11) PyAPI_FUNC(int) Py_SetStandardStreamEncoding( - const char *encoding, - const char *errors); - -/* PEP 432 Multi-phase initialization API (Private while provisional!) */ - -PyAPI_FUNC(PyStatus) Py_PreInitialize( - const PyPreConfig *src_config); -PyAPI_FUNC(PyStatus) Py_PreInitializeFromBytesArgs( - const PyPreConfig *src_config, - Py_ssize_t argc, - char **argv); -PyAPI_FUNC(PyStatus) Py_PreInitializeFromArgs( - const PyPreConfig *src_config, - Py_ssize_t argc, - wchar_t **argv); - -PyAPI_FUNC(int) _Py_IsCoreInitialized(void); - - -/* Initialization and finalization */ - -PyAPI_FUNC(PyStatus) Py_InitializeFromConfig( - const PyConfig *config); -PyAPI_FUNC(PyStatus) _Py_InitializeMain(void); - -PyAPI_FUNC(int) Py_RunMain(void); - - -PyAPI_FUNC(void) _Py_NO_RETURN Py_ExitStatusException(PyStatus err); - -/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ -PyAPI_FUNC(void) _Py_RestoreSignals(void); - -PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); -PyAPI_FUNC(int) _Py_FdIsInteractive(FILE *fp, PyObject *filename); - -Py_DEPRECATED(3.11) PyAPI_FUNC(void) _Py_SetProgramFullPath(const wchar_t *); - -PyAPI_FUNC(const char *) _Py_gitidentifier(void); -PyAPI_FUNC(const char *) _Py_gitversion(void); - -PyAPI_FUNC(int) _Py_IsFinalizing(void); - -/* Random */ -PyAPI_FUNC(int) _PyOS_URandom(void *buffer, Py_ssize_t size); -PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size); - -/* Legacy locale support */ -PyAPI_FUNC(int) _Py_CoerceLegacyLocale(int warn); -PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn); -PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category); - -PyAPI_FUNC(PyThreadState *) _Py_NewInterpreter(int isolated_subinterpreter); diff --git a/python/include/cpython/pymem.h b/python/include/cpython/pymem.h deleted file mode 100644 index 9db440d..0000000 --- a/python/include/cpython/pymem.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef Py_CPYTHON_PYMEM_H -# error "this header file must not be included directly" -#endif - -PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); -PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize); -PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size); -PyAPI_FUNC(void) PyMem_RawFree(void *ptr); - -/* Try to get the allocators name set by _PyMem_SetupAllocators(). */ -PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void); - -/* strdup() using PyMem_RawMalloc() */ -PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); - -/* strdup() using PyMem_Malloc() */ -PyAPI_FUNC(char *) _PyMem_Strdup(const char *str); - -/* wcsdup() using PyMem_RawMalloc() */ -PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str); - - -typedef enum { - /* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */ - PYMEM_DOMAIN_RAW, - - /* PyMem_Malloc(), PyMem_Realloc() and PyMem_Free() */ - PYMEM_DOMAIN_MEM, - - /* PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() */ - PYMEM_DOMAIN_OBJ -} PyMemAllocatorDomain; - -typedef enum { - PYMEM_ALLOCATOR_NOT_SET = 0, - PYMEM_ALLOCATOR_DEFAULT = 1, - PYMEM_ALLOCATOR_DEBUG = 2, - PYMEM_ALLOCATOR_MALLOC = 3, - PYMEM_ALLOCATOR_MALLOC_DEBUG = 4, -#ifdef WITH_PYMALLOC - PYMEM_ALLOCATOR_PYMALLOC = 5, - PYMEM_ALLOCATOR_PYMALLOC_DEBUG = 6, -#endif -} PyMemAllocatorName; - - -typedef struct { - /* user context passed as the first argument to the 4 functions */ - void *ctx; - - /* allocate a memory block */ - void* (*malloc) (void *ctx, size_t size); - - /* allocate a memory block initialized by zeros */ - void* (*calloc) (void *ctx, size_t nelem, size_t elsize); - - /* allocate or resize a memory block */ - void* (*realloc) (void *ctx, void *ptr, size_t new_size); - - /* release a memory block */ - void (*free) (void *ctx, void *ptr); -} PyMemAllocatorEx; - -/* Get the memory block allocator of the specified domain. */ -PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain, - PyMemAllocatorEx *allocator); - -/* Set the memory block allocator of the specified domain. - - The new allocator must return a distinct non-NULL pointer when requesting - zero bytes. - - For the PYMEM_DOMAIN_RAW domain, the allocator must be thread-safe: the GIL - is not held when the allocator is called. - - If the new allocator is not a hook (don't call the previous allocator), the - PyMem_SetupDebugHooks() function must be called to reinstall the debug hooks - on top on the new allocator. */ -PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain, - PyMemAllocatorEx *allocator); - -/* Setup hooks to detect bugs in the following Python memory allocator - functions: - - - PyMem_RawMalloc(), PyMem_RawRealloc(), PyMem_RawFree() - - PyMem_Malloc(), PyMem_Realloc(), PyMem_Free() - - PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() - - Newly allocated memory is filled with the byte 0xCB, freed memory is filled - with the byte 0xDB. Additional checks: - - - detect API violations, ex: PyObject_Free() called on a buffer allocated - by PyMem_Malloc() - - detect write before the start of the buffer (buffer underflow) - - detect write after the end of the buffer (buffer overflow) - - The function does nothing if Python is not compiled is debug mode. */ -PyAPI_FUNC(void) PyMem_SetupDebugHooks(void); diff --git a/python/include/cpython/pystate.h b/python/include/cpython/pystate.h deleted file mode 100644 index bd8519b..0000000 --- a/python/include/cpython/pystate.h +++ /dev/null @@ -1,366 +0,0 @@ -#ifndef Py_CPYTHON_PYSTATE_H -# error "this header file must not be included directly" -#endif - - -PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *); -PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int); - -PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *); - -/* State unique per thread */ - -/* Py_tracefunc return -1 when raising an exception, or 0 for success. */ -typedef int (*Py_tracefunc)(PyObject *, PyFrameObject *, int, PyObject *); - -/* The following values are used for 'what' for tracefunc functions - * - * To add a new kind of trace event, also update "trace_init" in - * Python/sysmodule.c to define the Python level event name - */ -#define PyTrace_CALL 0 -#define PyTrace_EXCEPTION 1 -#define PyTrace_LINE 2 -#define PyTrace_RETURN 3 -#define PyTrace_C_CALL 4 -#define PyTrace_C_EXCEPTION 5 -#define PyTrace_C_RETURN 6 -#define PyTrace_OPCODE 7 - - -typedef struct { - PyCodeObject *code; // The code object for the bounds. May be NULL. - PyCodeAddressRange bounds; // Only valid if code != NULL. -} PyTraceInfo; - -// Internal structure: you should not use it directly, but use public functions -// like PyThreadState_EnterTracing() and PyThreadState_LeaveTracing(). -typedef struct _PyCFrame { - /* This struct will be threaded through the C stack - * allowing fast access to per-thread state that needs - * to be accessed quickly by the interpreter, but can - * be modified outside of the interpreter. - * - * WARNING: This makes data on the C stack accessible from - * heap objects. Care must be taken to maintain stack - * discipline and make sure that instances of this struct cannot - * accessed outside of their lifetime. - */ - uint8_t use_tracing; // 0 or 255 (or'ed into opcode, hence 8-bit type) - /* Pointer to the currently executing frame (it can be NULL) */ - struct _PyInterpreterFrame *current_frame; - struct _PyCFrame *previous; -} _PyCFrame; - -typedef struct _err_stackitem { - /* This struct represents a single execution context where we might - * be currently handling an exception. It is a per-coroutine state - * (coroutine in the computer science sense, including the thread - * and generators). - * - * This is used as an entry on the exception stack, where each - * entry indicates if it is currently handling an exception. - * This ensures that the exception state is not impacted - * by "yields" from an except handler. The thread - * always has an entry (the bottom-most one). - */ - - /* The exception currently being handled in this context, if any. */ - PyObject *exc_value; - - struct _err_stackitem *previous_item; - -} _PyErr_StackItem; - -typedef struct _stack_chunk { - struct _stack_chunk *previous; - size_t size; - size_t top; - PyObject * data[1]; /* Variable sized */ -} _PyStackChunk; - -struct _ts { - /* See Python/ceval.c for comments explaining most fields */ - - PyThreadState *prev; - PyThreadState *next; - PyInterpreterState *interp; - - /* Has been initialized to a safe state. - - In order to be effective, this must be set to 0 during or right - after allocation. */ - int _initialized; - - /* Was this thread state statically allocated? */ - int _static; - - int recursion_remaining; - int recursion_limit; - int recursion_headroom; /* Allow 50 more calls to handle any errors. */ - - /* 'tracing' keeps track of the execution depth when tracing/profiling. - This is to prevent the actual trace/profile code from being recorded in - the trace/profile. */ - int tracing; - int tracing_what; /* The event currently being traced, if any. */ - - /* Pointer to current _PyCFrame in the C stack frame of the currently, - * or most recently, executing _PyEval_EvalFrameDefault. */ - _PyCFrame *cframe; - - Py_tracefunc c_profilefunc; - Py_tracefunc c_tracefunc; - PyObject *c_profileobj; - PyObject *c_traceobj; - - /* The exception currently being raised */ - PyObject *curexc_type; - PyObject *curexc_value; - PyObject *curexc_traceback; - - /* Pointer to the top of the exception stack for the exceptions - * we may be currently handling. (See _PyErr_StackItem above.) - * This is never NULL. */ - _PyErr_StackItem *exc_info; - - PyObject *dict; /* Stores per-thread state */ - - int gilstate_counter; - - PyObject *async_exc; /* Asynchronous exception to raise */ - unsigned long thread_id; /* Thread id where this tstate was created */ - - /* Native thread id where this tstate was created. This will be 0 except on - * those platforms that have the notion of native thread id, for which the - * macro PY_HAVE_THREAD_NATIVE_ID is then defined. - */ - unsigned long native_thread_id; - - int trash_delete_nesting; - PyObject *trash_delete_later; - - /* Called when a thread state is deleted normally, but not when it - * is destroyed after fork(). - * Pain: to prevent rare but fatal shutdown errors (issue 18808), - * Thread.join() must wait for the join'ed thread's tstate to be unlinked - * from the tstate chain. That happens at the end of a thread's life, - * in pystate.c. - * The obvious way doesn't quite work: create a lock which the tstate - * unlinking code releases, and have Thread.join() wait to acquire that - * lock. The problem is that we _are_ at the end of the thread's life: - * if the thread holds the last reference to the lock, decref'ing the - * lock will delete the lock, and that may trigger arbitrary Python code - * if there's a weakref, with a callback, to the lock. But by this time - * _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest - * of C code can be allowed to run (in particular it must not be possible to - * release the GIL). - * So instead of holding the lock directly, the tstate holds a weakref to - * the lock: that's the value of on_delete_data below. Decref'ing a - * weakref is harmless. - * on_delete points to _threadmodule.c's static release_sentinel() function. - * After the tstate is unlinked, release_sentinel is called with the - * weakref-to-lock (on_delete_data) argument, and release_sentinel releases - * the indirectly held lock. - */ - void (*on_delete)(void *); - void *on_delete_data; - - int coroutine_origin_tracking_depth; - - PyObject *async_gen_firstiter; - PyObject *async_gen_finalizer; - - PyObject *context; - uint64_t context_ver; - - /* Unique thread state id. */ - uint64_t id; - - PyTraceInfo trace_info; - - _PyStackChunk *datastack_chunk; - PyObject **datastack_top; - PyObject **datastack_limit; - /* XXX signal handlers should also be here */ - - /* The following fields are here to avoid allocation during init. - The data is exposed through PyThreadState pointer fields. - These fields should not be accessed directly outside of init. - This is indicated by an underscore prefix on the field names. - - All other PyInterpreterState pointer fields are populated when - needed and default to NULL. - */ - // Note some fields do not have a leading underscore for backward - // compatibility. See https://bugs.python.org/issue45953#msg412046. - - /* The thread's exception stack entry. (Always the last entry.) */ - _PyErr_StackItem exc_state; - - /* The bottom-most frame on the stack. */ - _PyCFrame root_cframe; -}; - - -/* other API */ - -// Alias for backward compatibility with Python 3.8 -#define _PyInterpreterState_Get PyInterpreterState_Get - -PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); - -/* Similar to PyThreadState_Get(), but don't issue a fatal error - * if it is NULL. */ -PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void); - -PyAPI_FUNC(PyObject *) _PyThreadState_GetDict(PyThreadState *tstate); - -// Disable tracing and profiling. -PyAPI_FUNC(void) PyThreadState_EnterTracing(PyThreadState *tstate); - -// Reset tracing and profiling: enable them if a trace function or a profile -// function is set, otherwise disable them. -PyAPI_FUNC(void) PyThreadState_LeaveTracing(PyThreadState *tstate); - -/* PyGILState */ - -/* Helper/diagnostic function - return 1 if the current thread - currently holds the GIL, 0 otherwise. - - The function returns 1 if _PyGILState_check_enabled is non-zero. */ -PyAPI_FUNC(int) PyGILState_Check(void); - -/* Get the single PyInterpreterState used by this process' GILState - implementation. - - This function doesn't check for error. Return NULL before _PyGILState_Init() - is called and after _PyGILState_Fini() is called. - - See also _PyInterpreterState_Get() and _PyInterpreterState_GET(). */ -PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void); - -/* The implementation of sys._current_frames() Returns a dict mapping - thread id to that thread's current frame. -*/ -PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); - -/* The implementation of sys._current_exceptions() Returns a dict mapping - thread id to that thread's current exception. -*/ -PyAPI_FUNC(PyObject *) _PyThread_CurrentExceptions(void); - -/* Routines for advanced debuggers, requested by David Beazley. - Don't use unless you know what you are doing! */ -PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void); -PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); -PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); -PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); -PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); -PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); - -/* Frame evaluation API */ - -typedef PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, struct _PyInterpreterFrame *, int); - -PyAPI_FUNC(_PyFrameEvalFunction) _PyInterpreterState_GetEvalFrameFunc( - PyInterpreterState *interp); -PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc( - PyInterpreterState *interp, - _PyFrameEvalFunction eval_frame); - -PyAPI_FUNC(const PyConfig*) _PyInterpreterState_GetConfig(PyInterpreterState *interp); - -/* Get a copy of the current interpreter configuration. - - Return 0 on success. Raise an exception and return -1 on error. - - The caller must initialize 'config', using PyConfig_InitPythonConfig() - for example. - - Python must be preinitialized to call this method. - The caller must hold the GIL. */ -PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy( - struct PyConfig *config); - -/* Set the configuration of the current interpreter. - - This function should be called during or just after the Python - initialization. - - Update the sys module with the new configuration. If the sys module was - modified directly after the Python initialization, these changes are lost. - - Some configuration like faulthandler or warnoptions can be updated in the - configuration, but don't reconfigure Python (don't enable/disable - faulthandler and don't reconfigure warnings filters). - - Return 0 on success. Raise an exception and return -1 on error. - - The configuration should come from _PyInterpreterState_GetConfigCopy(). */ -PyAPI_FUNC(int) _PyInterpreterState_SetConfig( - const struct PyConfig *config); - -// Get the configuration of the current interpreter. -// The caller must hold the GIL. -PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void); - - -/* cross-interpreter data */ - -// _PyCrossInterpreterData is similar to Py_buffer as an effectively -// opaque struct that holds data outside the object machinery. This -// is necessary to pass safely between interpreters in the same process. -typedef struct _xid _PyCrossInterpreterData; - -struct _xid { - // data is the cross-interpreter-safe derivation of a Python object - // (see _PyObject_GetCrossInterpreterData). It will be NULL if the - // new_object func (below) encodes the data. - void *data; - // obj is the Python object from which the data was derived. This - // is non-NULL only if the data remains bound to the object in some - // way, such that the object must be "released" (via a decref) when - // the data is released. In that case the code that sets the field, - // likely a registered "crossinterpdatafunc", is responsible for - // ensuring it owns the reference (i.e. incref). - PyObject *obj; - // interp is the ID of the owning interpreter of the original - // object. It corresponds to the active interpreter when - // _PyObject_GetCrossInterpreterData() was called. This should only - // be set by the cross-interpreter machinery. - // - // We use the ID rather than the PyInterpreterState to avoid issues - // with deleted interpreters. Note that IDs are never re-used, so - // each one will always correspond to a specific interpreter - // (whether still alive or not). - int64_t interp; - // new_object is a function that returns a new object in the current - // interpreter given the data. The resulting object (a new - // reference) will be equivalent to the original object. This field - // is required. - PyObject *(*new_object)(_PyCrossInterpreterData *); - // free is called when the data is released. If it is NULL then - // nothing will be done to free the data. For some types this is - // okay (e.g. bytes) and for those types this field should be set - // to NULL. However, for most the data was allocated just for - // cross-interpreter use, so it must be freed when - // _PyCrossInterpreterData_Release is called or the memory will - // leak. In that case, at the very least this field should be set - // to PyMem_RawFree (the default if not explicitly set to NULL). - // The call will happen with the original interpreter activated. - void (*free)(void *); -}; - -PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *); -PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *); -PyAPI_FUNC(void) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); - -PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *); - -/* cross-interpreter data registry */ - -typedef int (*crossinterpdatafunc)(PyObject *, _PyCrossInterpreterData *); - -PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc); -PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); diff --git a/python/include/cpython/pythonrun.h b/python/include/cpython/pythonrun.h deleted file mode 100644 index cf0e677..0000000 --- a/python/include/cpython/pythonrun.h +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef Py_CPYTHON_PYTHONRUN_H -# error "this header file must not be included directly" -#endif - -PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); -PyAPI_FUNC(int) _PyRun_SimpleFileObject( - FILE *fp, - PyObject *filename, - int closeit, - PyCompilerFlags *flags); -PyAPI_FUNC(int) PyRun_AnyFileExFlags( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - int closeit, - PyCompilerFlags *flags); -PyAPI_FUNC(int) _PyRun_AnyFileObject( - FILE *fp, - PyObject *filename, - int closeit, - PyCompilerFlags *flags); -PyAPI_FUNC(int) PyRun_SimpleFileExFlags( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - int closeit, - PyCompilerFlags *flags); -PyAPI_FUNC(int) PyRun_InteractiveOneFlags( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - PyCompilerFlags *flags); -PyAPI_FUNC(int) PyRun_InteractiveOneObject( - FILE *fp, - PyObject *filename, - PyCompilerFlags *flags); -PyAPI_FUNC(int) PyRun_InteractiveLoopFlags( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - PyCompilerFlags *flags); -PyAPI_FUNC(int) _PyRun_InteractiveLoopObject( - FILE *fp, - PyObject *filename, - PyCompilerFlags *flags); - - -PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *, - PyObject *, PyCompilerFlags *); - -PyAPI_FUNC(PyObject *) PyRun_FileExFlags( - FILE *fp, - const char *filename, /* decoded from the filesystem encoding */ - int start, - PyObject *globals, - PyObject *locals, - int closeit, - PyCompilerFlags *flags); - - -PyAPI_FUNC(PyObject *) Py_CompileStringExFlags( - const char *str, - const char *filename, /* decoded from the filesystem encoding */ - int start, - PyCompilerFlags *flags, - int optimize); -PyAPI_FUNC(PyObject *) Py_CompileStringObject( - const char *str, - PyObject *filename, int start, - PyCompilerFlags *flags, - int optimize); - -#define Py_CompileString(str, p, s) Py_CompileStringExFlags(str, p, s, NULL, -1) -#define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags(str, p, s, f, -1) - - -PyAPI_FUNC(const char *) _Py_SourceAsString( - PyObject *cmd, - const char *funcname, - const char *what, - PyCompilerFlags *cf, - PyObject **cmd_copy); - - -/* A function flavor is also exported by libpython. It is required when - libpython is accessed directly rather than using header files which defines - macros below. On Windows, for example, PyAPI_FUNC() uses dllexport to - export functions in pythonXX.dll. */ -PyAPI_FUNC(PyObject *) PyRun_String(const char *str, int s, PyObject *g, PyObject *l); -PyAPI_FUNC(int) PyRun_AnyFile(FILE *fp, const char *name); -PyAPI_FUNC(int) PyRun_AnyFileEx(FILE *fp, const char *name, int closeit); -PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); -PyAPI_FUNC(int) PyRun_SimpleString(const char *s); -PyAPI_FUNC(int) PyRun_SimpleFile(FILE *f, const char *p); -PyAPI_FUNC(int) PyRun_SimpleFileEx(FILE *f, const char *p, int c); -PyAPI_FUNC(int) PyRun_InteractiveOne(FILE *f, const char *p); -PyAPI_FUNC(int) PyRun_InteractiveLoop(FILE *f, const char *p); -PyAPI_FUNC(PyObject *) PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l); -PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c); -PyAPI_FUNC(PyObject *) PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, PyCompilerFlags *flags); - -/* Use macros for a bunch of old variants */ -#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL) -#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL) -#define PyRun_AnyFileEx(fp, name, closeit) \ - PyRun_AnyFileExFlags(fp, name, closeit, NULL) -#define PyRun_AnyFileFlags(fp, name, flags) \ - PyRun_AnyFileExFlags(fp, name, 0, flags) -#define PyRun_SimpleString(s) PyRun_SimpleStringFlags(s, NULL) -#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags(f, p, 0, NULL) -#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags(f, p, c, NULL) -#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags(f, p, NULL) -#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags(f, p, NULL) -#define PyRun_File(fp, p, s, g, l) \ - PyRun_FileExFlags(fp, p, s, g, l, 0, NULL) -#define PyRun_FileEx(fp, p, s, g, l, c) \ - PyRun_FileExFlags(fp, p, s, g, l, c, NULL) -#define PyRun_FileFlags(fp, p, s, g, l, flags) \ - PyRun_FileExFlags(fp, p, s, g, l, 0, flags) - - -/* Stuff with no proper home (yet) */ -PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, const char *); -PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; -PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *); diff --git a/python/include/cpython/pythread.h b/python/include/cpython/pythread.h deleted file mode 100644 index 7ebd534..0000000 --- a/python/include/cpython/pythread.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef Py_CPYTHON_PYTHREAD_H -# error "this header file must not be included directly" -#endif - -#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1) - -#ifdef HAVE_FORK -/* Private function to reinitialize a lock at fork in the child process. - Reset the lock to the unlocked state. - Return 0 on success, return -1 on error. */ -PyAPI_FUNC(int) _PyThread_at_fork_reinit(PyThread_type_lock *lock); -#endif /* HAVE_FORK */ - -#ifdef HAVE_PTHREAD_H - /* Darwin needs pthread.h to know type name the pthread_key_t. */ -# include -# define NATIVE_TSS_KEY_T pthread_key_t -#elif defined(NT_THREADS) - /* In Windows, native TSS key type is DWORD, - but hardcode the unsigned long to avoid errors for include directive. - */ -# define NATIVE_TSS_KEY_T unsigned long -#elif defined(HAVE_PTHREAD_STUBS) -# include "cpython/pthread_stubs.h" -# define NATIVE_TSS_KEY_T pthread_key_t -#else -# error "Require native threads. See https://bugs.python.org/issue31370" -#endif - -/* When Py_LIMITED_API is not defined, the type layout of Py_tss_t is - exposed to allow static allocation in the API clients. Even in this case, - you must handle TSS keys through API functions due to compatibility. -*/ -struct _Py_tss_t { - int _is_initialized; - NATIVE_TSS_KEY_T _key; -}; - -#undef NATIVE_TSS_KEY_T - -/* When static allocation, you must initialize with Py_tss_NEEDS_INIT. */ -#define Py_tss_NEEDS_INIT {0} diff --git a/python/include/cpython/pytime.h b/python/include/cpython/pytime.h deleted file mode 100644 index 23e0536..0000000 --- a/python/include/cpython/pytime.h +++ /dev/null @@ -1,323 +0,0 @@ -// The _PyTime_t API is written to use timestamp and timeout values stored in -// various formats and to read clocks. -// -// The _PyTime_t type is an integer to support directly common arithmetic -// operations like t1 + t2. -// -// The _PyTime_t API supports a resolution of 1 nanosecond. The _PyTime_t type -// is signed to support negative timestamps. The supported range is around -// [-292.3 years; +292.3 years]. Using the Unix epoch (January 1st, 1970), the -// supported date range is around [1677-09-21; 2262-04-11]. -// -// Formats: -// -// * seconds -// * seconds as a floating pointer number (C double) -// * milliseconds (10^-3 seconds) -// * microseconds (10^-6 seconds) -// * 100 nanoseconds (10^-7 seconds) -// * nanoseconds (10^-9 seconds) -// * timeval structure, 1 microsecond resolution (10^-6 seconds) -// * timespec structure, 1 nanosecond resolution (10^-9 seconds) -// -// Integer overflows are detected and raise OverflowError. Conversion to a -// resolution worse than 1 nanosecond is rounded correctly with the requested -// rounding mode. There are 4 rounding modes: floor (towards -inf), ceiling -// (towards +inf), half even and up (away from zero). -// -// Some functions clamp the result in the range [_PyTime_MIN; _PyTime_MAX], so -// the caller doesn't have to handle errors and doesn't need to hold the GIL. -// For example, _PyTime_Add(t1, t2) computes t1+t2 and clamp the result on -// overflow. -// -// Clocks: -// -// * System clock -// * Monotonic clock -// * Performance counter -// -// Operations like (t * k / q) with integers are implemented in a way to reduce -// the risk of integer overflow. Such operation is used to convert a clock -// value expressed in ticks with a frequency to _PyTime_t, like -// QueryPerformanceCounter() with QueryPerformanceFrequency(). - -#ifndef Py_LIMITED_API -#ifndef Py_PYTIME_H -#define Py_PYTIME_H - -/************************************************************************** -Symbols and macros to supply platform-independent interfaces to time related -functions and constants -**************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -/* _PyTime_t: Python timestamp with subsecond precision. It can be used to - store a duration, and so indirectly a date (related to another date, like - UNIX epoch). */ -typedef int64_t _PyTime_t; -// _PyTime_MIN nanoseconds is around -292.3 years -#define _PyTime_MIN INT64_MIN -// _PyTime_MAX nanoseconds is around +292.3 years -#define _PyTime_MAX INT64_MAX -#define _SIZEOF_PYTIME_T 8 - -typedef enum { - /* Round towards minus infinity (-inf). - For example, used to read a clock. */ - _PyTime_ROUND_FLOOR=0, - /* Round towards infinity (+inf). - For example, used for timeout to wait "at least" N seconds. */ - _PyTime_ROUND_CEILING=1, - /* Round to nearest with ties going to nearest even integer. - For example, used to round from a Python float. */ - _PyTime_ROUND_HALF_EVEN=2, - /* Round away from zero - For example, used for timeout. _PyTime_ROUND_CEILING rounds - -1e-9 to 0 milliseconds which causes bpo-31786 issue. - _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps - the timeout sign as expected. select.poll(timeout) must block - for negative values." */ - _PyTime_ROUND_UP=3, - /* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be - used for timeouts. */ - _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP -} _PyTime_round_t; - - -/* Convert a time_t to a PyLong. */ -PyAPI_FUNC(PyObject *) _PyLong_FromTime_t( - time_t sec); - -/* Convert a PyLong to a time_t. */ -PyAPI_FUNC(time_t) _PyLong_AsTime_t( - PyObject *obj); - -/* Convert a number of seconds, int or float, to time_t. */ -PyAPI_FUNC(int) _PyTime_ObjectToTime_t( - PyObject *obj, - time_t *sec, - _PyTime_round_t); - -/* Convert a number of seconds, int or float, to a timeval structure. - usec is in the range [0; 999999] and rounded towards zero. - For example, -1.2 is converted to (-2, 800000). */ -PyAPI_FUNC(int) _PyTime_ObjectToTimeval( - PyObject *obj, - time_t *sec, - long *usec, - _PyTime_round_t); - -/* Convert a number of seconds, int or float, to a timespec structure. - nsec is in the range [0; 999999999] and rounded towards zero. - For example, -1.2 is converted to (-2, 800000000). */ -PyAPI_FUNC(int) _PyTime_ObjectToTimespec( - PyObject *obj, - time_t *sec, - long *nsec, - _PyTime_round_t); - - -/* Create a timestamp from a number of seconds. */ -PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds); - -/* Macro to create a timestamp from a number of seconds, no integer overflow. - Only use the macro for small values, prefer _PyTime_FromSeconds(). */ -#define _PYTIME_FROMSECONDS(seconds) \ - ((_PyTime_t)(seconds) * (1000 * 1000 * 1000)) - -/* Create a timestamp from a number of nanoseconds. */ -PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns); - -/* Create a timestamp from nanoseconds (Python int). */ -PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t, - PyObject *obj); - -/* Convert a number of seconds (Python float or int) to a timestamp. - Raise an exception and return -1 on error, return 0 on success. */ -PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t, - PyObject *obj, - _PyTime_round_t round); - -/* Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp. - Raise an exception and return -1 on error, return 0 on success. */ -PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t, - PyObject *obj, - _PyTime_round_t round); - -/* Convert a timestamp to a number of seconds as a C double. */ -PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t); - -/* Convert timestamp to a number of milliseconds (10^-3 seconds). */ -PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t, - _PyTime_round_t round); - -/* Convert timestamp to a number of microseconds (10^-6 seconds). */ -PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t, - _PyTime_round_t round); - -/* Convert timestamp to a number of nanoseconds (10^-9 seconds). */ -PyAPI_FUNC(_PyTime_t) _PyTime_AsNanoseconds(_PyTime_t t); - -#ifdef MS_WINDOWS -// Convert timestamp to a number of 100 nanoseconds (10^-7 seconds). -PyAPI_FUNC(_PyTime_t) _PyTime_As100Nanoseconds(_PyTime_t t, - _PyTime_round_t round); -#endif - -/* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int - object. */ -PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t); - -#ifndef MS_WINDOWS -/* Create a timestamp from a timeval structure. - Raise an exception and return -1 on overflow, return 0 on success. */ -PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv); -#endif - -/* Convert a timestamp to a timeval structure (microsecond resolution). - tv_usec is always positive. - Raise an exception and return -1 if the conversion overflowed, - return 0 on success. */ -PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t, - struct timeval *tv, - _PyTime_round_t round); - -/* Similar to _PyTime_AsTimeval() but don't raise an exception on overflow. - On overflow, clamp tv_sec to _PyTime_t min/max. */ -PyAPI_FUNC(void) _PyTime_AsTimeval_clamp(_PyTime_t t, - struct timeval *tv, - _PyTime_round_t round); - -/* Convert a timestamp to a number of seconds (secs) and microseconds (us). - us is always positive. This function is similar to _PyTime_AsTimeval() - except that secs is always a time_t type, whereas the timeval structure - uses a C long for tv_sec on Windows. - Raise an exception and return -1 if the conversion overflowed, - return 0 on success. */ -PyAPI_FUNC(int) _PyTime_AsTimevalTime_t( - _PyTime_t t, - time_t *secs, - int *us, - _PyTime_round_t round); - -#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE) -/* Create a timestamp from a timespec structure. - Raise an exception and return -1 on overflow, return 0 on success. */ -PyAPI_FUNC(int) _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts); - -/* Convert a timestamp to a timespec structure (nanosecond resolution). - tv_nsec is always positive. - Raise an exception and return -1 on error, return 0 on success. */ -PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts); - -/* Similar to _PyTime_AsTimespec() but don't raise an exception on overflow. - On overflow, clamp tv_sec to _PyTime_t min/max. */ -PyAPI_FUNC(void) _PyTime_AsTimespec_clamp(_PyTime_t t, struct timespec *ts); -#endif - - -// Compute t1 + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. -PyAPI_FUNC(_PyTime_t) _PyTime_Add(_PyTime_t t1, _PyTime_t t2); - -/* Compute ticks * mul / div. - Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. - The caller must ensure that ((div - 1) * mul) cannot overflow. */ -PyAPI_FUNC(_PyTime_t) _PyTime_MulDiv(_PyTime_t ticks, - _PyTime_t mul, - _PyTime_t div); - -/* Structure used by time.get_clock_info() */ -typedef struct { - const char *implementation; - int monotonic; - int adjustable; - double resolution; -} _Py_clock_info_t; - -/* Get the current time from the system clock. - - If the internal clock fails, silently ignore the error and return 0. - On integer overflow, silently ignore the overflow and clamp the clock to - [_PyTime_MIN; _PyTime_MAX]. - - Use _PyTime_GetSystemClockWithInfo() to check for failure. */ -PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void); - -/* Get the current time from the system clock. - * On success, set *t and *info (if not NULL), and return 0. - * On error, raise an exception and return -1. - */ -PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo( - _PyTime_t *t, - _Py_clock_info_t *info); - -/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. - The clock is not affected by system clock updates. The reference point of - the returned value is undefined, so that only the difference between the - results of consecutive calls is valid. - - If the internal clock fails, silently ignore the error and return 0. - On integer overflow, silently ignore the overflow and clamp the clock to - [_PyTime_MIN; _PyTime_MAX]. - - Use _PyTime_GetMonotonicClockWithInfo() to check for failure. */ -PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void); - -/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. - The clock is not affected by system clock updates. The reference point of - the returned value is undefined, so that only the difference between the - results of consecutive calls is valid. - - Fill info (if set) with information of the function used to get the time. - - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo( - _PyTime_t *t, - _Py_clock_info_t *info); - - -/* Converts a timestamp to the Gregorian time, using the local time zone. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm); - -/* Converts a timestamp to the Gregorian time, assuming UTC. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm); - -/* Get the performance counter: clock with the highest available resolution to - measure a short duration. - - If the internal clock fails, silently ignore the error and return 0. - On integer overflow, silently ignore the overflow and clamp the clock to - [_PyTime_MIN; _PyTime_MAX]. - - Use _PyTime_GetPerfCounterWithInfo() to check for failure. */ -PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void); - -/* Get the performance counter: clock with the highest available resolution to - measure a short duration. - - Fill info (if set) with information of the function used to get the time. - - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo( - _PyTime_t *t, - _Py_clock_info_t *info); - - -// Create a deadline. -// Pseudo code: _PyTime_GetMonotonicClock() + timeout. -PyAPI_FUNC(_PyTime_t) _PyDeadline_Init(_PyTime_t timeout); - -// Get remaining time from a deadline. -// Pseudo code: deadline - _PyTime_GetMonotonicClock(). -PyAPI_FUNC(_PyTime_t) _PyDeadline_Get(_PyTime_t deadline); - -#ifdef __cplusplus -} -#endif - -#endif /* Py_PYTIME_H */ -#endif /* Py_LIMITED_API */ diff --git a/python/include/cpython/setobject.h b/python/include/cpython/setobject.h deleted file mode 100644 index 380500a..0000000 --- a/python/include/cpython/setobject.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef Py_CPYTHON_SETOBJECT_H -# error "this header file must not be included directly" -#endif - -/* There are three kinds of entries in the table: - -1. Unused: key == NULL and hash == 0 -2. Dummy: key == dummy and hash == -1 -3. Active: key != NULL and key != dummy and hash != -1 - -The hash field of Unused slots is always zero. - -The hash field of Dummy slots are set to -1 -meaning that dummy entries can be detected by -either entry->key==dummy or by entry->hash==-1. -*/ - -#define PySet_MINSIZE 8 - -typedef struct { - PyObject *key; - Py_hash_t hash; /* Cached hash code of the key */ -} setentry; - -/* The SetObject data structure is shared by set and frozenset objects. - -Invariant for sets: - - hash is -1 - -Invariants for frozensets: - - data is immutable. - - hash is the hash of the frozenset or -1 if not computed yet. - -*/ - -typedef struct { - PyObject_HEAD - - Py_ssize_t fill; /* Number active and dummy entries*/ - Py_ssize_t used; /* Number active entries */ - - /* The table contains mask + 1 slots, and that's a power of 2. - * We store the mask instead of the size because the mask is more - * frequently needed. - */ - Py_ssize_t mask; - - /* The table points to a fixed-size smalltable for small tables - * or to additional malloc'ed memory for bigger tables. - * The table pointer is never NULL which saves us from repeated - * runtime null-tests. - */ - setentry *table; - Py_hash_t hash; /* Only used by frozenset objects */ - Py_ssize_t finger; /* Search finger for pop() */ - - setentry smalltable[PySet_MINSIZE]; - PyObject *weakreflist; /* List of weak references */ -} PySetObject; - -#define PySet_GET_SIZE(so) \ - (assert(PyAnySet_Check(so)), (((PySetObject *)(so))->used)) - -PyAPI_DATA(PyObject *) _PySet_Dummy; - -PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); -PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); diff --git a/python/include/cpython/sysmodule.h b/python/include/cpython/sysmodule.h deleted file mode 100644 index 0f84620..0000000 --- a/python/include/cpython/sysmodule.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef Py_CPYTHON_SYSMODULE_H -# error "this header file must not be included directly" -#endif - -PyAPI_FUNC(PyObject *) _PySys_GetAttr(PyThreadState *tstate, - PyObject *name); - -PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); - -typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *); - -PyAPI_FUNC(int) PySys_Audit( - const char *event, - const char *argFormat, - ...); -PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*); diff --git a/python/include/cpython/traceback.h b/python/include/cpython/traceback.h deleted file mode 100644 index a43129b..0000000 --- a/python/include/cpython/traceback.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef Py_CPYTHON_TRACEBACK_H -# error "this header file must not be included directly" -#endif - -typedef struct _traceback PyTracebackObject; - -struct _traceback { - PyObject_HEAD - PyTracebackObject *tb_next; - PyFrameObject *tb_frame; - int tb_lasti; - int tb_lineno; -}; - -PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int, int *, PyObject **); -PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); diff --git a/python/include/cpython/tupleobject.h b/python/include/cpython/tupleobject.h deleted file mode 100644 index 6a6443b..0000000 --- a/python/include/cpython/tupleobject.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef Py_CPYTHON_TUPLEOBJECT_H -# error "this header file must not be included directly" -#endif - -typedef struct { - PyObject_VAR_HEAD - /* ob_item contains space for 'ob_size' elements. - Items must normally not be NULL, except during construction when - the tuple is not yet visible outside the function that builds it. */ - PyObject *ob_item[1]; -} PyTupleObject; - -PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t); -PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); - -/* Cast argument to PyTupleObject* type. */ -#define _PyTuple_CAST(op) \ - (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op))) - -// Macros and static inline functions, trading safety for speed - -static inline Py_ssize_t PyTuple_GET_SIZE(PyObject *op) { - PyTupleObject *tuple = _PyTuple_CAST(op); - return Py_SIZE(tuple); -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op)) -#endif - -#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[index]) - -/* Function *only* to be used to fill in brand new tuples */ -static inline void -PyTuple_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) { - PyTupleObject *tuple = _PyTuple_CAST(op); - tuple->ob_item[index] = value; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -#define PyTuple_SET_ITEM(op, index, value) \ - PyTuple_SET_ITEM(_PyObject_CAST(op), index, _PyObject_CAST(value)) -#endif - -PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out); diff --git a/python/include/cpython/unicodeobject.h b/python/include/cpython/unicodeobject.h deleted file mode 100644 index ff98851..0000000 --- a/python/include/cpython/unicodeobject.h +++ /dev/null @@ -1,1153 +0,0 @@ -#ifndef Py_CPYTHON_UNICODEOBJECT_H -# error "this header file must not be included directly" -#endif - -/* Py_UNICODE was the native Unicode storage format (code unit) used by - Python and represents a single Unicode element in the Unicode type. - With PEP 393, Py_UNICODE is deprecated and replaced with a - typedef to wchar_t. */ -#define PY_UNICODE_TYPE wchar_t -/* Py_DEPRECATED(3.3) */ typedef wchar_t Py_UNICODE; - -/* --- Internal Unicode Operations ---------------------------------------- */ - -#ifndef USE_UNICODE_WCHAR_CACHE -# define USE_UNICODE_WCHAR_CACHE 1 -#endif /* USE_UNICODE_WCHAR_CACHE */ - -/* Since splitting on whitespace is an important use case, and - whitespace in most situations is solely ASCII whitespace, we - optimize for the common case by using a quick look-up table - _Py_ascii_whitespace (see below) with an inlined check. - - */ -#define Py_UNICODE_ISSPACE(ch) \ - ((Py_UCS4)(ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch)) - -#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) -#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) -#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) -#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) - -#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) -#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) -#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) - -#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) -#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) -#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) -#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) - -#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) -#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) -#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) - -#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) - -#define Py_UNICODE_ISALNUM(ch) \ - (Py_UNICODE_ISALPHA(ch) || \ - Py_UNICODE_ISDECIMAL(ch) || \ - Py_UNICODE_ISDIGIT(ch) || \ - Py_UNICODE_ISNUMERIC(ch)) - -/* macros to work with surrogates */ -#define Py_UNICODE_IS_SURROGATE(ch) (0xD800 <= (ch) && (ch) <= 0xDFFF) -#define Py_UNICODE_IS_HIGH_SURROGATE(ch) (0xD800 <= (ch) && (ch) <= 0xDBFF) -#define Py_UNICODE_IS_LOW_SURROGATE(ch) (0xDC00 <= (ch) && (ch) <= 0xDFFF) -/* Join two surrogate characters and return a single Py_UCS4 value. */ -#define Py_UNICODE_JOIN_SURROGATES(high, low) \ - (((((Py_UCS4)(high) & 0x03FF) << 10) | \ - ((Py_UCS4)(low) & 0x03FF)) + 0x10000) -/* high surrogate = top 10 bits added to D800 */ -#define Py_UNICODE_HIGH_SURROGATE(ch) (0xD800 - (0x10000 >> 10) + ((ch) >> 10)) -/* low surrogate = bottom 10 bits added to DC00 */ -#define Py_UNICODE_LOW_SURROGATE(ch) (0xDC00 + ((ch) & 0x3FF)) - -/* --- Unicode Type ------------------------------------------------------- */ - -/* ASCII-only strings created through PyUnicode_New use the PyASCIIObject - structure. state.ascii and state.compact are set, and the data - immediately follow the structure. utf8_length and wstr_length can be found - in the length field; the utf8 pointer is equal to the data pointer. */ -typedef struct { - /* There are 4 forms of Unicode strings: - - - compact ascii: - - * structure = PyASCIIObject - * test: PyUnicode_IS_COMPACT_ASCII(op) - * kind = PyUnicode_1BYTE_KIND - * compact = 1 - * ascii = 1 - * ready = 1 - * (length is the length of the utf8 and wstr strings) - * (data starts just after the structure) - * (since ASCII is decoded from UTF-8, the utf8 string are the data) - - - compact: - - * structure = PyCompactUnicodeObject - * test: PyUnicode_IS_COMPACT(op) && !PyUnicode_IS_ASCII(op) - * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or - PyUnicode_4BYTE_KIND - * compact = 1 - * ready = 1 - * ascii = 0 - * utf8 is not shared with data - * utf8_length = 0 if utf8 is NULL - * wstr is shared with data and wstr_length=length - if kind=PyUnicode_2BYTE_KIND and sizeof(wchar_t)=2 - or if kind=PyUnicode_4BYTE_KIND and sizeof(wchar_t)=4 - * wstr_length = 0 if wstr is NULL - * (data starts just after the structure) - - - legacy string, not ready: - - * structure = PyUnicodeObject - * test: kind == PyUnicode_WCHAR_KIND - * length = 0 (use wstr_length) - * hash = -1 - * kind = PyUnicode_WCHAR_KIND - * compact = 0 - * ascii = 0 - * ready = 0 - * interned = SSTATE_NOT_INTERNED - * wstr is not NULL - * data.any is NULL - * utf8 is NULL - * utf8_length = 0 - - - legacy string, ready: - - * structure = PyUnicodeObject structure - * test: !PyUnicode_IS_COMPACT(op) && kind != PyUnicode_WCHAR_KIND - * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or - PyUnicode_4BYTE_KIND - * compact = 0 - * ready = 1 - * data.any is not NULL - * utf8 is shared and utf8_length = length with data.any if ascii = 1 - * utf8_length = 0 if utf8 is NULL - * wstr is shared with data.any and wstr_length = length - if kind=PyUnicode_2BYTE_KIND and sizeof(wchar_t)=2 - or if kind=PyUnicode_4BYTE_KIND and sizeof(wchar_4)=4 - * wstr_length = 0 if wstr is NULL - - Compact strings use only one memory block (structure + characters), - whereas legacy strings use one block for the structure and one block - for characters. - - Legacy strings are created by PyUnicode_FromUnicode() and - PyUnicode_FromStringAndSize(NULL, size) functions. They become ready - when PyUnicode_READY() is called. - - See also _PyUnicode_CheckConsistency(). - */ - PyObject_HEAD - Py_ssize_t length; /* Number of code points in the string */ - Py_hash_t hash; /* Hash value; -1 if not set */ - struct { - /* - SSTATE_NOT_INTERNED (0) - SSTATE_INTERNED_MORTAL (1) - SSTATE_INTERNED_IMMORTAL (2) - - If interned != SSTATE_NOT_INTERNED, the two references from the - dictionary to this object are *not* counted in ob_refcnt. - */ - unsigned int interned:2; - /* Character size: - - - PyUnicode_WCHAR_KIND (0): - - * character type = wchar_t (16 or 32 bits, depending on the - platform) - - - PyUnicode_1BYTE_KIND (1): - - * character type = Py_UCS1 (8 bits, unsigned) - * all characters are in the range U+0000-U+00FF (latin1) - * if ascii is set, all characters are in the range U+0000-U+007F - (ASCII), otherwise at least one character is in the range - U+0080-U+00FF - - - PyUnicode_2BYTE_KIND (2): - - * character type = Py_UCS2 (16 bits, unsigned) - * all characters are in the range U+0000-U+FFFF (BMP) - * at least one character is in the range U+0100-U+FFFF - - - PyUnicode_4BYTE_KIND (4): - - * character type = Py_UCS4 (32 bits, unsigned) - * all characters are in the range U+0000-U+10FFFF - * at least one character is in the range U+10000-U+10FFFF - */ - unsigned int kind:3; - /* Compact is with respect to the allocation scheme. Compact unicode - objects only require one memory block while non-compact objects use - one block for the PyUnicodeObject struct and another for its data - buffer. */ - unsigned int compact:1; - /* The string only contains characters in the range U+0000-U+007F (ASCII) - and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is - set, use the PyASCIIObject structure. */ - unsigned int ascii:1; - /* The ready flag indicates whether the object layout is initialized - completely. This means that this is either a compact object, or - the data pointer is filled out. The bit is redundant, and helps - to minimize the test in PyUnicode_IS_READY(). */ - unsigned int ready:1; - /* Padding to ensure that PyUnicode_DATA() is always aligned to - 4 bytes (see issue #19537 on m68k). */ - unsigned int :24; - } state; - wchar_t *wstr; /* wchar_t representation (null-terminated) */ -} PyASCIIObject; - -/* Non-ASCII strings allocated through PyUnicode_New use the - PyCompactUnicodeObject structure. state.compact is set, and the data - immediately follow the structure. */ -typedef struct { - PyASCIIObject _base; - Py_ssize_t utf8_length; /* Number of bytes in utf8, excluding the - * terminating \0. */ - char *utf8; /* UTF-8 representation (null-terminated) */ - Py_ssize_t wstr_length; /* Number of code points in wstr, possible - * surrogates count as two code points. */ -} PyCompactUnicodeObject; - -/* Strings allocated through PyUnicode_FromUnicode(NULL, len) use the - PyUnicodeObject structure. The actual string data is initially in the wstr - block, and copied into the data block using _PyUnicode_Ready. */ -typedef struct { - PyCompactUnicodeObject _base; - union { - void *any; - Py_UCS1 *latin1; - Py_UCS2 *ucs2; - Py_UCS4 *ucs4; - } data; /* Canonical, smallest-form Unicode buffer */ -} PyUnicodeObject; - -PyAPI_FUNC(int) _PyUnicode_CheckConsistency( - PyObject *op, - int check_content); - - -#define _PyASCIIObject_CAST(op) \ - (assert(PyUnicode_Check(op)), \ - _Py_CAST(PyASCIIObject*, (op))) -#define _PyCompactUnicodeObject_CAST(op) \ - (assert(PyUnicode_Check(op)), \ - _Py_CAST(PyCompactUnicodeObject*, (op))) -#define _PyUnicodeObject_CAST(op) \ - (assert(PyUnicode_Check(op)), \ - _Py_CAST(PyUnicodeObject*, (op))) - - -/* --- Flexible String Representation Helper Macros (PEP 393) -------------- */ - -/* Values for PyASCIIObject.state: */ - -/* Interning state. */ -#define SSTATE_NOT_INTERNED 0 -#define SSTATE_INTERNED_MORTAL 1 -#define SSTATE_INTERNED_IMMORTAL 2 - -/* Use only if you know it's a string */ -static inline unsigned int PyUnicode_CHECK_INTERNED(PyObject *op) { - return _PyASCIIObject_CAST(op)->state.interned; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_CHECK_INTERNED(op) PyUnicode_CHECK_INTERNED(_PyObject_CAST(op)) -#endif - -/* Fast check to determine whether an object is ready. Equivalent to: - PyUnicode_IS_COMPACT(op) || _PyUnicodeObject_CAST(op)->data.any */ -static inline unsigned int PyUnicode_IS_READY(PyObject *op) { - return _PyASCIIObject_CAST(op)->state.ready; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_IS_READY(op) PyUnicode_IS_READY(_PyObject_CAST(op)) -#endif - -/* Return true if the string contains only ASCII characters, or 0 if not. The - string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be - ready. */ -static inline unsigned int PyUnicode_IS_ASCII(PyObject *op) { - assert(PyUnicode_IS_READY(op)); - return _PyASCIIObject_CAST(op)->state.ascii; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_IS_ASCII(op) PyUnicode_IS_ASCII(_PyObject_CAST(op)) -#endif - -/* Return true if the string is compact or 0 if not. - No type checks or Ready calls are performed. */ -static inline unsigned int PyUnicode_IS_COMPACT(PyObject *op) { - return _PyASCIIObject_CAST(op)->state.compact; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_IS_COMPACT(op) PyUnicode_IS_COMPACT(_PyObject_CAST(op)) -#endif - -/* Return true if the string is a compact ASCII string (use PyASCIIObject - structure), or 0 if not. No type checks or Ready calls are performed. */ -static inline int PyUnicode_IS_COMPACT_ASCII(PyObject *op) { - return (_PyASCIIObject_CAST(op)->state.ascii && PyUnicode_IS_COMPACT(op)); -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_IS_COMPACT_ASCII(op) PyUnicode_IS_COMPACT_ASCII(_PyObject_CAST(op)) -#endif - -enum PyUnicode_Kind { -/* String contains only wstr byte characters. This is only possible - when the string was created with a legacy API and _PyUnicode_Ready() - has not been called yet. */ - PyUnicode_WCHAR_KIND = 0, -/* Return values of the PyUnicode_KIND() function: */ - PyUnicode_1BYTE_KIND = 1, - PyUnicode_2BYTE_KIND = 2, - PyUnicode_4BYTE_KIND = 4 -}; - -/* Return one of the PyUnicode_*_KIND values defined above. */ -#define PyUnicode_KIND(op) \ - (assert(PyUnicode_IS_READY(op)), \ - _PyASCIIObject_CAST(op)->state.kind) - -/* Return a void pointer to the raw unicode buffer. */ -static inline void* _PyUnicode_COMPACT_DATA(PyObject *op) { - if (PyUnicode_IS_ASCII(op)) { - return _Py_STATIC_CAST(void*, (_PyASCIIObject_CAST(op) + 1)); - } - return _Py_STATIC_CAST(void*, (_PyCompactUnicodeObject_CAST(op) + 1)); -} - -static inline void* _PyUnicode_NONCOMPACT_DATA(PyObject *op) { - void *data; - assert(!PyUnicode_IS_COMPACT(op)); - data = _PyUnicodeObject_CAST(op)->data.any; - assert(data != NULL); - return data; -} - -static inline void* PyUnicode_DATA(PyObject *op) { - if (PyUnicode_IS_COMPACT(op)) { - return _PyUnicode_COMPACT_DATA(op); - } - return _PyUnicode_NONCOMPACT_DATA(op); -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_DATA(op) PyUnicode_DATA(_PyObject_CAST(op)) -#endif - -/* Return pointers to the canonical representation cast to unsigned char, - Py_UCS2, or Py_UCS4 for direct character access. - No checks are performed, use PyUnicode_KIND() before to ensure - these will work correctly. */ - -#define PyUnicode_1BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS1*, PyUnicode_DATA(op)) -#define PyUnicode_2BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS2*, PyUnicode_DATA(op)) -#define PyUnicode_4BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS4*, PyUnicode_DATA(op)) - -/* Returns the length of the unicode string. The caller has to make sure that - the string has it's canonical representation set before calling - this function. Call PyUnicode_(FAST_)Ready to ensure that. */ -static inline Py_ssize_t PyUnicode_GET_LENGTH(PyObject *op) { - assert(PyUnicode_IS_READY(op)); - return _PyASCIIObject_CAST(op)->length; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_GET_LENGTH(op) PyUnicode_GET_LENGTH(_PyObject_CAST(op)) -#endif - -/* Write into the canonical representation, this function does not do any sanity - checks and is intended for usage in loops. The caller should cache the - kind and data pointers obtained from other function calls. - index is the index in the string (starts at 0) and value is the new - code point value which should be written to that location. */ -static inline void PyUnicode_WRITE(int kind, void *data, - Py_ssize_t index, Py_UCS4 value) -{ - if (kind == PyUnicode_1BYTE_KIND) { - assert(value <= 0xffU); - _Py_STATIC_CAST(Py_UCS1*, data)[index] = _Py_STATIC_CAST(Py_UCS1, value); - } - else if (kind == PyUnicode_2BYTE_KIND) { - assert(value <= 0xffffU); - _Py_STATIC_CAST(Py_UCS2*, data)[index] = _Py_STATIC_CAST(Py_UCS2, value); - } - else { - assert(kind == PyUnicode_4BYTE_KIND); - assert(value <= 0x10ffffU); - _Py_STATIC_CAST(Py_UCS4*, data)[index] = value; - } -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -#define PyUnicode_WRITE(kind, data, index, value) \ - PyUnicode_WRITE(_Py_STATIC_CAST(int, kind), _Py_CAST(void*, data), \ - (index), _Py_STATIC_CAST(Py_UCS4, value)) -#endif - -/* Read a code point from the string's canonical representation. No checks - or ready calls are performed. */ -static inline Py_UCS4 PyUnicode_READ(int kind, - const void *data, Py_ssize_t index) -{ - if (kind == PyUnicode_1BYTE_KIND) { - return _Py_STATIC_CAST(const Py_UCS1*, data)[index]; - } - if (kind == PyUnicode_2BYTE_KIND) { - return _Py_STATIC_CAST(const Py_UCS2*, data)[index]; - } - assert(kind == PyUnicode_4BYTE_KIND); - return _Py_STATIC_CAST(const Py_UCS4*, data)[index]; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -#define PyUnicode_READ(kind, data, index) \ - PyUnicode_READ(_Py_STATIC_CAST(int, kind), \ - _Py_STATIC_CAST(const void*, data), \ - (index)) -#endif - -/* PyUnicode_READ_CHAR() is less efficient than PyUnicode_READ() because it - calls PyUnicode_KIND() and might call it twice. For single reads, use - PyUnicode_READ_CHAR, for multiple consecutive reads callers should - cache kind and use PyUnicode_READ instead. */ -static inline Py_UCS4 PyUnicode_READ_CHAR(PyObject *unicode, Py_ssize_t index) -{ - int kind; - assert(PyUnicode_IS_READY(unicode)); - kind = PyUnicode_KIND(unicode); - if (kind == PyUnicode_1BYTE_KIND) { - return PyUnicode_1BYTE_DATA(unicode)[index]; - } - if (kind == PyUnicode_2BYTE_KIND) { - return PyUnicode_2BYTE_DATA(unicode)[index]; - } - assert(kind == PyUnicode_4BYTE_KIND); - return PyUnicode_4BYTE_DATA(unicode)[index]; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_READ_CHAR(unicode, index) \ - PyUnicode_READ_CHAR(_PyObject_CAST(unicode), (index)) -#endif - -/* Return a maximum character value which is suitable for creating another - string based on op. This is always an approximation but more efficient - than iterating over the string. */ -static inline Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *op) -{ - int kind; - - assert(PyUnicode_IS_READY(op)); - if (PyUnicode_IS_ASCII(op)) { - return 0x7fU; - } - - kind = PyUnicode_KIND(op); - if (kind == PyUnicode_1BYTE_KIND) { - return 0xffU; - } - if (kind == PyUnicode_2BYTE_KIND) { - return 0xffffU; - } - assert(kind == PyUnicode_4BYTE_KIND); - return 0x10ffffU; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_MAX_CHAR_VALUE(op) \ - PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op)) -#endif - -/* === Public API ========================================================= */ - -/* --- Plain Py_UNICODE --------------------------------------------------- */ - -/* With PEP 393, this is the recommended way to allocate a new unicode object. - This function will allocate the object and its buffer in a single memory - block. Objects created using this function are not resizable. */ -PyAPI_FUNC(PyObject*) PyUnicode_New( - Py_ssize_t size, /* Number of code points in the new string */ - Py_UCS4 maxchar /* maximum code point value in the string */ - ); - -/* Initializes the canonical string representation from the deprecated - wstr/Py_UNICODE representation. This function is used to convert Unicode - objects which were created using the old API to the new flexible format - introduced with PEP 393. - - Don't call this function directly, use the public PyUnicode_READY() function - instead. */ -PyAPI_FUNC(int) _PyUnicode_Ready( - PyObject *unicode /* Unicode object */ - ); - -/* PyUnicode_READY() does less work than _PyUnicode_Ready() in the best - case. If the canonical representation is not yet set, it will still call - _PyUnicode_Ready(). - Returns 0 on success and -1 on errors. */ -static inline int PyUnicode_READY(PyObject *op) -{ - if (PyUnicode_IS_READY(op)) { - return 0; - } - return _PyUnicode_Ready(op); -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_READY(op) PyUnicode_READY(_PyObject_CAST(op)) -#endif - -/* Get a copy of a Unicode string. */ -PyAPI_FUNC(PyObject*) _PyUnicode_Copy( - PyObject *unicode - ); - -/* Copy character from one unicode object into another, this function performs - character conversion when necessary and falls back to memcpy() if possible. - - Fail if to is too small (smaller than *how_many* or smaller than - len(from)-from_start), or if kind(from[from_start:from_start+how_many]) > - kind(to), or if *to* has more than 1 reference. - - Return the number of written character, or return -1 and raise an exception - on error. - - Pseudo-code: - - how_many = min(how_many, len(from) - from_start) - to[to_start:to_start+how_many] = from[from_start:from_start+how_many] - return how_many - - Note: The function doesn't write a terminating null character. - */ -PyAPI_FUNC(Py_ssize_t) PyUnicode_CopyCharacters( - PyObject *to, - Py_ssize_t to_start, - PyObject *from, - Py_ssize_t from_start, - Py_ssize_t how_many - ); - -/* Unsafe version of PyUnicode_CopyCharacters(): don't check arguments and so - may crash if parameters are invalid (e.g. if the output string - is too short). */ -PyAPI_FUNC(void) _PyUnicode_FastCopyCharacters( - PyObject *to, - Py_ssize_t to_start, - PyObject *from, - Py_ssize_t from_start, - Py_ssize_t how_many - ); - -/* Fill a string with a character: write fill_char into - unicode[start:start+length]. - - Fail if fill_char is bigger than the string maximum character, or if the - string has more than 1 reference. - - Return the number of written character, or return -1 and raise an exception - on error. */ -PyAPI_FUNC(Py_ssize_t) PyUnicode_Fill( - PyObject *unicode, - Py_ssize_t start, - Py_ssize_t length, - Py_UCS4 fill_char - ); - -/* Unsafe version of PyUnicode_Fill(): don't check arguments and so may crash - if parameters are invalid (e.g. if length is longer than the string). */ -PyAPI_FUNC(void) _PyUnicode_FastFill( - PyObject *unicode, - Py_ssize_t start, - Py_ssize_t length, - Py_UCS4 fill_char - ); - -/* Create a new string from a buffer of Py_UCS1, Py_UCS2 or Py_UCS4 characters. - Scan the string to find the maximum character. */ -PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData( - int kind, - const void *buffer, - Py_ssize_t size); - -/* Create a new string from a buffer of ASCII characters. - WARNING: Don't check if the string contains any non-ASCII character. */ -PyAPI_FUNC(PyObject*) _PyUnicode_FromASCII( - const char *buffer, - Py_ssize_t size); - -/* Compute the maximum character of the substring unicode[start:end]. - Return 127 for an empty string. */ -PyAPI_FUNC(Py_UCS4) _PyUnicode_FindMaxChar ( - PyObject *unicode, - Py_ssize_t start, - Py_ssize_t end); - -/* --- Legacy deprecated API ---------------------------------------------- */ - -/* Create a Unicode Object from the Py_UNICODE buffer u of the given - size. - - u may be NULL which causes the contents to be undefined. It is the - user's responsibility to fill in the needed data afterwards. Note - that modifying the Unicode object contents after construction is - only allowed if u was set to NULL. - - The buffer is copied into the new object. */ -Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode( - const Py_UNICODE *u, /* Unicode buffer */ - Py_ssize_t size /* size of buffer */ - ); - -/* Return a read-only pointer to the Unicode object's internal - Py_UNICODE buffer. - If the wchar_t/Py_UNICODE representation is not yet available, this - function will calculate it. */ -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( - PyObject *unicode /* Unicode object */ - ); - -/* Similar to PyUnicode_AsUnicode(), but raises a ValueError if the string - contains null characters. */ -PyAPI_FUNC(const Py_UNICODE *) _PyUnicode_AsUnicode( - PyObject *unicode /* Unicode object */ - ); - -/* Return a read-only pointer to the Unicode object's internal - Py_UNICODE buffer and save the length at size. - If the wchar_t/Py_UNICODE representation is not yet available, this - function will calculate it. */ - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicodeAndSize( - PyObject *unicode, /* Unicode object */ - Py_ssize_t *size /* location where to save the length */ - ); - - -/* Fast access macros */ - -Py_DEPRECATED(3.3) -static inline Py_ssize_t PyUnicode_WSTR_LENGTH(PyObject *op) -{ - if (PyUnicode_IS_COMPACT_ASCII(op)) { - return _PyASCIIObject_CAST(op)->length; - } - else { - return _PyCompactUnicodeObject_CAST(op)->wstr_length; - } -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_WSTR_LENGTH(op) PyUnicode_WSTR_LENGTH(_PyObject_CAST(op)) -#endif - -/* Returns the deprecated Py_UNICODE representation's size in code units - (this includes surrogate pairs as 2 units). - If the Py_UNICODE representation is not available, it will be computed - on request. Use PyUnicode_GET_LENGTH() for the length in code points. */ - -Py_DEPRECATED(3.3) -static inline Py_ssize_t PyUnicode_GET_SIZE(PyObject *op) -{ - _Py_COMP_DIAG_PUSH - _Py_COMP_DIAG_IGNORE_DEPR_DECLS - if (_PyASCIIObject_CAST(op)->wstr == _Py_NULL) { - (void)PyUnicode_AsUnicode(op); - assert(_PyASCIIObject_CAST(op)->wstr != _Py_NULL); - } - return PyUnicode_WSTR_LENGTH(op); - _Py_COMP_DIAG_POP -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_GET_SIZE(op) PyUnicode_GET_SIZE(_PyObject_CAST(op)) -#endif - -Py_DEPRECATED(3.3) -static inline Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *op) -{ - _Py_COMP_DIAG_PUSH - _Py_COMP_DIAG_IGNORE_DEPR_DECLS - return PyUnicode_GET_SIZE(op) * Py_UNICODE_SIZE; - _Py_COMP_DIAG_POP -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_GET_DATA_SIZE(op) PyUnicode_GET_DATA_SIZE(_PyObject_CAST(op)) -#endif - -/* Alias for PyUnicode_AsUnicode(). This will create a wchar_t/Py_UNICODE - representation on demand. Using this macro is very inefficient now, - try to port your code to use the new PyUnicode_*BYTE_DATA() macros or - use PyUnicode_WRITE() and PyUnicode_READ(). */ - -Py_DEPRECATED(3.3) -static inline Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *op) -{ - wchar_t *wstr = _PyASCIIObject_CAST(op)->wstr; - if (wstr != _Py_NULL) { - return wstr; - } - - _Py_COMP_DIAG_PUSH - _Py_COMP_DIAG_IGNORE_DEPR_DECLS - return PyUnicode_AsUnicode(op); - _Py_COMP_DIAG_POP -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_AS_UNICODE(op) PyUnicode_AS_UNICODE(_PyObject_CAST(op)) -#endif - -Py_DEPRECATED(3.3) -static inline const char* PyUnicode_AS_DATA(PyObject *op) -{ - _Py_COMP_DIAG_PUSH - _Py_COMP_DIAG_IGNORE_DEPR_DECLS - Py_UNICODE *data = PyUnicode_AS_UNICODE(op); - // In C++, casting directly PyUnicode* to const char* is not valid - return _Py_STATIC_CAST(const char*, _Py_STATIC_CAST(const void*, data)); - _Py_COMP_DIAG_POP -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_AS_DATA(op) PyUnicode_AS_DATA(_PyObject_CAST(op)) -#endif - - -/* --- _PyUnicodeWriter API ----------------------------------------------- */ - -typedef struct { - PyObject *buffer; - void *data; - enum PyUnicode_Kind kind; - Py_UCS4 maxchar; - Py_ssize_t size; - Py_ssize_t pos; - - /* minimum number of allocated characters (default: 0) */ - Py_ssize_t min_length; - - /* minimum character (default: 127, ASCII) */ - Py_UCS4 min_char; - - /* If non-zero, overallocate the buffer (default: 0). */ - unsigned char overallocate; - - /* If readonly is 1, buffer is a shared string (cannot be modified) - and size is set to 0. */ - unsigned char readonly; -} _PyUnicodeWriter ; - -/* Initialize a Unicode writer. - * - * By default, the minimum buffer size is 0 character and overallocation is - * disabled. Set min_length, min_char and overallocate attributes to control - * the allocation of the buffer. */ -PyAPI_FUNC(void) -_PyUnicodeWriter_Init(_PyUnicodeWriter *writer); - -/* Prepare the buffer to write 'length' characters - with the specified maximum character. - - Return 0 on success, raise an exception and return -1 on error. */ -#define _PyUnicodeWriter_Prepare(WRITER, LENGTH, MAXCHAR) \ - (((MAXCHAR) <= (WRITER)->maxchar \ - && (LENGTH) <= (WRITER)->size - (WRITER)->pos) \ - ? 0 \ - : (((LENGTH) == 0) \ - ? 0 \ - : _PyUnicodeWriter_PrepareInternal((WRITER), (LENGTH), (MAXCHAR)))) - -/* Don't call this function directly, use the _PyUnicodeWriter_Prepare() macro - instead. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, - Py_ssize_t length, Py_UCS4 maxchar); - -/* Prepare the buffer to have at least the kind KIND. - For example, kind=PyUnicode_2BYTE_KIND ensures that the writer will - support characters in range U+000-U+FFFF. - - Return 0 on success, raise an exception and return -1 on error. */ -#define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \ - (assert((KIND) != PyUnicode_WCHAR_KIND), \ - (KIND) <= (WRITER)->kind \ - ? 0 \ - : _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND))) - -/* Don't call this function directly, use the _PyUnicodeWriter_PrepareKind() - macro instead. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, - enum PyUnicode_Kind kind); - -/* Append a Unicode character. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, - Py_UCS4 ch - ); - -/* Append a Unicode string. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, - PyObject *str /* Unicode string */ - ); - -/* Append a substring of a Unicode string. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, - PyObject *str, /* Unicode string */ - Py_ssize_t start, - Py_ssize_t end - ); - -/* Append an ASCII-encoded byte string. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, - const char *str, /* ASCII-encoded byte string */ - Py_ssize_t len /* number of bytes, or -1 if unknown */ - ); - -/* Append a latin1-encoded byte string. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer, - const char *str, /* latin1-encoded byte string */ - Py_ssize_t len /* length in bytes */ - ); - -/* Get the value of the writer as a Unicode string. Clear the - buffer of the writer. Raise an exception and return NULL - on error. */ -PyAPI_FUNC(PyObject *) -_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer); - -/* Deallocate memory of a writer (clear its internal buffer). */ -PyAPI_FUNC(void) -_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer); - - -/* Format the object based on the format_spec, as defined in PEP 3101 - (Advanced String Formatting). */ -PyAPI_FUNC(int) _PyUnicode_FormatAdvancedWriter( - _PyUnicodeWriter *writer, - PyObject *obj, - PyObject *format_spec, - Py_ssize_t start, - Py_ssize_t end); - -/* --- Manage the default encoding ---------------------------------------- */ - -/* Returns a pointer to the default encoding (UTF-8) of the - Unicode object unicode. - - Like PyUnicode_AsUTF8AndSize(), this also caches the UTF-8 representation - in the unicodeobject. - - _PyUnicode_AsString is a #define for PyUnicode_AsUTF8 to - support the previous internal function with the same behaviour. - - Use of this API is DEPRECATED since no size information can be - extracted from the returned data. -*/ - -PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode); - -#define _PyUnicode_AsString PyUnicode_AsUTF8 - -/* --- UTF-7 Codecs ------------------------------------------------------- */ - -PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF7( - PyObject *unicode, /* Unicode object */ - int base64SetO, /* Encode RFC2152 Set O characters in base64 */ - int base64WhiteSpace, /* Encode whitespace (sp, ht, nl, cr) in base64 */ - const char *errors /* error handling */ - ); - -/* --- UTF-8 Codecs ------------------------------------------------------- */ - -PyAPI_FUNC(PyObject*) _PyUnicode_AsUTF8String( - PyObject *unicode, - const char *errors); - -/* --- UTF-32 Codecs ------------------------------------------------------ */ - -PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF32( - PyObject *object, /* Unicode object */ - const char *errors, /* error handling */ - int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ - ); - -/* --- UTF-16 Codecs ------------------------------------------------------ */ - -/* Returns a Python string object holding the UTF-16 encoded value of - the Unicode data. - - If byteorder is not 0, output is written according to the following - byte order: - - byteorder == -1: little endian - byteorder == 0: native byte order (writes a BOM mark) - byteorder == 1: big endian - - If byteorder is 0, the output string will always start with the - Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is - prepended. -*/ -PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF16( - PyObject* unicode, /* Unicode object */ - const char *errors, /* error handling */ - int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ - ); - -/* --- Unicode-Escape Codecs ---------------------------------------------- */ - -/* Variant of PyUnicode_DecodeUnicodeEscape that supports partial decoding. */ -PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeStateful( - const char *string, /* Unicode-Escape encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors, /* error handling */ - Py_ssize_t *consumed /* bytes consumed */ -); -/* Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape - chars. */ -PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal( - const char *string, /* Unicode-Escape encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors, /* error handling */ - Py_ssize_t *consumed, /* bytes consumed */ - const char **first_invalid_escape /* on return, points to first - invalid escaped char in - string. */ -); - -/* --- Raw-Unicode-Escape Codecs ---------------------------------------------- */ - -/* Variant of PyUnicode_DecodeRawUnicodeEscape that supports partial decoding. */ -PyAPI_FUNC(PyObject*) _PyUnicode_DecodeRawUnicodeEscapeStateful( - const char *string, /* Unicode-Escape encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors, /* error handling */ - Py_ssize_t *consumed /* bytes consumed */ -); - -/* --- Latin-1 Codecs ----------------------------------------------------- */ - -PyAPI_FUNC(PyObject*) _PyUnicode_AsLatin1String( - PyObject* unicode, - const char* errors); - -/* --- ASCII Codecs ------------------------------------------------------- */ - -PyAPI_FUNC(PyObject*) _PyUnicode_AsASCIIString( - PyObject* unicode, - const char* errors); - -/* --- Character Map Codecs ----------------------------------------------- */ - -/* Translate an Unicode object by applying a character mapping table to - it and return the resulting Unicode object. - - The mapping table must map Unicode ordinal integers to Unicode strings, - Unicode ordinal integers or None (causing deletion of the character). - - Mapping tables may be dictionaries or sequences. Unmapped character - ordinals (ones which cause a LookupError) are left untouched and - are copied as-is. -*/ -PyAPI_FUNC(PyObject*) _PyUnicode_EncodeCharmap( - PyObject *unicode, /* Unicode object */ - PyObject *mapping, /* encoding mapping */ - const char *errors /* error handling */ - ); - -/* --- Decimal Encoder ---------------------------------------------------- */ - -/* Coverts a Unicode object holding a decimal value to an ASCII string - for using in int, float and complex parsers. - Transforms code points that have decimal digit property to the - corresponding ASCII digit code points. Transforms spaces to ASCII. - Transforms code points starting from the first non-ASCII code point that - is neither a decimal digit nor a space to the end into '?'. */ - -PyAPI_FUNC(PyObject*) _PyUnicode_TransformDecimalAndSpaceToASCII( - PyObject *unicode /* Unicode object */ - ); - -/* --- Methods & Slots ---------------------------------------------------- */ - -PyAPI_FUNC(PyObject *) _PyUnicode_JoinArray( - PyObject *separator, - PyObject *const *items, - Py_ssize_t seqlen - ); - -/* Test whether a unicode is equal to ASCII identifier. Return 1 if true, - 0 otherwise. The right argument must be ASCII identifier. - Any error occurs inside will be cleared before return. */ -PyAPI_FUNC(int) _PyUnicode_EqualToASCIIId( - PyObject *left, /* Left string */ - _Py_Identifier *right /* Right identifier */ - ); - -/* Test whether a unicode is equal to ASCII string. Return 1 if true, - 0 otherwise. The right argument must be ASCII-encoded string. - Any error occurs inside will be cleared before return. */ -PyAPI_FUNC(int) _PyUnicode_EqualToASCIIString( - PyObject *left, - const char *right /* ASCII-encoded string */ - ); - -/* Externally visible for str.strip(unicode) */ -PyAPI_FUNC(PyObject *) _PyUnicode_XStrip( - PyObject *self, - int striptype, - PyObject *sepobj - ); - -/* Using explicit passed-in values, insert the thousands grouping - into the string pointed to by buffer. For the argument descriptions, - see Objects/stringlib/localeutil.h */ -PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping( - _PyUnicodeWriter *writer, - Py_ssize_t n_buffer, - PyObject *digits, - Py_ssize_t d_pos, - Py_ssize_t n_digits, - Py_ssize_t min_width, - const char *grouping, - PyObject *thousands_sep, - Py_UCS4 *maxchar); - -/* === Characters Type APIs =============================================== */ - -/* Helper array used by Py_UNICODE_ISSPACE(). */ - -PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[]; - -/* These should not be used directly. Use the Py_UNICODE_IS* and - Py_UNICODE_TO* macros instead. - - These APIs are implemented in Objects/unicodectype.c. - -*/ - -PyAPI_FUNC(int) _PyUnicode_IsLowercase( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsUppercase( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsTitlecase( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsXidStart( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsXidContinue( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsWhitespace( - const Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsLinebreak( - const Py_UCS4 ch /* Unicode character */ - ); - -/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UCS4) _PyUnicode_ToLowercase( - Py_UCS4 ch /* Unicode character */ - ); - -/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UCS4) _PyUnicode_ToUppercase( - Py_UCS4 ch /* Unicode character */ - ); - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UCS4) _PyUnicode_ToTitlecase( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_ToLowerFull( - Py_UCS4 ch, /* Unicode character */ - Py_UCS4 *res - ); - -PyAPI_FUNC(int) _PyUnicode_ToTitleFull( - Py_UCS4 ch, /* Unicode character */ - Py_UCS4 *res - ); - -PyAPI_FUNC(int) _PyUnicode_ToUpperFull( - Py_UCS4 ch, /* Unicode character */ - Py_UCS4 *res - ); - -PyAPI_FUNC(int) _PyUnicode_ToFoldedFull( - Py_UCS4 ch, /* Unicode character */ - Py_UCS4 *res - ); - -PyAPI_FUNC(int) _PyUnicode_IsCaseIgnorable( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsCased( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_ToDecimalDigit( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_ToDigit( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(double) _PyUnicode_ToNumeric( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsDecimalDigit( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsDigit( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsNumeric( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsPrintable( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(int) _PyUnicode_IsAlpha( - Py_UCS4 ch /* Unicode character */ - ); - -PyAPI_FUNC(PyObject*) _PyUnicode_FormatLong(PyObject *, int, int, int); - -/* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/ -PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); - -/* Fast equality check when the inputs are known to be exact unicode types - and where the hash values are equal (i.e. a very probable match) */ -PyAPI_FUNC(int) _PyUnicode_EQ(PyObject *, PyObject *); - -/* Equality check. Returns -1 on failure. */ -PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *, PyObject *); - -PyAPI_FUNC(int) _PyUnicode_WideCharString_Converter(PyObject *, void *); -PyAPI_FUNC(int) _PyUnicode_WideCharString_Opt_Converter(PyObject *, void *); - -PyAPI_FUNC(Py_ssize_t) _PyUnicode_ScanIdentifier(PyObject *); diff --git a/python/include/cpython/warnings.h b/python/include/cpython/warnings.h deleted file mode 100644 index 0e9d4d8..0000000 --- a/python/include/cpython/warnings.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef Py_CPYTHON_WARNINGS_H -# error "this header file must not be included directly" -#endif - -PyAPI_FUNC(int) PyErr_WarnExplicitObject( - PyObject *category, - PyObject *message, - PyObject *filename, - int lineno, - PyObject *module, - PyObject *registry); - -PyAPI_FUNC(int) PyErr_WarnExplicitFormat( - PyObject *category, - const char *filename, int lineno, - const char *module, PyObject *registry, - const char *format, ...); - -// DEPRECATED: Use PyErr_WarnEx() instead. -#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) diff --git a/python/include/cpython/weakrefobject.h b/python/include/cpython/weakrefobject.h deleted file mode 100644 index 1b56d0c..0000000 --- a/python/include/cpython/weakrefobject.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef Py_CPYTHON_WEAKREFOBJECT_H -# error "this header file must not be included directly" -#endif - -/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType, - * and CallableProxyType. - */ -struct _PyWeakReference { - PyObject_HEAD - - /* The object to which this is a weak reference, or Py_None if none. - * Note that this is a stealth reference: wr_object's refcount is - * not incremented to reflect this pointer. - */ - PyObject *wr_object; - - /* A callable to invoke when wr_object dies, or NULL if none. */ - PyObject *wr_callback; - - /* A cache for wr_object's hash code. As usual for hashes, this is -1 - * if the hash code isn't known yet. - */ - Py_hash_t hash; - - /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL- - * terminated list of weak references to it. These are the list pointers. - * If wr_object goes away, wr_object is set to Py_None, and these pointers - * have no meaning then. - */ - PyWeakReference *wr_prev; - PyWeakReference *wr_next; - vectorcallfunc vectorcall; -}; - -PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head); - -PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); - -static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) { - PyWeakReference *ref; - PyObject *obj; - assert(PyWeakref_Check(ref_obj)); - ref = _Py_CAST(PyWeakReference*, ref_obj); - obj = ref->wr_object; - // Explanation for the Py_REFCNT() check: when a weakref's target is part - // of a long chain of deallocations which triggers the trashcan mechanism, - // clearing the weakrefs can be delayed long after the target's refcount - // has dropped to zero. In the meantime, code accessing the weakref will - // be able to "see" the target object even though it is supposed to be - // unreachable. See issue gh-60806. - if (Py_REFCNT(obj) > 0) { - return obj; - } - return Py_None; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyWeakref_GET_OBJECT(ref) PyWeakref_GET_OBJECT(_PyObject_CAST(ref)) -#endif diff --git a/python/include/datetime.h b/python/include/datetime.h deleted file mode 100644 index d4e5c17..0000000 --- a/python/include/datetime.h +++ /dev/null @@ -1,267 +0,0 @@ -/* datetime.h - */ -#ifndef Py_LIMITED_API -#ifndef DATETIME_H -#define DATETIME_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Fields are packed into successive bytes, each viewed as unsigned and - * big-endian, unless otherwise noted: - * - * byte offset - * 0 year 2 bytes, 1-9999 - * 2 month 1 byte, 1-12 - * 3 day 1 byte, 1-31 - * 4 hour 1 byte, 0-23 - * 5 minute 1 byte, 0-59 - * 6 second 1 byte, 0-59 - * 7 usecond 3 bytes, 0-999999 - * 10 - */ - -/* # of bytes for year, month, and day. */ -#define _PyDateTime_DATE_DATASIZE 4 - -/* # of bytes for hour, minute, second, and usecond. */ -#define _PyDateTime_TIME_DATASIZE 6 - -/* # of bytes for year, month, day, hour, minute, second, and usecond. */ -#define _PyDateTime_DATETIME_DATASIZE 10 - - -typedef struct -{ - PyObject_HEAD - Py_hash_t hashcode; /* -1 when unknown */ - int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */ - int seconds; /* 0 <= seconds < 24*3600 is invariant */ - int microseconds; /* 0 <= microseconds < 1000000 is invariant */ -} PyDateTime_Delta; - -typedef struct -{ - PyObject_HEAD /* a pure abstract base class */ -} PyDateTime_TZInfo; - - -/* The datetime and time types have hashcodes, and an optional tzinfo member, - * present if and only if hastzinfo is true. - */ -#define _PyTZINFO_HEAD \ - PyObject_HEAD \ - Py_hash_t hashcode; \ - char hastzinfo; /* boolean flag */ - -/* No _PyDateTime_BaseTZInfo is allocated; it's just to have something - * convenient to cast to, when getting at the hastzinfo member of objects - * starting with _PyTZINFO_HEAD. - */ -typedef struct -{ - _PyTZINFO_HEAD -} _PyDateTime_BaseTZInfo; - -/* All time objects are of PyDateTime_TimeType, but that can be allocated - * in two ways, with or without a tzinfo member. Without is the same as - * tzinfo == None, but consumes less memory. _PyDateTime_BaseTime is an - * internal struct used to allocate the right amount of space for the - * "without" case. - */ -#define _PyDateTime_TIMEHEAD \ - _PyTZINFO_HEAD \ - unsigned char data[_PyDateTime_TIME_DATASIZE]; - -typedef struct -{ - _PyDateTime_TIMEHEAD -} _PyDateTime_BaseTime; /* hastzinfo false */ - -typedef struct -{ - _PyDateTime_TIMEHEAD - unsigned char fold; - PyObject *tzinfo; -} PyDateTime_Time; /* hastzinfo true */ - - -/* All datetime objects are of PyDateTime_DateTimeType, but that can be - * allocated in two ways too, just like for time objects above. In addition, - * the plain date type is a base class for datetime, so it must also have - * a hastzinfo member (although it's unused there). - */ -typedef struct -{ - _PyTZINFO_HEAD - unsigned char data[_PyDateTime_DATE_DATASIZE]; -} PyDateTime_Date; - -#define _PyDateTime_DATETIMEHEAD \ - _PyTZINFO_HEAD \ - unsigned char data[_PyDateTime_DATETIME_DATASIZE]; - -typedef struct -{ - _PyDateTime_DATETIMEHEAD -} _PyDateTime_BaseDateTime; /* hastzinfo false */ - -typedef struct -{ - _PyDateTime_DATETIMEHEAD - unsigned char fold; - PyObject *tzinfo; -} PyDateTime_DateTime; /* hastzinfo true */ - - -/* Apply for date and datetime instances. */ - -// o is a pointer to a time or a datetime object. -#define _PyDateTime_HAS_TZINFO(o) (((_PyDateTime_BaseTZInfo *)(o))->hastzinfo) - -#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \ - ((PyDateTime_Date*)o)->data[1]) -#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2]) -#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)o)->data[3]) - -#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)o)->data[4]) -#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5]) -#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6]) -#define PyDateTime_DATE_GET_MICROSECOND(o) \ - ((((PyDateTime_DateTime*)o)->data[7] << 16) | \ - (((PyDateTime_DateTime*)o)->data[8] << 8) | \ - ((PyDateTime_DateTime*)o)->data[9]) -#define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)o)->fold) -#define PyDateTime_DATE_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \ - ((PyDateTime_DateTime *)(o))->tzinfo : Py_None) - -/* Apply for time instances. */ -#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0]) -#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1]) -#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2]) -#define PyDateTime_TIME_GET_MICROSECOND(o) \ - ((((PyDateTime_Time*)o)->data[3] << 16) | \ - (((PyDateTime_Time*)o)->data[4] << 8) | \ - ((PyDateTime_Time*)o)->data[5]) -#define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)o)->fold) -#define PyDateTime_TIME_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \ - ((PyDateTime_Time *)(o))->tzinfo : Py_None) - -/* Apply for time delta instances */ -#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) -#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) -#define PyDateTime_DELTA_GET_MICROSECONDS(o) \ - (((PyDateTime_Delta*)o)->microseconds) - - -/* Define structure for C API. */ -typedef struct { - /* type objects */ - PyTypeObject *DateType; - PyTypeObject *DateTimeType; - PyTypeObject *TimeType; - PyTypeObject *DeltaType; - PyTypeObject *TZInfoType; - - /* singletons */ - PyObject *TimeZone_UTC; - - /* constructors */ - PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*); - PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, - PyObject*, PyTypeObject*); - PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*); - PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*); - PyObject *(*TimeZone_FromTimeZone)(PyObject *offset, PyObject *name); - - /* constructors for the DB API */ - PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*); - PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*); - - /* PEP 495 constructors */ - PyObject *(*DateTime_FromDateAndTimeAndFold)(int, int, int, int, int, int, int, - PyObject*, int, PyTypeObject*); - PyObject *(*Time_FromTimeAndFold)(int, int, int, int, PyObject*, int, PyTypeObject*); - -} PyDateTime_CAPI; - -#define PyDateTime_CAPSULE_NAME "datetime.datetime_CAPI" - - -/* This block is only used as part of the public API and should not be - * included in _datetimemodule.c, which does not use the C API capsule. - * See bpo-35081 for more details. - * */ -#ifndef _PY_DATETIME_IMPL -/* Define global variable for the C API and a macro for setting it. */ -static PyDateTime_CAPI *PyDateTimeAPI = NULL; - -#define PyDateTime_IMPORT \ - PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0) - -/* Macro for access to the UTC singleton */ -#define PyDateTime_TimeZone_UTC PyDateTimeAPI->TimeZone_UTC - -/* Macros for type checking when not building the Python core. */ -#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) -#define PyDate_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateType) - -#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType) -#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateTimeType) - -#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType) -#define PyTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TimeType) - -#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType) -#define PyDelta_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DeltaType) - -#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType) -#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TZInfoType) - - -/* Macros for accessing constructors in a simplified fashion. */ -#define PyDate_FromDate(year, month, day) \ - PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType) - -#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \ - PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \ - min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType) - -#define PyDateTime_FromDateAndTimeAndFold(year, month, day, hour, min, sec, usec, fold) \ - PyDateTimeAPI->DateTime_FromDateAndTimeAndFold(year, month, day, hour, \ - min, sec, usec, Py_None, fold, PyDateTimeAPI->DateTimeType) - -#define PyTime_FromTime(hour, minute, second, usecond) \ - PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \ - Py_None, PyDateTimeAPI->TimeType) - -#define PyTime_FromTimeAndFold(hour, minute, second, usecond, fold) \ - PyDateTimeAPI->Time_FromTimeAndFold(hour, minute, second, usecond, \ - Py_None, fold, PyDateTimeAPI->TimeType) - -#define PyDelta_FromDSU(days, seconds, useconds) \ - PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \ - PyDateTimeAPI->DeltaType) - -#define PyTimeZone_FromOffset(offset) \ - PyDateTimeAPI->TimeZone_FromTimeZone(offset, NULL) - -#define PyTimeZone_FromOffsetAndName(offset, name) \ - PyDateTimeAPI->TimeZone_FromTimeZone(offset, name) - -/* Macros supporting the DB API. */ -#define PyDateTime_FromTimestamp(args) \ - PyDateTimeAPI->DateTime_FromTimestamp( \ - (PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL) - -#define PyDate_FromTimestamp(args) \ - PyDateTimeAPI->Date_FromTimestamp( \ - (PyObject*) (PyDateTimeAPI->DateType), args) - -#endif /* !defined(_PY_DATETIME_IMPL) */ - -#ifdef __cplusplus -} -#endif -#endif -#endif /* !Py_LIMITED_API */ diff --git a/python/include/descrobject.h b/python/include/descrobject.h deleted file mode 100644 index f4fc9ef..0000000 --- a/python/include/descrobject.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Descriptors */ -#ifndef Py_DESCROBJECT_H -#define Py_DESCROBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -typedef PyObject *(*getter)(PyObject *, void *); -typedef int (*setter)(PyObject *, PyObject *, void *); - -struct PyGetSetDef { - const char *name; - getter get; - setter set; - const char *doc; - void *closure; -}; - -PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type; -PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; -PyAPI_DATA(PyTypeObject) PyMemberDescr_Type; -PyAPI_DATA(PyTypeObject) PyMethodDescr_Type; -PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type; -PyAPI_DATA(PyTypeObject) PyDictProxy_Type; -PyAPI_DATA(PyTypeObject) PyProperty_Type; - -PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); -PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); -PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *, PyMemberDef *); -PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, PyGetSetDef *); - -PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *); -PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_DESCROBJECT_H -# include "cpython/descrobject.h" -# undef Py_CPYTHON_DESCROBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_DESCROBJECT_H */ diff --git a/python/include/dictobject.h b/python/include/dictobject.h deleted file mode 100644 index d755525..0000000 --- a/python/include/dictobject.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef Py_DICTOBJECT_H -#define Py_DICTOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Dictionary object type -- mapping from hashable object to object */ - -/* The distribution includes a separate file, Objects/dictnotes.txt, - describing explorations into dictionary design and optimization. - It covers typical dictionary use patterns, the parameters for - tuning dictionaries, and several ideas for possible optimizations. -*/ - -PyAPI_DATA(PyTypeObject) PyDict_Type; - -#define PyDict_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) -#define PyDict_CheckExact(op) Py_IS_TYPE(op, &PyDict_Type) - -PyAPI_FUNC(PyObject *) PyDict_New(void); -PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); -PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key); -PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item); -PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key); -PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); -PyAPI_FUNC(int) PyDict_Next( - PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value); -PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp); -PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp); -PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp); -PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp); -PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); -PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); - -/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ -PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other); - -/* PyDict_Merge updates/merges from a mapping object (an object that - supports PyMapping_Keys() and PyObject_GetItem()). If override is true, - the last occurrence of a key wins, else the first. The Python - dict.update(other) is equivalent to PyDict_Merge(dict, other, 1). -*/ -PyAPI_FUNC(int) PyDict_Merge(PyObject *mp, - PyObject *other, - int override); - -/* PyDict_MergeFromSeq2 updates/merges from an iterable object producing - iterable objects of length 2. If override is true, the last occurrence - of a key wins, else the first. The Python dict constructor dict(seq2) - is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1). -*/ -PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d, - PyObject *seq2, - int override); - -PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key); -PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item); -PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 -PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *); -#endif - -/* Dictionary (keys, values, items) views */ - -PyAPI_DATA(PyTypeObject) PyDictKeys_Type; -PyAPI_DATA(PyTypeObject) PyDictValues_Type; -PyAPI_DATA(PyTypeObject) PyDictItems_Type; - -#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type) -#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type) -#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type) -/* This excludes Values, since they are not sets. */ -# define PyDictViewSet_Check(op) \ - (PyDictKeys_Check(op) || PyDictItems_Check(op)) - -/* Dictionary (key, value, items) iterators */ - -PyAPI_DATA(PyTypeObject) PyDictIterKey_Type; -PyAPI_DATA(PyTypeObject) PyDictIterValue_Type; -PyAPI_DATA(PyTypeObject) PyDictIterItem_Type; - -PyAPI_DATA(PyTypeObject) PyDictRevIterKey_Type; -PyAPI_DATA(PyTypeObject) PyDictRevIterItem_Type; -PyAPI_DATA(PyTypeObject) PyDictRevIterValue_Type; - - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_DICTOBJECT_H -# include "cpython/dictobject.h" -# undef Py_CPYTHON_DICTOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_DICTOBJECT_H */ diff --git a/python/include/dynamic_annotations.h b/python/include/dynamic_annotations.h deleted file mode 100644 index 3c08818..0000000 --- a/python/include/dynamic_annotations.h +++ /dev/null @@ -1,499 +0,0 @@ -/* Copyright (c) 2008-2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * --- - * Author: Kostya Serebryany - * Copied to CPython by Jeffrey Yasskin, with all macros renamed to - * start with _Py_ to avoid colliding with users embedding Python, and - * with deprecated macros removed. - */ - -/* This file defines dynamic annotations for use with dynamic analysis - tool such as valgrind, PIN, etc. - - Dynamic annotation is a source code annotation that affects - the generated code (that is, the annotation is not a comment). - Each such annotation is attached to a particular - instruction and/or to a particular object (address) in the program. - - The annotations that should be used by users are macros in all upper-case - (e.g., _Py_ANNOTATE_NEW_MEMORY). - - Actual implementation of these macros may differ depending on the - dynamic analysis tool being used. - - See https://code.google.com/p/data-race-test/ for more information. - - This file supports the following dynamic analysis tools: - - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). - Macros are defined empty. - - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1). - Macros are defined as calls to non-inlinable empty functions - that are intercepted by Valgrind. */ - -#ifndef __DYNAMIC_ANNOTATIONS_H__ -#define __DYNAMIC_ANNOTATIONS_H__ - -#ifndef DYNAMIC_ANNOTATIONS_ENABLED -# define DYNAMIC_ANNOTATIONS_ENABLED 0 -#endif - -#if DYNAMIC_ANNOTATIONS_ENABLED != 0 - - /* ------------------------------------------------------------- - Annotations useful when implementing condition variables such as CondVar, - using conditional critical sections (Await/LockWhen) and when constructing - user-defined synchronization mechanisms. - - The annotations _Py_ANNOTATE_HAPPENS_BEFORE() and - _Py_ANNOTATE_HAPPENS_AFTER() can be used to define happens-before arcs in - user-defined synchronization mechanisms: the race detector will infer an - arc from the former to the latter when they share the same argument - pointer. - - Example 1 (reference counting): - - void Unref() { - _Py_ANNOTATE_HAPPENS_BEFORE(&refcount_); - if (AtomicDecrementByOne(&refcount_) == 0) { - _Py_ANNOTATE_HAPPENS_AFTER(&refcount_); - delete this; - } - } - - Example 2 (message queue): - - void MyQueue::Put(Type *e) { - MutexLock lock(&mu_); - _Py_ANNOTATE_HAPPENS_BEFORE(e); - PutElementIntoMyQueue(e); - } - - Type *MyQueue::Get() { - MutexLock lock(&mu_); - Type *e = GetElementFromMyQueue(); - _Py_ANNOTATE_HAPPENS_AFTER(e); - return e; - } - - Note: when possible, please use the existing reference counting and message - queue implementations instead of inventing new ones. */ - - /* Report that wait on the condition variable at address "cv" has succeeded - and the lock at address "lock" is held. */ -#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ - AnnotateCondVarWait(__FILE__, __LINE__, cv, lock) - - /* Report that wait on the condition variable at "cv" has succeeded. Variant - w/o lock. */ -#define _Py_ANNOTATE_CONDVAR_WAIT(cv) \ - AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL) - - /* Report that we are about to signal on the condition variable at address - "cv". */ -#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) \ - AnnotateCondVarSignal(__FILE__, __LINE__, cv) - - /* Report that we are about to signal_all on the condition variable at "cv". */ -#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ - AnnotateCondVarSignalAll(__FILE__, __LINE__, cv) - - /* Annotations for user-defined synchronization mechanisms. */ -#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) _Py_ANNOTATE_CONDVAR_SIGNAL(obj) -#define _Py_ANNOTATE_HAPPENS_AFTER(obj) _Py_ANNOTATE_CONDVAR_WAIT(obj) - - /* Report that the bytes in the range [pointer, pointer+size) are about - to be published safely. The race checker will create a happens-before - arc from the call _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to - subsequent accesses to this memory. - Note: this annotation may not work properly if the race detector uses - sampling, i.e. does not observe all memory accesses. - */ -#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ - AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size) - - /* Instruct the tool to create a happens-before arc between mu->Unlock() and - mu->Lock(). This annotation may slow down the race detector and hide real - races. Normally it is used only when it would be difficult to annotate each - of the mutex's critical sections individually using the annotations above. - This annotation makes sense only for hybrid race detectors. For pure - happens-before detectors this is a no-op. For more details see - https://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ -#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \ - AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) - - /* ------------------------------------------------------------- - Annotations useful when defining memory allocators, or when memory that - was protected in one way starts to be protected in another. */ - - /* Report that a new memory at "address" of size "size" has been allocated. - This might be used when the memory has been retrieved from a free list and - is about to be reused, or when the locking discipline for a variable - changes. */ -#define _Py_ANNOTATE_NEW_MEMORY(address, size) \ - AnnotateNewMemory(__FILE__, __LINE__, address, size) - - /* ------------------------------------------------------------- - Annotations useful when defining FIFO queues that transfer data between - threads. */ - - /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at - address "pcq" has been created. The _Py_ANNOTATE_PCQ_* annotations should - be used only for FIFO queues. For non-FIFO queues use - _Py_ANNOTATE_HAPPENS_BEFORE (for put) and _Py_ANNOTATE_HAPPENS_AFTER (for - get). */ -#define _Py_ANNOTATE_PCQ_CREATE(pcq) \ - AnnotatePCQCreate(__FILE__, __LINE__, pcq) - - /* Report that the queue at address "pcq" is about to be destroyed. */ -#define _Py_ANNOTATE_PCQ_DESTROY(pcq) \ - AnnotatePCQDestroy(__FILE__, __LINE__, pcq) - - /* Report that we are about to put an element into a FIFO queue at address - "pcq". */ -#define _Py_ANNOTATE_PCQ_PUT(pcq) \ - AnnotatePCQPut(__FILE__, __LINE__, pcq) - - /* Report that we've just got an element from a FIFO queue at address "pcq". */ -#define _Py_ANNOTATE_PCQ_GET(pcq) \ - AnnotatePCQGet(__FILE__, __LINE__, pcq) - - /* ------------------------------------------------------------- - Annotations that suppress errors. It is usually better to express the - program's synchronization using the other annotations, but these can - be used when all else fails. */ - - /* Report that we may have a benign race at "pointer", with size - "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the - point where "pointer" has been allocated, preferably close to the point - where the race happens. See also _Py_ANNOTATE_BENIGN_RACE_STATIC. */ -#define _Py_ANNOTATE_BENIGN_RACE(pointer, description) \ - AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ - sizeof(*(pointer)), description) - - /* Same as _Py_ANNOTATE_BENIGN_RACE(address, description), but applies to - the memory range [address, address+size). */ -#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ - AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) - - /* Request the analysis tool to ignore all reads in the current thread - until _Py_ANNOTATE_IGNORE_READS_END is called. - Useful to ignore intentional racey reads, while still checking - other reads and all writes. - See also _Py_ANNOTATE_UNPROTECTED_READ. */ -#define _Py_ANNOTATE_IGNORE_READS_BEGIN() \ - AnnotateIgnoreReadsBegin(__FILE__, __LINE__) - - /* Stop ignoring reads. */ -#define _Py_ANNOTATE_IGNORE_READS_END() \ - AnnotateIgnoreReadsEnd(__FILE__, __LINE__) - - /* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */ -#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() \ - AnnotateIgnoreWritesBegin(__FILE__, __LINE__) - - /* Stop ignoring writes. */ -#define _Py_ANNOTATE_IGNORE_WRITES_END() \ - AnnotateIgnoreWritesEnd(__FILE__, __LINE__) - - /* Start ignoring all memory accesses (reads and writes). */ -#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ - do {\ - _Py_ANNOTATE_IGNORE_READS_BEGIN();\ - _Py_ANNOTATE_IGNORE_WRITES_BEGIN();\ - }while(0)\ - - /* Stop ignoring all memory accesses. */ -#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() \ - do {\ - _Py_ANNOTATE_IGNORE_WRITES_END();\ - _Py_ANNOTATE_IGNORE_READS_END();\ - }while(0)\ - - /* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events: - RWLOCK* and CONDVAR*. */ -#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() \ - AnnotateIgnoreSyncBegin(__FILE__, __LINE__) - - /* Stop ignoring sync events. */ -#define _Py_ANNOTATE_IGNORE_SYNC_END() \ - AnnotateIgnoreSyncEnd(__FILE__, __LINE__) - - - /* Enable (enable!=0) or disable (enable==0) race detection for all threads. - This annotation could be useful if you want to skip expensive race analysis - during some period of program execution, e.g. during initialization. */ -#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) \ - AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) - - /* ------------------------------------------------------------- - Annotations useful for debugging. */ - - /* Request to trace every access to "address". */ -#define _Py_ANNOTATE_TRACE_MEMORY(address) \ - AnnotateTraceMemory(__FILE__, __LINE__, address) - - /* Report the current thread name to a race detector. */ -#define _Py_ANNOTATE_THREAD_NAME(name) \ - AnnotateThreadName(__FILE__, __LINE__, name) - - /* ------------------------------------------------------------- - Annotations useful when implementing locks. They are not - normally needed by modules that merely use locks. - The "lock" argument is a pointer to the lock object. */ - - /* Report that a lock has been created at address "lock". */ -#define _Py_ANNOTATE_RWLOCK_CREATE(lock) \ - AnnotateRWLockCreate(__FILE__, __LINE__, lock) - - /* Report that the lock at address "lock" is about to be destroyed. */ -#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) \ - AnnotateRWLockDestroy(__FILE__, __LINE__, lock) - - /* Report that the lock at address "lock" has been acquired. - is_w=1 for writer lock, is_w=0 for reader lock. */ -#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ - AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) - - /* Report that the lock at address "lock" is about to be released. */ -#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ - AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) - - /* ------------------------------------------------------------- - Annotations useful when implementing barriers. They are not - normally needed by modules that merely use barriers. - The "barrier" argument is a pointer to the barrier object. */ - - /* Report that the "barrier" has been initialized with initial "count". - If 'reinitialization_allowed' is true, initialization is allowed to happen - multiple times w/o calling barrier_destroy() */ -#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \ - AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \ - reinitialization_allowed) - - /* Report that we are about to enter barrier_wait("barrier"). */ -#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \ - AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier) - - /* Report that we just exited barrier_wait("barrier"). */ -#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) \ - AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier) - - /* Report that the "barrier" has been destroyed. */ -#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) \ - AnnotateBarrierDestroy(__FILE__, __LINE__, barrier) - - /* ------------------------------------------------------------- - Annotations useful for testing race detectors. */ - - /* Report that we expect a race on the variable at "address". - Use only in unit tests for a race detector. */ -#define _Py_ANNOTATE_EXPECT_RACE(address, description) \ - AnnotateExpectRace(__FILE__, __LINE__, address, description) - - /* A no-op. Insert where you like to test the interceptors. */ -#define _Py_ANNOTATE_NO_OP(arg) \ - AnnotateNoOp(__FILE__, __LINE__, arg) - - /* Force the race detector to flush its state. The actual effect depends on - * the implementation of the detector. */ -#define _Py_ANNOTATE_FLUSH_STATE() \ - AnnotateFlushState(__FILE__, __LINE__) - - -#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ - -#define _Py_ANNOTATE_RWLOCK_CREATE(lock) /* empty */ -#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ -#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ -#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ -#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */ -#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */ -#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */ -#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) /* empty */ -#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */ -#define _Py_ANNOTATE_CONDVAR_WAIT(cv) /* empty */ -#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */ -#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */ -#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ -#define _Py_ANNOTATE_HAPPENS_AFTER(obj) /* empty */ -#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */ -#define _Py_ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */ -#define _Py_ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */ -#define _Py_ANNOTATE_PCQ_CREATE(pcq) /* empty */ -#define _Py_ANNOTATE_PCQ_DESTROY(pcq) /* empty */ -#define _Py_ANNOTATE_PCQ_PUT(pcq) /* empty */ -#define _Py_ANNOTATE_PCQ_GET(pcq) /* empty */ -#define _Py_ANNOTATE_NEW_MEMORY(address, size) /* empty */ -#define _Py_ANNOTATE_EXPECT_RACE(address, description) /* empty */ -#define _Py_ANNOTATE_BENIGN_RACE(address, description) /* empty */ -#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ -#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ -#define _Py_ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ -#define _Py_ANNOTATE_TRACE_MEMORY(arg) /* empty */ -#define _Py_ANNOTATE_THREAD_NAME(name) /* empty */ -#define _Py_ANNOTATE_IGNORE_READS_BEGIN() /* empty */ -#define _Py_ANNOTATE_IGNORE_READS_END() /* empty */ -#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ -#define _Py_ANNOTATE_IGNORE_WRITES_END() /* empty */ -#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ -#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ -#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */ -#define _Py_ANNOTATE_IGNORE_SYNC_END() /* empty */ -#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ -#define _Py_ANNOTATE_NO_OP(arg) /* empty */ -#define _Py_ANNOTATE_FLUSH_STATE() /* empty */ - -#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ - -/* Use the macros above rather than using these functions directly. */ -#ifdef __cplusplus -extern "C" { -#endif -void AnnotateRWLockCreate(const char *file, int line, - const volatile void *lock); -void AnnotateRWLockDestroy(const char *file, int line, - const volatile void *lock); -void AnnotateRWLockAcquired(const char *file, int line, - const volatile void *lock, long is_w); -void AnnotateRWLockReleased(const char *file, int line, - const volatile void *lock, long is_w); -void AnnotateBarrierInit(const char *file, int line, - const volatile void *barrier, long count, - long reinitialization_allowed); -void AnnotateBarrierWaitBefore(const char *file, int line, - const volatile void *barrier); -void AnnotateBarrierWaitAfter(const char *file, int line, - const volatile void *barrier); -void AnnotateBarrierDestroy(const char *file, int line, - const volatile void *barrier); -void AnnotateCondVarWait(const char *file, int line, - const volatile void *cv, - const volatile void *lock); -void AnnotateCondVarSignal(const char *file, int line, - const volatile void *cv); -void AnnotateCondVarSignalAll(const char *file, int line, - const volatile void *cv); -void AnnotatePublishMemoryRange(const char *file, int line, - const volatile void *address, - long size); -void AnnotateUnpublishMemoryRange(const char *file, int line, - const volatile void *address, - long size); -void AnnotatePCQCreate(const char *file, int line, - const volatile void *pcq); -void AnnotatePCQDestroy(const char *file, int line, - const volatile void *pcq); -void AnnotatePCQPut(const char *file, int line, - const volatile void *pcq); -void AnnotatePCQGet(const char *file, int line, - const volatile void *pcq); -void AnnotateNewMemory(const char *file, int line, - const volatile void *address, - long size); -void AnnotateExpectRace(const char *file, int line, - const volatile void *address, - const char *description); -void AnnotateBenignRace(const char *file, int line, - const volatile void *address, - const char *description); -void AnnotateBenignRaceSized(const char *file, int line, - const volatile void *address, - long size, - const char *description); -void AnnotateMutexIsUsedAsCondVar(const char *file, int line, - const volatile void *mu); -void AnnotateTraceMemory(const char *file, int line, - const volatile void *arg); -void AnnotateThreadName(const char *file, int line, - const char *name); -void AnnotateIgnoreReadsBegin(const char *file, int line); -void AnnotateIgnoreReadsEnd(const char *file, int line); -void AnnotateIgnoreWritesBegin(const char *file, int line); -void AnnotateIgnoreWritesEnd(const char *file, int line); -void AnnotateEnableRaceDetection(const char *file, int line, int enable); -void AnnotateNoOp(const char *file, int line, - const volatile void *arg); -void AnnotateFlushState(const char *file, int line); - -/* Return non-zero value if running under valgrind. - - If "valgrind.h" is included into dynamic_annotations.c, - the regular valgrind mechanism will be used. - See http://valgrind.org/docs/manual/manual-core-adv.html about - RUNNING_ON_VALGRIND and other valgrind "client requests". - The file "valgrind.h" may be obtained by doing - svn co svn://svn.valgrind.org/valgrind/trunk/include - - If for some reason you can't use "valgrind.h" or want to fake valgrind, - there are two ways to make this function return non-zero: - - Use environment variable: export RUNNING_ON_VALGRIND=1 - - Make your tool intercept the function RunningOnValgrind() and - change its return value. - */ -int RunningOnValgrind(void); - -#ifdef __cplusplus -} -#endif - -#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) - - /* _Py_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. - - Instead of doing - _Py_ANNOTATE_IGNORE_READS_BEGIN(); - ... = x; - _Py_ANNOTATE_IGNORE_READS_END(); - one can use - ... = _Py_ANNOTATE_UNPROTECTED_READ(x); */ - template - inline T _Py_ANNOTATE_UNPROTECTED_READ(const volatile T &x) { - _Py_ANNOTATE_IGNORE_READS_BEGIN(); - T res = x; - _Py_ANNOTATE_IGNORE_READS_END(); - return res; - } - /* Apply _Py_ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ -#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ - namespace { \ - class static_var ## _annotator { \ - public: \ - static_var ## _annotator() { \ - _Py_ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ - sizeof(static_var), \ - # static_var ": " description); \ - } \ - }; \ - static static_var ## _annotator the ## static_var ## _annotator;\ - } -#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ - -#define _Py_ANNOTATE_UNPROTECTED_READ(x) (x) -#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ - -#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ - -#endif /* __DYNAMIC_ANNOTATIONS_H__ */ diff --git a/python/include/enumobject.h b/python/include/enumobject.h deleted file mode 100644 index 42dc2d2..0000000 --- a/python/include/enumobject.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef Py_ENUMOBJECT_H -#define Py_ENUMOBJECT_H - -/* Enumerate Object */ - -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_DATA(PyTypeObject) PyEnum_Type; -PyAPI_DATA(PyTypeObject) PyReversed_Type; - -#ifdef __cplusplus -} -#endif - -#endif /* !Py_ENUMOBJECT_H */ diff --git a/python/include/errcode.h b/python/include/errcode.h deleted file mode 100644 index 66ef202..0000000 --- a/python/include/errcode.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef Py_ERRCODE_H -#define Py_ERRCODE_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* Error codes passed around between file input, tokenizer, parser and - interpreter. This is necessary so we can turn them into Python - exceptions at a higher level. Note that some errors have a - slightly different meaning when passed from the tokenizer to the - parser than when passed from the parser to the interpreter; e.g. - the parser only returns E_EOF when it hits EOF immediately, and it - never returns E_OK. */ - -#define E_OK 10 /* No error */ -#define E_EOF 11 /* End Of File */ -#define E_INTR 12 /* Interrupted */ -#define E_TOKEN 13 /* Bad token */ -#define E_SYNTAX 14 /* Syntax error */ -#define E_NOMEM 15 /* Ran out of memory */ -#define E_DONE 16 /* Parsing complete */ -#define E_ERROR 17 /* Execution error */ -#define E_TABSPACE 18 /* Inconsistent mixing of tabs and spaces */ -#define E_OVERFLOW 19 /* Node had too many children */ -#define E_TOODEEP 20 /* Too many indentation levels */ -#define E_DEDENT 21 /* No matching outer block for dedent */ -#define E_DECODE 22 /* Error in decoding into Unicode */ -#define E_EOFS 23 /* EOF in triple-quoted string */ -#define E_EOLS 24 /* EOL in single-quoted string */ -#define E_LINECONT 25 /* Unexpected characters after a line continuation */ -#define E_BADSINGLE 27 /* Ill-formed single statement input */ -#define E_INTERACT_STOP 28 /* Interactive mode stopped tokenization */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_ERRCODE_H */ diff --git a/python/include/exports.h b/python/include/exports.h deleted file mode 100644 index 20a74bb..0000000 --- a/python/include/exports.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef Py_EXPORTS_H -#define Py_EXPORTS_H - -#if defined(_WIN32) || defined(__CYGWIN__) - #define Py_IMPORTED_SYMBOL __declspec(dllimport) - #define Py_EXPORTED_SYMBOL __declspec(dllexport) - #define Py_LOCAL_SYMBOL -#else -/* - * If we only ever used gcc >= 5, we could use __has_attribute(visibility) - * as a cross-platform way to determine if visibility is supported. However, - * we may still need to support gcc >= 4, as some Ubuntu LTS and Centos versions - * have 4 < gcc < 5. - */ - #ifndef __has_attribute - #define __has_attribute(x) 0 // Compatibility with non-clang compilers. - #endif - #if (defined(__GNUC__) && (__GNUC__ >= 4)) ||\ - (defined(__clang__) && __has_attribute(visibility)) - #define Py_IMPORTED_SYMBOL __attribute__ ((visibility ("default"))) - #define Py_EXPORTED_SYMBOL __attribute__ ((visibility ("default"))) - #define Py_LOCAL_SYMBOL __attribute__ ((visibility ("hidden"))) - #else - #define Py_IMPORTED_SYMBOL - #define Py_EXPORTED_SYMBOL - #define Py_LOCAL_SYMBOL - #endif -#endif - -#endif /* Py_EXPORTS_H */ diff --git a/python/include/fileobject.h b/python/include/fileobject.h deleted file mode 100644 index cc880d5..0000000 --- a/python/include/fileobject.h +++ /dev/null @@ -1,49 +0,0 @@ -/* File object interface (what's left of it -- see io.py) */ - -#ifndef Py_FILEOBJECT_H -#define Py_FILEOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#define PY_STDIOTEXTMODE "b" - -PyAPI_FUNC(PyObject *) PyFile_FromFd(int, const char *, const char *, int, - const char *, const char *, - const char *, int); -PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int); -PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int); -PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *); -PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *); - -/* The default encoding used by the platform file system APIs - If non-NULL, this is different than the default encoding for strings -*/ -PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 -PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; -#endif -PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding; - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 -PyAPI_DATA(int) Py_UTF8Mode; -#endif - -/* A routine to check if a file descriptor can be select()-ed. */ -#ifdef _MSC_VER - /* On Windows, any socket fd can be select()-ed, no matter how high */ - #define _PyIsSelectable_fd(FD) (1) -#else - #define _PyIsSelectable_fd(FD) ((unsigned int)(FD) < (unsigned int)FD_SETSIZE) -#endif - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_FILEOBJECT_H -# include "cpython/fileobject.h" -# undef Py_CPYTHON_FILEOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_FILEOBJECT_H */ diff --git a/python/include/fileutils.h b/python/include/fileutils.h deleted file mode 100644 index 3c70e1c..0000000 --- a/python/include/fileutils.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef Py_FILEUTILS_H -#define Py_FILEUTILS_H -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -PyAPI_FUNC(wchar_t *) Py_DecodeLocale( - const char *arg, - size_t *size); - -PyAPI_FUNC(char*) Py_EncodeLocale( - const wchar_t *text, - size_t *error_pos); -#endif - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_FILEUTILS_H -# include "cpython/fileutils.h" -# undef Py_CPYTHON_FILEUTILS_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_FILEUTILS_H */ diff --git a/python/include/floatobject.h b/python/include/floatobject.h deleted file mode 100644 index 08ebb7b..0000000 --- a/python/include/floatobject.h +++ /dev/null @@ -1,54 +0,0 @@ - -/* Float object interface */ - -/* -PyFloatObject represents a (double precision) floating point number. -*/ - -#ifndef Py_FLOATOBJECT_H -#define Py_FLOATOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_DATA(PyTypeObject) PyFloat_Type; - -#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type) -#define PyFloat_CheckExact(op) Py_IS_TYPE(op, &PyFloat_Type) - -#define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN) - -#define Py_RETURN_INF(sign) \ - do { \ - if (copysign(1., sign) == 1.) { \ - return PyFloat_FromDouble(Py_HUGE_VAL); \ - } \ - else { \ - return PyFloat_FromDouble(-Py_HUGE_VAL); \ - } \ - } while(0) - -PyAPI_FUNC(double) PyFloat_GetMax(void); -PyAPI_FUNC(double) PyFloat_GetMin(void); -PyAPI_FUNC(PyObject*) PyFloat_GetInfo(void); - -/* Return Python float from string PyObject. */ -PyAPI_FUNC(PyObject*) PyFloat_FromString(PyObject*); - -/* Return Python float from C double. */ -PyAPI_FUNC(PyObject*) PyFloat_FromDouble(double); - -/* Extract C double from Python float. The macro version trades safety for - speed. */ -PyAPI_FUNC(double) PyFloat_AsDouble(PyObject*); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_FLOATOBJECT_H -# include "cpython/floatobject.h" -# undef Py_CPYTHON_FLOATOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_FLOATOBJECT_H */ diff --git a/python/include/frameobject.h b/python/include/frameobject.h deleted file mode 100644 index ad186c7..0000000 --- a/python/include/frameobject.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Frame object interface */ - -#ifndef Py_FRAMEOBJECT_H -#define Py_FRAMEOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "pyframe.h" - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_FRAMEOBJECT_H -# include "cpython/frameobject.h" -# undef Py_CPYTHON_FRAMEOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_FRAMEOBJECT_H */ diff --git a/python/include/genericaliasobject.h b/python/include/genericaliasobject.h deleted file mode 100644 index 7009609..0000000 --- a/python/include/genericaliasobject.h +++ /dev/null @@ -1,14 +0,0 @@ -// Implementation of PEP 585: support list[int] etc. -#ifndef Py_GENERICALIASOBJECT_H -#define Py_GENERICALIASOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_FUNC(PyObject *) Py_GenericAlias(PyObject *, PyObject *); -PyAPI_DATA(PyTypeObject) Py_GenericAliasType; - -#ifdef __cplusplus -} -#endif -#endif /* !Py_GENERICALIASOBJECT_H */ diff --git a/python/include/import.h b/python/include/import.h deleted file mode 100644 index 5014258..0000000 --- a/python/include/import.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Module definition and import interface */ - -#ifndef Py_IMPORT_H -#define Py_IMPORT_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_FUNC(long) PyImport_GetMagicNumber(void); -PyAPI_FUNC(const char *) PyImport_GetMagicTag(void); -PyAPI_FUNC(PyObject *) PyImport_ExecCodeModule( - const char *name, /* UTF-8 encoded string */ - PyObject *co - ); -PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleEx( - const char *name, /* UTF-8 encoded string */ - PyObject *co, - const char *pathname /* decoded from the filesystem encoding */ - ); -PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleWithPathnames( - const char *name, /* UTF-8 encoded string */ - PyObject *co, - const char *pathname, /* decoded from the filesystem encoding */ - const char *cpathname /* decoded from the filesystem encoding */ - ); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleObject( - PyObject *name, - PyObject *co, - PyObject *pathname, - PyObject *cpathname - ); -#endif -PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 -PyAPI_FUNC(PyObject *) PyImport_GetModule(PyObject *name); -#endif -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject *) PyImport_AddModuleObject( - PyObject *name - ); -#endif -PyAPI_FUNC(PyObject *) PyImport_AddModule( - const char *name /* UTF-8 encoded string */ - ); -PyAPI_FUNC(PyObject *) PyImport_ImportModule( - const char *name /* UTF-8 encoded string */ - ); -PyAPI_FUNC(PyObject *) PyImport_ImportModuleNoBlock( - const char *name /* UTF-8 encoded string */ - ); -PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel( - const char *name, /* UTF-8 encoded string */ - PyObject *globals, - PyObject *locals, - PyObject *fromlist, - int level - ); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevelObject( - PyObject *name, - PyObject *globals, - PyObject *locals, - PyObject *fromlist, - int level - ); -#endif - -#define PyImport_ImportModuleEx(n, g, l, f) \ - PyImport_ImportModuleLevel(n, g, l, f, 0) - -PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path); -PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name); -PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(int) PyImport_ImportFrozenModuleObject( - PyObject *name - ); -#endif -PyAPI_FUNC(int) PyImport_ImportFrozenModule( - const char *name /* UTF-8 encoded string */ - ); - -PyAPI_FUNC(int) PyImport_AppendInittab( - const char *name, /* ASCII encoded string */ - PyObject* (*initfunc)(void) - ); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_IMPORT_H -# include "cpython/import.h" -# undef Py_CPYTHON_IMPORT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_IMPORT_H */ diff --git a/python/include/internal/pycore_abstract.h b/python/include/internal/pycore_abstract.h deleted file mode 100644 index 96e82ef..0000000 --- a/python/include/internal/pycore_abstract.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef Py_INTERNAL_ABSTRACT_H -#define Py_INTERNAL_ABSTRACT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -// Fast inlined version of PyIndex_Check() -static inline int -_PyIndex_Check(PyObject *obj) -{ - PyNumberMethods *tp_as_number = Py_TYPE(obj)->tp_as_number; - return (tp_as_number != NULL && tp_as_number->nb_index != NULL); -} - -PyObject *_PyNumber_PowerNoMod(PyObject *lhs, PyObject *rhs); -PyObject *_PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_ABSTRACT_H */ diff --git a/python/include/internal/pycore_accu.h b/python/include/internal/pycore_accu.h deleted file mode 100644 index 344a9c6..0000000 --- a/python/include/internal/pycore_accu.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_INTERNAL_ACCU_H -#define Py_INTERNAL_ACCU_H -#ifdef __cplusplus -extern "C" { -#endif - -/*** This is a private API for use by the interpreter and the stdlib. - *** Its definition may be changed or removed at any moment. - ***/ - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -/* - * A two-level accumulator of unicode objects that avoids both the overhead - * of keeping a huge number of small separate objects, and the quadratic - * behaviour of using a naive repeated concatenation scheme. - */ - -#undef small /* defined by some Windows headers */ - -typedef struct { - PyObject *large; /* A list of previously accumulated large strings */ - PyObject *small; /* Pending small strings */ -} _PyAccu; - -PyAPI_FUNC(int) _PyAccu_Init(_PyAccu *acc); -PyAPI_FUNC(int) _PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode); -PyAPI_FUNC(PyObject *) _PyAccu_FinishAsList(_PyAccu *acc); -PyAPI_FUNC(PyObject *) _PyAccu_Finish(_PyAccu *acc); -PyAPI_FUNC(void) _PyAccu_Destroy(_PyAccu *acc); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_ACCU_H */ -#endif /* !Py_LIMITED_API */ diff --git a/python/include/internal/pycore_asdl.h b/python/include/internal/pycore_asdl.h deleted file mode 100644 index 3942023..0000000 --- a/python/include/internal/pycore_asdl.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef Py_INTERNAL_ASDL_H -#define Py_INTERNAL_ASDL_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_pyarena.h" // _PyArena_Malloc() - -typedef PyObject * identifier; -typedef PyObject * string; -typedef PyObject * object; -typedef PyObject * constant; - -/* It would be nice if the code generated by asdl_c.py was completely - independent of Python, but it is a goal the requires too much work - at this stage. So, for example, I'll represent identifiers as - interned Python strings. -*/ - -#define _ASDL_SEQ_HEAD \ - Py_ssize_t size; \ - void **elements; - -typedef struct { - _ASDL_SEQ_HEAD -} asdl_seq; - -typedef struct { - _ASDL_SEQ_HEAD - void *typed_elements[1]; -} asdl_generic_seq; - -typedef struct { - _ASDL_SEQ_HEAD - PyObject *typed_elements[1]; -} asdl_identifier_seq; - -typedef struct { - _ASDL_SEQ_HEAD - int typed_elements[1]; -} asdl_int_seq; - -asdl_generic_seq *_Py_asdl_generic_seq_new(Py_ssize_t size, PyArena *arena); -asdl_identifier_seq *_Py_asdl_identifier_seq_new(Py_ssize_t size, PyArena *arena); -asdl_int_seq *_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena); - - -#define GENERATE_ASDL_SEQ_CONSTRUCTOR(NAME, TYPE) \ -asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *arena) \ -{ \ - asdl_ ## NAME ## _seq *seq = NULL; \ - size_t n; \ - /* check size is sane */ \ - if (size < 0 || \ - (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { \ - PyErr_NoMemory(); \ - return NULL; \ - } \ - n = (size ? (sizeof(TYPE *) * (size - 1)) : 0); \ - /* check if size can be added safely */ \ - if (n > SIZE_MAX - sizeof(asdl_ ## NAME ## _seq)) { \ - PyErr_NoMemory(); \ - return NULL; \ - } \ - n += sizeof(asdl_ ## NAME ## _seq); \ - seq = (asdl_ ## NAME ## _seq *)_PyArena_Malloc(arena, n); \ - if (!seq) { \ - PyErr_NoMemory(); \ - return NULL; \ - } \ - memset(seq, 0, n); \ - seq->size = size; \ - seq->elements = (void**)seq->typed_elements; \ - return seq; \ -} - -#define asdl_seq_GET_UNTYPED(S, I) _Py_RVALUE((S)->elements[(I)]) -#define asdl_seq_GET(S, I) _Py_RVALUE((S)->typed_elements[(I)]) -#define asdl_seq_LEN(S) _Py_RVALUE(((S) == NULL ? 0 : (S)->size)) - -#ifdef Py_DEBUG -# define asdl_seq_SET(S, I, V) \ - do { \ - Py_ssize_t _asdl_i = (I); \ - assert((S) != NULL); \ - assert(0 <= _asdl_i && _asdl_i < (S)->size); \ - (S)->typed_elements[_asdl_i] = (V); \ - } while (0) -#else -# define asdl_seq_SET(S, I, V) _Py_RVALUE((S)->typed_elements[I] = (V)) -#endif - -#ifdef Py_DEBUG -# define asdl_seq_SET_UNTYPED(S, I, V) \ - do { \ - Py_ssize_t _asdl_i = (I); \ - assert((S) != NULL); \ - assert(0 <= _asdl_i && _asdl_i < (S)->size); \ - (S)->elements[_asdl_i] = (V); \ - } while (0) -#else -# define asdl_seq_SET_UNTYPED(S, I, V) _Py_RVALUE((S)->elements[I] = (V)) -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_ASDL_H */ diff --git a/python/include/internal/pycore_ast.h b/python/include/internal/pycore_ast.h deleted file mode 100644 index 1e03bf9..0000000 --- a/python/include/internal/pycore_ast.h +++ /dev/null @@ -1,866 +0,0 @@ -// File automatically generated by Parser/asdl_c.py. - -#ifndef Py_INTERNAL_AST_H -#define Py_INTERNAL_AST_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_asdl.h" - -typedef struct _mod *mod_ty; - -typedef struct _stmt *stmt_ty; - -typedef struct _expr *expr_ty; - -typedef enum _expr_context { Load=1, Store=2, Del=3 } expr_context_ty; - -typedef enum _boolop { And=1, Or=2 } boolop_ty; - -typedef enum _operator { Add=1, Sub=2, Mult=3, MatMult=4, Div=5, Mod=6, Pow=7, - LShift=8, RShift=9, BitOr=10, BitXor=11, BitAnd=12, - FloorDiv=13 } operator_ty; - -typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty; - -typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8, - In=9, NotIn=10 } cmpop_ty; - -typedef struct _comprehension *comprehension_ty; - -typedef struct _excepthandler *excepthandler_ty; - -typedef struct _arguments *arguments_ty; - -typedef struct _arg *arg_ty; - -typedef struct _keyword *keyword_ty; - -typedef struct _alias *alias_ty; - -typedef struct _withitem *withitem_ty; - -typedef struct _match_case *match_case_ty; - -typedef struct _pattern *pattern_ty; - -typedef struct _type_ignore *type_ignore_ty; - - -typedef struct { - _ASDL_SEQ_HEAD - mod_ty typed_elements[1]; -} asdl_mod_seq; - -asdl_mod_seq *_Py_asdl_mod_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - stmt_ty typed_elements[1]; -} asdl_stmt_seq; - -asdl_stmt_seq *_Py_asdl_stmt_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - expr_ty typed_elements[1]; -} asdl_expr_seq; - -asdl_expr_seq *_Py_asdl_expr_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - comprehension_ty typed_elements[1]; -} asdl_comprehension_seq; - -asdl_comprehension_seq *_Py_asdl_comprehension_seq_new(Py_ssize_t size, PyArena - *arena); - -typedef struct { - _ASDL_SEQ_HEAD - excepthandler_ty typed_elements[1]; -} asdl_excepthandler_seq; - -asdl_excepthandler_seq *_Py_asdl_excepthandler_seq_new(Py_ssize_t size, PyArena - *arena); - -typedef struct { - _ASDL_SEQ_HEAD - arguments_ty typed_elements[1]; -} asdl_arguments_seq; - -asdl_arguments_seq *_Py_asdl_arguments_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - arg_ty typed_elements[1]; -} asdl_arg_seq; - -asdl_arg_seq *_Py_asdl_arg_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - keyword_ty typed_elements[1]; -} asdl_keyword_seq; - -asdl_keyword_seq *_Py_asdl_keyword_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - alias_ty typed_elements[1]; -} asdl_alias_seq; - -asdl_alias_seq *_Py_asdl_alias_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - withitem_ty typed_elements[1]; -} asdl_withitem_seq; - -asdl_withitem_seq *_Py_asdl_withitem_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - match_case_ty typed_elements[1]; -} asdl_match_case_seq; - -asdl_match_case_seq *_Py_asdl_match_case_seq_new(Py_ssize_t size, PyArena - *arena); - -typedef struct { - _ASDL_SEQ_HEAD - pattern_ty typed_elements[1]; -} asdl_pattern_seq; - -asdl_pattern_seq *_Py_asdl_pattern_seq_new(Py_ssize_t size, PyArena *arena); - -typedef struct { - _ASDL_SEQ_HEAD - type_ignore_ty typed_elements[1]; -} asdl_type_ignore_seq; - -asdl_type_ignore_seq *_Py_asdl_type_ignore_seq_new(Py_ssize_t size, PyArena - *arena); - - -enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3, - FunctionType_kind=4}; -struct _mod { - enum _mod_kind kind; - union { - struct { - asdl_stmt_seq *body; - asdl_type_ignore_seq *type_ignores; - } Module; - - struct { - asdl_stmt_seq *body; - } Interactive; - - struct { - expr_ty body; - } Expression; - - struct { - asdl_expr_seq *argtypes; - expr_ty returns; - } FunctionType; - - } v; -}; - -enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3, - Return_kind=4, Delete_kind=5, Assign_kind=6, - AugAssign_kind=7, AnnAssign_kind=8, For_kind=9, - AsyncFor_kind=10, While_kind=11, If_kind=12, With_kind=13, - AsyncWith_kind=14, Match_kind=15, Raise_kind=16, Try_kind=17, - TryStar_kind=18, Assert_kind=19, Import_kind=20, - ImportFrom_kind=21, Global_kind=22, Nonlocal_kind=23, - Expr_kind=24, Pass_kind=25, Break_kind=26, Continue_kind=27}; -struct _stmt { - enum _stmt_kind kind; - union { - struct { - identifier name; - arguments_ty args; - asdl_stmt_seq *body; - asdl_expr_seq *decorator_list; - expr_ty returns; - string type_comment; - } FunctionDef; - - struct { - identifier name; - arguments_ty args; - asdl_stmt_seq *body; - asdl_expr_seq *decorator_list; - expr_ty returns; - string type_comment; - } AsyncFunctionDef; - - struct { - identifier name; - asdl_expr_seq *bases; - asdl_keyword_seq *keywords; - asdl_stmt_seq *body; - asdl_expr_seq *decorator_list; - } ClassDef; - - struct { - expr_ty value; - } Return; - - struct { - asdl_expr_seq *targets; - } Delete; - - struct { - asdl_expr_seq *targets; - expr_ty value; - string type_comment; - } Assign; - - struct { - expr_ty target; - operator_ty op; - expr_ty value; - } AugAssign; - - struct { - expr_ty target; - expr_ty annotation; - expr_ty value; - int simple; - } AnnAssign; - - struct { - expr_ty target; - expr_ty iter; - asdl_stmt_seq *body; - asdl_stmt_seq *orelse; - string type_comment; - } For; - - struct { - expr_ty target; - expr_ty iter; - asdl_stmt_seq *body; - asdl_stmt_seq *orelse; - string type_comment; - } AsyncFor; - - struct { - expr_ty test; - asdl_stmt_seq *body; - asdl_stmt_seq *orelse; - } While; - - struct { - expr_ty test; - asdl_stmt_seq *body; - asdl_stmt_seq *orelse; - } If; - - struct { - asdl_withitem_seq *items; - asdl_stmt_seq *body; - string type_comment; - } With; - - struct { - asdl_withitem_seq *items; - asdl_stmt_seq *body; - string type_comment; - } AsyncWith; - - struct { - expr_ty subject; - asdl_match_case_seq *cases; - } Match; - - struct { - expr_ty exc; - expr_ty cause; - } Raise; - - struct { - asdl_stmt_seq *body; - asdl_excepthandler_seq *handlers; - asdl_stmt_seq *orelse; - asdl_stmt_seq *finalbody; - } Try; - - struct { - asdl_stmt_seq *body; - asdl_excepthandler_seq *handlers; - asdl_stmt_seq *orelse; - asdl_stmt_seq *finalbody; - } TryStar; - - struct { - expr_ty test; - expr_ty msg; - } Assert; - - struct { - asdl_alias_seq *names; - } Import; - - struct { - identifier module; - asdl_alias_seq *names; - int level; - } ImportFrom; - - struct { - asdl_identifier_seq *names; - } Global; - - struct { - asdl_identifier_seq *names; - } Nonlocal; - - struct { - expr_ty value; - } Expr; - - } v; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -enum _expr_kind {BoolOp_kind=1, NamedExpr_kind=2, BinOp_kind=3, UnaryOp_kind=4, - Lambda_kind=5, IfExp_kind=6, Dict_kind=7, Set_kind=8, - ListComp_kind=9, SetComp_kind=10, DictComp_kind=11, - GeneratorExp_kind=12, Await_kind=13, Yield_kind=14, - YieldFrom_kind=15, Compare_kind=16, Call_kind=17, - FormattedValue_kind=18, JoinedStr_kind=19, Constant_kind=20, - Attribute_kind=21, Subscript_kind=22, Starred_kind=23, - Name_kind=24, List_kind=25, Tuple_kind=26, Slice_kind=27}; -struct _expr { - enum _expr_kind kind; - union { - struct { - boolop_ty op; - asdl_expr_seq *values; - } BoolOp; - - struct { - expr_ty target; - expr_ty value; - } NamedExpr; - - struct { - expr_ty left; - operator_ty op; - expr_ty right; - } BinOp; - - struct { - unaryop_ty op; - expr_ty operand; - } UnaryOp; - - struct { - arguments_ty args; - expr_ty body; - } Lambda; - - struct { - expr_ty test; - expr_ty body; - expr_ty orelse; - } IfExp; - - struct { - asdl_expr_seq *keys; - asdl_expr_seq *values; - } Dict; - - struct { - asdl_expr_seq *elts; - } Set; - - struct { - expr_ty elt; - asdl_comprehension_seq *generators; - } ListComp; - - struct { - expr_ty elt; - asdl_comprehension_seq *generators; - } SetComp; - - struct { - expr_ty key; - expr_ty value; - asdl_comprehension_seq *generators; - } DictComp; - - struct { - expr_ty elt; - asdl_comprehension_seq *generators; - } GeneratorExp; - - struct { - expr_ty value; - } Await; - - struct { - expr_ty value; - } Yield; - - struct { - expr_ty value; - } YieldFrom; - - struct { - expr_ty left; - asdl_int_seq *ops; - asdl_expr_seq *comparators; - } Compare; - - struct { - expr_ty func; - asdl_expr_seq *args; - asdl_keyword_seq *keywords; - } Call; - - struct { - expr_ty value; - int conversion; - expr_ty format_spec; - } FormattedValue; - - struct { - asdl_expr_seq *values; - } JoinedStr; - - struct { - constant value; - string kind; - } Constant; - - struct { - expr_ty value; - identifier attr; - expr_context_ty ctx; - } Attribute; - - struct { - expr_ty value; - expr_ty slice; - expr_context_ty ctx; - } Subscript; - - struct { - expr_ty value; - expr_context_ty ctx; - } Starred; - - struct { - identifier id; - expr_context_ty ctx; - } Name; - - struct { - asdl_expr_seq *elts; - expr_context_ty ctx; - } List; - - struct { - asdl_expr_seq *elts; - expr_context_ty ctx; - } Tuple; - - struct { - expr_ty lower; - expr_ty upper; - expr_ty step; - } Slice; - - } v; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _comprehension { - expr_ty target; - expr_ty iter; - asdl_expr_seq *ifs; - int is_async; -}; - -enum _excepthandler_kind {ExceptHandler_kind=1}; -struct _excepthandler { - enum _excepthandler_kind kind; - union { - struct { - expr_ty type; - identifier name; - asdl_stmt_seq *body; - } ExceptHandler; - - } v; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _arguments { - asdl_arg_seq *posonlyargs; - asdl_arg_seq *args; - arg_ty vararg; - asdl_arg_seq *kwonlyargs; - asdl_expr_seq *kw_defaults; - arg_ty kwarg; - asdl_expr_seq *defaults; -}; - -struct _arg { - identifier arg; - expr_ty annotation; - string type_comment; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _keyword { - identifier arg; - expr_ty value; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _alias { - identifier name; - identifier asname; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -struct _withitem { - expr_ty context_expr; - expr_ty optional_vars; -}; - -struct _match_case { - pattern_ty pattern; - expr_ty guard; - asdl_stmt_seq *body; -}; - -enum _pattern_kind {MatchValue_kind=1, MatchSingleton_kind=2, - MatchSequence_kind=3, MatchMapping_kind=4, - MatchClass_kind=5, MatchStar_kind=6, MatchAs_kind=7, - MatchOr_kind=8}; -struct _pattern { - enum _pattern_kind kind; - union { - struct { - expr_ty value; - } MatchValue; - - struct { - constant value; - } MatchSingleton; - - struct { - asdl_pattern_seq *patterns; - } MatchSequence; - - struct { - asdl_expr_seq *keys; - asdl_pattern_seq *patterns; - identifier rest; - } MatchMapping; - - struct { - expr_ty cls; - asdl_pattern_seq *patterns; - asdl_identifier_seq *kwd_attrs; - asdl_pattern_seq *kwd_patterns; - } MatchClass; - - struct { - identifier name; - } MatchStar; - - struct { - pattern_ty pattern; - identifier name; - } MatchAs; - - struct { - asdl_pattern_seq *patterns; - } MatchOr; - - } v; - int lineno; - int col_offset; - int end_lineno; - int end_col_offset; -}; - -enum _type_ignore_kind {TypeIgnore_kind=1}; -struct _type_ignore { - enum _type_ignore_kind kind; - union { - struct { - int lineno; - string tag; - } TypeIgnore; - - } v; -}; - - -// Note: these macros affect function definitions, not only call sites. -mod_ty _PyAST_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores, - PyArena *arena); -mod_ty _PyAST_Interactive(asdl_stmt_seq * body, PyArena *arena); -mod_ty _PyAST_Expression(expr_ty body, PyArena *arena); -mod_ty _PyAST_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena - *arena); -stmt_ty _PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * - body, asdl_expr_seq * decorator_list, expr_ty - returns, string type_comment, int lineno, int - col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -stmt_ty _PyAST_AsyncFunctionDef(identifier name, arguments_ty args, - asdl_stmt_seq * body, asdl_expr_seq * - decorator_list, expr_ty returns, string - type_comment, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -stmt_ty _PyAST_ClassDef(identifier name, asdl_expr_seq * bases, - asdl_keyword_seq * keywords, asdl_stmt_seq * body, - asdl_expr_seq * decorator_list, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -stmt_ty _PyAST_Return(expr_ty value, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -stmt_ty _PyAST_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -stmt_ty _PyAST_Assign(asdl_expr_seq * targets, expr_ty value, string - type_comment, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -stmt_ty _PyAST_AugAssign(expr_ty target, operator_ty op, expr_ty value, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -stmt_ty _PyAST_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int - simple, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -stmt_ty _PyAST_For(expr_ty target, expr_ty iter, asdl_stmt_seq * body, - asdl_stmt_seq * orelse, string type_comment, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -stmt_ty _PyAST_AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body, - asdl_stmt_seq * orelse, string type_comment, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -stmt_ty _PyAST_While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * - orelse, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -stmt_ty _PyAST_If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -stmt_ty _PyAST_With(asdl_withitem_seq * items, asdl_stmt_seq * body, string - type_comment, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -stmt_ty _PyAST_AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body, - string type_comment, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -stmt_ty _PyAST_Match(expr_ty subject, asdl_match_case_seq * cases, int lineno, - int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -stmt_ty _PyAST_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -stmt_ty _PyAST_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, - asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -stmt_ty _PyAST_TryStar(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, - asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -stmt_ty _PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -stmt_ty _PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -stmt_ty _PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -stmt_ty _PyAST_Global(asdl_identifier_seq * names, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -stmt_ty _PyAST_Nonlocal(asdl_identifier_seq * names, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -stmt_ty _PyAST_Expr(expr_ty value, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -stmt_ty _PyAST_Pass(int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -stmt_ty _PyAST_Break(int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -stmt_ty _PyAST_Continue(int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -expr_ty _PyAST_BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -expr_ty _PyAST_NamedExpr(expr_ty target, expr_ty value, int lineno, int - col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -expr_ty _PyAST_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, - int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -expr_ty _PyAST_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -expr_ty _PyAST_Lambda(arguments_ty args, expr_ty body, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -expr_ty _PyAST_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, - int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -expr_ty _PyAST_Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno, - int col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -expr_ty _PyAST_Set(asdl_expr_seq * elts, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -expr_ty _PyAST_ListComp(expr_ty elt, asdl_comprehension_seq * generators, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -expr_ty _PyAST_SetComp(expr_ty elt, asdl_comprehension_seq * generators, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -expr_ty _PyAST_DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq * - generators, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -expr_ty _PyAST_GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -expr_ty _PyAST_Await(expr_ty value, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -expr_ty _PyAST_Yield(expr_ty value, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -expr_ty _PyAST_YieldFrom(expr_ty value, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -expr_ty _PyAST_Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq * - comparators, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena); -expr_ty _PyAST_Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq * - keywords, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -expr_ty _PyAST_FormattedValue(expr_ty value, int conversion, expr_ty - format_spec, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -expr_ty _PyAST_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena *arena); -expr_ty _PyAST_Constant(constant value, string kind, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -expr_ty _PyAST_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, - int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -expr_ty _PyAST_Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int - lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -expr_ty _PyAST_Starred(expr_ty value, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -expr_ty _PyAST_Name(identifier id, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -expr_ty _PyAST_List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -expr_ty _PyAST_Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -expr_ty _PyAST_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, - int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -comprehension_ty _PyAST_comprehension(expr_ty target, expr_ty iter, - asdl_expr_seq * ifs, int is_async, - PyArena *arena); -excepthandler_ty _PyAST_ExceptHandler(expr_ty type, identifier name, - asdl_stmt_seq * body, int lineno, int - col_offset, int end_lineno, int - end_col_offset, PyArena *arena); -arguments_ty _PyAST_arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args, - arg_ty vararg, asdl_arg_seq * kwonlyargs, - asdl_expr_seq * kw_defaults, arg_ty kwarg, - asdl_expr_seq * defaults, PyArena *arena); -arg_ty _PyAST_arg(identifier arg, expr_ty annotation, string type_comment, int - lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -keyword_ty _PyAST_keyword(identifier arg, expr_ty value, int lineno, int - col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -alias_ty _PyAST_alias(identifier name, identifier asname, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); -withitem_ty _PyAST_withitem(expr_ty context_expr, expr_ty optional_vars, - PyArena *arena); -match_case_ty _PyAST_match_case(pattern_ty pattern, expr_ty guard, - asdl_stmt_seq * body, PyArena *arena); -pattern_ty _PyAST_MatchValue(expr_ty value, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -pattern_ty _PyAST_MatchSingleton(constant value, int lineno, int col_offset, - int end_lineno, int end_col_offset, PyArena - *arena); -pattern_ty _PyAST_MatchSequence(asdl_pattern_seq * patterns, int lineno, int - col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -pattern_ty _PyAST_MatchMapping(asdl_expr_seq * keys, asdl_pattern_seq * - patterns, identifier rest, int lineno, int - col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -pattern_ty _PyAST_MatchClass(expr_ty cls, asdl_pattern_seq * patterns, - asdl_identifier_seq * kwd_attrs, asdl_pattern_seq - * kwd_patterns, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -pattern_ty _PyAST_MatchStar(identifier name, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); -pattern_ty _PyAST_MatchAs(pattern_ty pattern, identifier name, int lineno, int - col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -pattern_ty _PyAST_MatchOr(asdl_pattern_seq * patterns, int lineno, int - col_offset, int end_lineno, int end_col_offset, - PyArena *arena); -type_ignore_ty _PyAST_TypeIgnore(int lineno, string tag, PyArena *arena); - - -PyObject* PyAST_mod2obj(mod_ty t); -mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode); -int PyAST_Check(PyObject* obj); - -extern int _PyAST_Validate(mod_ty); - -/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */ -extern PyObject* _PyAST_ExprAsUnicode(expr_ty); - -/* Return the borrowed reference to the first literal string in the - sequence of statements or NULL if it doesn't start from a literal string. - Doesn't set exception. */ -extern PyObject* _PyAST_GetDocString(asdl_stmt_seq *); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_AST_H */ diff --git a/python/include/internal/pycore_ast_state.h b/python/include/internal/pycore_ast_state.h deleted file mode 100644 index 7ec15d8..0000000 --- a/python/include/internal/pycore_ast_state.h +++ /dev/null @@ -1,258 +0,0 @@ -// File automatically generated by Parser/asdl_c.py. - -#ifndef Py_INTERNAL_AST_STATE_H -#define Py_INTERNAL_AST_STATE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -struct ast_state { - int initialized; - int recursion_depth; - int recursion_limit; - PyObject *AST_type; - PyObject *Add_singleton; - PyObject *Add_type; - PyObject *And_singleton; - PyObject *And_type; - PyObject *AnnAssign_type; - PyObject *Assert_type; - PyObject *Assign_type; - PyObject *AsyncFor_type; - PyObject *AsyncFunctionDef_type; - PyObject *AsyncWith_type; - PyObject *Attribute_type; - PyObject *AugAssign_type; - PyObject *Await_type; - PyObject *BinOp_type; - PyObject *BitAnd_singleton; - PyObject *BitAnd_type; - PyObject *BitOr_singleton; - PyObject *BitOr_type; - PyObject *BitXor_singleton; - PyObject *BitXor_type; - PyObject *BoolOp_type; - PyObject *Break_type; - PyObject *Call_type; - PyObject *ClassDef_type; - PyObject *Compare_type; - PyObject *Constant_type; - PyObject *Continue_type; - PyObject *Del_singleton; - PyObject *Del_type; - PyObject *Delete_type; - PyObject *DictComp_type; - PyObject *Dict_type; - PyObject *Div_singleton; - PyObject *Div_type; - PyObject *Eq_singleton; - PyObject *Eq_type; - PyObject *ExceptHandler_type; - PyObject *Expr_type; - PyObject *Expression_type; - PyObject *FloorDiv_singleton; - PyObject *FloorDiv_type; - PyObject *For_type; - PyObject *FormattedValue_type; - PyObject *FunctionDef_type; - PyObject *FunctionType_type; - PyObject *GeneratorExp_type; - PyObject *Global_type; - PyObject *GtE_singleton; - PyObject *GtE_type; - PyObject *Gt_singleton; - PyObject *Gt_type; - PyObject *IfExp_type; - PyObject *If_type; - PyObject *ImportFrom_type; - PyObject *Import_type; - PyObject *In_singleton; - PyObject *In_type; - PyObject *Interactive_type; - PyObject *Invert_singleton; - PyObject *Invert_type; - PyObject *IsNot_singleton; - PyObject *IsNot_type; - PyObject *Is_singleton; - PyObject *Is_type; - PyObject *JoinedStr_type; - PyObject *LShift_singleton; - PyObject *LShift_type; - PyObject *Lambda_type; - PyObject *ListComp_type; - PyObject *List_type; - PyObject *Load_singleton; - PyObject *Load_type; - PyObject *LtE_singleton; - PyObject *LtE_type; - PyObject *Lt_singleton; - PyObject *Lt_type; - PyObject *MatMult_singleton; - PyObject *MatMult_type; - PyObject *MatchAs_type; - PyObject *MatchClass_type; - PyObject *MatchMapping_type; - PyObject *MatchOr_type; - PyObject *MatchSequence_type; - PyObject *MatchSingleton_type; - PyObject *MatchStar_type; - PyObject *MatchValue_type; - PyObject *Match_type; - PyObject *Mod_singleton; - PyObject *Mod_type; - PyObject *Module_type; - PyObject *Mult_singleton; - PyObject *Mult_type; - PyObject *Name_type; - PyObject *NamedExpr_type; - PyObject *Nonlocal_type; - PyObject *NotEq_singleton; - PyObject *NotEq_type; - PyObject *NotIn_singleton; - PyObject *NotIn_type; - PyObject *Not_singleton; - PyObject *Not_type; - PyObject *Or_singleton; - PyObject *Or_type; - PyObject *Pass_type; - PyObject *Pow_singleton; - PyObject *Pow_type; - PyObject *RShift_singleton; - PyObject *RShift_type; - PyObject *Raise_type; - PyObject *Return_type; - PyObject *SetComp_type; - PyObject *Set_type; - PyObject *Slice_type; - PyObject *Starred_type; - PyObject *Store_singleton; - PyObject *Store_type; - PyObject *Sub_singleton; - PyObject *Sub_type; - PyObject *Subscript_type; - PyObject *TryStar_type; - PyObject *Try_type; - PyObject *Tuple_type; - PyObject *TypeIgnore_type; - PyObject *UAdd_singleton; - PyObject *UAdd_type; - PyObject *USub_singleton; - PyObject *USub_type; - PyObject *UnaryOp_type; - PyObject *While_type; - PyObject *With_type; - PyObject *YieldFrom_type; - PyObject *Yield_type; - PyObject *__dict__; - PyObject *__doc__; - PyObject *__match_args__; - PyObject *__module__; - PyObject *_attributes; - PyObject *_fields; - PyObject *alias_type; - PyObject *annotation; - PyObject *arg; - PyObject *arg_type; - PyObject *args; - PyObject *argtypes; - PyObject *arguments_type; - PyObject *asname; - PyObject *ast; - PyObject *attr; - PyObject *bases; - PyObject *body; - PyObject *boolop_type; - PyObject *cases; - PyObject *cause; - PyObject *cls; - PyObject *cmpop_type; - PyObject *col_offset; - PyObject *comparators; - PyObject *comprehension_type; - PyObject *context_expr; - PyObject *conversion; - PyObject *ctx; - PyObject *decorator_list; - PyObject *defaults; - PyObject *elt; - PyObject *elts; - PyObject *end_col_offset; - PyObject *end_lineno; - PyObject *exc; - PyObject *excepthandler_type; - PyObject *expr_context_type; - PyObject *expr_type; - PyObject *finalbody; - PyObject *format_spec; - PyObject *func; - PyObject *generators; - PyObject *guard; - PyObject *handlers; - PyObject *id; - PyObject *ifs; - PyObject *is_async; - PyObject *items; - PyObject *iter; - PyObject *key; - PyObject *keys; - PyObject *keyword_type; - PyObject *keywords; - PyObject *kind; - PyObject *kw_defaults; - PyObject *kwarg; - PyObject *kwd_attrs; - PyObject *kwd_patterns; - PyObject *kwonlyargs; - PyObject *left; - PyObject *level; - PyObject *lineno; - PyObject *lower; - PyObject *match_case_type; - PyObject *mod_type; - PyObject *module; - PyObject *msg; - PyObject *name; - PyObject *names; - PyObject *op; - PyObject *operand; - PyObject *operator_type; - PyObject *ops; - PyObject *optional_vars; - PyObject *orelse; - PyObject *pattern; - PyObject *pattern_type; - PyObject *patterns; - PyObject *posonlyargs; - PyObject *rest; - PyObject *returns; - PyObject *right; - PyObject *simple; - PyObject *slice; - PyObject *step; - PyObject *stmt_type; - PyObject *subject; - PyObject *tag; - PyObject *target; - PyObject *targets; - PyObject *test; - PyObject *type; - PyObject *type_comment; - PyObject *type_ignore_type; - PyObject *type_ignores; - PyObject *unaryop_type; - PyObject *upper; - PyObject *value; - PyObject *values; - PyObject *vararg; - PyObject *withitem_type; -}; - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_AST_STATE_H */ - diff --git a/python/include/internal/pycore_atomic.h b/python/include/internal/pycore_atomic.h deleted file mode 100644 index 34536f5..0000000 --- a/python/include/internal/pycore_atomic.h +++ /dev/null @@ -1,557 +0,0 @@ -#ifndef Py_ATOMIC_H -#define Py_ATOMIC_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "dynamic_annotations.h" /* _Py_ANNOTATE_MEMORY_ORDER */ -#include "pyconfig.h" - -#ifdef HAVE_STD_ATOMIC -# include -#endif - - -#if defined(_MSC_VER) -#include -#if defined(_M_IX86) || defined(_M_X64) -# include -#endif -#endif - -/* This is modeled after the atomics interface from C1x, according to - * the draft at - * http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1425.pdf. - * Operations and types are named the same except with a _Py_ prefix - * and have the same semantics. - * - * Beware, the implementations here are deep magic. - */ - -#if defined(HAVE_STD_ATOMIC) - -typedef enum _Py_memory_order { - _Py_memory_order_relaxed = memory_order_relaxed, - _Py_memory_order_acquire = memory_order_acquire, - _Py_memory_order_release = memory_order_release, - _Py_memory_order_acq_rel = memory_order_acq_rel, - _Py_memory_order_seq_cst = memory_order_seq_cst -} _Py_memory_order; - -typedef struct _Py_atomic_address { - atomic_uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - atomic_int _value; -} _Py_atomic_int; - -#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ - atomic_signal_fence(ORDER) - -#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ - atomic_thread_fence(ORDER) - -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - atomic_store_explicit(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER) - -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - atomic_load_explicit(&((ATOMIC_VAL)->_value), ORDER) - -// Use builtin atomic operations in GCC >= 4.7 and clang -#elif defined(HAVE_BUILTIN_ATOMIC) - -typedef enum _Py_memory_order { - _Py_memory_order_relaxed = __ATOMIC_RELAXED, - _Py_memory_order_acquire = __ATOMIC_ACQUIRE, - _Py_memory_order_release = __ATOMIC_RELEASE, - _Py_memory_order_acq_rel = __ATOMIC_ACQ_REL, - _Py_memory_order_seq_cst = __ATOMIC_SEQ_CST -} _Py_memory_order; - -typedef struct _Py_atomic_address { - uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - int _value; -} _Py_atomic_int; - -#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ - __atomic_signal_fence(ORDER) - -#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ - __atomic_thread_fence(ORDER) - -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - (assert((ORDER) == __ATOMIC_RELAXED \ - || (ORDER) == __ATOMIC_SEQ_CST \ - || (ORDER) == __ATOMIC_RELEASE), \ - __atomic_store_n(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER)) - -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - (assert((ORDER) == __ATOMIC_RELAXED \ - || (ORDER) == __ATOMIC_SEQ_CST \ - || (ORDER) == __ATOMIC_ACQUIRE \ - || (ORDER) == __ATOMIC_CONSUME), \ - __atomic_load_n(&((ATOMIC_VAL)->_value), ORDER)) - -/* Only support GCC (for expression statements) and x86 (for simple - * atomic semantics) and MSVC x86/x64/ARM */ -#elif defined(__GNUC__) && (defined(__i386__) || defined(__amd64)) -typedef enum _Py_memory_order { - _Py_memory_order_relaxed, - _Py_memory_order_acquire, - _Py_memory_order_release, - _Py_memory_order_acq_rel, - _Py_memory_order_seq_cst -} _Py_memory_order; - -typedef struct _Py_atomic_address { - uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - int _value; -} _Py_atomic_int; - - -static __inline__ void -_Py_atomic_signal_fence(_Py_memory_order order) -{ - if (order != _Py_memory_order_relaxed) - __asm__ volatile("":::"memory"); -} - -static __inline__ void -_Py_atomic_thread_fence(_Py_memory_order order) -{ - if (order != _Py_memory_order_relaxed) - __asm__ volatile("mfence":::"memory"); -} - -/* Tell the race checker about this operation's effects. */ -static __inline__ void -_Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) -{ - (void)address; /* shut up -Wunused-parameter */ - switch(order) { - case _Py_memory_order_release: - case _Py_memory_order_acq_rel: - case _Py_memory_order_seq_cst: - _Py_ANNOTATE_HAPPENS_BEFORE(address); - break; - case _Py_memory_order_relaxed: - case _Py_memory_order_acquire: - break; - } - switch(order) { - case _Py_memory_order_acquire: - case _Py_memory_order_acq_rel: - case _Py_memory_order_seq_cst: - _Py_ANNOTATE_HAPPENS_AFTER(address); - break; - case _Py_memory_order_relaxed: - case _Py_memory_order_release: - break; - } -} - -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - __extension__ ({ \ - __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \ - __typeof__(atomic_val->_value) new_val = NEW_VAL;\ - volatile __typeof__(new_val) *volatile_data = &atomic_val->_value; \ - _Py_memory_order order = ORDER; \ - _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \ - \ - /* Perform the operation. */ \ - _Py_ANNOTATE_IGNORE_WRITES_BEGIN(); \ - switch(order) { \ - case _Py_memory_order_release: \ - _Py_atomic_signal_fence(_Py_memory_order_release); \ - /* fallthrough */ \ - case _Py_memory_order_relaxed: \ - *volatile_data = new_val; \ - break; \ - \ - case _Py_memory_order_acquire: \ - case _Py_memory_order_acq_rel: \ - case _Py_memory_order_seq_cst: \ - __asm__ volatile("xchg %0, %1" \ - : "+r"(new_val) \ - : "m"(atomic_val->_value) \ - : "memory"); \ - break; \ - } \ - _Py_ANNOTATE_IGNORE_WRITES_END(); \ - }) - -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - __extension__ ({ \ - __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \ - __typeof__(atomic_val->_value) result; \ - volatile __typeof__(result) *volatile_data = &atomic_val->_value; \ - _Py_memory_order order = ORDER; \ - _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \ - \ - /* Perform the operation. */ \ - _Py_ANNOTATE_IGNORE_READS_BEGIN(); \ - switch(order) { \ - case _Py_memory_order_release: \ - case _Py_memory_order_acq_rel: \ - case _Py_memory_order_seq_cst: \ - /* Loads on x86 are not releases by default, so need a */ \ - /* thread fence. */ \ - _Py_atomic_thread_fence(_Py_memory_order_release); \ - break; \ - default: \ - /* No fence */ \ - break; \ - } \ - result = *volatile_data; \ - switch(order) { \ - case _Py_memory_order_acquire: \ - case _Py_memory_order_acq_rel: \ - case _Py_memory_order_seq_cst: \ - /* Loads on x86 are automatically acquire operations so */ \ - /* can get by with just a compiler fence. */ \ - _Py_atomic_signal_fence(_Py_memory_order_acquire); \ - break; \ - default: \ - /* No fence */ \ - break; \ - } \ - _Py_ANNOTATE_IGNORE_READS_END(); \ - result; \ - }) - -#elif defined(_MSC_VER) -/* _Interlocked* functions provide a full memory barrier and are therefore - enough for acq_rel and seq_cst. If the HLE variants aren't available - in hardware they will fall back to a full memory barrier as well. - - This might affect performance but likely only in some very specific and - hard to measure scenario. -*/ -#if defined(_M_IX86) || defined(_M_X64) -typedef enum _Py_memory_order { - _Py_memory_order_relaxed, - _Py_memory_order_acquire, - _Py_memory_order_release, - _Py_memory_order_acq_rel, - _Py_memory_order_seq_cst -} _Py_memory_order; - -typedef struct _Py_atomic_address { - volatile uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - volatile int _value; -} _Py_atomic_int; - - -#if defined(_M_X64) -#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \ - switch (ORDER) { \ - case _Py_memory_order_acquire: \ - _InterlockedExchange64_HLEAcquire((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ - break; \ - case _Py_memory_order_release: \ - _InterlockedExchange64_HLERelease((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ - break; \ - default: \ - _InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ - break; \ - } -#else -#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0); -#endif - -#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \ - switch (ORDER) { \ - case _Py_memory_order_acquire: \ - _InterlockedExchange_HLEAcquire((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ - break; \ - case _Py_memory_order_release: \ - _InterlockedExchange_HLERelease((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ - break; \ - default: \ - _InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ - break; \ - } - -#if defined(_M_X64) -/* This has to be an intptr_t for now. - gil_created() uses -1 as a sentinel value, if this returns - a uintptr_t it will do an unsigned compare and crash -*/ -inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) { - __int64 old; - switch (order) { - case _Py_memory_order_acquire: - { - do { - old = *value; - } while(_InterlockedCompareExchange64_HLEAcquire((volatile __int64*)value, old, old) != old); - break; - } - case _Py_memory_order_release: - { - do { - old = *value; - } while(_InterlockedCompareExchange64_HLERelease((volatile __int64*)value, old, old) != old); - break; - } - case _Py_memory_order_relaxed: - old = *value; - break; - default: - { - do { - old = *value; - } while(_InterlockedCompareExchange64((volatile __int64*)value, old, old) != old); - break; - } - } - return old; -} - -#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \ - _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER)) - -#else -#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value) -#endif - -inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) { - long old; - switch (order) { - case _Py_memory_order_acquire: - { - do { - old = *value; - } while(_InterlockedCompareExchange_HLEAcquire((volatile long*)value, old, old) != old); - break; - } - case _Py_memory_order_release: - { - do { - old = *value; - } while(_InterlockedCompareExchange_HLERelease((volatile long*)value, old, old) != old); - break; - } - case _Py_memory_order_relaxed: - old = *value; - break; - default: - { - do { - old = *value; - } while(_InterlockedCompareExchange((volatile long*)value, old, old) != old); - break; - } - } - return old; -} - -#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \ - _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER)) - -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - if (sizeof((ATOMIC_VAL)->_value) == 8) { \ - _Py_atomic_store_64bit((ATOMIC_VAL), NEW_VAL, ORDER) } else { \ - _Py_atomic_store_32bit((ATOMIC_VAL), NEW_VAL, ORDER) } - -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - ( \ - sizeof((ATOMIC_VAL)->_value) == 8 ? \ - _Py_atomic_load_64bit((ATOMIC_VAL), ORDER) : \ - _Py_atomic_load_32bit((ATOMIC_VAL), ORDER) \ - ) -#elif defined(_M_ARM) || defined(_M_ARM64) -typedef enum _Py_memory_order { - _Py_memory_order_relaxed, - _Py_memory_order_acquire, - _Py_memory_order_release, - _Py_memory_order_acq_rel, - _Py_memory_order_seq_cst -} _Py_memory_order; - -typedef struct _Py_atomic_address { - volatile uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - volatile int _value; -} _Py_atomic_int; - - -#if defined(_M_ARM64) -#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \ - switch (ORDER) { \ - case _Py_memory_order_acquire: \ - _InterlockedExchange64_acq((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ - break; \ - case _Py_memory_order_release: \ - _InterlockedExchange64_rel((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ - break; \ - default: \ - _InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ - break; \ - } -#else -#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0); -#endif - -#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \ - switch (ORDER) { \ - case _Py_memory_order_acquire: \ - _InterlockedExchange_acq((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ - break; \ - case _Py_memory_order_release: \ - _InterlockedExchange_rel((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ - break; \ - default: \ - _InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ - break; \ - } - -#if defined(_M_ARM64) -/* This has to be an intptr_t for now. - gil_created() uses -1 as a sentinel value, if this returns - a uintptr_t it will do an unsigned compare and crash -*/ -inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) { - uintptr_t old; - switch (order) { - case _Py_memory_order_acquire: - { - do { - old = *value; - } while(_InterlockedCompareExchange64_acq(value, old, old) != old); - break; - } - case _Py_memory_order_release: - { - do { - old = *value; - } while(_InterlockedCompareExchange64_rel(value, old, old) != old); - break; - } - case _Py_memory_order_relaxed: - old = *value; - break; - default: - { - do { - old = *value; - } while(_InterlockedCompareExchange64(value, old, old) != old); - break; - } - } - return old; -} - -#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \ - _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER)) - -#else -#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value) -#endif - -inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) { - int old; - switch (order) { - case _Py_memory_order_acquire: - { - do { - old = *value; - } while(_InterlockedCompareExchange_acq(value, old, old) != old); - break; - } - case _Py_memory_order_release: - { - do { - old = *value; - } while(_InterlockedCompareExchange_rel(value, old, old) != old); - break; - } - case _Py_memory_order_relaxed: - old = *value; - break; - default: - { - do { - old = *value; - } while(_InterlockedCompareExchange(value, old, old) != old); - break; - } - } - return old; -} - -#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \ - _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER)) - -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - if (sizeof((ATOMIC_VAL)->_value) == 8) { \ - _Py_atomic_store_64bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } else { \ - _Py_atomic_store_32bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } - -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - ( \ - sizeof((ATOMIC_VAL)->_value) == 8 ? \ - _Py_atomic_load_64bit((ATOMIC_VAL), (ORDER)) : \ - _Py_atomic_load_32bit((ATOMIC_VAL), (ORDER)) \ - ) -#endif -#else /* !gcc x86 !_msc_ver */ -typedef enum _Py_memory_order { - _Py_memory_order_relaxed, - _Py_memory_order_acquire, - _Py_memory_order_release, - _Py_memory_order_acq_rel, - _Py_memory_order_seq_cst -} _Py_memory_order; - -typedef struct _Py_atomic_address { - uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - int _value; -} _Py_atomic_int; -/* Fall back to other compilers and processors by assuming that simple - volatile accesses are atomic. This is false, so people should port - this. */ -#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) ((void)0) -#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) ((void)0) -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - ((ATOMIC_VAL)->_value = NEW_VAL) -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - ((ATOMIC_VAL)->_value) -#endif - -/* Standardized shortcuts. */ -#define _Py_atomic_store(ATOMIC_VAL, NEW_VAL) \ - _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_seq_cst) -#define _Py_atomic_load(ATOMIC_VAL) \ - _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_seq_cst) - -/* Python-local extensions */ - -#define _Py_atomic_store_relaxed(ATOMIC_VAL, NEW_VAL) \ - _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_relaxed) -#define _Py_atomic_load_relaxed(ATOMIC_VAL) \ - _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_relaxed) - -#ifdef __cplusplus -} -#endif -#endif /* Py_ATOMIC_H */ diff --git a/python/include/internal/pycore_atomic_funcs.h b/python/include/internal/pycore_atomic_funcs.h deleted file mode 100644 index a59b88f..0000000 --- a/python/include/internal/pycore_atomic_funcs.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Atomic functions: similar to pycore_atomic.h, but don't need - to declare variables as atomic. - - Py_ssize_t type: - - * value = _Py_atomic_size_get(&var) - * _Py_atomic_size_set(&var, value) - - Use sequentially-consistent ordering (__ATOMIC_SEQ_CST memory order): - enforce total ordering with all other atomic functions. -*/ -#ifndef Py_ATOMIC_FUNC_H -#define Py_ATOMIC_FUNC_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#if defined(_MSC_VER) -# include // _InterlockedExchange() -#endif - - -// Use builtin atomic operations in GCC >= 4.7 and clang -#ifdef HAVE_BUILTIN_ATOMIC - -static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var) -{ - return __atomic_load_n(var, __ATOMIC_SEQ_CST); -} - -static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value) -{ - __atomic_store_n(var, value, __ATOMIC_SEQ_CST); -} - -#elif defined(_MSC_VER) - -static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var) -{ -#if SIZEOF_VOID_P == 8 - Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var)); - volatile __int64 *volatile_var = (volatile __int64 *)var; - __int64 old; - do { - old = *volatile_var; - } while(_InterlockedCompareExchange64(volatile_var, old, old) != old); -#else - Py_BUILD_ASSERT(sizeof(long) == sizeof(*var)); - volatile long *volatile_var = (volatile long *)var; - long old; - do { - old = *volatile_var; - } while(_InterlockedCompareExchange(volatile_var, old, old) != old); -#endif - return old; -} - -static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value) -{ -#if SIZEOF_VOID_P == 8 - Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var)); - volatile __int64 *volatile_var = (volatile __int64 *)var; - _InterlockedExchange64(volatile_var, value); -#else - Py_BUILD_ASSERT(sizeof(long) == sizeof(*var)); - volatile long *volatile_var = (volatile long *)var; - _InterlockedExchange(volatile_var, value); -#endif -} - -#else -// Fallback implementation using volatile - -static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var) -{ - volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var; - return *volatile_var; -} - -static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value) -{ - volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var; - *volatile_var = value; -} -#endif - -#ifdef __cplusplus -} -#endif -#endif /* Py_ATOMIC_FUNC_H */ diff --git a/python/include/internal/pycore_bitutils.h b/python/include/internal/pycore_bitutils.h deleted file mode 100644 index 040dbc5..0000000 --- a/python/include/internal/pycore_bitutils.h +++ /dev/null @@ -1,186 +0,0 @@ -/* Bit and bytes utilities. - - Bytes swap functions, reverse order of bytes: - - - _Py_bswap16(uint16_t) - - _Py_bswap32(uint32_t) - - _Py_bswap64(uint64_t) -*/ - -#ifndef Py_INTERNAL_BITUTILS_H -#define Py_INTERNAL_BITUTILS_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#if defined(__GNUC__) \ - && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) - /* __builtin_bswap16() is available since GCC 4.8, - __builtin_bswap32() is available since GCC 4.3, - __builtin_bswap64() is available since GCC 4.3. */ -# define _PY_HAVE_BUILTIN_BSWAP -#endif - -#ifdef _MSC_VER - /* Get _byteswap_ushort(), _byteswap_ulong(), _byteswap_uint64() */ -# include -#endif - -static inline uint16_t -_Py_bswap16(uint16_t word) -{ -#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap16) - return __builtin_bswap16(word); -#elif defined(_MSC_VER) - Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned short)); - return _byteswap_ushort(word); -#else - // Portable implementation which doesn't rely on circular bit shift - return ( ((word & UINT16_C(0x00FF)) << 8) - | ((word & UINT16_C(0xFF00)) >> 8)); -#endif -} - -static inline uint32_t -_Py_bswap32(uint32_t word) -{ -#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap32) - return __builtin_bswap32(word); -#elif defined(_MSC_VER) - Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned long)); - return _byteswap_ulong(word); -#else - // Portable implementation which doesn't rely on circular bit shift - return ( ((word & UINT32_C(0x000000FF)) << 24) - | ((word & UINT32_C(0x0000FF00)) << 8) - | ((word & UINT32_C(0x00FF0000)) >> 8) - | ((word & UINT32_C(0xFF000000)) >> 24)); -#endif -} - -static inline uint64_t -_Py_bswap64(uint64_t word) -{ -#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap64) - return __builtin_bswap64(word); -#elif defined(_MSC_VER) - return _byteswap_uint64(word); -#else - // Portable implementation which doesn't rely on circular bit shift - return ( ((word & UINT64_C(0x00000000000000FF)) << 56) - | ((word & UINT64_C(0x000000000000FF00)) << 40) - | ((word & UINT64_C(0x0000000000FF0000)) << 24) - | ((word & UINT64_C(0x00000000FF000000)) << 8) - | ((word & UINT64_C(0x000000FF00000000)) >> 8) - | ((word & UINT64_C(0x0000FF0000000000)) >> 24) - | ((word & UINT64_C(0x00FF000000000000)) >> 40) - | ((word & UINT64_C(0xFF00000000000000)) >> 56)); -#endif -} - - -// Population count: count the number of 1's in 'x' -// (number of bits set to 1), also known as the hamming weight. -// -// Implementation note. CPUID is not used, to test if x86 POPCNT instruction -// can be used, to keep the implementation simple. For example, Visual Studio -// __popcnt() is not used this reason. The clang and GCC builtin function can -// use the x86 POPCNT instruction if the target architecture has SSE4a or -// newer. -static inline int -_Py_popcount32(uint32_t x) -{ -#if (defined(__clang__) || defined(__GNUC__)) - -#if SIZEOF_INT >= 4 - Py_BUILD_ASSERT(sizeof(x) <= sizeof(unsigned int)); - return __builtin_popcount(x); -#else - // The C standard guarantees that unsigned long will always be big enough - // to hold a uint32_t value without losing information. - Py_BUILD_ASSERT(sizeof(x) <= sizeof(unsigned long)); - return __builtin_popcountl(x); -#endif - -#else - // 32-bit SWAR (SIMD Within A Register) popcount - - // Binary: 0 1 0 1 ... - const uint32_t M1 = 0x55555555; - // Binary: 00 11 00 11. .. - const uint32_t M2 = 0x33333333; - // Binary: 0000 1111 0000 1111 ... - const uint32_t M4 = 0x0F0F0F0F; - - // Put count of each 2 bits into those 2 bits - x = x - ((x >> 1) & M1); - // Put count of each 4 bits into those 4 bits - x = (x & M2) + ((x >> 2) & M2); - // Put count of each 8 bits into those 8 bits - x = (x + (x >> 4)) & M4; - // Sum of the 4 byte counts. - // Take care when considering changes to the next line. Portability and - // correctness are delicate here, thanks to C's "integer promotions" (C99 - // §6.3.1.1p2). On machines where the `int` type has width greater than 32 - // bits, `x` will be promoted to an `int`, and following C's "usual - // arithmetic conversions" (C99 §6.3.1.8), the multiplication will be - // performed as a multiplication of two `unsigned int` operands. In this - // case it's critical that we cast back to `uint32_t` in order to keep only - // the least significant 32 bits. On machines where the `int` type has - // width no greater than 32, the multiplication is of two 32-bit unsigned - // integer types, and the (uint32_t) cast is a no-op. In both cases, we - // avoid the risk of undefined behaviour due to overflow of a - // multiplication of signed integer types. - return (uint32_t)(x * 0x01010101U) >> 24; -#endif -} - - -// Return the index of the most significant 1 bit in 'x'. This is the smallest -// integer k such that x < 2**k. Equivalent to floor(log2(x)) + 1 for x != 0. -static inline int -_Py_bit_length(unsigned long x) -{ -#if (defined(__clang__) || defined(__GNUC__)) - if (x != 0) { - // __builtin_clzl() is available since GCC 3.4. - // Undefined behavior for x == 0. - return (int)sizeof(unsigned long) * 8 - __builtin_clzl(x); - } - else { - return 0; - } -#elif defined(_MSC_VER) - // _BitScanReverse() is documented to search 32 bits. - Py_BUILD_ASSERT(sizeof(unsigned long) <= 4); - unsigned long msb; - if (_BitScanReverse(&msb, x)) { - return (int)msb + 1; - } - else { - return 0; - } -#else - const int BIT_LENGTH_TABLE[32] = { - 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 - }; - int msb = 0; - while (x >= 32) { - msb += 6; - x >>= 6; - } - msb += BIT_LENGTH_TABLE[x]; - return msb; -#endif -} - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_BITUTILS_H */ diff --git a/python/include/internal/pycore_blocks_output_buffer.h b/python/include/internal/pycore_blocks_output_buffer.h deleted file mode 100644 index 8e8daed..0000000 --- a/python/include/internal/pycore_blocks_output_buffer.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - _BlocksOutputBuffer is used to maintain an output buffer - that has unpredictable size. Suitable for compression/decompression - API (bz2/lzma/zlib) that has stream->next_out and stream->avail_out: - - stream->next_out: point to the next output position. - stream->avail_out: the number of available bytes left in the buffer. - - It maintains a list of bytes object, so there is no overhead of resizing - the buffer. - - Usage: - - 1, Initialize the struct instance like this: - _BlocksOutputBuffer buffer = {.list = NULL}; - Set .list to NULL for _BlocksOutputBuffer_OnError() - - 2, Initialize the buffer use one of these functions: - _BlocksOutputBuffer_InitAndGrow() - _BlocksOutputBuffer_InitWithSize() - - 3, If (avail_out == 0), grow the buffer: - _BlocksOutputBuffer_Grow() - - 4, Get the current outputted data size: - _BlocksOutputBuffer_GetDataSize() - - 5, Finish the buffer, and return a bytes object: - _BlocksOutputBuffer_Finish() - - 6, Clean up the buffer when an error occurred: - _BlocksOutputBuffer_OnError() -*/ - -#ifndef Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H -#define Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "Python.h" - -typedef struct { - // List of bytes objects - PyObject *list; - // Number of whole allocated size - Py_ssize_t allocated; - // Max length of the buffer, negative number means unlimited length. - Py_ssize_t max_length; -} _BlocksOutputBuffer; - -static const char unable_allocate_msg[] = "Unable to allocate output buffer."; - -/* In 32-bit build, the max block size should <= INT32_MAX. */ -#define OUTPUT_BUFFER_MAX_BLOCK_SIZE (256*1024*1024) - -/* Block size sequence */ -#define KB (1024) -#define MB (1024*1024) -static const Py_ssize_t BUFFER_BLOCK_SIZE[] = - { 32*KB, 64*KB, 256*KB, 1*MB, 4*MB, 8*MB, 16*MB, 16*MB, - 32*MB, 32*MB, 32*MB, 32*MB, 64*MB, 64*MB, 128*MB, 128*MB, - OUTPUT_BUFFER_MAX_BLOCK_SIZE }; -#undef KB -#undef MB - -/* According to the block sizes defined by BUFFER_BLOCK_SIZE, the whole - allocated size growth step is: - 1 32 KB +32 KB - 2 96 KB +64 KB - 3 352 KB +256 KB - 4 1.34 MB +1 MB - 5 5.34 MB +4 MB - 6 13.34 MB +8 MB - 7 29.34 MB +16 MB - 8 45.34 MB +16 MB - 9 77.34 MB +32 MB - 10 109.34 MB +32 MB - 11 141.34 MB +32 MB - 12 173.34 MB +32 MB - 13 237.34 MB +64 MB - 14 301.34 MB +64 MB - 15 429.34 MB +128 MB - 16 557.34 MB +128 MB - 17 813.34 MB +256 MB - 18 1069.34 MB +256 MB - 19 1325.34 MB +256 MB - 20 1581.34 MB +256 MB - 21 1837.34 MB +256 MB - 22 2093.34 MB +256 MB - ... -*/ - -/* Initialize the buffer, and grow the buffer. - - max_length: Max length of the buffer, -1 for unlimited length. - - On success, return allocated size (>=0) - On failure, return -1 -*/ -static inline Py_ssize_t -_BlocksOutputBuffer_InitAndGrow(_BlocksOutputBuffer *buffer, - const Py_ssize_t max_length, - void **next_out) -{ - PyObject *b; - Py_ssize_t block_size; - - // ensure .list was set to NULL - assert(buffer->list == NULL); - - // get block size - if (0 <= max_length && max_length < BUFFER_BLOCK_SIZE[0]) { - block_size = max_length; - } else { - block_size = BUFFER_BLOCK_SIZE[0]; - } - - // the first block - b = PyBytes_FromStringAndSize(NULL, block_size); - if (b == NULL) { - return -1; - } - - // create the list - buffer->list = PyList_New(1); - if (buffer->list == NULL) { - Py_DECREF(b); - return -1; - } - PyList_SET_ITEM(buffer->list, 0, b); - - // set variables - buffer->allocated = block_size; - buffer->max_length = max_length; - - *next_out = PyBytes_AS_STRING(b); - return block_size; -} - -/* Initialize the buffer, with an initial size. - - Check block size limit in the outer wrapper function. For example, some libs - accept UINT32_MAX as the maximum block size, then init_size should <= it. - - On success, return allocated size (>=0) - On failure, return -1 -*/ -static inline Py_ssize_t -_BlocksOutputBuffer_InitWithSize(_BlocksOutputBuffer *buffer, - const Py_ssize_t init_size, - void **next_out) -{ - PyObject *b; - - // ensure .list was set to NULL - assert(buffer->list == NULL); - - // the first block - b = PyBytes_FromStringAndSize(NULL, init_size); - if (b == NULL) { - PyErr_SetString(PyExc_MemoryError, unable_allocate_msg); - return -1; - } - - // create the list - buffer->list = PyList_New(1); - if (buffer->list == NULL) { - Py_DECREF(b); - return -1; - } - PyList_SET_ITEM(buffer->list, 0, b); - - // set variables - buffer->allocated = init_size; - buffer->max_length = -1; - - *next_out = PyBytes_AS_STRING(b); - return init_size; -} - -/* Grow the buffer. The avail_out must be 0, please check it before calling. - - On success, return allocated size (>=0) - On failure, return -1 -*/ -static inline Py_ssize_t -_BlocksOutputBuffer_Grow(_BlocksOutputBuffer *buffer, - void **next_out, - const Py_ssize_t avail_out) -{ - PyObject *b; - const Py_ssize_t list_len = Py_SIZE(buffer->list); - Py_ssize_t block_size; - - // ensure no gaps in the data - if (avail_out != 0) { - PyErr_SetString(PyExc_SystemError, - "avail_out is non-zero in _BlocksOutputBuffer_Grow()."); - return -1; - } - - // get block size - if (list_len < (Py_ssize_t) Py_ARRAY_LENGTH(BUFFER_BLOCK_SIZE)) { - block_size = BUFFER_BLOCK_SIZE[list_len]; - } else { - block_size = BUFFER_BLOCK_SIZE[Py_ARRAY_LENGTH(BUFFER_BLOCK_SIZE) - 1]; - } - - // check max_length - if (buffer->max_length >= 0) { - // if (rest == 0), should not grow the buffer. - Py_ssize_t rest = buffer->max_length - buffer->allocated; - assert(rest > 0); - - // block_size of the last block - if (block_size > rest) { - block_size = rest; - } - } - - // check buffer->allocated overflow - if (block_size > PY_SSIZE_T_MAX - buffer->allocated) { - PyErr_SetString(PyExc_MemoryError, unable_allocate_msg); - return -1; - } - - // create the block - b = PyBytes_FromStringAndSize(NULL, block_size); - if (b == NULL) { - PyErr_SetString(PyExc_MemoryError, unable_allocate_msg); - return -1; - } - if (PyList_Append(buffer->list, b) < 0) { - Py_DECREF(b); - return -1; - } - Py_DECREF(b); - - // set variables - buffer->allocated += block_size; - - *next_out = PyBytes_AS_STRING(b); - return block_size; -} - -/* Return the current outputted data size. */ -static inline Py_ssize_t -_BlocksOutputBuffer_GetDataSize(_BlocksOutputBuffer *buffer, - const Py_ssize_t avail_out) -{ - return buffer->allocated - avail_out; -} - -/* Finish the buffer. - - Return a bytes object on success - Return NULL on failure -*/ -static inline PyObject * -_BlocksOutputBuffer_Finish(_BlocksOutputBuffer *buffer, - const Py_ssize_t avail_out) -{ - PyObject *result, *block; - const Py_ssize_t list_len = Py_SIZE(buffer->list); - - // fast path for single block - if ((list_len == 1 && avail_out == 0) || - (list_len == 2 && Py_SIZE(PyList_GET_ITEM(buffer->list, 1)) == avail_out)) - { - block = PyList_GET_ITEM(buffer->list, 0); - Py_INCREF(block); - - Py_CLEAR(buffer->list); - return block; - } - - // final bytes object - result = PyBytes_FromStringAndSize(NULL, buffer->allocated - avail_out); - if (result == NULL) { - PyErr_SetString(PyExc_MemoryError, unable_allocate_msg); - return NULL; - } - - // memory copy - if (list_len > 0) { - char *posi = PyBytes_AS_STRING(result); - - // blocks except the last one - Py_ssize_t i = 0; - for (; i < list_len-1; i++) { - block = PyList_GET_ITEM(buffer->list, i); - memcpy(posi, PyBytes_AS_STRING(block), Py_SIZE(block)); - posi += Py_SIZE(block); - } - // the last block - block = PyList_GET_ITEM(buffer->list, i); - memcpy(posi, PyBytes_AS_STRING(block), Py_SIZE(block) - avail_out); - } else { - assert(Py_SIZE(result) == 0); - } - - Py_CLEAR(buffer->list); - return result; -} - -/* Clean up the buffer when an error occurred. */ -static inline void -_BlocksOutputBuffer_OnError(_BlocksOutputBuffer *buffer) -{ - Py_CLEAR(buffer->list); -} - -#ifdef __cplusplus -} -#endif -#endif /* Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H */ \ No newline at end of file diff --git a/python/include/internal/pycore_bytes_methods.h b/python/include/internal/pycore_bytes_methods.h deleted file mode 100644 index cc3a303..0000000 --- a/python/include/internal/pycore_bytes_methods.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_BYTES_CTYPE_H -#define Py_BYTES_CTYPE_H - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -/* - * The internal implementation behind PyBytes (bytes) and PyByteArray (bytearray) - * methods of the given names, they operate on ASCII byte strings. - */ -extern PyObject* _Py_bytes_isspace(const char *cptr, Py_ssize_t len); -extern PyObject* _Py_bytes_isalpha(const char *cptr, Py_ssize_t len); -extern PyObject* _Py_bytes_isalnum(const char *cptr, Py_ssize_t len); -extern PyObject* _Py_bytes_isascii(const char *cptr, Py_ssize_t len); -extern PyObject* _Py_bytes_isdigit(const char *cptr, Py_ssize_t len); -extern PyObject* _Py_bytes_islower(const char *cptr, Py_ssize_t len); -extern PyObject* _Py_bytes_isupper(const char *cptr, Py_ssize_t len); -extern PyObject* _Py_bytes_istitle(const char *cptr, Py_ssize_t len); - -/* These store their len sized answer in the given preallocated *result arg. */ -extern void _Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len); -extern void _Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len); -extern void _Py_bytes_title(char *result, const char *s, Py_ssize_t len); -extern void _Py_bytes_capitalize(char *result, const char *s, Py_ssize_t len); -extern void _Py_bytes_swapcase(char *result, const char *s, Py_ssize_t len); - -extern PyObject *_Py_bytes_find(const char *str, Py_ssize_t len, PyObject *args); -extern PyObject *_Py_bytes_index(const char *str, Py_ssize_t len, PyObject *args); -extern PyObject *_Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *args); -extern PyObject *_Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *args); -extern PyObject *_Py_bytes_count(const char *str, Py_ssize_t len, PyObject *args); -extern int _Py_bytes_contains(const char *str, Py_ssize_t len, PyObject *arg); -extern PyObject *_Py_bytes_startswith(const char *str, Py_ssize_t len, PyObject *args); -extern PyObject *_Py_bytes_endswith(const char *str, Py_ssize_t len, PyObject *args); - -/* The maketrans() static method. */ -extern PyObject* _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to); - -/* Shared __doc__ strings. */ -extern const char _Py_isspace__doc__[]; -extern const char _Py_isalpha__doc__[]; -extern const char _Py_isalnum__doc__[]; -extern const char _Py_isascii__doc__[]; -extern const char _Py_isdigit__doc__[]; -extern const char _Py_islower__doc__[]; -extern const char _Py_isupper__doc__[]; -extern const char _Py_istitle__doc__[]; -extern const char _Py_lower__doc__[]; -extern const char _Py_upper__doc__[]; -extern const char _Py_title__doc__[]; -extern const char _Py_capitalize__doc__[]; -extern const char _Py_swapcase__doc__[]; -extern const char _Py_count__doc__[]; -extern const char _Py_find__doc__[]; -extern const char _Py_index__doc__[]; -extern const char _Py_rfind__doc__[]; -extern const char _Py_rindex__doc__[]; -extern const char _Py_startswith__doc__[]; -extern const char _Py_endswith__doc__[]; -extern const char _Py_maketrans__doc__[]; -extern const char _Py_expandtabs__doc__[]; -extern const char _Py_ljust__doc__[]; -extern const char _Py_rjust__doc__[]; -extern const char _Py_center__doc__[]; -extern const char _Py_zfill__doc__[]; - -/* this is needed because some docs are shared from the .o, not static */ -#define PyDoc_STRVAR_shared(name,str) const char name[] = PyDoc_STR(str) - -#endif /* !Py_BYTES_CTYPE_H */ -#endif /* !Py_LIMITED_API */ diff --git a/python/include/internal/pycore_bytesobject.h b/python/include/internal/pycore_bytesobject.h deleted file mode 100644 index 905a541..0000000 --- a/python/include/internal/pycore_bytesobject.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef Py_INTERNAL_BYTESOBJECT_H -#define Py_INTERNAL_BYTESOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - - -/* runtime lifecycle */ - -extern PyStatus _PyBytes_InitTypes(PyInterpreterState *); - - -/* Substring Search. - - Returns the index of the first occurrence of - a substring ("needle") in a larger text ("haystack"). - If the needle is not found, return -1. - If the needle is found, add offset to the index. -*/ - -PyAPI_FUNC(Py_ssize_t) -_PyBytes_Find(const char *haystack, Py_ssize_t len_haystack, - const char *needle, Py_ssize_t len_needle, - Py_ssize_t offset); - -/* Same as above, but search right-to-left */ -PyAPI_FUNC(Py_ssize_t) -_PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack, - const char *needle, Py_ssize_t len_needle, - Py_ssize_t offset); - - -/** Helper function to implement the repeat and inplace repeat methods on a buffer - * - * len_dest is assumed to be an integer multiple of len_src. - * If src equals dest, then assume the operation is inplace. - * - * This method repeately doubles the number of bytes copied to reduce - * the number of invocations of memcpy. - */ -PyAPI_FUNC(void) -_PyBytes_Repeat(char* dest, Py_ssize_t len_dest, - const char* src, Py_ssize_t len_src); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_BYTESOBJECT_H */ diff --git a/python/include/internal/pycore_call.h b/python/include/internal/pycore_call.h deleted file mode 100644 index 51c2562..0000000 --- a/python/include/internal/pycore_call.h +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef Py_INTERNAL_CALL_H -#define Py_INTERNAL_CALL_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_pystate.h" // _PyThreadState_GET() - -PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend( - PyThreadState *tstate, - PyObject *callable, - PyObject *obj, - PyObject *args, - PyObject *kwargs); - -PyAPI_FUNC(PyObject *) _PyObject_FastCallDictTstate( - PyThreadState *tstate, - PyObject *callable, - PyObject *const *args, - size_t nargsf, - PyObject *kwargs); - -PyAPI_FUNC(PyObject *) _PyObject_Call( - PyThreadState *tstate, - PyObject *callable, - PyObject *args, - PyObject *kwargs); - -extern PyObject * _PyObject_CallMethodFormat( - PyThreadState *tstate, PyObject *callable, const char *format, ...); - - -// Static inline variant of public PyVectorcall_Function(). -static inline vectorcallfunc -_PyVectorcall_FunctionInline(PyObject *callable) -{ - assert(callable != NULL); - - PyTypeObject *tp = Py_TYPE(callable); - if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) { - return NULL; - } - assert(PyCallable_Check(callable)); - - Py_ssize_t offset = tp->tp_vectorcall_offset; - assert(offset > 0); - - vectorcallfunc ptr; - memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); - return ptr; -} - - -/* Call the callable object 'callable' with the "vectorcall" calling - convention. - - args is a C array for positional arguments. - - nargsf is the number of positional arguments plus optionally the flag - PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to - modify args[-1]. - - kwnames is a tuple of keyword names. The values of the keyword arguments - are stored in "args" after the positional arguments (note that the number - of keyword arguments does not change nargsf). kwnames can also be NULL if - there are no keyword arguments. - - keywords must only contain strings and all keys must be unique. - - Return the result on success. Raise an exception and return NULL on - error. */ -static inline PyObject * -_PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable, - PyObject *const *args, size_t nargsf, - PyObject *kwnames) -{ - vectorcallfunc func; - PyObject *res; - - assert(kwnames == NULL || PyTuple_Check(kwnames)); - assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0); - - func = _PyVectorcall_FunctionInline(callable); - if (func == NULL) { - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames); - } - res = func(callable, args, nargsf, kwnames); - return _Py_CheckFunctionResult(tstate, callable, res, NULL); -} - - -static inline PyObject * -_PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) { - return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); -} - - -// Private static inline function variant of public PyObject_CallNoArgs() -static inline PyObject * -_PyObject_CallNoArgs(PyObject *func) { - PyThreadState *tstate = _PyThreadState_GET(); - return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); -} - - -static inline PyObject * -_PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs) -{ - return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL); -} - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_CALL_H */ diff --git a/python/include/internal/pycore_ceval.h b/python/include/internal/pycore_ceval.h deleted file mode 100644 index 6b1adb5..0000000 --- a/python/include/internal/pycore_ceval.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef Py_INTERNAL_CEVAL_H -#define Py_INTERNAL_CEVAL_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -/* Forward declarations */ -struct pyruntimestate; -struct _ceval_runtime_state; - -/* WASI has limited call stack. Python's recursion limit depends on code - layout, optimization, and WASI runtime. Wasmtime can handle about 700-750 - recursions, sometimes less. 600 is a more conservative limit. */ -#ifndef Py_DEFAULT_RECURSION_LIMIT -# ifdef __wasi__ -# define Py_DEFAULT_RECURSION_LIMIT 600 -# else -# define Py_DEFAULT_RECURSION_LIMIT 1000 -# endif -#endif - -#include "pycore_interp.h" // PyInterpreterState.eval_frame -#include "pycore_pystate.h" // _PyThreadState_GET() - - -extern void _Py_FinishPendingCalls(PyThreadState *tstate); -extern void _PyEval_InitRuntimeState(struct _ceval_runtime_state *); -extern void _PyEval_InitState(struct _ceval_state *, PyThread_type_lock); -extern void _PyEval_FiniState(struct _ceval_state *ceval); -PyAPI_FUNC(void) _PyEval_SignalReceived(PyInterpreterState *interp); -PyAPI_FUNC(int) _PyEval_AddPendingCall( - PyInterpreterState *interp, - int (*func)(void *), - void *arg); -PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyInterpreterState *interp); -#ifdef HAVE_FORK -extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate); -#endif - -// Used by sys.call_tracing() -extern PyObject* _PyEval_CallTracing(PyObject *func, PyObject *args); - -// Used by sys.get_asyncgen_hooks() -extern PyObject* _PyEval_GetAsyncGenFirstiter(void); -extern PyObject* _PyEval_GetAsyncGenFinalizer(void); - -// Used by sys.set_asyncgen_hooks() -extern int _PyEval_SetAsyncGenFirstiter(PyObject *); -extern int _PyEval_SetAsyncGenFinalizer(PyObject *); - -// Used by sys.get_coroutine_origin_tracking_depth() -// and sys.set_coroutine_origin_tracking_depth() -extern int _PyEval_GetCoroutineOriginTrackingDepth(void); -extern int _PyEval_SetCoroutineOriginTrackingDepth(int depth); - -extern void _PyEval_Fini(void); - - -extern PyObject* _PyEval_GetBuiltins(PyThreadState *tstate); -extern PyObject* _PyEval_BuiltinsFromGlobals( - PyThreadState *tstate, - PyObject *globals); - - -static inline PyObject* -_PyEval_EvalFrame(PyThreadState *tstate, struct _PyInterpreterFrame *frame, int throwflag) -{ - if (tstate->interp->eval_frame == NULL) { - return _PyEval_EvalFrameDefault(tstate, frame, throwflag); - } - return tstate->interp->eval_frame(tstate, frame, throwflag); -} - -extern PyObject* -_PyEval_Vector(PyThreadState *tstate, - PyFunctionObject *func, PyObject *locals, - PyObject* const* args, size_t argcount, - PyObject *kwnames); - -extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime); -extern PyStatus _PyEval_InitGIL(PyThreadState *tstate); -extern void _PyEval_FiniGIL(PyInterpreterState *interp); - -extern void _PyEval_ReleaseLock(PyThreadState *tstate); - -extern void _PyEval_DeactivateOpCache(void); - - -/* --- _Py_EnterRecursiveCall() ----------------------------------------- */ - -#ifdef USE_STACKCHECK -/* With USE_STACKCHECK macro defined, trigger stack checks in - _Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */ -static inline int _Py_MakeRecCheck(PyThreadState *tstate) { - return (tstate->recursion_remaining-- <= 0 - || (tstate->recursion_remaining & 63) == 0); -} -#else -static inline int _Py_MakeRecCheck(PyThreadState *tstate) { - return tstate->recursion_remaining-- <= 0; -} -#endif - -PyAPI_FUNC(int) _Py_CheckRecursiveCall( - PyThreadState *tstate, - const char *where); - -static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate, - const char *where) { - return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where)); -} - -static inline int _Py_EnterRecursiveCall(const char *where) { - PyThreadState *tstate = _PyThreadState_GET(); - return _Py_EnterRecursiveCallTstate(tstate, where); -} - -static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { - tstate->recursion_remaining++; -} - -static inline void _Py_LeaveRecursiveCall(void) { - PyThreadState *tstate = _PyThreadState_GET(); - _Py_LeaveRecursiveCallTstate(tstate); -} - -extern struct _PyInterpreterFrame* _PyEval_GetFrame(void); - -extern PyObject* _Py_MakeCoro(PyFunctionObject *func); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_CEVAL_H */ diff --git a/python/include/internal/pycore_code.h b/python/include/internal/pycore_code.h deleted file mode 100644 index c35a437..0000000 --- a/python/include/internal/pycore_code.h +++ /dev/null @@ -1,564 +0,0 @@ -#ifndef Py_INTERNAL_CODE_H -#define Py_INTERNAL_CODE_H -#ifdef __cplusplus -extern "C" { -#endif - -/* PEP 659 - * Specialization and quickening structs and helper functions - */ - - -// Inline caches. If you change the number of cache entries for an instruction, -// you must *also* update the number of cache entries in Lib/opcode.py and bump -// the magic number in Lib/importlib/_bootstrap_external.py! - -#define CACHE_ENTRIES(cache) (sizeof(cache)/sizeof(_Py_CODEUNIT)) - -typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT index; - _Py_CODEUNIT module_keys_version[2]; - _Py_CODEUNIT builtin_keys_version; -} _PyLoadGlobalCache; - -#define INLINE_CACHE_ENTRIES_LOAD_GLOBAL CACHE_ENTRIES(_PyLoadGlobalCache) - -typedef struct { - _Py_CODEUNIT counter; -} _PyBinaryOpCache; - -#define INLINE_CACHE_ENTRIES_BINARY_OP CACHE_ENTRIES(_PyBinaryOpCache) - -typedef struct { - _Py_CODEUNIT counter; -} _PyUnpackSequenceCache; - -#define INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE \ - CACHE_ENTRIES(_PyUnpackSequenceCache) - -typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT mask; -} _PyCompareOpCache; - -#define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache) - -typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT type_version[2]; - _Py_CODEUNIT func_version; -} _PyBinarySubscrCache; - -#define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache) - -typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT version[2]; - _Py_CODEUNIT index; -} _PyAttrCache; - -#define INLINE_CACHE_ENTRIES_LOAD_ATTR CACHE_ENTRIES(_PyAttrCache) - -#define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache) - -typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT type_version[2]; - _Py_CODEUNIT dict_offset; - _Py_CODEUNIT keys_version[2]; - _Py_CODEUNIT descr[4]; -} _PyLoadMethodCache; - -#define INLINE_CACHE_ENTRIES_LOAD_METHOD CACHE_ENTRIES(_PyLoadMethodCache) - -typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT func_version[2]; - _Py_CODEUNIT min_args; -} _PyCallCache; - -#define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache) - -typedef struct { - _Py_CODEUNIT counter; -} _PyPrecallCache; - -#define INLINE_CACHE_ENTRIES_PRECALL CACHE_ENTRIES(_PyPrecallCache) - -typedef struct { - _Py_CODEUNIT counter; -} _PyStoreSubscrCache; - -#define INLINE_CACHE_ENTRIES_STORE_SUBSCR CACHE_ENTRIES(_PyStoreSubscrCache) - -#define QUICKENING_WARMUP_DELAY 8 - -/* We want to compare to zero for efficiency, so we offset values accordingly */ -#define QUICKENING_INITIAL_WARMUP_VALUE (-QUICKENING_WARMUP_DELAY) - -void _PyCode_Quicken(PyCodeObject *code); - -static inline void -_PyCode_Warmup(PyCodeObject *code) -{ - if (code->co_warmup != 0) { - code->co_warmup++; - if (code->co_warmup == 0) { - _PyCode_Quicken(code); - } - } -} - -extern uint8_t _PyOpcode_Adaptive[256]; - -extern Py_ssize_t _Py_QuickenedCount; - -// Borrowed references to common callables: -struct callable_cache { - PyObject *isinstance; - PyObject *len; - PyObject *list_append; -}; - -/* "Locals plus" for a code object is the set of locals + cell vars + - * free vars. This relates to variable names as well as offsets into - * the "fast locals" storage array of execution frames. The compiler - * builds the list of names, their offsets, and the corresponding - * kind of local. - * - * Those kinds represent the source of the initial value and the - * variable's scope (as related to closures). A "local" is an - * argument or other variable defined in the current scope. A "free" - * variable is one that is defined in an outer scope and comes from - * the function's closure. A "cell" variable is a local that escapes - * into an inner function as part of a closure, and thus must be - * wrapped in a cell. Any "local" can also be a "cell", but the - * "free" kind is mutually exclusive with both. - */ - -// Note that these all fit within a byte, as do combinations. -// Later, we will use the smaller numbers to differentiate the different -// kinds of locals (e.g. pos-only arg, varkwargs, local-only). -#define CO_FAST_LOCAL 0x20 -#define CO_FAST_CELL 0x40 -#define CO_FAST_FREE 0x80 - -typedef unsigned char _PyLocals_Kind; - -static inline _PyLocals_Kind -_PyLocals_GetKind(PyObject *kinds, int i) -{ - assert(PyBytes_Check(kinds)); - assert(0 <= i && i < PyBytes_GET_SIZE(kinds)); - char *ptr = PyBytes_AS_STRING(kinds); - return (_PyLocals_Kind)(ptr[i]); -} - -static inline void -_PyLocals_SetKind(PyObject *kinds, int i, _PyLocals_Kind kind) -{ - assert(PyBytes_Check(kinds)); - assert(0 <= i && i < PyBytes_GET_SIZE(kinds)); - char *ptr = PyBytes_AS_STRING(kinds); - ptr[i] = (char) kind; -} - - -struct _PyCodeConstructor { - /* metadata */ - PyObject *filename; - PyObject *name; - PyObject *qualname; - int flags; - - /* the code */ - PyObject *code; - int firstlineno; - PyObject *linetable; - - /* used by the code */ - PyObject *consts; - PyObject *names; - - /* mapping frame offsets to information */ - PyObject *localsplusnames; // Tuple of strings - PyObject *localspluskinds; // Bytes object, one byte per variable - - /* args (within varnames) */ - int argcount; - int posonlyargcount; - // XXX Replace argcount with posorkwargcount (argcount - posonlyargcount). - int kwonlyargcount; - - /* needed to create the frame */ - int stacksize; - - /* used by the eval loop */ - PyObject *exceptiontable; -}; - -// Using an "arguments struct" like this is helpful for maintainability -// in a case such as this with many parameters. It does bear a risk: -// if the struct changes and callers are not updated properly then the -// compiler will not catch problems (like a missing argument). This can -// cause hard-to-debug problems. The risk is mitigated by the use of -// check_code() in codeobject.c. However, we may decide to switch -// back to a regular function signature. Regardless, this approach -// wouldn't be appropriate if this weren't a strictly internal API. -// (See the comments in https://github.com/python/cpython/pull/26258.) -PyAPI_FUNC(int) _PyCode_Validate(struct _PyCodeConstructor *); -PyAPI_FUNC(PyCodeObject *) _PyCode_New(struct _PyCodeConstructor *); - - -/* Private API */ - -/* Getters for internal PyCodeObject data. */ -extern PyObject* _PyCode_GetVarnames(PyCodeObject *); -extern PyObject* _PyCode_GetCellvars(PyCodeObject *); -extern PyObject* _PyCode_GetFreevars(PyCodeObject *); -extern PyObject* _PyCode_GetCode(PyCodeObject *); - -/** API for initializing the line number tables. */ -extern int _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds); - -/** Out of process API for initializing the location table. */ -extern void _PyLineTable_InitAddressRange( - const char *linetable, - Py_ssize_t length, - int firstlineno, - PyCodeAddressRange *range); - -/** API for traversing the line number table. */ -extern int _PyLineTable_NextAddressRange(PyCodeAddressRange *range); -extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); - -/* Specialization functions */ - -extern int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, - PyObject *name); -extern int _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, - PyObject *name); -extern int _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name); -extern int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, - PyObject *name); -extern int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr); -extern int _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr); -extern int _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames); -extern int _Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames, int oparg); -extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, - int oparg, PyObject **locals); -extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, - _Py_CODEUNIT *instr, int oparg); -extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, - int oparg); - -/* Deallocator function for static codeobjects used in deepfreeze.py */ -extern void _PyStaticCode_Dealloc(PyCodeObject *co); -/* Function to intern strings of codeobjects */ -extern int _PyStaticCode_InternStrings(PyCodeObject *co); - -#ifdef Py_STATS - -#define SPECIALIZATION_FAILURE_KINDS 30 - -typedef struct _specialization_stats { - uint64_t success; - uint64_t failure; - uint64_t hit; - uint64_t deferred; - uint64_t miss; - uint64_t deopt; - uint64_t failure_kinds[SPECIALIZATION_FAILURE_KINDS]; -} SpecializationStats; - -typedef struct _opcode_stats { - SpecializationStats specialization; - uint64_t execution_count; - uint64_t pair_count[256]; -} OpcodeStats; - -typedef struct _call_stats { - uint64_t inlined_py_calls; - uint64_t pyeval_calls; - uint64_t frames_pushed; - uint64_t frame_objects_created; -} CallStats; - -typedef struct _object_stats { - uint64_t allocations; - uint64_t allocations512; - uint64_t allocations4k; - uint64_t allocations_big; - uint64_t frees; - uint64_t to_freelist; - uint64_t from_freelist; - uint64_t new_values; - uint64_t dict_materialized_on_request; - uint64_t dict_materialized_new_key; - uint64_t dict_materialized_too_big; - uint64_t dict_materialized_str_subclass; -} ObjectStats; - -typedef struct _stats { - OpcodeStats opcode_stats[256]; - CallStats call_stats; - ObjectStats object_stats; -} PyStats; - -extern PyStats _py_stats; - -#define STAT_INC(opname, name) _py_stats.opcode_stats[opname].specialization.name++ -#define STAT_DEC(opname, name) _py_stats.opcode_stats[opname].specialization.name-- -#define OPCODE_EXE_INC(opname) _py_stats.opcode_stats[opname].execution_count++ -#define CALL_STAT_INC(name) _py_stats.call_stats.name++ -#define OBJECT_STAT_INC(name) _py_stats.object_stats.name++ -#define OBJECT_STAT_INC_COND(name, cond) \ - do { if (cond) _py_stats.object_stats.name++; } while (0) - -extern void _Py_PrintSpecializationStats(int to_file); - -// Used by the _opcode extension which is built as a shared library -PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void); - -#else -#define STAT_INC(opname, name) ((void)0) -#define STAT_DEC(opname, name) ((void)0) -#define OPCODE_EXE_INC(opname) ((void)0) -#define CALL_STAT_INC(name) ((void)0) -#define OBJECT_STAT_INC(name) ((void)0) -#define OBJECT_STAT_INC_COND(name, cond) ((void)0) -#endif // !Py_STATS - -// Cache values are only valid in memory, so use native endianness. -#ifdef WORDS_BIGENDIAN - -static inline void -write_u32(uint16_t *p, uint32_t val) -{ - p[0] = (uint16_t)(val >> 16); - p[1] = (uint16_t)(val >> 0); -} - -static inline void -write_u64(uint16_t *p, uint64_t val) -{ - p[0] = (uint16_t)(val >> 48); - p[1] = (uint16_t)(val >> 32); - p[2] = (uint16_t)(val >> 16); - p[3] = (uint16_t)(val >> 0); -} - -static inline uint32_t -read_u32(uint16_t *p) -{ - uint32_t val = 0; - val |= (uint32_t)p[0] << 16; - val |= (uint32_t)p[1] << 0; - return val; -} - -static inline uint64_t -read_u64(uint16_t *p) -{ - uint64_t val = 0; - val |= (uint64_t)p[0] << 48; - val |= (uint64_t)p[1] << 32; - val |= (uint64_t)p[2] << 16; - val |= (uint64_t)p[3] << 0; - return val; -} - -#else - -static inline void -write_u32(uint16_t *p, uint32_t val) -{ - p[0] = (uint16_t)(val >> 0); - p[1] = (uint16_t)(val >> 16); -} - -static inline void -write_u64(uint16_t *p, uint64_t val) -{ - p[0] = (uint16_t)(val >> 0); - p[1] = (uint16_t)(val >> 16); - p[2] = (uint16_t)(val >> 32); - p[3] = (uint16_t)(val >> 48); -} - -static inline uint32_t -read_u32(uint16_t *p) -{ - uint32_t val = 0; - val |= (uint32_t)p[0] << 0; - val |= (uint32_t)p[1] << 16; - return val; -} - -static inline uint64_t -read_u64(uint16_t *p) -{ - uint64_t val = 0; - val |= (uint64_t)p[0] << 0; - val |= (uint64_t)p[1] << 16; - val |= (uint64_t)p[2] << 32; - val |= (uint64_t)p[3] << 48; - return val; -} - -#endif - -static inline void -write_obj(uint16_t *p, PyObject *obj) -{ - uintptr_t val = (uintptr_t)obj; -#if SIZEOF_VOID_P == 8 - write_u64(p, val); -#elif SIZEOF_VOID_P == 4 - write_u32(p, val); -#else - #error "SIZEOF_VOID_P must be 4 or 8" -#endif -} - -static inline PyObject * -read_obj(uint16_t *p) -{ - uintptr_t val; -#if SIZEOF_VOID_P == 8 - val = read_u64(p); -#elif SIZEOF_VOID_P == 4 - val = read_u32(p); -#else - #error "SIZEOF_VOID_P must be 4 or 8" -#endif - return (PyObject *)val; -} - -/* See Objects/exception_handling_notes.txt for details. - */ -static inline unsigned char * -parse_varint(unsigned char *p, int *result) { - int val = p[0] & 63; - while (p[0] & 64) { - p++; - val = (val << 6) | (p[0] & 63); - } - *result = val; - return p+1; -} - -static inline int -write_varint(uint8_t *ptr, unsigned int val) -{ - int written = 1; - while (val >= 64) { - *ptr++ = 64 | (val & 63); - val >>= 6; - written++; - } - *ptr = val; - return written; -} - -static inline int -write_signed_varint(uint8_t *ptr, int val) -{ - if (val < 0) { - val = ((-val)<<1) | 1; - } - else { - val = val << 1; - } - return write_varint(ptr, val); -} - -static inline int -write_location_entry_start(uint8_t *ptr, int code, int length) -{ - assert((code & 15) == code); - *ptr = 128 | (code << 3) | (length - 1); - return 1; -} - - -/** Counters - * The first 16-bit value in each inline cache is a counter. - * When counting misses, the counter is treated as a simple unsigned value. - * - * When counting executions until the next specialization attempt, - * exponential backoff is used to reduce the number of specialization failures. - * The high 12 bits store the counter, the low 4 bits store the backoff exponent. - * On a specialization failure, the backoff exponent is incremented and the - * counter set to (2**backoff - 1). - * Backoff == 6 -> starting counter == 63, backoff == 10 -> starting counter == 1023. - */ - -/* With a 16-bit counter, we have 12 bits for the counter value, and 4 bits for the backoff */ -#define ADAPTIVE_BACKOFF_BITS 4 -/* The initial counter value is 31 == 2**ADAPTIVE_BACKOFF_START - 1 */ -#define ADAPTIVE_BACKOFF_START 5 - -#define MAX_BACKOFF_VALUE (16 - ADAPTIVE_BACKOFF_BITS) - - -static inline uint16_t -adaptive_counter_bits(int value, int backoff) { - return (value << ADAPTIVE_BACKOFF_BITS) | - (backoff & ((1< MAX_BACKOFF_VALUE) { - backoff = MAX_BACKOFF_VALUE; - } - unsigned int value = (1 << backoff) - 1; - return adaptive_counter_bits(value, backoff); -} - - -/* Line array cache for tracing */ - -extern int _PyCode_CreateLineArray(PyCodeObject *co); - -static inline int -_PyCode_InitLineArray(PyCodeObject *co) -{ - if (co->_co_linearray) { - return 0; - } - return _PyCode_CreateLineArray(co); -} - -static inline int -_PyCode_LineNumberFromArray(PyCodeObject *co, int index) -{ - assert(co->_co_linearray != NULL); - assert(index >= 0); - assert(index < Py_SIZE(co)); - if (co->_co_linearray_entry_size == 2) { - return ((int16_t *)co->_co_linearray)[index]; - } - else { - assert(co->_co_linearray_entry_size == 4); - return ((int32_t *)co->_co_linearray)[index]; - } -} - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_CODE_H */ diff --git a/python/include/internal/pycore_compile.h b/python/include/internal/pycore_compile.h deleted file mode 100644 index 986365e..0000000 --- a/python/include/internal/pycore_compile.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef Py_INTERNAL_COMPILE_H -#define Py_INTERNAL_COMPILE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -struct _arena; // Type defined in pycore_pyarena.h -struct _mod; // Type defined in pycore_ast.h - -// Export the symbol for test_peg_generator (built as a library) -PyAPI_FUNC(PyCodeObject*) _PyAST_Compile( - struct _mod *mod, - PyObject *filename, - PyCompilerFlags *flags, - int optimize, - struct _arena *arena); -extern PyFutureFeatures* _PyFuture_FromAST( - struct _mod * mod, - PyObject *filename - ); - -extern PyObject* _Py_Mangle(PyObject *p, PyObject *name); - -typedef struct { - int optimize; - int ff_features; - - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ -} _PyASTOptimizeState; - -extern int _PyAST_Optimize( - struct _mod *, - struct _arena *arena, - _PyASTOptimizeState *state); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_COMPILE_H */ diff --git a/python/include/internal/pycore_condvar.h b/python/include/internal/pycore_condvar.h deleted file mode 100644 index b744557..0000000 --- a/python/include/internal/pycore_condvar.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef Py_INTERNAL_CONDVAR_H -#define Py_INTERNAL_CONDVAR_H - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#ifndef _POSIX_THREADS -/* This means pthreads are not implemented in libc headers, hence the macro - not present in unistd.h. But they still can be implemented as an external - library (e.g. gnu pth in pthread emulation) */ -# ifdef HAVE_PTHREAD_H -# include /* _POSIX_THREADS */ -# endif -#endif - -#ifdef _POSIX_THREADS -/* - * POSIX support - */ -#define Py_HAVE_CONDVAR - -#ifdef HAVE_PTHREAD_H -# include -#endif - -#define PyMUTEX_T pthread_mutex_t -#define PyCOND_T pthread_cond_t - -#elif defined(NT_THREADS) -/* - * Windows (XP, 2003 server and later, as well as (hopefully) CE) support - * - * Emulated condition variables ones that work with XP and later, plus - * example native support on VISTA and onwards. - */ -#define Py_HAVE_CONDVAR - -/* include windows if it hasn't been done before */ -#define WIN32_LEAN_AND_MEAN -#include - -/* options */ -/* non-emulated condition variables are provided for those that want - * to target Windows Vista. Modify this macro to enable them. - */ -#ifndef _PY_EMULATED_WIN_CV -#define _PY_EMULATED_WIN_CV 1 /* use emulated condition variables */ -#endif - -/* fall back to emulation if not targeting Vista */ -#if !defined NTDDI_VISTA || NTDDI_VERSION < NTDDI_VISTA -#undef _PY_EMULATED_WIN_CV -#define _PY_EMULATED_WIN_CV 1 -#endif - -#if _PY_EMULATED_WIN_CV - -typedef CRITICAL_SECTION PyMUTEX_T; - -/* The ConditionVariable object. From XP onwards it is easily emulated - with a Semaphore. - Semaphores are available on Windows XP (2003 server) and later. - We use a Semaphore rather than an auto-reset event, because although - an auto-reset event might appear to solve the lost-wakeup bug (race - condition between releasing the outer lock and waiting) because it - maintains state even though a wait hasn't happened, there is still - a lost wakeup problem if more than one thread are interrupted in the - critical place. A semaphore solves that, because its state is - counted, not Boolean. - Because it is ok to signal a condition variable with no one - waiting, we need to keep track of the number of - waiting threads. Otherwise, the semaphore's state could rise - without bound. This also helps reduce the number of "spurious wakeups" - that would otherwise happen. - */ - -typedef struct _PyCOND_T -{ - HANDLE sem; - int waiting; /* to allow PyCOND_SIGNAL to be a no-op */ -} PyCOND_T; - -#else /* !_PY_EMULATED_WIN_CV */ - -/* Use native Win7 primitives if build target is Win7 or higher */ - -/* SRWLOCK is faster and better than CriticalSection */ -typedef SRWLOCK PyMUTEX_T; - -typedef CONDITION_VARIABLE PyCOND_T; - -#endif /* _PY_EMULATED_WIN_CV */ - -#endif /* _POSIX_THREADS, NT_THREADS */ - -#endif /* Py_INTERNAL_CONDVAR_H */ diff --git a/python/include/internal/pycore_context.h b/python/include/internal/pycore_context.h deleted file mode 100644 index 4a87c5a..0000000 --- a/python/include/internal/pycore_context.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef Py_INTERNAL_CONTEXT_H -#define Py_INTERNAL_CONTEXT_H - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_hamt.h" /* PyHamtObject */ - - -extern PyTypeObject _PyContextTokenMissing_Type; - -/* runtime lifecycle */ - -PyStatus _PyContext_Init(PyInterpreterState *); -void _PyContext_Fini(PyInterpreterState *); - - -/* other API */ - -#ifndef WITH_FREELISTS -// without freelists -# define PyContext_MAXFREELIST 0 -#endif - -#ifndef PyContext_MAXFREELIST -# define PyContext_MAXFREELIST 255 -#endif - -struct _Py_context_state { -#if PyContext_MAXFREELIST > 0 - // List of free PyContext objects - PyContext *freelist; - int numfree; -#endif -}; - -struct _pycontextobject { - PyObject_HEAD - PyContext *ctx_prev; - PyHamtObject *ctx_vars; - PyObject *ctx_weakreflist; - int ctx_entered; -}; - - -struct _pycontextvarobject { - PyObject_HEAD - PyObject *var_name; - PyObject *var_default; - PyObject *var_cached; - uint64_t var_cached_tsid; - uint64_t var_cached_tsver; - Py_hash_t var_hash; -}; - - -struct _pycontexttokenobject { - PyObject_HEAD - PyContext *tok_ctx; - PyContextVar *tok_var; - PyObject *tok_oldval; - int tok_used; -}; - - -#endif /* !Py_INTERNAL_CONTEXT_H */ diff --git a/python/include/internal/pycore_dict.h b/python/include/internal/pycore_dict.h deleted file mode 100644 index 9334487..0000000 --- a/python/include/internal/pycore_dict.h +++ /dev/null @@ -1,178 +0,0 @@ - -#ifndef Py_INTERNAL_DICT_H -#define Py_INTERNAL_DICT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - - -/* runtime lifecycle */ - -extern void _PyDict_Fini(PyInterpreterState *interp); - - -/* other API */ - -#ifndef WITH_FREELISTS -// without freelists -# define PyDict_MAXFREELIST 0 -#endif - -#ifndef PyDict_MAXFREELIST -# define PyDict_MAXFREELIST 80 -#endif - -struct _Py_dict_state { -#if PyDict_MAXFREELIST > 0 - /* Dictionary reuse scheme to save calls to malloc and free */ - PyDictObject *free_list[PyDict_MAXFREELIST]; - int numfree; - PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST]; - int keys_numfree; -#endif -}; - -typedef struct { - /* Cached hash code of me_key. */ - Py_hash_t me_hash; - PyObject *me_key; - PyObject *me_value; /* This field is only meaningful for combined tables */ -} PyDictKeyEntry; - -typedef struct { - PyObject *me_key; /* The key must be Unicode and have hash. */ - PyObject *me_value; /* This field is only meaningful for combined tables */ -} PyDictUnicodeEntry; - -extern PyDictKeysObject *_PyDict_NewKeysForClass(void); -extern PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); - -/* Gets a version number unique to the current state of the keys of dict, if possible. - * Returns the version number, or zero if it was not possible to get a version number. */ -extern uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys); - -extern Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys); - -/* _Py_dict_lookup() returns index of entry which can be used like DK_ENTRIES(dk)[index]. - * -1 when no entry found, -3 when compare raises error. - */ -extern Py_ssize_t _Py_dict_lookup(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr); - -extern Py_ssize_t _PyDict_GetItemHint(PyDictObject *, PyObject *, Py_ssize_t, PyObject **); -extern Py_ssize_t _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyObject *key); -extern PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *); - -/* Consumes references to key and value */ -extern int _PyDict_SetItem_Take2(PyDictObject *op, PyObject *key, PyObject *value); -extern int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value); - -extern PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *); - -#define DKIX_EMPTY (-1) -#define DKIX_DUMMY (-2) /* Used internally */ -#define DKIX_ERROR (-3) -#define DKIX_KEY_CHANGED (-4) /* Used internally */ - -typedef enum { - DICT_KEYS_GENERAL = 0, - DICT_KEYS_UNICODE = 1, - DICT_KEYS_SPLIT = 2 -} DictKeysKind; - -/* See dictobject.c for actual layout of DictKeysObject */ -struct _dictkeysobject { - Py_ssize_t dk_refcnt; - - /* Size of the hash table (dk_indices). It must be a power of 2. */ - uint8_t dk_log2_size; - - /* Size of the hash table (dk_indices) by bytes. */ - uint8_t dk_log2_index_bytes; - - /* Kind of keys */ - uint8_t dk_kind; - - /* Version number -- Reset to 0 by any modification to keys */ - uint32_t dk_version; - - /* Number of usable entries in dk_entries. */ - Py_ssize_t dk_usable; - - /* Number of used entries in dk_entries. */ - Py_ssize_t dk_nentries; - - /* Actual hash table of dk_size entries. It holds indices in dk_entries, - or DKIX_EMPTY(-1) or DKIX_DUMMY(-2). - - Indices must be: 0 <= indice < USABLE_FRACTION(dk_size). - - The size in bytes of an indice depends on dk_size: - - - 1 byte if dk_size <= 0xff (char*) - - 2 bytes if dk_size <= 0xffff (int16_t*) - - 4 bytes if dk_size <= 0xffffffff (int32_t*) - - 8 bytes otherwise (int64_t*) - - Dynamically sized, SIZEOF_VOID_P is minimum. */ - char dk_indices[]; /* char is required to avoid strict aliasing. */ - - /* "PyDictKeyEntry or PyDictUnicodeEntry dk_entries[USABLE_FRACTION(DK_SIZE(dk))];" array follows: - see the DK_ENTRIES() macro */ -}; - -/* This must be no more than 250, for the prefix size to fit in one byte. */ -#define SHARED_KEYS_MAX_SIZE 30 -#define NEXT_LOG2_SHARED_KEYS_MAX_SIZE 6 - -/* Layout of dict values: - * - * The PyObject *values are preceded by an array of bytes holding - * the insertion order and size. - * [-1] = prefix size. [-2] = used size. size[-2-n...] = insertion order. - */ -struct _dictvalues { - PyObject *values[1]; -}; - -#define DK_LOG_SIZE(dk) ((dk)->dk_log2_size) -#if SIZEOF_VOID_P > 4 -#define DK_SIZE(dk) (((int64_t)1)<dk_kind == DICT_KEYS_GENERAL), (PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes])) -#define DK_UNICODE_ENTRIES(dk) \ - (assert(dk->dk_kind != DICT_KEYS_GENERAL), (PyDictUnicodeEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes])) -#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL) - -extern uint64_t _pydict_global_version; - -#define DICT_NEXT_VERSION() (++_pydict_global_version) - -extern PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values); -extern PyObject *_PyDict_FromItems( - PyObject *const *keys, Py_ssize_t keys_offset, - PyObject *const *values, Py_ssize_t values_offset, - Py_ssize_t length); - -static inline void -_PyDictValues_AddToInsertionOrder(PyDictValues *values, Py_ssize_t ix) -{ - assert(ix < SHARED_KEYS_MAX_SIZE); - uint8_t *size_ptr = ((uint8_t *)values)-2; - int size = *size_ptr; - assert(size+2 < ((uint8_t *)values)[-1]); - size++; - size_ptr[-size] = (uint8_t)ix; - *size_ptr = size; -} - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_DICT_H */ diff --git a/python/include/internal/pycore_dtoa.h b/python/include/internal/pycore_dtoa.h deleted file mode 100644 index 0636165..0000000 --- a/python/include/internal/pycore_dtoa.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR - - -#if _PY_SHORT_FLOAT_REPR == 1 - -/* These functions are used by modules compiled as C extension like math: - they must be exported. */ - -PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr); -PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits, - int *decpt, int *sign, char **rve); -PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); -PyAPI_FUNC(double) _Py_dg_stdnan(int sign); -PyAPI_FUNC(double) _Py_dg_infinity(int sign); - -#endif // _PY_SHORT_FLOAT_REPR == 1 - -#ifdef __cplusplus -} -#endif diff --git a/python/include/internal/pycore_emscripten_signal.h b/python/include/internal/pycore_emscripten_signal.h deleted file mode 100644 index cbb8941..0000000 --- a/python/include/internal/pycore_emscripten_signal.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef Py_EMSCRIPTEN_SIGNAL_H -#define Py_EMSCRIPTEN_SIGNAL_H - -#if defined(__EMSCRIPTEN__) - -void -_Py_CheckEmscriptenSignals(void); - -void -_Py_CheckEmscriptenSignalsPeriodically(void); - -#define _Py_CHECK_EMSCRIPTEN_SIGNALS() _Py_CheckEmscriptenSignals() - -#define _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY() _Py_CheckEmscriptenSignalsPeriodically() - -extern int Py_EMSCRIPTEN_SIGNAL_HANDLING; - -#else - -#define _Py_CHECK_EMSCRIPTEN_SIGNALS() -#define _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY() - -#endif // defined(__EMSCRIPTEN__) - -#endif // ndef Py_EMSCRIPTEN_SIGNAL_H diff --git a/python/include/internal/pycore_exceptions.h b/python/include/internal/pycore_exceptions.h deleted file mode 100644 index a66af16..0000000 --- a/python/include/internal/pycore_exceptions.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef Py_INTERNAL_EXCEPTIONS_H -#define Py_INTERNAL_EXCEPTIONS_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - - -/* runtime lifecycle */ - -extern PyStatus _PyExc_InitState(PyInterpreterState *); -extern PyStatus _PyExc_InitGlobalObjects(PyInterpreterState *); -extern int _PyExc_InitTypes(PyInterpreterState *); -extern void _PyExc_Fini(PyInterpreterState *); - - -/* other API */ - -struct _Py_exc_state { - // The dict mapping from errno codes to OSError subclasses - PyObject *errnomap; - PyBaseExceptionObject *memerrors_freelist; - int memerrors_numfree; - // The ExceptionGroup type - PyObject *PyExc_ExceptionGroup; -}; - -extern void _PyExc_ClearExceptionGroupType(PyInterpreterState *); - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_EXCEPTIONS_H */ diff --git a/python/include/internal/pycore_fileutils.h b/python/include/internal/pycore_fileutils.h deleted file mode 100644 index 8252b75..0000000 --- a/python/include/internal/pycore_fileutils.h +++ /dev/null @@ -1,275 +0,0 @@ -#ifndef Py_INTERNAL_FILEUTILS_H -#define Py_INTERNAL_FILEUTILS_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "Py_BUILD_CORE must be defined to include this header" -#endif - -#include /* struct lconv */ - -typedef enum { - _Py_ERROR_UNKNOWN=0, - _Py_ERROR_STRICT, - _Py_ERROR_SURROGATEESCAPE, - _Py_ERROR_REPLACE, - _Py_ERROR_IGNORE, - _Py_ERROR_BACKSLASHREPLACE, - _Py_ERROR_SURROGATEPASS, - _Py_ERROR_XMLCHARREFREPLACE, - _Py_ERROR_OTHER -} _Py_error_handler; - -PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors); - -PyAPI_FUNC(int) _Py_DecodeLocaleEx( - const char *arg, - wchar_t **wstr, - size_t *wlen, - const char **reason, - int current_locale, - _Py_error_handler errors); - -PyAPI_FUNC(int) _Py_EncodeLocaleEx( - const wchar_t *text, - char **str, - size_t *error_pos, - const char **reason, - int current_locale, - _Py_error_handler errors); - -PyAPI_FUNC(char*) _Py_EncodeLocaleRaw( - const wchar_t *text, - size_t *error_pos); - -PyAPI_FUNC(PyObject *) _Py_device_encoding(int); - -#if defined(MS_WINDOWS) || defined(__APPLE__) - /* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611). - On macOS 10.13, read() and write() with more than INT_MAX bytes - fail with EINVAL (bpo-24658). */ -# define _PY_READ_MAX INT_MAX -# define _PY_WRITE_MAX INT_MAX -#else - /* write() should truncate the input to PY_SSIZE_T_MAX bytes, - but it's safer to do it ourself to have a portable behaviour */ -# define _PY_READ_MAX PY_SSIZE_T_MAX -# define _PY_WRITE_MAX PY_SSIZE_T_MAX -#endif - -#ifdef MS_WINDOWS -struct _Py_stat_struct { - unsigned long st_dev; - uint64_t st_ino; - unsigned short st_mode; - int st_nlink; - int st_uid; - int st_gid; - unsigned long st_rdev; - __int64 st_size; - time_t st_atime; - int st_atime_nsec; - time_t st_mtime; - int st_mtime_nsec; - time_t st_ctime; - int st_ctime_nsec; - unsigned long st_file_attributes; - unsigned long st_reparse_tag; -}; -#else -# define _Py_stat_struct stat -#endif - -PyAPI_FUNC(int) _Py_fstat( - int fd, - struct _Py_stat_struct *status); - -PyAPI_FUNC(int) _Py_fstat_noraise( - int fd, - struct _Py_stat_struct *status); - -PyAPI_FUNC(int) _Py_stat( - PyObject *path, - struct stat *status); - -PyAPI_FUNC(int) _Py_open( - const char *pathname, - int flags); - -PyAPI_FUNC(int) _Py_open_noraise( - const char *pathname, - int flags); - -PyAPI_FUNC(FILE *) _Py_wfopen( - const wchar_t *path, - const wchar_t *mode); - -PyAPI_FUNC(Py_ssize_t) _Py_read( - int fd, - void *buf, - size_t count); - -PyAPI_FUNC(Py_ssize_t) _Py_write( - int fd, - const void *buf, - size_t count); - -PyAPI_FUNC(Py_ssize_t) _Py_write_noraise( - int fd, - const void *buf, - size_t count); - -#ifdef HAVE_READLINK -PyAPI_FUNC(int) _Py_wreadlink( - const wchar_t *path, - wchar_t *buf, - /* Number of characters of 'buf' buffer - including the trailing NUL character */ - size_t buflen); -#endif - -#ifdef HAVE_REALPATH -PyAPI_FUNC(wchar_t*) _Py_wrealpath( - const wchar_t *path, - wchar_t *resolved_path, - /* Number of characters of 'resolved_path' buffer - including the trailing NUL character */ - size_t resolved_path_len); -#endif - -PyAPI_FUNC(wchar_t*) _Py_wgetcwd( - wchar_t *buf, - /* Number of characters of 'buf' buffer - including the trailing NUL character */ - size_t buflen); - -PyAPI_FUNC(int) _Py_get_inheritable(int fd); - -PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, - int *atomic_flag_works); - -PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable, - int *atomic_flag_works); - -PyAPI_FUNC(int) _Py_dup(int fd); - -#ifndef MS_WINDOWS -PyAPI_FUNC(int) _Py_get_blocking(int fd); - -PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); -#else /* MS_WINDOWS */ -PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd); - -PyAPI_FUNC(void*) _Py_get_osfhandle(int fd); - -PyAPI_FUNC(int) _Py_open_osfhandle_noraise(void *handle, int flags); - -PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags); -#endif /* MS_WINDOWS */ - -// This is used after getting NULL back from Py_DecodeLocale(). -#define DECODE_LOCALE_ERR(NAME, LEN) \ - ((LEN) == (size_t)-2) \ - ? _PyStatus_ERR("cannot decode " NAME) \ - : _PyStatus_NO_MEMORY() - -PyAPI_DATA(int) _Py_HasFileSystemDefaultEncodeErrors; - -PyAPI_FUNC(int) _Py_DecodeUTF8Ex( - const char *arg, - Py_ssize_t arglen, - wchar_t **wstr, - size_t *wlen, - const char **reason, - _Py_error_handler errors); - -PyAPI_FUNC(int) _Py_EncodeUTF8Ex( - const wchar_t *text, - char **str, - size_t *error_pos, - const char **reason, - int raw_malloc, - _Py_error_handler errors); - -PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape( - const char *arg, - Py_ssize_t arglen, - size_t *wlen); - -extern int -_Py_wstat(const wchar_t *, struct stat *); - -PyAPI_FUNC(int) _Py_GetForceASCII(void); - -/* Reset "force ASCII" mode (if it was initialized). - - This function should be called when Python changes the LC_CTYPE locale, - so the "force ASCII" mode can be detected again on the new locale - encoding. */ -PyAPI_FUNC(void) _Py_ResetForceASCII(void); - - -PyAPI_FUNC(int) _Py_GetLocaleconvNumeric( - struct lconv *lc, - PyObject **decimal_point, - PyObject **thousands_sep); - -PyAPI_FUNC(void) _Py_closerange(int first, int last); - -PyAPI_FUNC(wchar_t*) _Py_GetLocaleEncoding(void); -PyAPI_FUNC(PyObject*) _Py_GetLocaleEncodingObject(void); - -#ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION -extern int _Py_LocaleUsesNonUnicodeWchar(void); - -extern wchar_t* _Py_DecodeNonUnicodeWchar( - const wchar_t* native, - Py_ssize_t size); - -extern int _Py_EncodeNonUnicodeWchar_InPlace( - wchar_t* unicode, - Py_ssize_t size); -#endif - -extern int _Py_isabs(const wchar_t *path); -extern int _Py_abspath(const wchar_t *path, wchar_t **abspath_p); -#ifdef MS_WINDOWS -extern int _PyOS_getfullpathname(const wchar_t *path, wchar_t **abspath_p); -#endif -extern wchar_t * _Py_join_relfile(const wchar_t *dirname, - const wchar_t *relfile); -extern int _Py_add_relfile(wchar_t *dirname, - const wchar_t *relfile, - size_t bufsize); -extern size_t _Py_find_basename(const wchar_t *filename); -PyAPI_FUNC(wchar_t *) _Py_normpath(wchar_t *path, Py_ssize_t size); - - -// Macros to protect CRT calls against instant termination when passed an -// invalid parameter (bpo-23524). IPH stands for Invalid Parameter Handler. -// Usage: -// -// _Py_BEGIN_SUPPRESS_IPH -// ... -// _Py_END_SUPPRESS_IPH -#if defined _MSC_VER && _MSC_VER >= 1900 - -# include // _set_thread_local_invalid_parameter_handler() - - extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; -# define _Py_BEGIN_SUPPRESS_IPH \ - { _invalid_parameter_handler _Py_old_handler = \ - _set_thread_local_invalid_parameter_handler(_Py_silent_invalid_parameter_handler); -# define _Py_END_SUPPRESS_IPH \ - _set_thread_local_invalid_parameter_handler(_Py_old_handler); } -#else -# define _Py_BEGIN_SUPPRESS_IPH -# define _Py_END_SUPPRESS_IPH -#endif /* _MSC_VER >= 1900 */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_FILEUTILS_H */ diff --git a/python/include/internal/pycore_floatobject.h b/python/include/internal/pycore_floatobject.h deleted file mode 100644 index a4467b4..0000000 --- a/python/include/internal/pycore_floatobject.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef Py_INTERNAL_FLOATOBJECT_H -#define Py_INTERNAL_FLOATOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - - -/* runtime lifecycle */ - -extern void _PyFloat_InitState(PyInterpreterState *); -extern PyStatus _PyFloat_InitTypes(PyInterpreterState *); -extern void _PyFloat_Fini(PyInterpreterState *); -extern void _PyFloat_FiniType(PyInterpreterState *); - - -/* other API */ - -#ifndef WITH_FREELISTS -// without freelists -# define PyFloat_MAXFREELIST 0 -#endif - -#ifndef PyFloat_MAXFREELIST -# define PyFloat_MAXFREELIST 100 -#endif - -struct _Py_float_state { -#if PyFloat_MAXFREELIST > 0 - /* Special free list - free_list is a singly-linked list of available PyFloatObjects, - linked via abuse of their ob_type members. */ - int numfree; - PyFloatObject *free_list; -#endif -}; - -void _PyFloat_ExactDealloc(PyObject *op); - - -PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out); - - -/* Format the object based on the format_spec, as defined in PEP 3101 - (Advanced String Formatting). */ -PyAPI_FUNC(int) _PyFloat_FormatAdvancedWriter( - _PyUnicodeWriter *writer, - PyObject *obj, - PyObject *format_spec, - Py_ssize_t start, - Py_ssize_t end); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_FLOATOBJECT_H */ diff --git a/python/include/internal/pycore_format.h b/python/include/internal/pycore_format.h deleted file mode 100644 index 0cdf3ac..0000000 --- a/python/include/internal/pycore_format.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef Py_INTERNAL_FORMAT_H -#define Py_INTERNAL_FORMAT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -/* Format codes - * F_LJUST '-' - * F_SIGN '+' - * F_BLANK ' ' - * F_ALT '#' - * F_ZERO '0' - * F_NO_NEG_0 'z' - */ -#define F_LJUST (1<<0) -#define F_SIGN (1<<1) -#define F_BLANK (1<<2) -#define F_ALT (1<<3) -#define F_ZERO (1<<4) -#define F_NO_NEG_0 (1<<5) - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_FORMAT_H */ diff --git a/python/include/internal/pycore_frame.h b/python/include/internal/pycore_frame.h deleted file mode 100644 index 75e8c49..0000000 --- a/python/include/internal/pycore_frame.h +++ /dev/null @@ -1,237 +0,0 @@ -#ifndef Py_INTERNAL_FRAME_H -#define Py_INTERNAL_FRAME_H -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/* See Objects/frame_layout.md for an explanation of the frame stack - * including explanation of the PyFrameObject and _PyInterpreterFrame - * structs. */ - - -struct _frame { - PyObject_HEAD - PyFrameObject *f_back; /* previous frame, or NULL */ - struct _PyInterpreterFrame *f_frame; /* points to the frame data */ - PyObject *f_trace; /* Trace function */ - int f_lineno; /* Current line number. Only valid if non-zero */ - char f_trace_lines; /* Emit per-line trace events? */ - char f_trace_opcodes; /* Emit per-opcode trace events? */ - char f_fast_as_locals; /* Have the fast locals of this frame been converted to a dict? */ - /* The frame data, if this frame object owns the frame */ - PyObject *_f_frame_data[1]; -}; - -extern PyFrameObject* _PyFrame_New_NoTrack(PyCodeObject *code); - - -/* other API */ - -typedef enum _framestate { - FRAME_CREATED = -2, - FRAME_SUSPENDED = -1, - FRAME_EXECUTING = 0, - FRAME_COMPLETED = 1, - FRAME_CLEARED = 4 -} PyFrameState; - -enum _frameowner { - FRAME_OWNED_BY_THREAD = 0, - FRAME_OWNED_BY_GENERATOR = 1, - FRAME_OWNED_BY_FRAME_OBJECT = 2 -}; - -typedef struct _PyInterpreterFrame { - /* "Specials" section */ - PyFunctionObject *f_func; /* Strong reference */ - PyObject *f_globals; /* Borrowed reference */ - PyObject *f_builtins; /* Borrowed reference */ - PyObject *f_locals; /* Strong reference, may be NULL */ - PyCodeObject *f_code; /* Strong reference */ - PyFrameObject *frame_obj; /* Strong reference, may be NULL */ - /* Linkage section */ - struct _PyInterpreterFrame *previous; - // NOTE: This is not necessarily the last instruction started in the given - // frame. Rather, it is the code unit *prior to* the *next* instruction. For - // example, it may be an inline CACHE entry, an instruction we just jumped - // over, or (in the case of a newly-created frame) a totally invalid value: - _Py_CODEUNIT *prev_instr; - int stacktop; /* Offset of TOS from localsplus */ - bool is_entry; // Whether this is the "root" frame for the current _PyCFrame. - char owner; - /* Locals and stack */ - PyObject *localsplus[1]; -} _PyInterpreterFrame; - -#define _PyInterpreterFrame_LASTI(IF) \ - ((int)((IF)->prev_instr - _PyCode_CODE((IF)->f_code))) - -static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) { - return f->localsplus + f->f_code->co_nlocalsplus; -} - -static inline PyObject *_PyFrame_StackPeek(_PyInterpreterFrame *f) { - assert(f->stacktop > f->f_code->co_nlocalsplus); - assert(f->localsplus[f->stacktop-1] != NULL); - return f->localsplus[f->stacktop-1]; -} - -static inline PyObject *_PyFrame_StackPop(_PyInterpreterFrame *f) { - assert(f->stacktop > f->f_code->co_nlocalsplus); - f->stacktop--; - return f->localsplus[f->stacktop]; -} - -static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, PyObject *value) { - f->localsplus[f->stacktop] = value; - f->stacktop++; -} - -#define FRAME_SPECIALS_SIZE ((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *)) - -void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest); - -/* Consumes reference to func */ -static inline void -_PyFrame_InitializeSpecials( - _PyInterpreterFrame *frame, PyFunctionObject *func, - PyObject *locals, int nlocalsplus) -{ - frame->f_func = func; - frame->f_code = (PyCodeObject *)Py_NewRef(func->func_code); - frame->f_builtins = func->func_builtins; - frame->f_globals = func->func_globals; - frame->f_locals = Py_XNewRef(locals); - frame->stacktop = nlocalsplus; - frame->frame_obj = NULL; - frame->prev_instr = _PyCode_CODE(frame->f_code) - 1; - frame->is_entry = false; - frame->owner = FRAME_OWNED_BY_THREAD; -} - -/* Gets the pointer to the locals array - * that precedes this frame. - */ -static inline PyObject** -_PyFrame_GetLocalsArray(_PyInterpreterFrame *frame) -{ - return frame->localsplus; -} - -static inline PyObject** -_PyFrame_GetStackPointer(_PyInterpreterFrame *frame) -{ - return frame->localsplus+frame->stacktop; -} - -static inline void -_PyFrame_SetStackPointer(_PyInterpreterFrame *frame, PyObject **stack_pointer) -{ - frame->stacktop = (int)(stack_pointer - frame->localsplus); -} - -/* Determine whether a frame is incomplete. - * A frame is incomplete if it is part way through - * creating cell objects or a generator or coroutine. - * - * Frames on the frame stack are incomplete until the - * first RESUME instruction. - * Frames owned by a generator are always complete. - */ -static inline bool -_PyFrame_IsIncomplete(_PyInterpreterFrame *frame) -{ - return frame->owner != FRAME_OWNED_BY_GENERATOR && - frame->prev_instr < _PyCode_CODE(frame->f_code) + frame->f_code->_co_firsttraceable; -} - -/* For use by _PyFrame_GetFrameObject - Do not call directly. */ -PyFrameObject * -_PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame); - -/* Gets the PyFrameObject for this frame, lazily - * creating it if necessary. - * Returns a borrowed referennce */ -static inline PyFrameObject * -_PyFrame_GetFrameObject(_PyInterpreterFrame *frame) -{ - - assert(!_PyFrame_IsIncomplete(frame)); - PyFrameObject *res = frame->frame_obj; - if (res != NULL) { - return res; - } - return _PyFrame_MakeAndSetFrameObject(frame); -} - -/* Clears all references in the frame. - * If take is non-zero, then the _PyInterpreterFrame frame - * may be transferred to the frame object it references - * instead of being cleared. Either way - * the caller no longer owns the references - * in the frame. - * take should be set to 1 for heap allocated - * frames like the ones in generators and coroutines. - */ -void -_PyFrame_Clear(_PyInterpreterFrame * frame); - -int -_PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg); - -int -_PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame); - -void -_PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear); - -extern _PyInterpreterFrame * -_PyThreadState_BumpFramePointerSlow(PyThreadState *tstate, size_t size); - -static inline bool -_PyThreadState_HasStackSpace(PyThreadState *tstate, size_t size) -{ - assert( - (tstate->datastack_top == NULL && tstate->datastack_limit == NULL) - || - (tstate->datastack_top != NULL && tstate->datastack_limit != NULL) - ); - return tstate->datastack_top != NULL && - size < (size_t)(tstate->datastack_limit - tstate->datastack_top); -} - -static inline _PyInterpreterFrame * -_PyThreadState_BumpFramePointer(PyThreadState *tstate, size_t size) -{ - if (_PyThreadState_HasStackSpace(tstate, size)) { - _PyInterpreterFrame *res = (_PyInterpreterFrame *)tstate->datastack_top; - tstate->datastack_top += size; - return res; - } - return _PyThreadState_BumpFramePointerSlow(tstate, size); -} - -void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame); - -/* Consume reference to func */ -_PyInterpreterFrame * -_PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func); - -int _PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame); - -static inline -PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame) -{ - assert(frame->owner == FRAME_OWNED_BY_GENERATOR); - size_t offset_in_gen = offsetof(PyGenObject, gi_iframe); - return (PyGenObject *)(((char *)frame) - offset_in_gen); -} - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_FRAME_H */ diff --git a/python/include/internal/pycore_function.h b/python/include/internal/pycore_function.h deleted file mode 100644 index 85118be..0000000 --- a/python/include/internal/pycore_function.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef Py_INTERNAL_FUNCTION_H -#define Py_INTERNAL_FUNCTION_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -extern PyFunctionObject* _PyFunction_FromConstructor(PyFrameConstructor *constr); - -extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_FUNCTION_H */ diff --git a/python/include/internal/pycore_gc.h b/python/include/internal/pycore_gc.h deleted file mode 100644 index 7d15c05..0000000 --- a/python/include/internal/pycore_gc.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef Py_INTERNAL_GC_H -#define Py_INTERNAL_GC_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -/* GC information is stored BEFORE the object structure. */ -typedef struct { - // Pointer to next object in the list. - // 0 means the object is not tracked - uintptr_t _gc_next; - - // Pointer to previous object in the list. - // Lowest two bits are used for flags documented later. - uintptr_t _gc_prev; -} PyGC_Head; - -#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1) -#define _PyGC_Head_UNUSED PyGC_Head - -/* True if the object is currently tracked by the GC. */ -#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0) - -/* True if the object may be tracked by the GC in the future, or already is. - This can be useful to implement some optimizations. */ -#define _PyObject_GC_MAY_BE_TRACKED(obj) \ - (PyObject_IS_GC(obj) && \ - (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj))) - - -/* Bit flags for _gc_prev */ -/* Bit 0 is set when tp_finalize is called */ -#define _PyGC_PREV_MASK_FINALIZED (1) -/* Bit 1 is set when the object is in generation which is GCed currently. */ -#define _PyGC_PREV_MASK_COLLECTING (2) -/* The (N-2) most significant bits contain the real address. */ -#define _PyGC_PREV_SHIFT (2) -#define _PyGC_PREV_MASK (((uintptr_t) -1) << _PyGC_PREV_SHIFT) - -// Lowest bit of _gc_next is used for flags only in GC. -// But it is always 0 for normal code. -#define _PyGCHead_NEXT(g) ((PyGC_Head*)(g)->_gc_next) -#define _PyGCHead_SET_NEXT(g, p) _Py_RVALUE((g)->_gc_next = (uintptr_t)(p)) - -// Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags. -#define _PyGCHead_PREV(g) ((PyGC_Head*)((g)->_gc_prev & _PyGC_PREV_MASK)) -#define _PyGCHead_SET_PREV(g, p) do { \ - assert(((uintptr_t)p & ~_PyGC_PREV_MASK) == 0); \ - (g)->_gc_prev = ((g)->_gc_prev & ~_PyGC_PREV_MASK) \ - | ((uintptr_t)(p)); \ - } while (0) - -#define _PyGCHead_FINALIZED(g) \ - (((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0) -#define _PyGCHead_SET_FINALIZED(g) \ - _Py_RVALUE((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED) - -#define _PyGC_FINALIZED(o) \ - _PyGCHead_FINALIZED(_Py_AS_GC(o)) -#define _PyGC_SET_FINALIZED(o) \ - _PyGCHead_SET_FINALIZED(_Py_AS_GC(o)) - - -/* GC runtime state */ - -/* If we change this, we need to change the default value in the - signature of gc.collect. */ -#define NUM_GENERATIONS 3 -/* - NOTE: about untracking of mutable objects. - - Certain types of container cannot participate in a reference cycle, and - so do not need to be tracked by the garbage collector. Untracking these - objects reduces the cost of garbage collections. However, determining - which objects may be untracked is not free, and the costs must be - weighed against the benefits for garbage collection. - - There are two possible strategies for when to untrack a container: - - i) When the container is created. - ii) When the container is examined by the garbage collector. - - Tuples containing only immutable objects (integers, strings etc, and - recursively, tuples of immutable objects) do not need to be tracked. - The interpreter creates a large number of tuples, many of which will - not survive until garbage collection. It is therefore not worthwhile - to untrack eligible tuples at creation time. - - Instead, all tuples except the empty tuple are tracked when created. - During garbage collection it is determined whether any surviving tuples - can be untracked. A tuple can be untracked if all of its contents are - already not tracked. Tuples are examined for untracking in all garbage - collection cycles. It may take more than one cycle to untrack a tuple. - - Dictionaries containing only immutable objects also do not need to be - tracked. Dictionaries are untracked when created. If a tracked item is - inserted into a dictionary (either as a key or value), the dictionary - becomes tracked. During a full garbage collection (all generations), - the collector will untrack any dictionaries whose contents are not - tracked. - - The module provides the python function is_tracked(obj), which returns - the CURRENT tracking status of the object. Subsequent garbage - collections may change the tracking status of the object. - - Untracking of certain containers was introduced in issue #4688, and - the algorithm was refined in response to issue #14775. -*/ - -struct gc_generation { - PyGC_Head head; - int threshold; /* collection threshold */ - int count; /* count of allocations or collections of younger - generations */ -}; - -/* Running stats per generation */ -struct gc_generation_stats { - /* total number of collections */ - Py_ssize_t collections; - /* total number of collected objects */ - Py_ssize_t collected; - /* total number of uncollectable objects (put into gc.garbage) */ - Py_ssize_t uncollectable; -}; - -struct _gc_runtime_state { - /* List of objects that still need to be cleaned up, singly linked - * via their gc headers' gc_prev pointers. */ - PyObject *trash_delete_later; - /* Current call-stack depth of tp_dealloc calls. */ - int trash_delete_nesting; - - /* Is automatic collection enabled? */ - int enabled; - int debug; - /* linked lists of container objects */ - struct gc_generation generations[NUM_GENERATIONS]; - PyGC_Head *generation0; - /* a permanent generation which won't be collected */ - struct gc_generation permanent_generation; - struct gc_generation_stats generation_stats[NUM_GENERATIONS]; - /* true if we are currently running the collector */ - int collecting; - /* list of uncollectable objects */ - PyObject *garbage; - /* a list of callbacks to be invoked when collection is performed */ - PyObject *callbacks; - /* This is the number of objects that survived the last full - collection. It approximates the number of long lived objects - tracked by the GC. - - (by "full collection", we mean a collection of the oldest - generation). */ - Py_ssize_t long_lived_total; - /* This is the number of objects that survived all "non-full" - collections, and are awaiting to undergo a full collection for - the first time. */ - Py_ssize_t long_lived_pending; -}; - - -extern void _PyGC_InitState(struct _gc_runtime_state *); - -extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate); - - -// Functions to clear types free lists -extern void _PyTuple_ClearFreeList(PyInterpreterState *interp); -extern void _PyFloat_ClearFreeList(PyInterpreterState *interp); -extern void _PyList_ClearFreeList(PyInterpreterState *interp); -extern void _PyDict_ClearFreeList(PyInterpreterState *interp); -extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp); -extern void _PyContext_ClearFreeList(PyInterpreterState *interp); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_GC_H */ diff --git a/python/include/internal/pycore_genobject.h b/python/include/internal/pycore_genobject.h deleted file mode 100644 index e8f56a6..0000000 --- a/python/include/internal/pycore_genobject.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef Py_INTERNAL_GENOBJECT_H -#define Py_INTERNAL_GENOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -extern PyObject *_PyGen_yf(PyGenObject *); -extern PyObject *_PyCoro_GetAwaitableIter(PyObject *o); -extern PyObject *_PyAsyncGenValueWrapperNew(PyObject *); - -/* runtime lifecycle */ - -extern void _PyAsyncGen_Fini(PyInterpreterState *); - - -/* other API */ - -#ifndef WITH_FREELISTS -// without freelists -# define _PyAsyncGen_MAXFREELIST 0 -#endif - -#ifndef _PyAsyncGen_MAXFREELIST -# define _PyAsyncGen_MAXFREELIST 80 -#endif - -struct _Py_async_gen_state { -#if _PyAsyncGen_MAXFREELIST > 0 - /* Freelists boost performance 6-10%; they also reduce memory - fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend - are short-living objects that are instantiated for every - __anext__() call. */ - struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST]; - int value_numfree; - - struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST]; - int asend_numfree; -#endif -}; - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_GENOBJECT_H */ diff --git a/python/include/internal/pycore_getopt.h b/python/include/internal/pycore_getopt.h deleted file mode 100644 index d045469..0000000 --- a/python/include/internal/pycore_getopt.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef Py_INTERNAL_PYGETOPT_H -#define Py_INTERNAL_PYGETOPT_H - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -extern int _PyOS_opterr; -extern Py_ssize_t _PyOS_optind; -extern const wchar_t *_PyOS_optarg; - -extern void _PyOS_ResetGetOpt(void); - -typedef struct { - const wchar_t *name; - int has_arg; - int val; -} _PyOS_LongOption; - -extern int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex); - -#endif /* !Py_INTERNAL_PYGETOPT_H */ diff --git a/python/include/internal/pycore_gil.h b/python/include/internal/pycore_gil.h deleted file mode 100644 index e1c8923..0000000 --- a/python/include/internal/pycore_gil.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef Py_INTERNAL_GIL_H -#define Py_INTERNAL_GIL_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_atomic.h" /* _Py_atomic_address */ -#include "pycore_condvar.h" /* PyCOND_T */ - -#ifndef Py_HAVE_CONDVAR -# error You need either a POSIX-compatible or a Windows system! -#endif - -/* Enable if you want to force the switching of threads at least - every `interval`. */ -#undef FORCE_SWITCHING -#define FORCE_SWITCHING - -struct _gil_runtime_state { - /* microseconds (the Python API uses seconds, though) */ - unsigned long interval; - /* Last PyThreadState holding / having held the GIL. This helps us - know whether anyone else was scheduled after we dropped the GIL. */ - _Py_atomic_address last_holder; - /* Whether the GIL is already taken (-1 if uninitialized). This is - atomic because it can be read without any lock taken in ceval.c. */ - _Py_atomic_int locked; - /* Number of GIL switches since the beginning. */ - unsigned long switch_number; - /* This condition variable allows one or several threads to wait - until the GIL is released. In addition, the mutex also protects - the above variables. */ - PyCOND_T cond; - PyMUTEX_T mutex; -#ifdef FORCE_SWITCHING - /* This condition variable helps the GIL-releasing thread wait for - a GIL-awaiting thread to be scheduled and take the GIL. */ - PyCOND_T switch_cond; - PyMUTEX_T switch_mutex; -#endif -}; - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_GIL_H */ diff --git a/python/include/internal/pycore_global_objects.h b/python/include/internal/pycore_global_objects.h deleted file mode 100644 index 4b6eff6..0000000 --- a/python/include/internal/pycore_global_objects.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef Py_INTERNAL_GLOBAL_OBJECTS_H -#define Py_INTERNAL_GLOBAL_OBJECTS_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_gc.h" // PyGC_Head -#include "pycore_global_strings.h" // struct _Py_global_strings - - -// These would be in pycore_long.h if it weren't for an include cycle. -#define _PY_NSMALLPOSINTS 257 -#define _PY_NSMALLNEGINTS 5 - - -// Only immutable objects should be considered runtime-global. -// All others must be per-interpreter. - -#define _Py_GLOBAL_OBJECT(NAME) \ - _PyRuntime.global_objects.NAME -#define _Py_SINGLETON(NAME) \ - _Py_GLOBAL_OBJECT(singletons.NAME) - -struct _Py_global_objects { - struct { - /* Small integers are preallocated in this array so that they - * can be shared. - * The integers that are preallocated are those in the range - * -_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (exclusive). - */ - PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS]; - - PyBytesObject bytes_empty; - struct { - PyBytesObject ob; - char eos; - } bytes_characters[256]; - - struct _Py_global_strings strings; - - _PyGC_Head_UNUSED _tuple_empty_gc_not_used; - PyTupleObject tuple_empty; - } singletons; -}; - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_GLOBAL_OBJECTS_H */ diff --git a/python/include/internal/pycore_global_strings.h b/python/include/internal/pycore_global_strings.h deleted file mode 100644 index 1679d45..0000000 --- a/python/include/internal/pycore_global_strings.h +++ /dev/null @@ -1,395 +0,0 @@ -#ifndef Py_INTERNAL_GLOBAL_STRINGS_H -#define Py_INTERNAL_GLOBAL_STRINGS_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -// The data structure & init here are inspired by Tools/scripts/deepfreeze.py. - -// All field names generated by ASCII_STR() have a common prefix, -// to help avoid collisions with keywords, etc. - -#define STRUCT_FOR_ASCII_STR(LITERAL) \ - struct { \ - PyASCIIObject _ascii; \ - uint8_t _data[sizeof(LITERAL)]; \ - } -#define STRUCT_FOR_STR(NAME, LITERAL) \ - STRUCT_FOR_ASCII_STR(LITERAL) _ ## NAME; -#define STRUCT_FOR_ID(NAME) \ - STRUCT_FOR_ASCII_STR(#NAME) _ ## NAME; - -// XXX Order by frequency of use? - -/* The following is auto-generated by Tools/scripts/generate_global_objects.py. */ -struct _Py_global_strings { - struct { - STRUCT_FOR_STR(anon_dictcomp, "") - STRUCT_FOR_STR(anon_genexpr, "") - STRUCT_FOR_STR(anon_lambda, "") - STRUCT_FOR_STR(anon_listcomp, "") - STRUCT_FOR_STR(anon_module, "") - STRUCT_FOR_STR(anon_setcomp, "") - STRUCT_FOR_STR(anon_string, "") - STRUCT_FOR_STR(anon_unknown, "") - STRUCT_FOR_STR(close_br, "}") - STRUCT_FOR_STR(comma_sep, ", ") - STRUCT_FOR_STR(dbl_close_br, "}}") - STRUCT_FOR_STR(dbl_open_br, "{{") - STRUCT_FOR_STR(dbl_percent, "%%") - STRUCT_FOR_STR(dot, ".") - STRUCT_FOR_STR(dot_locals, ".") - STRUCT_FOR_STR(empty, "") - STRUCT_FOR_STR(list_err, "list index out of range") - STRUCT_FOR_STR(newline, "\n") - STRUCT_FOR_STR(open_br, "{") - STRUCT_FOR_STR(percent, "%") - STRUCT_FOR_STR(utf_8, "utf-8") - } literals; - - struct { - STRUCT_FOR_ID(False) - STRUCT_FOR_ID(Py_Repr) - STRUCT_FOR_ID(TextIOWrapper) - STRUCT_FOR_ID(True) - STRUCT_FOR_ID(WarningMessage) - STRUCT_FOR_ID(_) - STRUCT_FOR_ID(__IOBase_closed) - STRUCT_FOR_ID(__abc_tpflags__) - STRUCT_FOR_ID(__abs__) - STRUCT_FOR_ID(__abstractmethods__) - STRUCT_FOR_ID(__add__) - STRUCT_FOR_ID(__aenter__) - STRUCT_FOR_ID(__aexit__) - STRUCT_FOR_ID(__aiter__) - STRUCT_FOR_ID(__all__) - STRUCT_FOR_ID(__and__) - STRUCT_FOR_ID(__anext__) - STRUCT_FOR_ID(__annotations__) - STRUCT_FOR_ID(__args__) - STRUCT_FOR_ID(__await__) - STRUCT_FOR_ID(__bases__) - STRUCT_FOR_ID(__bool__) - STRUCT_FOR_ID(__build_class__) - STRUCT_FOR_ID(__builtins__) - STRUCT_FOR_ID(__bytes__) - STRUCT_FOR_ID(__call__) - STRUCT_FOR_ID(__cantrace__) - STRUCT_FOR_ID(__class__) - STRUCT_FOR_ID(__class_getitem__) - STRUCT_FOR_ID(__classcell__) - STRUCT_FOR_ID(__complex__) - STRUCT_FOR_ID(__contains__) - STRUCT_FOR_ID(__copy__) - STRUCT_FOR_ID(__del__) - STRUCT_FOR_ID(__delattr__) - STRUCT_FOR_ID(__delete__) - STRUCT_FOR_ID(__delitem__) - STRUCT_FOR_ID(__dict__) - STRUCT_FOR_ID(__dir__) - STRUCT_FOR_ID(__divmod__) - STRUCT_FOR_ID(__doc__) - STRUCT_FOR_ID(__enter__) - STRUCT_FOR_ID(__eq__) - STRUCT_FOR_ID(__exit__) - STRUCT_FOR_ID(__file__) - STRUCT_FOR_ID(__float__) - STRUCT_FOR_ID(__floordiv__) - STRUCT_FOR_ID(__format__) - STRUCT_FOR_ID(__fspath__) - STRUCT_FOR_ID(__ge__) - STRUCT_FOR_ID(__get__) - STRUCT_FOR_ID(__getattr__) - STRUCT_FOR_ID(__getattribute__) - STRUCT_FOR_ID(__getinitargs__) - STRUCT_FOR_ID(__getitem__) - STRUCT_FOR_ID(__getnewargs__) - STRUCT_FOR_ID(__getnewargs_ex__) - STRUCT_FOR_ID(__getstate__) - STRUCT_FOR_ID(__gt__) - STRUCT_FOR_ID(__hash__) - STRUCT_FOR_ID(__iadd__) - STRUCT_FOR_ID(__iand__) - STRUCT_FOR_ID(__ifloordiv__) - STRUCT_FOR_ID(__ilshift__) - STRUCT_FOR_ID(__imatmul__) - STRUCT_FOR_ID(__imod__) - STRUCT_FOR_ID(__import__) - STRUCT_FOR_ID(__imul__) - STRUCT_FOR_ID(__index__) - STRUCT_FOR_ID(__init__) - STRUCT_FOR_ID(__init_subclass__) - STRUCT_FOR_ID(__instancecheck__) - STRUCT_FOR_ID(__int__) - STRUCT_FOR_ID(__invert__) - STRUCT_FOR_ID(__ior__) - STRUCT_FOR_ID(__ipow__) - STRUCT_FOR_ID(__irshift__) - STRUCT_FOR_ID(__isabstractmethod__) - STRUCT_FOR_ID(__isub__) - STRUCT_FOR_ID(__iter__) - STRUCT_FOR_ID(__itruediv__) - STRUCT_FOR_ID(__ixor__) - STRUCT_FOR_ID(__le__) - STRUCT_FOR_ID(__len__) - STRUCT_FOR_ID(__length_hint__) - STRUCT_FOR_ID(__lltrace__) - STRUCT_FOR_ID(__loader__) - STRUCT_FOR_ID(__lshift__) - STRUCT_FOR_ID(__lt__) - STRUCT_FOR_ID(__main__) - STRUCT_FOR_ID(__matmul__) - STRUCT_FOR_ID(__missing__) - STRUCT_FOR_ID(__mod__) - STRUCT_FOR_ID(__module__) - STRUCT_FOR_ID(__mro_entries__) - STRUCT_FOR_ID(__mul__) - STRUCT_FOR_ID(__name__) - STRUCT_FOR_ID(__ne__) - STRUCT_FOR_ID(__neg__) - STRUCT_FOR_ID(__new__) - STRUCT_FOR_ID(__newobj__) - STRUCT_FOR_ID(__newobj_ex__) - STRUCT_FOR_ID(__next__) - STRUCT_FOR_ID(__notes__) - STRUCT_FOR_ID(__or__) - STRUCT_FOR_ID(__orig_class__) - STRUCT_FOR_ID(__origin__) - STRUCT_FOR_ID(__package__) - STRUCT_FOR_ID(__parameters__) - STRUCT_FOR_ID(__path__) - STRUCT_FOR_ID(__pos__) - STRUCT_FOR_ID(__pow__) - STRUCT_FOR_ID(__prepare__) - STRUCT_FOR_ID(__qualname__) - STRUCT_FOR_ID(__radd__) - STRUCT_FOR_ID(__rand__) - STRUCT_FOR_ID(__rdivmod__) - STRUCT_FOR_ID(__reduce__) - STRUCT_FOR_ID(__reduce_ex__) - STRUCT_FOR_ID(__repr__) - STRUCT_FOR_ID(__reversed__) - STRUCT_FOR_ID(__rfloordiv__) - STRUCT_FOR_ID(__rlshift__) - STRUCT_FOR_ID(__rmatmul__) - STRUCT_FOR_ID(__rmod__) - STRUCT_FOR_ID(__rmul__) - STRUCT_FOR_ID(__ror__) - STRUCT_FOR_ID(__round__) - STRUCT_FOR_ID(__rpow__) - STRUCT_FOR_ID(__rrshift__) - STRUCT_FOR_ID(__rshift__) - STRUCT_FOR_ID(__rsub__) - STRUCT_FOR_ID(__rtruediv__) - STRUCT_FOR_ID(__rxor__) - STRUCT_FOR_ID(__set__) - STRUCT_FOR_ID(__set_name__) - STRUCT_FOR_ID(__setattr__) - STRUCT_FOR_ID(__setitem__) - STRUCT_FOR_ID(__setstate__) - STRUCT_FOR_ID(__sizeof__) - STRUCT_FOR_ID(__slotnames__) - STRUCT_FOR_ID(__slots__) - STRUCT_FOR_ID(__spec__) - STRUCT_FOR_ID(__str__) - STRUCT_FOR_ID(__sub__) - STRUCT_FOR_ID(__subclasscheck__) - STRUCT_FOR_ID(__subclasshook__) - STRUCT_FOR_ID(__truediv__) - STRUCT_FOR_ID(__trunc__) - STRUCT_FOR_ID(__typing_is_unpacked_typevartuple__) - STRUCT_FOR_ID(__typing_prepare_subst__) - STRUCT_FOR_ID(__typing_subst__) - STRUCT_FOR_ID(__typing_unpacked_tuple_args__) - STRUCT_FOR_ID(__warningregistry__) - STRUCT_FOR_ID(__weakref__) - STRUCT_FOR_ID(__xor__) - STRUCT_FOR_ID(_abc_impl) - STRUCT_FOR_ID(_annotation) - STRUCT_FOR_ID(_blksize) - STRUCT_FOR_ID(_bootstrap) - STRUCT_FOR_ID(_dealloc_warn) - STRUCT_FOR_ID(_finalizing) - STRUCT_FOR_ID(_find_and_load) - STRUCT_FOR_ID(_fix_up_module) - STRUCT_FOR_ID(_get_sourcefile) - STRUCT_FOR_ID(_handle_fromlist) - STRUCT_FOR_ID(_initializing) - STRUCT_FOR_ID(_is_text_encoding) - STRUCT_FOR_ID(_lock_unlock_module) - STRUCT_FOR_ID(_showwarnmsg) - STRUCT_FOR_ID(_shutdown) - STRUCT_FOR_ID(_slotnames) - STRUCT_FOR_ID(_strptime_time) - STRUCT_FOR_ID(_uninitialized_submodules) - STRUCT_FOR_ID(_warn_unawaited_coroutine) - STRUCT_FOR_ID(_xoptions) - STRUCT_FOR_ID(add) - STRUCT_FOR_ID(append) - STRUCT_FOR_ID(big) - STRUCT_FOR_ID(buffer) - STRUCT_FOR_ID(builtins) - STRUCT_FOR_ID(c_call) - STRUCT_FOR_ID(c_exception) - STRUCT_FOR_ID(c_return) - STRUCT_FOR_ID(call) - STRUCT_FOR_ID(clear) - STRUCT_FOR_ID(close) - STRUCT_FOR_ID(closed) - STRUCT_FOR_ID(code) - STRUCT_FOR_ID(copy) - STRUCT_FOR_ID(copyreg) - STRUCT_FOR_ID(decode) - STRUCT_FOR_ID(default) - STRUCT_FOR_ID(defaultaction) - STRUCT_FOR_ID(dictcomp) - STRUCT_FOR_ID(difference_update) - STRUCT_FOR_ID(dispatch_table) - STRUCT_FOR_ID(displayhook) - STRUCT_FOR_ID(enable) - STRUCT_FOR_ID(encode) - STRUCT_FOR_ID(encoding) - STRUCT_FOR_ID(end_lineno) - STRUCT_FOR_ID(end_offset) - STRUCT_FOR_ID(errors) - STRUCT_FOR_ID(excepthook) - STRUCT_FOR_ID(exception) - STRUCT_FOR_ID(extend) - STRUCT_FOR_ID(filename) - STRUCT_FOR_ID(fileno) - STRUCT_FOR_ID(fillvalue) - STRUCT_FOR_ID(filters) - STRUCT_FOR_ID(find_class) - STRUCT_FOR_ID(flush) - STRUCT_FOR_ID(genexpr) - STRUCT_FOR_ID(get) - STRUCT_FOR_ID(get_source) - STRUCT_FOR_ID(getattr) - STRUCT_FOR_ID(getstate) - STRUCT_FOR_ID(ignore) - STRUCT_FOR_ID(importlib) - STRUCT_FOR_ID(inf) - STRUCT_FOR_ID(intersection) - STRUCT_FOR_ID(isatty) - STRUCT_FOR_ID(isinstance) - STRUCT_FOR_ID(items) - STRUCT_FOR_ID(iter) - STRUCT_FOR_ID(join) - STRUCT_FOR_ID(keys) - STRUCT_FOR_ID(lambda) - STRUCT_FOR_ID(last_traceback) - STRUCT_FOR_ID(last_type) - STRUCT_FOR_ID(last_value) - STRUCT_FOR_ID(latin1) - STRUCT_FOR_ID(len) - STRUCT_FOR_ID(line) - STRUCT_FOR_ID(lineno) - STRUCT_FOR_ID(listcomp) - STRUCT_FOR_ID(little) - STRUCT_FOR_ID(locale) - STRUCT_FOR_ID(match) - STRUCT_FOR_ID(metaclass) - STRUCT_FOR_ID(mode) - STRUCT_FOR_ID(modules) - STRUCT_FOR_ID(mro) - STRUCT_FOR_ID(msg) - STRUCT_FOR_ID(n_fields) - STRUCT_FOR_ID(n_sequence_fields) - STRUCT_FOR_ID(n_unnamed_fields) - STRUCT_FOR_ID(name) - STRUCT_FOR_ID(newlines) - STRUCT_FOR_ID(next) - STRUCT_FOR_ID(obj) - STRUCT_FOR_ID(offset) - STRUCT_FOR_ID(onceregistry) - STRUCT_FOR_ID(opcode) - STRUCT_FOR_ID(open) - STRUCT_FOR_ID(parent) - STRUCT_FOR_ID(partial) - STRUCT_FOR_ID(path) - STRUCT_FOR_ID(peek) - STRUCT_FOR_ID(persistent_id) - STRUCT_FOR_ID(persistent_load) - STRUCT_FOR_ID(print_file_and_line) - STRUCT_FOR_ID(ps1) - STRUCT_FOR_ID(ps2) - STRUCT_FOR_ID(raw) - STRUCT_FOR_ID(read) - STRUCT_FOR_ID(read1) - STRUCT_FOR_ID(readable) - STRUCT_FOR_ID(readall) - STRUCT_FOR_ID(readinto) - STRUCT_FOR_ID(readinto1) - STRUCT_FOR_ID(readline) - STRUCT_FOR_ID(reducer_override) - STRUCT_FOR_ID(reload) - STRUCT_FOR_ID(replace) - STRUCT_FOR_ID(reset) - STRUCT_FOR_ID(return) - STRUCT_FOR_ID(reversed) - STRUCT_FOR_ID(seek) - STRUCT_FOR_ID(seekable) - STRUCT_FOR_ID(send) - STRUCT_FOR_ID(setcomp) - STRUCT_FOR_ID(setstate) - STRUCT_FOR_ID(sort) - STRUCT_FOR_ID(stderr) - STRUCT_FOR_ID(stdin) - STRUCT_FOR_ID(stdout) - STRUCT_FOR_ID(strict) - STRUCT_FOR_ID(symmetric_difference_update) - STRUCT_FOR_ID(tell) - STRUCT_FOR_ID(text) - STRUCT_FOR_ID(threading) - STRUCT_FOR_ID(throw) - STRUCT_FOR_ID(top) - STRUCT_FOR_ID(truncate) - STRUCT_FOR_ID(unraisablehook) - STRUCT_FOR_ID(values) - STRUCT_FOR_ID(version) - STRUCT_FOR_ID(warnings) - STRUCT_FOR_ID(warnoptions) - STRUCT_FOR_ID(writable) - STRUCT_FOR_ID(write) - STRUCT_FOR_ID(zipimporter) - } identifiers; - struct { - PyASCIIObject _ascii; - uint8_t _data[2]; - } ascii[128]; - struct { - PyCompactUnicodeObject _latin1; - uint8_t _data[2]; - } latin1[128]; -}; -/* End auto-generated code */ - -#undef ID -#undef STR - - -#define _Py_ID(NAME) \ - (_Py_SINGLETON(strings.identifiers._ ## NAME._ascii.ob_base)) -#define _Py_STR(NAME) \ - (_Py_SINGLETON(strings.literals._ ## NAME._ascii.ob_base)) - -/* _Py_DECLARE_STR() should precede all uses of _Py_STR() in a function. - - This is true even if the same string has already been declared - elsewhere, even in the same file. Mismatched duplicates are detected - by Tools/scripts/generate-global-objects.py. - - Pairing _Py_DECLARE_STR() with every use of _Py_STR() makes sure the - string keeps working even if the declaration is removed somewhere - else. It also makes it clear what the actual string is at every - place it is being used. */ -#define _Py_DECLARE_STR(name, str) - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_GLOBAL_STRINGS_H */ diff --git a/python/include/internal/pycore_hamt.h b/python/include/internal/pycore_hamt.h deleted file mode 100644 index 0cb2b67..0000000 --- a/python/include/internal/pycore_hamt.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef Py_INTERNAL_HAMT_H -#define Py_INTERNAL_HAMT_H - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - - -/* -HAMT tree is shaped by hashes of keys. Every group of 5 bits of a hash denotes -the exact position of the key in one level of the tree. Since we're using -32 bit hashes, we can have at most 7 such levels. Although if there are -two distinct keys with equal hashes, they will have to occupy the same -cell in the 7th level of the tree -- so we'd put them in a "collision" node. -Which brings the total possible tree depth to 8. Read more about the actual -layout of the HAMT tree in `hamt.c`. - -This constant is used to define a datastucture for storing iteration state. -*/ -#define _Py_HAMT_MAX_TREE_DEPTH 8 - - -extern PyTypeObject _PyHamt_Type; -extern PyTypeObject _PyHamt_ArrayNode_Type; -extern PyTypeObject _PyHamt_BitmapNode_Type; -extern PyTypeObject _PyHamt_CollisionNode_Type; -extern PyTypeObject _PyHamtKeys_Type; -extern PyTypeObject _PyHamtValues_Type; -extern PyTypeObject _PyHamtItems_Type; - -/* runtime lifecycle */ - -void _PyHamt_Fini(PyInterpreterState *); - - -/* other API */ - -#define PyHamt_Check(o) Py_IS_TYPE(o, &_PyHamt_Type) - - -/* Abstract tree node. */ -typedef struct { - PyObject_HEAD -} PyHamtNode; - - -/* An HAMT immutable mapping collection. */ -typedef struct { - PyObject_HEAD - PyHamtNode *h_root; - PyObject *h_weakreflist; - Py_ssize_t h_count; -} PyHamtObject; - - -/* A struct to hold the state of depth-first traverse of the tree. - - HAMT is an immutable collection. Iterators will hold a strong reference - to it, and every node in the HAMT has strong references to its children. - - So for iterators, we can implement zero allocations and zero reference - inc/dec depth-first iteration. - - - i_nodes: an array of seven pointers to tree nodes - - i_level: the current node in i_nodes - - i_pos: an array of positions within nodes in i_nodes. -*/ -typedef struct { - PyHamtNode *i_nodes[_Py_HAMT_MAX_TREE_DEPTH]; - Py_ssize_t i_pos[_Py_HAMT_MAX_TREE_DEPTH]; - int8_t i_level; -} PyHamtIteratorState; - - -/* Base iterator object. - - Contains the iteration state, a pointer to the HAMT tree, - and a pointer to the 'yield function'. The latter is a simple - function that returns a key/value tuple for the 'Items' iterator, - just a key for the 'Keys' iterator, and a value for the 'Values' - iterator. -*/ -typedef struct { - PyObject_HEAD - PyHamtObject *hi_obj; - PyHamtIteratorState hi_iter; - binaryfunc hi_yield; -} PyHamtIterator; - - -/* Create a new HAMT immutable mapping. */ -PyHamtObject * _PyHamt_New(void); - -/* Return a new collection based on "o", but with an additional - key/val pair. */ -PyHamtObject * _PyHamt_Assoc(PyHamtObject *o, PyObject *key, PyObject *val); - -/* Return a new collection based on "o", but without "key". */ -PyHamtObject * _PyHamt_Without(PyHamtObject *o, PyObject *key); - -/* Find "key" in the "o" collection. - - Return: - - -1: An error occurred. - - 0: "key" wasn't found in "o". - - 1: "key" is in "o"; "*val" is set to its value (a borrowed ref). -*/ -int _PyHamt_Find(PyHamtObject *o, PyObject *key, PyObject **val); - -/* Check if "v" is equal to "w". - - Return: - - 0: v != w - - 1: v == w - - -1: An error occurred. -*/ -int _PyHamt_Eq(PyHamtObject *v, PyHamtObject *w); - -/* Return the size of "o"; equivalent of "len(o)". */ -Py_ssize_t _PyHamt_Len(PyHamtObject *o); - -/* Return a Keys iterator over "o". */ -PyObject * _PyHamt_NewIterKeys(PyHamtObject *o); - -/* Return a Values iterator over "o". */ -PyObject * _PyHamt_NewIterValues(PyHamtObject *o); - -/* Return a Items iterator over "o". */ -PyObject * _PyHamt_NewIterItems(PyHamtObject *o); - -#endif /* !Py_INTERNAL_HAMT_H */ diff --git a/python/include/internal/pycore_hashtable.h b/python/include/internal/pycore_hashtable.h deleted file mode 100644 index 8fa411a..0000000 --- a/python/include/internal/pycore_hashtable.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef Py_INTERNAL_HASHTABLE_H -#define Py_INTERNAL_HASHTABLE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -/* Single linked list */ - -typedef struct _Py_slist_item_s { - struct _Py_slist_item_s *next; -} _Py_slist_item_t; - -typedef struct { - _Py_slist_item_t *head; -} _Py_slist_t; - -#define _Py_SLIST_ITEM_NEXT(ITEM) (((_Py_slist_item_t *)ITEM)->next) - -#define _Py_SLIST_HEAD(SLIST) (((_Py_slist_t *)SLIST)->head) - - -/* _Py_hashtable: table entry */ - -typedef struct { - /* used by _Py_hashtable_t.buckets to link entries */ - _Py_slist_item_t _Py_slist_item; - - Py_uhash_t key_hash; - void *key; - void *value; -} _Py_hashtable_entry_t; - - -/* _Py_hashtable: prototypes */ - -/* Forward declaration */ -struct _Py_hashtable_t; -typedef struct _Py_hashtable_t _Py_hashtable_t; - -typedef Py_uhash_t (*_Py_hashtable_hash_func) (const void *key); -typedef int (*_Py_hashtable_compare_func) (const void *key1, const void *key2); -typedef void (*_Py_hashtable_destroy_func) (void *key); -typedef _Py_hashtable_entry_t* (*_Py_hashtable_get_entry_func)(_Py_hashtable_t *ht, - const void *key); - -typedef struct { - // Allocate a memory block - void* (*malloc) (size_t size); - - // Release a memory block - void (*free) (void *ptr); -} _Py_hashtable_allocator_t; - - -/* _Py_hashtable: table */ -struct _Py_hashtable_t { - size_t nentries; // Total number of entries in the table - size_t nbuckets; - _Py_slist_t *buckets; - - _Py_hashtable_get_entry_func get_entry_func; - _Py_hashtable_hash_func hash_func; - _Py_hashtable_compare_func compare_func; - _Py_hashtable_destroy_func key_destroy_func; - _Py_hashtable_destroy_func value_destroy_func; - _Py_hashtable_allocator_t alloc; -}; - -/* Hash a pointer (void*) */ -PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr(const void *key); - -/* Comparison using memcmp() */ -PyAPI_FUNC(int) _Py_hashtable_compare_direct( - const void *key1, - const void *key2); - -PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new( - _Py_hashtable_hash_func hash_func, - _Py_hashtable_compare_func compare_func); - -PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new_full( - _Py_hashtable_hash_func hash_func, - _Py_hashtable_compare_func compare_func, - _Py_hashtable_destroy_func key_destroy_func, - _Py_hashtable_destroy_func value_destroy_func, - _Py_hashtable_allocator_t *allocator); - -PyAPI_FUNC(void) _Py_hashtable_destroy(_Py_hashtable_t *ht); - -PyAPI_FUNC(void) _Py_hashtable_clear(_Py_hashtable_t *ht); - -typedef int (*_Py_hashtable_foreach_func) (_Py_hashtable_t *ht, - const void *key, const void *value, - void *user_data); - -/* Call func() on each entry of the hashtable. - Iteration stops if func() result is non-zero, in this case it's the result - of the call. Otherwise, the function returns 0. */ -PyAPI_FUNC(int) _Py_hashtable_foreach( - _Py_hashtable_t *ht, - _Py_hashtable_foreach_func func, - void *user_data); - -PyAPI_FUNC(size_t) _Py_hashtable_size(const _Py_hashtable_t *ht); - -/* Add a new entry to the hash. The key must not be present in the hash table. - Return 0 on success, -1 on memory error. */ -PyAPI_FUNC(int) _Py_hashtable_set( - _Py_hashtable_t *ht, - const void *key, - void *value); - - -/* Get an entry. - Return NULL if the key does not exist. */ -static inline _Py_hashtable_entry_t * -_Py_hashtable_get_entry(_Py_hashtable_t *ht, const void *key) -{ - return ht->get_entry_func(ht, key); -} - - -/* Get value from an entry. - Return NULL if the entry is not found. - - Use _Py_hashtable_get_entry() to distinguish entry value equal to NULL - and entry not found. */ -PyAPI_FUNC(void*) _Py_hashtable_get(_Py_hashtable_t *ht, const void *key); - - -/* Remove a key and its associated value without calling key and value destroy - functions. - - Return the removed value if the key was found. - Return NULL if the key was not found. */ -PyAPI_FUNC(void*) _Py_hashtable_steal( - _Py_hashtable_t *ht, - const void *key); - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_HASHTABLE_H */ diff --git a/python/include/internal/pycore_import.h b/python/include/internal/pycore_import.h deleted file mode 100644 index 8b9bd66..0000000 --- a/python/include/internal/pycore_import.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_INTERNAL_IMPORT_H -#define Py_INTERNAL_IMPORT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_FORK -extern PyStatus _PyImport_ReInitLock(void); -#endif -extern PyObject* _PyImport_BootstrapImp(PyThreadState *tstate); - -struct _module_alias { - const char *name; /* ASCII encoded string */ - const char *orig; /* ASCII encoded string */ -}; - -PyAPI_DATA(const struct _frozen *) _PyImport_FrozenBootstrap; -PyAPI_DATA(const struct _frozen *) _PyImport_FrozenStdlib; -PyAPI_DATA(const struct _frozen *) _PyImport_FrozenTest; -extern const struct _module_alias * _PyImport_FrozenAliases; - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_IMPORT_H */ -#endif /* !Py_LIMITED_API */ diff --git a/python/include/internal/pycore_initconfig.h b/python/include/internal/pycore_initconfig.h deleted file mode 100644 index 5e0c245..0000000 --- a/python/include/internal/pycore_initconfig.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef Py_INTERNAL_CORECONFIG_H -#define Py_INTERNAL_CORECONFIG_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -/* Forward declaration */ -struct pyruntimestate; - -/* --- PyStatus ----------------------------------------------- */ - -/* Almost all errors causing Python initialization to fail */ -#ifdef _MSC_VER - /* Visual Studio 2015 doesn't implement C99 __func__ in C */ -# define _PyStatus_GET_FUNC() __FUNCTION__ -#else -# define _PyStatus_GET_FUNC() __func__ -#endif - -#define _PyStatus_OK() \ - (PyStatus){._type = _PyStatus_TYPE_OK,} - /* other fields are set to 0 */ -#define _PyStatus_ERR(ERR_MSG) \ - (PyStatus){ \ - ._type = _PyStatus_TYPE_ERROR, \ - .func = _PyStatus_GET_FUNC(), \ - .err_msg = (ERR_MSG)} - /* other fields are set to 0 */ -#define _PyStatus_NO_MEMORY() _PyStatus_ERR("memory allocation failed") -#define _PyStatus_EXIT(EXITCODE) \ - (PyStatus){ \ - ._type = _PyStatus_TYPE_EXIT, \ - .exitcode = (EXITCODE)} -#define _PyStatus_IS_ERROR(err) \ - (err._type == _PyStatus_TYPE_ERROR) -#define _PyStatus_IS_EXIT(err) \ - (err._type == _PyStatus_TYPE_EXIT) -#define _PyStatus_EXCEPTION(err) \ - (err._type != _PyStatus_TYPE_OK) -#define _PyStatus_UPDATE_FUNC(err) \ - do { err.func = _PyStatus_GET_FUNC(); } while (0) - -PyObject* _PyErr_SetFromPyStatus(PyStatus status); - -/* --- PyWideStringList ------------------------------------------------ */ - -#define _PyWideStringList_INIT (PyWideStringList){.length = 0, .items = NULL} - -#ifndef NDEBUG -PyAPI_FUNC(int) _PyWideStringList_CheckConsistency(const PyWideStringList *list); -#endif -PyAPI_FUNC(void) _PyWideStringList_Clear(PyWideStringList *list); -PyAPI_FUNC(int) _PyWideStringList_Copy(PyWideStringList *list, - const PyWideStringList *list2); -PyAPI_FUNC(PyStatus) _PyWideStringList_Extend(PyWideStringList *list, - const PyWideStringList *list2); -PyAPI_FUNC(PyObject*) _PyWideStringList_AsList(const PyWideStringList *list); - - -/* --- _PyArgv ---------------------------------------------------- */ - -typedef struct _PyArgv { - Py_ssize_t argc; - int use_bytes_argv; - char * const *bytes_argv; - wchar_t * const *wchar_argv; -} _PyArgv; - -PyAPI_FUNC(PyStatus) _PyArgv_AsWstrList(const _PyArgv *args, - PyWideStringList *list); - - -/* --- Helper functions ------------------------------------------- */ - -PyAPI_FUNC(int) _Py_str_to_int( - const char *str, - int *result); -PyAPI_FUNC(const wchar_t*) _Py_get_xoption( - const PyWideStringList *xoptions, - const wchar_t *name); -PyAPI_FUNC(const char*) _Py_GetEnv( - int use_environment, - const char *name); -PyAPI_FUNC(void) _Py_get_env_flag( - int use_environment, - int *flag, - const char *name); - -/* Py_GetArgcArgv() helper */ -PyAPI_FUNC(void) _Py_ClearArgcArgv(void); - - -/* --- _PyPreCmdline ------------------------------------------------- */ - -typedef struct { - PyWideStringList argv; - PyWideStringList xoptions; /* "-X value" option */ - int isolated; /* -I option */ - int use_environment; /* -E option */ - int dev_mode; /* -X dev and PYTHONDEVMODE */ - int warn_default_encoding; /* -X warn_default_encoding and PYTHONWARNDEFAULTENCODING */ -} _PyPreCmdline; - -#define _PyPreCmdline_INIT \ - (_PyPreCmdline){ \ - .use_environment = -1, \ - .isolated = -1, \ - .dev_mode = -1} -/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */ - -extern void _PyPreCmdline_Clear(_PyPreCmdline *cmdline); -extern PyStatus _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, - const _PyArgv *args); -extern PyStatus _PyPreCmdline_SetConfig( - const _PyPreCmdline *cmdline, - PyConfig *config); -extern PyStatus _PyPreCmdline_Read(_PyPreCmdline *cmdline, - const PyPreConfig *preconfig); - - -/* --- PyPreConfig ----------------------------------------------- */ - -PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(PyPreConfig *preconfig); -extern void _PyPreConfig_InitFromConfig( - PyPreConfig *preconfig, - const PyConfig *config); -extern PyStatus _PyPreConfig_InitFromPreConfig( - PyPreConfig *preconfig, - const PyPreConfig *config2); -extern PyObject* _PyPreConfig_AsDict(const PyPreConfig *preconfig); -extern void _PyPreConfig_GetConfig(PyPreConfig *preconfig, - const PyConfig *config); -extern PyStatus _PyPreConfig_Read(PyPreConfig *preconfig, - const _PyArgv *args); -extern PyStatus _PyPreConfig_Write(const PyPreConfig *preconfig); - - -/* --- PyConfig ---------------------------------------------- */ - -typedef enum { - /* Py_Initialize() API: backward compatibility with Python 3.6 and 3.7 */ - _PyConfig_INIT_COMPAT = 1, - _PyConfig_INIT_PYTHON = 2, - _PyConfig_INIT_ISOLATED = 3 -} _PyConfigInitEnum; - -PyAPI_FUNC(void) _PyConfig_InitCompatConfig(PyConfig *config); -extern PyStatus _PyConfig_Copy( - PyConfig *config, - const PyConfig *config2); -extern PyStatus _PyConfig_InitPathConfig( - PyConfig *config, - int compute_path_config); -extern PyStatus _PyConfig_InitImportConfig(PyConfig *config); -extern PyStatus _PyConfig_Read(PyConfig *config, int compute_path_config); -extern PyStatus _PyConfig_Write(const PyConfig *config, - struct pyruntimestate *runtime); -extern PyStatus _PyConfig_SetPyArgv( - PyConfig *config, - const _PyArgv *args); - -PyAPI_FUNC(PyObject*) _PyConfig_AsDict(const PyConfig *config); -PyAPI_FUNC(int) _PyConfig_FromDict(PyConfig *config, PyObject *dict); - -extern void _Py_DumpPathConfig(PyThreadState *tstate); - -PyAPI_FUNC(PyObject*) _Py_Get_Getpath_CodeObject(void); - -extern int _Py_global_config_int_max_str_digits; - - -/* --- Function used for testing ---------------------------------- */ - -PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_CORECONFIG_H */ diff --git a/python/include/internal/pycore_interp.h b/python/include/internal/pycore_interp.h deleted file mode 100644 index 6e072fe..0000000 --- a/python/include/internal/pycore_interp.h +++ /dev/null @@ -1,227 +0,0 @@ -#ifndef Py_INTERNAL_INTERP_H -#define Py_INTERNAL_INTERP_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include - -#include "pycore_atomic.h" // _Py_atomic_address -#include "pycore_ast_state.h" // struct ast_state -#include "pycore_code.h" // struct callable_cache -#include "pycore_context.h" // struct _Py_context_state -#include "pycore_dict.h" // struct _Py_dict_state -#include "pycore_exceptions.h" // struct _Py_exc_state -#include "pycore_floatobject.h" // struct _Py_float_state -#include "pycore_genobject.h" // struct _Py_async_gen_state -#include "pycore_gil.h" // struct _gil_runtime_state -#include "pycore_gc.h" // struct _gc_runtime_state -#include "pycore_list.h" // struct _Py_list_state -#include "pycore_tuple.h" // struct _Py_tuple_state -#include "pycore_typeobject.h" // struct type_cache -#include "pycore_unicodeobject.h" // struct _Py_unicode_state -#include "pycore_warnings.h" // struct _warnings_runtime_state - -struct _pending_calls { - PyThread_type_lock lock; - /* Request for running pending calls. */ - _Py_atomic_int calls_to_do; - /* Request for looking at the `async_exc` field of the current - thread state. - Guarded by the GIL. */ - int async_exc; -#define NPENDINGCALLS 32 - struct { - int (*func)(void *); - void *arg; - } calls[NPENDINGCALLS]; - int first; - int last; -}; - -struct _ceval_state { - int recursion_limit; - /* This single variable consolidates all requests to break out of - the fast path in the eval loop. */ - _Py_atomic_int eval_breaker; - /* Request for dropping the GIL */ - _Py_atomic_int gil_drop_request; - struct _pending_calls pending; -}; - - -// atexit state -typedef struct { - PyObject *func; - PyObject *args; - PyObject *kwargs; -} atexit_callback; - -struct atexit_state { - atexit_callback **callbacks; - int ncallbacks; - int callback_len; -}; - - -/* interpreter state */ - -/* PyInterpreterState holds the global state for one of the runtime's - interpreters. Typically the initial (main) interpreter is the only one. - - The PyInterpreterState typedef is in Include/pystate.h. - */ -struct _is { - - PyInterpreterState *next; - - struct pythreads { - uint64_t next_unique_id; - /* The linked list of threads, newest first. */ - PyThreadState *head; - /* Used in Modules/_threadmodule.c. */ - long count; - /* Support for runtime thread stack size tuning. - A value of 0 means using the platform's default stack size - or the size specified by the THREAD_STACK_SIZE macro. */ - /* Used in Python/thread.c. */ - size_t stacksize; - } threads; - - /* Reference to the _PyRuntime global variable. This field exists - to not have to pass runtime in addition to tstate to a function. - Get runtime from tstate: tstate->interp->runtime. */ - struct pyruntimestate *runtime; - - int64_t id; - int64_t id_refcount; - int requires_idref; - PyThread_type_lock id_mutex; - - /* Has been initialized to a safe state. - - In order to be effective, this must be set to 0 during or right - after allocation. */ - int _initialized; - int finalizing; - - /* Was this interpreter statically allocated? */ - bool _static; - - struct _ceval_state ceval; - struct _gc_runtime_state gc; - - // sys.modules dictionary - PyObject *modules; - PyObject *modules_by_index; - // Dictionary of the sys module - PyObject *sysdict; - // Dictionary of the builtins module - PyObject *builtins; - // importlib module - PyObject *importlib; - // override for config->use_frozen_modules (for tests) - // (-1: "off", 1: "on", 0: no override) - int override_frozen_modules; - - PyObject *codec_search_path; - PyObject *codec_search_cache; - PyObject *codec_error_registry; - int codecs_initialized; - - PyConfig config; -#ifdef HAVE_DLOPEN - int dlopenflags; -#endif - - PyObject *dict; /* Stores per-interpreter state */ - - PyObject *builtins_copy; - PyObject *import_func; - // Initialized to _PyEval_EvalFrameDefault(). - _PyFrameEvalFunction eval_frame; - - Py_ssize_t co_extra_user_count; - freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; - -#ifdef HAVE_FORK - PyObject *before_forkers; - PyObject *after_forkers_parent; - PyObject *after_forkers_child; -#endif - - struct _warnings_runtime_state warnings; - struct atexit_state atexit; - - PyObject *audit_hooks; - - struct _Py_unicode_state unicode; - struct _Py_float_state float_state; - /* Using a cache is very effective since typically only a single slice is - created and then deleted again. */ - PySliceObject *slice_cache; - - struct _Py_tuple_state tuple; - struct _Py_list_state list; - struct _Py_dict_state dict_state; - struct _Py_async_gen_state async_gen; - struct _Py_context_state context; - struct _Py_exc_state exc_state; - - struct ast_state ast; - struct type_cache type_cache; - struct callable_cache callable_cache; - - int int_max_str_digits; - - /* The following fields are here to avoid allocation during init. - The data is exposed through PyInterpreterState pointer fields. - These fields should not be accessed directly outside of init. - - All other PyInterpreterState pointer fields are populated when - needed and default to NULL. - - For now there are some exceptions to that rule, which require - allocation during init. These will be addressed on a case-by-case - basis. Also see _PyRuntimeState regarding the various mutex fields. - */ - - /* the initial PyInterpreterState.threads.head */ - PyThreadState _initial_thread; -}; - - -/* other API */ - -extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp); -extern void _PyInterpreterState_Clear(PyThreadState *tstate); - - -/* cross-interpreter data registry */ - -/* For now we use a global registry of shareable classes. An - alternative would be to add a tp_* slot for a class's - crossinterpdatafunc. It would be simpler and more efficient. */ - -struct _xidregitem; - -struct _xidregitem { - PyTypeObject *cls; - crossinterpdatafunc getdata; - struct _xidregitem *next; -}; - -PyAPI_FUNC(PyInterpreterState*) _PyInterpreterState_LookUpID(int64_t); - -PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *); -PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *); -PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_INTERP_H */ diff --git a/python/include/internal/pycore_interpreteridobject.h b/python/include/internal/pycore_interpreteridobject.h deleted file mode 100644 index 3c477a3..0000000 --- a/python/include/internal/pycore_interpreteridobject.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Interpreter ID Object */ - -#ifndef Py_INTERNAL_INTERPRETERIDOBJECT_H -#define Py_INTERNAL_INTERPRETERIDOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -PyAPI_DATA(PyTypeObject) _PyInterpreterID_Type; - -PyAPI_FUNC(PyObject *) _PyInterpreterID_New(int64_t); -PyAPI_FUNC(PyObject *) _PyInterpreterState_GetIDObject(PyInterpreterState *); -PyAPI_FUNC(PyInterpreterState *) _PyInterpreterID_LookUp(PyObject *); - -#ifdef __cplusplus -} -#endif -#endif // !Py_INTERNAL_INTERPRETERIDOBJECT_H diff --git a/python/include/internal/pycore_list.h b/python/include/internal/pycore_list.h deleted file mode 100644 index 8fd6ec7..0000000 --- a/python/include/internal/pycore_list.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef Py_INTERNAL_LIST_H -#define Py_INTERNAL_LIST_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "listobject.h" // _PyList_CAST() - - -/* runtime lifecycle */ - -extern void _PyList_Fini(PyInterpreterState *); - - -/* other API */ - -#ifndef WITH_FREELISTS -// without freelists -# define PyList_MAXFREELIST 0 -#endif - -/* Empty list reuse scheme to save calls to malloc and free */ -#ifndef PyList_MAXFREELIST -# define PyList_MAXFREELIST 80 -#endif - -struct _Py_list_state { -#if PyList_MAXFREELIST > 0 - PyListObject *free_list[PyList_MAXFREELIST]; - int numfree; -#endif -}; - -#define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item) - -extern int -_PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem); - -static inline int -_PyList_AppendTakeRef(PyListObject *self, PyObject *newitem) -{ - assert(self != NULL && newitem != NULL); - assert(PyList_Check(self)); - Py_ssize_t len = PyList_GET_SIZE(self); - Py_ssize_t allocated = self->allocated; - assert((size_t)len + 1 < PY_SSIZE_T_MAX); - if (allocated > len) { - PyList_SET_ITEM(self, len, newitem); - Py_SET_SIZE(self, len + 1); - return 0; - } - return _PyList_AppendTakeRefListResize(self, newitem); -} - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_LIST_H */ diff --git a/python/include/internal/pycore_long.h b/python/include/internal/pycore_long.h deleted file mode 100644 index 3a80001..0000000 --- a/python/include/internal/pycore_long.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef Py_INTERNAL_LONG_H -#define Py_INTERNAL_LONG_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_global_objects.h" // _PY_NSMALLNEGINTS -#include "pycore_runtime.h" // _PyRuntime - -/* - * Default int base conversion size limitation: Denial of Service prevention. - * - * Chosen such that this isn't wildly slow on modern hardware and so that - * everyone's existing deployed numpy test suite passes before - * https://github.com/numpy/numpy/issues/22098 is widely available. - * - * $ python -m timeit -s 's = "1"*4300' 'int(s)' - * 2000 loops, best of 5: 125 usec per loop - * $ python -m timeit -s 's = "1"*4300; v = int(s)' 'str(v)' - * 1000 loops, best of 5: 311 usec per loop - * (zen2 cloud VM) - * - * 4300 decimal digits fits a ~14284 bit number. - */ -#define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300 -/* - * Threshold for max digits check. For performance reasons int() and - * int.__str__() don't checks values that are smaller than this - * threshold. Acts as a guaranteed minimum size limit for bignums that - * applications can expect from CPython. - * - * % python -m timeit -s 's = "1"*640; v = int(s)' 'str(int(s))' - * 20000 loops, best of 5: 12 usec per loop - * - * "640 digits should be enough for anyone." - gps - * fits a ~2126 bit decimal number. - */ -#define _PY_LONG_MAX_STR_DIGITS_THRESHOLD 640 - -#if ((_PY_LONG_DEFAULT_MAX_STR_DIGITS != 0) && \ - (_PY_LONG_DEFAULT_MAX_STR_DIGITS < _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) -# error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold." -#endif - - -/* runtime lifecycle */ - -extern PyStatus _PyLong_InitTypes(PyInterpreterState *); -extern void _PyLong_FiniTypes(PyInterpreterState *interp); - - -/* other API */ - -#define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints) - -// _PyLong_GetZero() and _PyLong_GetOne() must always be available -// _PyLong_FromUnsignedChar must always be available -#if _PY_NSMALLPOSINTS < 257 -# error "_PY_NSMALLPOSINTS must be greater than or equal to 257" -#endif - -// Return a borrowed reference to the zero singleton. -// The function cannot return NULL. -static inline PyObject* _PyLong_GetZero(void) -{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; } - -// Return a borrowed reference to the one singleton. -// The function cannot return NULL. -static inline PyObject* _PyLong_GetOne(void) -{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; } - -static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i) -{ - return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]); -} - -PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right); -PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right); -PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right); - -/* Used by Python/mystrtoul.c, _PyBytes_FromHex(), - _PyBytes_DecodeEscape(), etc. */ -PyAPI_DATA(unsigned char) _PyLong_DigitValue[256]; - -/* Format the object based on the format_spec, as defined in PEP 3101 - (Advanced String Formatting). */ -PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter( - _PyUnicodeWriter *writer, - PyObject *obj, - PyObject *format_spec, - Py_ssize_t start, - Py_ssize_t end); - -PyAPI_FUNC(int) _PyLong_FormatWriter( - _PyUnicodeWriter *writer, - PyObject *obj, - int base, - int alternate); - -PyAPI_FUNC(char*) _PyLong_FormatBytesWriter( - _PyBytesWriter *writer, - char *str, - PyObject *obj, - int base, - int alternate); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_LONG_H */ diff --git a/python/include/internal/pycore_moduleobject.h b/python/include/internal/pycore_moduleobject.h deleted file mode 100644 index 85d466c..0000000 --- a/python/include/internal/pycore_moduleobject.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef Py_INTERNAL_MODULEOBJECT_H -#define Py_INTERNAL_MODULEOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -typedef struct { - PyObject_HEAD - PyObject *md_dict; - PyModuleDef *md_def; - void *md_state; - PyObject *md_weaklist; - // for logging purposes after md_dict is cleared - PyObject *md_name; -} PyModuleObject; - -static inline PyModuleDef* _PyModule_GetDef(PyObject *mod) { - assert(PyModule_Check(mod)); - return ((PyModuleObject *)mod)->md_def; -} - -static inline void* _PyModule_GetState(PyObject* mod) { - assert(PyModule_Check(mod)); - return ((PyModuleObject *)mod)->md_state; -} - -static inline PyObject* _PyModule_GetDict(PyObject *mod) { - assert(PyModule_Check(mod)); - PyObject *dict = ((PyModuleObject *)mod) -> md_dict; - // _PyModule_GetDict(mod) must not be used after calling module_clear(mod) - assert(dict != NULL); - return dict; -} - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_MODULEOBJECT_H */ diff --git a/python/include/internal/pycore_namespace.h b/python/include/internal/pycore_namespace.h deleted file mode 100644 index 9c1d334..0000000 --- a/python/include/internal/pycore_namespace.h +++ /dev/null @@ -1,20 +0,0 @@ -// Simple namespace object interface - -#ifndef Py_INTERNAL_NAMESPACE_H -#define Py_INTERNAL_NAMESPACE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -PyAPI_DATA(PyTypeObject) _PyNamespace_Type; - -PyAPI_FUNC(PyObject *) _PyNamespace_New(PyObject *kwds); - -#ifdef __cplusplus -} -#endif -#endif // !Py_INTERNAL_NAMESPACE_H diff --git a/python/include/internal/pycore_object.h b/python/include/internal/pycore_object.h deleted file mode 100644 index 72182af..0000000 --- a/python/include/internal/pycore_object.h +++ /dev/null @@ -1,310 +0,0 @@ -#ifndef Py_INTERNAL_OBJECT_H -#define Py_INTERNAL_OBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include -#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() -#include "pycore_interp.h" // PyInterpreterState.gc -#include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_runtime.h" // _PyRuntime - -#define _PyObject_IMMORTAL_INIT(type) \ - { \ - .ob_refcnt = 999999999, \ - .ob_type = type, \ - } -#define _PyVarObject_IMMORTAL_INIT(type, size) \ - { \ - .ob_base = _PyObject_IMMORTAL_INIT(type), \ - .ob_size = size, \ - } - -PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc( - const char *func, - const char *message); - -#define _Py_FatalRefcountError(message) _Py_FatalRefcountErrorFunc(__func__, message) - -static inline void -_Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct) -{ -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif - if (--op->ob_refcnt != 0) { - assert(op->ob_refcnt > 0); - } - else { -#ifdef Py_TRACE_REFS - _Py_ForgetReference(op); -#endif - destruct(op); - } -} - -static inline void -_Py_DECREF_NO_DEALLOC(PyObject *op) -{ -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif - op->ob_refcnt--; -#ifdef Py_DEBUG - if (op->ob_refcnt <= 0) { - _Py_FatalRefcountError("Expected a positive remaining refcount"); - } -#endif -} - -PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type); -PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); - -/* Update the Python traceback of an object. This function must be called - when a memory block is reused from a free list. - - Internal function called by _Py_NewReference(). */ -extern int _PyTraceMalloc_NewReference(PyObject *op); - -// Fast inlined version of PyType_HasFeature() -static inline int -_PyType_HasFeature(PyTypeObject *type, unsigned long feature) { - return ((type->tp_flags & feature) != 0); -} - -extern void _PyType_InitCache(PyInterpreterState *interp); - - -/* Inline functions trading binary compatibility for speed: - _PyObject_Init() is the fast version of PyObject_Init(), and - _PyObject_InitVar() is the fast version of PyObject_InitVar(). - - These inline functions must not be called with op=NULL. */ -static inline void -_PyObject_Init(PyObject *op, PyTypeObject *typeobj) -{ - assert(op != NULL); - Py_SET_TYPE(op, typeobj); - if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) { - Py_INCREF(typeobj); - } - _Py_NewReference(op); -} - -static inline void -_PyObject_InitVar(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size) -{ - assert(op != NULL); - Py_SET_SIZE(op, size); - _PyObject_Init((PyObject *)op, typeobj); -} - - -/* Tell the GC to track this object. - * - * The object must not be tracked by the GC. - * - * NB: While the object is tracked by the collector, it must be safe to call the - * ob_traverse method. - * - * Internal note: interp->gc.generation0->_gc_prev doesn't have any bit flags - * because it's not object header. So we don't use _PyGCHead_PREV() and - * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. - * - * See also the public PyObject_GC_Track() function. - */ -static inline void _PyObject_GC_TRACK( -// The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined -#ifndef NDEBUG - const char *filename, int lineno, -#endif - PyObject *op) -{ - _PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op), - "object already tracked by the garbage collector", - filename, lineno, __func__); - - PyGC_Head *gc = _Py_AS_GC(op); - _PyObject_ASSERT_FROM(op, - (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0, - "object is in generation which is garbage collected", - filename, lineno, __func__); - - PyInterpreterState *interp = _PyInterpreterState_GET(); - PyGC_Head *generation0 = interp->gc.generation0; - PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev); - _PyGCHead_SET_NEXT(last, gc); - _PyGCHead_SET_PREV(gc, last); - _PyGCHead_SET_NEXT(gc, generation0); - generation0->_gc_prev = (uintptr_t)gc; -} - -/* Tell the GC to stop tracking this object. - * - * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING - * must be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept. - * - * The object must be tracked by the GC. - * - * See also the public PyObject_GC_UnTrack() which accept an object which is - * not tracked. - */ -static inline void _PyObject_GC_UNTRACK( -// The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined -#ifndef NDEBUG - const char *filename, int lineno, -#endif - PyObject *op) -{ - _PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op), - "object not tracked by the garbage collector", - filename, lineno, __func__); - - PyGC_Head *gc = _Py_AS_GC(op); - PyGC_Head *prev = _PyGCHead_PREV(gc); - PyGC_Head *next = _PyGCHead_NEXT(gc); - _PyGCHead_SET_NEXT(prev, next); - _PyGCHead_SET_PREV(next, prev); - gc->_gc_next = 0; - gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED; -} - -// Macros to accept any type for the parameter, and to automatically pass -// the filename and the filename (if NDEBUG is not defined) where the macro -// is called. -#ifdef NDEBUG -# define _PyObject_GC_TRACK(op) \ - _PyObject_GC_TRACK(_PyObject_CAST(op)) -# define _PyObject_GC_UNTRACK(op) \ - _PyObject_GC_UNTRACK(_PyObject_CAST(op)) -#else -# define _PyObject_GC_TRACK(op) \ - _PyObject_GC_TRACK(__FILE__, __LINE__, _PyObject_CAST(op)) -# define _PyObject_GC_UNTRACK(op) \ - _PyObject_GC_UNTRACK(__FILE__, __LINE__, _PyObject_CAST(op)) -#endif - -#ifdef Py_REF_DEBUG -extern void _PyDebug_PrintTotalRefs(void); -#endif - -#ifdef Py_TRACE_REFS -extern void _Py_AddToAllObjects(PyObject *op, int force); -extern void _Py_PrintReferences(FILE *); -extern void _Py_PrintReferenceAddresses(FILE *); -#endif - -static inline PyObject ** -_PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) -{ - Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; - return (PyObject **)((char *)op + offset); -} - -// Fast inlined version of PyObject_IS_GC() -static inline int -_PyObject_IS_GC(PyObject *obj) -{ - return (PyType_IS_GC(Py_TYPE(obj)) - && (Py_TYPE(obj)->tp_is_gc == NULL - || Py_TYPE(obj)->tp_is_gc(obj))); -} - -// Fast inlined version of PyType_IS_GC() -#define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) - -static inline size_t -_PyType_PreHeaderSize(PyTypeObject *tp) -{ - return _PyType_IS_GC(tp) * sizeof(PyGC_Head) + - _PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT) * 2 * sizeof(PyObject *); -} - -void _PyObject_GC_Link(PyObject *op); - -// Usage: assert(_Py_CheckSlotResult(obj, "__getitem__", result != NULL)); -extern int _Py_CheckSlotResult( - PyObject *obj, - const char *slot_name, - int success); - -// PyType_Ready() must be called if _PyType_IsReady() is false. -// See also the Py_TPFLAGS_READY flag. -#define _PyType_IsReady(type) ((type)->tp_dict != NULL) - -// Test if a type supports weak references -static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) { - return (type->tp_weaklistoffset > 0); -} - -extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems); - -extern int _PyObject_InitializeDict(PyObject *obj); -extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, - PyObject *name, PyObject *value); -PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, - PyObject *name); - -static inline PyDictValues **_PyObject_ValuesPointer(PyObject *obj) -{ - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - return ((PyDictValues **)obj)-4; -} - -static inline PyObject **_PyObject_ManagedDictPointer(PyObject *obj) -{ - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - return ((PyObject **)obj)-3; -} - -#define MANAGED_DICT_OFFSET (((int)sizeof(PyObject *))*-3) - -extern PyObject ** _PyObject_DictPointer(PyObject *); -extern int _PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg); -extern void _PyObject_ClearInstanceAttributes(PyObject *self); -extern void _PyObject_FreeInstanceAttributes(PyObject *self); -extern int _PyObject_IsInstanceDictEmpty(PyObject *); -extern PyObject* _PyType_GetSubclasses(PyTypeObject *); - -// Access macro to the members which are floating "behind" the object -#define _PyHeapType_GET_MEMBERS(etype) \ - ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize)) - -PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *); - -/* C function call trampolines to mitigate bad function pointer casts. - * - * Typical native ABIs ignore additional arguments or fill in missing - * values with 0/NULL in function pointer cast. Compilers do not show - * warnings when a function pointer is explicitly casted to an - * incompatible type. - * - * Bad fpcasts are an issue in WebAssembly. WASM's indirect_call has strict - * function signature checks. Argument count, types, and return type must - * match. - * - * Third party code unintentionally rely on problematic fpcasts. The call - * trampoline mitigates common occurences of bad fpcasts on Emscripten. - */ -#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) -#define _PyCFunction_TrampolineCall(meth, self, args) \ - _PyCFunctionWithKeywords_TrampolineCall( \ - (*(PyCFunctionWithKeywords)(void(*)(void))meth), self, args, NULL) -extern PyObject* _PyCFunctionWithKeywords_TrampolineCall( - PyCFunctionWithKeywords meth, PyObject *, PyObject *, PyObject *); -#else -#define _PyCFunction_TrampolineCall(meth, self, args) \ - (meth)((self), (args)) -#define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \ - (meth)((self), (args), (kw)) -#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_OBJECT_H */ diff --git a/python/include/internal/pycore_opcode.h b/python/include/internal/pycore_opcode.h deleted file mode 100644 index 8073de4..0000000 --- a/python/include/internal/pycore_opcode.h +++ /dev/null @@ -1,581 +0,0 @@ -// Auto-generated by Tools/scripts/generate_opcode_h.py from Lib/opcode.py - -#ifndef Py_INTERNAL_OPCODE_H -#define Py_INTERNAL_OPCODE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "opcode.h" - -extern const uint8_t _PyOpcode_Caches[256]; - -extern const uint8_t _PyOpcode_Deopt[256]; - -#ifdef NEED_OPCODE_TABLES -static const uint32_t _PyOpcode_RelativeJump[8] = { - 0U, - 0U, - 536870912U, - 135118848U, - 4163U, - 122880U, - 0U, - 0U, -}; -static const uint32_t _PyOpcode_Jump[8] = { - 0U, - 0U, - 536870912U, - 135118848U, - 4163U, - 122880U, - 0U, - 0U, -}; - -const uint8_t _PyOpcode_Caches[256] = { - [BINARY_SUBSCR] = 4, - [STORE_SUBSCR] = 1, - [UNPACK_SEQUENCE] = 1, - [STORE_ATTR] = 4, - [LOAD_ATTR] = 4, - [COMPARE_OP] = 2, - [LOAD_GLOBAL] = 5, - [BINARY_OP] = 1, - [LOAD_METHOD] = 10, - [PRECALL] = 1, - [CALL] = 4, -}; - -const uint8_t _PyOpcode_Deopt[256] = { - [ASYNC_GEN_WRAP] = ASYNC_GEN_WRAP, - [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH, - [BEFORE_WITH] = BEFORE_WITH, - [BINARY_OP] = BINARY_OP, - [BINARY_OP_ADAPTIVE] = BINARY_OP, - [BINARY_OP_ADD_FLOAT] = BINARY_OP, - [BINARY_OP_ADD_INT] = BINARY_OP, - [BINARY_OP_ADD_UNICODE] = BINARY_OP, - [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP, - [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP, - [BINARY_OP_MULTIPLY_INT] = BINARY_OP, - [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP, - [BINARY_OP_SUBTRACT_INT] = BINARY_OP, - [BINARY_SUBSCR] = BINARY_SUBSCR, - [BINARY_SUBSCR_ADAPTIVE] = BINARY_SUBSCR, - [BINARY_SUBSCR_DICT] = BINARY_SUBSCR, - [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR, - [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR, - [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR, - [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP, - [BUILD_LIST] = BUILD_LIST, - [BUILD_MAP] = BUILD_MAP, - [BUILD_SET] = BUILD_SET, - [BUILD_SLICE] = BUILD_SLICE, - [BUILD_STRING] = BUILD_STRING, - [BUILD_TUPLE] = BUILD_TUPLE, - [CACHE] = CACHE, - [CALL] = CALL, - [CALL_ADAPTIVE] = CALL, - [CALL_FUNCTION_EX] = CALL_FUNCTION_EX, - [CALL_PY_EXACT_ARGS] = CALL, - [CALL_PY_WITH_DEFAULTS] = CALL, - [CHECK_EG_MATCH] = CHECK_EG_MATCH, - [CHECK_EXC_MATCH] = CHECK_EXC_MATCH, - [COMPARE_OP] = COMPARE_OP, - [COMPARE_OP_ADAPTIVE] = COMPARE_OP, - [COMPARE_OP_FLOAT_JUMP] = COMPARE_OP, - [COMPARE_OP_INT_JUMP] = COMPARE_OP, - [COMPARE_OP_STR_JUMP] = COMPARE_OP, - [CONTAINS_OP] = CONTAINS_OP, - [COPY] = COPY, - [COPY_FREE_VARS] = COPY_FREE_VARS, - [DELETE_ATTR] = DELETE_ATTR, - [DELETE_DEREF] = DELETE_DEREF, - [DELETE_FAST] = DELETE_FAST, - [DELETE_GLOBAL] = DELETE_GLOBAL, - [DELETE_NAME] = DELETE_NAME, - [DELETE_SUBSCR] = DELETE_SUBSCR, - [DICT_MERGE] = DICT_MERGE, - [DICT_UPDATE] = DICT_UPDATE, - [END_ASYNC_FOR] = END_ASYNC_FOR, - [EXTENDED_ARG] = EXTENDED_ARG, - [EXTENDED_ARG_QUICK] = EXTENDED_ARG, - [FORMAT_VALUE] = FORMAT_VALUE, - [FOR_ITER] = FOR_ITER, - [GET_AITER] = GET_AITER, - [GET_ANEXT] = GET_ANEXT, - [GET_AWAITABLE] = GET_AWAITABLE, - [GET_ITER] = GET_ITER, - [GET_LEN] = GET_LEN, - [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER, - [IMPORT_FROM] = IMPORT_FROM, - [IMPORT_NAME] = IMPORT_NAME, - [IMPORT_STAR] = IMPORT_STAR, - [IS_OP] = IS_OP, - [JUMP_BACKWARD] = JUMP_BACKWARD, - [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT, - [JUMP_BACKWARD_QUICK] = JUMP_BACKWARD, - [JUMP_FORWARD] = JUMP_FORWARD, - [JUMP_IF_FALSE_OR_POP] = JUMP_IF_FALSE_OR_POP, - [JUMP_IF_TRUE_OR_POP] = JUMP_IF_TRUE_OR_POP, - [KW_NAMES] = KW_NAMES, - [LIST_APPEND] = LIST_APPEND, - [LIST_EXTEND] = LIST_EXTEND, - [LIST_TO_TUPLE] = LIST_TO_TUPLE, - [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR, - [LOAD_ATTR] = LOAD_ATTR, - [LOAD_ATTR_ADAPTIVE] = LOAD_ATTR, - [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, - [LOAD_ATTR_MODULE] = LOAD_ATTR, - [LOAD_ATTR_SLOT] = LOAD_ATTR, - [LOAD_ATTR_WITH_HINT] = LOAD_ATTR, - [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS, - [LOAD_CLASSDEREF] = LOAD_CLASSDEREF, - [LOAD_CLOSURE] = LOAD_CLOSURE, - [LOAD_CONST] = LOAD_CONST, - [LOAD_CONST__LOAD_FAST] = LOAD_CONST, - [LOAD_DEREF] = LOAD_DEREF, - [LOAD_FAST] = LOAD_FAST, - [LOAD_FAST__LOAD_CONST] = LOAD_FAST, - [LOAD_FAST__LOAD_FAST] = LOAD_FAST, - [LOAD_GLOBAL] = LOAD_GLOBAL, - [LOAD_GLOBAL_ADAPTIVE] = LOAD_GLOBAL, - [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, - [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, - [LOAD_METHOD] = LOAD_METHOD, - [LOAD_METHOD_ADAPTIVE] = LOAD_METHOD, - [LOAD_METHOD_CLASS] = LOAD_METHOD, - [LOAD_METHOD_MODULE] = LOAD_METHOD, - [LOAD_METHOD_NO_DICT] = LOAD_METHOD, - [LOAD_METHOD_WITH_DICT] = LOAD_METHOD, - [LOAD_METHOD_WITH_VALUES] = LOAD_METHOD, - [LOAD_NAME] = LOAD_NAME, - [MAKE_CELL] = MAKE_CELL, - [MAKE_FUNCTION] = MAKE_FUNCTION, - [MAP_ADD] = MAP_ADD, - [MATCH_CLASS] = MATCH_CLASS, - [MATCH_KEYS] = MATCH_KEYS, - [MATCH_MAPPING] = MATCH_MAPPING, - [MATCH_SEQUENCE] = MATCH_SEQUENCE, - [NOP] = NOP, - [POP_EXCEPT] = POP_EXCEPT, - [POP_JUMP_BACKWARD_IF_FALSE] = POP_JUMP_BACKWARD_IF_FALSE, - [POP_JUMP_BACKWARD_IF_NONE] = POP_JUMP_BACKWARD_IF_NONE, - [POP_JUMP_BACKWARD_IF_NOT_NONE] = POP_JUMP_BACKWARD_IF_NOT_NONE, - [POP_JUMP_BACKWARD_IF_TRUE] = POP_JUMP_BACKWARD_IF_TRUE, - [POP_JUMP_FORWARD_IF_FALSE] = POP_JUMP_FORWARD_IF_FALSE, - [POP_JUMP_FORWARD_IF_NONE] = POP_JUMP_FORWARD_IF_NONE, - [POP_JUMP_FORWARD_IF_NOT_NONE] = POP_JUMP_FORWARD_IF_NOT_NONE, - [POP_JUMP_FORWARD_IF_TRUE] = POP_JUMP_FORWARD_IF_TRUE, - [POP_TOP] = POP_TOP, - [PRECALL] = PRECALL, - [PRECALL_ADAPTIVE] = PRECALL, - [PRECALL_BOUND_METHOD] = PRECALL, - [PRECALL_BUILTIN_CLASS] = PRECALL, - [PRECALL_BUILTIN_FAST_WITH_KEYWORDS] = PRECALL, - [PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = PRECALL, - [PRECALL_NO_KW_BUILTIN_FAST] = PRECALL, - [PRECALL_NO_KW_BUILTIN_O] = PRECALL, - [PRECALL_NO_KW_ISINSTANCE] = PRECALL, - [PRECALL_NO_KW_LEN] = PRECALL, - [PRECALL_NO_KW_LIST_APPEND] = PRECALL, - [PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST] = PRECALL, - [PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = PRECALL, - [PRECALL_NO_KW_METHOD_DESCRIPTOR_O] = PRECALL, - [PRECALL_NO_KW_STR_1] = PRECALL, - [PRECALL_NO_KW_TUPLE_1] = PRECALL, - [PRECALL_NO_KW_TYPE_1] = PRECALL, - [PRECALL_PYFUNC] = PRECALL, - [PREP_RERAISE_STAR] = PREP_RERAISE_STAR, - [PRINT_EXPR] = PRINT_EXPR, - [PUSH_EXC_INFO] = PUSH_EXC_INFO, - [PUSH_NULL] = PUSH_NULL, - [RAISE_VARARGS] = RAISE_VARARGS, - [RERAISE] = RERAISE, - [RESUME] = RESUME, - [RESUME_QUICK] = RESUME, - [RETURN_GENERATOR] = RETURN_GENERATOR, - [RETURN_VALUE] = RETURN_VALUE, - [SEND] = SEND, - [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS, - [SET_ADD] = SET_ADD, - [SET_UPDATE] = SET_UPDATE, - [STORE_ATTR] = STORE_ATTR, - [STORE_ATTR_ADAPTIVE] = STORE_ATTR, - [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR, - [STORE_ATTR_SLOT] = STORE_ATTR, - [STORE_ATTR_WITH_HINT] = STORE_ATTR, - [STORE_DEREF] = STORE_DEREF, - [STORE_FAST] = STORE_FAST, - [STORE_FAST__LOAD_FAST] = STORE_FAST, - [STORE_FAST__STORE_FAST] = STORE_FAST, - [STORE_GLOBAL] = STORE_GLOBAL, - [STORE_NAME] = STORE_NAME, - [STORE_SUBSCR] = STORE_SUBSCR, - [STORE_SUBSCR_ADAPTIVE] = STORE_SUBSCR, - [STORE_SUBSCR_DICT] = STORE_SUBSCR, - [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR, - [SWAP] = SWAP, - [UNARY_INVERT] = UNARY_INVERT, - [UNARY_NEGATIVE] = UNARY_NEGATIVE, - [UNARY_NOT] = UNARY_NOT, - [UNARY_POSITIVE] = UNARY_POSITIVE, - [UNPACK_EX] = UNPACK_EX, - [UNPACK_SEQUENCE] = UNPACK_SEQUENCE, - [UNPACK_SEQUENCE_ADAPTIVE] = UNPACK_SEQUENCE, - [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE, - [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE, - [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE, - [WITH_EXCEPT_START] = WITH_EXCEPT_START, - [YIELD_VALUE] = YIELD_VALUE, -}; -#endif // NEED_OPCODE_TABLES - -#ifdef Py_DEBUG -static const char *const _PyOpcode_OpName[256] = { - [CACHE] = "CACHE", - [POP_TOP] = "POP_TOP", - [PUSH_NULL] = "PUSH_NULL", - [BINARY_OP_ADAPTIVE] = "BINARY_OP_ADAPTIVE", - [BINARY_OP_ADD_FLOAT] = "BINARY_OP_ADD_FLOAT", - [BINARY_OP_ADD_INT] = "BINARY_OP_ADD_INT", - [BINARY_OP_ADD_UNICODE] = "BINARY_OP_ADD_UNICODE", - [BINARY_OP_INPLACE_ADD_UNICODE] = "BINARY_OP_INPLACE_ADD_UNICODE", - [BINARY_OP_MULTIPLY_FLOAT] = "BINARY_OP_MULTIPLY_FLOAT", - [NOP] = "NOP", - [UNARY_POSITIVE] = "UNARY_POSITIVE", - [UNARY_NEGATIVE] = "UNARY_NEGATIVE", - [UNARY_NOT] = "UNARY_NOT", - [BINARY_OP_MULTIPLY_INT] = "BINARY_OP_MULTIPLY_INT", - [BINARY_OP_SUBTRACT_FLOAT] = "BINARY_OP_SUBTRACT_FLOAT", - [UNARY_INVERT] = "UNARY_INVERT", - [BINARY_OP_SUBTRACT_INT] = "BINARY_OP_SUBTRACT_INT", - [BINARY_SUBSCR_ADAPTIVE] = "BINARY_SUBSCR_ADAPTIVE", - [BINARY_SUBSCR_DICT] = "BINARY_SUBSCR_DICT", - [BINARY_SUBSCR_GETITEM] = "BINARY_SUBSCR_GETITEM", - [BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT", - [BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT", - [CALL_ADAPTIVE] = "CALL_ADAPTIVE", - [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS", - [CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS", - [BINARY_SUBSCR] = "BINARY_SUBSCR", - [COMPARE_OP_ADAPTIVE] = "COMPARE_OP_ADAPTIVE", - [COMPARE_OP_FLOAT_JUMP] = "COMPARE_OP_FLOAT_JUMP", - [COMPARE_OP_INT_JUMP] = "COMPARE_OP_INT_JUMP", - [COMPARE_OP_STR_JUMP] = "COMPARE_OP_STR_JUMP", - [GET_LEN] = "GET_LEN", - [MATCH_MAPPING] = "MATCH_MAPPING", - [MATCH_SEQUENCE] = "MATCH_SEQUENCE", - [MATCH_KEYS] = "MATCH_KEYS", - [EXTENDED_ARG_QUICK] = "EXTENDED_ARG_QUICK", - [PUSH_EXC_INFO] = "PUSH_EXC_INFO", - [CHECK_EXC_MATCH] = "CHECK_EXC_MATCH", - [CHECK_EG_MATCH] = "CHECK_EG_MATCH", - [JUMP_BACKWARD_QUICK] = "JUMP_BACKWARD_QUICK", - [LOAD_ATTR_ADAPTIVE] = "LOAD_ATTR_ADAPTIVE", - [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", - [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", - [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", - [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", - [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", - [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", - [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", - [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", - [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", - [WITH_EXCEPT_START] = "WITH_EXCEPT_START", - [GET_AITER] = "GET_AITER", - [GET_ANEXT] = "GET_ANEXT", - [BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH", - [BEFORE_WITH] = "BEFORE_WITH", - [END_ASYNC_FOR] = "END_ASYNC_FOR", - [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", - [LOAD_METHOD_ADAPTIVE] = "LOAD_METHOD_ADAPTIVE", - [LOAD_METHOD_CLASS] = "LOAD_METHOD_CLASS", - [LOAD_METHOD_MODULE] = "LOAD_METHOD_MODULE", - [LOAD_METHOD_NO_DICT] = "LOAD_METHOD_NO_DICT", - [STORE_SUBSCR] = "STORE_SUBSCR", - [DELETE_SUBSCR] = "DELETE_SUBSCR", - [LOAD_METHOD_WITH_DICT] = "LOAD_METHOD_WITH_DICT", - [LOAD_METHOD_WITH_VALUES] = "LOAD_METHOD_WITH_VALUES", - [PRECALL_ADAPTIVE] = "PRECALL_ADAPTIVE", - [PRECALL_BOUND_METHOD] = "PRECALL_BOUND_METHOD", - [PRECALL_BUILTIN_CLASS] = "PRECALL_BUILTIN_CLASS", - [PRECALL_BUILTIN_FAST_WITH_KEYWORDS] = "PRECALL_BUILTIN_FAST_WITH_KEYWORDS", - [GET_ITER] = "GET_ITER", - [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", - [PRINT_EXPR] = "PRINT_EXPR", - [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", - [PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", - [PRECALL_NO_KW_BUILTIN_FAST] = "PRECALL_NO_KW_BUILTIN_FAST", - [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", - [RETURN_GENERATOR] = "RETURN_GENERATOR", - [PRECALL_NO_KW_BUILTIN_O] = "PRECALL_NO_KW_BUILTIN_O", - [PRECALL_NO_KW_ISINSTANCE] = "PRECALL_NO_KW_ISINSTANCE", - [PRECALL_NO_KW_LEN] = "PRECALL_NO_KW_LEN", - [PRECALL_NO_KW_LIST_APPEND] = "PRECALL_NO_KW_LIST_APPEND", - [PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST] = "PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST", - [PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = "PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", - [LIST_TO_TUPLE] = "LIST_TO_TUPLE", - [RETURN_VALUE] = "RETURN_VALUE", - [IMPORT_STAR] = "IMPORT_STAR", - [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", - [YIELD_VALUE] = "YIELD_VALUE", - [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP", - [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR", - [POP_EXCEPT] = "POP_EXCEPT", - [STORE_NAME] = "STORE_NAME", - [DELETE_NAME] = "DELETE_NAME", - [UNPACK_SEQUENCE] = "UNPACK_SEQUENCE", - [FOR_ITER] = "FOR_ITER", - [UNPACK_EX] = "UNPACK_EX", - [STORE_ATTR] = "STORE_ATTR", - [DELETE_ATTR] = "DELETE_ATTR", - [STORE_GLOBAL] = "STORE_GLOBAL", - [DELETE_GLOBAL] = "DELETE_GLOBAL", - [SWAP] = "SWAP", - [LOAD_CONST] = "LOAD_CONST", - [LOAD_NAME] = "LOAD_NAME", - [BUILD_TUPLE] = "BUILD_TUPLE", - [BUILD_LIST] = "BUILD_LIST", - [BUILD_SET] = "BUILD_SET", - [BUILD_MAP] = "BUILD_MAP", - [LOAD_ATTR] = "LOAD_ATTR", - [COMPARE_OP] = "COMPARE_OP", - [IMPORT_NAME] = "IMPORT_NAME", - [IMPORT_FROM] = "IMPORT_FROM", - [JUMP_FORWARD] = "JUMP_FORWARD", - [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP", - [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP", - [PRECALL_NO_KW_METHOD_DESCRIPTOR_O] = "PRECALL_NO_KW_METHOD_DESCRIPTOR_O", - [POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE", - [POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE", - [LOAD_GLOBAL] = "LOAD_GLOBAL", - [IS_OP] = "IS_OP", - [CONTAINS_OP] = "CONTAINS_OP", - [RERAISE] = "RERAISE", - [COPY] = "COPY", - [PRECALL_NO_KW_STR_1] = "PRECALL_NO_KW_STR_1", - [BINARY_OP] = "BINARY_OP", - [SEND] = "SEND", - [LOAD_FAST] = "LOAD_FAST", - [STORE_FAST] = "STORE_FAST", - [DELETE_FAST] = "DELETE_FAST", - [PRECALL_NO_KW_TUPLE_1] = "PRECALL_NO_KW_TUPLE_1", - [POP_JUMP_FORWARD_IF_NOT_NONE] = "POP_JUMP_FORWARD_IF_NOT_NONE", - [POP_JUMP_FORWARD_IF_NONE] = "POP_JUMP_FORWARD_IF_NONE", - [RAISE_VARARGS] = "RAISE_VARARGS", - [GET_AWAITABLE] = "GET_AWAITABLE", - [MAKE_FUNCTION] = "MAKE_FUNCTION", - [BUILD_SLICE] = "BUILD_SLICE", - [JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT", - [MAKE_CELL] = "MAKE_CELL", - [LOAD_CLOSURE] = "LOAD_CLOSURE", - [LOAD_DEREF] = "LOAD_DEREF", - [STORE_DEREF] = "STORE_DEREF", - [DELETE_DEREF] = "DELETE_DEREF", - [JUMP_BACKWARD] = "JUMP_BACKWARD", - [PRECALL_NO_KW_TYPE_1] = "PRECALL_NO_KW_TYPE_1", - [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", - [PRECALL_PYFUNC] = "PRECALL_PYFUNC", - [EXTENDED_ARG] = "EXTENDED_ARG", - [LIST_APPEND] = "LIST_APPEND", - [SET_ADD] = "SET_ADD", - [MAP_ADD] = "MAP_ADD", - [LOAD_CLASSDEREF] = "LOAD_CLASSDEREF", - [COPY_FREE_VARS] = "COPY_FREE_VARS", - [RESUME_QUICK] = "RESUME_QUICK", - [RESUME] = "RESUME", - [MATCH_CLASS] = "MATCH_CLASS", - [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", - [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", - [FORMAT_VALUE] = "FORMAT_VALUE", - [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", - [BUILD_STRING] = "BUILD_STRING", - [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", - [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", - [LOAD_METHOD] = "LOAD_METHOD", - [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", - [LIST_EXTEND] = "LIST_EXTEND", - [SET_UPDATE] = "SET_UPDATE", - [DICT_MERGE] = "DICT_MERGE", - [DICT_UPDATE] = "DICT_UPDATE", - [PRECALL] = "PRECALL", - [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", - [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", - [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", - [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", - [CALL] = "CALL", - [KW_NAMES] = "KW_NAMES", - [POP_JUMP_BACKWARD_IF_NOT_NONE] = "POP_JUMP_BACKWARD_IF_NOT_NONE", - [POP_JUMP_BACKWARD_IF_NONE] = "POP_JUMP_BACKWARD_IF_NONE", - [POP_JUMP_BACKWARD_IF_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE", - [POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE", - [UNPACK_SEQUENCE_ADAPTIVE] = "UNPACK_SEQUENCE_ADAPTIVE", - [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", - [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", - [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", - [181] = "<181>", - [182] = "<182>", - [183] = "<183>", - [184] = "<184>", - [185] = "<185>", - [186] = "<186>", - [187] = "<187>", - [188] = "<188>", - [189] = "<189>", - [190] = "<190>", - [191] = "<191>", - [192] = "<192>", - [193] = "<193>", - [194] = "<194>", - [195] = "<195>", - [196] = "<196>", - [197] = "<197>", - [198] = "<198>", - [199] = "<199>", - [200] = "<200>", - [201] = "<201>", - [202] = "<202>", - [203] = "<203>", - [204] = "<204>", - [205] = "<205>", - [206] = "<206>", - [207] = "<207>", - [208] = "<208>", - [209] = "<209>", - [210] = "<210>", - [211] = "<211>", - [212] = "<212>", - [213] = "<213>", - [214] = "<214>", - [215] = "<215>", - [216] = "<216>", - [217] = "<217>", - [218] = "<218>", - [219] = "<219>", - [220] = "<220>", - [221] = "<221>", - [222] = "<222>", - [223] = "<223>", - [224] = "<224>", - [225] = "<225>", - [226] = "<226>", - [227] = "<227>", - [228] = "<228>", - [229] = "<229>", - [230] = "<230>", - [231] = "<231>", - [232] = "<232>", - [233] = "<233>", - [234] = "<234>", - [235] = "<235>", - [236] = "<236>", - [237] = "<237>", - [238] = "<238>", - [239] = "<239>", - [240] = "<240>", - [241] = "<241>", - [242] = "<242>", - [243] = "<243>", - [244] = "<244>", - [245] = "<245>", - [246] = "<246>", - [247] = "<247>", - [248] = "<248>", - [249] = "<249>", - [250] = "<250>", - [251] = "<251>", - [252] = "<252>", - [253] = "<253>", - [254] = "<254>", - [DO_TRACING] = "DO_TRACING", -}; -#endif - -#define EXTRA_CASES \ - case 181: \ - case 182: \ - case 183: \ - case 184: \ - case 185: \ - case 186: \ - case 187: \ - case 188: \ - case 189: \ - case 190: \ - case 191: \ - case 192: \ - case 193: \ - case 194: \ - case 195: \ - case 196: \ - case 197: \ - case 198: \ - case 199: \ - case 200: \ - case 201: \ - case 202: \ - case 203: \ - case 204: \ - case 205: \ - case 206: \ - case 207: \ - case 208: \ - case 209: \ - case 210: \ - case 211: \ - case 212: \ - case 213: \ - case 214: \ - case 215: \ - case 216: \ - case 217: \ - case 218: \ - case 219: \ - case 220: \ - case 221: \ - case 222: \ - case 223: \ - case 224: \ - case 225: \ - case 226: \ - case 227: \ - case 228: \ - case 229: \ - case 230: \ - case 231: \ - case 232: \ - case 233: \ - case 234: \ - case 235: \ - case 236: \ - case 237: \ - case 238: \ - case 239: \ - case 240: \ - case 241: \ - case 242: \ - case 243: \ - case 244: \ - case 245: \ - case 246: \ - case 247: \ - case 248: \ - case 249: \ - case 250: \ - case 251: \ - case 252: \ - case 253: \ - case 254: \ - ; - -#ifdef __cplusplus -} -#endif -#endif // !Py_INTERNAL_OPCODE_H diff --git a/python/include/internal/pycore_parser.h b/python/include/internal/pycore_parser.h deleted file mode 100644 index 20bffe9..0000000 --- a/python/include/internal/pycore_parser.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef Py_INTERNAL_PARSER_H -#define Py_INTERNAL_PARSER_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -extern struct _mod* _PyParser_ASTFromString( - const char *str, - PyObject* filename, - int mode, - PyCompilerFlags *flags, - PyArena *arena); -extern struct _mod* _PyParser_ASTFromFile( - FILE *fp, - PyObject *filename_ob, - const char *enc, - int mode, - const char *ps1, - const char *ps2, - PyCompilerFlags *flags, - int *errcode, - PyArena *arena); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_PARSER_H */ diff --git a/python/include/internal/pycore_pathconfig.h b/python/include/internal/pycore_pathconfig.h deleted file mode 100644 index d08d046..0000000 --- a/python/include/internal/pycore_pathconfig.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef Py_INTERNAL_PATHCONFIG_H -#define Py_INTERNAL_PATHCONFIG_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -PyAPI_FUNC(void) _PyPathConfig_ClearGlobal(void); -extern PyStatus _PyPathConfig_ReadGlobal(PyConfig *config); -extern PyStatus _PyPathConfig_UpdateGlobal(const PyConfig *config); -extern const wchar_t * _PyPathConfig_GetGlobalModuleSearchPath(void); - -extern int _PyPathConfig_ComputeSysPath0( - const PyWideStringList *argv, - PyObject **path0); - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_PATHCONFIG_H */ diff --git a/python/include/internal/pycore_pyarena.h b/python/include/internal/pycore_pyarena.h deleted file mode 100644 index 6d6ddc5..0000000 --- a/python/include/internal/pycore_pyarena.h +++ /dev/null @@ -1,64 +0,0 @@ -/* An arena-like memory interface for the compiler. - */ - -#ifndef Py_INTERNAL_PYARENA_H -#define Py_INTERNAL_PYARENA_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -typedef struct _arena PyArena; - -/* _PyArena_New() and _PyArena_Free() create a new arena and free it, - respectively. Once an arena has been created, it can be used - to allocate memory via _PyArena_Malloc(). Pointers to PyObject can - also be registered with the arena via _PyArena_AddPyObject(), and the - arena will ensure that the PyObjects stay alive at least until - _PyArena_Free() is called. When an arena is freed, all the memory it - allocated is freed, the arena releases internal references to registered - PyObject*, and none of its pointers are valid. - XXX (tim) What does "none of its pointers are valid" mean? Does it - XXX mean that pointers previously obtained via _PyArena_Malloc() are - XXX no longer valid? (That's clearly true, but not sure that's what - XXX the text is trying to say.) - - _PyArena_New() returns an arena pointer. On error, it - returns a negative number and sets an exception. - XXX (tim): Not true. On error, _PyArena_New() actually returns NULL, - XXX and looks like it may or may not set an exception (e.g., if the - XXX internal PyList_New(0) returns NULL, _PyArena_New() passes that on - XXX and an exception is set; OTOH, if the internal - XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but - XXX an exception is not set in that case). -*/ -PyAPI_FUNC(PyArena*) _PyArena_New(void); -PyAPI_FUNC(void) _PyArena_Free(PyArena *); - -/* Mostly like malloc(), return the address of a block of memory spanning - * `size` bytes, or return NULL (without setting an exception) if enough - * new memory can't be obtained. Unlike malloc(0), _PyArena_Malloc() with - * size=0 does not guarantee to return a unique pointer (the pointer - * returned may equal one or more other pointers obtained from - * _PyArena_Malloc()). - * Note that pointers obtained via _PyArena_Malloc() must never be passed to - * the system free() or realloc(), or to any of Python's similar memory- - * management functions. _PyArena_Malloc()-obtained pointers remain valid - * until _PyArena_Free(ar) is called, at which point all pointers obtained - * from the arena `ar` become invalid simultaneously. - */ -PyAPI_FUNC(void*) _PyArena_Malloc(PyArena *, size_t size); - -/* This routine isn't a proper arena allocation routine. It takes - * a PyObject* and records it so that it can be DECREFed when the - * arena is freed. - */ -PyAPI_FUNC(int) _PyArena_AddPyObject(PyArena *, PyObject *); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_PYARENA_H */ diff --git a/python/include/internal/pycore_pyerrors.h b/python/include/internal/pycore_pyerrors.h deleted file mode 100644 index 5bb24c5..0000000 --- a/python/include/internal/pycore_pyerrors.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef Py_INTERNAL_PYERRORS_H -#define Py_INTERNAL_PYERRORS_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - - -/* runtime lifecycle */ - -extern PyStatus _PyErr_InitTypes(PyInterpreterState *); -extern void _PyErr_FiniTypes(PyInterpreterState *); - - -/* other API */ - -static inline PyObject* _PyErr_Occurred(PyThreadState *tstate) -{ - assert(tstate != NULL); - return tstate->curexc_type; -} - -static inline void _PyErr_ClearExcState(_PyErr_StackItem *exc_state) -{ - Py_CLEAR(exc_state->exc_value); -} - -PyAPI_FUNC(PyObject*) _PyErr_StackItemToExcInfoTuple( - _PyErr_StackItem *err_info); - -PyAPI_FUNC(void) _PyErr_Fetch( - PyThreadState *tstate, - PyObject **type, - PyObject **value, - PyObject **traceback); - -PyAPI_FUNC(int) _PyErr_ExceptionMatches( - PyThreadState *tstate, - PyObject *exc); - -PyAPI_FUNC(void) _PyErr_Restore( - PyThreadState *tstate, - PyObject *type, - PyObject *value, - PyObject *traceback); - -PyAPI_FUNC(void) _PyErr_SetObject( - PyThreadState *tstate, - PyObject *type, - PyObject *value); - -PyAPI_FUNC(void) _PyErr_ChainStackItem( - _PyErr_StackItem *exc_info); - -PyAPI_FUNC(void) _PyErr_Clear(PyThreadState *tstate); - -PyAPI_FUNC(void) _PyErr_SetNone(PyThreadState *tstate, PyObject *exception); - -PyAPI_FUNC(PyObject *) _PyErr_NoMemory(PyThreadState *tstate); - -PyAPI_FUNC(void) _PyErr_SetString( - PyThreadState *tstate, - PyObject *exception, - const char *string); - -PyAPI_FUNC(PyObject *) _PyErr_Format( - PyThreadState *tstate, - PyObject *exception, - const char *format, - ...); - -PyAPI_FUNC(void) _PyErr_NormalizeException( - PyThreadState *tstate, - PyObject **exc, - PyObject **val, - PyObject **tb); - -PyAPI_FUNC(PyObject *) _PyErr_FormatFromCauseTstate( - PyThreadState *tstate, - PyObject *exception, - const char *format, - ...); - -PyAPI_FUNC(PyObject *) _PyExc_CreateExceptionGroup( - const char *msg, - PyObject *excs); - -PyAPI_FUNC(PyObject *) _PyExc_PrepReraiseStar( - PyObject *orig, - PyObject *excs); - -PyAPI_FUNC(int) _PyErr_CheckSignalsTstate(PyThreadState *tstate); - -PyAPI_FUNC(void) _Py_DumpExtensionModules(int fd, PyInterpreterState *interp); - -extern PyObject* _Py_Offer_Suggestions(PyObject* exception); -PyAPI_FUNC(Py_ssize_t) _Py_UTF8_Edit_Cost(PyObject *str_a, PyObject *str_b, - Py_ssize_t max_cost); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_PYERRORS_H */ diff --git a/python/include/internal/pycore_pyhash.h b/python/include/internal/pycore_pyhash.h deleted file mode 100644 index 53d44d9..0000000 --- a/python/include/internal/pycore_pyhash.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef Py_INTERNAL_HASH_H -#define Py_INTERNAL_HASH_H - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -uint64_t _Py_KeyedHash(uint64_t, const char *, Py_ssize_t); - -#endif diff --git a/python/include/internal/pycore_pylifecycle.h b/python/include/internal/pycore_pylifecycle.h deleted file mode 100644 index f08ae59..0000000 --- a/python/include/internal/pycore_pylifecycle.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef Py_INTERNAL_LIFECYCLE_H -#define Py_INTERNAL_LIFECYCLE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_runtime.h" // _PyRuntimeState - -/* Forward declarations */ -struct _PyArgv; -struct pyruntimestate; - -/* True if the main interpreter thread exited due to an unhandled - * KeyboardInterrupt exception, suggesting the user pressed ^C. */ -PyAPI_DATA(int) _Py_UnhandledKeyboardInterrupt; - -extern int _Py_SetFileSystemEncoding( - const char *encoding, - const char *errors); -extern void _Py_ClearFileSystemEncoding(void); -extern PyStatus _PyUnicode_InitEncodings(PyThreadState *tstate); -#ifdef MS_WINDOWS -extern int _PyUnicode_EnableLegacyWindowsFSEncoding(void); -#endif - -PyAPI_FUNC(void) _Py_ClearStandardStreamEncoding(void); - -PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc); - -/* Various one-time initializers */ - -extern PyStatus _PyFaulthandler_Init(int enable); -extern int _PyTraceMalloc_Init(int enable); -extern PyObject * _PyBuiltin_Init(PyInterpreterState *interp); -extern PyStatus _PySys_Create( - PyThreadState *tstate, - PyObject **sysmod_p); -extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options); -extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config); -extern int _PySys_UpdateConfig(PyThreadState *tstate); -extern void _PySys_Fini(PyInterpreterState *interp); -extern int _PyBuiltins_AddExceptions(PyObject * bltinmod); -extern PyStatus _Py_HashRandomization_Init(const PyConfig *); - -extern PyStatus _PyImportZip_Init(PyThreadState *tstate); -extern PyStatus _PyGC_Init(PyInterpreterState *interp); -extern PyStatus _PyAtExit_Init(PyInterpreterState *interp); -extern int _Py_Deepfreeze_Init(void); - -/* Various internal finalizers */ - -extern int _PySignal_Init(int install_signal_handlers); -extern void _PySignal_Fini(void); - -extern void _PyImport_Fini(void); -extern void _PyImport_Fini2(void); -extern void _PyGC_Fini(PyInterpreterState *interp); -extern void _Py_HashRandomization_Fini(void); -extern void _PyFaulthandler_Fini(void); -extern void _PyHash_Fini(void); -extern void _PyTraceMalloc_Fini(void); -extern void _PyWarnings_Fini(PyInterpreterState *interp); -extern void _PyAST_Fini(PyInterpreterState *interp); -extern void _PyAtExit_Fini(PyInterpreterState *interp); -extern void _PyThread_FiniType(PyInterpreterState *interp); -extern void _Py_Deepfreeze_Fini(void); -extern void _PyArg_Fini(void); - -extern PyStatus _PyGILState_Init(_PyRuntimeState *runtime); -extern PyStatus _PyGILState_SetTstate(PyThreadState *tstate); -extern void _PyGILState_Fini(PyInterpreterState *interp); - -PyAPI_FUNC(void) _PyGC_DumpShutdownStats(PyInterpreterState *interp); - -PyAPI_FUNC(PyStatus) _Py_PreInitializeFromPyArgv( - const PyPreConfig *src_config, - const struct _PyArgv *args); -PyAPI_FUNC(PyStatus) _Py_PreInitializeFromConfig( - const PyConfig *config, - const struct _PyArgv *args); - -PyAPI_FUNC(wchar_t *) _Py_GetStdlibDir(void); - -PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p); - -PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable); - -PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate); -PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception, - PyObject *value, PyObject *tb); - -PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(PyThreadState *tstate); - -extern void _PyAtExit_Call(PyInterpreterState *interp); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_LIFECYCLE_H */ diff --git a/python/include/internal/pycore_pymath.h b/python/include/internal/pycore_pymath.h deleted file mode 100644 index 0d2104f..0000000 --- a/python/include/internal/pycore_pymath.h +++ /dev/null @@ -1,224 +0,0 @@ -#ifndef Py_INTERNAL_PYMATH_H -#define Py_INTERNAL_PYMATH_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - - -/* _Py_ADJUST_ERANGE1(x) - * _Py_ADJUST_ERANGE2(x, y) - * Set errno to 0 before calling a libm function, and invoke one of these - * macros after, passing the function result(s) (_Py_ADJUST_ERANGE2 is useful - * for functions returning complex results). This makes two kinds of - * adjustments to errno: (A) If it looks like the platform libm set - * errno=ERANGE due to underflow, clear errno. (B) If it looks like the - * platform libm overflowed but didn't set errno, force errno to ERANGE. In - * effect, we're trying to force a useful implementation of C89 errno - * behavior. - * Caution: - * This isn't reliable. C99 no longer requires libm to set errno under - * any exceptional condition, but does require +- HUGE_VAL return - * values on overflow. A 754 box *probably* maps HUGE_VAL to a - * double infinity, and we're cool if that's so, unless the input - * was an infinity and an infinity is the expected result. A C89 - * system sets errno to ERANGE, so we check for that too. We're - * out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or - * if the returned result is a NaN, or if a C89 box returns HUGE_VAL - * in non-overflow cases. - */ -static inline void _Py_ADJUST_ERANGE1(double x) -{ - if (errno == 0) { - if (x == Py_HUGE_VAL || x == -Py_HUGE_VAL) { - errno = ERANGE; - } - } - else if (errno == ERANGE && x == 0.0) { - errno = 0; - } -} - -static inline void _Py_ADJUST_ERANGE2(double x, double y) -{ - if (x == Py_HUGE_VAL || x == -Py_HUGE_VAL || - y == Py_HUGE_VAL || y == -Py_HUGE_VAL) - { - if (errno == 0) { - errno = ERANGE; - } - } - else if (errno == ERANGE) { - errno = 0; - } -} - -// Return whether integral type *type* is signed or not. -#define _Py_IntegralTypeSigned(type) \ - ((type)(-1) < 0) - -// Return the maximum value of integral type *type*. -#define _Py_IntegralTypeMax(type) \ - ((_Py_IntegralTypeSigned(type)) ? (((((type)1 << (sizeof(type)*CHAR_BIT - 2)) - 1) << 1) + 1) : ~(type)0) - -// Return the minimum value of integral type *type*. -#define _Py_IntegralTypeMin(type) \ - ((_Py_IntegralTypeSigned(type)) ? -_Py_IntegralTypeMax(type) - 1 : 0) - -// Check whether *v* is in the range of integral type *type*. This is most -// useful if *v* is floating-point, since demoting a floating-point *v* to an -// integral type that cannot represent *v*'s integral part is undefined -// behavior. -#define _Py_InIntegralTypeRange(type, v) \ - (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type)) - - -//--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------ -// -// The functions _Py_dg_strtod() and _Py_dg_dtoa() in Python/dtoa.c (which are -// required to support the short float repr introduced in Python 3.1) require -// that the floating-point unit that's being used for arithmetic operations on -// C doubles is set to use 53-bit precision. It also requires that the FPU -// rounding mode is round-half-to-even, but that's less often an issue. -// -// If your FPU isn't already set to 53-bit precision/round-half-to-even, and -// you want to make use of _Py_dg_strtod() and _Py_dg_dtoa(), then you should: -// -// #define HAVE_PY_SET_53BIT_PRECISION 1 -// -// and also give appropriate definitions for the following three macros: -// -// * _Py_SET_53BIT_PRECISION_HEADER: any variable declarations needed to -// use the two macros below. -// * _Py_SET_53BIT_PRECISION_START: store original FPU settings, and -// set FPU to 53-bit precision/round-half-to-even -// * _Py_SET_53BIT_PRECISION_END: restore original FPU settings -// -// The macros are designed to be used within a single C function: see -// Python/pystrtod.c for an example of their use. - - -// Get and set x87 control word for gcc/x86 -#ifdef HAVE_GCC_ASM_FOR_X87 -#define HAVE_PY_SET_53BIT_PRECISION 1 - -// Functions defined in Python/pymath.c -extern unsigned short _Py_get_387controlword(void); -extern void _Py_set_387controlword(unsigned short); - -#define _Py_SET_53BIT_PRECISION_HEADER \ - unsigned short old_387controlword, new_387controlword -#define _Py_SET_53BIT_PRECISION_START \ - do { \ - old_387controlword = _Py_get_387controlword(); \ - new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \ - if (new_387controlword != old_387controlword) { \ - _Py_set_387controlword(new_387controlword); \ - } \ - } while (0) -#define _Py_SET_53BIT_PRECISION_END \ - do { \ - if (new_387controlword != old_387controlword) { \ - _Py_set_387controlword(old_387controlword); \ - } \ - } while (0) -#endif - -// Get and set x87 control word for VisualStudio/x86. -// x87 is not supported in 64-bit or ARM. -#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM) -#define HAVE_PY_SET_53BIT_PRECISION 1 - -#include // __control87_2() - -#define _Py_SET_53BIT_PRECISION_HEADER \ - unsigned int old_387controlword, new_387controlword, out_387controlword - // We use the __control87_2 function to set only the x87 control word. - // The SSE control word is unaffected. -#define _Py_SET_53BIT_PRECISION_START \ - do { \ - __control87_2(0, 0, &old_387controlword, NULL); \ - new_387controlword = \ - (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \ - if (new_387controlword != old_387controlword) { \ - __control87_2(new_387controlword, _MCW_PC | _MCW_RC, \ - &out_387controlword, NULL); \ - } \ - } while (0) -#define _Py_SET_53BIT_PRECISION_END \ - do { \ - if (new_387controlword != old_387controlword) { \ - __control87_2(old_387controlword, _MCW_PC | _MCW_RC, \ - &out_387controlword, NULL); \ - } \ - } while (0) -#endif - - -// MC68881 -#ifdef HAVE_GCC_ASM_FOR_MC68881 -#define HAVE_PY_SET_53BIT_PRECISION 1 -#define _Py_SET_53BIT_PRECISION_HEADER \ - unsigned int old_fpcr, new_fpcr -#define _Py_SET_53BIT_PRECISION_START \ - do { \ - __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \ - /* Set double precision / round to nearest. */ \ - new_fpcr = (old_fpcr & ~0xf0) | 0x80; \ - if (new_fpcr != old_fpcr) { \ - __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr));\ - } \ - } while (0) -#define _Py_SET_53BIT_PRECISION_END \ - do { \ - if (new_fpcr != old_fpcr) { \ - __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \ - } \ - } while (0) -#endif - -// Default definitions are empty -#ifndef _Py_SET_53BIT_PRECISION_HEADER -# define _Py_SET_53BIT_PRECISION_HEADER -# define _Py_SET_53BIT_PRECISION_START -# define _Py_SET_53BIT_PRECISION_END -#endif - - -//--- _PY_SHORT_FLOAT_REPR macro ------------------------------------------- - -// If we can't guarantee 53-bit precision, don't use the code -// in Python/dtoa.c, but fall back to standard code. This -// means that repr of a float will be long (17 significant digits). -// -// Realistically, there are two things that could go wrong: -// -// (1) doubles aren't IEEE 754 doubles, or -// (2) we're on x86 with the rounding precision set to 64-bits -// (extended precision), and we don't know how to change -// the rounding precision. -#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \ - !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \ - !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) -# define _PY_SHORT_FLOAT_REPR 0 -#endif - -// Double rounding is symptomatic of use of extended precision on x86. -// If we're seeing double rounding, and we don't have any mechanism available -// for changing the FPU rounding precision, then don't use Python/dtoa.c. -#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION) -# define _PY_SHORT_FLOAT_REPR 0 -#endif - -#ifndef _PY_SHORT_FLOAT_REPR -# define _PY_SHORT_FLOAT_REPR 1 -#endif - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_PYMATH_H */ diff --git a/python/include/internal/pycore_pymem.h b/python/include/internal/pycore_pymem.h deleted file mode 100644 index 73fbb4f..0000000 --- a/python/include/internal/pycore_pymem.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef Py_INTERNAL_PYMEM_H -#define Py_INTERNAL_PYMEM_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pymem.h" // PyMemAllocatorName - - -/* Set the memory allocator of the specified domain to the default. - Save the old allocator into *old_alloc if it's non-NULL. - Return on success, or return -1 if the domain is unknown. */ -PyAPI_FUNC(int) _PyMem_SetDefaultAllocator( - PyMemAllocatorDomain domain, - PyMemAllocatorEx *old_alloc); - -/* Special bytes broadcast into debug memory blocks at appropriate times. - Strings of these are unlikely to be valid addresses, floats, ints or - 7-bit ASCII. - - - PYMEM_CLEANBYTE: clean (newly allocated) memory - - PYMEM_DEADBYTE dead (newly freed) memory - - PYMEM_FORBIDDENBYTE: untouchable bytes at each end of a block - - Byte patterns 0xCB, 0xDB and 0xFB have been replaced with 0xCD, 0xDD and - 0xFD to use the same values than Windows CRT debug malloc() and free(). - If modified, _PyMem_IsPtrFreed() should be updated as well. */ -#define PYMEM_CLEANBYTE 0xCD -#define PYMEM_DEADBYTE 0xDD -#define PYMEM_FORBIDDENBYTE 0xFD - -/* Heuristic checking if a pointer value is newly allocated - (uninitialized), newly freed or NULL (is equal to zero). - - The pointer is not dereferenced, only the pointer value is checked. - - The heuristic relies on the debug hooks on Python memory allocators which - fills newly allocated memory with CLEANBYTE (0xCD) and newly freed memory - with DEADBYTE (0xDD). Detect also "untouchable bytes" marked - with FORBIDDENBYTE (0xFD). */ -static inline int _PyMem_IsPtrFreed(const void *ptr) -{ - uintptr_t value = (uintptr_t)ptr; -#if SIZEOF_VOID_P == 8 - return (value == 0 - || value == (uintptr_t)0xCDCDCDCDCDCDCDCD - || value == (uintptr_t)0xDDDDDDDDDDDDDDDD - || value == (uintptr_t)0xFDFDFDFDFDFDFDFD); -#elif SIZEOF_VOID_P == 4 - return (value == 0 - || value == (uintptr_t)0xCDCDCDCD - || value == (uintptr_t)0xDDDDDDDD - || value == (uintptr_t)0xFDFDFDFD); -#else -# error "unknown pointer size" -#endif -} - -PyAPI_FUNC(int) _PyMem_GetAllocatorName( - const char *name, - PyMemAllocatorName *allocator); - -/* Configure the Python memory allocators. - Pass PYMEM_ALLOCATOR_DEFAULT to use default allocators. - PYMEM_ALLOCATOR_NOT_SET does nothing. */ -PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); - -struct _PyTraceMalloc_Config { - /* Module initialized? - Variable protected by the GIL */ - enum { - TRACEMALLOC_NOT_INITIALIZED, - TRACEMALLOC_INITIALIZED, - TRACEMALLOC_FINALIZED - } initialized; - - /* Is tracemalloc tracing memory allocations? - Variable protected by the GIL */ - int tracing; - - /* limit of the number of frames in a traceback, 1 by default. - Variable protected by the GIL. */ - int max_nframe; -}; - -#define _PyTraceMalloc_Config_INIT \ - {.initialized = TRACEMALLOC_NOT_INITIALIZED, \ - .tracing = 0, \ - .max_nframe = 1} - -PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config; - -/* Allocate memory directly from the O/S virtual memory system, - * where supported. Otherwise fallback on malloc */ -void *_PyObject_VirtualAlloc(size_t size); -void _PyObject_VirtualFree(void *, size_t size); - -/* This function returns the number of allocated memory blocks, regardless of size */ -PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void); - -/* Macros */ -#ifdef WITH_PYMALLOC -// Export the symbol for the 3rd party guppy3 project -PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out); -#endif - -#ifdef __cplusplus -} -#endif -#endif // !Py_INTERNAL_PYMEM_H diff --git a/python/include/internal/pycore_pystate.h b/python/include/internal/pycore_pystate.h deleted file mode 100644 index 6f4361b..0000000 --- a/python/include/internal/pycore_pystate.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef Py_INTERNAL_PYSTATE_H -#define Py_INTERNAL_PYSTATE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_runtime.h" /* PyRuntimeState */ - - -/* Check if the current thread is the main thread. - Use _Py_IsMainInterpreter() to check if it's the main interpreter. */ -static inline int -_Py_IsMainThread(void) -{ - unsigned long thread = PyThread_get_thread_ident(); - return (thread == _PyRuntime.main_thread); -} - - -static inline PyInterpreterState * -_PyInterpreterState_Main(void) -{ - return _PyRuntime.interpreters.main; -} - -static inline int -_Py_IsMainInterpreter(PyInterpreterState *interp) -{ - return (interp == _PyInterpreterState_Main()); -} - - -static inline const PyConfig * -_Py_GetMainConfig(void) -{ - PyInterpreterState *interp = _PyInterpreterState_Main(); - if (interp == NULL) { - return NULL; - } - return _PyInterpreterState_GetConfig(interp); -} - - -/* Only handle signals on the main thread of the main interpreter. */ -static inline int -_Py_ThreadCanHandleSignals(PyInterpreterState *interp) -{ - return (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)); -} - - -/* Only execute pending calls on the main thread. */ -static inline int -_Py_ThreadCanHandlePendingCalls(void) -{ - return _Py_IsMainThread(); -} - - -/* Variable and macro for in-line access to current thread - and interpreter state */ - -static inline PyThreadState* -_PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) -{ - return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current); -} - -/* Get the current Python thread state. - - Efficient macro reading directly the 'gilstate.tstate_current' atomic - variable. The macro is unsafe: it does not check for error and it can - return NULL. - - The caller must hold the GIL. - - See also PyThreadState_Get() and _PyThreadState_UncheckedGet(). */ -static inline PyThreadState* -_PyThreadState_GET(void) -{ - return _PyRuntimeState_GetThreadState(&_PyRuntime); -} - -PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalError_TstateNULL(const char *func); - -static inline void -_Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate) -{ - if (tstate == NULL) { - _Py_FatalError_TstateNULL(func); - } -} - -// Call Py_FatalError() if tstate is NULL -#define _Py_EnsureTstateNotNULL(tstate) \ - _Py_EnsureFuncTstateNotNULL(__func__, tstate) - - -/* Get the current interpreter state. - - The macro is unsafe: it does not check for error and it can return NULL. - - The caller must hold the GIL. - - See also _PyInterpreterState_Get() - and _PyGILState_GetInterpreterStateUnsafe(). */ -static inline PyInterpreterState* _PyInterpreterState_GET(void) { - PyThreadState *tstate = _PyThreadState_GET(); -#ifdef Py_DEBUG - _Py_EnsureTstateNotNULL(tstate); -#endif - return tstate->interp; -} - - -// PyThreadState functions - -PyAPI_FUNC(void) _PyThreadState_SetCurrent(PyThreadState *tstate); -// We keep this around exclusively for stable ABI compatibility. -PyAPI_FUNC(void) _PyThreadState_Init( - PyThreadState *tstate); -PyAPI_FUNC(void) _PyThreadState_DeleteExcept( - _PyRuntimeState *runtime, - PyThreadState *tstate); - - -static inline void -_PyThreadState_UpdateTracingState(PyThreadState *tstate) -{ - bool use_tracing = - (tstate->tracing == 0) && - (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL); - tstate->cframe->use_tracing = (use_tracing ? 255 : 0); -} - - -/* Other */ - -PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( - struct _gilstate_runtime_state *gilstate, - PyThreadState *newts); - -PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime); - -#ifdef HAVE_FORK -extern PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); -extern PyStatus _PyGILState_Reinit(_PyRuntimeState *runtime); -extern void _PySignal_AfterFork(void); -#endif - - -PyAPI_FUNC(int) _PyState_AddModule( - PyThreadState *tstate, - PyObject* module, - PyModuleDef* def); - - -PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_PYSTATE_H */ diff --git a/python/include/internal/pycore_runtime.h b/python/include/internal/pycore_runtime.h deleted file mode 100644 index 6cab63b..0000000 --- a/python/include/internal/pycore_runtime.h +++ /dev/null @@ -1,181 +0,0 @@ -#ifndef Py_INTERNAL_RUNTIME_H -#define Py_INTERNAL_RUNTIME_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_atomic.h" /* _Py_atomic_address */ -#include "pycore_gil.h" // struct _gil_runtime_state -#include "pycore_global_objects.h" // struct _Py_global_objects -#include "pycore_interp.h" // PyInterpreterState -#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids - - -/* ceval state */ - -struct _ceval_runtime_state { - /* Request for checking signals. It is shared by all interpreters (see - bpo-40513). Any thread of any interpreter can receive a signal, but only - the main thread of the main interpreter can handle signals: see - _Py_ThreadCanHandleSignals(). */ - _Py_atomic_int signals_pending; - struct _gil_runtime_state gil; -}; - -/* GIL state */ - -struct _gilstate_runtime_state { - /* bpo-26558: Flag to disable PyGILState_Check(). - If set to non-zero, PyGILState_Check() always return 1. */ - int check_enabled; - /* Assuming the current thread holds the GIL, this is the - PyThreadState for the current thread. */ - _Py_atomic_address tstate_current; - /* The single PyInterpreterState used by this process' - GILState implementation - */ - /* TODO: Given interp_main, it may be possible to kill this ref */ - PyInterpreterState *autoInterpreterState; - Py_tss_t autoTSSkey; -}; - -/* Runtime audit hook state */ - -typedef struct _Py_AuditHookEntry { - struct _Py_AuditHookEntry *next; - Py_AuditHookFunction hookCFunction; - void *userData; -} _Py_AuditHookEntry; - -/* Full Python runtime state */ - -/* _PyRuntimeState holds the global state for the CPython runtime. - That data is exposed in the internal API as a static variable (_PyRuntime). - */ -typedef struct pyruntimestate { - /* Has been initialized to a safe state. - - In order to be effective, this must be set to 0 during or right - after allocation. */ - int _initialized; - - /* Is running Py_PreInitialize()? */ - int preinitializing; - - /* Is Python preinitialized? Set to 1 by Py_PreInitialize() */ - int preinitialized; - - /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */ - int core_initialized; - - /* Is Python fully initialized? Set to 1 by Py_Initialize() */ - int initialized; - - /* Set by Py_FinalizeEx(). Only reset to NULL if Py_Initialize() - is called again. - - Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing() - to access it, don't access it directly. */ - _Py_atomic_address _finalizing; - - struct pyinterpreters { - PyThread_type_lock mutex; - /* The linked list of interpreters, newest first. */ - PyInterpreterState *head; - /* The runtime's initial interpreter, which has a special role - in the operation of the runtime. It is also often the only - interpreter. */ - PyInterpreterState *main; - /* _next_interp_id is an auto-numbered sequence of small - integers. It gets initialized in _PyInterpreterState_Init(), - which is called in Py_Initialize(), and used in - PyInterpreterState_New(). A negative interpreter ID - indicates an error occurred. The main interpreter will - always have an ID of 0. Overflow results in a RuntimeError. - If that becomes a problem later then we can adjust, e.g. by - using a Python int. */ - int64_t next_id; - } interpreters; - // XXX Remove this field once we have a tp_* slot. - struct _xidregistry { - PyThread_type_lock mutex; - struct _xidregitem *head; - } xidregistry; - - unsigned long main_thread; - -#define NEXITFUNCS 32 - void (*exitfuncs[NEXITFUNCS])(void); - int nexitfuncs; - - struct _ceval_runtime_state ceval; - struct _gilstate_runtime_state gilstate; - - PyPreConfig preconfig; - - // Audit values must be preserved when Py_Initialize()/Py_Finalize() - // is called multiple times. - Py_OpenCodeHookFunction open_code_hook; - void *open_code_userdata; - _Py_AuditHookEntry *audit_hook_head; - - struct _Py_unicode_runtime_ids unicode_ids; - - /* All the objects that are shared by the runtime's interpreters. */ - struct _Py_global_objects global_objects; - - /* The following fields are here to avoid allocation during init. - The data is exposed through _PyRuntimeState pointer fields. - These fields should not be accessed directly outside of init. - - All other _PyRuntimeState pointer fields are populated when - needed and default to NULL. - - For now there are some exceptions to that rule, which require - allocation during init. These will be addressed on a case-by-case - basis. Most notably, we don't pre-allocated the several mutex - (PyThread_type_lock) fields, because on Windows we only ever get - a pointer type. - */ - - /* PyInterpreterState.interpreters.main */ - PyInterpreterState _main_interpreter; -} _PyRuntimeState; - - -/* other API */ - -PyAPI_DATA(_PyRuntimeState) _PyRuntime; - -PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime); -PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime); - -#ifdef HAVE_FORK -extern PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); -#endif - -/* Initialize _PyRuntimeState. - Return NULL on success, or return an error message on failure. */ -PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void); - -PyAPI_FUNC(void) _PyRuntime_Finalize(void); - - -static inline PyThreadState* -_PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) { - return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing); -} - -static inline void -_PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) { - _Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate); -} - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_RUNTIME_H */ diff --git a/python/include/internal/pycore_runtime_init.h b/python/include/internal/pycore_runtime_init.h deleted file mode 100644 index 276ed93..0000000 --- a/python/include/internal/pycore_runtime_init.h +++ /dev/null @@ -1,1256 +0,0 @@ -#ifndef Py_INTERNAL_RUNTIME_INIT_H -#define Py_INTERNAL_RUNTIME_INIT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_object.h" - - -/* The static initializers defined here should only be used - in the runtime init code (in pystate.c and pylifecycle.c). */ - - -#define _PyRuntimeState_INIT \ - { \ - .gilstate = { \ - .check_enabled = 1, \ - /* A TSS key must be initialized with Py_tss_NEEDS_INIT \ - in accordance with the specification. */ \ - .autoTSSkey = Py_tss_NEEDS_INIT, \ - }, \ - .interpreters = { \ - /* This prevents interpreters from getting created \ - until _PyInterpreterState_Enable() is called. */ \ - .next_id = -1, \ - }, \ - .global_objects = _Py_global_objects_INIT, \ - ._main_interpreter = _PyInterpreterState_INIT, \ - } - -#ifdef HAVE_DLOPEN -# include -# if HAVE_DECL_RTLD_NOW -# define _Py_DLOPEN_FLAGS RTLD_NOW -# else -# define _Py_DLOPEN_FLAGS RTLD_LAZY -# endif -# define DLOPENFLAGS_INIT .dlopenflags = _Py_DLOPEN_FLAGS, -#else -# define _Py_DLOPEN_FLAGS 0 -# define DLOPENFLAGS_INIT -#endif - -#define _PyInterpreterState_INIT \ - { \ - ._static = 1, \ - .id_refcount = -1, \ - DLOPENFLAGS_INIT \ - .ceval = { \ - .recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ - }, \ - .gc = { \ - .enabled = 1, \ - .generations = { \ - /* .head is set in _PyGC_InitState(). */ \ - { .threshold = 700, }, \ - { .threshold = 10, }, \ - { .threshold = 10, }, \ - }, \ - }, \ - ._initial_thread = _PyThreadState_INIT, \ - } - -#define _PyThreadState_INIT \ - { \ - ._static = 1, \ - .recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ - .context_ver = 1, \ - } - - -// global objects - -#define _PyLong_DIGIT_INIT(val) \ - { \ - _PyVarObject_IMMORTAL_INIT(&PyLong_Type, \ - ((val) == 0 ? 0 : ((val) > 0 ? 1 : -1))), \ - .ob_digit = { ((val) >= 0 ? (val) : -(val)) }, \ - } - -#define _PyBytes_SIMPLE_INIT(CH, LEN) \ - { \ - _PyVarObject_IMMORTAL_INIT(&PyBytes_Type, LEN), \ - .ob_shash = -1, \ - .ob_sval = { CH }, \ - } -#define _PyBytes_CHAR_INIT(CH) \ - { \ - _PyBytes_SIMPLE_INIT(CH, 1) \ - } - -#define _PyUnicode_ASCII_BASE_INIT(LITERAL, ASCII) \ - { \ - .ob_base = _PyObject_IMMORTAL_INIT(&PyUnicode_Type), \ - .length = sizeof(LITERAL) - 1, \ - .hash = -1, \ - .state = { \ - .kind = 1, \ - .compact = 1, \ - .ascii = ASCII, \ - .ready = 1, \ - }, \ - } -#define _PyASCIIObject_INIT(LITERAL) \ - { \ - ._ascii = _PyUnicode_ASCII_BASE_INIT(LITERAL, 1), \ - ._data = LITERAL \ - } -#define INIT_STR(NAME, LITERAL) \ - ._ ## NAME = _PyASCIIObject_INIT(LITERAL) -#define INIT_ID(NAME) \ - ._ ## NAME = _PyASCIIObject_INIT(#NAME) -#define _PyUnicode_LATIN1_INIT(LITERAL) \ - { \ - ._latin1 = { \ - ._base = _PyUnicode_ASCII_BASE_INIT(LITERAL, 0), \ - }, \ - ._data = LITERAL, \ - } - -/* The following is auto-generated by Tools/scripts/generate_global_objects.py. */ -#define _Py_global_objects_INIT { \ - .singletons = { \ - .small_ints = { \ - _PyLong_DIGIT_INIT(-5), \ - _PyLong_DIGIT_INIT(-4), \ - _PyLong_DIGIT_INIT(-3), \ - _PyLong_DIGIT_INIT(-2), \ - _PyLong_DIGIT_INIT(-1), \ - _PyLong_DIGIT_INIT(0), \ - _PyLong_DIGIT_INIT(1), \ - _PyLong_DIGIT_INIT(2), \ - _PyLong_DIGIT_INIT(3), \ - _PyLong_DIGIT_INIT(4), \ - _PyLong_DIGIT_INIT(5), \ - _PyLong_DIGIT_INIT(6), \ - _PyLong_DIGIT_INIT(7), \ - _PyLong_DIGIT_INIT(8), \ - _PyLong_DIGIT_INIT(9), \ - _PyLong_DIGIT_INIT(10), \ - _PyLong_DIGIT_INIT(11), \ - _PyLong_DIGIT_INIT(12), \ - _PyLong_DIGIT_INIT(13), \ - _PyLong_DIGIT_INIT(14), \ - _PyLong_DIGIT_INIT(15), \ - _PyLong_DIGIT_INIT(16), \ - _PyLong_DIGIT_INIT(17), \ - _PyLong_DIGIT_INIT(18), \ - _PyLong_DIGIT_INIT(19), \ - _PyLong_DIGIT_INIT(20), \ - _PyLong_DIGIT_INIT(21), \ - _PyLong_DIGIT_INIT(22), \ - _PyLong_DIGIT_INIT(23), \ - _PyLong_DIGIT_INIT(24), \ - _PyLong_DIGIT_INIT(25), \ - _PyLong_DIGIT_INIT(26), \ - _PyLong_DIGIT_INIT(27), \ - _PyLong_DIGIT_INIT(28), \ - _PyLong_DIGIT_INIT(29), \ - _PyLong_DIGIT_INIT(30), \ - _PyLong_DIGIT_INIT(31), \ - _PyLong_DIGIT_INIT(32), \ - _PyLong_DIGIT_INIT(33), \ - _PyLong_DIGIT_INIT(34), \ - _PyLong_DIGIT_INIT(35), \ - _PyLong_DIGIT_INIT(36), \ - _PyLong_DIGIT_INIT(37), \ - _PyLong_DIGIT_INIT(38), \ - _PyLong_DIGIT_INIT(39), \ - _PyLong_DIGIT_INIT(40), \ - _PyLong_DIGIT_INIT(41), \ - _PyLong_DIGIT_INIT(42), \ - _PyLong_DIGIT_INIT(43), \ - _PyLong_DIGIT_INIT(44), \ - _PyLong_DIGIT_INIT(45), \ - _PyLong_DIGIT_INIT(46), \ - _PyLong_DIGIT_INIT(47), \ - _PyLong_DIGIT_INIT(48), \ - _PyLong_DIGIT_INIT(49), \ - _PyLong_DIGIT_INIT(50), \ - _PyLong_DIGIT_INIT(51), \ - _PyLong_DIGIT_INIT(52), \ - _PyLong_DIGIT_INIT(53), \ - _PyLong_DIGIT_INIT(54), \ - _PyLong_DIGIT_INIT(55), \ - _PyLong_DIGIT_INIT(56), \ - _PyLong_DIGIT_INIT(57), \ - _PyLong_DIGIT_INIT(58), \ - _PyLong_DIGIT_INIT(59), \ - _PyLong_DIGIT_INIT(60), \ - _PyLong_DIGIT_INIT(61), \ - _PyLong_DIGIT_INIT(62), \ - _PyLong_DIGIT_INIT(63), \ - _PyLong_DIGIT_INIT(64), \ - _PyLong_DIGIT_INIT(65), \ - _PyLong_DIGIT_INIT(66), \ - _PyLong_DIGIT_INIT(67), \ - _PyLong_DIGIT_INIT(68), \ - _PyLong_DIGIT_INIT(69), \ - _PyLong_DIGIT_INIT(70), \ - _PyLong_DIGIT_INIT(71), \ - _PyLong_DIGIT_INIT(72), \ - _PyLong_DIGIT_INIT(73), \ - _PyLong_DIGIT_INIT(74), \ - _PyLong_DIGIT_INIT(75), \ - _PyLong_DIGIT_INIT(76), \ - _PyLong_DIGIT_INIT(77), \ - _PyLong_DIGIT_INIT(78), \ - _PyLong_DIGIT_INIT(79), \ - _PyLong_DIGIT_INIT(80), \ - _PyLong_DIGIT_INIT(81), \ - _PyLong_DIGIT_INIT(82), \ - _PyLong_DIGIT_INIT(83), \ - _PyLong_DIGIT_INIT(84), \ - _PyLong_DIGIT_INIT(85), \ - _PyLong_DIGIT_INIT(86), \ - _PyLong_DIGIT_INIT(87), \ - _PyLong_DIGIT_INIT(88), \ - _PyLong_DIGIT_INIT(89), \ - _PyLong_DIGIT_INIT(90), \ - _PyLong_DIGIT_INIT(91), \ - _PyLong_DIGIT_INIT(92), \ - _PyLong_DIGIT_INIT(93), \ - _PyLong_DIGIT_INIT(94), \ - _PyLong_DIGIT_INIT(95), \ - _PyLong_DIGIT_INIT(96), \ - _PyLong_DIGIT_INIT(97), \ - _PyLong_DIGIT_INIT(98), \ - _PyLong_DIGIT_INIT(99), \ - _PyLong_DIGIT_INIT(100), \ - _PyLong_DIGIT_INIT(101), \ - _PyLong_DIGIT_INIT(102), \ - _PyLong_DIGIT_INIT(103), \ - _PyLong_DIGIT_INIT(104), \ - _PyLong_DIGIT_INIT(105), \ - _PyLong_DIGIT_INIT(106), \ - _PyLong_DIGIT_INIT(107), \ - _PyLong_DIGIT_INIT(108), \ - _PyLong_DIGIT_INIT(109), \ - _PyLong_DIGIT_INIT(110), \ - _PyLong_DIGIT_INIT(111), \ - _PyLong_DIGIT_INIT(112), \ - _PyLong_DIGIT_INIT(113), \ - _PyLong_DIGIT_INIT(114), \ - _PyLong_DIGIT_INIT(115), \ - _PyLong_DIGIT_INIT(116), \ - _PyLong_DIGIT_INIT(117), \ - _PyLong_DIGIT_INIT(118), \ - _PyLong_DIGIT_INIT(119), \ - _PyLong_DIGIT_INIT(120), \ - _PyLong_DIGIT_INIT(121), \ - _PyLong_DIGIT_INIT(122), \ - _PyLong_DIGIT_INIT(123), \ - _PyLong_DIGIT_INIT(124), \ - _PyLong_DIGIT_INIT(125), \ - _PyLong_DIGIT_INIT(126), \ - _PyLong_DIGIT_INIT(127), \ - _PyLong_DIGIT_INIT(128), \ - _PyLong_DIGIT_INIT(129), \ - _PyLong_DIGIT_INIT(130), \ - _PyLong_DIGIT_INIT(131), \ - _PyLong_DIGIT_INIT(132), \ - _PyLong_DIGIT_INIT(133), \ - _PyLong_DIGIT_INIT(134), \ - _PyLong_DIGIT_INIT(135), \ - _PyLong_DIGIT_INIT(136), \ - _PyLong_DIGIT_INIT(137), \ - _PyLong_DIGIT_INIT(138), \ - _PyLong_DIGIT_INIT(139), \ - _PyLong_DIGIT_INIT(140), \ - _PyLong_DIGIT_INIT(141), \ - _PyLong_DIGIT_INIT(142), \ - _PyLong_DIGIT_INIT(143), \ - _PyLong_DIGIT_INIT(144), \ - _PyLong_DIGIT_INIT(145), \ - _PyLong_DIGIT_INIT(146), \ - _PyLong_DIGIT_INIT(147), \ - _PyLong_DIGIT_INIT(148), \ - _PyLong_DIGIT_INIT(149), \ - _PyLong_DIGIT_INIT(150), \ - _PyLong_DIGIT_INIT(151), \ - _PyLong_DIGIT_INIT(152), \ - _PyLong_DIGIT_INIT(153), \ - _PyLong_DIGIT_INIT(154), \ - _PyLong_DIGIT_INIT(155), \ - _PyLong_DIGIT_INIT(156), \ - _PyLong_DIGIT_INIT(157), \ - _PyLong_DIGIT_INIT(158), \ - _PyLong_DIGIT_INIT(159), \ - _PyLong_DIGIT_INIT(160), \ - _PyLong_DIGIT_INIT(161), \ - _PyLong_DIGIT_INIT(162), \ - _PyLong_DIGIT_INIT(163), \ - _PyLong_DIGIT_INIT(164), \ - _PyLong_DIGIT_INIT(165), \ - _PyLong_DIGIT_INIT(166), \ - _PyLong_DIGIT_INIT(167), \ - _PyLong_DIGIT_INIT(168), \ - _PyLong_DIGIT_INIT(169), \ - _PyLong_DIGIT_INIT(170), \ - _PyLong_DIGIT_INIT(171), \ - _PyLong_DIGIT_INIT(172), \ - _PyLong_DIGIT_INIT(173), \ - _PyLong_DIGIT_INIT(174), \ - _PyLong_DIGIT_INIT(175), \ - _PyLong_DIGIT_INIT(176), \ - _PyLong_DIGIT_INIT(177), \ - _PyLong_DIGIT_INIT(178), \ - _PyLong_DIGIT_INIT(179), \ - _PyLong_DIGIT_INIT(180), \ - _PyLong_DIGIT_INIT(181), \ - _PyLong_DIGIT_INIT(182), \ - _PyLong_DIGIT_INIT(183), \ - _PyLong_DIGIT_INIT(184), \ - _PyLong_DIGIT_INIT(185), \ - _PyLong_DIGIT_INIT(186), \ - _PyLong_DIGIT_INIT(187), \ - _PyLong_DIGIT_INIT(188), \ - _PyLong_DIGIT_INIT(189), \ - _PyLong_DIGIT_INIT(190), \ - _PyLong_DIGIT_INIT(191), \ - _PyLong_DIGIT_INIT(192), \ - _PyLong_DIGIT_INIT(193), \ - _PyLong_DIGIT_INIT(194), \ - _PyLong_DIGIT_INIT(195), \ - _PyLong_DIGIT_INIT(196), \ - _PyLong_DIGIT_INIT(197), \ - _PyLong_DIGIT_INIT(198), \ - _PyLong_DIGIT_INIT(199), \ - _PyLong_DIGIT_INIT(200), \ - _PyLong_DIGIT_INIT(201), \ - _PyLong_DIGIT_INIT(202), \ - _PyLong_DIGIT_INIT(203), \ - _PyLong_DIGIT_INIT(204), \ - _PyLong_DIGIT_INIT(205), \ - _PyLong_DIGIT_INIT(206), \ - _PyLong_DIGIT_INIT(207), \ - _PyLong_DIGIT_INIT(208), \ - _PyLong_DIGIT_INIT(209), \ - _PyLong_DIGIT_INIT(210), \ - _PyLong_DIGIT_INIT(211), \ - _PyLong_DIGIT_INIT(212), \ - _PyLong_DIGIT_INIT(213), \ - _PyLong_DIGIT_INIT(214), \ - _PyLong_DIGIT_INIT(215), \ - _PyLong_DIGIT_INIT(216), \ - _PyLong_DIGIT_INIT(217), \ - _PyLong_DIGIT_INIT(218), \ - _PyLong_DIGIT_INIT(219), \ - _PyLong_DIGIT_INIT(220), \ - _PyLong_DIGIT_INIT(221), \ - _PyLong_DIGIT_INIT(222), \ - _PyLong_DIGIT_INIT(223), \ - _PyLong_DIGIT_INIT(224), \ - _PyLong_DIGIT_INIT(225), \ - _PyLong_DIGIT_INIT(226), \ - _PyLong_DIGIT_INIT(227), \ - _PyLong_DIGIT_INIT(228), \ - _PyLong_DIGIT_INIT(229), \ - _PyLong_DIGIT_INIT(230), \ - _PyLong_DIGIT_INIT(231), \ - _PyLong_DIGIT_INIT(232), \ - _PyLong_DIGIT_INIT(233), \ - _PyLong_DIGIT_INIT(234), \ - _PyLong_DIGIT_INIT(235), \ - _PyLong_DIGIT_INIT(236), \ - _PyLong_DIGIT_INIT(237), \ - _PyLong_DIGIT_INIT(238), \ - _PyLong_DIGIT_INIT(239), \ - _PyLong_DIGIT_INIT(240), \ - _PyLong_DIGIT_INIT(241), \ - _PyLong_DIGIT_INIT(242), \ - _PyLong_DIGIT_INIT(243), \ - _PyLong_DIGIT_INIT(244), \ - _PyLong_DIGIT_INIT(245), \ - _PyLong_DIGIT_INIT(246), \ - _PyLong_DIGIT_INIT(247), \ - _PyLong_DIGIT_INIT(248), \ - _PyLong_DIGIT_INIT(249), \ - _PyLong_DIGIT_INIT(250), \ - _PyLong_DIGIT_INIT(251), \ - _PyLong_DIGIT_INIT(252), \ - _PyLong_DIGIT_INIT(253), \ - _PyLong_DIGIT_INIT(254), \ - _PyLong_DIGIT_INIT(255), \ - _PyLong_DIGIT_INIT(256), \ - }, \ - \ - .bytes_empty = _PyBytes_SIMPLE_INIT(0, 0), \ - .bytes_characters = { \ - _PyBytes_CHAR_INIT(0), \ - _PyBytes_CHAR_INIT(1), \ - _PyBytes_CHAR_INIT(2), \ - _PyBytes_CHAR_INIT(3), \ - _PyBytes_CHAR_INIT(4), \ - _PyBytes_CHAR_INIT(5), \ - _PyBytes_CHAR_INIT(6), \ - _PyBytes_CHAR_INIT(7), \ - _PyBytes_CHAR_INIT(8), \ - _PyBytes_CHAR_INIT(9), \ - _PyBytes_CHAR_INIT(10), \ - _PyBytes_CHAR_INIT(11), \ - _PyBytes_CHAR_INIT(12), \ - _PyBytes_CHAR_INIT(13), \ - _PyBytes_CHAR_INIT(14), \ - _PyBytes_CHAR_INIT(15), \ - _PyBytes_CHAR_INIT(16), \ - _PyBytes_CHAR_INIT(17), \ - _PyBytes_CHAR_INIT(18), \ - _PyBytes_CHAR_INIT(19), \ - _PyBytes_CHAR_INIT(20), \ - _PyBytes_CHAR_INIT(21), \ - _PyBytes_CHAR_INIT(22), \ - _PyBytes_CHAR_INIT(23), \ - _PyBytes_CHAR_INIT(24), \ - _PyBytes_CHAR_INIT(25), \ - _PyBytes_CHAR_INIT(26), \ - _PyBytes_CHAR_INIT(27), \ - _PyBytes_CHAR_INIT(28), \ - _PyBytes_CHAR_INIT(29), \ - _PyBytes_CHAR_INIT(30), \ - _PyBytes_CHAR_INIT(31), \ - _PyBytes_CHAR_INIT(32), \ - _PyBytes_CHAR_INIT(33), \ - _PyBytes_CHAR_INIT(34), \ - _PyBytes_CHAR_INIT(35), \ - _PyBytes_CHAR_INIT(36), \ - _PyBytes_CHAR_INIT(37), \ - _PyBytes_CHAR_INIT(38), \ - _PyBytes_CHAR_INIT(39), \ - _PyBytes_CHAR_INIT(40), \ - _PyBytes_CHAR_INIT(41), \ - _PyBytes_CHAR_INIT(42), \ - _PyBytes_CHAR_INIT(43), \ - _PyBytes_CHAR_INIT(44), \ - _PyBytes_CHAR_INIT(45), \ - _PyBytes_CHAR_INIT(46), \ - _PyBytes_CHAR_INIT(47), \ - _PyBytes_CHAR_INIT(48), \ - _PyBytes_CHAR_INIT(49), \ - _PyBytes_CHAR_INIT(50), \ - _PyBytes_CHAR_INIT(51), \ - _PyBytes_CHAR_INIT(52), \ - _PyBytes_CHAR_INIT(53), \ - _PyBytes_CHAR_INIT(54), \ - _PyBytes_CHAR_INIT(55), \ - _PyBytes_CHAR_INIT(56), \ - _PyBytes_CHAR_INIT(57), \ - _PyBytes_CHAR_INIT(58), \ - _PyBytes_CHAR_INIT(59), \ - _PyBytes_CHAR_INIT(60), \ - _PyBytes_CHAR_INIT(61), \ - _PyBytes_CHAR_INIT(62), \ - _PyBytes_CHAR_INIT(63), \ - _PyBytes_CHAR_INIT(64), \ - _PyBytes_CHAR_INIT(65), \ - _PyBytes_CHAR_INIT(66), \ - _PyBytes_CHAR_INIT(67), \ - _PyBytes_CHAR_INIT(68), \ - _PyBytes_CHAR_INIT(69), \ - _PyBytes_CHAR_INIT(70), \ - _PyBytes_CHAR_INIT(71), \ - _PyBytes_CHAR_INIT(72), \ - _PyBytes_CHAR_INIT(73), \ - _PyBytes_CHAR_INIT(74), \ - _PyBytes_CHAR_INIT(75), \ - _PyBytes_CHAR_INIT(76), \ - _PyBytes_CHAR_INIT(77), \ - _PyBytes_CHAR_INIT(78), \ - _PyBytes_CHAR_INIT(79), \ - _PyBytes_CHAR_INIT(80), \ - _PyBytes_CHAR_INIT(81), \ - _PyBytes_CHAR_INIT(82), \ - _PyBytes_CHAR_INIT(83), \ - _PyBytes_CHAR_INIT(84), \ - _PyBytes_CHAR_INIT(85), \ - _PyBytes_CHAR_INIT(86), \ - _PyBytes_CHAR_INIT(87), \ - _PyBytes_CHAR_INIT(88), \ - _PyBytes_CHAR_INIT(89), \ - _PyBytes_CHAR_INIT(90), \ - _PyBytes_CHAR_INIT(91), \ - _PyBytes_CHAR_INIT(92), \ - _PyBytes_CHAR_INIT(93), \ - _PyBytes_CHAR_INIT(94), \ - _PyBytes_CHAR_INIT(95), \ - _PyBytes_CHAR_INIT(96), \ - _PyBytes_CHAR_INIT(97), \ - _PyBytes_CHAR_INIT(98), \ - _PyBytes_CHAR_INIT(99), \ - _PyBytes_CHAR_INIT(100), \ - _PyBytes_CHAR_INIT(101), \ - _PyBytes_CHAR_INIT(102), \ - _PyBytes_CHAR_INIT(103), \ - _PyBytes_CHAR_INIT(104), \ - _PyBytes_CHAR_INIT(105), \ - _PyBytes_CHAR_INIT(106), \ - _PyBytes_CHAR_INIT(107), \ - _PyBytes_CHAR_INIT(108), \ - _PyBytes_CHAR_INIT(109), \ - _PyBytes_CHAR_INIT(110), \ - _PyBytes_CHAR_INIT(111), \ - _PyBytes_CHAR_INIT(112), \ - _PyBytes_CHAR_INIT(113), \ - _PyBytes_CHAR_INIT(114), \ - _PyBytes_CHAR_INIT(115), \ - _PyBytes_CHAR_INIT(116), \ - _PyBytes_CHAR_INIT(117), \ - _PyBytes_CHAR_INIT(118), \ - _PyBytes_CHAR_INIT(119), \ - _PyBytes_CHAR_INIT(120), \ - _PyBytes_CHAR_INIT(121), \ - _PyBytes_CHAR_INIT(122), \ - _PyBytes_CHAR_INIT(123), \ - _PyBytes_CHAR_INIT(124), \ - _PyBytes_CHAR_INIT(125), \ - _PyBytes_CHAR_INIT(126), \ - _PyBytes_CHAR_INIT(127), \ - _PyBytes_CHAR_INIT(128), \ - _PyBytes_CHAR_INIT(129), \ - _PyBytes_CHAR_INIT(130), \ - _PyBytes_CHAR_INIT(131), \ - _PyBytes_CHAR_INIT(132), \ - _PyBytes_CHAR_INIT(133), \ - _PyBytes_CHAR_INIT(134), \ - _PyBytes_CHAR_INIT(135), \ - _PyBytes_CHAR_INIT(136), \ - _PyBytes_CHAR_INIT(137), \ - _PyBytes_CHAR_INIT(138), \ - _PyBytes_CHAR_INIT(139), \ - _PyBytes_CHAR_INIT(140), \ - _PyBytes_CHAR_INIT(141), \ - _PyBytes_CHAR_INIT(142), \ - _PyBytes_CHAR_INIT(143), \ - _PyBytes_CHAR_INIT(144), \ - _PyBytes_CHAR_INIT(145), \ - _PyBytes_CHAR_INIT(146), \ - _PyBytes_CHAR_INIT(147), \ - _PyBytes_CHAR_INIT(148), \ - _PyBytes_CHAR_INIT(149), \ - _PyBytes_CHAR_INIT(150), \ - _PyBytes_CHAR_INIT(151), \ - _PyBytes_CHAR_INIT(152), \ - _PyBytes_CHAR_INIT(153), \ - _PyBytes_CHAR_INIT(154), \ - _PyBytes_CHAR_INIT(155), \ - _PyBytes_CHAR_INIT(156), \ - _PyBytes_CHAR_INIT(157), \ - _PyBytes_CHAR_INIT(158), \ - _PyBytes_CHAR_INIT(159), \ - _PyBytes_CHAR_INIT(160), \ - _PyBytes_CHAR_INIT(161), \ - _PyBytes_CHAR_INIT(162), \ - _PyBytes_CHAR_INIT(163), \ - _PyBytes_CHAR_INIT(164), \ - _PyBytes_CHAR_INIT(165), \ - _PyBytes_CHAR_INIT(166), \ - _PyBytes_CHAR_INIT(167), \ - _PyBytes_CHAR_INIT(168), \ - _PyBytes_CHAR_INIT(169), \ - _PyBytes_CHAR_INIT(170), \ - _PyBytes_CHAR_INIT(171), \ - _PyBytes_CHAR_INIT(172), \ - _PyBytes_CHAR_INIT(173), \ - _PyBytes_CHAR_INIT(174), \ - _PyBytes_CHAR_INIT(175), \ - _PyBytes_CHAR_INIT(176), \ - _PyBytes_CHAR_INIT(177), \ - _PyBytes_CHAR_INIT(178), \ - _PyBytes_CHAR_INIT(179), \ - _PyBytes_CHAR_INIT(180), \ - _PyBytes_CHAR_INIT(181), \ - _PyBytes_CHAR_INIT(182), \ - _PyBytes_CHAR_INIT(183), \ - _PyBytes_CHAR_INIT(184), \ - _PyBytes_CHAR_INIT(185), \ - _PyBytes_CHAR_INIT(186), \ - _PyBytes_CHAR_INIT(187), \ - _PyBytes_CHAR_INIT(188), \ - _PyBytes_CHAR_INIT(189), \ - _PyBytes_CHAR_INIT(190), \ - _PyBytes_CHAR_INIT(191), \ - _PyBytes_CHAR_INIT(192), \ - _PyBytes_CHAR_INIT(193), \ - _PyBytes_CHAR_INIT(194), \ - _PyBytes_CHAR_INIT(195), \ - _PyBytes_CHAR_INIT(196), \ - _PyBytes_CHAR_INIT(197), \ - _PyBytes_CHAR_INIT(198), \ - _PyBytes_CHAR_INIT(199), \ - _PyBytes_CHAR_INIT(200), \ - _PyBytes_CHAR_INIT(201), \ - _PyBytes_CHAR_INIT(202), \ - _PyBytes_CHAR_INIT(203), \ - _PyBytes_CHAR_INIT(204), \ - _PyBytes_CHAR_INIT(205), \ - _PyBytes_CHAR_INIT(206), \ - _PyBytes_CHAR_INIT(207), \ - _PyBytes_CHAR_INIT(208), \ - _PyBytes_CHAR_INIT(209), \ - _PyBytes_CHAR_INIT(210), \ - _PyBytes_CHAR_INIT(211), \ - _PyBytes_CHAR_INIT(212), \ - _PyBytes_CHAR_INIT(213), \ - _PyBytes_CHAR_INIT(214), \ - _PyBytes_CHAR_INIT(215), \ - _PyBytes_CHAR_INIT(216), \ - _PyBytes_CHAR_INIT(217), \ - _PyBytes_CHAR_INIT(218), \ - _PyBytes_CHAR_INIT(219), \ - _PyBytes_CHAR_INIT(220), \ - _PyBytes_CHAR_INIT(221), \ - _PyBytes_CHAR_INIT(222), \ - _PyBytes_CHAR_INIT(223), \ - _PyBytes_CHAR_INIT(224), \ - _PyBytes_CHAR_INIT(225), \ - _PyBytes_CHAR_INIT(226), \ - _PyBytes_CHAR_INIT(227), \ - _PyBytes_CHAR_INIT(228), \ - _PyBytes_CHAR_INIT(229), \ - _PyBytes_CHAR_INIT(230), \ - _PyBytes_CHAR_INIT(231), \ - _PyBytes_CHAR_INIT(232), \ - _PyBytes_CHAR_INIT(233), \ - _PyBytes_CHAR_INIT(234), \ - _PyBytes_CHAR_INIT(235), \ - _PyBytes_CHAR_INIT(236), \ - _PyBytes_CHAR_INIT(237), \ - _PyBytes_CHAR_INIT(238), \ - _PyBytes_CHAR_INIT(239), \ - _PyBytes_CHAR_INIT(240), \ - _PyBytes_CHAR_INIT(241), \ - _PyBytes_CHAR_INIT(242), \ - _PyBytes_CHAR_INIT(243), \ - _PyBytes_CHAR_INIT(244), \ - _PyBytes_CHAR_INIT(245), \ - _PyBytes_CHAR_INIT(246), \ - _PyBytes_CHAR_INIT(247), \ - _PyBytes_CHAR_INIT(248), \ - _PyBytes_CHAR_INIT(249), \ - _PyBytes_CHAR_INIT(250), \ - _PyBytes_CHAR_INIT(251), \ - _PyBytes_CHAR_INIT(252), \ - _PyBytes_CHAR_INIT(253), \ - _PyBytes_CHAR_INIT(254), \ - _PyBytes_CHAR_INIT(255), \ - }, \ - \ - .strings = { \ - .literals = { \ - INIT_STR(anon_dictcomp, ""), \ - INIT_STR(anon_genexpr, ""), \ - INIT_STR(anon_lambda, ""), \ - INIT_STR(anon_listcomp, ""), \ - INIT_STR(anon_module, ""), \ - INIT_STR(anon_setcomp, ""), \ - INIT_STR(anon_string, ""), \ - INIT_STR(anon_unknown, ""), \ - INIT_STR(close_br, "}"), \ - INIT_STR(comma_sep, ", "), \ - INIT_STR(dbl_close_br, "}}"), \ - INIT_STR(dbl_open_br, "{{"), \ - INIT_STR(dbl_percent, "%%"), \ - INIT_STR(dot, "."), \ - INIT_STR(dot_locals, "."), \ - INIT_STR(empty, ""), \ - INIT_STR(list_err, "list index out of range"), \ - INIT_STR(newline, "\n"), \ - INIT_STR(open_br, "{"), \ - INIT_STR(percent, "%"), \ - INIT_STR(utf_8, "utf-8"), \ - }, \ - .identifiers = { \ - INIT_ID(False), \ - INIT_ID(Py_Repr), \ - INIT_ID(TextIOWrapper), \ - INIT_ID(True), \ - INIT_ID(WarningMessage), \ - INIT_ID(_), \ - INIT_ID(__IOBase_closed), \ - INIT_ID(__abc_tpflags__), \ - INIT_ID(__abs__), \ - INIT_ID(__abstractmethods__), \ - INIT_ID(__add__), \ - INIT_ID(__aenter__), \ - INIT_ID(__aexit__), \ - INIT_ID(__aiter__), \ - INIT_ID(__all__), \ - INIT_ID(__and__), \ - INIT_ID(__anext__), \ - INIT_ID(__annotations__), \ - INIT_ID(__args__), \ - INIT_ID(__await__), \ - INIT_ID(__bases__), \ - INIT_ID(__bool__), \ - INIT_ID(__build_class__), \ - INIT_ID(__builtins__), \ - INIT_ID(__bytes__), \ - INIT_ID(__call__), \ - INIT_ID(__cantrace__), \ - INIT_ID(__class__), \ - INIT_ID(__class_getitem__), \ - INIT_ID(__classcell__), \ - INIT_ID(__complex__), \ - INIT_ID(__contains__), \ - INIT_ID(__copy__), \ - INIT_ID(__del__), \ - INIT_ID(__delattr__), \ - INIT_ID(__delete__), \ - INIT_ID(__delitem__), \ - INIT_ID(__dict__), \ - INIT_ID(__dir__), \ - INIT_ID(__divmod__), \ - INIT_ID(__doc__), \ - INIT_ID(__enter__), \ - INIT_ID(__eq__), \ - INIT_ID(__exit__), \ - INIT_ID(__file__), \ - INIT_ID(__float__), \ - INIT_ID(__floordiv__), \ - INIT_ID(__format__), \ - INIT_ID(__fspath__), \ - INIT_ID(__ge__), \ - INIT_ID(__get__), \ - INIT_ID(__getattr__), \ - INIT_ID(__getattribute__), \ - INIT_ID(__getinitargs__), \ - INIT_ID(__getitem__), \ - INIT_ID(__getnewargs__), \ - INIT_ID(__getnewargs_ex__), \ - INIT_ID(__getstate__), \ - INIT_ID(__gt__), \ - INIT_ID(__hash__), \ - INIT_ID(__iadd__), \ - INIT_ID(__iand__), \ - INIT_ID(__ifloordiv__), \ - INIT_ID(__ilshift__), \ - INIT_ID(__imatmul__), \ - INIT_ID(__imod__), \ - INIT_ID(__import__), \ - INIT_ID(__imul__), \ - INIT_ID(__index__), \ - INIT_ID(__init__), \ - INIT_ID(__init_subclass__), \ - INIT_ID(__instancecheck__), \ - INIT_ID(__int__), \ - INIT_ID(__invert__), \ - INIT_ID(__ior__), \ - INIT_ID(__ipow__), \ - INIT_ID(__irshift__), \ - INIT_ID(__isabstractmethod__), \ - INIT_ID(__isub__), \ - INIT_ID(__iter__), \ - INIT_ID(__itruediv__), \ - INIT_ID(__ixor__), \ - INIT_ID(__le__), \ - INIT_ID(__len__), \ - INIT_ID(__length_hint__), \ - INIT_ID(__lltrace__), \ - INIT_ID(__loader__), \ - INIT_ID(__lshift__), \ - INIT_ID(__lt__), \ - INIT_ID(__main__), \ - INIT_ID(__matmul__), \ - INIT_ID(__missing__), \ - INIT_ID(__mod__), \ - INIT_ID(__module__), \ - INIT_ID(__mro_entries__), \ - INIT_ID(__mul__), \ - INIT_ID(__name__), \ - INIT_ID(__ne__), \ - INIT_ID(__neg__), \ - INIT_ID(__new__), \ - INIT_ID(__newobj__), \ - INIT_ID(__newobj_ex__), \ - INIT_ID(__next__), \ - INIT_ID(__notes__), \ - INIT_ID(__or__), \ - INIT_ID(__orig_class__), \ - INIT_ID(__origin__), \ - INIT_ID(__package__), \ - INIT_ID(__parameters__), \ - INIT_ID(__path__), \ - INIT_ID(__pos__), \ - INIT_ID(__pow__), \ - INIT_ID(__prepare__), \ - INIT_ID(__qualname__), \ - INIT_ID(__radd__), \ - INIT_ID(__rand__), \ - INIT_ID(__rdivmod__), \ - INIT_ID(__reduce__), \ - INIT_ID(__reduce_ex__), \ - INIT_ID(__repr__), \ - INIT_ID(__reversed__), \ - INIT_ID(__rfloordiv__), \ - INIT_ID(__rlshift__), \ - INIT_ID(__rmatmul__), \ - INIT_ID(__rmod__), \ - INIT_ID(__rmul__), \ - INIT_ID(__ror__), \ - INIT_ID(__round__), \ - INIT_ID(__rpow__), \ - INIT_ID(__rrshift__), \ - INIT_ID(__rshift__), \ - INIT_ID(__rsub__), \ - INIT_ID(__rtruediv__), \ - INIT_ID(__rxor__), \ - INIT_ID(__set__), \ - INIT_ID(__set_name__), \ - INIT_ID(__setattr__), \ - INIT_ID(__setitem__), \ - INIT_ID(__setstate__), \ - INIT_ID(__sizeof__), \ - INIT_ID(__slotnames__), \ - INIT_ID(__slots__), \ - INIT_ID(__spec__), \ - INIT_ID(__str__), \ - INIT_ID(__sub__), \ - INIT_ID(__subclasscheck__), \ - INIT_ID(__subclasshook__), \ - INIT_ID(__truediv__), \ - INIT_ID(__trunc__), \ - INIT_ID(__typing_is_unpacked_typevartuple__), \ - INIT_ID(__typing_prepare_subst__), \ - INIT_ID(__typing_subst__), \ - INIT_ID(__typing_unpacked_tuple_args__), \ - INIT_ID(__warningregistry__), \ - INIT_ID(__weakref__), \ - INIT_ID(__xor__), \ - INIT_ID(_abc_impl), \ - INIT_ID(_annotation), \ - INIT_ID(_blksize), \ - INIT_ID(_bootstrap), \ - INIT_ID(_dealloc_warn), \ - INIT_ID(_finalizing), \ - INIT_ID(_find_and_load), \ - INIT_ID(_fix_up_module), \ - INIT_ID(_get_sourcefile), \ - INIT_ID(_handle_fromlist), \ - INIT_ID(_initializing), \ - INIT_ID(_is_text_encoding), \ - INIT_ID(_lock_unlock_module), \ - INIT_ID(_showwarnmsg), \ - INIT_ID(_shutdown), \ - INIT_ID(_slotnames), \ - INIT_ID(_strptime_time), \ - INIT_ID(_uninitialized_submodules), \ - INIT_ID(_warn_unawaited_coroutine), \ - INIT_ID(_xoptions), \ - INIT_ID(add), \ - INIT_ID(append), \ - INIT_ID(big), \ - INIT_ID(buffer), \ - INIT_ID(builtins), \ - INIT_ID(c_call), \ - INIT_ID(c_exception), \ - INIT_ID(c_return), \ - INIT_ID(call), \ - INIT_ID(clear), \ - INIT_ID(close), \ - INIT_ID(closed), \ - INIT_ID(code), \ - INIT_ID(copy), \ - INIT_ID(copyreg), \ - INIT_ID(decode), \ - INIT_ID(default), \ - INIT_ID(defaultaction), \ - INIT_ID(dictcomp), \ - INIT_ID(difference_update), \ - INIT_ID(dispatch_table), \ - INIT_ID(displayhook), \ - INIT_ID(enable), \ - INIT_ID(encode), \ - INIT_ID(encoding), \ - INIT_ID(end_lineno), \ - INIT_ID(end_offset), \ - INIT_ID(errors), \ - INIT_ID(excepthook), \ - INIT_ID(exception), \ - INIT_ID(extend), \ - INIT_ID(filename), \ - INIT_ID(fileno), \ - INIT_ID(fillvalue), \ - INIT_ID(filters), \ - INIT_ID(find_class), \ - INIT_ID(flush), \ - INIT_ID(genexpr), \ - INIT_ID(get), \ - INIT_ID(get_source), \ - INIT_ID(getattr), \ - INIT_ID(getstate), \ - INIT_ID(ignore), \ - INIT_ID(importlib), \ - INIT_ID(inf), \ - INIT_ID(intersection), \ - INIT_ID(isatty), \ - INIT_ID(isinstance), \ - INIT_ID(items), \ - INIT_ID(iter), \ - INIT_ID(join), \ - INIT_ID(keys), \ - INIT_ID(lambda), \ - INIT_ID(last_traceback), \ - INIT_ID(last_type), \ - INIT_ID(last_value), \ - INIT_ID(latin1), \ - INIT_ID(len), \ - INIT_ID(line), \ - INIT_ID(lineno), \ - INIT_ID(listcomp), \ - INIT_ID(little), \ - INIT_ID(locale), \ - INIT_ID(match), \ - INIT_ID(metaclass), \ - INIT_ID(mode), \ - INIT_ID(modules), \ - INIT_ID(mro), \ - INIT_ID(msg), \ - INIT_ID(n_fields), \ - INIT_ID(n_sequence_fields), \ - INIT_ID(n_unnamed_fields), \ - INIT_ID(name), \ - INIT_ID(newlines), \ - INIT_ID(next), \ - INIT_ID(obj), \ - INIT_ID(offset), \ - INIT_ID(onceregistry), \ - INIT_ID(opcode), \ - INIT_ID(open), \ - INIT_ID(parent), \ - INIT_ID(partial), \ - INIT_ID(path), \ - INIT_ID(peek), \ - INIT_ID(persistent_id), \ - INIT_ID(persistent_load), \ - INIT_ID(print_file_and_line), \ - INIT_ID(ps1), \ - INIT_ID(ps2), \ - INIT_ID(raw), \ - INIT_ID(read), \ - INIT_ID(read1), \ - INIT_ID(readable), \ - INIT_ID(readall), \ - INIT_ID(readinto), \ - INIT_ID(readinto1), \ - INIT_ID(readline), \ - INIT_ID(reducer_override), \ - INIT_ID(reload), \ - INIT_ID(replace), \ - INIT_ID(reset), \ - INIT_ID(return), \ - INIT_ID(reversed), \ - INIT_ID(seek), \ - INIT_ID(seekable), \ - INIT_ID(send), \ - INIT_ID(setcomp), \ - INIT_ID(setstate), \ - INIT_ID(sort), \ - INIT_ID(stderr), \ - INIT_ID(stdin), \ - INIT_ID(stdout), \ - INIT_ID(strict), \ - INIT_ID(symmetric_difference_update), \ - INIT_ID(tell), \ - INIT_ID(text), \ - INIT_ID(threading), \ - INIT_ID(throw), \ - INIT_ID(top), \ - INIT_ID(truncate), \ - INIT_ID(unraisablehook), \ - INIT_ID(values), \ - INIT_ID(version), \ - INIT_ID(warnings), \ - INIT_ID(warnoptions), \ - INIT_ID(writable), \ - INIT_ID(write), \ - INIT_ID(zipimporter), \ - }, \ - .ascii = { \ - _PyASCIIObject_INIT("\x00"), \ - _PyASCIIObject_INIT("\x01"), \ - _PyASCIIObject_INIT("\x02"), \ - _PyASCIIObject_INIT("\x03"), \ - _PyASCIIObject_INIT("\x04"), \ - _PyASCIIObject_INIT("\x05"), \ - _PyASCIIObject_INIT("\x06"), \ - _PyASCIIObject_INIT("\x07"), \ - _PyASCIIObject_INIT("\x08"), \ - _PyASCIIObject_INIT("\x09"), \ - _PyASCIIObject_INIT("\x0a"), \ - _PyASCIIObject_INIT("\x0b"), \ - _PyASCIIObject_INIT("\x0c"), \ - _PyASCIIObject_INIT("\x0d"), \ - _PyASCIIObject_INIT("\x0e"), \ - _PyASCIIObject_INIT("\x0f"), \ - _PyASCIIObject_INIT("\x10"), \ - _PyASCIIObject_INIT("\x11"), \ - _PyASCIIObject_INIT("\x12"), \ - _PyASCIIObject_INIT("\x13"), \ - _PyASCIIObject_INIT("\x14"), \ - _PyASCIIObject_INIT("\x15"), \ - _PyASCIIObject_INIT("\x16"), \ - _PyASCIIObject_INIT("\x17"), \ - _PyASCIIObject_INIT("\x18"), \ - _PyASCIIObject_INIT("\x19"), \ - _PyASCIIObject_INIT("\x1a"), \ - _PyASCIIObject_INIT("\x1b"), \ - _PyASCIIObject_INIT("\x1c"), \ - _PyASCIIObject_INIT("\x1d"), \ - _PyASCIIObject_INIT("\x1e"), \ - _PyASCIIObject_INIT("\x1f"), \ - _PyASCIIObject_INIT("\x20"), \ - _PyASCIIObject_INIT("\x21"), \ - _PyASCIIObject_INIT("\x22"), \ - _PyASCIIObject_INIT("\x23"), \ - _PyASCIIObject_INIT("\x24"), \ - _PyASCIIObject_INIT("\x25"), \ - _PyASCIIObject_INIT("\x26"), \ - _PyASCIIObject_INIT("\x27"), \ - _PyASCIIObject_INIT("\x28"), \ - _PyASCIIObject_INIT("\x29"), \ - _PyASCIIObject_INIT("\x2a"), \ - _PyASCIIObject_INIT("\x2b"), \ - _PyASCIIObject_INIT("\x2c"), \ - _PyASCIIObject_INIT("\x2d"), \ - _PyASCIIObject_INIT("\x2e"), \ - _PyASCIIObject_INIT("\x2f"), \ - _PyASCIIObject_INIT("\x30"), \ - _PyASCIIObject_INIT("\x31"), \ - _PyASCIIObject_INIT("\x32"), \ - _PyASCIIObject_INIT("\x33"), \ - _PyASCIIObject_INIT("\x34"), \ - _PyASCIIObject_INIT("\x35"), \ - _PyASCIIObject_INIT("\x36"), \ - _PyASCIIObject_INIT("\x37"), \ - _PyASCIIObject_INIT("\x38"), \ - _PyASCIIObject_INIT("\x39"), \ - _PyASCIIObject_INIT("\x3a"), \ - _PyASCIIObject_INIT("\x3b"), \ - _PyASCIIObject_INIT("\x3c"), \ - _PyASCIIObject_INIT("\x3d"), \ - _PyASCIIObject_INIT("\x3e"), \ - _PyASCIIObject_INIT("\x3f"), \ - _PyASCIIObject_INIT("\x40"), \ - _PyASCIIObject_INIT("\x41"), \ - _PyASCIIObject_INIT("\x42"), \ - _PyASCIIObject_INIT("\x43"), \ - _PyASCIIObject_INIT("\x44"), \ - _PyASCIIObject_INIT("\x45"), \ - _PyASCIIObject_INIT("\x46"), \ - _PyASCIIObject_INIT("\x47"), \ - _PyASCIIObject_INIT("\x48"), \ - _PyASCIIObject_INIT("\x49"), \ - _PyASCIIObject_INIT("\x4a"), \ - _PyASCIIObject_INIT("\x4b"), \ - _PyASCIIObject_INIT("\x4c"), \ - _PyASCIIObject_INIT("\x4d"), \ - _PyASCIIObject_INIT("\x4e"), \ - _PyASCIIObject_INIT("\x4f"), \ - _PyASCIIObject_INIT("\x50"), \ - _PyASCIIObject_INIT("\x51"), \ - _PyASCIIObject_INIT("\x52"), \ - _PyASCIIObject_INIT("\x53"), \ - _PyASCIIObject_INIT("\x54"), \ - _PyASCIIObject_INIT("\x55"), \ - _PyASCIIObject_INIT("\x56"), \ - _PyASCIIObject_INIT("\x57"), \ - _PyASCIIObject_INIT("\x58"), \ - _PyASCIIObject_INIT("\x59"), \ - _PyASCIIObject_INIT("\x5a"), \ - _PyASCIIObject_INIT("\x5b"), \ - _PyASCIIObject_INIT("\x5c"), \ - _PyASCIIObject_INIT("\x5d"), \ - _PyASCIIObject_INIT("\x5e"), \ - _PyASCIIObject_INIT("\x5f"), \ - _PyASCIIObject_INIT("\x60"), \ - _PyASCIIObject_INIT("\x61"), \ - _PyASCIIObject_INIT("\x62"), \ - _PyASCIIObject_INIT("\x63"), \ - _PyASCIIObject_INIT("\x64"), \ - _PyASCIIObject_INIT("\x65"), \ - _PyASCIIObject_INIT("\x66"), \ - _PyASCIIObject_INIT("\x67"), \ - _PyASCIIObject_INIT("\x68"), \ - _PyASCIIObject_INIT("\x69"), \ - _PyASCIIObject_INIT("\x6a"), \ - _PyASCIIObject_INIT("\x6b"), \ - _PyASCIIObject_INIT("\x6c"), \ - _PyASCIIObject_INIT("\x6d"), \ - _PyASCIIObject_INIT("\x6e"), \ - _PyASCIIObject_INIT("\x6f"), \ - _PyASCIIObject_INIT("\x70"), \ - _PyASCIIObject_INIT("\x71"), \ - _PyASCIIObject_INIT("\x72"), \ - _PyASCIIObject_INIT("\x73"), \ - _PyASCIIObject_INIT("\x74"), \ - _PyASCIIObject_INIT("\x75"), \ - _PyASCIIObject_INIT("\x76"), \ - _PyASCIIObject_INIT("\x77"), \ - _PyASCIIObject_INIT("\x78"), \ - _PyASCIIObject_INIT("\x79"), \ - _PyASCIIObject_INIT("\x7a"), \ - _PyASCIIObject_INIT("\x7b"), \ - _PyASCIIObject_INIT("\x7c"), \ - _PyASCIIObject_INIT("\x7d"), \ - _PyASCIIObject_INIT("\x7e"), \ - _PyASCIIObject_INIT("\x7f"), \ - }, \ - .latin1 = { \ - _PyUnicode_LATIN1_INIT("\x80"), \ - _PyUnicode_LATIN1_INIT("\x81"), \ - _PyUnicode_LATIN1_INIT("\x82"), \ - _PyUnicode_LATIN1_INIT("\x83"), \ - _PyUnicode_LATIN1_INIT("\x84"), \ - _PyUnicode_LATIN1_INIT("\x85"), \ - _PyUnicode_LATIN1_INIT("\x86"), \ - _PyUnicode_LATIN1_INIT("\x87"), \ - _PyUnicode_LATIN1_INIT("\x88"), \ - _PyUnicode_LATIN1_INIT("\x89"), \ - _PyUnicode_LATIN1_INIT("\x8a"), \ - _PyUnicode_LATIN1_INIT("\x8b"), \ - _PyUnicode_LATIN1_INIT("\x8c"), \ - _PyUnicode_LATIN1_INIT("\x8d"), \ - _PyUnicode_LATIN1_INIT("\x8e"), \ - _PyUnicode_LATIN1_INIT("\x8f"), \ - _PyUnicode_LATIN1_INIT("\x90"), \ - _PyUnicode_LATIN1_INIT("\x91"), \ - _PyUnicode_LATIN1_INIT("\x92"), \ - _PyUnicode_LATIN1_INIT("\x93"), \ - _PyUnicode_LATIN1_INIT("\x94"), \ - _PyUnicode_LATIN1_INIT("\x95"), \ - _PyUnicode_LATIN1_INIT("\x96"), \ - _PyUnicode_LATIN1_INIT("\x97"), \ - _PyUnicode_LATIN1_INIT("\x98"), \ - _PyUnicode_LATIN1_INIT("\x99"), \ - _PyUnicode_LATIN1_INIT("\x9a"), \ - _PyUnicode_LATIN1_INIT("\x9b"), \ - _PyUnicode_LATIN1_INIT("\x9c"), \ - _PyUnicode_LATIN1_INIT("\x9d"), \ - _PyUnicode_LATIN1_INIT("\x9e"), \ - _PyUnicode_LATIN1_INIT("\x9f"), \ - _PyUnicode_LATIN1_INIT("\xa0"), \ - _PyUnicode_LATIN1_INIT("\xa1"), \ - _PyUnicode_LATIN1_INIT("\xa2"), \ - _PyUnicode_LATIN1_INIT("\xa3"), \ - _PyUnicode_LATIN1_INIT("\xa4"), \ - _PyUnicode_LATIN1_INIT("\xa5"), \ - _PyUnicode_LATIN1_INIT("\xa6"), \ - _PyUnicode_LATIN1_INIT("\xa7"), \ - _PyUnicode_LATIN1_INIT("\xa8"), \ - _PyUnicode_LATIN1_INIT("\xa9"), \ - _PyUnicode_LATIN1_INIT("\xaa"), \ - _PyUnicode_LATIN1_INIT("\xab"), \ - _PyUnicode_LATIN1_INIT("\xac"), \ - _PyUnicode_LATIN1_INIT("\xad"), \ - _PyUnicode_LATIN1_INIT("\xae"), \ - _PyUnicode_LATIN1_INIT("\xaf"), \ - _PyUnicode_LATIN1_INIT("\xb0"), \ - _PyUnicode_LATIN1_INIT("\xb1"), \ - _PyUnicode_LATIN1_INIT("\xb2"), \ - _PyUnicode_LATIN1_INIT("\xb3"), \ - _PyUnicode_LATIN1_INIT("\xb4"), \ - _PyUnicode_LATIN1_INIT("\xb5"), \ - _PyUnicode_LATIN1_INIT("\xb6"), \ - _PyUnicode_LATIN1_INIT("\xb7"), \ - _PyUnicode_LATIN1_INIT("\xb8"), \ - _PyUnicode_LATIN1_INIT("\xb9"), \ - _PyUnicode_LATIN1_INIT("\xba"), \ - _PyUnicode_LATIN1_INIT("\xbb"), \ - _PyUnicode_LATIN1_INIT("\xbc"), \ - _PyUnicode_LATIN1_INIT("\xbd"), \ - _PyUnicode_LATIN1_INIT("\xbe"), \ - _PyUnicode_LATIN1_INIT("\xbf"), \ - _PyUnicode_LATIN1_INIT("\xc0"), \ - _PyUnicode_LATIN1_INIT("\xc1"), \ - _PyUnicode_LATIN1_INIT("\xc2"), \ - _PyUnicode_LATIN1_INIT("\xc3"), \ - _PyUnicode_LATIN1_INIT("\xc4"), \ - _PyUnicode_LATIN1_INIT("\xc5"), \ - _PyUnicode_LATIN1_INIT("\xc6"), \ - _PyUnicode_LATIN1_INIT("\xc7"), \ - _PyUnicode_LATIN1_INIT("\xc8"), \ - _PyUnicode_LATIN1_INIT("\xc9"), \ - _PyUnicode_LATIN1_INIT("\xca"), \ - _PyUnicode_LATIN1_INIT("\xcb"), \ - _PyUnicode_LATIN1_INIT("\xcc"), \ - _PyUnicode_LATIN1_INIT("\xcd"), \ - _PyUnicode_LATIN1_INIT("\xce"), \ - _PyUnicode_LATIN1_INIT("\xcf"), \ - _PyUnicode_LATIN1_INIT("\xd0"), \ - _PyUnicode_LATIN1_INIT("\xd1"), \ - _PyUnicode_LATIN1_INIT("\xd2"), \ - _PyUnicode_LATIN1_INIT("\xd3"), \ - _PyUnicode_LATIN1_INIT("\xd4"), \ - _PyUnicode_LATIN1_INIT("\xd5"), \ - _PyUnicode_LATIN1_INIT("\xd6"), \ - _PyUnicode_LATIN1_INIT("\xd7"), \ - _PyUnicode_LATIN1_INIT("\xd8"), \ - _PyUnicode_LATIN1_INIT("\xd9"), \ - _PyUnicode_LATIN1_INIT("\xda"), \ - _PyUnicode_LATIN1_INIT("\xdb"), \ - _PyUnicode_LATIN1_INIT("\xdc"), \ - _PyUnicode_LATIN1_INIT("\xdd"), \ - _PyUnicode_LATIN1_INIT("\xde"), \ - _PyUnicode_LATIN1_INIT("\xdf"), \ - _PyUnicode_LATIN1_INIT("\xe0"), \ - _PyUnicode_LATIN1_INIT("\xe1"), \ - _PyUnicode_LATIN1_INIT("\xe2"), \ - _PyUnicode_LATIN1_INIT("\xe3"), \ - _PyUnicode_LATIN1_INIT("\xe4"), \ - _PyUnicode_LATIN1_INIT("\xe5"), \ - _PyUnicode_LATIN1_INIT("\xe6"), \ - _PyUnicode_LATIN1_INIT("\xe7"), \ - _PyUnicode_LATIN1_INIT("\xe8"), \ - _PyUnicode_LATIN1_INIT("\xe9"), \ - _PyUnicode_LATIN1_INIT("\xea"), \ - _PyUnicode_LATIN1_INIT("\xeb"), \ - _PyUnicode_LATIN1_INIT("\xec"), \ - _PyUnicode_LATIN1_INIT("\xed"), \ - _PyUnicode_LATIN1_INIT("\xee"), \ - _PyUnicode_LATIN1_INIT("\xef"), \ - _PyUnicode_LATIN1_INIT("\xf0"), \ - _PyUnicode_LATIN1_INIT("\xf1"), \ - _PyUnicode_LATIN1_INIT("\xf2"), \ - _PyUnicode_LATIN1_INIT("\xf3"), \ - _PyUnicode_LATIN1_INIT("\xf4"), \ - _PyUnicode_LATIN1_INIT("\xf5"), \ - _PyUnicode_LATIN1_INIT("\xf6"), \ - _PyUnicode_LATIN1_INIT("\xf7"), \ - _PyUnicode_LATIN1_INIT("\xf8"), \ - _PyUnicode_LATIN1_INIT("\xf9"), \ - _PyUnicode_LATIN1_INIT("\xfa"), \ - _PyUnicode_LATIN1_INIT("\xfb"), \ - _PyUnicode_LATIN1_INIT("\xfc"), \ - _PyUnicode_LATIN1_INIT("\xfd"), \ - _PyUnicode_LATIN1_INIT("\xfe"), \ - _PyUnicode_LATIN1_INIT("\xff"), \ - }, \ - }, \ - \ - .tuple_empty = { \ - .ob_base = _PyVarObject_IMMORTAL_INIT(&PyTuple_Type, 0) \ - }, \ - }, \ -} -/* End auto-generated code */ - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_RUNTIME_INIT_H */ diff --git a/python/include/internal/pycore_signal.h b/python/include/internal/pycore_signal.h deleted file mode 100644 index 2f1f778..0000000 --- a/python/include/internal/pycore_signal.h +++ /dev/null @@ -1,35 +0,0 @@ -// Define Py_NSIG constant for signal handling. - -#ifndef Py_INTERNAL_SIGNAL_H -#define Py_INTERNAL_SIGNAL_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include // NSIG - -#ifdef _SIG_MAXSIG - // gh-91145: On FreeBSD, defines NSIG as 32: it doesn't include - // realtime signals: [SIGRTMIN,SIGRTMAX]. Use _SIG_MAXSIG instead. For - // example on x86-64 FreeBSD 13, SIGRTMAX is 126 and _SIG_MAXSIG is 128. -# define Py_NSIG _SIG_MAXSIG -#elif defined(NSIG) -# define Py_NSIG NSIG -#elif defined(_NSIG) -# define Py_NSIG _NSIG // BSD/SysV -#elif defined(_SIGMAX) -# define Py_NSIG (_SIGMAX + 1) // QNX -#elif defined(SIGMAX) -# define Py_NSIG (SIGMAX + 1) // djgpp -#else -# define Py_NSIG 64 // Use a reasonable default value -#endif - -#ifdef __cplusplus -} -#endif -#endif // !Py_INTERNAL_SIGNAL_H diff --git a/python/include/internal/pycore_sliceobject.h b/python/include/internal/pycore_sliceobject.h deleted file mode 100644 index b943594..0000000 --- a/python/include/internal/pycore_sliceobject.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef Py_INTERNAL_SLICEOBJECT_H -#define Py_INTERNAL_SLICEOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - - -/* runtime lifecycle */ - -extern void _PySlice_Fini(PyInterpreterState *); - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_SLICEOBJECT_H */ diff --git a/python/include/internal/pycore_strhex.h b/python/include/internal/pycore_strhex.h deleted file mode 100644 index 053e84d..0000000 --- a/python/include/internal/pycore_strhex.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef Py_INTERNAL_STRHEX_H -#define Py_INTERNAL_STRHEX_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -// Returns a str() containing the hex representation of argbuf. -PyAPI_FUNC(PyObject*) _Py_strhex(const - char* argbuf, - const Py_ssize_t arglen); - -// Returns a bytes() containing the ASCII hex representation of argbuf. -PyAPI_FUNC(PyObject*) _Py_strhex_bytes( - const char* argbuf, - const Py_ssize_t arglen); - -// These variants include support for a separator between every N bytes: -PyAPI_FUNC(PyObject*) _Py_strhex_with_sep( - const char* argbuf, - const Py_ssize_t arglen, - PyObject* sep, - const int bytes_per_group); -PyAPI_FUNC(PyObject*) _Py_strhex_bytes_with_sep( - const char* argbuf, - const Py_ssize_t arglen, - PyObject* sep, - const int bytes_per_group); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_STRHEX_H */ diff --git a/python/include/internal/pycore_structseq.h b/python/include/internal/pycore_structseq.h deleted file mode 100644 index 9c1f38e..0000000 --- a/python/include/internal/pycore_structseq.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef Py_INTERNAL_STRUCTSEQ_H -#define Py_INTERNAL_STRUCTSEQ_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - - -/* other API */ - -PyAPI_FUNC(PyTypeObject *) _PyStructSequence_NewType( - PyStructSequence_Desc *desc, - unsigned long tp_flags); - -PyAPI_FUNC(int) _PyStructSequence_InitType( - PyTypeObject *type, - PyStructSequence_Desc *desc, - unsigned long tp_flags); - -extern void _PyStructSequence_FiniType(PyTypeObject *type); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_STRUCTSEQ_H */ diff --git a/python/include/internal/pycore_symtable.h b/python/include/internal/pycore_symtable.h deleted file mode 100644 index 0fd6ce1..0000000 --- a/python/include/internal/pycore_symtable.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef Py_INTERNAL_SYMTABLE_H -#define Py_INTERNAL_SYMTABLE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -struct _mod; // Type defined in pycore_ast.h - -typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock, AnnotationBlock } - _Py_block_ty; - -typedef enum _comprehension_type { - NoComprehension = 0, - ListComprehension = 1, - DictComprehension = 2, - SetComprehension = 3, - GeneratorExpression = 4 } _Py_comprehension_ty; - -struct _symtable_entry; - -struct symtable { - PyObject *st_filename; /* name of file being compiled, - decoded from the filesystem encoding */ - struct _symtable_entry *st_cur; /* current symbol table entry */ - struct _symtable_entry *st_top; /* symbol table entry for module */ - PyObject *st_blocks; /* dict: map AST node addresses - * to symbol table entries */ - PyObject *st_stack; /* list: stack of namespace info */ - PyObject *st_global; /* borrowed ref to st_top->ste_symbols */ - int st_nblocks; /* number of blocks used. kept for - consistency with the corresponding - compiler structure */ - PyObject *st_private; /* name of current class or NULL */ - PyFutureFeatures *st_future; /* module's future features that affect - the symbol table */ - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ -}; - -typedef struct _symtable_entry { - PyObject_HEAD - PyObject *ste_id; /* int: key in ste_table->st_blocks */ - PyObject *ste_symbols; /* dict: variable names to flags */ - PyObject *ste_name; /* string: name of current block */ - PyObject *ste_varnames; /* list of function parameters */ - PyObject *ste_children; /* list of child blocks */ - PyObject *ste_directives;/* locations of global and nonlocal statements */ - _Py_block_ty ste_type; /* module, class or function */ - int ste_nested; /* true if block is nested */ - unsigned ste_free : 1; /* true if block has free variables */ - unsigned ste_child_free : 1; /* true if a child block has free vars, - including free refs to globals */ - unsigned ste_generator : 1; /* true if namespace is a generator */ - unsigned ste_coroutine : 1; /* true if namespace is a coroutine */ - _Py_comprehension_ty ste_comprehension; /* Kind of comprehension (if any) */ - unsigned ste_varargs : 1; /* true if block has varargs */ - unsigned ste_varkeywords : 1; /* true if block has varkeywords */ - unsigned ste_returns_value : 1; /* true if namespace uses return with - an argument */ - unsigned ste_needs_class_closure : 1; /* for class scopes, true if a - closure over __class__ - should be created */ - unsigned ste_comp_iter_target : 1; /* true if visiting comprehension target */ - int ste_comp_iter_expr; /* non-zero if visiting a comprehension range expression */ - int ste_lineno; /* first line of block */ - int ste_col_offset; /* offset of first line of block */ - int ste_end_lineno; /* end line of block */ - int ste_end_col_offset; /* end offset of first line of block */ - int ste_opt_lineno; /* lineno of last exec or import * */ - int ste_opt_col_offset; /* offset of last exec or import * */ - struct symtable *ste_table; -} PySTEntryObject; - -extern PyTypeObject PySTEntry_Type; - -#define PySTEntry_Check(op) Py_IS_TYPE(op, &PySTEntry_Type) - -extern long _PyST_GetSymbol(PySTEntryObject *, PyObject *); -extern int _PyST_GetScope(PySTEntryObject *, PyObject *); - -extern struct symtable* _PySymtable_Build( - struct _mod *mod, - PyObject *filename, - PyFutureFeatures *future); -PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *); - -extern void _PySymtable_Free(struct symtable *); - -/* Flags for def-use information */ - -#define DEF_GLOBAL 1 /* global stmt */ -#define DEF_LOCAL 2 /* assignment in code block */ -#define DEF_PARAM 2<<1 /* formal parameter */ -#define DEF_NONLOCAL 2<<2 /* nonlocal stmt */ -#define USE 2<<3 /* name is used */ -#define DEF_FREE 2<<4 /* name used but not defined in nested block */ -#define DEF_FREE_CLASS 2<<5 /* free variable from class's method */ -#define DEF_IMPORT 2<<6 /* assignment occurred via import */ -#define DEF_ANNOT 2<<7 /* this name is annotated */ -#define DEF_COMP_ITER 2<<8 /* this name is a comprehension iteration variable */ - -#define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT) - -/* GLOBAL_EXPLICIT and GLOBAL_IMPLICIT are used internally by the symbol - table. GLOBAL is returned from PyST_GetScope() for either of them. - It is stored in ste_symbols at bits 12-15. -*/ -#define SCOPE_OFFSET 11 -#define SCOPE_MASK (DEF_GLOBAL | DEF_LOCAL | DEF_PARAM | DEF_NONLOCAL) - -#define LOCAL 1 -#define GLOBAL_EXPLICIT 2 -#define GLOBAL_IMPLICIT 3 -#define FREE 4 -#define CELL 5 - -#define GENERATOR 1 -#define GENERATOR_EXPRESSION 2 - -// Used by symtablemodule.c -extern struct symtable* _Py_SymtableStringObjectFlags( - const char *str, - PyObject *filename, - int start, - PyCompilerFlags *flags); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_SYMTABLE_H */ diff --git a/python/include/internal/pycore_sysmodule.h b/python/include/internal/pycore_sysmodule.h deleted file mode 100644 index 282e863..0000000 --- a/python/include/internal/pycore_sysmodule.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef Py_INTERNAL_SYSMODULE_H -#define Py_INTERNAL_SYSMODULE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -PyAPI_FUNC(int) _PySys_Audit( - PyThreadState *tstate, - const char *event, - const char *argFormat, - ...); - -/* We want minimal exposure of this function, so use extern rather than - PyAPI_FUNC() to not export the symbol. */ -extern void _PySys_ClearAuditHooks(PyThreadState *tstate); - -PyAPI_FUNC(int) _PySys_SetAttr(PyObject *, PyObject *); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_SYSMODULE_H */ diff --git a/python/include/internal/pycore_traceback.h b/python/include/internal/pycore_traceback.h deleted file mode 100644 index 2312642..0000000 --- a/python/include/internal/pycore_traceback.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef Py_INTERNAL_TRACEBACK_H -#define Py_INTERNAL_TRACEBACK_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -/* Write the Python traceback into the file 'fd'. For example: - - Traceback (most recent call first): - File "xxx", line xxx in - File "xxx", line xxx in - ... - File "xxx", line xxx in - - This function is written for debug purpose only, to dump the traceback in - the worst case: after a segmentation fault, at fatal error, etc. That's why, - it is very limited. Strings are truncated to 100 characters and encoded to - ASCII with backslashreplace. It doesn't write the source code, only the - function name, filename and line number of each frame. Write only the first - 100 frames: if the traceback is truncated, write the line " ...". - - This function is signal safe. */ - -PyAPI_FUNC(void) _Py_DumpTraceback( - int fd, - PyThreadState *tstate); - -/* Write the traceback of all threads into the file 'fd'. current_thread can be - NULL. - - Return NULL on success, or an error message on error. - - This function is written for debug purpose only. It calls - _Py_DumpTraceback() for each thread, and so has the same limitations. It - only write the traceback of the first 100 threads: write "..." if there are - more threads. - - If current_tstate is NULL, the function tries to get the Python thread state - of the current thread. It is not an error if the function is unable to get - the current Python thread state. - - If interp is NULL, the function tries to get the interpreter state from - the current Python thread state, or from - _PyGILState_GetInterpreterStateUnsafe() in last resort. - - It is better to pass NULL to interp and current_tstate, the function tries - different options to retrieve this information. - - This function is signal safe. */ - -PyAPI_FUNC(const char*) _Py_DumpTracebackThreads( - int fd, - PyInterpreterState *interp, - PyThreadState *current_tstate); - -/* Write a Unicode object into the file descriptor fd. Encode the string to - ASCII using the backslashreplace error handler. - - Do nothing if text is not a Unicode object. The function accepts Unicode - string which is not ready (PyUnicode_WCHAR_KIND). - - This function is signal safe. */ -PyAPI_FUNC(void) _Py_DumpASCII(int fd, PyObject *text); - -/* Format an integer as decimal into the file descriptor fd. - - This function is signal safe. */ -PyAPI_FUNC(void) _Py_DumpDecimal( - int fd, - size_t value); - -/* Format an integer as hexadecimal with width digits into fd file descriptor. - The function is signal safe. */ -PyAPI_FUNC(void) _Py_DumpHexadecimal( - int fd, - uintptr_t value, - Py_ssize_t width); - -PyAPI_FUNC(PyObject*) _PyTraceBack_FromFrame( - PyObject *tb_next, - PyFrameObject *frame); - -#define EXCEPTION_TB_HEADER "Traceback (most recent call last):\n" -#define EXCEPTION_GROUP_TB_HEADER "Exception Group Traceback (most recent call last):\n" - -/* Write the traceback tb to file f. Prefix each line with - indent spaces followed by the margin (if it is not NULL). */ -PyAPI_FUNC(int) _PyTraceBack_Print_Indented( - PyObject *tb, int indent, const char* margin, - const char *header_margin, const char *header, PyObject *f); -PyAPI_FUNC(int) _Py_WriteIndentedMargin(int, const char*, PyObject *); -PyAPI_FUNC(int) _Py_WriteIndent(int, PyObject *); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_TRACEBACK_H */ diff --git a/python/include/internal/pycore_tuple.h b/python/include/internal/pycore_tuple.h deleted file mode 100644 index 3e4a7f1..0000000 --- a/python/include/internal/pycore_tuple.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef Py_INTERNAL_TUPLE_H -#define Py_INTERNAL_TUPLE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "tupleobject.h" /* _PyTuple_CAST() */ - - -/* runtime lifecycle */ - -extern PyStatus _PyTuple_InitGlobalObjects(PyInterpreterState *); -extern PyStatus _PyTuple_InitTypes(PyInterpreterState *); -extern void _PyTuple_Fini(PyInterpreterState *); - - -/* other API */ - -// PyTuple_MAXSAVESIZE - largest tuple to save on free list -// PyTuple_MAXFREELIST - maximum number of tuples of each size to save - -#if defined(PyTuple_MAXSAVESIZE) && PyTuple_MAXSAVESIZE <= 0 - // A build indicated that tuple freelists should not be used. -# define PyTuple_NFREELISTS 0 -# undef PyTuple_MAXSAVESIZE -# undef PyTuple_MAXFREELIST - -#elif !defined(WITH_FREELISTS) -# define PyTuple_NFREELISTS 0 -# undef PyTuple_MAXSAVESIZE -# undef PyTuple_MAXFREELIST - -#else - // We are using a freelist for tuples. -# ifndef PyTuple_MAXSAVESIZE -# define PyTuple_MAXSAVESIZE 20 -# endif -# define PyTuple_NFREELISTS PyTuple_MAXSAVESIZE -# ifndef PyTuple_MAXFREELIST -# define PyTuple_MAXFREELIST 2000 -# endif -#endif - -struct _Py_tuple_state { -#if PyTuple_NFREELISTS > 0 - /* There is one freelist for each size from 1 to PyTuple_MAXSAVESIZE. - The empty tuple is handled separately. - - Each tuple stored in the array is the head of the linked list - (and the next available tuple) for that size. The actual tuple - object is used as the linked list node, with its first item - (ob_item[0]) pointing to the next node (i.e. the previous head). - Each linked list is initially NULL. */ - PyTupleObject *free_list[PyTuple_NFREELISTS]; - int numfree[PyTuple_NFREELISTS]; -#else - char _unused; // Empty structs are not allowed. -#endif -}; - -#define _PyTuple_ITEMS(op) (_PyTuple_CAST(op)->ob_item) - -extern PyObject *_PyTuple_FromArray(PyObject *const *, Py_ssize_t); -extern PyObject *_PyTuple_FromArraySteal(PyObject *const *, Py_ssize_t); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_TUPLE_H */ diff --git a/python/include/internal/pycore_typeobject.h b/python/include/internal/pycore_typeobject.h deleted file mode 100644 index 6bfe176..0000000 --- a/python/include/internal/pycore_typeobject.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef Py_INTERNAL_TYPEOBJECT_H -#define Py_INTERNAL_TYPEOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - - -/* runtime lifecycle */ - -extern PyStatus _PyTypes_InitState(PyInterpreterState *); -extern PyStatus _PyTypes_InitTypes(PyInterpreterState *); -extern void _PyTypes_FiniTypes(PyInterpreterState *); -extern void _PyTypes_Fini(PyInterpreterState *); - - -/* other API */ - -// Type attribute lookup cache: speed up attribute and method lookups, -// see _PyType_Lookup(). -struct type_cache_entry { - unsigned int version; // initialized from type->tp_version_tag - PyObject *name; // reference to exactly a str or None - PyObject *value; // borrowed reference or NULL -}; - -#define MCACHE_SIZE_EXP 12 -#define MCACHE_STATS 0 - -struct type_cache { - struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP]; -#if MCACHE_STATS - size_t hits; - size_t misses; - size_t collisions; -#endif -}; - -extern PyStatus _PyTypes_InitSlotDefs(void); - -extern void _PyStaticType_Dealloc(PyTypeObject *type); - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_TYPEOBJECT_H */ diff --git a/python/include/internal/pycore_ucnhash.h b/python/include/internal/pycore_ucnhash.h deleted file mode 100644 index c7b559f..0000000 --- a/python/include/internal/pycore_ucnhash.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Unicode name database interface */ -#ifndef Py_INTERNAL_UCNHASH_H -#define Py_INTERNAL_UCNHASH_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -/* revised ucnhash CAPI interface (exported through a "wrapper") */ - -#define PyUnicodeData_CAPSULE_NAME "unicodedata._ucnhash_CAPI" - -typedef struct { - - /* Get name for a given character code. - Returns non-zero if success, zero if not. - Does not set Python exceptions. */ - int (*getname)(Py_UCS4 code, char* buffer, int buflen, - int with_alias_and_seq); - - /* Get character code for a given name. - Same error handling as for getname(). */ - int (*getcode)(const char* name, int namelen, Py_UCS4* code, - int with_named_seq); - -} _PyUnicode_Name_CAPI; - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_UCNHASH_H */ diff --git a/python/include/internal/pycore_unicodeobject.h b/python/include/internal/pycore_unicodeobject.h deleted file mode 100644 index 4a64c9d..0000000 --- a/python/include/internal/pycore_unicodeobject.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef Py_INTERNAL_UNICODEOBJECT_H -#define Py_INTERNAL_UNICODEOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_fileutils.h" // _Py_error_handler - -void _PyUnicode_ExactDealloc(PyObject *op); - -/* runtime lifecycle */ - -extern void _PyUnicode_InitState(PyInterpreterState *); -extern PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *); -extern PyStatus _PyUnicode_InitTypes(PyInterpreterState *); -extern void _PyUnicode_Fini(PyInterpreterState *); -extern void _PyUnicode_FiniTypes(PyInterpreterState *); -extern void _PyStaticUnicode_Dealloc(PyObject *); - -extern PyTypeObject _PyUnicodeASCIIIter_Type; - -/* other API */ - -struct _Py_unicode_runtime_ids { - PyThread_type_lock lock; - // next_index value must be preserved when Py_Initialize()/Py_Finalize() - // is called multiple times: see _PyUnicode_FromId() implementation. - Py_ssize_t next_index; -}; - -/* fs_codec.encoding is initialized to NULL. - Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */ -struct _Py_unicode_fs_codec { - char *encoding; // Filesystem encoding (encoded to UTF-8) - int utf8; // encoding=="utf-8"? - char *errors; // Filesystem errors (encoded to UTF-8) - _Py_error_handler error_handler; -}; - -struct _Py_unicode_ids { - Py_ssize_t size; - PyObject **array; -}; - -struct _Py_unicode_state { - struct _Py_unicode_fs_codec fs_codec; - - // Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId() - struct _Py_unicode_ids ids; -}; - -extern void _PyUnicode_ClearInterned(PyInterpreterState *interp); - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_UNICODEOBJECT_H */ diff --git a/python/include/internal/pycore_unionobject.h b/python/include/internal/pycore_unionobject.h deleted file mode 100644 index 4908b0d..0000000 --- a/python/include/internal/pycore_unionobject.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef Py_INTERNAL_UNIONOBJECT_H -#define Py_INTERNAL_UNIONOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -extern PyTypeObject _PyUnion_Type; -#define _PyUnion_Check(op) Py_IS_TYPE(op, &_PyUnion_Type) -extern PyObject *_Py_union_type_or(PyObject *, PyObject *); - -#define _PyGenericAlias_Check(op) PyObject_TypeCheck(op, &Py_GenericAliasType) -extern PyObject *_Py_subs_parameters(PyObject *, PyObject *, PyObject *, PyObject *); -extern PyObject *_Py_make_parameters(PyObject *); -extern PyObject *_Py_union_args(PyObject *self); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_UNIONOBJECT_H */ diff --git a/python/include/internal/pycore_warnings.h b/python/include/internal/pycore_warnings.h deleted file mode 100644 index adaaf80..0000000 --- a/python/include/internal/pycore_warnings.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef Py_INTERNAL_WARNINGS_H -#define Py_INTERNAL_WARNINGS_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -struct _warnings_runtime_state { - /* Both 'filters' and 'onceregistry' can be set in warnings.py; - get_warnings_attr() will reset these variables accordingly. */ - PyObject *filters; /* List */ - PyObject *once_registry; /* Dict */ - PyObject *default_action; /* String */ - long filters_version; -}; - -extern int _PyWarnings_InitState(PyInterpreterState *interp); - -PyAPI_FUNC(PyObject*) _PyWarnings_Init(void); - -extern void _PyErr_WarnUnawaitedCoroutine(PyObject *coro); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_WARNINGS_H */ diff --git a/python/include/intrcheck.h b/python/include/intrcheck.h deleted file mode 100644 index 8659787..0000000 --- a/python/include/intrcheck.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef Py_INTRCHECK_H -#define Py_INTRCHECK_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_FUNC(int) PyOS_InterruptOccurred(void); -#ifdef HAVE_FORK -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 -PyAPI_FUNC(void) PyOS_BeforeFork(void); -PyAPI_FUNC(void) PyOS_AfterFork_Parent(void); -PyAPI_FUNC(void) PyOS_AfterFork_Child(void); -#endif -#endif -/* Deprecated, please use PyOS_AfterFork_Child() instead */ -Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyOS_AfterFork(void); - -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PyOS_IsMainThread(void); - -#ifdef MS_WINDOWS -/* windows.h is not included by Python.h so use void* instead of HANDLE */ -PyAPI_FUNC(void*) _PyOS_SigintEvent(void); -#endif -#endif /* !Py_LIMITED_API */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTRCHECK_H */ diff --git a/python/include/iterobject.h b/python/include/iterobject.h deleted file mode 100644 index 38ce0ac..0000000 --- a/python/include/iterobject.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef Py_ITEROBJECT_H -#define Py_ITEROBJECT_H -/* Iterators (the basic kind, over a sequence) */ -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_DATA(PyTypeObject) PySeqIter_Type; -PyAPI_DATA(PyTypeObject) PyCallIter_Type; -#ifdef Py_BUILD_CORE -extern PyTypeObject _PyAnextAwaitable_Type; -#endif - -#define PySeqIter_Check(op) Py_IS_TYPE(op, &PySeqIter_Type) - -PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *); - - -#define PyCallIter_Check(op) Py_IS_TYPE(op, &PyCallIter_Type) - -PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_ITEROBJECT_H */ - diff --git a/python/include/listobject.h b/python/include/listobject.h deleted file mode 100644 index 6cfdb80..0000000 --- a/python/include/listobject.h +++ /dev/null @@ -1,52 +0,0 @@ -/* List object interface - - Another generally useful object type is a list of object pointers. - This is a mutable type: the list items can be changed, and items can be - added or removed. Out-of-range indices or non-list objects are ignored. - - WARNING: PyList_SetItem does not increment the new item's reference count, - but does decrement the reference count of the item it replaces, if not nil. - It does *decrement* the reference count if it is *not* inserted in the list. - Similarly, PyList_GetItem does not increment the returned item's reference - count. -*/ - -#ifndef Py_LISTOBJECT_H -#define Py_LISTOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_DATA(PyTypeObject) PyList_Type; -PyAPI_DATA(PyTypeObject) PyListIter_Type; -PyAPI_DATA(PyTypeObject) PyListRevIter_Type; - -#define PyList_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) -#define PyList_CheckExact(op) Py_IS_TYPE(op, &PyList_Type) - -PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); -PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *); - -PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t); -PyAPI_FUNC(int) PyList_SetItem(PyObject *, Py_ssize_t, PyObject *); -PyAPI_FUNC(int) PyList_Insert(PyObject *, Py_ssize_t, PyObject *); -PyAPI_FUNC(int) PyList_Append(PyObject *, PyObject *); - -PyAPI_FUNC(PyObject *) PyList_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); -PyAPI_FUNC(int) PyList_SetSlice(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); - -PyAPI_FUNC(int) PyList_Sort(PyObject *); -PyAPI_FUNC(int) PyList_Reverse(PyObject *); -PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_LISTOBJECT_H -# include "cpython/listobject.h" -# undef Py_CPYTHON_LISTOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_LISTOBJECT_H */ diff --git a/python/include/longobject.h b/python/include/longobject.h deleted file mode 100644 index 0748a95..0000000 --- a/python/include/longobject.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef Py_LONGOBJECT_H -#define Py_LONGOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* Long (arbitrary precision) integer object interface */ - -PyAPI_DATA(PyTypeObject) PyLong_Type; - -#define PyLong_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) -#define PyLong_CheckExact(op) Py_IS_TYPE(op, &PyLong_Type) - -PyAPI_FUNC(PyObject *) PyLong_FromLong(long); -PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); -PyAPI_FUNC(PyObject *) PyLong_FromSize_t(size_t); -PyAPI_FUNC(PyObject *) PyLong_FromSsize_t(Py_ssize_t); -PyAPI_FUNC(PyObject *) PyLong_FromDouble(double); -PyAPI_FUNC(long) PyLong_AsLong(PyObject *); -PyAPI_FUNC(long) PyLong_AsLongAndOverflow(PyObject *, int *); -PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t(PyObject *); -PyAPI_FUNC(size_t) PyLong_AsSize_t(PyObject *); -PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); -PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); -PyAPI_FUNC(PyObject *) PyLong_GetInfo(void); - -/* It may be useful in the future. I've added it in the PyInt -> PyLong - cleanup to keep the extra information. [CH] */ -#define PyLong_AS_LONG(op) PyLong_AsLong(op) - -/* Issue #1983: pid_t can be longer than a C long on some systems */ -#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT -#define _Py_PARSE_PID "i" -#define PyLong_FromPid PyLong_FromLong -#define PyLong_AsPid PyLong_AsLong -#elif SIZEOF_PID_T == SIZEOF_LONG -#define _Py_PARSE_PID "l" -#define PyLong_FromPid PyLong_FromLong -#define PyLong_AsPid PyLong_AsLong -#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG -#define _Py_PARSE_PID "L" -#define PyLong_FromPid PyLong_FromLongLong -#define PyLong_AsPid PyLong_AsLongLong -#else -#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)" -#endif /* SIZEOF_PID_T */ - -#if SIZEOF_VOID_P == SIZEOF_INT -# define _Py_PARSE_INTPTR "i" -# define _Py_PARSE_UINTPTR "I" -#elif SIZEOF_VOID_P == SIZEOF_LONG -# define _Py_PARSE_INTPTR "l" -# define _Py_PARSE_UINTPTR "k" -#elif defined(SIZEOF_LONG_LONG) && SIZEOF_VOID_P == SIZEOF_LONG_LONG -# define _Py_PARSE_INTPTR "L" -# define _Py_PARSE_UINTPTR "K" -#else -# error "void* different in size from int, long and long long" -#endif /* SIZEOF_VOID_P */ - -PyAPI_FUNC(double) PyLong_AsDouble(PyObject *); -PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *); -PyAPI_FUNC(void *) PyLong_AsVoidPtr(PyObject *); - -PyAPI_FUNC(PyObject *) PyLong_FromLongLong(long long); -PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLongLong(unsigned long long); -PyAPI_FUNC(long long) PyLong_AsLongLong(PyObject *); -PyAPI_FUNC(unsigned long long) PyLong_AsUnsignedLongLong(PyObject *); -PyAPI_FUNC(unsigned long long) PyLong_AsUnsignedLongLongMask(PyObject *); -PyAPI_FUNC(long long) PyLong_AsLongLongAndOverflow(PyObject *, int *); - -PyAPI_FUNC(PyObject *) PyLong_FromString(const char *, char **, int); - -/* These aren't really part of the int object, but they're handy. The - functions are in Python/mystrtoul.c. - */ -PyAPI_FUNC(unsigned long) PyOS_strtoul(const char *, char **, int); -PyAPI_FUNC(long) PyOS_strtol(const char *, char **, int); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_LONGOBJECT_H -# include "cpython/longobject.h" -# undef Py_CPYTHON_LONGOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_LONGOBJECT_H */ diff --git a/python/include/marshal.h b/python/include/marshal.h deleted file mode 100644 index 9f4961a..0000000 --- a/python/include/marshal.h +++ /dev/null @@ -1,31 +0,0 @@ - -/* Interface for marshal.c */ - -#ifndef Py_MARSHAL_H -#define Py_MARSHAL_H -#ifndef Py_LIMITED_API - -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(const char *, - Py_ssize_t); -PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *, int); - -#define Py_MARSHAL_VERSION 4 - -PyAPI_FUNC(long) PyMarshal_ReadLongFromFile(FILE *); -PyAPI_FUNC(int) PyMarshal_ReadShortFromFile(FILE *); -PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromFile(FILE *); -PyAPI_FUNC(PyObject *) PyMarshal_ReadLastObjectFromFile(FILE *); - -PyAPI_FUNC(void) PyMarshal_WriteLongToFile(long, FILE *, int); -PyAPI_FUNC(void) PyMarshal_WriteObjectToFile(PyObject *, FILE *, int); - -#ifdef __cplusplus -} -#endif - -#endif /* Py_LIMITED_API */ -#endif /* !Py_MARSHAL_H */ diff --git a/python/include/memoryobject.h b/python/include/memoryobject.h deleted file mode 100644 index 16129f4..0000000 --- a/python/include/memoryobject.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Memory view object. In Python this is available as "memoryview". */ - -#ifndef Py_MEMORYOBJECT_H -#define Py_MEMORYOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_LIMITED_API -PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type; -#endif -PyAPI_DATA(PyTypeObject) PyMemoryView_Type; - -#define PyMemoryView_Check(op) Py_IS_TYPE(op, &PyMemoryView_Type) - -#ifndef Py_LIMITED_API -/* Get a pointer to the memoryview's private copy of the exporter's buffer. */ -#define PyMemoryView_GET_BUFFER(op) (&((PyMemoryViewObject *)(op))->view) -/* Get a pointer to the exporting object (this may be NULL!). */ -#define PyMemoryView_GET_BASE(op) (((PyMemoryViewObject *)(op))->view.obj) -#endif - -PyAPI_FUNC(PyObject *) PyMemoryView_FromObject(PyObject *base); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject *) PyMemoryView_FromMemory(char *mem, Py_ssize_t size, - int flags); -#endif -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030b0000 -PyAPI_FUNC(PyObject *) PyMemoryView_FromBuffer(const Py_buffer *info); -#endif -PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base, - int buffertype, - char order); - - -/* The structs are declared here so that macros can work, but they shouldn't - be considered public. Don't access their fields directly, use the macros - and functions instead! */ -#ifndef Py_LIMITED_API -#define _Py_MANAGED_BUFFER_RELEASED 0x001 /* access to exporter blocked */ -#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002 /* free format */ -typedef struct { - PyObject_HEAD - int flags; /* state flags */ - Py_ssize_t exports; /* number of direct memoryview exports */ - Py_buffer master; /* snapshot buffer obtained from the original exporter */ -} _PyManagedBufferObject; - - -/* memoryview state flags */ -#define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */ -#define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */ -#define _Py_MEMORYVIEW_FORTRAN 0x004 /* Fortran contiguous layout */ -#define _Py_MEMORYVIEW_SCALAR 0x008 /* scalar: ndim = 0 */ -#define _Py_MEMORYVIEW_PIL 0x010 /* PIL-style layout */ - -typedef struct { - PyObject_VAR_HEAD - _PyManagedBufferObject *mbuf; /* managed buffer */ - Py_hash_t hash; /* hash value for read-only views */ - int flags; /* state flags */ - Py_ssize_t exports; /* number of buffer re-exports */ - Py_buffer view; /* private copy of the exporter's view */ - PyObject *weakreflist; - Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */ -} PyMemoryViewObject; -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_MEMORYOBJECT_H */ diff --git a/python/include/methodobject.h b/python/include/methodobject.h deleted file mode 100644 index 56816e4..0000000 --- a/python/include/methodobject.h +++ /dev/null @@ -1,132 +0,0 @@ - -/* Method object interface */ - -#ifndef Py_METHODOBJECT_H -#define Py_METHODOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -/* This is about the type 'builtin_function_or_method', - not Python methods in user-defined classes. See classobject.h - for the latter. */ - -PyAPI_DATA(PyTypeObject) PyCFunction_Type; - -#define PyCFunction_CheckExact(op) Py_IS_TYPE(op, &PyCFunction_Type) -#define PyCFunction_Check(op) PyObject_TypeCheck(op, &PyCFunction_Type) - -typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); -typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t); -typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *, - PyObject *); -typedef PyObject *(*_PyCFunctionFastWithKeywords) (PyObject *, - PyObject *const *, Py_ssize_t, - PyObject *); -typedef PyObject *(*PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, - size_t, PyObject *); - -// Cast an function to the PyCFunction type to use it with PyMethodDef. -// -// This macro can be used to prevent compiler warnings if the first parameter -// uses a different pointer type than PyObject* (ex: METH_VARARGS and METH_O -// calling conventions). -// -// The macro can also be used for METH_FASTCALL and METH_VARARGS|METH_KEYWORDS -// calling conventions to avoid compiler warnings because the function has more -// than 2 parameters. The macro first casts the function to the -// "void func(void)" type to prevent compiler warnings. -// -// If a function is declared with the METH_NOARGS calling convention, it must -// have 2 parameters. Since the second parameter is unused, Py_UNUSED() can be -// used to prevent a compiler warning. If the function has a single parameter, -// it triggers an undefined behavior when Python calls it with 2 parameters -// (bpo-33012). -#define _PyCFunction_CAST(func) \ - _Py_CAST(PyCFunction, _Py_CAST(void(*)(void), (func))) - -PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *); -PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *); -PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *); - -Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *); - -struct PyMethodDef { - const char *ml_name; /* The name of the built-in function/method */ - PyCFunction ml_meth; /* The C function that implements it */ - int ml_flags; /* Combination of METH_xxx flags, which mostly - describe the args expected by the C func */ - const char *ml_doc; /* The __doc__ attribute, or NULL */ -}; - -/* PyCFunction_New is declared as a function for stable ABI (declaration is - * needed for e.g. GCC with -fvisibility=hidden), but redefined as a macro - * that calls PyCFunction_NewEx. */ -PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *); -#define PyCFunction_New(ML, SELF) PyCFunction_NewEx((ML), (SELF), NULL) - -/* PyCFunction_NewEx is similar: on 3.9+, this calls PyCMethod_New. */ -PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, - PyObject *); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 -#define PyCFunction_NewEx(ML, SELF, MOD) PyCMethod_New((ML), (SELF), (MOD), NULL) -PyAPI_FUNC(PyObject *) PyCMethod_New(PyMethodDef *, PyObject *, - PyObject *, PyTypeObject *); -#endif - - -/* Flag passed to newmethodobject */ -/* #define METH_OLDARGS 0x0000 -- unsupported now */ -#define METH_VARARGS 0x0001 -#define METH_KEYWORDS 0x0002 -/* METH_NOARGS and METH_O must not be combined with the flags above. */ -#define METH_NOARGS 0x0004 -#define METH_O 0x0008 - -/* METH_CLASS and METH_STATIC are a little different; these control - the construction of methods for a class. These cannot be used for - functions in modules. */ -#define METH_CLASS 0x0010 -#define METH_STATIC 0x0020 - -/* METH_COEXIST allows a method to be entered even though a slot has - already filled the entry. When defined, the flag allows a separate - method, "__contains__" for example, to coexist with a defined - slot like sq_contains. */ - -#define METH_COEXIST 0x0040 - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030a0000 -# define METH_FASTCALL 0x0080 -#endif - -/* This bit is preserved for Stackless Python */ -#ifdef STACKLESS -# define METH_STACKLESS 0x0100 -#else -# define METH_STACKLESS 0x0000 -#endif - -/* METH_METHOD means the function stores an - * additional reference to the class that defines it; - * both self and class are passed to it. - * It uses PyCMethodObject instead of PyCFunctionObject. - * May not be combined with METH_NOARGS, METH_O, METH_CLASS or METH_STATIC. - */ - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 -#define METH_METHOD 0x0200 -#endif - - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_METHODOBJECT_H -# include "cpython/methodobject.h" -# undef Py_CPYTHON_METHODOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_METHODOBJECT_H */ diff --git a/python/include/modsupport.h b/python/include/modsupport.h deleted file mode 100644 index 174503b..0000000 --- a/python/include/modsupport.h +++ /dev/null @@ -1,168 +0,0 @@ - -#ifndef Py_MODSUPPORT_H -#define Py_MODSUPPORT_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Module support interface */ - -#include // va_list - -/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier - to mean Py_ssize_t */ -#ifdef PY_SSIZE_T_CLEAN -#define PyArg_Parse _PyArg_Parse_SizeT -#define PyArg_ParseTuple _PyArg_ParseTuple_SizeT -#define PyArg_ParseTupleAndKeywords _PyArg_ParseTupleAndKeywords_SizeT -#define PyArg_VaParse _PyArg_VaParse_SizeT -#define PyArg_VaParseTupleAndKeywords _PyArg_VaParseTupleAndKeywords_SizeT -#define Py_BuildValue _Py_BuildValue_SizeT -#define Py_VaBuildValue _Py_VaBuildValue_SizeT -#endif - -/* Due to a glitch in 3.2, the _SizeT versions weren't exported from the DLL. */ -#if !defined(PY_SSIZE_T_CLEAN) || !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...); -PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); -PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, ...); -PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); -PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, va_list); -#endif -PyAPI_FUNC(int) PyArg_ValidateKeywordArguments(PyObject *); -PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...); -PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); -PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); - - -#define ANY_VARARGS(n) (n == PY_SSIZE_T_MAX) - -PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list); - -// Add an attribute with name 'name' and value 'obj' to the module 'mod. -// On success, return 0 on success. -// On error, raise an exception and return -1. -PyAPI_FUNC(int) PyModule_AddObjectRef(PyObject *mod, const char *name, PyObject *value); - -// Similar to PyModule_AddObjectRef() but steal a reference to 'obj' -// (Py_DECREF(obj)) on success (if it returns 0). -PyAPI_FUNC(int) PyModule_AddObject(PyObject *mod, const char *, PyObject *value); - -PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long); -PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char *); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 -/* New in 3.9 */ -PyAPI_FUNC(int) PyModule_AddType(PyObject *module, PyTypeObject *type); -#endif /* Py_LIMITED_API */ - -#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, #c, c) -#define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c) - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -/* New in 3.5 */ -PyAPI_FUNC(int) PyModule_SetDocString(PyObject *, const char *); -PyAPI_FUNC(int) PyModule_AddFunctions(PyObject *, PyMethodDef *); -PyAPI_FUNC(int) PyModule_ExecDef(PyObject *module, PyModuleDef *def); -#endif - -#define Py_CLEANUP_SUPPORTED 0x20000 - -#define PYTHON_API_VERSION 1013 -#define PYTHON_API_STRING "1013" -/* The API version is maintained (independently from the Python version) - so we can detect mismatches between the interpreter and dynamically - loaded modules. These are diagnosed by an error message but - the module is still loaded (because the mismatch can only be tested - after loading the module). The error message is intended to - explain the core dump a few seconds later. - - The symbol PYTHON_API_STRING defines the same value as a string - literal. *** PLEASE MAKE SURE THE DEFINITIONS MATCH. *** - - Please add a line or two to the top of this log for each API - version change: - - 22-Feb-2006 MvL 1013 PEP 353 - long indices for sequence lengths - - 19-Aug-2002 GvR 1012 Changes to string object struct for - interning changes, saving 3 bytes. - - 17-Jul-2001 GvR 1011 Descr-branch, just to be on the safe side - - 25-Jan-2001 FLD 1010 Parameters added to PyCode_New() and - PyFrame_New(); Python 2.1a2 - - 14-Mar-2000 GvR 1009 Unicode API added - - 3-Jan-1999 GvR 1007 Decided to change back! (Don't reuse 1008!) - - 3-Dec-1998 GvR 1008 Python 1.5.2b1 - - 18-Jan-1997 GvR 1007 string interning and other speedups - - 11-Oct-1996 GvR renamed Py_Ellipses to Py_Ellipsis :-( - - 30-Jul-1996 GvR Slice and ellipses syntax added - - 23-Jul-1996 GvR For 1.4 -- better safe than sorry this time :-) - - 7-Nov-1995 GvR Keyword arguments (should've been done at 1.3 :-( ) - - 10-Jan-1995 GvR Renamed globals to new naming scheme - - 9-Jan-1995 GvR Initial version (incompatible with older API) -*/ - -/* The PYTHON_ABI_VERSION is introduced in PEP 384. For the lifetime of - Python 3, it will stay at the value of 3; changes to the limited API - must be performed in a strictly backwards-compatible manner. */ -#define PYTHON_ABI_VERSION 3 -#define PYTHON_ABI_STRING "3" - -#ifdef Py_TRACE_REFS - /* When we are tracing reference counts, rename module creation functions so - modules compiled with incompatible settings will generate a - link-time error. */ - #define PyModule_Create2 PyModule_Create2TraceRefs - #define PyModule_FromDefAndSpec2 PyModule_FromDefAndSpec2TraceRefs -#endif - -PyAPI_FUNC(PyObject *) PyModule_Create2(PyModuleDef*, int apiver); - -#ifdef Py_LIMITED_API -#define PyModule_Create(module) \ - PyModule_Create2(module, PYTHON_ABI_VERSION) -#else -#define PyModule_Create(module) \ - PyModule_Create2(module, PYTHON_API_VERSION) -#endif - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -/* New in 3.5 */ -PyAPI_FUNC(PyObject *) PyModule_FromDefAndSpec2(PyModuleDef *def, - PyObject *spec, - int module_api_version); - -#ifdef Py_LIMITED_API -#define PyModule_FromDefAndSpec(module, spec) \ - PyModule_FromDefAndSpec2(module, spec, PYTHON_ABI_VERSION) -#else -#define PyModule_FromDefAndSpec(module, spec) \ - PyModule_FromDefAndSpec2(module, spec, PYTHON_API_VERSION) -#endif /* Py_LIMITED_API */ - -#endif /* New in 3.5 */ - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_MODSUPPORT_H -# include "cpython/modsupport.h" -# undef Py_CPYTHON_MODSUPPORT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_MODSUPPORT_H */ diff --git a/python/include/moduleobject.h b/python/include/moduleobject.h deleted file mode 100644 index cf0d541..0000000 --- a/python/include/moduleobject.h +++ /dev/null @@ -1,95 +0,0 @@ - -/* Module object interface */ - -#ifndef Py_MODULEOBJECT_H -#define Py_MODULEOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_DATA(PyTypeObject) PyModule_Type; - -#define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type) -#define PyModule_CheckExact(op) Py_IS_TYPE(op, &PyModule_Type) - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject *) PyModule_NewObject( - PyObject *name - ); -#endif -PyAPI_FUNC(PyObject *) PyModule_New( - const char *name /* UTF-8 encoded string */ - ); -PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject *) PyModule_GetNameObject(PyObject *); -#endif -PyAPI_FUNC(const char *) PyModule_GetName(PyObject *); -Py_DEPRECATED(3.2) PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *); -PyAPI_FUNC(PyObject *) PyModule_GetFilenameObject(PyObject *); -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) _PyModule_Clear(PyObject *); -PyAPI_FUNC(void) _PyModule_ClearDict(PyObject *); -PyAPI_FUNC(int) _PyModuleSpec_IsInitializing(PyObject *); -#endif -PyAPI_FUNC(PyModuleDef*) PyModule_GetDef(PyObject*); -PyAPI_FUNC(void*) PyModule_GetState(PyObject*); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -/* New in 3.5 */ -PyAPI_FUNC(PyObject *) PyModuleDef_Init(PyModuleDef*); -PyAPI_DATA(PyTypeObject) PyModuleDef_Type; -#endif - -typedef struct PyModuleDef_Base { - PyObject_HEAD - PyObject* (*m_init)(void); - Py_ssize_t m_index; - PyObject* m_copy; -} PyModuleDef_Base; - -#define PyModuleDef_HEAD_INIT { \ - PyObject_HEAD_INIT(_Py_NULL) \ - _Py_NULL, /* m_init */ \ - 0, /* m_index */ \ - _Py_NULL, /* m_copy */ \ - } - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -/* New in 3.5 */ -struct PyModuleDef_Slot { - int slot; - void *value; -}; - -#define Py_mod_create 1 -#define Py_mod_exec 2 - -#ifndef Py_LIMITED_API -#define _Py_mod_LAST_SLOT 2 -#endif - -#endif /* New in 3.5 */ - -struct PyModuleDef { - PyModuleDef_Base m_base; - const char* m_name; - const char* m_doc; - Py_ssize_t m_size; - PyMethodDef *m_methods; - PyModuleDef_Slot *m_slots; - traverseproc m_traverse; - inquiry m_clear; - freefunc m_free; -}; - - -// Internal C API -#ifdef Py_BUILD_CORE -extern int _PyModule_IsExtension(PyObject *obj); -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_MODULEOBJECT_H */ diff --git a/python/include/object.h b/python/include/object.h deleted file mode 100644 index 59f8582..0000000 --- a/python/include/object.h +++ /dev/null @@ -1,797 +0,0 @@ -#ifndef Py_OBJECT_H -#define Py_OBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* Object and type object interface */ - -/* -Objects are structures allocated on the heap. Special rules apply to -the use of objects to ensure they are properly garbage-collected. -Objects are never allocated statically or on the stack; they must be -accessed through special macros and functions only. (Type objects are -exceptions to the first rule; the standard types are represented by -statically initialized type objects, although work on type/class unification -for Python 2.2 made it possible to have heap-allocated type objects too). - -An object has a 'reference count' that is increased or decreased when a -pointer to the object is copied or deleted; when the reference count -reaches zero there are no references to the object left and it can be -removed from the heap. - -An object has a 'type' that determines what it represents and what kind -of data it contains. An object's type is fixed when it is created. -Types themselves are represented as objects; an object contains a -pointer to the corresponding type object. The type itself has a type -pointer pointing to the object representing the type 'type', which -contains a pointer to itself!. - -Objects do not float around in memory; once allocated an object keeps -the same size and address. Objects that must hold variable-size data -can contain pointers to variable-size parts of the object. Not all -objects of the same type have the same size; but the size cannot change -after allocation. (These restrictions are made so a reference to an -object can be simply a pointer -- moving an object would require -updating all the pointers, and changing an object's size would require -moving it if there was another object right next to it.) - -Objects are always accessed through pointers of the type 'PyObject *'. -The type 'PyObject' is a structure that only contains the reference count -and the type pointer. The actual memory allocated for an object -contains other data that can only be accessed after casting the pointer -to a pointer to a longer structure type. This longer type must start -with the reference count and type fields; the macro PyObject_HEAD should be -used for this (to accommodate for future changes). The implementation -of a particular object type can cast the object pointer to the proper -type and back. - -A standard interface exists for objects that contain an array of items -whose size is determined when the object is allocated. -*/ - -/* Py_DEBUG implies Py_REF_DEBUG. */ -#if defined(Py_DEBUG) && !defined(Py_REF_DEBUG) -# define Py_REF_DEBUG -#endif - -#if defined(Py_LIMITED_API) && defined(Py_TRACE_REFS) -# error Py_LIMITED_API is incompatible with Py_TRACE_REFS -#endif - -#ifdef Py_TRACE_REFS -/* Define pointers to support a doubly-linked list of all live heap objects. */ -#define _PyObject_HEAD_EXTRA \ - PyObject *_ob_next; \ - PyObject *_ob_prev; - -#define _PyObject_EXTRA_INIT _Py_NULL, _Py_NULL, - -#else -# define _PyObject_HEAD_EXTRA -# define _PyObject_EXTRA_INIT -#endif - -/* PyObject_HEAD defines the initial segment of every PyObject. */ -#define PyObject_HEAD PyObject ob_base; - -#define PyObject_HEAD_INIT(type) \ - { _PyObject_EXTRA_INIT \ - 1, type }, - -#define PyVarObject_HEAD_INIT(type, size) \ - { PyObject_HEAD_INIT(type) size }, - -/* PyObject_VAR_HEAD defines the initial segment of all variable-size - * container objects. These end with a declaration of an array with 1 - * element, but enough space is malloc'ed so that the array actually - * has room for ob_size elements. Note that ob_size is an element count, - * not necessarily a byte count. - */ -#define PyObject_VAR_HEAD PyVarObject ob_base; -#define Py_INVALID_SIZE (Py_ssize_t)-1 - -/* Nothing is actually declared to be a PyObject, but every pointer to - * a Python object can be cast to a PyObject*. This is inheritance built - * by hand. Similarly every pointer to a variable-size Python object can, - * in addition, be cast to PyVarObject*. - */ -struct _object { - _PyObject_HEAD_EXTRA - Py_ssize_t ob_refcnt; - PyTypeObject *ob_type; -}; - -/* Cast argument to PyObject* type. */ -#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op)) - -typedef struct { - PyObject ob_base; - Py_ssize_t ob_size; /* Number of items in variable part */ -} PyVarObject; - -/* Cast argument to PyVarObject* type. */ -#define _PyVarObject_CAST(op) _Py_CAST(PyVarObject*, (op)) - - -// Test if the 'x' object is the 'y' object, the same as "x is y" in Python. -PyAPI_FUNC(int) Py_Is(PyObject *x, PyObject *y); -#define Py_Is(x, y) ((x) == (y)) - - -static inline Py_ssize_t Py_REFCNT(PyObject *ob) { - return ob->ob_refcnt; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_REFCNT(ob) Py_REFCNT(_PyObject_CAST(ob)) -#endif - - -// bpo-39573: The Py_SET_TYPE() function must be used to set an object type. -static inline PyTypeObject* Py_TYPE(PyObject *ob) { - return ob->ob_type; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob)) -#endif - -// bpo-39573: The Py_SET_SIZE() function must be used to set an object size. -static inline Py_ssize_t Py_SIZE(PyObject *ob) { - PyVarObject *var_ob = _PyVarObject_CAST(ob); - return var_ob->ob_size; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_SIZE(ob) Py_SIZE(_PyObject_CAST(ob)) -#endif - - -static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) { - return Py_TYPE(ob) == type; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(ob), type) -#endif - - -static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { - ob->ob_refcnt = refcnt; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), refcnt) -#endif - - -static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { - ob->ob_type = type; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_SET_TYPE(ob, type) Py_SET_TYPE(_PyObject_CAST(ob), type) -#endif - - -static inline void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) { - ob->ob_size = size; -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_SET_SIZE(ob, size) Py_SET_SIZE(_PyVarObject_CAST(ob), size) -#endif - - -/* -Type objects contain a string containing the type name (to help somewhat -in debugging), the allocation parameters (see PyObject_New() and -PyObject_NewVar()), -and methods for accessing objects of the type. Methods are optional, a -nil pointer meaning that particular kind of access is not available for -this type. The Py_DECREF() macro uses the tp_dealloc method without -checking for a nil pointer; it should always be implemented except if -the implementation can guarantee that the reference count will never -reach zero (e.g., for statically allocated type objects). - -NB: the methods for certain type groups are now contained in separate -method blocks. -*/ - -typedef PyObject * (*unaryfunc)(PyObject *); -typedef PyObject * (*binaryfunc)(PyObject *, PyObject *); -typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *); -typedef int (*inquiry)(PyObject *); -typedef Py_ssize_t (*lenfunc)(PyObject *); -typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t); -typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t); -typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *); -typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); -typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *); - -typedef int (*objobjproc)(PyObject *, PyObject *); -typedef int (*visitproc)(PyObject *, void *); -typedef int (*traverseproc)(PyObject *, visitproc, void *); - - -typedef void (*freefunc)(void *); -typedef void (*destructor)(PyObject *); -typedef PyObject *(*getattrfunc)(PyObject *, char *); -typedef PyObject *(*getattrofunc)(PyObject *, PyObject *); -typedef int (*setattrfunc)(PyObject *, char *, PyObject *); -typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *); -typedef PyObject *(*reprfunc)(PyObject *); -typedef Py_hash_t (*hashfunc)(PyObject *); -typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int); -typedef PyObject *(*getiterfunc) (PyObject *); -typedef PyObject *(*iternextfunc) (PyObject *); -typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *); -typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); -typedef int (*initproc)(PyObject *, PyObject *, PyObject *); -typedef PyObject *(*newfunc)(PyTypeObject *, PyObject *, PyObject *); -typedef PyObject *(*allocfunc)(PyTypeObject *, Py_ssize_t); - -typedef struct{ - int slot; /* slot id, see below */ - void *pfunc; /* function pointer */ -} PyType_Slot; - -typedef struct{ - const char* name; - int basicsize; - int itemsize; - unsigned int flags; - PyType_Slot *slots; /* terminated by slot==0. */ -} PyType_Spec; - -PyAPI_FUNC(PyObject*) PyType_FromSpec(PyType_Spec*); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject*) PyType_FromSpecWithBases(PyType_Spec*, PyObject*); -#endif -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 -PyAPI_FUNC(void*) PyType_GetSlot(PyTypeObject*, int); -#endif -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 -PyAPI_FUNC(PyObject*) PyType_FromModuleAndSpec(PyObject *, PyType_Spec *, PyObject *); -PyAPI_FUNC(PyObject *) PyType_GetModule(PyTypeObject *); -PyAPI_FUNC(void *) PyType_GetModuleState(PyTypeObject *); -#endif -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030B0000 -PyAPI_FUNC(PyObject *) PyType_GetName(PyTypeObject *); -PyAPI_FUNC(PyObject *) PyType_GetQualName(PyTypeObject *); -#endif - -/* Generic type check */ -PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); - -static inline int PyObject_TypeCheck(PyObject *ob, PyTypeObject *type) { - return Py_IS_TYPE(ob, type) || PyType_IsSubtype(Py_TYPE(ob), type); -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyObject_TypeCheck(ob, type) PyObject_TypeCheck(_PyObject_CAST(ob), type) -#endif - -PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */ -PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */ -PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */ - -PyAPI_FUNC(unsigned long) PyType_GetFlags(PyTypeObject*); - -PyAPI_FUNC(int) PyType_Ready(PyTypeObject *); -PyAPI_FUNC(PyObject *) PyType_GenericAlloc(PyTypeObject *, Py_ssize_t); -PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *, - PyObject *, PyObject *); -PyAPI_FUNC(unsigned int) PyType_ClearCache(void); -PyAPI_FUNC(void) PyType_Modified(PyTypeObject *); - -/* Generic operations on objects */ -PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *); -PyAPI_FUNC(PyObject *) PyObject_Str(PyObject *); -PyAPI_FUNC(PyObject *) PyObject_ASCII(PyObject *); -PyAPI_FUNC(PyObject *) PyObject_Bytes(PyObject *); -PyAPI_FUNC(PyObject *) PyObject_RichCompare(PyObject *, PyObject *, int); -PyAPI_FUNC(int) PyObject_RichCompareBool(PyObject *, PyObject *, int); -PyAPI_FUNC(PyObject *) PyObject_GetAttrString(PyObject *, const char *); -PyAPI_FUNC(int) PyObject_SetAttrString(PyObject *, const char *, PyObject *); -PyAPI_FUNC(int) PyObject_HasAttrString(PyObject *, const char *); -PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *); -PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); -PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); -PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); -PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, PyObject *, PyObject *); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(int) PyObject_GenericSetDict(PyObject *, PyObject *, void *); -#endif -PyAPI_FUNC(Py_hash_t) PyObject_Hash(PyObject *); -PyAPI_FUNC(Py_hash_t) PyObject_HashNotImplemented(PyObject *); -PyAPI_FUNC(int) PyObject_IsTrue(PyObject *); -PyAPI_FUNC(int) PyObject_Not(PyObject *); -PyAPI_FUNC(int) PyCallable_Check(PyObject *); -PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *); - -/* PyObject_Dir(obj) acts like Python builtins.dir(obj), returning a - list of strings. PyObject_Dir(NULL) is like builtins.dir(), - returning the names of the current locals. In this case, if there are - no current locals, NULL is returned, and PyErr_Occurred() is false. -*/ -PyAPI_FUNC(PyObject *) PyObject_Dir(PyObject *); - -/* Pickle support. */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyObject_GetState(PyObject *); -#endif - - -/* Helpers for printing recursive container types */ -PyAPI_FUNC(int) Py_ReprEnter(PyObject *); -PyAPI_FUNC(void) Py_ReprLeave(PyObject *); - -/* Flag bits for printing: */ -#define Py_PRINT_RAW 1 /* No string quotes etc. */ - -/* -Type flags (tp_flags) - -These flags are used to change expected features and behavior for a -particular type. - -Arbitration of the flag bit positions will need to be coordinated among -all extension writers who publicly release their extensions (this will -be fewer than you might expect!). - -Most flags were removed as of Python 3.0 to make room for new flags. (Some -flags are not for backwards compatibility but to indicate the presence of an -optional feature; these flags remain of course.) - -Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value. - -Code can use PyType_HasFeature(type_ob, flag_value) to test whether the -given type object has a specified feature. -*/ - -#ifndef Py_LIMITED_API - -/* Placement of dict (and values) pointers are managed by the VM, not by the type. - * The VM will automatically set tp_dictoffset. Should not be used for variable sized - * classes, such as classes that extend tuple. - */ -#define Py_TPFLAGS_MANAGED_DICT (1 << 4) - -/* Set if instances of the type object are treated as sequences for pattern matching */ -#define Py_TPFLAGS_SEQUENCE (1 << 5) -/* Set if instances of the type object are treated as mappings for pattern matching */ -#define Py_TPFLAGS_MAPPING (1 << 6) -#endif - -/* Disallow creating instances of the type: set tp_new to NULL and don't create - * the "__new__" key in the type dictionary. */ -#define Py_TPFLAGS_DISALLOW_INSTANTIATION (1UL << 7) - -/* Set if the type object is immutable: type attributes cannot be set nor deleted */ -#define Py_TPFLAGS_IMMUTABLETYPE (1UL << 8) - -/* Set if the type object is dynamically allocated */ -#define Py_TPFLAGS_HEAPTYPE (1UL << 9) - -/* Set if the type allows subclassing */ -#define Py_TPFLAGS_BASETYPE (1UL << 10) - -/* Set if the type implements the vectorcall protocol (PEP 590) */ -#ifndef Py_LIMITED_API -#define Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11) -// Backwards compatibility alias for API that was provisional in Python 3.8 -#define _Py_TPFLAGS_HAVE_VECTORCALL Py_TPFLAGS_HAVE_VECTORCALL -#endif - -/* Set if the type is 'ready' -- fully initialized */ -#define Py_TPFLAGS_READY (1UL << 12) - -/* Set while the type is being 'readied', to prevent recursive ready calls */ -#define Py_TPFLAGS_READYING (1UL << 13) - -/* Objects support garbage collection (see objimpl.h) */ -#define Py_TPFLAGS_HAVE_GC (1UL << 14) - -/* These two bits are preserved for Stackless Python, next after this is 17 */ -#ifdef STACKLESS -#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION (3UL << 15) -#else -#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0 -#endif - -/* Objects behave like an unbound method */ -#define Py_TPFLAGS_METHOD_DESCRIPTOR (1UL << 17) - -/* Object has up-to-date type attribute cache */ -#define Py_TPFLAGS_VALID_VERSION_TAG (1UL << 19) - -/* Type is abstract and cannot be instantiated */ -#define Py_TPFLAGS_IS_ABSTRACT (1UL << 20) - -// This undocumented flag gives certain built-ins their unique pattern-matching -// behavior, which allows a single positional subpattern to match against the -// subject itself (rather than a mapped attribute on it): -#define _Py_TPFLAGS_MATCH_SELF (1UL << 22) - -/* These flags are used to determine if a type is a subclass. */ -#define Py_TPFLAGS_LONG_SUBCLASS (1UL << 24) -#define Py_TPFLAGS_LIST_SUBCLASS (1UL << 25) -#define Py_TPFLAGS_TUPLE_SUBCLASS (1UL << 26) -#define Py_TPFLAGS_BYTES_SUBCLASS (1UL << 27) -#define Py_TPFLAGS_UNICODE_SUBCLASS (1UL << 28) -#define Py_TPFLAGS_DICT_SUBCLASS (1UL << 29) -#define Py_TPFLAGS_BASE_EXC_SUBCLASS (1UL << 30) -#define Py_TPFLAGS_TYPE_SUBCLASS (1UL << 31) - -#define Py_TPFLAGS_DEFAULT ( \ - Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \ - 0) - -/* NOTE: Some of the following flags reuse lower bits (removed as part of the - * Python 3.0 transition). */ - -/* The following flags are kept for compatibility; in previous - * versions they indicated presence of newer tp_* fields on the - * type struct. - * Starting with 3.8, binary compatibility of C extensions across - * feature releases of Python is not supported anymore (except when - * using the stable ABI, in which all classes are created dynamically, - * using the interpreter's memory layout.) - * Note that older extensions using the stable ABI set these flags, - * so the bits must not be repurposed. - */ -#define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0) -#define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18) - - -/* -The macros Py_INCREF(op) and Py_DECREF(op) are used to increment or decrement -reference counts. Py_DECREF calls the object's deallocator function when -the refcount falls to 0; for -objects that don't contain references to other objects or heap memory -this can be the standard function free(). Both macros can be used -wherever a void expression is allowed. The argument must not be a -NULL pointer. If it may be NULL, use Py_XINCREF/Py_XDECREF instead. -The macro _Py_NewReference(op) initialize reference counts to 1, and -in special builds (Py_REF_DEBUG, Py_TRACE_REFS) performs additional -bookkeeping appropriate to the special build. - -We assume that the reference count field can never overflow; this can -be proven when the size of the field is the same as the pointer size, so -we ignore the possibility. Provided a C int is at least 32 bits (which -is implicitly assumed in many parts of this code), that's enough for -about 2**31 references to an object. - -XXX The following became out of date in Python 2.2, but I'm not sure -XXX what the full truth is now. Certainly, heap-allocated type objects -XXX can and should be deallocated. -Type objects should never be deallocated; the type pointer in an object -is not considered to be a reference to the type object, to save -complications in the deallocation function. (This is actually a -decision that's up to the implementer of each new type so if you want, -you can count such references to the type object.) -*/ - -#ifdef Py_REF_DEBUG -PyAPI_DATA(Py_ssize_t) _Py_RefTotal; -PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno, - PyObject *op); -#endif /* Py_REF_DEBUG */ - -PyAPI_FUNC(void) _Py_Dealloc(PyObject *); - -/* -These are provided as conveniences to Python runtime embedders, so that -they can have object code that is not dependent on Python compilation flags. -*/ -PyAPI_FUNC(void) Py_IncRef(PyObject *); -PyAPI_FUNC(void) Py_DecRef(PyObject *); - -// Similar to Py_IncRef() and Py_DecRef() but the argument must be non-NULL. -// Private functions used by Py_INCREF() and Py_DECREF(). -PyAPI_FUNC(void) _Py_IncRef(PyObject *); -PyAPI_FUNC(void) _Py_DecRef(PyObject *); - -static inline void Py_INCREF(PyObject *op) -{ -#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000 - // Stable ABI for Python 3.10 built in debug mode. - _Py_IncRef(op); -#else - // Non-limited C API and limited C API for Python 3.9 and older access - // directly PyObject.ob_refcnt. -#ifdef Py_REF_DEBUG - _Py_RefTotal++; -#endif - op->ob_refcnt++; -#endif -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op)) -#endif - - -#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000 -// Stable ABI for limited C API version 3.10 of Python debug build -static inline void Py_DECREF(PyObject *op) { - _Py_DecRef(op); -} -#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op)) - -#elif defined(Py_REF_DEBUG) -static inline void Py_DECREF(const char *filename, int lineno, PyObject *op) -{ - _Py_RefTotal--; - if (--op->ob_refcnt != 0) { - if (op->ob_refcnt < 0) { - _Py_NegativeRefcount(filename, lineno, op); - } - } - else { - _Py_Dealloc(op); - } -} -#define Py_DECREF(op) Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op)) - -#else -static inline void Py_DECREF(PyObject *op) -{ - // Non-limited C API and limited C API for Python 3.9 and older access - // directly PyObject.ob_refcnt. - if (--op->ob_refcnt == 0) { - _Py_Dealloc(op); - } -} -#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op)) -#endif - - -/* Safely decref `op` and set `op` to NULL, especially useful in tp_clear - * and tp_dealloc implementations. - * - * Note that "the obvious" code can be deadly: - * - * Py_XDECREF(op); - * op = NULL; - * - * Typically, `op` is something like self->containee, and `self` is done - * using its `containee` member. In the code sequence above, suppose - * `containee` is non-NULL with a refcount of 1. Its refcount falls to - * 0 on the first line, which can trigger an arbitrary amount of code, - * possibly including finalizers (like __del__ methods or weakref callbacks) - * coded in Python, which in turn can release the GIL and allow other threads - * to run, etc. Such code may even invoke methods of `self` again, or cause - * cyclic gc to trigger, but-- oops! --self->containee still points to the - * object being torn down, and it may be in an insane state while being torn - * down. This has in fact been a rich historic source of miserable (rare & - * hard-to-diagnose) segfaulting (and other) bugs. - * - * The safe way is: - * - * Py_CLEAR(op); - * - * That arranges to set `op` to NULL _before_ decref'ing, so that any code - * triggered as a side-effect of `op` getting torn down no longer believes - * `op` points to a valid object. - * - * There are cases where it's safe to use the naive code, but they're brittle. - * For example, if `op` points to a Python integer, you know that destroying - * one of those can't cause problems -- but in part that relies on that - * Python integers aren't currently weakly referencable. Best practice is - * to use Py_CLEAR() even if you can't think of a reason for why you need to. - */ -#define Py_CLEAR(op) \ - do { \ - PyObject *_py_tmp = _PyObject_CAST(op); \ - if (_py_tmp != NULL) { \ - (op) = NULL; \ - Py_DECREF(_py_tmp); \ - } \ - } while (0) - -/* Function to use in case the object pointer can be NULL: */ -static inline void Py_XINCREF(PyObject *op) -{ - if (op != _Py_NULL) { - Py_INCREF(op); - } -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_XINCREF(op) Py_XINCREF(_PyObject_CAST(op)) -#endif - -static inline void Py_XDECREF(PyObject *op) -{ - if (op != _Py_NULL) { - Py_DECREF(op); - } -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op)) -#endif - -// Create a new strong reference to an object: -// increment the reference count of the object and return the object. -PyAPI_FUNC(PyObject*) Py_NewRef(PyObject *obj); - -// Similar to Py_NewRef(), but the object can be NULL. -PyAPI_FUNC(PyObject*) Py_XNewRef(PyObject *obj); - -static inline PyObject* _Py_NewRef(PyObject *obj) -{ - Py_INCREF(obj); - return obj; -} - -static inline PyObject* _Py_XNewRef(PyObject *obj) -{ - Py_XINCREF(obj); - return obj; -} - -// Py_NewRef() and Py_XNewRef() are exported as functions for the stable ABI. -// Names overridden with macros by static inline functions for best -// performances. -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj)) -# define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj)) -#else -# define Py_NewRef(obj) _Py_NewRef(obj) -# define Py_XNewRef(obj) _Py_XNewRef(obj) -#endif - - -/* -_Py_NoneStruct is an object of undefined type which can be used in contexts -where NULL (nil) is not suitable (since NULL often means 'error'). - -Don't forget to apply Py_INCREF() when returning this value!!! -*/ -PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */ -#define Py_None (&_Py_NoneStruct) - -// Test if an object is the None singleton, the same as "x is None" in Python. -PyAPI_FUNC(int) Py_IsNone(PyObject *x); -#define Py_IsNone(x) Py_Is((x), Py_None) - -/* Macro for returning Py_None from a function */ -#define Py_RETURN_NONE return Py_NewRef(Py_None) - -/* -Py_NotImplemented is a singleton used to signal that an operation is -not implemented for a given type combination. -*/ -PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */ -#define Py_NotImplemented (&_Py_NotImplementedStruct) - -/* Macro for returning Py_NotImplemented from a function */ -#define Py_RETURN_NOTIMPLEMENTED return Py_NewRef(Py_NotImplemented) - -/* Rich comparison opcodes */ -#define Py_LT 0 -#define Py_LE 1 -#define Py_EQ 2 -#define Py_NE 3 -#define Py_GT 4 -#define Py_GE 5 - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 -/* Result of calling PyIter_Send */ -typedef enum { - PYGEN_RETURN = 0, - PYGEN_ERROR = -1, - PYGEN_NEXT = 1, -} PySendResult; -#endif - -/* - * Macro for implementing rich comparisons - * - * Needs to be a macro because any C-comparable type can be used. - */ -#define Py_RETURN_RICHCOMPARE(val1, val2, op) \ - do { \ - switch (op) { \ - case Py_EQ: if ((val1) == (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ - case Py_NE: if ((val1) != (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ - case Py_LT: if ((val1) < (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ - case Py_GT: if ((val1) > (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ - case Py_LE: if ((val1) <= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ - case Py_GE: if ((val1) >= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE; \ - default: \ - Py_UNREACHABLE(); \ - } \ - } while (0) - - -/* -More conventions -================ - -Argument Checking ------------------ - -Functions that take objects as arguments normally don't check for nil -arguments, but they do check the type of the argument, and return an -error if the function doesn't apply to the type. - -Failure Modes -------------- - -Functions may fail for a variety of reasons, including running out of -memory. This is communicated to the caller in two ways: an error string -is set (see errors.h), and the function result differs: functions that -normally return a pointer return NULL for failure, functions returning -an integer return -1 (which could be a legal return value too!), and -other functions return 0 for success and -1 for failure. -Callers should always check for errors before using the result. If -an error was set, the caller must either explicitly clear it, or pass -the error on to its caller. - -Reference Counts ----------------- - -It takes a while to get used to the proper usage of reference counts. - -Functions that create an object set the reference count to 1; such new -objects must be stored somewhere or destroyed again with Py_DECREF(). -Some functions that 'store' objects, such as PyTuple_SetItem() and -PyList_SetItem(), -don't increment the reference count of the object, since the most -frequent use is to store a fresh object. Functions that 'retrieve' -objects, such as PyTuple_GetItem() and PyDict_GetItemString(), also -don't increment -the reference count, since most frequently the object is only looked at -quickly. Thus, to retrieve an object and store it again, the caller -must call Py_INCREF() explicitly. - -NOTE: functions that 'consume' a reference count, like -PyList_SetItem(), consume the reference even if the object wasn't -successfully stored, to simplify error handling. - -It seems attractive to make other functions that take an object as -argument consume a reference count; however, this may quickly get -confusing (even the current practice is already confusing). Consider -it carefully, it may save lots of calls to Py_INCREF() and Py_DECREF() at -times. -*/ - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_OBJECT_H -# include "cpython/object.h" -# undef Py_CPYTHON_OBJECT_H -#endif - - -static inline int -PyType_HasFeature(PyTypeObject *type, unsigned long feature) -{ - unsigned long flags; -#ifdef Py_LIMITED_API - // PyTypeObject is opaque in the limited C API - flags = PyType_GetFlags(type); -#else - flags = type->tp_flags; -#endif - return ((flags & feature) != 0); -} - -#define PyType_FastSubclass(type, flag) PyType_HasFeature(type, flag) - -static inline int PyType_Check(PyObject *op) { - return PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS); -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyType_Check(op) PyType_Check(_PyObject_CAST(op)) -#endif - -#define _PyType_CAST(op) \ - (assert(PyType_Check(op)), _Py_CAST(PyTypeObject*, (op))) - -static inline int PyType_CheckExact(PyObject *op) { - return Py_IS_TYPE(op, &PyType_Type); -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyType_CheckExact(op) PyType_CheckExact(_PyObject_CAST(op)) -#endif - -#ifdef __cplusplus -} -#endif -#endif // !Py_OBJECT_H diff --git a/python/include/objimpl.h b/python/include/objimpl.h deleted file mode 100644 index 11b5c7a..0000000 --- a/python/include/objimpl.h +++ /dev/null @@ -1,215 +0,0 @@ -/* The PyObject_ memory family: high-level object memory interfaces. - See pymem.h for the low-level PyMem_ family. -*/ - -#ifndef Py_OBJIMPL_H -#define Py_OBJIMPL_H - -#include "pymem.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEWARE: - - Each interface exports both functions and macros. Extension modules should - use the functions, to ensure binary compatibility across Python versions. - Because the Python implementation is free to change internal details, and - the macros may (or may not) expose details for speed, if you do use the - macros you must recompile your extensions with each Python release. - - Never mix calls to PyObject_ memory functions with calls to the platform - malloc/realloc/ calloc/free, or with calls to PyMem_. -*/ - -/* -Functions and macros for modules that implement new object types. - - - PyObject_New(type, typeobj) allocates memory for a new object of the given - type, and initializes part of it. 'type' must be the C structure type used - to represent the object, and 'typeobj' the address of the corresponding - type object. Reference count and type pointer are filled in; the rest of - the bytes of the object are *undefined*! The resulting expression type is - 'type *'. The size of the object is determined by the tp_basicsize field - of the type object. - - - PyObject_NewVar(type, typeobj, n) is similar but allocates a variable-size - object with room for n items. In addition to the refcount and type pointer - fields, this also fills in the ob_size field. - - - PyObject_Free(op) releases the memory allocated for an object. It does not - run a destructor -- it only frees the memory. PyObject_Free is identical. - - - PyObject_Init(op, typeobj) and PyObject_InitVar(op, typeobj, n) don't - allocate memory. Instead of a 'type' parameter, they take a pointer to a - new object (allocated by an arbitrary allocator), and initialize its object - header fields. - -Note that objects created with PyObject_{New, NewVar} are allocated using the -specialized Python allocator (implemented in obmalloc.c), if WITH_PYMALLOC is -enabled. In addition, a special debugging allocator is used if Py_DEBUG -macro is also defined. - -In case a specific form of memory management is needed (for example, if you -must use the platform malloc heap(s), or shared memory, or C++ local storage or -operator new), you must first allocate the object with your custom allocator, -then pass its pointer to PyObject_{Init, InitVar} for filling in its Python- -specific fields: reference count, type pointer, possibly others. You should -be aware that Python has no control over these objects because they don't -cooperate with the Python memory manager. Such objects may not be eligible -for automatic garbage collection and you have to make sure that they are -released accordingly whenever their destructor gets called (cf. the specific -form of memory management you're using). - -Unless you have specific memory management requirements, use -PyObject_{New, NewVar, Del}. -*/ - -/* - * Raw object memory interface - * =========================== - */ - -/* Functions to call the same malloc/realloc/free as used by Python's - object allocator. If WITH_PYMALLOC is enabled, these may differ from - the platform malloc/realloc/free. The Python object allocator is - designed for fast, cache-conscious allocation of many "small" objects, - and with low hidden memory overhead. - - PyObject_Malloc(0) returns a unique non-NULL pointer if possible. - - PyObject_Realloc(NULL, n) acts like PyObject_Malloc(n). - PyObject_Realloc(p != NULL, 0) does not return NULL, or free the memory - at p. - - Returned pointers must be checked for NULL explicitly; no action is - performed on failure other than to return NULL (no warning it printed, no - exception is set, etc). - - For allocating objects, use PyObject_{New, NewVar} instead whenever - possible. The PyObject_{Malloc, Realloc, Free} family is exposed - so that you can exploit Python's small-block allocator for non-object - uses. If you must use these routines to allocate object memory, make sure - the object gets initialized via PyObject_{Init, InitVar} after obtaining - the raw memory. -*/ -PyAPI_FUNC(void *) PyObject_Malloc(size_t size); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -PyAPI_FUNC(void *) PyObject_Calloc(size_t nelem, size_t elsize); -#endif -PyAPI_FUNC(void *) PyObject_Realloc(void *ptr, size_t new_size); -PyAPI_FUNC(void) PyObject_Free(void *ptr); - - -// Deprecated aliases only kept for backward compatibility. -// PyObject_Del and PyObject_DEL are defined with no parameter to be able to -// use them as function pointers (ex: tp_free = PyObject_Del). -#define PyObject_MALLOC PyObject_Malloc -#define PyObject_REALLOC PyObject_Realloc -#define PyObject_FREE PyObject_Free -#define PyObject_Del PyObject_Free -#define PyObject_DEL PyObject_Free - - -/* - * Generic object allocator interface - * ================================== - */ - -/* Functions */ -PyAPI_FUNC(PyObject *) PyObject_Init(PyObject *, PyTypeObject *); -PyAPI_FUNC(PyVarObject *) PyObject_InitVar(PyVarObject *, - PyTypeObject *, Py_ssize_t); - -#define PyObject_INIT(op, typeobj) \ - PyObject_Init(_PyObject_CAST(op), (typeobj)) -#define PyObject_INIT_VAR(op, typeobj, size) \ - PyObject_InitVar(_PyVarObject_CAST(op), (typeobj), (size)) - - -PyAPI_FUNC(PyObject *) _PyObject_New(PyTypeObject *); -PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); - -#define PyObject_New(type, typeobj) ((type *)_PyObject_New(typeobj)) - -// Alias to PyObject_New(). In Python 3.8, PyObject_NEW() called directly -// PyObject_MALLOC() with _PyObject_SIZE(). -#define PyObject_NEW(type, typeobj) PyObject_New(type, typeobj) - -#define PyObject_NewVar(type, typeobj, n) \ - ( (type *) _PyObject_NewVar((typeobj), (n)) ) - -// Alias to PyObject_NewVar(). In Python 3.8, PyObject_NEW_VAR() called -// directly PyObject_MALLOC() with _PyObject_VAR_SIZE(). -#define PyObject_NEW_VAR(type, typeobj, n) PyObject_NewVar(type, typeobj, n) - - -/* - * Garbage Collection Support - * ========================== - */ - -/* C equivalent of gc.collect(). */ -PyAPI_FUNC(Py_ssize_t) PyGC_Collect(void); -/* C API for controlling the state of the garbage collector */ -PyAPI_FUNC(int) PyGC_Enable(void); -PyAPI_FUNC(int) PyGC_Disable(void); -PyAPI_FUNC(int) PyGC_IsEnabled(void); - -/* Test if a type has a GC head */ -#define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) - -PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t); -#define PyObject_GC_Resize(type, op, n) \ - ( (type *) _PyObject_GC_Resize(_PyVarObject_CAST(op), (n)) ) - - - -PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); -PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t); - -/* Tell the GC to track this object. - * - * See also private _PyObject_GC_TRACK() macro. */ -PyAPI_FUNC(void) PyObject_GC_Track(void *); - -/* Tell the GC to stop tracking this object. - * - * See also private _PyObject_GC_UNTRACK() macro. */ -PyAPI_FUNC(void) PyObject_GC_UnTrack(void *); - -PyAPI_FUNC(void) PyObject_GC_Del(void *); - -#define PyObject_GC_New(type, typeobj) \ - _Py_CAST(type*, _PyObject_GC_New(typeobj)) -#define PyObject_GC_NewVar(type, typeobj, n) \ - _Py_CAST(type*, _PyObject_GC_NewVar((typeobj), (n))) - -PyAPI_FUNC(int) PyObject_GC_IsTracked(PyObject *); -PyAPI_FUNC(int) PyObject_GC_IsFinalized(PyObject *); - -/* Utility macro to help write tp_traverse functions. - * To use this macro, the tp_traverse function must name its arguments - * "visit" and "arg". This is intended to keep tp_traverse functions - * looking as much alike as possible. - */ -#define Py_VISIT(op) \ - do { \ - if (op) { \ - int vret = visit(_PyObject_CAST(op), arg); \ - if (vret) \ - return vret; \ - } \ - } while (0) - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_OBJIMPL_H -# include "cpython/objimpl.h" -# undef Py_CPYTHON_OBJIMPL_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_OBJIMPL_H */ diff --git a/python/include/opcode.h b/python/include/opcode.h deleted file mode 100644 index 27cd936..0000000 --- a/python/include/opcode.h +++ /dev/null @@ -1,236 +0,0 @@ -// Auto-generated by Tools/scripts/generate_opcode_h.py from Lib/opcode.py - -#ifndef Py_OPCODE_H -#define Py_OPCODE_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* Instruction opcodes for compiled code */ -#define CACHE 0 -#define POP_TOP 1 -#define PUSH_NULL 2 -#define NOP 9 -#define UNARY_POSITIVE 10 -#define UNARY_NEGATIVE 11 -#define UNARY_NOT 12 -#define UNARY_INVERT 15 -#define BINARY_SUBSCR 25 -#define GET_LEN 30 -#define MATCH_MAPPING 31 -#define MATCH_SEQUENCE 32 -#define MATCH_KEYS 33 -#define PUSH_EXC_INFO 35 -#define CHECK_EXC_MATCH 36 -#define CHECK_EG_MATCH 37 -#define WITH_EXCEPT_START 49 -#define GET_AITER 50 -#define GET_ANEXT 51 -#define BEFORE_ASYNC_WITH 52 -#define BEFORE_WITH 53 -#define END_ASYNC_FOR 54 -#define STORE_SUBSCR 60 -#define DELETE_SUBSCR 61 -#define GET_ITER 68 -#define GET_YIELD_FROM_ITER 69 -#define PRINT_EXPR 70 -#define LOAD_BUILD_CLASS 71 -#define LOAD_ASSERTION_ERROR 74 -#define RETURN_GENERATOR 75 -#define LIST_TO_TUPLE 82 -#define RETURN_VALUE 83 -#define IMPORT_STAR 84 -#define SETUP_ANNOTATIONS 85 -#define YIELD_VALUE 86 -#define ASYNC_GEN_WRAP 87 -#define PREP_RERAISE_STAR 88 -#define POP_EXCEPT 89 -#define HAVE_ARGUMENT 90 -#define STORE_NAME 90 -#define DELETE_NAME 91 -#define UNPACK_SEQUENCE 92 -#define FOR_ITER 93 -#define UNPACK_EX 94 -#define STORE_ATTR 95 -#define DELETE_ATTR 96 -#define STORE_GLOBAL 97 -#define DELETE_GLOBAL 98 -#define SWAP 99 -#define LOAD_CONST 100 -#define LOAD_NAME 101 -#define BUILD_TUPLE 102 -#define BUILD_LIST 103 -#define BUILD_SET 104 -#define BUILD_MAP 105 -#define LOAD_ATTR 106 -#define COMPARE_OP 107 -#define IMPORT_NAME 108 -#define IMPORT_FROM 109 -#define JUMP_FORWARD 110 -#define JUMP_IF_FALSE_OR_POP 111 -#define JUMP_IF_TRUE_OR_POP 112 -#define POP_JUMP_FORWARD_IF_FALSE 114 -#define POP_JUMP_FORWARD_IF_TRUE 115 -#define LOAD_GLOBAL 116 -#define IS_OP 117 -#define CONTAINS_OP 118 -#define RERAISE 119 -#define COPY 120 -#define BINARY_OP 122 -#define SEND 123 -#define LOAD_FAST 124 -#define STORE_FAST 125 -#define DELETE_FAST 126 -#define POP_JUMP_FORWARD_IF_NOT_NONE 128 -#define POP_JUMP_FORWARD_IF_NONE 129 -#define RAISE_VARARGS 130 -#define GET_AWAITABLE 131 -#define MAKE_FUNCTION 132 -#define BUILD_SLICE 133 -#define JUMP_BACKWARD_NO_INTERRUPT 134 -#define MAKE_CELL 135 -#define LOAD_CLOSURE 136 -#define LOAD_DEREF 137 -#define STORE_DEREF 138 -#define DELETE_DEREF 139 -#define JUMP_BACKWARD 140 -#define CALL_FUNCTION_EX 142 -#define EXTENDED_ARG 144 -#define LIST_APPEND 145 -#define SET_ADD 146 -#define MAP_ADD 147 -#define LOAD_CLASSDEREF 148 -#define COPY_FREE_VARS 149 -#define RESUME 151 -#define MATCH_CLASS 152 -#define FORMAT_VALUE 155 -#define BUILD_CONST_KEY_MAP 156 -#define BUILD_STRING 157 -#define LOAD_METHOD 160 -#define LIST_EXTEND 162 -#define SET_UPDATE 163 -#define DICT_MERGE 164 -#define DICT_UPDATE 165 -#define PRECALL 166 -#define CALL 171 -#define KW_NAMES 172 -#define POP_JUMP_BACKWARD_IF_NOT_NONE 173 -#define POP_JUMP_BACKWARD_IF_NONE 174 -#define POP_JUMP_BACKWARD_IF_FALSE 175 -#define POP_JUMP_BACKWARD_IF_TRUE 176 -#define BINARY_OP_ADAPTIVE 3 -#define BINARY_OP_ADD_FLOAT 4 -#define BINARY_OP_ADD_INT 5 -#define BINARY_OP_ADD_UNICODE 6 -#define BINARY_OP_INPLACE_ADD_UNICODE 7 -#define BINARY_OP_MULTIPLY_FLOAT 8 -#define BINARY_OP_MULTIPLY_INT 13 -#define BINARY_OP_SUBTRACT_FLOAT 14 -#define BINARY_OP_SUBTRACT_INT 16 -#define BINARY_SUBSCR_ADAPTIVE 17 -#define BINARY_SUBSCR_DICT 18 -#define BINARY_SUBSCR_GETITEM 19 -#define BINARY_SUBSCR_LIST_INT 20 -#define BINARY_SUBSCR_TUPLE_INT 21 -#define CALL_ADAPTIVE 22 -#define CALL_PY_EXACT_ARGS 23 -#define CALL_PY_WITH_DEFAULTS 24 -#define COMPARE_OP_ADAPTIVE 26 -#define COMPARE_OP_FLOAT_JUMP 27 -#define COMPARE_OP_INT_JUMP 28 -#define COMPARE_OP_STR_JUMP 29 -#define EXTENDED_ARG_QUICK 34 -#define JUMP_BACKWARD_QUICK 38 -#define LOAD_ATTR_ADAPTIVE 39 -#define LOAD_ATTR_INSTANCE_VALUE 40 -#define LOAD_ATTR_MODULE 41 -#define LOAD_ATTR_SLOT 42 -#define LOAD_ATTR_WITH_HINT 43 -#define LOAD_CONST__LOAD_FAST 44 -#define LOAD_FAST__LOAD_CONST 45 -#define LOAD_FAST__LOAD_FAST 46 -#define LOAD_GLOBAL_ADAPTIVE 47 -#define LOAD_GLOBAL_BUILTIN 48 -#define LOAD_GLOBAL_MODULE 55 -#define LOAD_METHOD_ADAPTIVE 56 -#define LOAD_METHOD_CLASS 57 -#define LOAD_METHOD_MODULE 58 -#define LOAD_METHOD_NO_DICT 59 -#define LOAD_METHOD_WITH_DICT 62 -#define LOAD_METHOD_WITH_VALUES 63 -#define PRECALL_ADAPTIVE 64 -#define PRECALL_BOUND_METHOD 65 -#define PRECALL_BUILTIN_CLASS 66 -#define PRECALL_BUILTIN_FAST_WITH_KEYWORDS 67 -#define PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 72 -#define PRECALL_NO_KW_BUILTIN_FAST 73 -#define PRECALL_NO_KW_BUILTIN_O 76 -#define PRECALL_NO_KW_ISINSTANCE 77 -#define PRECALL_NO_KW_LEN 78 -#define PRECALL_NO_KW_LIST_APPEND 79 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 80 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 81 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 113 -#define PRECALL_NO_KW_STR_1 121 -#define PRECALL_NO_KW_TUPLE_1 127 -#define PRECALL_NO_KW_TYPE_1 141 -#define PRECALL_PYFUNC 143 -#define RESUME_QUICK 150 -#define STORE_ATTR_ADAPTIVE 153 -#define STORE_ATTR_INSTANCE_VALUE 154 -#define STORE_ATTR_SLOT 158 -#define STORE_ATTR_WITH_HINT 159 -#define STORE_FAST__LOAD_FAST 161 -#define STORE_FAST__STORE_FAST 167 -#define STORE_SUBSCR_ADAPTIVE 168 -#define STORE_SUBSCR_DICT 169 -#define STORE_SUBSCR_LIST_INT 170 -#define UNPACK_SEQUENCE_ADAPTIVE 177 -#define UNPACK_SEQUENCE_LIST 178 -#define UNPACK_SEQUENCE_TUPLE 179 -#define UNPACK_SEQUENCE_TWO_TUPLE 180 -#define DO_TRACING 255 - -#define HAS_CONST(op) (false\ - || ((op) == 100) \ - || ((op) == 172) \ - ) - -#define NB_ADD 0 -#define NB_AND 1 -#define NB_FLOOR_DIVIDE 2 -#define NB_LSHIFT 3 -#define NB_MATRIX_MULTIPLY 4 -#define NB_MULTIPLY 5 -#define NB_REMAINDER 6 -#define NB_OR 7 -#define NB_POWER 8 -#define NB_RSHIFT 9 -#define NB_SUBTRACT 10 -#define NB_TRUE_DIVIDE 11 -#define NB_XOR 12 -#define NB_INPLACE_ADD 13 -#define NB_INPLACE_AND 14 -#define NB_INPLACE_FLOOR_DIVIDE 15 -#define NB_INPLACE_LSHIFT 16 -#define NB_INPLACE_MATRIX_MULTIPLY 17 -#define NB_INPLACE_MULTIPLY 18 -#define NB_INPLACE_REMAINDER 19 -#define NB_INPLACE_OR 20 -#define NB_INPLACE_POWER 21 -#define NB_INPLACE_RSHIFT 22 -#define NB_INPLACE_SUBTRACT 23 -#define NB_INPLACE_TRUE_DIVIDE 24 -#define NB_INPLACE_XOR 25 - -#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) - -/* Reserve some bytecodes for internal use in the compiler. - * The value of 240 is arbitrary. */ -#define IS_ARTIFICIAL(op) ((op) > 240) - -#ifdef __cplusplus -} -#endif -#endif /* !Py_OPCODE_H */ diff --git a/python/include/osdefs.h b/python/include/osdefs.h deleted file mode 100644 index 4ff50cb..0000000 --- a/python/include/osdefs.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef Py_OSDEFS_H -#define Py_OSDEFS_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* Operating system dependencies */ - -#ifdef MS_WINDOWS -#define SEP L'\\' -#define ALTSEP L'/' -#define MAXPATHLEN 256 -#define DELIM L';' -#endif - -#ifdef __VXWORKS__ -#define DELIM L';' -#endif - -/* Filename separator */ -#ifndef SEP -#define SEP L'/' -#endif - -/* Max pathname length */ -#ifdef __hpux -#include -#include -#ifndef PATH_MAX -#define PATH_MAX MAXPATHLEN -#endif -#endif - -#ifndef MAXPATHLEN -#if defined(PATH_MAX) && PATH_MAX > 1024 -#define MAXPATHLEN PATH_MAX -#else -#define MAXPATHLEN 1024 -#endif -#endif - -/* Search path entry delimiter */ -#ifndef DELIM -#define DELIM L':' -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_OSDEFS_H */ diff --git a/python/include/osmodule.h b/python/include/osmodule.h deleted file mode 100644 index af50850..0000000 --- a/python/include/osmodule.h +++ /dev/null @@ -1,17 +0,0 @@ - -/* os module interface */ - -#ifndef Py_OSMODULE_H -#define Py_OSMODULE_H -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 -PyAPI_FUNC(PyObject *) PyOS_FSPath(PyObject *path); -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_OSMODULE_H */ diff --git a/python/include/patchlevel.h b/python/include/patchlevel.h deleted file mode 100644 index 372f82f..0000000 --- a/python/include/patchlevel.h +++ /dev/null @@ -1,35 +0,0 @@ - -/* Python version identification scheme. - - When the major or minor version changes, the VERSION variable in - configure.ac must also be changed. - - There is also (independent) API version information in modsupport.h. -*/ - -/* Values for PY_RELEASE_LEVEL */ -#define PY_RELEASE_LEVEL_ALPHA 0xA -#define PY_RELEASE_LEVEL_BETA 0xB -#define PY_RELEASE_LEVEL_GAMMA 0xC /* For release candidates */ -#define PY_RELEASE_LEVEL_FINAL 0xF /* Serial should be 0 here */ - /* Higher for patch releases */ - -/* Version parsed out into numeric values */ -/*--start constants--*/ -#define PY_MAJOR_VERSION 3 -#define PY_MINOR_VERSION 11 -#define PY_MICRO_VERSION 1 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL -#define PY_RELEASE_SERIAL 0 - -/* Version as a string */ -#define PY_VERSION "3.11.1" -/*--end constants--*/ - -/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. - Use this for numeric comparisons, e.g. #if PY_VERSION_HEX >= ... */ -#define PY_VERSION_HEX ((PY_MAJOR_VERSION << 24) | \ - (PY_MINOR_VERSION << 16) | \ - (PY_MICRO_VERSION << 8) | \ - (PY_RELEASE_LEVEL << 4) | \ - (PY_RELEASE_SERIAL << 0)) diff --git a/python/include/py_curses.h b/python/include/py_curses.h deleted file mode 100644 index 68b847e..0000000 --- a/python/include/py_curses.h +++ /dev/null @@ -1,99 +0,0 @@ - -#ifndef Py_CURSES_H -#define Py_CURSES_H - -#ifdef __APPLE__ -/* -** On Mac OS X 10.2 [n]curses.h and stdlib.h use different guards -** against multiple definition of wchar_t. -*/ -#ifdef _BSD_WCHAR_T_DEFINED_ -#define _WCHAR_T -#endif -#endif /* __APPLE__ */ - -/* On FreeBSD, [n]curses.h and stdlib.h/wchar.h use different guards - against multiple definition of wchar_t and wint_t. */ -#if defined(__FreeBSD__) && defined(_XOPEN_SOURCE_EXTENDED) -# ifndef __wchar_t -# define __wchar_t -# endif -# ifndef __wint_t -# define __wint_t -# endif -#endif - -#if !defined(HAVE_CURSES_IS_PAD) && defined(WINDOW_HAS_FLAGS) -/* The following definition is necessary for ncurses 5.7; without it, - some of [n]curses.h set NCURSES_OPAQUE to 1, and then Python - can't get at the WINDOW flags field. */ -#define NCURSES_OPAQUE 0 -#endif - -#ifdef HAVE_NCURSES_H -#include -#else -#include -#endif - -#ifdef HAVE_NCURSES_H -/* configure was checking , but we will - use , which has some or all these features. */ -#if !defined(WINDOW_HAS_FLAGS) && !(NCURSES_OPAQUE+0) -#define WINDOW_HAS_FLAGS 1 -#endif -#if !defined(HAVE_CURSES_IS_PAD) && NCURSES_VERSION_PATCH+0 >= 20090906 -#define HAVE_CURSES_IS_PAD 1 -#endif -#ifndef MVWDELCH_IS_EXPRESSION -#define MVWDELCH_IS_EXPRESSION 1 -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define PyCurses_API_pointers 4 - -/* Type declarations */ - -typedef struct { - PyObject_HEAD - WINDOW *win; - char *encoding; -} PyCursesWindowObject; - -#define PyCursesWindow_Check(v) Py_IS_TYPE(v, &PyCursesWindow_Type) - -#define PyCurses_CAPSULE_NAME "_curses._C_API" - - -#ifdef CURSES_MODULE -/* This section is used when compiling _cursesmodule.c */ - -#else -/* This section is used in modules that use the _cursesmodule API */ - -static void **PyCurses_API; - -#define PyCursesWindow_Type (*_PyType_CAST(PyCurses_API[0])) -#define PyCursesSetupTermCalled {if (! ((int (*)(void))PyCurses_API[1]) () ) return NULL;} -#define PyCursesInitialised {if (! ((int (*)(void))PyCurses_API[2]) () ) return NULL;} -#define PyCursesInitialisedColor {if (! ((int (*)(void))PyCurses_API[3]) () ) return NULL;} - -#define import_curses() \ - PyCurses_API = (void **)PyCapsule_Import(PyCurses_CAPSULE_NAME, 1); - -#endif - -/* general error messages */ -static const char catchall_ERR[] = "curses function returned ERR"; -static const char catchall_NULL[] = "curses function returned NULL"; - -#ifdef __cplusplus -} -#endif - -#endif /* !defined(Py_CURSES_H) */ - diff --git a/python/include/pybuffer.h b/python/include/pybuffer.h deleted file mode 100644 index ec802d8..0000000 --- a/python/include/pybuffer.h +++ /dev/null @@ -1,142 +0,0 @@ -/* Public Py_buffer API */ - -#ifndef Py_BUFFER_H -#define Py_BUFFER_H -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030b0000 - -/* === New Buffer API ============================================ - * Limited API and stable ABI since Python 3.11 - * - * Py_buffer struct layout and size is now part of the stable abi3. The - * struct layout and size must not be changed in any way, as it would - * break the ABI. - * - */ - -typedef struct { - void *buf; - PyObject *obj; /* owned reference */ - Py_ssize_t len; - Py_ssize_t itemsize; /* This is Py_ssize_t so it can be - pointed to by strides in simple case.*/ - int readonly; - int ndim; - char *format; - Py_ssize_t *shape; - Py_ssize_t *strides; - Py_ssize_t *suboffsets; - void *internal; -} Py_buffer; - -/* Return 1 if the getbuffer function is available, otherwise return 0. */ -PyAPI_FUNC(int) PyObject_CheckBuffer(PyObject *obj); - -/* This is a C-API version of the getbuffer function call. It checks - to make sure object has the required function pointer and issues the - call. - - Returns -1 and raises an error on failure and returns 0 on success. */ -PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view, - int flags); - -/* Get the memory area pointed to by the indices for the buffer given. - Note that view->ndim is the assumed size of indices. */ -PyAPI_FUNC(void *) PyBuffer_GetPointer(const Py_buffer *view, const Py_ssize_t *indices); - -/* Return the implied itemsize of the data-format area from a - struct-style description. */ -PyAPI_FUNC(Py_ssize_t) PyBuffer_SizeFromFormat(const char *format); - -/* Implementation in memoryobject.c */ -PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, const Py_buffer *view, - Py_ssize_t len, char order); - -PyAPI_FUNC(int) PyBuffer_FromContiguous(const Py_buffer *view, const void *buf, - Py_ssize_t len, char order); - -/* Copy len bytes of data from the contiguous chunk of memory - pointed to by buf into the buffer exported by obj. Return - 0 on success and return -1 and raise a PyBuffer_Error on - error (i.e. the object does not have a buffer interface or - it is not working). - - If fort is 'F', then if the object is multi-dimensional, - then the data will be copied into the array in - Fortran-style (first dimension varies the fastest). If - fort is 'C', then the data will be copied into the array - in C-style (last dimension varies the fastest). If fort - is 'A', then it does not matter and the copy will be made - in whatever way is more efficient. */ -PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src); - -/* Copy the data from the src buffer to the buffer of destination. */ -PyAPI_FUNC(int) PyBuffer_IsContiguous(const Py_buffer *view, char fort); - -/*Fill the strides array with byte-strides of a contiguous - (Fortran-style if fort is 'F' or C-style otherwise) - array of the given shape with the given number of bytes - per element. */ -PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims, - Py_ssize_t *shape, - Py_ssize_t *strides, - int itemsize, - char fort); - -/* Fills in a buffer-info structure correctly for an exporter - that can only share a contiguous chunk of memory of - "unsigned bytes" of the given length. - - Returns 0 on success and -1 (with raising an error) on error. */ -PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf, - Py_ssize_t len, int readonly, - int flags); - -/* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */ -PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view); - -/* Maximum number of dimensions */ -#define PyBUF_MAX_NDIM 64 - -/* Flags for getting buffers */ -#define PyBUF_SIMPLE 0 -#define PyBUF_WRITABLE 0x0001 - -#ifndef Py_LIMITED_API -/* we used to include an E, backwards compatible alias */ -#define PyBUF_WRITEABLE PyBUF_WRITABLE -#endif - -#define PyBUF_FORMAT 0x0004 -#define PyBUF_ND 0x0008 -#define PyBUF_STRIDES (0x0010 | PyBUF_ND) -#define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES) -#define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES) -#define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES) -#define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES) - -#define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITABLE) -#define PyBUF_CONTIG_RO (PyBUF_ND) - -#define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITABLE) -#define PyBUF_STRIDED_RO (PyBUF_STRIDES) - -#define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT) -#define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT) - -#define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT) -#define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT) - - -#define PyBUF_READ 0x100 -#define PyBUF_WRITE 0x200 - -#endif /* !Py_LIMITED_API || Py_LIMITED_API >= 3.11 */ - -#ifdef __cplusplus -} -#endif -#endif /* Py_BUFFER_H */ diff --git a/python/include/pycapsule.h b/python/include/pycapsule.h deleted file mode 100644 index 9387a1c..0000000 --- a/python/include/pycapsule.h +++ /dev/null @@ -1,59 +0,0 @@ - -/* Capsule objects let you wrap a C "void *" pointer in a Python - object. They're a way of passing data through the Python interpreter - without creating your own custom type. - - Capsules are used for communication between extension modules. - They provide a way for an extension module to export a C interface - to other extension modules, so that extension modules can use the - Python import mechanism to link to one another. - - For more information, please see "c-api/capsule.html" in the - documentation. -*/ - -#ifndef Py_CAPSULE_H -#define Py_CAPSULE_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_DATA(PyTypeObject) PyCapsule_Type; - -typedef void (*PyCapsule_Destructor)(PyObject *); - -#define PyCapsule_CheckExact(op) Py_IS_TYPE(op, &PyCapsule_Type) - - -PyAPI_FUNC(PyObject *) PyCapsule_New( - void *pointer, - const char *name, - PyCapsule_Destructor destructor); - -PyAPI_FUNC(void *) PyCapsule_GetPointer(PyObject *capsule, const char *name); - -PyAPI_FUNC(PyCapsule_Destructor) PyCapsule_GetDestructor(PyObject *capsule); - -PyAPI_FUNC(const char *) PyCapsule_GetName(PyObject *capsule); - -PyAPI_FUNC(void *) PyCapsule_GetContext(PyObject *capsule); - -PyAPI_FUNC(int) PyCapsule_IsValid(PyObject *capsule, const char *name); - -PyAPI_FUNC(int) PyCapsule_SetPointer(PyObject *capsule, void *pointer); - -PyAPI_FUNC(int) PyCapsule_SetDestructor(PyObject *capsule, PyCapsule_Destructor destructor); - -PyAPI_FUNC(int) PyCapsule_SetName(PyObject *capsule, const char *name); - -PyAPI_FUNC(int) PyCapsule_SetContext(PyObject *capsule, void *context); - -PyAPI_FUNC(void *) PyCapsule_Import( - const char *name, /* UTF-8 encoded string */ - int no_block); - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_CAPSULE_H */ diff --git a/python/include/pyconfig.h b/python/include/pyconfig.h deleted file mode 100644 index b8615a7..0000000 --- a/python/include/pyconfig.h +++ /dev/null @@ -1,710 +0,0 @@ -#ifndef Py_CONFIG_H -#define Py_CONFIG_H - -/* pyconfig.h. NOT Generated automatically by configure. - -This is a manually maintained version used for the Watcom, -Borland and Microsoft Visual C++ compilers. It is a -standard part of the Python distribution. - -WINDOWS DEFINES: -The code specific to Windows should be wrapped around one of -the following #defines - -MS_WIN64 - Code specific to the MS Win64 API -MS_WIN32 - Code specific to the MS Win32 (and Win64) API (obsolete, this covers all supported APIs) -MS_WINDOWS - Code specific to Windows, but all versions. -Py_ENABLE_SHARED - Code if the Python core is built as a DLL. - -Also note that neither "_M_IX86" or "_MSC_VER" should be used for -any purpose other than "Windows Intel x86 specific" and "Microsoft -compiler specific". Therefore, these should be very rare. - - -NOTE: The following symbols are deprecated: -NT, USE_DL_EXPORT, USE_DL_IMPORT, DL_EXPORT, DL_IMPORT -MS_CORE_DLL. - -WIN32 is still required for the locale module. - -*/ - -/* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */ -#ifdef USE_DL_EXPORT -# define Py_BUILD_CORE -#endif /* USE_DL_EXPORT */ - -/* Visual Studio 2005 introduces deprecation warnings for - "insecure" and POSIX functions. The insecure functions should - be replaced by *_s versions (according to Microsoft); the - POSIX functions by _* versions (which, according to Microsoft, - would be ISO C conforming). Neither renaming is feasible, so - we just silence the warnings. */ - -#ifndef _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif -#ifndef _CRT_NONSTDC_NO_DEPRECATE -#define _CRT_NONSTDC_NO_DEPRECATE 1 -#endif - -#define HAVE_IO_H -#define HAVE_SYS_UTIME_H -#define HAVE_TEMPNAM -#define HAVE_TMPFILE -#define HAVE_TMPNAM -#define HAVE_CLOCK -#define HAVE_STRERROR - -#include - -#define HAVE_STRFTIME -#define DONT_HAVE_SIG_ALARM -#define DONT_HAVE_SIG_PAUSE -#define LONG_BIT 32 -#define WORD_BIT 32 - -#define MS_WIN32 /* only support win32 and greater. */ -#define MS_WINDOWS -#define NT_THREADS -#define WITH_THREAD -#ifndef NETSCAPE_PI -#define USE_SOCKET -#endif - - -/* Compiler specific defines */ - -/* ------------------------------------------------------------------------*/ -/* Microsoft C defines _MSC_VER */ -#ifdef _MSC_VER - -/* We want COMPILER to expand to a string containing _MSC_VER's *value*. - * This is horridly tricky, because the stringization operator only works - * on macro arguments, and doesn't evaluate macros passed *as* arguments. - * Attempts simpler than the following appear doomed to produce "_MSC_VER" - * literally in the string. - */ -#define _Py_PASTE_VERSION(SUFFIX) \ - ("[MSC v." _Py_STRINGIZE(_MSC_VER) " " SUFFIX "]") -/* e.g., this produces, after compile-time string catenation, - * ("[MSC v.1200 32 bit (Intel)]") - * - * _Py_STRINGIZE(_MSC_VER) expands to - * _Py_STRINGIZE1((_MSC_VER)) expands to - * _Py_STRINGIZE2(_MSC_VER) but as this call is the result of token-pasting - * it's scanned again for macros and so further expands to (under MSVC 6) - * _Py_STRINGIZE2(1200) which then expands to - * "1200" - */ -#define _Py_STRINGIZE(X) _Py_STRINGIZE1((X)) -#define _Py_STRINGIZE1(X) _Py_STRINGIZE2 ## X -#define _Py_STRINGIZE2(X) #X - -/* MSVC defines _WINxx to differentiate the windows platform types - - Note that for compatibility reasons _WIN32 is defined on Win32 - *and* on Win64. For the same reasons, in Python, MS_WIN32 is - defined on Win32 *and* Win64. Win32 only code must therefore be - guarded as follows: - #if defined(MS_WIN32) && !defined(MS_WIN64) -*/ -#ifdef _WIN64 -#define MS_WIN64 -#endif - -/* set the COMPILER and support tier - * - * win_amd64 MSVC (x86_64-pc-windows-msvc): 1 - * win32 MSVC (i686-pc-windows-msvc): 1 - * win_arm64 MSVC (aarch64-pc-windows-msvc): 3 - * other archs and ICC: 0 - */ -#ifdef MS_WIN64 -#if defined(_M_X64) || defined(_M_AMD64) -#if defined(__INTEL_COMPILER) -#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") -#define PY_SUPPORT_TIER 0 -#else -#define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") -#define PY_SUPPORT_TIER 1 -#endif /* __INTEL_COMPILER */ -#define PYD_PLATFORM_TAG "win_amd64" -#elif defined(_M_ARM64) -#define COMPILER _Py_PASTE_VERSION("64 bit (ARM64)") -#define PY_SUPPORT_TIER 3 -#define PYD_PLATFORM_TAG "win_arm64" -#else -#define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") -#define PY_SUPPORT_TIER 0 -#endif -#endif /* MS_WIN64 */ - -/* set the version macros for the windows headers */ -/* Python 3.9+ requires Windows 8 or greater */ -#define Py_WINVER 0x0602 /* _WIN32_WINNT_WIN8 */ -#define Py_NTDDI NTDDI_WIN8 - -/* We only set these values when building Python - we don't want to force - these values on extensions, as that will affect the prototypes and - structures exposed in the Windows headers. Even when building Python, we - allow a single source file to override this - they may need access to - structures etc so it can optionally use new Windows features if it - determines at runtime they are available. -*/ -#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) || defined(Py_BUILD_CORE_MODULE) -#ifndef NTDDI_VERSION -#define NTDDI_VERSION Py_NTDDI -#endif -#ifndef WINVER -#define WINVER Py_WINVER -#endif -#ifndef _WIN32_WINNT -#define _WIN32_WINNT Py_WINVER -#endif -#endif - -/* _W64 is not defined for VC6 or eVC4 */ -#ifndef _W64 -#define _W64 -#endif - -/* Define like size_t, omitting the "unsigned" */ -#ifdef MS_WIN64 -typedef __int64 Py_ssize_t; -# define PY_SSIZE_T_MAX LLONG_MAX -#else -typedef _W64 int Py_ssize_t; -# define PY_SSIZE_T_MAX INT_MAX -#endif -#define HAVE_PY_SSIZE_T 1 - -#if defined(MS_WIN32) && !defined(MS_WIN64) -#if defined(_M_IX86) -#if defined(__INTEL_COMPILER) -#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") -#define PY_SUPPORT_TIER 0 -#else -#define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") -#define PY_SUPPORT_TIER 1 -#endif /* __INTEL_COMPILER */ -#define PYD_PLATFORM_TAG "win32" -#elif defined(_M_ARM) -#define COMPILER _Py_PASTE_VERSION("32 bit (ARM)") -#define PYD_PLATFORM_TAG "win_arm32" -#define PY_SUPPORT_TIER 0 -#else -#define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)") -#define PY_SUPPORT_TIER 0 -#endif -#endif /* MS_WIN32 && !MS_WIN64 */ - -typedef int pid_t; - -/* define some ANSI types that are not defined in earlier Win headers */ -#if _MSC_VER >= 1200 -/* This file only exists in VC 6.0 or higher */ -#include -#endif - -#endif /* _MSC_VER */ - -/* ------------------------------------------------------------------------*/ -/* egcs/gnu-win32 defines __GNUC__ and _WIN32 */ -#if defined(__GNUC__) && defined(_WIN32) -/* XXX These defines are likely incomplete, but should be easy to fix. - They should be complete enough to build extension modules. */ -/* Suggested by Rene Liebscher to avoid a GCC 2.91.* - bug that requires structure imports. More recent versions of the - compiler don't exhibit this bug. -*/ -#if (__GNUC__==2) && (__GNUC_MINOR__<=91) -#warning "Please use an up-to-date version of gcc! (>2.91 recommended)" -#endif - -#define COMPILER "[gcc]" -#define PY_LONG_LONG long long -#define PY_LLONG_MIN LLONG_MIN -#define PY_LLONG_MAX LLONG_MAX -#define PY_ULLONG_MAX ULLONG_MAX -#endif /* GNUC */ - -/* ------------------------------------------------------------------------*/ -/* lcc-win32 defines __LCC__ */ -#if defined(__LCC__) -/* XXX These defines are likely incomplete, but should be easy to fix. - They should be complete enough to build extension modules. */ - -#define COMPILER "[lcc-win32]" -typedef int pid_t; -/* __declspec() is supported here too - do nothing to get the defaults */ - -#endif /* LCC */ - -/* ------------------------------------------------------------------------*/ -/* End of compilers - finish up */ - -#ifndef NO_STDIO_H -# include -#endif - -/* 64 bit ints are usually spelt __int64 unless compiler has overridden */ -#ifndef PY_LONG_LONG -# define PY_LONG_LONG __int64 -# define PY_LLONG_MAX _I64_MAX -# define PY_LLONG_MIN _I64_MIN -# define PY_ULLONG_MAX _UI64_MAX -#endif - -/* For Windows the Python core is in a DLL by default. Test -Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ -#if !defined(MS_NO_COREDLL) && !defined(Py_NO_ENABLE_SHARED) -# define Py_ENABLE_SHARED 1 /* standard symbol for shared library */ -# define MS_COREDLL /* deprecated old symbol */ -#endif /* !MS_NO_COREDLL && ... */ - -/* All windows compilers that use this header support __declspec */ -#define HAVE_DECLSPEC_DLL - -/* For an MSVC DLL, we can nominate the .lib files used by extensions */ -#ifdef MS_COREDLL -# if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) - /* not building the core - must be an ext */ -# if defined(_MSC_VER) - /* So MSVC users need not specify the .lib - file in their Makefile (other compilers are - generally taken care of by distutils.) */ -# if defined(_DEBUG) -# pragma comment(lib,"python311_d.lib") -# elif defined(Py_LIMITED_API) -# pragma comment(lib,"python3.lib") -# else -# pragma comment(lib,"python311.lib") -# endif /* _DEBUG */ -# endif /* _MSC_VER */ -# endif /* Py_BUILD_CORE */ -#endif /* MS_COREDLL */ - -#if defined(MS_WIN64) -/* maintain "win32" sys.platform for backward compatibility of Python code, - the Win64 API should be close enough to the Win32 API to make this - preferable */ -# define PLATFORM "win32" -# define SIZEOF_VOID_P 8 -# define SIZEOF_TIME_T 8 -# define SIZEOF_OFF_T 4 -# define SIZEOF_FPOS_T 8 -# define SIZEOF_HKEY 8 -# define SIZEOF_SIZE_T 8 -# define ALIGNOF_SIZE_T 8 -/* configure.ac defines HAVE_LARGEFILE_SUPPORT iff - sizeof(off_t) > sizeof(long), and sizeof(long long) >= sizeof(off_t). - On Win64 the second condition is not true, but if fpos_t replaces off_t - then this is true. The uses of HAVE_LARGEFILE_SUPPORT imply that Win64 - should define this. */ -# define HAVE_LARGEFILE_SUPPORT -#elif defined(MS_WIN32) -# define PLATFORM "win32" -# define HAVE_LARGEFILE_SUPPORT -# define SIZEOF_VOID_P 4 -# define SIZEOF_OFF_T 4 -# define SIZEOF_FPOS_T 8 -# define SIZEOF_HKEY 4 -# define SIZEOF_SIZE_T 4 -# define ALIGNOF_SIZE_T 4 - /* MS VS2005 changes time_t to a 64-bit type on all platforms */ -# if defined(_MSC_VER) && _MSC_VER >= 1400 -# define SIZEOF_TIME_T 8 -# else -# define SIZEOF_TIME_T 4 -# endif -#endif - -#ifdef _DEBUG -# define Py_DEBUG -#endif - - -#ifdef MS_WIN32 - -#define SIZEOF_SHORT 2 -#define SIZEOF_INT 4 -#define SIZEOF_LONG 4 -#define ALIGNOF_LONG 4 -#define SIZEOF_LONG_LONG 8 -#define SIZEOF_DOUBLE 8 -#define SIZEOF_FLOAT 4 - -/* VC 7.1 has them and VC 6.0 does not. VC 6.0 has a version number of 1200. - Microsoft eMbedded Visual C++ 4.0 has a version number of 1201 and doesn't - define these. - If some compiler does not provide them, modify the #if appropriately. */ -#if defined(_MSC_VER) -#if _MSC_VER > 1300 -#define HAVE_UINTPTR_T 1 -#define HAVE_INTPTR_T 1 -#else -/* VC6, VS 2002 and eVC4 don't support the C99 LL suffix for 64-bit integer literals */ -#define Py_LL(x) x##I64 -#endif /* _MSC_VER > 1300 */ -#endif /* _MSC_VER */ - -#endif - -/* define signed and unsigned exact-width 32-bit and 64-bit types, used in the - implementation of Python integers. */ -#define PY_UINT32_T uint32_t -#define PY_UINT64_T uint64_t -#define PY_INT32_T int32_t -#define PY_INT64_T int64_t - -/* Fairly standard from here! */ - -/* Define if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -/* #undef _ALL_SOURCE */ -#endif - -/* Define to empty if the keyword does not work. */ -/* #define const */ - -/* Define to 1 if you have the header file. */ -#define HAVE_CONIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_DIRECT_H 1 - -/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. - */ -#define HAVE_DECL_TZNAME 1 - -/* Define if you have dirent.h. */ -/* #define DIRENT 1 */ - -/* Define to the type of elements in the array set by `getgroups'. - Usually this is either `int' or `gid_t'. */ -/* #undef GETGROUPS_T */ - -/* Define to `int' if doesn't define. */ -/* #undef gid_t */ - -/* Define if your struct tm has tm_zone. */ -/* #undef HAVE_TM_ZONE */ - -/* Define if you don't have tm_zone but do have the external array - tzname. */ -#define HAVE_TZNAME - -/* Define to `int' if doesn't define. */ -/* #undef mode_t */ - -/* Define if you don't have dirent.h, but have ndir.h. */ -/* #undef NDIR */ - -/* Define to `long' if doesn't define. */ -/* #undef off_t */ - -/* Define to `int' if doesn't define. */ -/* #undef pid_t */ - -/* Define if the system does not provide POSIX.1 features except - with this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define if you need to in order for stat and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define as the return type of signal handlers (int or void). */ -#define RETSIGTYPE void - -/* Define to `unsigned' if doesn't define. */ -/* #undef size_t */ - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define if you don't have dirent.h, but have sys/dir.h. */ -/* #undef SYSDIR */ - -/* Define if you don't have dirent.h, but have sys/ndir.h. */ -/* #undef SYSNDIR */ - -/* Define if you can safely include both and . */ -/* #undef TIME_WITH_SYS_TIME */ - -/* Define if your declares struct tm. */ -/* #define TM_IN_SYS_TIME 1 */ - -/* Define to `int' if doesn't define. */ -/* #undef uid_t */ - -/* Define if the closedir function returns void instead of int. */ -/* #undef VOID_CLOSEDIR */ - -/* Define if getpgrp() must be called as getpgrp(0) - and (consequently) setpgrp() as setpgrp(0, 0). */ -/* #undef GETPGRP_HAVE_ARGS */ - -/* Define this if your time.h defines altzone */ -/* #define HAVE_ALTZONE */ - -/* Define if you have the putenv function. */ -#define HAVE_PUTENV - -/* Define if your compiler supports function prototypes */ -#define HAVE_PROTOTYPES - -/* Define if you can safely include both and - (which you can't on SCO ODT 3.0). */ -/* #undef SYS_SELECT_WITH_SYS_TIME */ - -/* Define if you want build the _decimal module using a coroutine-local rather - than a thread-local context */ -#define WITH_DECIMAL_CONTEXTVAR 1 - -/* Define if you want documentation strings in extension modules */ -#define WITH_DOC_STRINGS 1 - -/* Define if you want to compile in rudimentary thread support */ -/* #undef WITH_THREAD */ - -/* Define if you want to use the GNU readline library */ -/* #define WITH_READLINE 1 */ - -/* Use Python's own small-block memory-allocator. */ -#define WITH_PYMALLOC 1 - -/* Define if you want to compile in object freelists optimization */ -#define WITH_FREELISTS 1 - -/* Define if you have clock. */ -/* #define HAVE_CLOCK */ - -/* Define when any dynamic module loading is enabled */ -#define HAVE_DYNAMIC_LOADING - -/* Define if you have ftime. */ -#define HAVE_FTIME - -/* Define if you have getpeername. */ -#define HAVE_GETPEERNAME - -/* Define if you have getpgrp. */ -/* #undef HAVE_GETPGRP */ - -/* Define if you have getpid. */ -#define HAVE_GETPID - -/* Define if you have gettimeofday. */ -/* #undef HAVE_GETTIMEOFDAY */ - -/* Define if you have getwd. */ -/* #undef HAVE_GETWD */ - -/* Define if you have lstat. */ -/* #undef HAVE_LSTAT */ - -/* Define if you have the mktime function. */ -#define HAVE_MKTIME - -/* Define if you have nice. */ -/* #undef HAVE_NICE */ - -/* Define if you have readlink. */ -/* #undef HAVE_READLINK */ - -/* Define if you have setpgid. */ -/* #undef HAVE_SETPGID */ - -/* Define if you have setpgrp. */ -/* #undef HAVE_SETPGRP */ - -/* Define if you have setsid. */ -/* #undef HAVE_SETSID */ - -/* Define if you have setvbuf. */ -#define HAVE_SETVBUF - -/* Define if you have siginterrupt. */ -/* #undef HAVE_SIGINTERRUPT */ - -/* Define to 1 if you have the `shutdown' function. */ -#define HAVE_SHUTDOWN 1 - -/* Define if you have symlink. */ -/* #undef HAVE_SYMLINK */ - -/* Define if you have tcgetpgrp. */ -/* #undef HAVE_TCGETPGRP */ - -/* Define if you have tcsetpgrp. */ -/* #undef HAVE_TCSETPGRP */ - -/* Define if you have times. */ -/* #undef HAVE_TIMES */ - -/* Define to 1 if you have the `umask' function. */ -#define HAVE_UMASK 1 - -/* Define if you have uname. */ -/* #undef HAVE_UNAME */ - -/* Define if you have waitpid. */ -/* #undef HAVE_WAITPID */ - -/* Define to 1 if you have the `wcsftime' function. */ -#if defined(_MSC_VER) && _MSC_VER >= 1310 -#define HAVE_WCSFTIME 1 -#endif - -/* Define to 1 if you have the `wcscoll' function. */ -#define HAVE_WCSCOLL 1 - -/* Define to 1 if you have the `wcsxfrm' function. */ -#define HAVE_WCSXFRM 1 - -/* Define if the zlib library has inflateCopy */ -#define HAVE_ZLIB_COPY 1 - -/* Define if you have the header file. */ -/* #undef HAVE_DLFCN_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_PROCESS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SIGNAL_H 1 - -/* Define if you have the prototypes. */ -#define HAVE_STDARG_PROTOTYPES - -/* Define if you have the header file. */ -#define HAVE_STDDEF_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_SYS_AUDIOIO_H */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_PARAM_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_SELECT_H 1 */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_SYS_TIME_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_TIMES_H 1 */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_SYS_UN_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_UTIME_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_UTSNAME_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_UNISTD_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_UTIME_H 1 */ - -/* Define if the compiler provides a wchar.h header file. */ -#define HAVE_WCHAR_H 1 - -/* The size of `wchar_t', as computed by sizeof. */ -#define SIZEOF_WCHAR_T 2 - -/* The size of `_Bool', as computed by sizeof. */ -#define SIZEOF__BOOL 1 - -/* The size of `pid_t', as computed by sizeof. */ -#define SIZEOF_PID_T SIZEOF_INT - -/* Define if you have the dl library (-ldl). */ -/* #undef HAVE_LIBDL */ - -/* Define if you have the mpc library (-lmpc). */ -/* #undef HAVE_LIBMPC */ - -/* Define if you have the nsl library (-lnsl). */ -#define HAVE_LIBNSL 1 - -/* Define if you have the seq library (-lseq). */ -/* #undef HAVE_LIBSEQ */ - -/* Define if you have the socket library (-lsocket). */ -#define HAVE_LIBSOCKET 1 - -/* Define if you have the sun library (-lsun). */ -/* #undef HAVE_LIBSUN */ - -/* Define if you have the termcap library (-ltermcap). */ -/* #undef HAVE_LIBTERMCAP */ - -/* Define if you have the termlib library (-ltermlib). */ -/* #undef HAVE_LIBTERMLIB */ - -/* Define if you have the thread library (-lthread). */ -/* #undef HAVE_LIBTHREAD */ - -/* WinSock does not use a bitmask in select, and uses - socket handles greater than FD_SETSIZE */ -#define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE - -/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the - least significant byte first */ -#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1 - -/* Define to 1 if you have the `erf' function. */ -#define HAVE_ERF 1 - -/* Define to 1 if you have the `erfc' function. */ -#define HAVE_ERFC 1 - -// netdb.h functions (provided by winsock.h) -#define HAVE_GETHOSTNAME 1 -#define HAVE_GETHOSTBYADDR 1 -#define HAVE_GETHOSTBYNAME 1 -#define HAVE_GETPROTOBYNAME 1 -#define HAVE_GETSERVBYNAME 1 -#define HAVE_GETSERVBYPORT 1 -// sys/socket.h functions (provided by winsock.h) -#define HAVE_INET_PTON 1 -#define HAVE_INET_NTOA 1 -#define HAVE_ACCEPT 1 -#define HAVE_BIND 1 -#define HAVE_CONNECT 1 -#define HAVE_GETSOCKNAME 1 -#define HAVE_LISTEN 1 -#define HAVE_RECVFROM 1 -#define HAVE_SENDTO 1 -#define HAVE_SETSOCKOPT 1 -#define HAVE_SOCKET 1 - -/* Define to 1 if you have the `dup' function. */ -#define HAVE_DUP 1 - -/* framework name */ -#define _PYTHONFRAMEWORK "" - -/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */ -#define HAVE_X509_VERIFY_PARAM_SET1_HOST 1 - -#endif /* !Py_CONFIG_H */ diff --git a/python/include/pydtrace.h b/python/include/pydtrace.h deleted file mode 100644 index 8fac200..0000000 --- a/python/include/pydtrace.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Static DTrace probes interface */ - -#ifndef Py_DTRACE_H -#define Py_DTRACE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef WITH_DTRACE - -#include "pydtrace_probes.h" - -/* pydtrace_probes.h, on systems with DTrace, is auto-generated to include - `PyDTrace_{PROBE}` and `PyDTrace_{PROBE}_ENABLED()` macros for every probe - defined in pydtrace_provider.d. - - Calling these functions must be guarded by a `PyDTrace_{PROBE}_ENABLED()` - check to minimize performance impact when probing is off. For example: - - if (PyDTrace_FUNCTION_ENTRY_ENABLED()) - PyDTrace_FUNCTION_ENTRY(f); -*/ - -#else - -/* Without DTrace, compile to nothing. */ - -static inline void PyDTrace_LINE(const char *arg0, const char *arg1, int arg2) {} -static inline void PyDTrace_FUNCTION_ENTRY(const char *arg0, const char *arg1, int arg2) {} -static inline void PyDTrace_FUNCTION_RETURN(const char *arg0, const char *arg1, int arg2) {} -static inline void PyDTrace_GC_START(int arg0) {} -static inline void PyDTrace_GC_DONE(Py_ssize_t arg0) {} -static inline void PyDTrace_INSTANCE_NEW_START(int arg0) {} -static inline void PyDTrace_INSTANCE_NEW_DONE(int arg0) {} -static inline void PyDTrace_INSTANCE_DELETE_START(int arg0) {} -static inline void PyDTrace_INSTANCE_DELETE_DONE(int arg0) {} -static inline void PyDTrace_IMPORT_FIND_LOAD_START(const char *arg0) {} -static inline void PyDTrace_IMPORT_FIND_LOAD_DONE(const char *arg0, int arg1) {} -static inline void PyDTrace_AUDIT(const char *arg0, void *arg1) {} - -static inline int PyDTrace_LINE_ENABLED(void) { return 0; } -static inline int PyDTrace_FUNCTION_ENTRY_ENABLED(void) { return 0; } -static inline int PyDTrace_FUNCTION_RETURN_ENABLED(void) { return 0; } -static inline int PyDTrace_GC_START_ENABLED(void) { return 0; } -static inline int PyDTrace_GC_DONE_ENABLED(void) { return 0; } -static inline int PyDTrace_INSTANCE_NEW_START_ENABLED(void) { return 0; } -static inline int PyDTrace_INSTANCE_NEW_DONE_ENABLED(void) { return 0; } -static inline int PyDTrace_INSTANCE_DELETE_START_ENABLED(void) { return 0; } -static inline int PyDTrace_INSTANCE_DELETE_DONE_ENABLED(void) { return 0; } -static inline int PyDTrace_IMPORT_FIND_LOAD_START_ENABLED(void) { return 0; } -static inline int PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED(void) { return 0; } -static inline int PyDTrace_AUDIT_ENABLED(void) { return 0; } - -#endif /* !WITH_DTRACE */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_DTRACE_H */ diff --git a/python/include/pyerrors.h b/python/include/pyerrors.h deleted file mode 100644 index 5ce49e4..0000000 --- a/python/include/pyerrors.h +++ /dev/null @@ -1,331 +0,0 @@ -#ifndef Py_ERRORS_H -#define Py_ERRORS_H -#ifdef __cplusplus -extern "C" { -#endif - -#include // va_list - -/* Error handling definitions */ - -PyAPI_FUNC(void) PyErr_SetNone(PyObject *); -PyAPI_FUNC(void) PyErr_SetObject(PyObject *, PyObject *); -PyAPI_FUNC(void) PyErr_SetString( - PyObject *exception, - const char *string /* decoded from utf-8 */ - ); -PyAPI_FUNC(PyObject *) PyErr_Occurred(void); -PyAPI_FUNC(void) PyErr_Clear(void); -PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **); -PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030b0000 -PyAPI_FUNC(PyObject*) PyErr_GetHandledException(void); -PyAPI_FUNC(void) PyErr_SetHandledException(PyObject *); -#endif -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(void) PyErr_GetExcInfo(PyObject **, PyObject **, PyObject **); -PyAPI_FUNC(void) PyErr_SetExcInfo(PyObject *, PyObject *, PyObject *); -#endif - -/* Defined in Python/pylifecycle.c - - The Py_FatalError() function is replaced with a macro which logs - automatically the name of the current function, unless the Py_LIMITED_API - macro is defined. */ -PyAPI_FUNC(void) _Py_NO_RETURN Py_FatalError(const char *message); - -/* Error testing and normalization */ -PyAPI_FUNC(int) PyErr_GivenExceptionMatches(PyObject *, PyObject *); -PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *); -PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**); - -/* Traceback manipulation (PEP 3134) */ -PyAPI_FUNC(int) PyException_SetTraceback(PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyException_GetTraceback(PyObject *); - -/* Cause manipulation (PEP 3134) */ -PyAPI_FUNC(PyObject *) PyException_GetCause(PyObject *); -PyAPI_FUNC(void) PyException_SetCause(PyObject *, PyObject *); - -/* Context manipulation (PEP 3134) */ -PyAPI_FUNC(PyObject *) PyException_GetContext(PyObject *); -PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); - -/* */ - -#define PyExceptionClass_Check(x) \ - (PyType_Check((x)) && \ - PyType_FastSubclass((PyTypeObject*)(x), Py_TPFLAGS_BASE_EXC_SUBCLASS)) - -#define PyExceptionInstance_Check(x) \ - PyType_FastSubclass(Py_TYPE(x), Py_TPFLAGS_BASE_EXC_SUBCLASS) - -PyAPI_FUNC(const char *) PyExceptionClass_Name(PyObject *); - -#define PyExceptionInstance_Class(x) ((PyObject*)Py_TYPE(x)) - -#define _PyBaseExceptionGroup_Check(x) \ - PyObject_TypeCheck(x, (PyTypeObject *)PyExc_BaseExceptionGroup) - -/* Predefined exceptions */ - -PyAPI_DATA(PyObject *) PyExc_BaseException; -PyAPI_DATA(PyObject *) PyExc_Exception; -PyAPI_DATA(PyObject *) PyExc_BaseExceptionGroup; -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -PyAPI_DATA(PyObject *) PyExc_StopAsyncIteration; -#endif -PyAPI_DATA(PyObject *) PyExc_StopIteration; -PyAPI_DATA(PyObject *) PyExc_GeneratorExit; -PyAPI_DATA(PyObject *) PyExc_ArithmeticError; -PyAPI_DATA(PyObject *) PyExc_LookupError; - -PyAPI_DATA(PyObject *) PyExc_AssertionError; -PyAPI_DATA(PyObject *) PyExc_AttributeError; -PyAPI_DATA(PyObject *) PyExc_BufferError; -PyAPI_DATA(PyObject *) PyExc_EOFError; -PyAPI_DATA(PyObject *) PyExc_FloatingPointError; -PyAPI_DATA(PyObject *) PyExc_OSError; -PyAPI_DATA(PyObject *) PyExc_ImportError; -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 -PyAPI_DATA(PyObject *) PyExc_ModuleNotFoundError; -#endif -PyAPI_DATA(PyObject *) PyExc_IndexError; -PyAPI_DATA(PyObject *) PyExc_KeyError; -PyAPI_DATA(PyObject *) PyExc_KeyboardInterrupt; -PyAPI_DATA(PyObject *) PyExc_MemoryError; -PyAPI_DATA(PyObject *) PyExc_NameError; -PyAPI_DATA(PyObject *) PyExc_OverflowError; -PyAPI_DATA(PyObject *) PyExc_RuntimeError; -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -PyAPI_DATA(PyObject *) PyExc_RecursionError; -#endif -PyAPI_DATA(PyObject *) PyExc_NotImplementedError; -PyAPI_DATA(PyObject *) PyExc_SyntaxError; -PyAPI_DATA(PyObject *) PyExc_IndentationError; -PyAPI_DATA(PyObject *) PyExc_TabError; -PyAPI_DATA(PyObject *) PyExc_ReferenceError; -PyAPI_DATA(PyObject *) PyExc_SystemError; -PyAPI_DATA(PyObject *) PyExc_SystemExit; -PyAPI_DATA(PyObject *) PyExc_TypeError; -PyAPI_DATA(PyObject *) PyExc_UnboundLocalError; -PyAPI_DATA(PyObject *) PyExc_UnicodeError; -PyAPI_DATA(PyObject *) PyExc_UnicodeEncodeError; -PyAPI_DATA(PyObject *) PyExc_UnicodeDecodeError; -PyAPI_DATA(PyObject *) PyExc_UnicodeTranslateError; -PyAPI_DATA(PyObject *) PyExc_ValueError; -PyAPI_DATA(PyObject *) PyExc_ZeroDivisionError; - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_DATA(PyObject *) PyExc_BlockingIOError; -PyAPI_DATA(PyObject *) PyExc_BrokenPipeError; -PyAPI_DATA(PyObject *) PyExc_ChildProcessError; -PyAPI_DATA(PyObject *) PyExc_ConnectionError; -PyAPI_DATA(PyObject *) PyExc_ConnectionAbortedError; -PyAPI_DATA(PyObject *) PyExc_ConnectionRefusedError; -PyAPI_DATA(PyObject *) PyExc_ConnectionResetError; -PyAPI_DATA(PyObject *) PyExc_FileExistsError; -PyAPI_DATA(PyObject *) PyExc_FileNotFoundError; -PyAPI_DATA(PyObject *) PyExc_InterruptedError; -PyAPI_DATA(PyObject *) PyExc_IsADirectoryError; -PyAPI_DATA(PyObject *) PyExc_NotADirectoryError; -PyAPI_DATA(PyObject *) PyExc_PermissionError; -PyAPI_DATA(PyObject *) PyExc_ProcessLookupError; -PyAPI_DATA(PyObject *) PyExc_TimeoutError; -#endif - - -/* Compatibility aliases */ -PyAPI_DATA(PyObject *) PyExc_EnvironmentError; -PyAPI_DATA(PyObject *) PyExc_IOError; -#ifdef MS_WINDOWS -PyAPI_DATA(PyObject *) PyExc_WindowsError; -#endif - -/* Predefined warning categories */ -PyAPI_DATA(PyObject *) PyExc_Warning; -PyAPI_DATA(PyObject *) PyExc_UserWarning; -PyAPI_DATA(PyObject *) PyExc_DeprecationWarning; -PyAPI_DATA(PyObject *) PyExc_PendingDeprecationWarning; -PyAPI_DATA(PyObject *) PyExc_SyntaxWarning; -PyAPI_DATA(PyObject *) PyExc_RuntimeWarning; -PyAPI_DATA(PyObject *) PyExc_FutureWarning; -PyAPI_DATA(PyObject *) PyExc_ImportWarning; -PyAPI_DATA(PyObject *) PyExc_UnicodeWarning; -PyAPI_DATA(PyObject *) PyExc_BytesWarning; -PyAPI_DATA(PyObject *) PyExc_EncodingWarning; -PyAPI_DATA(PyObject *) PyExc_ResourceWarning; - - -/* Convenience functions */ - -PyAPI_FUNC(int) PyErr_BadArgument(void); -PyAPI_FUNC(PyObject *) PyErr_NoMemory(void); -PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *); -PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObject( - PyObject *, PyObject *); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 -PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObjects( - PyObject *, PyObject *, PyObject *); -#endif -PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename( - PyObject *exc, - const char *filename /* decoded from the filesystem encoding */ - ); - -PyAPI_FUNC(PyObject *) PyErr_Format( - PyObject *exception, - const char *format, /* ASCII-encoded string */ - ... - ); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -PyAPI_FUNC(PyObject *) PyErr_FormatV( - PyObject *exception, - const char *format, - va_list vargs); -#endif - -#ifdef MS_WINDOWS -PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename( - int ierr, - const char *filename /* decoded from the filesystem encoding */ - ); -PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int); -PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject( - PyObject *,int, PyObject *); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 -PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObjects( - PyObject *,int, PyObject *, PyObject *); -#endif -PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename( - PyObject *exc, - int ierr, - const char *filename /* decoded from the filesystem encoding */ - ); -PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int); -#endif /* MS_WINDOWS */ - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 -PyAPI_FUNC(PyObject *) PyErr_SetImportErrorSubclass(PyObject *, PyObject *, - PyObject *, PyObject *); -#endif -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject *) PyErr_SetImportError(PyObject *, PyObject *, - PyObject *); -#endif - -/* Export the old function so that the existing API remains available: */ -PyAPI_FUNC(void) PyErr_BadInternalCall(void); -PyAPI_FUNC(void) _PyErr_BadInternalCall(const char *filename, int lineno); -/* Mask the old API with a call to the new API for code compiled under - Python 2.0: */ -#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) - -/* Function to create a new exception */ -PyAPI_FUNC(PyObject *) PyErr_NewException( - const char *name, PyObject *base, PyObject *dict); -PyAPI_FUNC(PyObject *) PyErr_NewExceptionWithDoc( - const char *name, const char *doc, PyObject *base, PyObject *dict); -PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *); - - -/* In signalmodule.c */ -PyAPI_FUNC(int) PyErr_CheckSignals(void); -PyAPI_FUNC(void) PyErr_SetInterrupt(void); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 -PyAPI_FUNC(int) PyErr_SetInterruptEx(int signum); -#endif - -/* Support for adding program text to SyntaxErrors */ -PyAPI_FUNC(void) PyErr_SyntaxLocation( - const char *filename, /* decoded from the filesystem encoding */ - int lineno); -PyAPI_FUNC(void) PyErr_SyntaxLocationEx( - const char *filename, /* decoded from the filesystem encoding */ - int lineno, - int col_offset); -PyAPI_FUNC(PyObject *) PyErr_ProgramText( - const char *filename, /* decoded from the filesystem encoding */ - int lineno); - -/* The following functions are used to create and modify unicode - exceptions from C */ - -/* create a UnicodeDecodeError object */ -PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_Create( - const char *encoding, /* UTF-8 encoded string */ - const char *object, - Py_ssize_t length, - Py_ssize_t start, - Py_ssize_t end, - const char *reason /* UTF-8 encoded string */ - ); - -/* get the encoding attribute */ -PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetEncoding(PyObject *); -PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetEncoding(PyObject *); - -/* get the object attribute */ -PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetObject(PyObject *); -PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetObject(PyObject *); -PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetObject(PyObject *); - -/* get the value of the start attribute (the int * may not be NULL) - return 0 on success, -1 on failure */ -PyAPI_FUNC(int) PyUnicodeEncodeError_GetStart(PyObject *, Py_ssize_t *); -PyAPI_FUNC(int) PyUnicodeDecodeError_GetStart(PyObject *, Py_ssize_t *); -PyAPI_FUNC(int) PyUnicodeTranslateError_GetStart(PyObject *, Py_ssize_t *); - -/* assign a new value to the start attribute - return 0 on success, -1 on failure */ -PyAPI_FUNC(int) PyUnicodeEncodeError_SetStart(PyObject *, Py_ssize_t); -PyAPI_FUNC(int) PyUnicodeDecodeError_SetStart(PyObject *, Py_ssize_t); -PyAPI_FUNC(int) PyUnicodeTranslateError_SetStart(PyObject *, Py_ssize_t); - -/* get the value of the end attribute (the int *may not be NULL) - return 0 on success, -1 on failure */ -PyAPI_FUNC(int) PyUnicodeEncodeError_GetEnd(PyObject *, Py_ssize_t *); -PyAPI_FUNC(int) PyUnicodeDecodeError_GetEnd(PyObject *, Py_ssize_t *); -PyAPI_FUNC(int) PyUnicodeTranslateError_GetEnd(PyObject *, Py_ssize_t *); - -/* assign a new value to the end attribute - return 0 on success, -1 on failure */ -PyAPI_FUNC(int) PyUnicodeEncodeError_SetEnd(PyObject *, Py_ssize_t); -PyAPI_FUNC(int) PyUnicodeDecodeError_SetEnd(PyObject *, Py_ssize_t); -PyAPI_FUNC(int) PyUnicodeTranslateError_SetEnd(PyObject *, Py_ssize_t); - -/* get the value of the reason attribute */ -PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetReason(PyObject *); -PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetReason(PyObject *); -PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetReason(PyObject *); - -/* assign a new value to the reason attribute - return 0 on success, -1 on failure */ -PyAPI_FUNC(int) PyUnicodeEncodeError_SetReason( - PyObject *exc, - const char *reason /* UTF-8 encoded string */ - ); -PyAPI_FUNC(int) PyUnicodeDecodeError_SetReason( - PyObject *exc, - const char *reason /* UTF-8 encoded string */ - ); -PyAPI_FUNC(int) PyUnicodeTranslateError_SetReason( - PyObject *exc, - const char *reason /* UTF-8 encoded string */ - ); - -PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...) - Py_GCC_ATTRIBUTE((format(printf, 3, 4))); -PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) - Py_GCC_ATTRIBUTE((format(printf, 3, 0))); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_ERRORS_H -# include "cpython/pyerrors.h" -# undef Py_CPYTHON_ERRORS_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_ERRORS_H */ diff --git a/python/include/pyexpat.h b/python/include/pyexpat.h deleted file mode 100644 index 5f5d381..0000000 --- a/python/include/pyexpat.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Stuff to export relevant 'expat' entry points from pyexpat to other - * parser modules, such as cElementTree. */ - -/* note: you must import expat.h before importing this module! */ - -#define PyExpat_CAPI_MAGIC "pyexpat.expat_CAPI 1.1" -#define PyExpat_CAPSULE_NAME "pyexpat.expat_CAPI" - -struct PyExpat_CAPI -{ - char* magic; /* set to PyExpat_CAPI_MAGIC */ - int size; /* set to sizeof(struct PyExpat_CAPI) */ - int MAJOR_VERSION; - int MINOR_VERSION; - int MICRO_VERSION; - /* pointers to selected expat functions. add new functions at - the end, if needed */ - const XML_LChar * (*ErrorString)(enum XML_Error code); - enum XML_Error (*GetErrorCode)(XML_Parser parser); - XML_Size (*GetErrorColumnNumber)(XML_Parser parser); - XML_Size (*GetErrorLineNumber)(XML_Parser parser); - enum XML_Status (*Parse)( - XML_Parser parser, const char *s, int len, int isFinal); - XML_Parser (*ParserCreate_MM)( - const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, - const XML_Char *namespaceSeparator); - void (*ParserFree)(XML_Parser parser); - void (*SetCharacterDataHandler)( - XML_Parser parser, XML_CharacterDataHandler handler); - void (*SetCommentHandler)( - XML_Parser parser, XML_CommentHandler handler); - void (*SetDefaultHandlerExpand)( - XML_Parser parser, XML_DefaultHandler handler); - void (*SetElementHandler)( - XML_Parser parser, XML_StartElementHandler start, - XML_EndElementHandler end); - void (*SetNamespaceDeclHandler)( - XML_Parser parser, XML_StartNamespaceDeclHandler start, - XML_EndNamespaceDeclHandler end); - void (*SetProcessingInstructionHandler)( - XML_Parser parser, XML_ProcessingInstructionHandler handler); - void (*SetUnknownEncodingHandler)( - XML_Parser parser, XML_UnknownEncodingHandler handler, - void *encodingHandlerData); - void (*SetUserData)(XML_Parser parser, void *userData); - void (*SetStartDoctypeDeclHandler)(XML_Parser parser, - XML_StartDoctypeDeclHandler start); - enum XML_Status (*SetEncoding)(XML_Parser parser, const XML_Char *encoding); - int (*DefaultUnknownEncodingHandler)( - void *encodingHandlerData, const XML_Char *name, XML_Encoding *info); - /* might be none for expat < 2.1.0 */ - int (*SetHashSalt)(XML_Parser parser, unsigned long hash_salt); - /* always add new stuff to the end! */ -}; - diff --git a/python/include/pyframe.h b/python/include/pyframe.h deleted file mode 100644 index 9d9c169..0000000 --- a/python/include/pyframe.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Limited C API of PyFrame API - * - * Include "frameobject.h" to get the PyFrameObject structure. - */ - -#ifndef Py_PYFRAME_H -#define Py_PYFRAME_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Return the line of code the frame is currently executing. */ -PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *); - -PyAPI_FUNC(PyCodeObject *) PyFrame_GetCode(PyFrameObject *frame); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_PYFRAME_H -# include "cpython/pyframe.h" -# undef Py_CPYTHON_PYFRAME_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PYFRAME_H */ diff --git a/python/include/pyhash.h b/python/include/pyhash.h deleted file mode 100644 index f47706a..0000000 --- a/python/include/pyhash.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef Py_HASH_H - -#define Py_HASH_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Helpers for hash functions */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(Py_hash_t) _Py_HashDouble(PyObject *, double); -PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*); -// Similar to _Py_HashPointer(), but don't replace -1 with -2 -PyAPI_FUNC(Py_hash_t) _Py_HashPointerRaw(const void*); -PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); -#endif - -/* Prime multiplier used in string and various other hashes. */ -#define _PyHASH_MULTIPLIER 1000003UL /* 0xf4243 */ - -/* Parameters used for the numeric hash implementation. See notes for - _Py_HashDouble in Python/pyhash.c. Numeric hashes are based on - reduction modulo the prime 2**_PyHASH_BITS - 1. */ - -#if SIZEOF_VOID_P >= 8 -# define _PyHASH_BITS 61 -#else -# define _PyHASH_BITS 31 -#endif - -#define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1) -#define _PyHASH_INF 314159 -#define _PyHASH_IMAG _PyHASH_MULTIPLIER - - -/* hash secret - * - * memory layout on 64 bit systems - * cccccccc cccccccc cccccccc uc -- unsigned char[24] - * pppppppp ssssssss ........ fnv -- two Py_hash_t - * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t - * ........ ........ ssssssss djbx33a -- 16 bytes padding + one Py_hash_t - * ........ ........ eeeeeeee pyexpat XML hash salt - * - * memory layout on 32 bit systems - * cccccccc cccccccc cccccccc uc - * ppppssss ........ ........ fnv -- two Py_hash_t - * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t (*) - * ........ ........ ssss.... djbx33a -- 16 bytes padding + one Py_hash_t - * ........ ........ eeee.... pyexpat XML hash salt - * - * (*) The siphash member may not be available on 32 bit platforms without - * an unsigned int64 data type. - */ -#ifndef Py_LIMITED_API -typedef union { - /* ensure 24 bytes */ - unsigned char uc[24]; - /* two Py_hash_t for FNV */ - struct { - Py_hash_t prefix; - Py_hash_t suffix; - } fnv; - /* two uint64 for SipHash24 */ - struct { - uint64_t k0; - uint64_t k1; - } siphash; - /* a different (!) Py_hash_t for small string optimization */ - struct { - unsigned char padding[16]; - Py_hash_t suffix; - } djbx33a; - struct { - unsigned char padding[16]; - Py_hash_t hashsalt; - } expat; -} _Py_HashSecret_t; -PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; - -#ifdef Py_DEBUG -PyAPI_DATA(int) _Py_HashSecret_Initialized; -#endif - - -/* hash function definition */ -typedef struct { - Py_hash_t (*const hash)(const void *, Py_ssize_t); - const char *name; - const int hash_bits; - const int seed_bits; -} PyHash_FuncDef; - -PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void); -#endif - - -/* cutoff for small string DJBX33A optimization in range [1, cutoff). - * - * About 50% of the strings in a typical Python application are smaller than - * 6 to 7 chars. However DJBX33A is vulnerable to hash collision attacks. - * NEVER use DJBX33A for long strings! - * - * A Py_HASH_CUTOFF of 0 disables small string optimization. 32 bit platforms - * should use a smaller cutoff because it is easier to create colliding - * strings. A cutoff of 7 on 64bit platforms and 5 on 32bit platforms should - * provide a decent safety margin. - */ -#ifndef Py_HASH_CUTOFF -# define Py_HASH_CUTOFF 0 -#elif (Py_HASH_CUTOFF > 7 || Py_HASH_CUTOFF < 0) -# error Py_HASH_CUTOFF must in range 0...7. -#endif /* Py_HASH_CUTOFF */ - - -/* hash algorithm selection - * - * The values for Py_HASH_* are hard-coded in the - * configure script. - * - * - FNV and SIPHASH* are available on all platforms and architectures. - * - With EXTERNAL embedders can provide an alternative implementation with:: - * - * PyHash_FuncDef PyHash_Func = {...}; - * - * XXX: Figure out __declspec() for extern PyHash_FuncDef. - */ -#define Py_HASH_EXTERNAL 0 -#define Py_HASH_SIPHASH24 1 -#define Py_HASH_FNV 2 -#define Py_HASH_SIPHASH13 3 - -#ifndef Py_HASH_ALGORITHM -# ifndef HAVE_ALIGNED_REQUIRED -# define Py_HASH_ALGORITHM Py_HASH_SIPHASH13 -# else -# define Py_HASH_ALGORITHM Py_HASH_FNV -# endif /* uint64_t && uint32_t && aligned */ -#endif /* Py_HASH_ALGORITHM */ - -#ifdef __cplusplus -} -#endif - -#endif /* !Py_HASH_H */ diff --git a/python/include/pylifecycle.h b/python/include/pylifecycle.h deleted file mode 100644 index b1bdcaf..0000000 --- a/python/include/pylifecycle.h +++ /dev/null @@ -1,78 +0,0 @@ - -/* Interfaces to configure, query, create & destroy the Python runtime */ - -#ifndef Py_PYLIFECYCLE_H -#define Py_PYLIFECYCLE_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* Initialization and finalization */ -PyAPI_FUNC(void) Py_Initialize(void); -PyAPI_FUNC(void) Py_InitializeEx(int); -PyAPI_FUNC(void) Py_Finalize(void); -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 -PyAPI_FUNC(int) Py_FinalizeEx(void); -#endif -PyAPI_FUNC(int) Py_IsInitialized(void); - -/* Subinterpreter support */ -PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void); -PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *); - - -/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level - * exit functions. - */ -PyAPI_FUNC(int) Py_AtExit(void (*func)(void)); - -PyAPI_FUNC(void) _Py_NO_RETURN Py_Exit(int); - -/* Bootstrap __main__ (defined in Modules/main.c) */ -PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); -PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv); - -/* In pathconfig.c */ -Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *); -PyAPI_FUNC(wchar_t *) Py_GetProgramName(void); - -Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *); -PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void); - -PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void); - -PyAPI_FUNC(wchar_t *) Py_GetPrefix(void); -PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void); -PyAPI_FUNC(wchar_t *) Py_GetPath(void); -Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetPath(const wchar_t *); -#ifdef MS_WINDOWS -int _Py_CheckPython3(void); -#endif - -/* In their own files */ -PyAPI_FUNC(const char *) Py_GetVersion(void); -PyAPI_FUNC(const char *) Py_GetPlatform(void); -PyAPI_FUNC(const char *) Py_GetCopyright(void); -PyAPI_FUNC(const char *) Py_GetCompiler(void); -PyAPI_FUNC(const char *) Py_GetBuildInfo(void); - -/* Signals */ -typedef void (*PyOS_sighandler_t)(int); -PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int); -PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030B0000 -PyAPI_DATA(const unsigned long) Py_Version; -#endif - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_PYLIFECYCLE_H -# include "cpython/pylifecycle.h" -# undef Py_CPYTHON_PYLIFECYCLE_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PYLIFECYCLE_H */ diff --git a/python/include/pymacconfig.h b/python/include/pymacconfig.h deleted file mode 100644 index a1eccea..0000000 --- a/python/include/pymacconfig.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef PYMACCONFIG_H -#define PYMACCONFIG_H - /* - * This file moves some of the autoconf magic to compile-time - * when building on MacOSX. This is needed for building 4-way - * universal binaries and for 64-bit universal binaries because - * the values redefined below aren't configure-time constant but - * only compile-time constant in these scenarios. - */ - -#if defined(__APPLE__) - -# undef SIZEOF_LONG -# undef SIZEOF_PTHREAD_T -# undef SIZEOF_SIZE_T -# undef SIZEOF_TIME_T -# undef SIZEOF_VOID_P -# undef SIZEOF__BOOL -# undef SIZEOF_UINTPTR_T -# undef SIZEOF_PTHREAD_T -# undef WORDS_BIGENDIAN -# undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 -# undef DOUBLE_IS_BIG_ENDIAN_IEEE754 -# undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 -# undef HAVE_GCC_ASM_FOR_X87 - -# undef VA_LIST_IS_ARRAY -# if defined(__LP64__) && defined(__x86_64__) -# define VA_LIST_IS_ARRAY 1 -# endif - -# undef HAVE_LARGEFILE_SUPPORT -# ifndef __LP64__ -# define HAVE_LARGEFILE_SUPPORT 1 -# endif - -# undef SIZEOF_LONG -# ifdef __LP64__ -# define SIZEOF__BOOL 1 -# define SIZEOF__BOOL 1 -# define SIZEOF_LONG 8 -# define SIZEOF_PTHREAD_T 8 -# define SIZEOF_SIZE_T 8 -# define SIZEOF_TIME_T 8 -# define SIZEOF_VOID_P 8 -# define SIZEOF_UINTPTR_T 8 -# define SIZEOF_PTHREAD_T 8 -# else -# ifdef __ppc__ -# define SIZEOF__BOOL 4 -# else -# define SIZEOF__BOOL 1 -# endif -# define SIZEOF_LONG 4 -# define SIZEOF_PTHREAD_T 4 -# define SIZEOF_SIZE_T 4 -# define SIZEOF_TIME_T 4 -# define SIZEOF_VOID_P 4 -# define SIZEOF_UINTPTR_T 4 -# define SIZEOF_PTHREAD_T 4 -# endif - -# if defined(__LP64__) - /* MacOSX 10.4 (the first release to support 64-bit code - * at all) only supports 64-bit in the UNIX layer. - * Therefore suppress the toolbox-glue in 64-bit mode. - */ - - /* In 64-bit mode setpgrp always has no arguments, in 32-bit - * mode that depends on the compilation environment - */ -# undef SETPGRP_HAVE_ARG - -# endif - -#ifdef __BIG_ENDIAN__ -#define WORDS_BIGENDIAN 1 -#define DOUBLE_IS_BIG_ENDIAN_IEEE754 -#else -#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 -#endif /* __BIG_ENDIAN */ - -#ifdef __i386__ -# define HAVE_GCC_ASM_FOR_X87 -#endif - - /* - * The definition in pyconfig.h is only valid on the OS release - * where configure ran on and not necessarily for all systems where - * the executable can be used on. - * - * Specifically: OSX 10.4 has limited supported for '%zd', while - * 10.5 has full support for '%zd'. A binary built on 10.5 won't - * work properly on 10.4 unless we suppress the definition - * of PY_FORMAT_SIZE_T - */ -#undef PY_FORMAT_SIZE_T - - -#endif /* defined(_APPLE__) */ - -#endif /* PYMACCONFIG_H */ diff --git a/python/include/pymacro.h b/python/include/pymacro.h deleted file mode 100644 index c7b7921..0000000 --- a/python/include/pymacro.h +++ /dev/null @@ -1,155 +0,0 @@ -#ifndef Py_PYMACRO_H -#define Py_PYMACRO_H - -// gh-91782: On FreeBSD 12, if the _POSIX_C_SOURCE and _XOPEN_SOURCE macros are -// defined, disables C11 support and does not define -// the static_assert() macro. Define the static_assert() macro in Python until -// suports C11: -// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=255290 -#if defined(__FreeBSD__) && !defined(static_assert) -# define static_assert _Static_assert -#endif - -// static_assert is defined in glibc from version 2.16. Before it requires -// compiler support (gcc >= 4.6) and is called _Static_assert. -// In C++ 11 static_assert is a keyword, redefining is undefined behaviour. -#if (defined(__GLIBC__) \ - && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 16)) \ - && !(defined(__cplusplus) && __cplusplus >= 201103L) \ - && !defined(static_assert)) -# define static_assert _Static_assert -#endif - -/* Minimum value between x and y */ -#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x)) - -/* Maximum value between x and y */ -#define Py_MAX(x, y) (((x) > (y)) ? (x) : (y)) - -/* Absolute value of the number x */ -#define Py_ABS(x) ((x) < 0 ? -(x) : (x)) - -#define _Py_XSTRINGIFY(x) #x - -/* Convert the argument to a string. For example, Py_STRINGIFY(123) is replaced - with "123" by the preprocessor. Defines are also replaced by their value. - For example Py_STRINGIFY(__LINE__) is replaced by the line number, not - by "__LINE__". */ -#define Py_STRINGIFY(x) _Py_XSTRINGIFY(x) - -/* Get the size of a structure member in bytes */ -#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) - -/* Argument must be a char or an int in [-128, 127] or [0, 255]. */ -#define Py_CHARMASK(c) ((unsigned char)((c) & 0xff)) - -/* Assert a build-time dependency, as an expression. - - Your compile will fail if the condition isn't true, or can't be evaluated - by the compiler. This can be used in an expression: its value is 0. - - Example: - - #define foo_to_char(foo) \ - ((char *)(foo) \ - + Py_BUILD_ASSERT_EXPR(offsetof(struct foo, string) == 0)) - - Written by Rusty Russell, public domain, http://ccodearchive.net/ */ -#define Py_BUILD_ASSERT_EXPR(cond) \ - (sizeof(char [1 - 2*!(cond)]) - 1) - -#define Py_BUILD_ASSERT(cond) do { \ - (void)Py_BUILD_ASSERT_EXPR(cond); \ - } while(0) - -/* Get the number of elements in a visible array - - This does not work on pointers, or arrays declared as [], or function - parameters. With correct compiler support, such usage will cause a build - error (see Py_BUILD_ASSERT_EXPR). - - Written by Rusty Russell, public domain, http://ccodearchive.net/ - - Requires at GCC 3.1+ */ -#if (defined(__GNUC__) && !defined(__STRICT_ANSI__) && \ - (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ >= 4))) -/* Two gcc extensions. - &a[0] degrades to a pointer: a different type from an array */ -#define Py_ARRAY_LENGTH(array) \ - (sizeof(array) / sizeof((array)[0]) \ - + Py_BUILD_ASSERT_EXPR(!__builtin_types_compatible_p(typeof(array), \ - typeof(&(array)[0])))) -#else -#define Py_ARRAY_LENGTH(array) \ - (sizeof(array) / sizeof((array)[0])) -#endif - - -/* Define macros for inline documentation. */ -#define PyDoc_VAR(name) static const char name[] -#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str) -#ifdef WITH_DOC_STRINGS -#define PyDoc_STR(str) str -#else -#define PyDoc_STR(str) "" -#endif - -/* Below "a" is a power of 2. */ -/* Round down size "n" to be a multiple of "a". */ -#define _Py_SIZE_ROUND_DOWN(n, a) ((size_t)(n) & ~(size_t)((a) - 1)) -/* Round up size "n" to be a multiple of "a". */ -#define _Py_SIZE_ROUND_UP(n, a) (((size_t)(n) + \ - (size_t)((a) - 1)) & ~(size_t)((a) - 1)) -/* Round pointer "p" down to the closest "a"-aligned address <= "p". */ -#define _Py_ALIGN_DOWN(p, a) ((void *)((uintptr_t)(p) & ~(uintptr_t)((a) - 1))) -/* Round pointer "p" up to the closest "a"-aligned address >= "p". */ -#define _Py_ALIGN_UP(p, a) ((void *)(((uintptr_t)(p) + \ - (uintptr_t)((a) - 1)) & ~(uintptr_t)((a) - 1))) -/* Check if pointer "p" is aligned to "a"-bytes boundary. */ -#define _Py_IS_ALIGNED(p, a) (!((uintptr_t)(p) & (uintptr_t)((a) - 1))) - -/* Use this for unused arguments in a function definition to silence compiler - * warnings. Example: - * - * int func(int a, int Py_UNUSED(b)) { return a; } - */ -#if defined(__GNUC__) || defined(__clang__) -# define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) -#else -# define Py_UNUSED(name) _unused_ ## name -#endif - -#if defined(RANDALL_WAS_HERE) -# define Py_UNREACHABLE() \ - Py_FatalError( \ - "If you're seeing this, the code is in what I thought was\n" \ - "an unreachable state.\n\n" \ - "I could give you advice for what to do, but honestly, why\n" \ - "should you trust me? I clearly screwed this up. I'm writing\n" \ - "a message that should never appear, yet I know it will\n" \ - "probably appear someday.\n\n" \ - "On a deep level, I know I'm not up to this task.\n" \ - "I'm so sorry.\n" \ - "https://xkcd.com/2200") -#elif defined(Py_DEBUG) -# define Py_UNREACHABLE() \ - Py_FatalError( \ - "We've reached an unreachable state. Anything is possible.\n" \ - "The limits were in our heads all along. Follow your dreams.\n" \ - "https://xkcd.com/2200") -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) -# define Py_UNREACHABLE() __builtin_unreachable() -#elif defined(__clang__) || defined(__INTEL_COMPILER) -# define Py_UNREACHABLE() __builtin_unreachable() -#elif defined(_MSC_VER) -# define Py_UNREACHABLE() __assume(0) -#else -# define Py_UNREACHABLE() \ - Py_FatalError("Unreachable C code path reached") -#endif - -// Prevent using an expression as a l-value. -// For example, "int x; _Py_RVALUE(x) = 1;" fails with a compiler error. -#define _Py_RVALUE(EXPR) ((void)0, (EXPR)) - -#endif /* Py_PYMACRO_H */ diff --git a/python/include/pymath.h b/python/include/pymath.h deleted file mode 100644 index b0ec907..0000000 --- a/python/include/pymath.h +++ /dev/null @@ -1,65 +0,0 @@ -// Symbols and macros to supply platform-independent interfaces to mathematical -// functions and constants. - -#ifndef Py_PYMATH_H -#define Py_PYMATH_H - -/* High precision definition of pi and e (Euler) - * The values are taken from libc6's math.h. - */ -#ifndef Py_MATH_PIl -#define Py_MATH_PIl 3.1415926535897932384626433832795029L -#endif -#ifndef Py_MATH_PI -#define Py_MATH_PI 3.14159265358979323846 -#endif - -#ifndef Py_MATH_El -#define Py_MATH_El 2.7182818284590452353602874713526625L -#endif - -#ifndef Py_MATH_E -#define Py_MATH_E 2.7182818284590452354 -#endif - -/* Tau (2pi) to 40 digits, taken from tauday.com/tau-digits. */ -#ifndef Py_MATH_TAU -#define Py_MATH_TAU 6.2831853071795864769252867665590057683943L -#endif - -// Py_IS_NAN(X) -// Return 1 if float or double arg is a NaN, else 0. -#define Py_IS_NAN(X) isnan(X) - -// Py_IS_INFINITY(X) -// Return 1 if float or double arg is an infinity, else 0. -#define Py_IS_INFINITY(X) isinf(X) - -// Py_IS_FINITE(X) -// Return 1 if float or double arg is neither infinite nor NAN, else 0. -#define Py_IS_FINITE(X) isfinite(X) - -/* HUGE_VAL is supposed to expand to a positive double infinity. Python - * uses Py_HUGE_VAL instead because some platforms are broken in this - * respect. We used to embed code in pyport.h to try to worm around that, - * but different platforms are broken in conflicting ways. If you're on - * a platform where HUGE_VAL is defined incorrectly, fiddle your Python - * config to #define Py_HUGE_VAL to something that works on your platform. - */ -#ifndef Py_HUGE_VAL -# define Py_HUGE_VAL HUGE_VAL -#endif - -// Py_NAN: Value that evaluates to a quiet Not-a-Number (NaN). -#if !defined(Py_NAN) -# if _Py__has_builtin(__builtin_nan) - // Built-in implementation of the ISO C99 function nan(): quiet NaN. -# define Py_NAN (__builtin_nan("")) -#else - // Use C99 NAN constant: quiet Not-A-Number. - // NAN is a float, Py_NAN is a double: cast to double. -# define Py_NAN ((double)NAN) -# endif -#endif - -#endif /* Py_PYMATH_H */ diff --git a/python/include/pymem.h b/python/include/pymem.h deleted file mode 100644 index 10b2538..0000000 --- a/python/include/pymem.h +++ /dev/null @@ -1,104 +0,0 @@ -/* The PyMem_ family: low-level memory allocation interfaces. - See objimpl.h for the PyObject_ memory family. -*/ - -#ifndef Py_PYMEM_H -#define Py_PYMEM_H - -#include "pyport.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEWARE: - - Each interface exports both functions and macros. Extension modules should - use the functions, to ensure binary compatibility across Python versions. - Because the Python implementation is free to change internal details, and - the macros may (or may not) expose details for speed, if you do use the - macros you must recompile your extensions with each Python release. - - Never mix calls to PyMem_ with calls to the platform malloc/realloc/ - calloc/free. For example, on Windows different DLLs may end up using - different heaps, and if you use PyMem_Malloc you'll get the memory from the - heap used by the Python DLL; it could be a disaster if you free()'ed that - directly in your own extension. Using PyMem_Free instead ensures Python - can return the memory to the proper heap. As another example, in - a debug build (Py_DEBUG macro), Python wraps all calls to all PyMem_ and - PyObject_ memory functions in special debugging wrappers that add additional - debugging info to dynamic memory blocks. The system routines have no idea - what to do with that stuff, and the Python wrappers have no idea what to do - with raw blocks obtained directly by the system routines then. - - The GIL must be held when using these APIs. -*/ - -/* - * Raw memory interface - * ==================== - */ - -/* Functions - - Functions supplying platform-independent semantics for malloc/realloc/ - free. These functions make sure that allocating 0 bytes returns a distinct - non-NULL pointer (whenever possible -- if we're flat out of memory, NULL - may be returned), even if the platform malloc and realloc don't. - Returned pointers must be checked for NULL explicitly. No action is - performed on failure (no exception is set, no warning is printed, etc). -*/ - -PyAPI_FUNC(void *) PyMem_Malloc(size_t size); -PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); -PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size); -PyAPI_FUNC(void) PyMem_Free(void *ptr); - -/* - * Type-oriented memory interface - * ============================== - * - * Allocate memory for n objects of the given type. Returns a new pointer - * or NULL if the request was too large or memory allocation failed. Use - * these macros rather than doing the multiplication yourself so that proper - * overflow checking is always done. - */ - -#define PyMem_New(type, n) \ - ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ - ( (type *) PyMem_Malloc((n) * sizeof(type)) ) ) - -/* - * The value of (p) is always clobbered by this macro regardless of success. - * The caller MUST check if (p) is NULL afterwards and deal with the memory - * error if so. This means the original value of (p) MUST be saved for the - * caller's memory error handler to not lose track of it. - */ -#define PyMem_Resize(p, type, n) \ - ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ - (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) - - -// Deprecated aliases only kept for backward compatibility. -// PyMem_Del and PyMem_DEL are defined with no parameter to be able to use -// them as function pointers (ex: dealloc = PyMem_Del). -#define PyMem_MALLOC(n) PyMem_Malloc(n) -#define PyMem_NEW(type, n) PyMem_New(type, n) -#define PyMem_REALLOC(p, n) PyMem_Realloc(p, n) -#define PyMem_RESIZE(p, type, n) PyMem_Resize(p, type, n) -#define PyMem_FREE(p) PyMem_Free(p) -#define PyMem_Del PyMem_Free -#define PyMem_DEL PyMem_Free - - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_PYMEM_H -# include "cpython/pymem.h" -# undef Py_CPYTHON_PYMEM_H -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* !Py_PYMEM_H */ diff --git a/python/include/pyport.h b/python/include/pyport.h deleted file mode 100644 index 2bd3d64..0000000 --- a/python/include/pyport.h +++ /dev/null @@ -1,742 +0,0 @@ -#ifndef Py_PYPORT_H -#define Py_PYPORT_H - -#include "pyconfig.h" /* include for defines */ - -#include - -#include -#ifndef UCHAR_MAX -# error "limits.h must define UCHAR_MAX" -#endif -#if UCHAR_MAX != 255 -# error "Python's source code assumes C's unsigned char is an 8-bit type" -#endif - - -// Macro to use C++ static_cast<> in the Python C API. -#ifdef __cplusplus -# define _Py_STATIC_CAST(type, expr) static_cast(expr) -#else -# define _Py_STATIC_CAST(type, expr) ((type)(expr)) -#endif -// Macro to use the more powerful/dangerous C-style cast even in C++. -#define _Py_CAST(type, expr) ((type)(expr)) - -// Static inline functions should use _Py_NULL rather than using directly NULL -// to prevent C++ compiler warnings. On C++11 and newer, _Py_NULL is defined as -// nullptr. -#if defined(__cplusplus) && __cplusplus >= 201103 -# define _Py_NULL nullptr -#else -# define _Py_NULL NULL -#endif - - -/* Defines to build Python and its standard library: - * - * - Py_BUILD_CORE: Build Python core. Give access to Python internals, but - * should not be used by third-party modules. - * - Py_BUILD_CORE_BUILTIN: Build a Python stdlib module as a built-in module. - * - Py_BUILD_CORE_MODULE: Build a Python stdlib module as a dynamic library. - * - * Py_BUILD_CORE_BUILTIN and Py_BUILD_CORE_MODULE imply Py_BUILD_CORE. - * - * On Windows, Py_BUILD_CORE_MODULE exports "PyInit_xxx" symbol, whereas - * Py_BUILD_CORE_BUILTIN does not. - */ -#if defined(Py_BUILD_CORE_BUILTIN) && !defined(Py_BUILD_CORE) -# define Py_BUILD_CORE -#endif -#if defined(Py_BUILD_CORE_MODULE) && !defined(Py_BUILD_CORE) -# define Py_BUILD_CORE -#endif - - -/************************************************************************** -Symbols and macros to supply platform-independent interfaces to basic -C language & library operations whose spellings vary across platforms. - -Please try to make documentation here as clear as possible: by definition, -the stuff here is trying to illuminate C's darkest corners. - -Config #defines referenced here: - -SIGNED_RIGHT_SHIFT_ZERO_FILLS -Meaning: To be defined iff i>>j does not extend the sign bit when i is a - signed integral type and i < 0. -Used in: Py_ARITHMETIC_RIGHT_SHIFT - -Py_DEBUG -Meaning: Extra checks compiled in for debug mode. -Used in: Py_SAFE_DOWNCAST - -**************************************************************************/ - -/* typedefs for some C9X-defined synonyms for integral types. - * - * The names in Python are exactly the same as the C9X names, except with a - * Py_ prefix. Until C9X is universally implemented, this is the only way - * to ensure that Python gets reliable names that don't conflict with names - * in non-Python code that are playing their own tricks to define the C9X - * names. - * - * NOTE: don't go nuts here! Python has no use for *most* of the C9X - * integral synonyms. Only define the ones we actually need. - */ - -/* long long is required. Ensure HAVE_LONG_LONG is defined for compatibility. */ -#ifndef HAVE_LONG_LONG -#define HAVE_LONG_LONG 1 -#endif -#ifndef PY_LONG_LONG -#define PY_LONG_LONG long long -/* If LLONG_MAX is defined in limits.h, use that. */ -#define PY_LLONG_MIN LLONG_MIN -#define PY_LLONG_MAX LLONG_MAX -#define PY_ULLONG_MAX ULLONG_MAX -#endif - -#define PY_UINT32_T uint32_t -#define PY_UINT64_T uint64_t - -/* Signed variants of the above */ -#define PY_INT32_T int32_t -#define PY_INT64_T int64_t - -/* PYLONG_BITS_IN_DIGIT describes the number of bits per "digit" (limb) in the - * PyLongObject implementation (longintrepr.h). It's currently either 30 or 15, - * defaulting to 30. The 15-bit digit option may be removed in the future. - */ -#ifndef PYLONG_BITS_IN_DIGIT -#define PYLONG_BITS_IN_DIGIT 30 -#endif - -/* uintptr_t is the C9X name for an unsigned integral type such that a - * legitimate void* can be cast to uintptr_t and then back to void* again - * without loss of information. Similarly for intptr_t, wrt a signed - * integral type. - */ -typedef uintptr_t Py_uintptr_t; -typedef intptr_t Py_intptr_t; - -/* Py_ssize_t is a signed integral type such that sizeof(Py_ssize_t) == - * sizeof(size_t). C99 doesn't define such a thing directly (size_t is an - * unsigned integral type). See PEP 353 for details. - * PY_SSIZE_T_MAX is the largest positive value of type Py_ssize_t. - */ -#ifdef HAVE_PY_SSIZE_T - -#elif HAVE_SSIZE_T -typedef ssize_t Py_ssize_t; -# define PY_SSIZE_T_MAX SSIZE_MAX -#elif SIZEOF_VOID_P == SIZEOF_SIZE_T -typedef Py_intptr_t Py_ssize_t; -# define PY_SSIZE_T_MAX INTPTR_MAX -#else -# error "Python needs a typedef for Py_ssize_t in pyport.h." -#endif - -/* Smallest negative value of type Py_ssize_t. */ -#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1) - -/* Py_hash_t is the same size as a pointer. */ -#define SIZEOF_PY_HASH_T SIZEOF_SIZE_T -typedef Py_ssize_t Py_hash_t; -/* Py_uhash_t is the unsigned equivalent needed to calculate numeric hash. */ -#define SIZEOF_PY_UHASH_T SIZEOF_SIZE_T -typedef size_t Py_uhash_t; - -/* Now PY_SSIZE_T_CLEAN is mandatory. This is just for backward compatibility. */ -typedef Py_ssize_t Py_ssize_clean_t; - -/* Largest possible value of size_t. */ -#define PY_SIZE_MAX SIZE_MAX - -/* Macro kept for backward compatibility: use "z" in new code. - * - * PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf - * format to convert an argument with the width of a size_t or Py_ssize_t. - * C99 introduced "z" for this purpose, but old MSVCs had not supported it. - * Since MSVC supports "z" since (at least) 2015, we can just use "z" - * for new code. - * - * These "high level" Python format functions interpret "z" correctly on - * all platforms (Python interprets the format string itself, and does whatever - * the platform C requires to convert a size_t/Py_ssize_t argument): - * - * PyBytes_FromFormat - * PyErr_Format - * PyBytes_FromFormatV - * PyUnicode_FromFormatV - * - * Lower-level uses require that you interpolate the correct format modifier - * yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for - * example, - * - * Py_ssize_t index; - * fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index); - * - * That will expand to %zd or to something else correct for a Py_ssize_t on - * the platform. - */ -#ifndef PY_FORMAT_SIZE_T -# define PY_FORMAT_SIZE_T "z" -#endif - -/* Py_LOCAL can be used instead of static to get the fastest possible calling - * convention for functions that are local to a given module. - * - * Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining, - * for platforms that support that. - * - * NOTE: You can only use this for functions that are entirely local to a - * module; functions that are exported via method tables, callbacks, etc, - * should keep using static. - */ - -#if defined(_MSC_VER) - /* ignore warnings if the compiler decides not to inline a function */ -# pragma warning(disable: 4710) - /* fastest possible local call under MSVC */ -# define Py_LOCAL(type) static type __fastcall -# define Py_LOCAL_INLINE(type) static __inline type __fastcall -#else -# define Py_LOCAL(type) static type -# define Py_LOCAL_INLINE(type) static inline type -#endif - -// bpo-28126: Py_MEMCPY is kept for backwards compatibility, -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_MEMCPY memcpy -#endif - -#ifdef HAVE_IEEEFP_H -#include /* needed for 'finite' declaration on some platforms */ -#endif - -#include /* Moved here from the math section, before extern "C" */ - -/******************************************** - * WRAPPER FOR and/or * - ********************************************/ - -#ifdef HAVE_SYS_TIME_H -#include -#endif -#include - -/****************************** - * WRAPPER FOR * - ******************************/ - -/* NB caller must include */ - -#ifdef HAVE_SYS_SELECT_H -#include -#endif /* !HAVE_SYS_SELECT_H */ - -/******************************* - * stat() and fstat() fiddling * - *******************************/ - -#ifdef HAVE_SYS_STAT_H -#include -#elif defined(HAVE_STAT_H) -#include -#endif - -#ifndef S_IFMT -/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */ -#define S_IFMT 0170000 -#endif - -#ifndef S_IFLNK -/* Windows doesn't define S_IFLNK but posixmodule.c maps - * IO_REPARSE_TAG_SYMLINK to S_IFLNK */ -# define S_IFLNK 0120000 -#endif - -#ifndef S_ISREG -#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) -#endif - -#ifndef S_ISDIR -#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) -#endif - -#ifndef S_ISCHR -#define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR) -#endif - -#ifdef __cplusplus -/* Move this down here since some C++ #include's don't like to be included - inside an extern "C" */ -extern "C" { -#endif - - -/* Py_ARITHMETIC_RIGHT_SHIFT - * C doesn't define whether a right-shift of a signed integer sign-extends - * or zero-fills. Here a macro to force sign extension: - * Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) - * Return I >> J, forcing sign extension. Arithmetically, return the - * floor of I/2**J. - * Requirements: - * I should have signed integer type. In the terminology of C99, this can - * be either one of the five standard signed integer types (signed char, - * short, int, long, long long) or an extended signed integer type. - * J is an integer >= 0 and strictly less than the number of bits in the - * type of I (because C doesn't define what happens for J outside that - * range either). - * TYPE used to specify the type of I, but is now ignored. It's been left - * in for backwards compatibility with versions <= 2.6 or 3.0. - * Caution: - * I may be evaluated more than once. - */ -#ifdef SIGNED_RIGHT_SHIFT_ZERO_FILLS -#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) \ - ((I) < 0 ? -1-((-1-(I)) >> (J)) : (I) >> (J)) -#else -#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) ((I) >> (J)) -#endif - -/* Py_FORCE_EXPANSION(X) - * "Simply" returns its argument. However, macro expansions within the - * argument are evaluated. This unfortunate trickery is needed to get - * token-pasting to work as desired in some cases. - */ -#define Py_FORCE_EXPANSION(X) X - -/* Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) - * Cast VALUE to type NARROW from type WIDE. In Py_DEBUG mode, this - * assert-fails if any information is lost. - * Caution: - * VALUE may be evaluated more than once. - */ -#ifdef Py_DEBUG -# define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \ - (assert(_Py_STATIC_CAST(WIDE, _Py_STATIC_CAST(NARROW, (VALUE))) == (VALUE)), \ - _Py_STATIC_CAST(NARROW, (VALUE))) -#else -# define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) _Py_STATIC_CAST(NARROW, (VALUE)) -#endif - - -/* Py_DEPRECATED(version) - * Declare a variable, type, or function deprecated. - * The macro must be placed before the declaration. - * Usage: - * Py_DEPRECATED(3.3) extern int old_var; - * Py_DEPRECATED(3.4) typedef int T1; - * Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void); - */ -#if defined(__GNUC__) \ - && ((__GNUC__ >= 4) || (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) -#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) -#elif defined(_MSC_VER) -#define Py_DEPRECATED(VERSION) __declspec(deprecated( \ - "deprecated in " #VERSION)) -#else -#define Py_DEPRECATED(VERSION_UNUSED) -#endif - -#if defined(__clang__) -#define _Py_COMP_DIAG_PUSH _Pragma("clang diagnostic push") -#define _Py_COMP_DIAG_IGNORE_DEPR_DECLS \ - _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") -#define _Py_COMP_DIAG_POP _Pragma("clang diagnostic pop") -#elif defined(__GNUC__) \ - && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) -#define _Py_COMP_DIAG_PUSH _Pragma("GCC diagnostic push") -#define _Py_COMP_DIAG_IGNORE_DEPR_DECLS \ - _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#define _Py_COMP_DIAG_POP _Pragma("GCC diagnostic pop") -#elif defined(_MSC_VER) -#define _Py_COMP_DIAG_PUSH __pragma(warning(push)) -#define _Py_COMP_DIAG_IGNORE_DEPR_DECLS __pragma(warning(disable: 4996)) -#define _Py_COMP_DIAG_POP __pragma(warning(pop)) -#else -#define _Py_COMP_DIAG_PUSH -#define _Py_COMP_DIAG_IGNORE_DEPR_DECLS -#define _Py_COMP_DIAG_POP -#endif - -/* _Py_HOT_FUNCTION - * The hot attribute on a function is used to inform the compiler that the - * function is a hot spot of the compiled program. The function is optimized - * more aggressively and on many target it is placed into special subsection of - * the text section so all hot functions appears close together improving - * locality. - * - * Usage: - * int _Py_HOT_FUNCTION x(void) { return 3; } - * - * Issue #28618: This attribute must not be abused, otherwise it can have a - * negative effect on performance. Only the functions were Python spend most of - * its time must use it. Use a profiler when running performance benchmark - * suite to find these functions. - */ -#if defined(__GNUC__) \ - && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) -#define _Py_HOT_FUNCTION __attribute__((hot)) -#else -#define _Py_HOT_FUNCTION -#endif - -// Ask the compiler to always inline a static inline function. The compiler can -// ignore it and decides to not inline the function. -// -// It can be used to inline performance critical static inline functions when -// building Python in debug mode with function inlining disabled. For example, -// MSC disables function inlining when building in debug mode. -// -// Marking blindly a static inline function with Py_ALWAYS_INLINE can result in -// worse performances (due to increased code size for example). The compiler is -// usually smarter than the developer for the cost/benefit analysis. -// -// If Python is built in debug mode (if the Py_DEBUG macro is defined), the -// Py_ALWAYS_INLINE macro does nothing. -// -// It must be specified before the function return type. Usage: -// -// static inline Py_ALWAYS_INLINE int random(void) { return 4; } -#if defined(Py_DEBUG) - // If Python is built in debug mode, usually compiler optimizations are - // disabled. In this case, Py_ALWAYS_INLINE can increase a lot the stack - // memory usage. For example, forcing inlining using gcc -O0 increases the - // stack usage from 6 KB to 15 KB per Python function call. -# define Py_ALWAYS_INLINE -#elif defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) -# define Py_ALWAYS_INLINE __attribute__((always_inline)) -#elif defined(_MSC_VER) -# define Py_ALWAYS_INLINE __forceinline -#else -# define Py_ALWAYS_INLINE -#endif - -// Py_NO_INLINE -// Disable inlining on a function. For example, it reduces the C stack -// consumption: useful on LTO+PGO builds which heavily inline code (see -// bpo-33720). -// -// Usage: -// -// Py_NO_INLINE static int random(void) { return 4; } -#if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER) -# define Py_NO_INLINE __attribute__ ((noinline)) -#elif defined(_MSC_VER) -# define Py_NO_INLINE __declspec(noinline) -#else -# define Py_NO_INLINE -#endif - -/************************************************************************** -Prototypes that are missing from the standard include files on some systems -(and possibly only some versions of such systems.) - -Please be conservative with adding new ones, document them and enclose them -in platform-specific #ifdefs. -**************************************************************************/ - -#ifdef SOLARIS -/* Unchecked */ -extern int gethostname(char *, int); -#endif - -#ifdef HAVE__GETPTY -#include /* we need to import mode_t */ -extern char * _getpty(int *, int, mode_t, int); -#endif - -/* On QNX 6, struct termio must be declared by including sys/termio.h - if TCGETA, TCSETA, TCSETAW, or TCSETAF are used. sys/termio.h must - be included before termios.h or it will generate an error. */ -#if defined(HAVE_SYS_TERMIO_H) && !defined(__hpux) -#include -#endif - - -/* On 4.4BSD-descendants, ctype functions serves the whole range of - * wchar_t character set rather than single byte code points only. - * This characteristic can break some operations of string object - * including str.upper() and str.split() on UTF-8 locales. This - * workaround was provided by Tim Robbins of FreeBSD project. - */ - -#if defined(__APPLE__) -# define _PY_PORT_CTYPE_UTF8_ISSUE -#endif - -#ifdef _PY_PORT_CTYPE_UTF8_ISSUE -#ifndef __cplusplus - /* The workaround below is unsafe in C++ because - * the defines these symbols as real functions, - * with a slightly different signature. - * See issue #10910 - */ -#include -#include -#undef isalnum -#define isalnum(c) iswalnum(btowc(c)) -#undef isalpha -#define isalpha(c) iswalpha(btowc(c)) -#undef islower -#define islower(c) iswlower(btowc(c)) -#undef isspace -#define isspace(c) iswspace(btowc(c)) -#undef isupper -#define isupper(c) iswupper(btowc(c)) -#undef tolower -#define tolower(c) towlower(btowc(c)) -#undef toupper -#define toupper(c) towupper(btowc(c)) -#endif -#endif - - -/* Declarations for symbol visibility. - - PyAPI_FUNC(type): Declares a public Python API function and return type - PyAPI_DATA(type): Declares public Python data and its type - PyMODINIT_FUNC: A Python module init function. If these functions are - inside the Python core, they are private to the core. - If in an extension module, it may be declared with - external linkage depending on the platform. - - As a number of platforms support/require "__declspec(dllimport/dllexport)", - we support a HAVE_DECLSPEC_DLL macro to save duplication. -*/ - -/* - All windows ports, except cygwin, are handled in PC/pyconfig.h. - - Cygwin is the only other autoconf platform requiring special - linkage handling and it uses __declspec(). -*/ -#if defined(__CYGWIN__) -# define HAVE_DECLSPEC_DLL -#endif - -#include "exports.h" - -/* only get special linkage if built as shared or platform is Cygwin */ -#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__) -# if defined(HAVE_DECLSPEC_DLL) -# if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE -# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE - /* module init functions inside the core need no external linkage */ - /* except for Cygwin to handle embedding */ -# if defined(__CYGWIN__) -# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject* -# else /* __CYGWIN__ */ -# define PyMODINIT_FUNC PyObject* -# endif /* __CYGWIN__ */ -# else /* Py_BUILD_CORE */ - /* Building an extension module, or an embedded situation */ - /* public Python functions and data are imported */ - /* Under Cygwin, auto-import functions to prevent compilation */ - /* failures similar to those described at the bottom of 4.1: */ - /* http://docs.python.org/extending/windows.html#a-cookbook-approach */ -# if !defined(__CYGWIN__) -# define PyAPI_FUNC(RTYPE) Py_IMPORTED_SYMBOL RTYPE -# endif /* !__CYGWIN__ */ -# define PyAPI_DATA(RTYPE) extern Py_IMPORTED_SYMBOL RTYPE - /* module init functions outside the core must be exported */ -# if defined(__cplusplus) -# define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject* -# else /* __cplusplus */ -# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject* -# endif /* __cplusplus */ -# endif /* Py_BUILD_CORE */ -# endif /* HAVE_DECLSPEC_DLL */ -#endif /* Py_ENABLE_SHARED */ - -/* If no external linkage macros defined by now, create defaults */ -#ifndef PyAPI_FUNC -# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE -#endif -#ifndef PyAPI_DATA -# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE -#endif -#ifndef PyMODINIT_FUNC -# if defined(__cplusplus) -# define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject* -# else /* __cplusplus */ -# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject* -# endif /* __cplusplus */ -#endif - -/* limits.h constants that may be missing */ - -#ifndef INT_MAX -#define INT_MAX 2147483647 -#endif - -#ifndef LONG_MAX -#if SIZEOF_LONG == 4 -#define LONG_MAX 0X7FFFFFFFL -#elif SIZEOF_LONG == 8 -#define LONG_MAX 0X7FFFFFFFFFFFFFFFL -#else -#error "could not set LONG_MAX in pyport.h" -#endif -#endif - -#ifndef LONG_MIN -#define LONG_MIN (-LONG_MAX-1) -#endif - -#ifndef LONG_BIT -#define LONG_BIT (8 * SIZEOF_LONG) -#endif - -#if LONG_BIT != 8 * SIZEOF_LONG -/* 04-Oct-2000 LONG_BIT is apparently (mis)defined as 64 on some recent - * 32-bit platforms using gcc. We try to catch that here at compile-time - * rather than waiting for integer multiplication to trigger bogus - * overflows. - */ -#error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)." -#endif - -#ifdef __cplusplus -} -#endif - -/* - * Hide GCC attributes from compilers that don't support them. - */ -#if (!defined(__GNUC__) || __GNUC__ < 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ) -#define Py_GCC_ATTRIBUTE(x) -#else -#define Py_GCC_ATTRIBUTE(x) __attribute__(x) -#endif - -/* - * Specify alignment on compilers that support it. - */ -#if defined(__GNUC__) && __GNUC__ >= 3 -#define Py_ALIGNED(x) __attribute__((aligned(x))) -#else -#define Py_ALIGNED(x) -#endif - -/* Eliminate end-of-loop code not reached warnings from SunPro C - * when using do{...}while(0) macros - */ -#ifdef __SUNPRO_C -#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED) -#endif - -#ifndef Py_LL -#define Py_LL(x) x##LL -#endif - -#ifndef Py_ULL -#define Py_ULL(x) Py_LL(x##U) -#endif - -#define Py_VA_COPY va_copy - -/* - * Convenient macros to deal with endianness of the platform. WORDS_BIGENDIAN is - * detected by configure and defined in pyconfig.h. The code in pyconfig.h - * also takes care of Apple's universal builds. - */ - -#ifdef WORDS_BIGENDIAN -# define PY_BIG_ENDIAN 1 -# define PY_LITTLE_ENDIAN 0 -#else -# define PY_BIG_ENDIAN 0 -# define PY_LITTLE_ENDIAN 1 -#endif - -#ifdef __ANDROID__ - /* The Android langinfo.h header is not used. */ -# undef HAVE_LANGINFO_H -# undef CODESET -#endif - -/* Maximum value of the Windows DWORD type */ -#define PY_DWORD_MAX 4294967295U - -/* This macro used to tell whether Python was built with multithreading - * enabled. Now multithreading is always enabled, but keep the macro - * for compatibility. - */ -#ifndef WITH_THREAD -# define WITH_THREAD -#endif - -/* Check that ALT_SOABI is consistent with Py_TRACE_REFS: - ./configure --with-trace-refs should must be used to define Py_TRACE_REFS */ -#if defined(ALT_SOABI) && defined(Py_TRACE_REFS) -# error "Py_TRACE_REFS ABI is not compatible with release and debug ABI" -#endif - -#if defined(__ANDROID__) || defined(__VXWORKS__) - // Use UTF-8 as the locale encoding, ignore the LC_CTYPE locale. - // See _Py_GetLocaleEncoding(), PyUnicode_DecodeLocale() - // and PyUnicode_EncodeLocale(). -# define _Py_FORCE_UTF8_LOCALE -#endif - -#if defined(_Py_FORCE_UTF8_LOCALE) || defined(__APPLE__) - // Use UTF-8 as the filesystem encoding. - // See PyUnicode_DecodeFSDefaultAndSize(), PyUnicode_EncodeFSDefault(), - // Py_DecodeLocale() and Py_EncodeLocale(). -# define _Py_FORCE_UTF8_FS_ENCODING -#endif - -/* Mark a function which cannot return. Example: - PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); - - XLC support is intentionally omitted due to bpo-40244 */ -#ifndef _Py_NO_RETURN -#if defined(__clang__) || \ - (defined(__GNUC__) && \ - ((__GNUC__ >= 3) || \ - (__GNUC__ == 2) && (__GNUC_MINOR__ >= 5))) -# define _Py_NO_RETURN __attribute__((__noreturn__)) -#elif defined(_MSC_VER) -# define _Py_NO_RETURN __declspec(noreturn) -#else -# define _Py_NO_RETURN -#endif -#endif - - -// Preprocessor check for a builtin preprocessor function. Always return 0 -// if __has_builtin() macro is not defined. -// -// __has_builtin() is available on clang and GCC 10. -#ifdef __has_builtin -# define _Py__has_builtin(x) __has_builtin(x) -#else -# define _Py__has_builtin(x) 0 -#endif - - -/* A convenient way for code to know if sanitizers are enabled. */ -#if defined(__has_feature) -# if __has_feature(memory_sanitizer) -# if !defined(_Py_MEMORY_SANITIZER) -# define _Py_MEMORY_SANITIZER -# endif -# endif -# if __has_feature(address_sanitizer) -# if !defined(_Py_ADDRESS_SANITIZER) -# define _Py_ADDRESS_SANITIZER -# endif -# endif -#elif defined(__GNUC__) -# if defined(__SANITIZE_ADDRESS__) -# define _Py_ADDRESS_SANITIZER -# endif -#endif - -#endif /* Py_PYPORT_H */ diff --git a/python/include/pystate.h b/python/include/pystate.h deleted file mode 100644 index 1af98ba..0000000 --- a/python/include/pystate.h +++ /dev/null @@ -1,132 +0,0 @@ -/* Thread and interpreter state structures and their interfaces */ - - -#ifndef Py_PYSTATE_H -#define Py_PYSTATE_H -#ifdef __cplusplus -extern "C" { -#endif - -/* This limitation is for performance and simplicity. If needed it can be -removed (with effort). */ -#define MAX_CO_EXTRA_USERS 255 - -PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void); -PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *); -PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 -/* New in 3.9 */ -/* Get the current interpreter state. - - Issue a fatal error if there no current Python thread state or no current - interpreter. It cannot return NULL. - - The caller must hold the GIL. */ -PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Get(void); -#endif - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03080000 -/* New in 3.8 */ -PyAPI_FUNC(PyObject *) PyInterpreterState_GetDict(PyInterpreterState *); -#endif - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 -/* New in 3.7 */ -PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *); -#endif -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 - -/* State unique per thread */ - -/* New in 3.3 */ -PyAPI_FUNC(int) PyState_AddModule(PyObject*, PyModuleDef*); -PyAPI_FUNC(int) PyState_RemoveModule(PyModuleDef*); -#endif -PyAPI_FUNC(PyObject*) PyState_FindModule(PyModuleDef*); - -PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *); -PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *); -PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *); - -/* Get the current thread state. - - When the current thread state is NULL, this issues a fatal error (so that - the caller needn't check for NULL). - - The caller must hold the GIL. - - See also _PyThreadState_UncheckedGet() and _PyThreadState_GET(). */ -PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void); - -// Alias to PyThreadState_Get() -#define PyThreadState_GET() PyThreadState_Get() - -PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *); -PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void); -PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 -/* New in 3.9 */ -PyAPI_FUNC(PyInterpreterState*) PyThreadState_GetInterpreter(PyThreadState *tstate); -PyAPI_FUNC(PyFrameObject*) PyThreadState_GetFrame(PyThreadState *tstate); -PyAPI_FUNC(uint64_t) PyThreadState_GetID(PyThreadState *tstate); -#endif - -typedef - enum {PyGILState_LOCKED, PyGILState_UNLOCKED} - PyGILState_STATE; - - -/* Ensure that the current thread is ready to call the Python - C API, regardless of the current state of Python, or of its - thread lock. This may be called as many times as desired - by a thread so long as each call is matched with a call to - PyGILState_Release(). In general, other thread-state APIs may - be used between _Ensure() and _Release() calls, so long as the - thread-state is restored to its previous state before the Release(). - For example, normal use of the Py_BEGIN_ALLOW_THREADS/ - Py_END_ALLOW_THREADS macros are acceptable. - - The return value is an opaque "handle" to the thread state when - PyGILState_Ensure() was called, and must be passed to - PyGILState_Release() to ensure Python is left in the same state. Even - though recursive calls are allowed, these handles can *not* be shared - - each unique call to PyGILState_Ensure must save the handle for its - call to PyGILState_Release. - - When the function returns, the current thread will hold the GIL. - - Failure is a fatal error. -*/ -PyAPI_FUNC(PyGILState_STATE) PyGILState_Ensure(void); - -/* Release any resources previously acquired. After this call, Python's - state will be the same as it was prior to the corresponding - PyGILState_Ensure() call (but generally this state will be unknown to - the caller, hence the use of the GILState API.) - - Every call to PyGILState_Ensure must be matched by a call to - PyGILState_Release on the same thread. -*/ -PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE); - -/* Helper/diagnostic function - get the current thread state for - this thread. May return NULL if no GILState API has been used - on the current thread. Note that the main thread always has such a - thread-state, even if no auto-thread-state call has been made - on the main thread. -*/ -PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void); - - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_PYSTATE_H -# include "cpython/pystate.h" -# undef Py_CPYTHON_PYSTATE_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PYSTATE_H */ diff --git a/python/include/pystrcmp.h b/python/include/pystrcmp.h deleted file mode 100644 index eccabdc..0000000 --- a/python/include/pystrcmp.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef Py_STRCMP_H -#define Py_STRCMP_H - -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_FUNC(int) PyOS_mystrnicmp(const char *, const char *, Py_ssize_t); -PyAPI_FUNC(int) PyOS_mystricmp(const char *, const char *); - -#ifdef MS_WINDOWS -#define PyOS_strnicmp strnicmp -#define PyOS_stricmp stricmp -#else -#define PyOS_strnicmp PyOS_mystrnicmp -#define PyOS_stricmp PyOS_mystricmp -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* !Py_STRCMP_H */ diff --git a/python/include/pystrtod.h b/python/include/pystrtod.h deleted file mode 100644 index 52c292d..0000000 --- a/python/include/pystrtod.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef Py_STRTOD_H -#define Py_STRTOD_H - -#ifdef __cplusplus -extern "C" { -#endif - - -PyAPI_FUNC(double) PyOS_string_to_double(const char *str, - char **endptr, - PyObject *overflow_exception); - -/* The caller is responsible for calling PyMem_Free to free the buffer - that's is returned. */ -PyAPI_FUNC(char *) PyOS_double_to_string(double val, - char format_code, - int precision, - int flags, - int *type); - -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _Py_string_to_number_with_underscores( - const char *str, Py_ssize_t len, const char *what, PyObject *obj, void *arg, - PyObject *(*innerfunc)(const char *, Py_ssize_t, void *)); - -PyAPI_FUNC(double) _Py_parse_inf_or_nan(const char *p, char **endptr); -#endif - - -/* PyOS_double_to_string's "flags" parameter can be set to 0 or more of: */ -#define Py_DTSF_SIGN 0x01 /* always add the sign */ -#define Py_DTSF_ADD_DOT_0 0x02 /* if the result is an integer add ".0" */ -#define Py_DTSF_ALT 0x04 /* "alternate" formatting. it's format_code - specific */ -#define Py_DTSF_NO_NEG_0 0x08 /* negative zero result is coerced to 0 */ - -/* PyOS_double_to_string's "type", if non-NULL, will be set to one of: */ -#define Py_DTST_FINITE 0 -#define Py_DTST_INFINITE 1 -#define Py_DTST_NAN 2 - -#ifdef __cplusplus -} -#endif - -#endif /* !Py_STRTOD_H */ diff --git a/python/include/pythonrun.h b/python/include/pythonrun.h deleted file mode 100644 index 0a896db..0000000 --- a/python/include/pythonrun.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* Interfaces to parse and execute pieces of python code */ - -#ifndef Py_PYTHONRUN_H -#define Py_PYTHONRUN_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_FUNC(PyObject *) Py_CompileString(const char *, const char *, int); - -PyAPI_FUNC(void) PyErr_Print(void); -PyAPI_FUNC(void) PyErr_PrintEx(int); -PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *); - - -/* Stuff with no proper home (yet) */ -PyAPI_DATA(int) (*PyOS_InputHook)(void); - -/* Stack size, in "pointers" (so we get extra safety margins - on 64-bit platforms). On a 32-bit platform, this translates - to an 8k margin. */ -#define PYOS_STACK_MARGIN 2048 - -#if defined(WIN32) && !defined(MS_WIN64) && !defined(_M_ARM) && defined(_MSC_VER) && _MSC_VER >= 1300 -/* Enable stack checking under Microsoft C */ -// When changing the platforms, ensure PyOS_CheckStack() docs are still correct -#define USE_STACKCHECK -#endif - -#ifdef USE_STACKCHECK -/* Check that we aren't overflowing our stack */ -PyAPI_FUNC(int) PyOS_CheckStack(void); -#endif - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_PYTHONRUN_H -# include "cpython/pythonrun.h" -# undef Py_CPYTHON_PYTHONRUN_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PYTHONRUN_H */ diff --git a/python/include/pythread.h b/python/include/pythread.h deleted file mode 100644 index 42ca5b0..0000000 --- a/python/include/pythread.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef Py_PYTHREAD_H -#define Py_PYTHREAD_H - -typedef void *PyThread_type_lock; - -#ifdef __cplusplus -extern "C" { -#endif - -/* Return status codes for Python lock acquisition. Chosen for maximum - * backwards compatibility, ie failure -> 0, success -> 1. */ -typedef enum PyLockStatus { - PY_LOCK_FAILURE = 0, - PY_LOCK_ACQUIRED = 1, - PY_LOCK_INTR -} PyLockStatus; - -PyAPI_FUNC(void) PyThread_init_thread(void); -PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); -PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); -PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); - -#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_WIN32) || defined(_AIX) -#define PY_HAVE_THREAD_NATIVE_ID -PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); -#endif - -PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void); -PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock); -PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int); -#define WAIT_LOCK 1 -#define NOWAIT_LOCK 0 - -/* PY_TIMEOUT_T is the integral type used to specify timeouts when waiting - on a lock (see PyThread_acquire_lock_timed() below). - PY_TIMEOUT_MAX is the highest usable value (in microseconds) of that - type, and depends on the system threading API. - - NOTE: this isn't the same value as `_thread.TIMEOUT_MAX`. The _thread - module exposes a higher-level API, with timeouts expressed in seconds - and floating-point numbers allowed. -*/ -#define PY_TIMEOUT_T long long - -#if defined(_POSIX_THREADS) - /* PyThread_acquire_lock_timed() uses _PyTime_FromNanoseconds(us * 1000), - convert microseconds to nanoseconds. */ -# define PY_TIMEOUT_MAX (LLONG_MAX / 1000) -#elif defined (NT_THREADS) - // WaitForSingleObject() accepts timeout in milliseconds in the range - // [0; 0xFFFFFFFE] (DWORD type). INFINITE value (0xFFFFFFFF) means no - // timeout. 0xFFFFFFFE milliseconds is around 49.7 days. -# if 0xFFFFFFFELL * 1000 < LLONG_MAX -# define PY_TIMEOUT_MAX (0xFFFFFFFELL * 1000) -# else -# define PY_TIMEOUT_MAX LLONG_MAX -# endif -#else -# define PY_TIMEOUT_MAX LLONG_MAX -#endif - - -/* If microseconds == 0, the call is non-blocking: it returns immediately - even when the lock can't be acquired. - If microseconds > 0, the call waits up to the specified duration. - If microseconds < 0, the call waits until success (or abnormal failure) - - microseconds must be less than PY_TIMEOUT_MAX. Behaviour otherwise is - undefined. - - If intr_flag is true and the acquire is interrupted by a signal, then the - call will return PY_LOCK_INTR. The caller may reattempt to acquire the - lock. -*/ -PyAPI_FUNC(PyLockStatus) PyThread_acquire_lock_timed(PyThread_type_lock, - PY_TIMEOUT_T microseconds, - int intr_flag); - -PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock); - -PyAPI_FUNC(size_t) PyThread_get_stacksize(void); -PyAPI_FUNC(int) PyThread_set_stacksize(size_t); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject*) PyThread_GetInfo(void); -#endif - - -/* Thread Local Storage (TLS) API - TLS API is DEPRECATED. Use Thread Specific Storage (TSS) API. - - The existing TLS API has used int to represent TLS keys across all - platforms, but it is not POSIX-compliant. Therefore, the new TSS API uses - opaque data type to represent TSS keys to be compatible (see PEP 539). -*/ -Py_DEPRECATED(3.7) PyAPI_FUNC(int) PyThread_create_key(void); -Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_delete_key(int key); -Py_DEPRECATED(3.7) PyAPI_FUNC(int) PyThread_set_key_value(int key, - void *value); -Py_DEPRECATED(3.7) PyAPI_FUNC(void *) PyThread_get_key_value(int key); -Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_delete_key_value(int key); - -/* Cleanup after a fork */ -Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_ReInitTLS(void); - - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 -/* New in 3.7 */ -/* Thread Specific Storage (TSS) API */ - -typedef struct _Py_tss_t Py_tss_t; /* opaque */ - -PyAPI_FUNC(Py_tss_t *) PyThread_tss_alloc(void); -PyAPI_FUNC(void) PyThread_tss_free(Py_tss_t *key); - -/* The parameter key must not be NULL. */ -PyAPI_FUNC(int) PyThread_tss_is_created(Py_tss_t *key); -PyAPI_FUNC(int) PyThread_tss_create(Py_tss_t *key); -PyAPI_FUNC(void) PyThread_tss_delete(Py_tss_t *key); -PyAPI_FUNC(int) PyThread_tss_set(Py_tss_t *key, void *value); -PyAPI_FUNC(void *) PyThread_tss_get(Py_tss_t *key); -#endif /* New in 3.7 */ - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_PYTHREAD_H -# include "cpython/pythread.h" -# undef Py_CPYTHON_PYTHREAD_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PYTHREAD_H */ diff --git a/python/include/pytypedefs.h b/python/include/pytypedefs.h deleted file mode 100644 index 1cf6af9..0000000 --- a/python/include/pytypedefs.h +++ /dev/null @@ -1,30 +0,0 @@ -// Forward declarations of types of the Python C API. -// Declare them at the same place since redefining typedef is a C11 feature. -// Only use a forward declaration if there is an interdependency between two -// header files. - -#ifndef Py_PYTYPEDEFS_H -#define Py_PYTYPEDEFS_H -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct PyModuleDef PyModuleDef; -typedef struct PyModuleDef_Slot PyModuleDef_Slot; -typedef struct PyMethodDef PyMethodDef; -typedef struct PyGetSetDef PyGetSetDef; -typedef struct PyMemberDef PyMemberDef; - -typedef struct _object PyObject; -typedef struct _longobject PyLongObject; -typedef struct _typeobject PyTypeObject; -typedef struct PyCodeObject PyCodeObject; -typedef struct _frame PyFrameObject; - -typedef struct _ts PyThreadState; -typedef struct _is PyInterpreterState; - -#ifdef __cplusplus -} -#endif -#endif // !Py_PYTYPEDEFS_H diff --git a/python/include/rangeobject.h b/python/include/rangeobject.h deleted file mode 100644 index d2105d0..0000000 --- a/python/include/rangeobject.h +++ /dev/null @@ -1,27 +0,0 @@ - -/* Range object interface */ - -#ifndef Py_RANGEOBJECT_H -#define Py_RANGEOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -/* -A range object represents an integer range. This is an immutable object; -a range cannot change its value after creation. - -Range objects behave like the corresponding tuple objects except that -they are represented by a start, stop, and step datamembers. -*/ - -PyAPI_DATA(PyTypeObject) PyRange_Type; -PyAPI_DATA(PyTypeObject) PyRangeIter_Type; -PyAPI_DATA(PyTypeObject) PyLongRangeIter_Type; - -#define PyRange_Check(op) Py_IS_TYPE(op, &PyRange_Type) - -#ifdef __cplusplus -} -#endif -#endif /* !Py_RANGEOBJECT_H */ diff --git a/python/include/setobject.h b/python/include/setobject.h deleted file mode 100644 index 52f95ca..0000000 --- a/python/include/setobject.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Set object interface */ - -#ifndef Py_SETOBJECT_H -#define Py_SETOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_DATA(PyTypeObject) PySet_Type; -PyAPI_DATA(PyTypeObject) PyFrozenSet_Type; -PyAPI_DATA(PyTypeObject) PySetIter_Type; - -PyAPI_FUNC(PyObject *) PySet_New(PyObject *); -PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); - -PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key); -PyAPI_FUNC(int) PySet_Clear(PyObject *set); -PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key); -PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); -PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); -PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); - -#define PyFrozenSet_CheckExact(ob) Py_IS_TYPE(ob, &PyFrozenSet_Type) -#define PyFrozenSet_Check(ob) \ - (Py_IS_TYPE(ob, &PyFrozenSet_Type) || \ - PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) - -#define PyAnySet_CheckExact(ob) \ - (Py_IS_TYPE(ob, &PySet_Type) || Py_IS_TYPE(ob, &PyFrozenSet_Type)) -#define PyAnySet_Check(ob) \ - (Py_IS_TYPE(ob, &PySet_Type) || Py_IS_TYPE(ob, &PyFrozenSet_Type) || \ - PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \ - PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) - -#define PySet_CheckExact(op) Py_IS_TYPE(op, &PySet_Type) -#define PySet_Check(ob) \ - (Py_IS_TYPE(ob, &PySet_Type) || \ - PyType_IsSubtype(Py_TYPE(ob), &PySet_Type)) - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_SETOBJECT_H -# include "cpython/setobject.h" -# undef Py_CPYTHON_SETOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_SETOBJECT_H */ diff --git a/python/include/sliceobject.h b/python/include/sliceobject.h deleted file mode 100644 index c415060..0000000 --- a/python/include/sliceobject.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef Py_SLICEOBJECT_H -#define Py_SLICEOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -/* The unique ellipsis object "..." */ - -PyAPI_DATA(PyObject) _Py_EllipsisObject; /* Don't use this directly */ - -#define Py_Ellipsis (&_Py_EllipsisObject) - -/* Slice object interface */ - -/* - -A slice object containing start, stop, and step data members (the -names are from range). After much talk with Guido, it was decided to -let these be any arbitrary python type. Py_None stands for omitted values. -*/ -#ifndef Py_LIMITED_API -typedef struct { - PyObject_HEAD - PyObject *start, *stop, *step; /* not NULL */ -} PySliceObject; -#endif - -PyAPI_DATA(PyTypeObject) PySlice_Type; -PyAPI_DATA(PyTypeObject) PyEllipsis_Type; - -#define PySlice_Check(op) Py_IS_TYPE(op, &PySlice_Type) - -PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop, - PyObject* step); -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PySlice_FromIndices(Py_ssize_t start, Py_ssize_t stop); -PyAPI_FUNC(int) _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, - PyObject **start_ptr, PyObject **stop_ptr, - PyObject **step_ptr); -#endif -PyAPI_FUNC(int) PySlice_GetIndices(PyObject *r, Py_ssize_t length, - Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); -Py_DEPRECATED(3.7) -PyAPI_FUNC(int) PySlice_GetIndicesEx(PyObject *r, Py_ssize_t length, - Py_ssize_t *start, Py_ssize_t *stop, - Py_ssize_t *step, - Py_ssize_t *slicelength); - -#if !defined(Py_LIMITED_API) || (Py_LIMITED_API+0 >= 0x03050400 && Py_LIMITED_API+0 < 0x03060000) || Py_LIMITED_API+0 >= 0x03060100 -#define PySlice_GetIndicesEx(slice, length, start, stop, step, slicelen) ( \ - PySlice_Unpack((slice), (start), (stop), (step)) < 0 ? \ - ((*(slicelen) = 0), -1) : \ - ((*(slicelen) = PySlice_AdjustIndices((length), (start), (stop), *(step))), \ - 0)) -PyAPI_FUNC(int) PySlice_Unpack(PyObject *slice, - Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); -PyAPI_FUNC(Py_ssize_t) PySlice_AdjustIndices(Py_ssize_t length, - Py_ssize_t *start, Py_ssize_t *stop, - Py_ssize_t step); -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_SLICEOBJECT_H */ diff --git a/python/include/structmember.h b/python/include/structmember.h deleted file mode 100644 index ea0645b..0000000 --- a/python/include/structmember.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef Py_STRUCTMEMBER_H -#define Py_STRUCTMEMBER_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* Interface to map C struct members to Python object attributes */ - -#include /* For offsetof */ - -/* An array of PyMemberDef structures defines the name, type and offset - of selected members of a C structure. These can be read by - PyMember_GetOne() and set by PyMember_SetOne() (except if their READONLY - flag is set). The array must be terminated with an entry whose name - pointer is NULL. */ - -struct PyMemberDef { - const char *name; - int type; - Py_ssize_t offset; - int flags; - const char *doc; -}; - -/* Types */ -#define T_SHORT 0 -#define T_INT 1 -#define T_LONG 2 -#define T_FLOAT 3 -#define T_DOUBLE 4 -#define T_STRING 5 -#define T_OBJECT 6 -/* XXX the ordering here is weird for binary compatibility */ -#define T_CHAR 7 /* 1-character string */ -#define T_BYTE 8 /* 8-bit signed int */ -/* unsigned variants: */ -#define T_UBYTE 9 -#define T_USHORT 10 -#define T_UINT 11 -#define T_ULONG 12 - -/* Added by Jack: strings contained in the structure */ -#define T_STRING_INPLACE 13 - -/* Added by Lillo: bools contained in the structure (assumed char) */ -#define T_BOOL 14 - -#define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError - when the value is NULL, instead of - converting to None. */ -#define T_LONGLONG 17 -#define T_ULONGLONG 18 - -#define T_PYSSIZET 19 /* Py_ssize_t */ -#define T_NONE 20 /* Value is always None */ - - -/* Flags */ -#define READONLY 1 -#define READ_RESTRICTED 2 -#define PY_WRITE_RESTRICTED 4 -#define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED) - -#define PY_AUDIT_READ READ_RESTRICTED - -/* Current API, use this */ -PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, PyMemberDef *); -PyAPI_FUNC(int) PyMember_SetOne(char *, PyMemberDef *, PyObject *); - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_STRUCTMEMBER_H */ diff --git a/python/include/structseq.h b/python/include/structseq.h deleted file mode 100644 index 034eb8f..0000000 --- a/python/include/structseq.h +++ /dev/null @@ -1,49 +0,0 @@ - -/* Named tuple object interface */ - -#ifndef Py_STRUCTSEQ_H -#define Py_STRUCTSEQ_H -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct PyStructSequence_Field { - const char *name; - const char *doc; -} PyStructSequence_Field; - -typedef struct PyStructSequence_Desc { - const char *name; - const char *doc; - PyStructSequence_Field *fields; - int n_in_sequence; -} PyStructSequence_Desc; - -PyAPI_DATA(const char * const) PyStructSequence_UnnamedField; - -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type, - PyStructSequence_Desc *desc); -PyAPI_FUNC(int) PyStructSequence_InitType2(PyTypeObject *type, - PyStructSequence_Desc *desc); -#endif -PyAPI_FUNC(PyTypeObject*) PyStructSequence_NewType(PyStructSequence_Desc *desc); - -PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type); - -#ifndef Py_LIMITED_API -typedef PyTupleObject PyStructSequence; - -/* Macro, *only* to be used to fill in brand new objects */ -#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM(op, i, v) - -#define PyStructSequence_GET_ITEM(op, i) PyTuple_GET_ITEM(op, i) -#endif - -PyAPI_FUNC(void) PyStructSequence_SetItem(PyObject*, Py_ssize_t, PyObject*); -PyAPI_FUNC(PyObject*) PyStructSequence_GetItem(PyObject*, Py_ssize_t); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_STRUCTSEQ_H */ diff --git a/python/include/sysmodule.h b/python/include/sysmodule.h deleted file mode 100644 index 8b42b04..0000000 --- a/python/include/sysmodule.h +++ /dev/null @@ -1,41 +0,0 @@ - -/* System module interface */ - -#ifndef Py_SYSMODULE_H -#define Py_SYSMODULE_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_FUNC(PyObject *) PySys_GetObject(const char *); -PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *); - -Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **); -Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int); -Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetPath(const wchar_t *); - -PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) - Py_GCC_ATTRIBUTE((format(printf, 1, 2))); -PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) - Py_GCC_ATTRIBUTE((format(printf, 1, 2))); -PyAPI_FUNC(void) PySys_FormatStdout(const char *format, ...); -PyAPI_FUNC(void) PySys_FormatStderr(const char *format, ...); - -PyAPI_FUNC(void) PySys_ResetWarnOptions(void); -Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_AddWarnOption(const wchar_t *); -Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_AddWarnOptionUnicode(PyObject *); -Py_DEPRECATED(3.11) PyAPI_FUNC(int) PySys_HasWarnOptions(void); - -Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_AddXOption(const wchar_t *); -PyAPI_FUNC(PyObject *) PySys_GetXOptions(void); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_SYSMODULE_H -# include "cpython/sysmodule.h" -# undef Py_CPYTHON_SYSMODULE_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_SYSMODULE_H */ diff --git a/python/include/token.h b/python/include/token.h deleted file mode 100644 index 6f7ad99..0000000 --- a/python/include/token.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Auto-generated by Tools/scripts/generate_token.py */ - -/* Token types */ -#ifndef Py_LIMITED_API -#ifndef Py_TOKEN_H -#define Py_TOKEN_H -#ifdef __cplusplus -extern "C" { -#endif - -#undef TILDE /* Prevent clash of our definition with system macro. Ex AIX, ioctl.h */ - -#define ENDMARKER 0 -#define NAME 1 -#define NUMBER 2 -#define STRING 3 -#define NEWLINE 4 -#define INDENT 5 -#define DEDENT 6 -#define LPAR 7 -#define RPAR 8 -#define LSQB 9 -#define RSQB 10 -#define COLON 11 -#define COMMA 12 -#define SEMI 13 -#define PLUS 14 -#define MINUS 15 -#define STAR 16 -#define SLASH 17 -#define VBAR 18 -#define AMPER 19 -#define LESS 20 -#define GREATER 21 -#define EQUAL 22 -#define DOT 23 -#define PERCENT 24 -#define LBRACE 25 -#define RBRACE 26 -#define EQEQUAL 27 -#define NOTEQUAL 28 -#define LESSEQUAL 29 -#define GREATEREQUAL 30 -#define TILDE 31 -#define CIRCUMFLEX 32 -#define LEFTSHIFT 33 -#define RIGHTSHIFT 34 -#define DOUBLESTAR 35 -#define PLUSEQUAL 36 -#define MINEQUAL 37 -#define STAREQUAL 38 -#define SLASHEQUAL 39 -#define PERCENTEQUAL 40 -#define AMPEREQUAL 41 -#define VBAREQUAL 42 -#define CIRCUMFLEXEQUAL 43 -#define LEFTSHIFTEQUAL 44 -#define RIGHTSHIFTEQUAL 45 -#define DOUBLESTAREQUAL 46 -#define DOUBLESLASH 47 -#define DOUBLESLASHEQUAL 48 -#define AT 49 -#define ATEQUAL 50 -#define RARROW 51 -#define ELLIPSIS 52 -#define COLONEQUAL 53 -#define OP 54 -#define AWAIT 55 -#define ASYNC 56 -#define TYPE_IGNORE 57 -#define TYPE_COMMENT 58 -#define SOFT_KEYWORD 59 -#define ERRORTOKEN 60 -#define N_TOKENS 64 -#define NT_OFFSET 256 - -/* Special definitions for cooperation with parser */ - -#define ISTERMINAL(x) ((x) < NT_OFFSET) -#define ISNONTERMINAL(x) ((x) >= NT_OFFSET) -#define ISEOF(x) ((x) == ENDMARKER) -#define ISWHITESPACE(x) ((x) == ENDMARKER || \ - (x) == NEWLINE || \ - (x) == INDENT || \ - (x) == DEDENT) - - -PyAPI_DATA(const char * const) _PyParser_TokenNames[]; /* Token names */ -PyAPI_FUNC(int) PyToken_OneChar(int); -PyAPI_FUNC(int) PyToken_TwoChars(int, int); -PyAPI_FUNC(int) PyToken_ThreeChars(int, int, int); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_TOKEN_H */ -#endif /* Py_LIMITED_API */ diff --git a/python/include/traceback.h b/python/include/traceback.h deleted file mode 100644 index a7b6822..0000000 --- a/python/include/traceback.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef Py_TRACEBACK_H -#define Py_TRACEBACK_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Traceback interface */ - -PyAPI_FUNC(int) PyTraceBack_Here(PyFrameObject *); -PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); - -/* Reveal traceback type so we can typecheck traceback objects */ -PyAPI_DATA(PyTypeObject) PyTraceBack_Type; -#define PyTraceBack_Check(v) Py_IS_TYPE(v, &PyTraceBack_Type) - - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_TRACEBACK_H -# include "cpython/traceback.h" -# undef Py_CPYTHON_TRACEBACK_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_TRACEBACK_H */ diff --git a/python/include/tracemalloc.h b/python/include/tracemalloc.h deleted file mode 100644 index 05b4cc1..0000000 --- a/python/include/tracemalloc.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef Py_TRACEMALLOC_H -#define Py_TRACEMALLOC_H - -#ifndef Py_LIMITED_API -/* Track an allocated memory block in the tracemalloc module. - Return 0 on success, return -1 on error (failed to allocate memory to store - the trace). - - Return -2 if tracemalloc is disabled. - - If memory block is already tracked, update the existing trace. */ -PyAPI_FUNC(int) PyTraceMalloc_Track( - unsigned int domain, - uintptr_t ptr, - size_t size); - -/* Untrack an allocated memory block in the tracemalloc module. - Do nothing if the block was not tracked. - - Return -2 if tracemalloc is disabled, otherwise return 0. */ -PyAPI_FUNC(int) PyTraceMalloc_Untrack( - unsigned int domain, - uintptr_t ptr); - -/* Get the traceback where a memory block was allocated. - - Return a tuple of (filename: str, lineno: int) tuples. - - Return None if the tracemalloc module is disabled or if the memory block - is not tracked by tracemalloc. - - Raise an exception and return NULL on error. */ -PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback( - unsigned int domain, - uintptr_t ptr); -#endif - -#endif /* !Py_TRACEMALLOC_H */ diff --git a/python/include/tupleobject.h b/python/include/tupleobject.h deleted file mode 100644 index fc6917d..0000000 --- a/python/include/tupleobject.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Tuple object interface */ - -#ifndef Py_TUPLEOBJECT_H -#define Py_TUPLEOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -/* -Another generally useful object type is a tuple of object pointers. -For Python, this is an immutable type. C code can change the tuple items -(but not their number), and even use tuples as general-purpose arrays of -object references, but in general only brand new tuples should be mutated, -not ones that might already have been exposed to Python code. - -*** WARNING *** PyTuple_SetItem does not increment the new item's reference -count, but does decrement the reference count of the item it replaces, -if not nil. It does *decrement* the reference count if it is *not* -inserted in the tuple. Similarly, PyTuple_GetItem does not increment the -returned item's reference count. -*/ - -PyAPI_DATA(PyTypeObject) PyTuple_Type; -PyAPI_DATA(PyTypeObject) PyTupleIter_Type; - -#define PyTuple_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) -#define PyTuple_CheckExact(op) Py_IS_TYPE(op, &PyTuple_Type) - -PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); -PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); -PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t); -PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); -PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); -PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_TUPLEOBJECT_H -# include "cpython/tupleobject.h" -# undef Py_CPYTHON_TUPLEOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_TUPLEOBJECT_H */ diff --git a/python/include/typeslots.h b/python/include/typeslots.h deleted file mode 100644 index d091cf0..0000000 --- a/python/include/typeslots.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Do not renumber the file; these numbers are part of the stable ABI. */ -#define Py_bf_getbuffer 1 -#define Py_bf_releasebuffer 2 -#define Py_mp_ass_subscript 3 -#define Py_mp_length 4 -#define Py_mp_subscript 5 -#define Py_nb_absolute 6 -#define Py_nb_add 7 -#define Py_nb_and 8 -#define Py_nb_bool 9 -#define Py_nb_divmod 10 -#define Py_nb_float 11 -#define Py_nb_floor_divide 12 -#define Py_nb_index 13 -#define Py_nb_inplace_add 14 -#define Py_nb_inplace_and 15 -#define Py_nb_inplace_floor_divide 16 -#define Py_nb_inplace_lshift 17 -#define Py_nb_inplace_multiply 18 -#define Py_nb_inplace_or 19 -#define Py_nb_inplace_power 20 -#define Py_nb_inplace_remainder 21 -#define Py_nb_inplace_rshift 22 -#define Py_nb_inplace_subtract 23 -#define Py_nb_inplace_true_divide 24 -#define Py_nb_inplace_xor 25 -#define Py_nb_int 26 -#define Py_nb_invert 27 -#define Py_nb_lshift 28 -#define Py_nb_multiply 29 -#define Py_nb_negative 30 -#define Py_nb_or 31 -#define Py_nb_positive 32 -#define Py_nb_power 33 -#define Py_nb_remainder 34 -#define Py_nb_rshift 35 -#define Py_nb_subtract 36 -#define Py_nb_true_divide 37 -#define Py_nb_xor 38 -#define Py_sq_ass_item 39 -#define Py_sq_concat 40 -#define Py_sq_contains 41 -#define Py_sq_inplace_concat 42 -#define Py_sq_inplace_repeat 43 -#define Py_sq_item 44 -#define Py_sq_length 45 -#define Py_sq_repeat 46 -#define Py_tp_alloc 47 -#define Py_tp_base 48 -#define Py_tp_bases 49 -#define Py_tp_call 50 -#define Py_tp_clear 51 -#define Py_tp_dealloc 52 -#define Py_tp_del 53 -#define Py_tp_descr_get 54 -#define Py_tp_descr_set 55 -#define Py_tp_doc 56 -#define Py_tp_getattr 57 -#define Py_tp_getattro 58 -#define Py_tp_hash 59 -#define Py_tp_init 60 -#define Py_tp_is_gc 61 -#define Py_tp_iter 62 -#define Py_tp_iternext 63 -#define Py_tp_methods 64 -#define Py_tp_new 65 -#define Py_tp_repr 66 -#define Py_tp_richcompare 67 -#define Py_tp_setattr 68 -#define Py_tp_setattro 69 -#define Py_tp_str 70 -#define Py_tp_traverse 71 -#define Py_tp_members 72 -#define Py_tp_getset 73 -#define Py_tp_free 74 -#define Py_nb_matrix_multiply 75 -#define Py_nb_inplace_matrix_multiply 76 -#define Py_am_await 77 -#define Py_am_aiter 78 -#define Py_am_anext 79 -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 -/* New in 3.5 */ -#define Py_tp_finalize 80 -#endif -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 -/* New in 3.10 */ -#define Py_am_send 81 -#endif diff --git a/python/include/unicodeobject.h b/python/include/unicodeobject.h deleted file mode 100644 index b10ea82..0000000 --- a/python/include/unicodeobject.h +++ /dev/null @@ -1,1049 +0,0 @@ -#ifndef Py_UNICODEOBJECT_H -#define Py_UNICODEOBJECT_H - -#include // va_list - -/* - -Unicode implementation based on original code by Fredrik Lundh, -modified by Marc-Andre Lemburg (mal@lemburg.com) according to the -Unicode Integration Proposal. (See -http://www.egenix.com/files/python/unicode-proposal.txt). - -Copyright (c) Corporation for National Research Initiatives. - - - Original header: - -------------------------------------------------------------------- - - * Yet another Unicode string type for Python. This type supports the - * 16-bit Basic Multilingual Plane (BMP) only. - * - * Written by Fredrik Lundh, January 1999. - * - * Copyright (c) 1999 by Secret Labs AB. - * Copyright (c) 1999 by Fredrik Lundh. - * - * fredrik@pythonware.com - * http://www.pythonware.com - * - * -------------------------------------------------------------------- - * This Unicode String Type is - * - * Copyright (c) 1999 by Secret Labs AB - * Copyright (c) 1999 by Fredrik Lundh - * - * By obtaining, using, and/or copying this software and/or its - * associated documentation, you agree that you have read, understood, - * and will comply with the following terms and conditions: - * - * Permission to use, copy, modify, and distribute this software and its - * associated documentation for any purpose and without fee is hereby - * granted, provided that the above copyright notice appears in all - * copies, and that both that copyright notice and this permission notice - * appear in supporting documentation, and that the name of Secret Labs - * AB or the author not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. - * - * SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * -------------------------------------------------------------------- */ - -#include - -/* === Internal API ======================================================= */ - -/* --- Internal Unicode Format -------------------------------------------- */ - -/* Python 3.x requires unicode */ -#define Py_USING_UNICODE - -#ifndef SIZEOF_WCHAR_T -#error Must define SIZEOF_WCHAR_T -#endif - -#define Py_UNICODE_SIZE SIZEOF_WCHAR_T - -/* If wchar_t can be used for UCS-4 storage, set Py_UNICODE_WIDE. - Otherwise, Unicode strings are stored as UCS-2 (with limited support - for UTF-16) */ - -#if Py_UNICODE_SIZE >= 4 -#define Py_UNICODE_WIDE -#endif - -/* Set these flags if the platform has "wchar.h" and the - wchar_t type is a 16-bit unsigned type */ -/* #define HAVE_WCHAR_H */ -/* #define HAVE_USABLE_WCHAR_T */ - -/* If the compiler provides a wchar_t type we try to support it - through the interface functions PyUnicode_FromWideChar(), - PyUnicode_AsWideChar() and PyUnicode_AsWideCharString(). */ - -#ifdef HAVE_USABLE_WCHAR_T -# ifndef HAVE_WCHAR_H -# define HAVE_WCHAR_H -# endif -#endif - -#ifdef HAVE_WCHAR_H -# include -#endif - -/* Py_UCS4 and Py_UCS2 are typedefs for the respective - unicode representations. */ -typedef uint32_t Py_UCS4; -typedef uint16_t Py_UCS2; -typedef uint8_t Py_UCS1; - -#ifdef __cplusplus -extern "C" { -#endif - - -PyAPI_DATA(PyTypeObject) PyUnicode_Type; -PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; - -#define PyUnicode_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) -#define PyUnicode_CheckExact(op) Py_IS_TYPE(op, &PyUnicode_Type) - -/* --- Constants ---------------------------------------------------------- */ - -/* This Unicode character will be used as replacement character during - decoding if the errors argument is set to "replace". Note: the - Unicode character U+FFFD is the official REPLACEMENT CHARACTER in - Unicode 3.0. */ - -#define Py_UNICODE_REPLACEMENT_CHARACTER ((Py_UCS4) 0xFFFD) - -/* === Public API ========================================================= */ - -/* Similar to PyUnicode_FromUnicode(), but u points to UTF-8 encoded bytes */ -PyAPI_FUNC(PyObject*) PyUnicode_FromStringAndSize( - const char *u, /* UTF-8 encoded string */ - Py_ssize_t size /* size of buffer */ - ); - -/* Similar to PyUnicode_FromUnicode(), but u points to null-terminated - UTF-8 encoded bytes. The size is determined with strlen(). */ -PyAPI_FUNC(PyObject*) PyUnicode_FromString( - const char *u /* UTF-8 encoded string */ - ); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject*) PyUnicode_Substring( - PyObject *str, - Py_ssize_t start, - Py_ssize_t end); -#endif - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -/* Copy the string into a UCS4 buffer including the null character if copy_null - is set. Return NULL and raise an exception on error. Raise a SystemError if - the buffer is smaller than the string. Return buffer on success. - - buflen is the length of the buffer in (Py_UCS4) characters. */ -PyAPI_FUNC(Py_UCS4*) PyUnicode_AsUCS4( - PyObject *unicode, - Py_UCS4* buffer, - Py_ssize_t buflen, - int copy_null); - -/* Copy the string into a UCS4 buffer. A new buffer is allocated using - * PyMem_Malloc; if this fails, NULL is returned with a memory error - exception set. */ -PyAPI_FUNC(Py_UCS4*) PyUnicode_AsUCS4Copy(PyObject *unicode); -#endif - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -/* Get the length of the Unicode object. */ - -PyAPI_FUNC(Py_ssize_t) PyUnicode_GetLength( - PyObject *unicode -); -#endif - -/* Get the number of Py_UNICODE units in the - string representation. */ - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize( - PyObject *unicode /* Unicode object */ - ); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -/* Read a character from the string. */ - -PyAPI_FUNC(Py_UCS4) PyUnicode_ReadChar( - PyObject *unicode, - Py_ssize_t index - ); - -/* Write a character to the string. The string must have been created through - PyUnicode_New, must not be shared, and must not have been hashed yet. - - Return 0 on success, -1 on error. */ - -PyAPI_FUNC(int) PyUnicode_WriteChar( - PyObject *unicode, - Py_ssize_t index, - Py_UCS4 character - ); -#endif - -/* Resize a Unicode object. The length is the number of characters, except - if the kind of the string is PyUnicode_WCHAR_KIND: in this case, the length - is the number of Py_UNICODE characters. - - *unicode is modified to point to the new (resized) object and 0 - returned on success. - - Try to resize the string in place (which is usually faster than allocating - a new string and copy characters), or create a new string. - - Error handling is implemented as follows: an exception is set, -1 - is returned and *unicode left untouched. - - WARNING: The function doesn't check string content, the result may not be a - string in canonical representation. */ - -PyAPI_FUNC(int) PyUnicode_Resize( - PyObject **unicode, /* Pointer to the Unicode object */ - Py_ssize_t length /* New length */ - ); - -/* Decode obj to a Unicode object. - - bytes, bytearray and other bytes-like objects are decoded according to the - given encoding and error handler. The encoding and error handler can be - NULL to have the interface use UTF-8 and "strict". - - All other objects (including Unicode objects) raise an exception. - - The API returns NULL in case of an error. The caller is responsible - for decref'ing the returned objects. - -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_FromEncodedObject( - PyObject *obj, /* Object */ - const char *encoding, /* encoding */ - const char *errors /* error handling */ - ); - -/* Copy an instance of a Unicode subtype to a new true Unicode object if - necessary. If obj is already a true Unicode object (not a subtype), return - the reference with *incremented* refcount. - - The API returns NULL in case of an error. The caller is responsible - for decref'ing the returned objects. - -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_FromObject( - PyObject *obj /* Object */ - ); - -PyAPI_FUNC(PyObject *) PyUnicode_FromFormatV( - const char *format, /* ASCII-encoded string */ - va_list vargs - ); -PyAPI_FUNC(PyObject *) PyUnicode_FromFormat( - const char *format, /* ASCII-encoded string */ - ... - ); - -PyAPI_FUNC(void) PyUnicode_InternInPlace(PyObject **); -PyAPI_FUNC(PyObject *) PyUnicode_InternFromString( - const char *u /* UTF-8 encoded string */ - ); - -// PyUnicode_InternImmortal() is deprecated since Python 3.10 -// and will be removed in Python 3.12. Use PyUnicode_InternInPlace() instead. -Py_DEPRECATED(3.10) PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); - -/* --- wchar_t support for platforms which support it --------------------- */ - -#ifdef HAVE_WCHAR_H - -/* Create a Unicode Object from the wchar_t buffer w of the given - size. - - The buffer is copied into the new object. */ - -PyAPI_FUNC(PyObject*) PyUnicode_FromWideChar( - const wchar_t *w, /* wchar_t buffer */ - Py_ssize_t size /* size of buffer */ - ); - -/* Copies the Unicode Object contents into the wchar_t buffer w. At - most size wchar_t characters are copied. - - Note that the resulting wchar_t string may or may not be - 0-terminated. It is the responsibility of the caller to make sure - that the wchar_t string is 0-terminated in case this is required by - the application. - - Returns the number of wchar_t characters copied (excluding a - possibly trailing 0-termination character) or -1 in case of an - error. */ - -PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar( - PyObject *unicode, /* Unicode object */ - wchar_t *w, /* wchar_t buffer */ - Py_ssize_t size /* size of buffer */ - ); - -/* Convert the Unicode object to a wide character string. The output string - always ends with a nul character. If size is not NULL, write the number of - wide characters (excluding the null character) into *size. - - Returns a buffer allocated by PyMem_Malloc() (use PyMem_Free() to free it) - on success. On error, returns NULL, *size is undefined and raises a - MemoryError. */ - -PyAPI_FUNC(wchar_t*) PyUnicode_AsWideCharString( - PyObject *unicode, /* Unicode object */ - Py_ssize_t *size /* number of characters of the result */ - ); - -#endif - -/* --- Unicode ordinals --------------------------------------------------- */ - -/* Create a Unicode Object from the given Unicode code point ordinal. - - The ordinal must be in range(0x110000). A ValueError is - raised in case it is not. - -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_FromOrdinal(int ordinal); - -/* === Builtin Codecs ===================================================== - - Many of these APIs take two arguments encoding and errors. These - parameters encoding and errors have the same semantics as the ones - of the builtin str() API. - - Setting encoding to NULL causes the default encoding (UTF-8) to be used. - - Error handling is set by errors which may also be set to NULL - meaning to use the default handling defined for the codec. Default - error handling for all builtin codecs is "strict" (ValueErrors are - raised). - - The codecs all use a similar interface. Only deviation from the - generic ones are documented. - -*/ - -/* --- Manage the default encoding ---------------------------------------- */ - -/* Returns "utf-8". */ -PyAPI_FUNC(const char*) PyUnicode_GetDefaultEncoding(void); - -/* --- Generic Codecs ----------------------------------------------------- */ - -/* Create a Unicode object by decoding the encoded string s of the - given size. */ - -PyAPI_FUNC(PyObject*) PyUnicode_Decode( - const char *s, /* encoded string */ - Py_ssize_t size, /* size of buffer */ - const char *encoding, /* encoding */ - const char *errors /* error handling */ - ); - -/* Decode a Unicode object unicode and return the result as Python - object. - - This API is DEPRECATED. The only supported standard encoding is rot13. - Use PyCodec_Decode() to decode with rot13 and non-standard codecs - that decode from str. */ - -Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedObject( - PyObject *unicode, /* Unicode object */ - const char *encoding, /* encoding */ - const char *errors /* error handling */ - ); - -/* Decode a Unicode object unicode and return the result as Unicode - object. - - This API is DEPRECATED. The only supported standard encoding is rot13. - Use PyCodec_Decode() to decode with rot13 and non-standard codecs - that decode from str to str. */ - -Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedUnicode( - PyObject *unicode, /* Unicode object */ - const char *encoding, /* encoding */ - const char *errors /* error handling */ - ); - -/* Encodes a Unicode object and returns the result as Python - object. - - This API is DEPRECATED. It is superseded by PyUnicode_AsEncodedString() - since all standard encodings (except rot13) encode str to bytes. - Use PyCodec_Encode() for encoding with rot13 and non-standard codecs - that encode form str to non-bytes. */ - -Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedObject( - PyObject *unicode, /* Unicode object */ - const char *encoding, /* encoding */ - const char *errors /* error handling */ - ); - -/* Encodes a Unicode object and returns the result as Python string - object. */ - -PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedString( - PyObject *unicode, /* Unicode object */ - const char *encoding, /* encoding */ - const char *errors /* error handling */ - ); - -/* Encodes a Unicode object and returns the result as Unicode - object. - - This API is DEPRECATED. The only supported standard encodings is rot13. - Use PyCodec_Encode() to encode with rot13 and non-standard codecs - that encode from str to str. */ - -Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedUnicode( - PyObject *unicode, /* Unicode object */ - const char *encoding, /* encoding */ - const char *errors /* error handling */ - ); - -/* Build an encoding map. */ - -PyAPI_FUNC(PyObject*) PyUnicode_BuildEncodingMap( - PyObject* string /* 256 character map */ - ); - -/* --- UTF-7 Codecs ------------------------------------------------------- */ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF7( - const char *string, /* UTF-7 encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors /* error handling */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF7Stateful( - const char *string, /* UTF-7 encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors, /* error handling */ - Py_ssize_t *consumed /* bytes consumed */ - ); - -/* --- UTF-8 Codecs ------------------------------------------------------- */ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8( - const char *string, /* UTF-8 encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors /* error handling */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8Stateful( - const char *string, /* UTF-8 encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors, /* error handling */ - Py_ssize_t *consumed /* bytes consumed */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_AsUTF8String( - PyObject *unicode /* Unicode object */ - ); - -/* Returns a pointer to the default encoding (UTF-8) of the - Unicode object unicode and the size of the encoded representation - in bytes stored in *size. - - In case of an error, no *size is set. - - This function caches the UTF-8 encoded string in the unicodeobject - and subsequent calls will return the same string. The memory is released - when the unicodeobject is deallocated. -*/ - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000 -PyAPI_FUNC(const char *) PyUnicode_AsUTF8AndSize( - PyObject *unicode, - Py_ssize_t *size); -#endif - -/* --- UTF-32 Codecs ------------------------------------------------------ */ - -/* Decodes length bytes from a UTF-32 encoded buffer string and returns - the corresponding Unicode object. - - errors (if non-NULL) defines the error handling. It defaults - to "strict". - - If byteorder is non-NULL, the decoder starts decoding using the - given byte order: - - *byteorder == -1: little endian - *byteorder == 0: native order - *byteorder == 1: big endian - - In native mode, the first four bytes of the stream are checked for a - BOM mark. If found, the BOM mark is analysed, the byte order - adjusted and the BOM skipped. In the other modes, no BOM mark - interpretation is done. After completion, *byteorder is set to the - current byte order at the end of input data. - - If byteorder is NULL, the codec starts in native order mode. - -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF32( - const char *string, /* UTF-32 encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors, /* error handling */ - int *byteorder /* pointer to byteorder to use - 0=native;-1=LE,1=BE; updated on - exit */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF32Stateful( - const char *string, /* UTF-32 encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors, /* error handling */ - int *byteorder, /* pointer to byteorder to use - 0=native;-1=LE,1=BE; updated on - exit */ - Py_ssize_t *consumed /* bytes consumed */ - ); - -/* Returns a Python string using the UTF-32 encoding in native byte - order. The string always starts with a BOM mark. */ - -PyAPI_FUNC(PyObject*) PyUnicode_AsUTF32String( - PyObject *unicode /* Unicode object */ - ); - -/* Returns a Python string object holding the UTF-32 encoded value of - the Unicode data. - - If byteorder is not 0, output is written according to the following - byte order: - - byteorder == -1: little endian - byteorder == 0: native byte order (writes a BOM mark) - byteorder == 1: big endian - - If byteorder is 0, the output string will always start with the - Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is - prepended. - -*/ - -/* --- UTF-16 Codecs ------------------------------------------------------ */ - -/* Decodes length bytes from a UTF-16 encoded buffer string and returns - the corresponding Unicode object. - - errors (if non-NULL) defines the error handling. It defaults - to "strict". - - If byteorder is non-NULL, the decoder starts decoding using the - given byte order: - - *byteorder == -1: little endian - *byteorder == 0: native order - *byteorder == 1: big endian - - In native mode, the first two bytes of the stream are checked for a - BOM mark. If found, the BOM mark is analysed, the byte order - adjusted and the BOM skipped. In the other modes, no BOM mark - interpretation is done. After completion, *byteorder is set to the - current byte order at the end of input data. - - If byteorder is NULL, the codec starts in native order mode. - -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16( - const char *string, /* UTF-16 encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors, /* error handling */ - int *byteorder /* pointer to byteorder to use - 0=native;-1=LE,1=BE; updated on - exit */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16Stateful( - const char *string, /* UTF-16 encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors, /* error handling */ - int *byteorder, /* pointer to byteorder to use - 0=native;-1=LE,1=BE; updated on - exit */ - Py_ssize_t *consumed /* bytes consumed */ - ); - -/* Returns a Python string using the UTF-16 encoding in native byte - order. The string always starts with a BOM mark. */ - -PyAPI_FUNC(PyObject*) PyUnicode_AsUTF16String( - PyObject *unicode /* Unicode object */ - ); - -/* --- Unicode-Escape Codecs ---------------------------------------------- */ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeUnicodeEscape( - const char *string, /* Unicode-Escape encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors /* error handling */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_AsUnicodeEscapeString( - PyObject *unicode /* Unicode object */ - ); - -/* --- Raw-Unicode-Escape Codecs ------------------------------------------ */ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeRawUnicodeEscape( - const char *string, /* Raw-Unicode-Escape encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors /* error handling */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_AsRawUnicodeEscapeString( - PyObject *unicode /* Unicode object */ - ); - -/* --- Latin-1 Codecs ----------------------------------------------------- - - Note: Latin-1 corresponds to the first 256 Unicode ordinals. */ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeLatin1( - const char *string, /* Latin-1 encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors /* error handling */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_AsLatin1String( - PyObject *unicode /* Unicode object */ - ); - -/* --- ASCII Codecs ------------------------------------------------------- - - Only 7-bit ASCII data is excepted. All other codes generate errors. - -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeASCII( - const char *string, /* ASCII encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors /* error handling */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_AsASCIIString( - PyObject *unicode /* Unicode object */ - ); - -/* --- Character Map Codecs ----------------------------------------------- - - This codec uses mappings to encode and decode characters. - - Decoding mappings must map byte ordinals (integers in the range from 0 to - 255) to Unicode strings, integers (which are then interpreted as Unicode - ordinals) or None. Unmapped data bytes (ones which cause a LookupError) - as well as mapped to None, 0xFFFE or '\ufffe' are treated as "undefined - mapping" and cause an error. - - Encoding mappings must map Unicode ordinal integers to bytes objects, - integers in the range from 0 to 255 or None. Unmapped character - ordinals (ones which cause a LookupError) as well as mapped to - None are treated as "undefined mapping" and cause an error. - -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeCharmap( - const char *string, /* Encoded string */ - Py_ssize_t length, /* size of string */ - PyObject *mapping, /* decoding mapping */ - const char *errors /* error handling */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_AsCharmapString( - PyObject *unicode, /* Unicode object */ - PyObject *mapping /* encoding mapping */ - ); - -/* --- MBCS codecs for Windows -------------------------------------------- */ - -#ifdef MS_WINDOWS -PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCS( - const char *string, /* MBCS encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors /* error handling */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCSStateful( - const char *string, /* MBCS encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors, /* error handling */ - Py_ssize_t *consumed /* bytes consumed */ - ); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject*) PyUnicode_DecodeCodePageStateful( - int code_page, /* code page number */ - const char *string, /* encoded string */ - Py_ssize_t length, /* size of string */ - const char *errors, /* error handling */ - Py_ssize_t *consumed /* bytes consumed */ - ); -#endif - -PyAPI_FUNC(PyObject*) PyUnicode_AsMBCSString( - PyObject *unicode /* Unicode object */ - ); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -PyAPI_FUNC(PyObject*) PyUnicode_EncodeCodePage( - int code_page, /* code page number */ - PyObject *unicode, /* Unicode object */ - const char *errors /* error handling */ - ); -#endif - -#endif /* MS_WINDOWS */ - -/* --- Locale encoding --------------------------------------------------- */ - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -/* Decode a string from the current locale encoding. The decoder is strict if - *surrogateescape* is equal to zero, otherwise it uses the 'surrogateescape' - error handler (PEP 383) to escape undecodable bytes. If a byte sequence can - be decoded as a surrogate character and *surrogateescape* is not equal to - zero, the byte sequence is escaped using the 'surrogateescape' error handler - instead of being decoded. *str* must end with a null character but cannot - contain embedded null characters. */ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeLocaleAndSize( - const char *str, - Py_ssize_t len, - const char *errors); - -/* Similar to PyUnicode_DecodeLocaleAndSize(), but compute the string - length using strlen(). */ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeLocale( - const char *str, - const char *errors); - -/* Encode a Unicode object to the current locale encoding. The encoder is - strict is *surrogateescape* is equal to zero, otherwise the - "surrogateescape" error handler is used. Return a bytes object. The string - cannot contain embedded null characters. */ - -PyAPI_FUNC(PyObject*) PyUnicode_EncodeLocale( - PyObject *unicode, - const char *errors - ); -#endif - -/* --- File system encoding ---------------------------------------------- */ - -/* ParseTuple converter: encode str objects to bytes using - PyUnicode_EncodeFSDefault(); bytes objects are output as-is. */ - -PyAPI_FUNC(int) PyUnicode_FSConverter(PyObject*, void*); - -/* ParseTuple converter: decode bytes objects to unicode using - PyUnicode_DecodeFSDefaultAndSize(); str objects are output as-is. */ - -PyAPI_FUNC(int) PyUnicode_FSDecoder(PyObject*, void*); - -/* Decode a null-terminated string using Py_FileSystemDefaultEncoding - and the "surrogateescape" error handler. - - If Py_FileSystemDefaultEncoding is not set, fall back to the locale - encoding. - - Use PyUnicode_DecodeFSDefaultAndSize() if the string length is known. -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefault( - const char *s /* encoded string */ - ); - -/* Decode a string using Py_FileSystemDefaultEncoding - and the "surrogateescape" error handler. - - If Py_FileSystemDefaultEncoding is not set, fall back to the locale - encoding. -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefaultAndSize( - const char *s, /* encoded string */ - Py_ssize_t size /* size */ - ); - -/* Encode a Unicode object to Py_FileSystemDefaultEncoding with the - "surrogateescape" error handler, and return bytes. - - If Py_FileSystemDefaultEncoding is not set, fall back to the locale - encoding. -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_EncodeFSDefault( - PyObject *unicode - ); - -/* --- Methods & Slots ---------------------------------------------------- - - These are capable of handling Unicode objects and strings on input - (we refer to them as strings in the descriptions) and return - Unicode objects or integers as appropriate. */ - -/* Concat two strings giving a new Unicode string. */ - -PyAPI_FUNC(PyObject*) PyUnicode_Concat( - PyObject *left, /* Left string */ - PyObject *right /* Right string */ - ); - -/* Concat two strings and put the result in *pleft - (sets *pleft to NULL on error) */ - -PyAPI_FUNC(void) PyUnicode_Append( - PyObject **pleft, /* Pointer to left string */ - PyObject *right /* Right string */ - ); - -/* Concat two strings, put the result in *pleft and drop the right object - (sets *pleft to NULL on error) */ - -PyAPI_FUNC(void) PyUnicode_AppendAndDel( - PyObject **pleft, /* Pointer to left string */ - PyObject *right /* Right string */ - ); - -/* Split a string giving a list of Unicode strings. - - If sep is NULL, splitting will be done at all whitespace - substrings. Otherwise, splits occur at the given separator. - - At most maxsplit splits will be done. If negative, no limit is set. - - Separators are not included in the resulting list. - -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_Split( - PyObject *s, /* String to split */ - PyObject *sep, /* String separator */ - Py_ssize_t maxsplit /* Maxsplit count */ - ); - -/* Dito, but split at line breaks. - - CRLF is considered to be one line break. Line breaks are not - included in the resulting list. */ - -PyAPI_FUNC(PyObject*) PyUnicode_Splitlines( - PyObject *s, /* String to split */ - int keepends /* If true, line end markers are included */ - ); - -/* Partition a string using a given separator. */ - -PyAPI_FUNC(PyObject*) PyUnicode_Partition( - PyObject *s, /* String to partition */ - PyObject *sep /* String separator */ - ); - -/* Partition a string using a given separator, searching from the end of the - string. */ - -PyAPI_FUNC(PyObject*) PyUnicode_RPartition( - PyObject *s, /* String to partition */ - PyObject *sep /* String separator */ - ); - -/* Split a string giving a list of Unicode strings. - - If sep is NULL, splitting will be done at all whitespace - substrings. Otherwise, splits occur at the given separator. - - At most maxsplit splits will be done. But unlike PyUnicode_Split - PyUnicode_RSplit splits from the end of the string. If negative, - no limit is set. - - Separators are not included in the resulting list. - -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_RSplit( - PyObject *s, /* String to split */ - PyObject *sep, /* String separator */ - Py_ssize_t maxsplit /* Maxsplit count */ - ); - -/* Translate a string by applying a character mapping table to it and - return the resulting Unicode object. - - The mapping table must map Unicode ordinal integers to Unicode strings, - Unicode ordinal integers or None (causing deletion of the character). - - Mapping tables may be dictionaries or sequences. Unmapped character - ordinals (ones which cause a LookupError) are left untouched and - are copied as-is. - -*/ - -PyAPI_FUNC(PyObject *) PyUnicode_Translate( - PyObject *str, /* String */ - PyObject *table, /* Translate table */ - const char *errors /* error handling */ - ); - -/* Join a sequence of strings using the given separator and return - the resulting Unicode string. */ - -PyAPI_FUNC(PyObject*) PyUnicode_Join( - PyObject *separator, /* Separator string */ - PyObject *seq /* Sequence object */ - ); - -/* Return 1 if substr matches str[start:end] at the given tail end, 0 - otherwise. */ - -PyAPI_FUNC(Py_ssize_t) PyUnicode_Tailmatch( - PyObject *str, /* String */ - PyObject *substr, /* Prefix or Suffix string */ - Py_ssize_t start, /* Start index */ - Py_ssize_t end, /* Stop index */ - int direction /* Tail end: -1 prefix, +1 suffix */ - ); - -/* Return the first position of substr in str[start:end] using the - given search direction or -1 if not found. -2 is returned in case - an error occurred and an exception is set. */ - -PyAPI_FUNC(Py_ssize_t) PyUnicode_Find( - PyObject *str, /* String */ - PyObject *substr, /* Substring to find */ - Py_ssize_t start, /* Start index */ - Py_ssize_t end, /* Stop index */ - int direction /* Find direction: +1 forward, -1 backward */ - ); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 -/* Like PyUnicode_Find, but search for single character only. */ -PyAPI_FUNC(Py_ssize_t) PyUnicode_FindChar( - PyObject *str, - Py_UCS4 ch, - Py_ssize_t start, - Py_ssize_t end, - int direction - ); -#endif - -/* Count the number of occurrences of substr in str[start:end]. */ - -PyAPI_FUNC(Py_ssize_t) PyUnicode_Count( - PyObject *str, /* String */ - PyObject *substr, /* Substring to count */ - Py_ssize_t start, /* Start index */ - Py_ssize_t end /* Stop index */ - ); - -/* Replace at most maxcount occurrences of substr in str with replstr - and return the resulting Unicode object. */ - -PyAPI_FUNC(PyObject *) PyUnicode_Replace( - PyObject *str, /* String */ - PyObject *substr, /* Substring to find */ - PyObject *replstr, /* Substring to replace */ - Py_ssize_t maxcount /* Max. number of replacements to apply; - -1 = all */ - ); - -/* Compare two strings and return -1, 0, 1 for less than, equal, - greater than resp. - Raise an exception and return -1 on error. */ - -PyAPI_FUNC(int) PyUnicode_Compare( - PyObject *left, /* Left string */ - PyObject *right /* Right string */ - ); - -/* Compare a Unicode object with C string and return -1, 0, 1 for less than, - equal, and greater than, respectively. It is best to pass only - ASCII-encoded strings, but the function interprets the input string as - ISO-8859-1 if it contains non-ASCII characters. - This function does not raise exceptions. */ - -PyAPI_FUNC(int) PyUnicode_CompareWithASCIIString( - PyObject *left, - const char *right /* ASCII-encoded string */ - ); - -/* Rich compare two strings and return one of the following: - - - NULL in case an exception was raised - - Py_True or Py_False for successful comparisons - - Py_NotImplemented in case the type combination is unknown - - Possible values for op: - - Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE - -*/ - -PyAPI_FUNC(PyObject *) PyUnicode_RichCompare( - PyObject *left, /* Left string */ - PyObject *right, /* Right string */ - int op /* Operation: Py_EQ, Py_NE, Py_GT, etc. */ - ); - -/* Apply an argument tuple or dictionary to a format string and return - the resulting Unicode string. */ - -PyAPI_FUNC(PyObject *) PyUnicode_Format( - PyObject *format, /* Format string */ - PyObject *args /* Argument tuple or dictionary */ - ); - -/* Checks whether element is contained in container and return 1/0 - accordingly. - - element has to coerce to a one element Unicode string. -1 is - returned in case of an error. */ - -PyAPI_FUNC(int) PyUnicode_Contains( - PyObject *container, /* Container string */ - PyObject *element /* Element string */ - ); - -/* Checks whether argument is a valid identifier. */ - -PyAPI_FUNC(int) PyUnicode_IsIdentifier(PyObject *s); - -/* === Characters Type APIs =============================================== */ - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_UNICODEOBJECT_H -# include "cpython/unicodeobject.h" -# undef Py_CPYTHON_UNICODEOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_UNICODEOBJECT_H */ diff --git a/python/include/warnings.h b/python/include/warnings.h deleted file mode 100644 index 060ac1e..0000000 --- a/python/include/warnings.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef Py_WARNINGS_H -#define Py_WARNINGS_H -#ifdef __cplusplus -extern "C" { -#endif - -PyAPI_FUNC(int) PyErr_WarnEx( - PyObject *category, - const char *message, /* UTF-8 encoded string */ - Py_ssize_t stack_level); - -PyAPI_FUNC(int) PyErr_WarnFormat( - PyObject *category, - Py_ssize_t stack_level, - const char *format, /* ASCII-encoded string */ - ...); - -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 -/* Emit a ResourceWarning warning */ -PyAPI_FUNC(int) PyErr_ResourceWarning( - PyObject *source, - Py_ssize_t stack_level, - const char *format, /* ASCII-encoded string */ - ...); -#endif - -PyAPI_FUNC(int) PyErr_WarnExplicit( - PyObject *category, - const char *message, /* UTF-8 encoded string */ - const char *filename, /* decoded from the filesystem encoding */ - int lineno, - const char *module, /* UTF-8 encoded string */ - PyObject *registry); - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_WARNINGS_H -# include "cpython/warnings.h" -# undef Py_CPYTHON_WARNINGS_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_WARNINGS_H */ - diff --git a/python/include/weakrefobject.h b/python/include/weakrefobject.h deleted file mode 100644 index 190a818..0000000 --- a/python/include/weakrefobject.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Weak references objects for Python. */ - -#ifndef Py_WEAKREFOBJECT_H -#define Py_WEAKREFOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _PyWeakReference PyWeakReference; - -PyAPI_DATA(PyTypeObject) _PyWeakref_RefType; -PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType; -PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType; - -#define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType) -#define PyWeakref_CheckRefExact(op) \ - Py_IS_TYPE(op, &_PyWeakref_RefType) -#define PyWeakref_CheckProxy(op) \ - (Py_IS_TYPE(op, &_PyWeakref_ProxyType) || \ - Py_IS_TYPE(op, &_PyWeakref_CallableProxyType)) - -#define PyWeakref_Check(op) \ - (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op)) - - -PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob, - PyObject *callback); -PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob, - PyObject *callback); -PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref); - - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_WEAKREFOBJECT_H -# include "cpython/weakrefobject.h" -# undef Py_CPYTHON_WEAKREFOBJECT_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_WEAKREFOBJECT_H */ diff --git a/python/libs/python3.lib b/python/libs/python3.lib deleted file mode 100644 index cb7a736a9de266170d870477df883124a9454217..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183544 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 D-3C8j diff --git a/python/libs/python311.lib b/python/libs/python311.lib deleted file mode 100644 index 478b5dc126e807b8792b3b8189af62cd531adf00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 360148 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 diff --git a/python/python.exe b/python/python.exe deleted file mode 100644 index 641251fde921b535cdef7b81fd743028be06a0af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101752 zcmeFY2UJtd^DulvuLhB30Rn=E0->p(lpr8cK~S0n2rU$)cLYL^q8Je@fSqCiQ9%%- zDFo@F0wRLaL5dXV5Nh7NAv}*h|KIcff9HJXJ?DGB^RC`Iv$M0av$M0a>tGn5c(g*Oq`s(Q666Ij$SsdC_5WBH+LVD zEgt3N>xOc6L+KbAqg>tX@p9bU91?WVQ%+@%UbAP-uRo=pYV&VEe!(|$E|&%~<{r`D zv$-|;^SL~bX9wjl#0RbMy=KpxkEGF4=kjULXnqa8pyf|E+d08)toO)B7lQ1gSRi6j ztlc_o0uqNf88(PR8vx}bf<{i}1%QW!VrUc?XMi9U8tHEcC4*96M5FTzz@FA�Zf! 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 diff --git a/python/python311.dll b/python/python311.dll deleted file mode 100644 index c3f667934aef746160e9afe14d15cbc056bbe2b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5761912 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 z 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

    l?HmD9ExccxKn*T_@X6H@tM~+(@%rOpg59OxS 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® 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 z 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

    laKalz-s)yBWp1sA*E1upmyFlKpngLLug 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

    !k6g0BuV>p*ecdrhESONJX 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

  1. o)~gZ5w;J@7A+kzgrN4@W0s0 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�&IX&i$ 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±N#RQ+jv$m-L?W z-t=$j-_w7j52TOD9Gf{VQ$KTj=H$#NnTDA&GG}Ja&NR-PmuZq|nzKm2oo_nW33sncRKy z=FZHN%-xxLGxufg&peQMI5RCXJu@RSGxJ2|$;{K4XEL)hb2BewUd$}ayp&m#S)5s# zS(aIzS&>Pq#bW27>vzI42FvUG~nKx!zR zDxEH!A)P6mC7mNRlFpSHOXo{Xqzk3yQVXf2)LLpIwUydQ?WGPLc})`bqtz0n!!HKxvRPSPDvv#7bc)B5_ho;-$DGNC_z^ zrKGf!kt8Vx=XeweP76qeWJ(1Iik~D~a-jwo+ImB+@d#<8G)lTwx=tD`jghXG#!5Fx zH%jBAo1~kiTcq*QtJ?VYv1L;F)tF%qpE`20@EPWziwp;d+Z1-%B?4{X0*?!sn*#X(BvcW8qjb^!QEE~@X*<@DCrn2d5CM#vLSvjj@ zwXB=1$ifY*+2Pp{*-_bRv!k;&WN*xl%if&5B|AQQYxef+9odQ5N!iKSJG1v>AILtO zeIz?A`*?O%_Q~wi*=MrPXJ=>UWann*XJ5!J$S%yjlzln7IJ+#nBD*qMd2m(st?b6^ z+u1GIkFprCbNzBxE|E*-#9SsP=aih9({e`6%oTEW z&dF8ehUA9khUG@&M&_=|jn0k9U7x!lH!gQm?&jPrx!ZFSb5nA6=kCefo4YUfK<>fZ zL%D}@kL0H19?eb9&CJcpJ)4`8o0prPdoi~#ws z<$linlKVCHTkiMVAG!Ux1G&mv9l5T2w0w+wtb80a7CS*cQ9ea(AfG0mE}tQvDW4^u zEuSl&CpVFs$`{C$2QQSH$<5^!ax1y5+)i#UcaS^Eo#f7P7rCq4O}<3#AzvzACijy2 z$bIF3@*w$Yd9WOigEAwBWqtelgvQKBkqvLTytL58|( z*^ylt`k2T=|SIVp8*W}gm8hNe!hWw`dmb^~hD8DUlmfw}P$nVJ?%3I}a@^<+n`4jn5`7?Q^ z{Dr(r{!0E@{zm>*{!ad0{z3jx{z?8>-Yx$k?~#9%_sYM?`{du{Kji)L0r^k4Qa&gj zrPNmHD0P*3%F)U(%CSnBQeQb8@O=^i+B&y_G&nU!|Wi zK)FJ>N*SaKRsss6uu52oC^3as1SP4Ym5d@OvZ6qFF!aV%4D1c6*ovzRQHCkkC?k}S z$|&VpG6O~EIWaTd99_3zTs&c>bpz??^ zO?gb2p**h4Ql3(tQJzy~EAy23$_vT@W> z{!}WJgUV5AUA3NijC!nkoLXN!K|NVLMQxy-uAZTush+K#qc&0-tLLjt)TZhM>P2b` zwWZohZLPLd+p8VbPHI=Rn|g`bUG1UvR4-S1seRObYJYWrdWCwWI#9hz9jpdaMh&UF z3fUDkp(a&PO{p0*tL9Wi&8xaj+us6*6Y>IikDdaZh$I$FJ69jo4;j#F<| zZ&7bmZ&N3zx2qG?N$OV}N%heU?O7&HBmHL|cy1H6j zqpnroP~TMFQrD^L)eY)Kb(8wG`i{C;eOKM0zNfygexPnuKUP0cKUF_dcc?qn&($x~ zUFuirH|n?Qck1`*59*KV&+4!0UUi@Phq_<=Q#~qQJ6|VXH(xJ*bpDw9@%a<;C*@Dc zH^?{4pPoN6e^&nNe4~70IA?c$zDd4m{(}64`DXbR`L_A?`HuNc`7Zgc`EL13@;&mG z<}b@%p6{LSm+zmyB7aqWP=0Wp%}4Uld@RrB<9Q*U$cy=GK9`sCYCfMg^M$;Xck@H@ z*W@b?j>wP9kIG-0ADthYzcD{9e{=qp{H^&3`8)Cx^ON$E^HcJ7G_%YS^1~)&*f+5=jG?;7vvY^7w2EeFUc>>FUv2_ugJfee?7lCzb3yn|3?1J z{9E~T`Stk?`7QbP^6%%j!4k%b=JCQ-L)Rt<=Pe6AZ@S~)L4zvVj8c-H9<>gNlnyJ zT3R!-f>zWl&DI>v)he_h+AwW|Hc}g9!*K1?78?~FX@!GB0ZQ2CwcI^&r zqBcppQ=6jQrQM_5t4-DJ*B;Ow)E?3v)*jKOX^(1;Y16gGwVB!z+SA%I+Oyho+H7r} zHeXwyE!1ApUe+oPF47ijuV_oOrP?xWxwcYUrM;%TuC3PAXlu1MwRPGCZKJkHdt2MA zy{o;ay{~eDdTYI{-cIkJcho!So%JqySG}9wUGJe^s$Zt} z(tGQD^?rJPeSm(2ex*K8ze*pZU#$<;1A0(r^pMW#VLhsII4=#%ux`knd|{Vx4( zeX4$+{(%0V{)j$Je^h@=pRUi)AJ=Er3>ddgZ}o`f`1R{;Ix8e@%Z~U#+jv*XnQRZ|Upxjr!aAJNjmQi~gSezW#y!p}tk$ zu79L|tbeBO(0A&e>tEbvx>^sn`A^l$a=^dIye^`G>g^6k!-sos_GA=f{7+sBS#wA8~qla;+ zak0mhZaK;tT7ka4v!*a#RwBV@2f*oYWWgEL}=U?dIENEvA(V`Pn- zAsecZH#9>x48t@EM$xbg+i;8uV~8=-7-n2!3^zs?ql{~f(Z(3#dgBJ;Mq`|DvvG?t z-niAc&6r@^Zrou^G$tE&8Fw4^821`ejr)xUj0cT}jE9X!jA_QB#&lzb@whS5c*2-v zK!n+N%6P_j-k5F7G3FZcjQPe3#scF-W1;bq@v^bVSZusvEHRcE%Z%m53S*`5s}U2juQabR2bqJ-fEhFyGi0)6*o>G_lQUx`Zwh9@Oq!yZ zGSg=5TX_Im#Sujxnz{$C@{rx0;m)?=UBs zlg&HLDds)qz2<%9{pJJa!{#IAH1kpOF>{9bxH;2&!klG3X+C8>Z9Z#0XFhMvHs_dg z&3Wd0bD{aNxyW2>zG5yhmzvAW73M1QHFLGO#$0Q@VZLduGdGx<%(u-C%&q2j^CR

    XIVRd0mVQt~9!urC7!p6ee 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%0A#CUi1K}h%9p=JKuoB*etzh(Fe1c&x0UF^FxD}p( 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 z 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%0Dx*Xes{E&4Xv%lS8& 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 l>SBgnEq9K^Yk8|QT|4U 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%0Dy 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

  2. t&v?QYO1}wL=wtR_Qx3l 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 z

    " lines in HTML files). That may be - because this is the only method of the 3 that has a *concept* of - "junk" . - - Example, comparing two strings, and considering blanks to be "junk": - - >>> s = SequenceMatcher(lambda x: x == " ", - ... "private Thread currentThread;", - ... "private volatile Thread currentThread;") - >>> - - .ratio() returns a float in [0, 1], measuring the "similarity" of the - sequences. As a rule of thumb, a .ratio() value over 0.6 means the - sequences are close matches: - - >>> print(round(s.ratio(), 3)) - 0.866 - >>> - - If you're only interested in where the sequences match, - .get_matching_blocks() is handy: - - >>> for block in s.get_matching_blocks(): - ... print("a[%d] and b[%d] match for %d elements" % block) - a[0] and b[0] match for 8 elements - a[8] and b[17] match for 21 elements - a[29] and b[38] match for 0 elements - - Note that the last tuple returned by .get_matching_blocks() is always a - dummy, (len(a), len(b), 0), and this is the only case in which the last - tuple element (number of elements matched) is 0. - - If you want to know how to change the first sequence into the second, - use .get_opcodes(): - - >>> for opcode in s.get_opcodes(): - ... print("%6s a[%d:%d] b[%d:%d]" % opcode) - equal a[0:8] b[0:8] - insert a[8:8] b[8:17] - equal a[8:29] b[17:38] - - See the Differ class for a fancy human-friendly file differencer, which - uses SequenceMatcher both to compare sequences of lines, and to compare - sequences of characters within similar (near-matching) lines. - - See also function get_close_matches() in this module, which shows how - simple code building on SequenceMatcher can be used to do useful work. - - Timing: Basic R-O is cubic time worst case and quadratic time expected - case. SequenceMatcher is quadratic time for the worst case and has - expected-case behavior dependent in a complicated way on how many - elements the sequences have in common; best case time is linear. - """ - - def __init__(self, isjunk=None, a='', b='', autojunk=True): - """Construct a SequenceMatcher. - - Optional arg isjunk is None (the default), or a one-argument - function that takes a sequence element and returns true iff the - element is junk. None is equivalent to passing "lambda x: 0", i.e. - no elements are considered to be junk. For example, pass - lambda x: x in " \\t" - if you're comparing lines as sequences of characters, and don't - want to synch up on blanks or hard tabs. - - Optional arg a is the first of two sequences to be compared. By - default, an empty string. The elements of a must be hashable. See - also .set_seqs() and .set_seq1(). - - Optional arg b is the second of two sequences to be compared. By - default, an empty string. The elements of b must be hashable. See - also .set_seqs() and .set_seq2(). - - Optional arg autojunk should be set to False to disable the - "automatic junk heuristic" that treats popular elements as junk - (see module documentation for more information). - """ - - # Members: - # a - # first sequence - # b - # second sequence; differences are computed as "what do - # we need to do to 'a' to change it into 'b'?" - # b2j - # for x in b, b2j[x] is a list of the indices (into b) - # at which x appears; junk and popular elements do not appear - # fullbcount - # for x in b, fullbcount[x] == the number of times x - # appears in b; only materialized if really needed (used - # only for computing quick_ratio()) - # matching_blocks - # a list of (i, j, k) triples, where a[i:i+k] == b[j:j+k]; - # ascending & non-overlapping in i and in j; terminated by - # a dummy (len(a), len(b), 0) sentinel - # opcodes - # a list of (tag, i1, i2, j1, j2) tuples, where tag is - # one of - # 'replace' a[i1:i2] should be replaced by b[j1:j2] - # 'delete' a[i1:i2] should be deleted - # 'insert' b[j1:j2] should be inserted - # 'equal' a[i1:i2] == b[j1:j2] - # isjunk - # a user-supplied function taking a sequence element and - # returning true iff the element is "junk" -- this has - # subtle but helpful effects on the algorithm, which I'll - # get around to writing up someday <0.9 wink>. - # DON'T USE! Only __chain_b uses this. Use "in self.bjunk". - # bjunk - # the items in b for which isjunk is True. - # bpopular - # nonjunk items in b treated as junk by the heuristic (if used). - - self.isjunk = isjunk - self.a = self.b = None - self.autojunk = autojunk - self.set_seqs(a, b) - - def set_seqs(self, a, b): - """Set the two sequences to be compared. - - >>> s = SequenceMatcher() - >>> s.set_seqs("abcd", "bcde") - >>> s.ratio() - 0.75 - """ - - self.set_seq1(a) - self.set_seq2(b) - - def set_seq1(self, a): - """Set the first sequence to be compared. - - The second sequence to be compared is not changed. - - >>> s = SequenceMatcher(None, "abcd", "bcde") - >>> s.ratio() - 0.75 - >>> s.set_seq1("bcde") - >>> s.ratio() - 1.0 - >>> - - SequenceMatcher computes and caches detailed information about the - second sequence, so if you want to compare one sequence S against - many sequences, use .set_seq2(S) once and call .set_seq1(x) - repeatedly for each of the other sequences. - - See also set_seqs() and set_seq2(). - """ - - if a is self.a: - return - self.a = a - self.matching_blocks = self.opcodes = None - - def set_seq2(self, b): - """Set the second sequence to be compared. - - The first sequence to be compared is not changed. - - >>> s = SequenceMatcher(None, "abcd", "bcde") - >>> s.ratio() - 0.75 - >>> s.set_seq2("abcd") - >>> s.ratio() - 1.0 - >>> - - SequenceMatcher computes and caches detailed information about the - second sequence, so if you want to compare one sequence S against - many sequences, use .set_seq2(S) once and call .set_seq1(x) - repeatedly for each of the other sequences. - - See also set_seqs() and set_seq1(). - """ - - if b is self.b: - return - self.b = b - self.matching_blocks = self.opcodes = None - self.fullbcount = None - self.__chain_b() - - # For each element x in b, set b2j[x] to a list of the indices in - # b where x appears; the indices are in increasing order; note that - # the number of times x appears in b is len(b2j[x]) ... - # when self.isjunk is defined, junk elements don't show up in this - # map at all, which stops the central find_longest_match method - # from starting any matching block at a junk element ... - # b2j also does not contain entries for "popular" elements, meaning - # elements that account for more than 1 + 1% of the total elements, and - # when the sequence is reasonably large (>= 200 elements); this can - # be viewed as an adaptive notion of semi-junk, and yields an enormous - # speedup when, e.g., comparing program files with hundreds of - # instances of "return NULL;" ... - # note that this is only called when b changes; so for cross-product - # kinds of matches, it's best to call set_seq2 once, then set_seq1 - # repeatedly - - def __chain_b(self): - # Because isjunk is a user-defined (not C) function, and we test - # for junk a LOT, it's important to minimize the number of calls. - # Before the tricks described here, __chain_b was by far the most - # time-consuming routine in the whole module! If anyone sees - # Jim Roskind, thank him again for profile.py -- I never would - # have guessed that. - # The first trick is to build b2j ignoring the possibility - # of junk. I.e., we don't call isjunk at all yet. Throwing - # out the junk later is much cheaper than building b2j "right" - # from the start. - b = self.b - self.b2j = b2j = {} - - for i, elt in enumerate(b): - indices = b2j.setdefault(elt, []) - indices.append(i) - - # Purge junk elements - self.bjunk = junk = set() - isjunk = self.isjunk - if isjunk: - for elt in b2j.keys(): - if isjunk(elt): - junk.add(elt) - for elt in junk: # separate loop avoids separate list of keys - del b2j[elt] - - # Purge popular elements that are not junk - self.bpopular = popular = set() - n = len(b) - if self.autojunk and n >= 200: - ntest = n // 100 + 1 - for elt, idxs in b2j.items(): - if len(idxs) > ntest: - popular.add(elt) - for elt in popular: # ditto; as fast for 1% deletion - del b2j[elt] - - def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None): - """Find longest matching block in a[alo:ahi] and b[blo:bhi]. - - By default it will find the longest match in the entirety of a and b. - - If isjunk is not defined: - - Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where - alo <= i <= i+k <= ahi - blo <= j <= j+k <= bhi - and for all (i',j',k') meeting those conditions, - k >= k' - i <= i' - and if i == i', j <= j' - - In other words, of all maximal matching blocks, return one that - starts earliest in a, and of all those maximal matching blocks that - start earliest in a, return the one that starts earliest in b. - - >>> s = SequenceMatcher(None, " abcd", "abcd abcd") - >>> s.find_longest_match(0, 5, 0, 9) - Match(a=0, b=4, size=5) - - If isjunk is defined, first the longest matching block is - determined as above, but with the additional restriction that no - junk element appears in the block. Then that block is extended as - far as possible by matching (only) junk elements on both sides. So - the resulting block never matches on junk except as identical junk - happens to be adjacent to an "interesting" match. - - Here's the same example as before, but considering blanks to be - junk. That prevents " abcd" from matching the " abcd" at the tail - end of the second sequence directly. Instead only the "abcd" can - match, and matches the leftmost "abcd" in the second sequence: - - >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd") - >>> s.find_longest_match(0, 5, 0, 9) - Match(a=1, b=0, size=4) - - If no blocks match, return (alo, blo, 0). - - >>> s = SequenceMatcher(None, "ab", "c") - >>> s.find_longest_match(0, 2, 0, 1) - Match(a=0, b=0, size=0) - """ - - # CAUTION: stripping common prefix or suffix would be incorrect. - # E.g., - # ab - # acab - # Longest matching block is "ab", but if common prefix is - # stripped, it's "a" (tied with "b"). UNIX(tm) diff does so - # strip, so ends up claiming that ab is changed to acab by - # inserting "ca" in the middle. That's minimal but unintuitive: - # "it's obvious" that someone inserted "ac" at the front. - # Windiff ends up at the same place as diff, but by pairing up - # the unique 'b's and then matching the first two 'a's. - - a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.bjunk.__contains__ - if ahi is None: - ahi = len(a) - if bhi is None: - bhi = len(b) - besti, bestj, bestsize = alo, blo, 0 - # find longest junk-free match - # during an iteration of the loop, j2len[j] = length of longest - # junk-free match ending with a[i-1] and b[j] - j2len = {} - nothing = [] - for i in range(alo, ahi): - # look at all instances of a[i] in b; note that because - # b2j has no junk keys, the loop is skipped if a[i] is junk - j2lenget = j2len.get - newj2len = {} - for j in b2j.get(a[i], nothing): - # a[i] matches b[j] - if j < blo: - continue - if j >= bhi: - break - k = newj2len[j] = j2lenget(j-1, 0) + 1 - if k > bestsize: - besti, bestj, bestsize = i-k+1, j-k+1, k - j2len = newj2len - - # Extend the best by non-junk elements on each end. In particular, - # "popular" non-junk elements aren't in b2j, which greatly speeds - # the inner loop above, but also means "the best" match so far - # doesn't contain any junk *or* popular non-junk elements. - while besti > alo and bestj > blo and \ - not isbjunk(b[bestj-1]) and \ - a[besti-1] == b[bestj-1]: - besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 - while besti+bestsize < ahi and bestj+bestsize < bhi and \ - not isbjunk(b[bestj+bestsize]) and \ - a[besti+bestsize] == b[bestj+bestsize]: - bestsize += 1 - - # Now that we have a wholly interesting match (albeit possibly - # empty!), we may as well suck up the matching junk on each - # side of it too. Can't think of a good reason not to, and it - # saves post-processing the (possibly considerable) expense of - # figuring out what to do with it. In the case of an empty - # interesting match, this is clearly the right thing to do, - # because no other kind of match is possible in the regions. - while besti > alo and bestj > blo and \ - isbjunk(b[bestj-1]) and \ - a[besti-1] == b[bestj-1]: - besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 - while besti+bestsize < ahi and bestj+bestsize < bhi and \ - isbjunk(b[bestj+bestsize]) and \ - a[besti+bestsize] == b[bestj+bestsize]: - bestsize = bestsize + 1 - - return Match(besti, bestj, bestsize) - - def get_matching_blocks(self): - """Return list of triples describing matching subsequences. - - Each triple is of the form (i, j, n), and means that - a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in - i and in j. New in Python 2.5, it's also guaranteed that if - (i, j, n) and (i', j', n') are adjacent triples in the list, and - the second is not the last triple in the list, then i+n != i' or - j+n != j'. IOW, adjacent triples never describe adjacent equal - blocks. - - The last triple is a dummy, (len(a), len(b), 0), and is the only - triple with n==0. - - >>> s = SequenceMatcher(None, "abxcd", "abcd") - >>> list(s.get_matching_blocks()) - [Match(a=0, b=0, size=2), Match(a=3, b=2, size=2), Match(a=5, b=4, size=0)] - """ - - if self.matching_blocks is not None: - return self.matching_blocks - la, lb = len(self.a), len(self.b) - - # This is most naturally expressed as a recursive algorithm, but - # at least one user bumped into extreme use cases that exceeded - # the recursion limit on their box. So, now we maintain a list - # ('queue`) of blocks we still need to look at, and append partial - # results to `matching_blocks` in a loop; the matches are sorted - # at the end. - queue = [(0, la, 0, lb)] - matching_blocks = [] - while queue: - alo, ahi, blo, bhi = queue.pop() - i, j, k = x = self.find_longest_match(alo, ahi, blo, bhi) - # a[alo:i] vs b[blo:j] unknown - # a[i:i+k] same as b[j:j+k] - # a[i+k:ahi] vs b[j+k:bhi] unknown - if k: # if k is 0, there was no matching block - matching_blocks.append(x) - if alo < i and blo < j: - queue.append((alo, i, blo, j)) - if i+k < ahi and j+k < bhi: - queue.append((i+k, ahi, j+k, bhi)) - matching_blocks.sort() - - # It's possible that we have adjacent equal blocks in the - # matching_blocks list now. Starting with 2.5, this code was added - # to collapse them. - i1 = j1 = k1 = 0 - non_adjacent = [] - for i2, j2, k2 in matching_blocks: - # Is this block adjacent to i1, j1, k1? - if i1 + k1 == i2 and j1 + k1 == j2: - # Yes, so collapse them -- this just increases the length of - # the first block by the length of the second, and the first - # block so lengthened remains the block to compare against. - k1 += k2 - else: - # Not adjacent. Remember the first block (k1==0 means it's - # the dummy we started with), and make the second block the - # new block to compare against. - if k1: - non_adjacent.append((i1, j1, k1)) - i1, j1, k1 = i2, j2, k2 - if k1: - non_adjacent.append((i1, j1, k1)) - - non_adjacent.append( (la, lb, 0) ) - self.matching_blocks = list(map(Match._make, non_adjacent)) - return self.matching_blocks - - def get_opcodes(self): - """Return list of 5-tuples describing how to turn a into b. - - Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple - has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the - tuple preceding it, and likewise for j1 == the previous j2. - - The tags are strings, with these meanings: - - 'replace': a[i1:i2] should be replaced by b[j1:j2] - 'delete': a[i1:i2] should be deleted. - Note that j1==j2 in this case. - 'insert': b[j1:j2] should be inserted at a[i1:i1]. - Note that i1==i2 in this case. - 'equal': a[i1:i2] == b[j1:j2] - - >>> a = "qabxcd" - >>> b = "abycdf" - >>> s = SequenceMatcher(None, a, b) - >>> for tag, i1, i2, j1, j2 in s.get_opcodes(): - ... print(("%7s a[%d:%d] (%s) b[%d:%d] (%s)" % - ... (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2]))) - delete a[0:1] (q) b[0:0] () - equal a[1:3] (ab) b[0:2] (ab) - replace a[3:4] (x) b[2:3] (y) - equal a[4:6] (cd) b[3:5] (cd) - insert a[6:6] () b[5:6] (f) - """ - - if self.opcodes is not None: - return self.opcodes - i = j = 0 - self.opcodes = answer = [] - for ai, bj, size in self.get_matching_blocks(): - # invariant: we've pumped out correct diffs to change - # a[:i] into b[:j], and the next matching block is - # a[ai:ai+size] == b[bj:bj+size]. So we need to pump - # out a diff to change a[i:ai] into b[j:bj], pump out - # the matching block, and move (i,j) beyond the match - tag = '' - if i < ai and j < bj: - tag = 'replace' - elif i < ai: - tag = 'delete' - elif j < bj: - tag = 'insert' - if tag: - answer.append( (tag, i, ai, j, bj) ) - i, j = ai+size, bj+size - # the list of matching blocks is terminated by a - # sentinel with size 0 - if size: - answer.append( ('equal', ai, i, bj, j) ) - return answer - - def get_grouped_opcodes(self, n=3): - """ Isolate change clusters by eliminating ranges with no changes. - - Return a generator of groups with up to n lines of context. - Each group is in the same format as returned by get_opcodes(). - - >>> from pprint import pprint - >>> a = list(map(str, range(1,40))) - >>> b = a[:] - >>> b[8:8] = ['i'] # Make an insertion - >>> b[20] += 'x' # Make a replacement - >>> b[23:28] = [] # Make a deletion - >>> b[30] += 'y' # Make another replacement - >>> pprint(list(SequenceMatcher(None,a,b).get_grouped_opcodes())) - [[('equal', 5, 8, 5, 8), ('insert', 8, 8, 8, 9), ('equal', 8, 11, 9, 12)], - [('equal', 16, 19, 17, 20), - ('replace', 19, 20, 20, 21), - ('equal', 20, 22, 21, 23), - ('delete', 22, 27, 23, 23), - ('equal', 27, 30, 23, 26)], - [('equal', 31, 34, 27, 30), - ('replace', 34, 35, 30, 31), - ('equal', 35, 38, 31, 34)]] - """ - - codes = self.get_opcodes() - if not codes: - codes = [("equal", 0, 1, 0, 1)] - # Fixup leading and trailing groups if they show no changes. - if codes[0][0] == 'equal': - tag, i1, i2, j1, j2 = codes[0] - codes[0] = tag, max(i1, i2-n), i2, max(j1, j2-n), j2 - if codes[-1][0] == 'equal': - tag, i1, i2, j1, j2 = codes[-1] - codes[-1] = tag, i1, min(i2, i1+n), j1, min(j2, j1+n) - - nn = n + n - group = [] - for tag, i1, i2, j1, j2 in codes: - # End the current group and start a new one whenever - # there is a large range with no changes. - if tag == 'equal' and i2-i1 > nn: - group.append((tag, i1, min(i2, i1+n), j1, min(j2, j1+n))) - yield group - group = [] - i1, j1 = max(i1, i2-n), max(j1, j2-n) - group.append((tag, i1, i2, j1 ,j2)) - if group and not (len(group)==1 and group[0][0] == 'equal'): - yield group - - def ratio(self): - """Return a measure of the sequences' similarity (float in [0,1]). - - Where T is the total number of elements in both sequences, and - M is the number of matches, this is 2.0*M / T. - Note that this is 1 if the sequences are identical, and 0 if - they have nothing in common. - - .ratio() is expensive to compute if you haven't already computed - .get_matching_blocks() or .get_opcodes(), in which case you may - want to try .quick_ratio() or .real_quick_ratio() first to get an - upper bound. - - >>> s = SequenceMatcher(None, "abcd", "bcde") - >>> s.ratio() - 0.75 - >>> s.quick_ratio() - 0.75 - >>> s.real_quick_ratio() - 1.0 - """ - - matches = sum(triple[-1] for triple in self.get_matching_blocks()) - return _calculate_ratio(matches, len(self.a) + len(self.b)) - - def quick_ratio(self): - """Return an upper bound on ratio() relatively quickly. - - This isn't defined beyond that it is an upper bound on .ratio(), and - is faster to compute. - """ - - # viewing a and b as multisets, set matches to the cardinality - # of their intersection; this counts the number of matches - # without regard to order, so is clearly an upper bound - if self.fullbcount is None: - self.fullbcount = fullbcount = {} - for elt in self.b: - fullbcount[elt] = fullbcount.get(elt, 0) + 1 - fullbcount = self.fullbcount - # avail[x] is the number of times x appears in 'b' less the - # number of times we've seen it in 'a' so far ... kinda - avail = {} - availhas, matches = avail.__contains__, 0 - for elt in self.a: - if availhas(elt): - numb = avail[elt] - else: - numb = fullbcount.get(elt, 0) - avail[elt] = numb - 1 - if numb > 0: - matches = matches + 1 - return _calculate_ratio(matches, len(self.a) + len(self.b)) - - def real_quick_ratio(self): - """Return an upper bound on ratio() very quickly. - - This isn't defined beyond that it is an upper bound on .ratio(), and - is faster to compute than either .ratio() or .quick_ratio(). - """ - - la, lb = len(self.a), len(self.b) - # can't have more matches than the number of elements in the - # shorter sequence - return _calculate_ratio(min(la, lb), la + lb) - - __class_getitem__ = classmethod(GenericAlias) - - -def get_close_matches(word, possibilities, n=3, cutoff=0.6): - """Use SequenceMatcher to return list of the best "good enough" matches. - - word is a sequence for which close matches are desired (typically a - string). - - possibilities is a list of sequences against which to match word - (typically a list of strings). - - Optional arg n (default 3) is the maximum number of close matches to - return. n must be > 0. - - Optional arg cutoff (default 0.6) is a float in [0, 1]. Possibilities - that don't score at least that similar to word are ignored. - - The best (no more than n) matches among the possibilities are returned - in a list, sorted by similarity score, most similar first. - - >>> get_close_matches("appel", ["ape", "apple", "peach", "puppy"]) - ['apple', 'ape'] - >>> import keyword as _keyword - >>> get_close_matches("wheel", _keyword.kwlist) - ['while'] - >>> get_close_matches("Apple", _keyword.kwlist) - [] - >>> get_close_matches("accept", _keyword.kwlist) - ['except'] - """ - - if not n > 0: - raise ValueError("n must be > 0: %r" % (n,)) - if not 0.0 <= cutoff <= 1.0: - raise ValueError("cutoff must be in [0.0, 1.0]: %r" % (cutoff,)) - result = [] - s = SequenceMatcher() - s.set_seq2(word) - for x in possibilities: - s.set_seq1(x) - if s.real_quick_ratio() >= cutoff and \ - s.quick_ratio() >= cutoff and \ - s.ratio() >= cutoff: - result.append((s.ratio(), x)) - - # Move the best scorers to head of list - result = _nlargest(n, result) - # Strip scores for the best n matches - return [x for score, x in result] - - -def _keep_original_ws(s, tag_s): - """Replace whitespace with the original whitespace characters in `s`""" - return ''.join( - c if tag_c == " " and c.isspace() else tag_c - for c, tag_c in zip(s, tag_s) - ) - - - -class Differ: - r""" - Differ is a class for comparing sequences of lines of text, and - producing human-readable differences or deltas. Differ uses - SequenceMatcher both to compare sequences of lines, and to compare - sequences of characters within similar (near-matching) lines. - - Each line of a Differ delta begins with a two-letter code: - - '- ' line unique to sequence 1 - '+ ' line unique to sequence 2 - ' ' line common to both sequences - '? ' line not present in either input sequence - - Lines beginning with '? ' attempt to guide the eye to intraline - differences, and were not present in either input sequence. These lines - can be confusing if the sequences contain tab characters. - - Note that Differ makes no claim to produce a *minimal* diff. To the - contrary, minimal diffs are often counter-intuitive, because they synch - up anywhere possible, sometimes accidental matches 100 pages apart. - Restricting synch points to contiguous matches preserves some notion of - locality, at the occasional cost of producing a longer diff. - - Example: Comparing two texts. - - First we set up the texts, sequences of individual single-line strings - ending with newlines (such sequences can also be obtained from the - `readlines()` method of file-like objects): - - >>> text1 = ''' 1. Beautiful is better than ugly. - ... 2. Explicit is better than implicit. - ... 3. Simple is better than complex. - ... 4. Complex is better than complicated. - ... '''.splitlines(keepends=True) - >>> len(text1) - 4 - >>> text1[0][-1] - '\n' - >>> text2 = ''' 1. Beautiful is better than ugly. - ... 3. Simple is better than complex. - ... 4. Complicated is better than complex. - ... 5. Flat is better than nested. - ... '''.splitlines(keepends=True) - - Next we instantiate a Differ object: - - >>> d = Differ() - - Note that when instantiating a Differ object we may pass functions to - filter out line and character 'junk'. See Differ.__init__ for details. - - Finally, we compare the two: - - >>> result = list(d.compare(text1, text2)) - - 'result' is a list of strings, so let's pretty-print it: - - >>> from pprint import pprint as _pprint - >>> _pprint(result) - [' 1. Beautiful is better than ugly.\n', - '- 2. Explicit is better than implicit.\n', - '- 3. Simple is better than complex.\n', - '+ 3. Simple is better than complex.\n', - '? ++\n', - '- 4. Complex is better than complicated.\n', - '? ^ ---- ^\n', - '+ 4. Complicated is better than complex.\n', - '? ++++ ^ ^\n', - '+ 5. Flat is better than nested.\n'] - - As a single multi-line string it looks like this: - - >>> print(''.join(result), end="") - 1. Beautiful is better than ugly. - - 2. Explicit is better than implicit. - - 3. Simple is better than complex. - + 3. Simple is better than complex. - ? ++ - - 4. Complex is better than complicated. - ? ^ ---- ^ - + 4. Complicated is better than complex. - ? ++++ ^ ^ - + 5. Flat is better than nested. - """ - - def __init__(self, linejunk=None, charjunk=None): - """ - Construct a text differencer, with optional filters. - - The two optional keyword parameters are for filter functions: - - - `linejunk`: A function that should accept a single string argument, - and return true iff the string is junk. The module-level function - `IS_LINE_JUNK` may be used to filter out lines without visible - characters, except for at most one splat ('#'). It is recommended - to leave linejunk None; the underlying SequenceMatcher class has - an adaptive notion of "noise" lines that's better than any static - definition the author has ever been able to craft. - - - `charjunk`: A function that should accept a string of length 1. The - module-level function `IS_CHARACTER_JUNK` may be used to filter out - whitespace characters (a blank or tab; **note**: bad idea to include - newline in this!). Use of IS_CHARACTER_JUNK is recommended. - """ - - self.linejunk = linejunk - self.charjunk = charjunk - - def compare(self, a, b): - r""" - Compare two sequences of lines; generate the resulting delta. - - Each sequence must contain individual single-line strings ending with - newlines. Such sequences can be obtained from the `readlines()` method - of file-like objects. The delta generated also consists of newline- - terminated strings, ready to be printed as-is via the writelines() - method of a file-like object. - - Example: - - >>> print(''.join(Differ().compare('one\ntwo\nthree\n'.splitlines(True), - ... 'ore\ntree\nemu\n'.splitlines(True))), - ... end="") - - one - ? ^ - + ore - ? ^ - - two - - three - ? - - + tree - + emu - """ - - cruncher = SequenceMatcher(self.linejunk, a, b) - for tag, alo, ahi, blo, bhi in cruncher.get_opcodes(): - if tag == 'replace': - g = self._fancy_replace(a, alo, ahi, b, blo, bhi) - elif tag == 'delete': - g = self._dump('-', a, alo, ahi) - elif tag == 'insert': - g = self._dump('+', b, blo, bhi) - elif tag == 'equal': - g = self._dump(' ', a, alo, ahi) - else: - raise ValueError('unknown tag %r' % (tag,)) - - yield from g - - def _dump(self, tag, x, lo, hi): - """Generate comparison results for a same-tagged range.""" - for i in range(lo, hi): - yield '%s %s' % (tag, x[i]) - - def _plain_replace(self, a, alo, ahi, b, blo, bhi): - assert alo < ahi and blo < bhi - # dump the shorter block first -- reduces the burden on short-term - # memory if the blocks are of very different sizes - if bhi - blo < ahi - alo: - first = self._dump('+', b, blo, bhi) - second = self._dump('-', a, alo, ahi) - else: - first = self._dump('-', a, alo, ahi) - second = self._dump('+', b, blo, bhi) - - for g in first, second: - yield from g - - def _fancy_replace(self, a, alo, ahi, b, blo, bhi): - r""" - When replacing one block of lines with another, search the blocks - for *similar* lines; the best-matching pair (if any) is used as a - synch point, and intraline difference marking is done on the - similar pair. Lots of work, but often worth it. - - Example: - - >>> d = Differ() - >>> results = d._fancy_replace(['abcDefghiJkl\n'], 0, 1, - ... ['abcdefGhijkl\n'], 0, 1) - >>> print(''.join(results), end="") - - abcDefghiJkl - ? ^ ^ ^ - + abcdefGhijkl - ? ^ ^ ^ - """ - - # don't synch up unless the lines have a similarity score of at - # least cutoff; best_ratio tracks the best score seen so far - best_ratio, cutoff = 0.74, 0.75 - cruncher = SequenceMatcher(self.charjunk) - eqi, eqj = None, None # 1st indices of equal lines (if any) - - # search for the pair that matches best without being identical - # (identical lines must be junk lines, & we don't want to synch up - # on junk -- unless we have to) - for j in range(blo, bhi): - bj = b[j] - cruncher.set_seq2(bj) - for i in range(alo, ahi): - ai = a[i] - if ai == bj: - if eqi is None: - eqi, eqj = i, j - continue - cruncher.set_seq1(ai) - # computing similarity is expensive, so use the quick - # upper bounds first -- have seen this speed up messy - # compares by a factor of 3. - # note that ratio() is only expensive to compute the first - # time it's called on a sequence pair; the expensive part - # of the computation is cached by cruncher - if cruncher.real_quick_ratio() > best_ratio and \ - cruncher.quick_ratio() > best_ratio and \ - cruncher.ratio() > best_ratio: - best_ratio, best_i, best_j = cruncher.ratio(), i, j - if best_ratio < cutoff: - # no non-identical "pretty close" pair - if eqi is None: - # no identical pair either -- treat it as a straight replace - yield from self._plain_replace(a, alo, ahi, b, blo, bhi) - return - # no close pair, but an identical pair -- synch up on that - best_i, best_j, best_ratio = eqi, eqj, 1.0 - else: - # there's a close pair, so forget the identical pair (if any) - eqi = None - - # a[best_i] very similar to b[best_j]; eqi is None iff they're not - # identical - - # pump out diffs from before the synch point - yield from self._fancy_helper(a, alo, best_i, b, blo, best_j) - - # do intraline marking on the synch pair - aelt, belt = a[best_i], b[best_j] - if eqi is None: - # pump out a '-', '?', '+', '?' quad for the synched lines - atags = btags = "" - cruncher.set_seqs(aelt, belt) - for tag, ai1, ai2, bj1, bj2 in cruncher.get_opcodes(): - la, lb = ai2 - ai1, bj2 - bj1 - if tag == 'replace': - atags += '^' * la - btags += '^' * lb - elif tag == 'delete': - atags += '-' * la - elif tag == 'insert': - btags += '+' * lb - elif tag == 'equal': - atags += ' ' * la - btags += ' ' * lb - else: - raise ValueError('unknown tag %r' % (tag,)) - yield from self._qformat(aelt, belt, atags, btags) - else: - # the synch pair is identical - yield ' ' + aelt - - # pump out diffs from after the synch point - yield from self._fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi) - - def _fancy_helper(self, a, alo, ahi, b, blo, bhi): - g = [] - if alo < ahi: - if blo < bhi: - g = self._fancy_replace(a, alo, ahi, b, blo, bhi) - else: - g = self._dump('-', a, alo, ahi) - elif blo < bhi: - g = self._dump('+', b, blo, bhi) - - yield from g - - def _qformat(self, aline, bline, atags, btags): - r""" - Format "?" output and deal with tabs. - - Example: - - >>> d = Differ() - >>> results = d._qformat('\tabcDefghiJkl\n', '\tabcdefGhijkl\n', - ... ' ^ ^ ^ ', ' ^ ^ ^ ') - >>> for line in results: print(repr(line)) - ... - '- \tabcDefghiJkl\n' - '? \t ^ ^ ^\n' - '+ \tabcdefGhijkl\n' - '? \t ^ ^ ^\n' - """ - atags = _keep_original_ws(aline, atags).rstrip() - btags = _keep_original_ws(bline, btags).rstrip() - - yield "- " + aline - if atags: - yield f"? {atags}\n" - - yield "+ " + bline - if btags: - yield f"? {btags}\n" - -# With respect to junk, an earlier version of ndiff simply refused to -# *start* a match with a junk element. The result was cases like this: -# before: private Thread currentThread; -# after: private volatile Thread currentThread; -# If you consider whitespace to be junk, the longest contiguous match -# not starting with junk is "e Thread currentThread". So ndiff reported -# that "e volatil" was inserted between the 't' and the 'e' in "private". -# While an accurate view, to people that's absurd. The current version -# looks for matching blocks that are entirely junk-free, then extends the -# longest one of those as far as possible but only with matching junk. -# So now "currentThread" is matched, then extended to suck up the -# preceding blank; then "private" is matched, and extended to suck up the -# following blank; then "Thread" is matched; and finally ndiff reports -# that "volatile " was inserted before "Thread". The only quibble -# remaining is that perhaps it was really the case that " volatile" -# was inserted after "private". I can live with that . - -import re - -def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match): - r""" - Return True for ignorable line: iff `line` is blank or contains a single '#'. - - Examples: - - >>> IS_LINE_JUNK('\n') - True - >>> IS_LINE_JUNK(' # \n') - True - >>> IS_LINE_JUNK('hello\n') - False - """ - - return pat(line) is not None - -def IS_CHARACTER_JUNK(ch, ws=" \t"): - r""" - Return True for ignorable character: iff `ch` is a space or tab. - - Examples: - - >>> IS_CHARACTER_JUNK(' ') - True - >>> IS_CHARACTER_JUNK('\t') - True - >>> IS_CHARACTER_JUNK('\n') - False - >>> IS_CHARACTER_JUNK('x') - False - """ - - return ch in ws - - -######################################################################## -### Unified Diff -######################################################################## - -def _format_range_unified(start, stop): - 'Convert range to the "ed" format' - # Per the diff spec at http://www.unix.org/single_unix_specification/ - beginning = start + 1 # lines start numbering with one - length = stop - start - if length == 1: - return '{}'.format(beginning) - if not length: - beginning -= 1 # empty ranges begin at line just before the range - return '{},{}'.format(beginning, length) - -def unified_diff(a, b, fromfile='', tofile='', fromfiledate='', - tofiledate='', n=3, lineterm='\n'): - r""" - Compare two sequences of lines; generate the delta as a unified diff. - - Unified diffs are a compact way of showing line changes and a few - lines of context. The number of context lines is set by 'n' which - defaults to three. - - By default, the diff control lines (those with ---, +++, or @@) are - created with a trailing newline. This is helpful so that inputs - created from file.readlines() result in diffs that are suitable for - file.writelines() since both the inputs and outputs have trailing - newlines. - - For inputs that do not have trailing newlines, set the lineterm - argument to "" so that the output will be uniformly newline free. - - The unidiff format normally has a header for filenames and modification - times. Any or all of these may be specified using strings for - 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. - The modification times are normally expressed in the ISO 8601 format. - - Example: - - >>> for line in unified_diff('one two three four'.split(), - ... 'zero one tree four'.split(), 'Original', 'Current', - ... '2005-01-26 23:30:50', '2010-04-02 10:20:52', - ... lineterm=''): - ... print(line) # doctest: +NORMALIZE_WHITESPACE - --- Original 2005-01-26 23:30:50 - +++ Current 2010-04-02 10:20:52 - @@ -1,4 +1,4 @@ - +zero - one - -two - -three - +tree - four - """ - - _check_types(a, b, fromfile, tofile, fromfiledate, tofiledate, lineterm) - started = False - for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): - if not started: - started = True - fromdate = '\t{}'.format(fromfiledate) if fromfiledate else '' - todate = '\t{}'.format(tofiledate) if tofiledate else '' - yield '--- {}{}{}'.format(fromfile, fromdate, lineterm) - yield '+++ {}{}{}'.format(tofile, todate, lineterm) - - first, last = group[0], group[-1] - file1_range = _format_range_unified(first[1], last[2]) - file2_range = _format_range_unified(first[3], last[4]) - yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm) - - for tag, i1, i2, j1, j2 in group: - if tag == 'equal': - for line in a[i1:i2]: - yield ' ' + line - continue - if tag in {'replace', 'delete'}: - for line in a[i1:i2]: - yield '-' + line - if tag in {'replace', 'insert'}: - for line in b[j1:j2]: - yield '+' + line - - -######################################################################## -### Context Diff -######################################################################## - -def _format_range_context(start, stop): - 'Convert range to the "ed" format' - # Per the diff spec at http://www.unix.org/single_unix_specification/ - beginning = start + 1 # lines start numbering with one - length = stop - start - if not length: - beginning -= 1 # empty ranges begin at line just before the range - if length <= 1: - return '{}'.format(beginning) - return '{},{}'.format(beginning, beginning + length - 1) - -# See http://www.unix.org/single_unix_specification/ -def context_diff(a, b, fromfile='', tofile='', - fromfiledate='', tofiledate='', n=3, lineterm='\n'): - r""" - Compare two sequences of lines; generate the delta as a context diff. - - Context diffs are a compact way of showing line changes and a few - lines of context. The number of context lines is set by 'n' which - defaults to three. - - By default, the diff control lines (those with *** or ---) are - created with a trailing newline. This is helpful so that inputs - created from file.readlines() result in diffs that are suitable for - file.writelines() since both the inputs and outputs have trailing - newlines. - - For inputs that do not have trailing newlines, set the lineterm - argument to "" so that the output will be uniformly newline free. - - The context diff format normally has a header for filenames and - modification times. Any or all of these may be specified using - strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. - The modification times are normally expressed in the ISO 8601 format. - If not specified, the strings default to blanks. - - Example: - - >>> print(''.join(context_diff('one\ntwo\nthree\nfour\n'.splitlines(True), - ... 'zero\none\ntree\nfour\n'.splitlines(True), 'Original', 'Current')), - ... end="") - *** Original - --- Current - *************** - *** 1,4 **** - one - ! two - ! three - four - --- 1,4 ---- - + zero - one - ! tree - four - """ - - _check_types(a, b, fromfile, tofile, fromfiledate, tofiledate, lineterm) - prefix = dict(insert='+ ', delete='- ', replace='! ', equal=' ') - started = False - for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): - if not started: - started = True - fromdate = '\t{}'.format(fromfiledate) if fromfiledate else '' - todate = '\t{}'.format(tofiledate) if tofiledate else '' - yield '*** {}{}{}'.format(fromfile, fromdate, lineterm) - yield '--- {}{}{}'.format(tofile, todate, lineterm) - - first, last = group[0], group[-1] - yield '***************' + lineterm - - file1_range = _format_range_context(first[1], last[2]) - yield '*** {} ****{}'.format(file1_range, lineterm) - - if any(tag in {'replace', 'delete'} for tag, _, _, _, _ in group): - for tag, i1, i2, _, _ in group: - if tag != 'insert': - for line in a[i1:i2]: - yield prefix[tag] + line - - file2_range = _format_range_context(first[3], last[4]) - yield '--- {} ----{}'.format(file2_range, lineterm) - - if any(tag in {'replace', 'insert'} for tag, _, _, _, _ in group): - for tag, _, _, j1, j2 in group: - if tag != 'delete': - for line in b[j1:j2]: - yield prefix[tag] + line - -def _check_types(a, b, *args): - # Checking types is weird, but the alternative is garbled output when - # someone passes mixed bytes and str to {unified,context}_diff(). E.g. - # without this check, passing filenames as bytes results in output like - # --- b'oldfile.txt' - # +++ b'newfile.txt' - # because of how str.format() incorporates bytes objects. - if a and not isinstance(a[0], str): - raise TypeError('lines to compare must be str, not %s (%r)' % - (type(a[0]).__name__, a[0])) - if b and not isinstance(b[0], str): - raise TypeError('lines to compare must be str, not %s (%r)' % - (type(b[0]).__name__, b[0])) - for arg in args: - if not isinstance(arg, str): - raise TypeError('all arguments must be str, not: %r' % (arg,)) - -def diff_bytes(dfunc, a, b, fromfile=b'', tofile=b'', - fromfiledate=b'', tofiledate=b'', n=3, lineterm=b'\n'): - r""" - Compare `a` and `b`, two sequences of lines represented as bytes rather - than str. This is a wrapper for `dfunc`, which is typically either - unified_diff() or context_diff(). Inputs are losslessly converted to - strings so that `dfunc` only has to worry about strings, and encoded - back to bytes on return. This is necessary to compare files with - unknown or inconsistent encoding. All other inputs (except `n`) must be - bytes rather than str. - """ - def decode(s): - try: - return s.decode('ascii', 'surrogateescape') - except AttributeError as err: - msg = ('all arguments must be bytes, not %s (%r)' % - (type(s).__name__, s)) - raise TypeError(msg) from err - a = list(map(decode, a)) - b = list(map(decode, b)) - fromfile = decode(fromfile) - tofile = decode(tofile) - fromfiledate = decode(fromfiledate) - tofiledate = decode(tofiledate) - lineterm = decode(lineterm) - - lines = dfunc(a, b, fromfile, tofile, fromfiledate, tofiledate, n, lineterm) - for line in lines: - yield line.encode('ascii', 'surrogateescape') - -def ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK): - r""" - Compare `a` and `b` (lists of strings); return a `Differ`-style delta. - - Optional keyword parameters `linejunk` and `charjunk` are for filter - functions, or can be None: - - - linejunk: A function that should accept a single string argument and - return true iff the string is junk. The default is None, and is - recommended; the underlying SequenceMatcher class has an adaptive - notion of "noise" lines. - - - charjunk: A function that accepts a character (string of length - 1), and returns true iff the character is junk. The default is - the module-level function IS_CHARACTER_JUNK, which filters out - whitespace characters (a blank or tab; note: it's a bad idea to - include newline in this!). - - Tools/scripts/ndiff.py is a command-line front-end to this function. - - Example: - - >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(keepends=True), - ... 'ore\ntree\nemu\n'.splitlines(keepends=True)) - >>> print(''.join(diff), end="") - - one - ? ^ - + ore - ? ^ - - two - - three - ? - - + tree - + emu - """ - return Differ(linejunk, charjunk).compare(a, b) - -def _mdiff(fromlines, tolines, context=None, linejunk=None, - charjunk=IS_CHARACTER_JUNK): - r"""Returns generator yielding marked up from/to side by side differences. - - Arguments: - fromlines -- list of text lines to compared to tolines - tolines -- list of text lines to be compared to fromlines - context -- number of context lines to display on each side of difference, - if None, all from/to text lines will be generated. - linejunk -- passed on to ndiff (see ndiff documentation) - charjunk -- passed on to ndiff (see ndiff documentation) - - This function returns an iterator which returns a tuple: - (from line tuple, to line tuple, boolean flag) - - from/to line tuple -- (line num, line text) - line num -- integer or None (to indicate a context separation) - line text -- original line text with following markers inserted: - '\0+' -- marks start of added text - '\0-' -- marks start of deleted text - '\0^' -- marks start of changed text - '\1' -- marks end of added/deleted/changed text - - boolean flag -- None indicates context separation, True indicates - either "from" or "to" line contains a change, otherwise False. - - This function/iterator was originally developed to generate side by side - file difference for making HTML pages (see HtmlDiff class for example - usage). - - Note, this function utilizes the ndiff function to generate the side by - side difference markup. Optional ndiff arguments may be passed to this - function and they in turn will be passed to ndiff. - """ - import re - - # regular expression for finding intraline change indices - change_re = re.compile(r'(\++|\-+|\^+)') - - # create the difference iterator to generate the differences - diff_lines_iterator = ndiff(fromlines,tolines,linejunk,charjunk) - - def _make_line(lines, format_key, side, num_lines=[0,0]): - """Returns line of text with user's change markup and line formatting. - - lines -- list of lines from the ndiff generator to produce a line of - text from. When producing the line of text to return, the - lines used are removed from this list. - format_key -- '+' return first line in list with "add" markup around - the entire line. - '-' return first line in list with "delete" markup around - the entire line. - '?' return first line in list with add/delete/change - intraline markup (indices obtained from second line) - None return first line in list with no markup - side -- indice into the num_lines list (0=from,1=to) - num_lines -- from/to current line number. This is NOT intended to be a - passed parameter. It is present as a keyword argument to - maintain memory of the current line numbers between calls - of this function. - - Note, this function is purposefully not defined at the module scope so - that data it needs from its parent function (within whose context it - is defined) does not need to be of module scope. - """ - num_lines[side] += 1 - # Handle case where no user markup is to be added, just return line of - # text with user's line format to allow for usage of the line number. - if format_key is None: - return (num_lines[side],lines.pop(0)[2:]) - # Handle case of intraline changes - if format_key == '?': - text, markers = lines.pop(0), lines.pop(0) - # find intraline changes (store change type and indices in tuples) - sub_info = [] - def record_sub_info(match_object,sub_info=sub_info): - sub_info.append([match_object.group(1)[0],match_object.span()]) - return match_object.group(1) - change_re.sub(record_sub_info,markers) - # process each tuple inserting our special marks that won't be - # noticed by an xml/html escaper. - for key,(begin,end) in reversed(sub_info): - text = text[0:begin]+'\0'+key+text[begin:end]+'\1'+text[end:] - text = text[2:] - # Handle case of add/delete entire line - else: - text = lines.pop(0)[2:] - # if line of text is just a newline, insert a space so there is - # something for the user to highlight and see. - if not text: - text = ' ' - # insert marks that won't be noticed by an xml/html escaper. - text = '\0' + format_key + text + '\1' - # Return line of text, first allow user's line formatter to do its - # thing (such as adding the line number) then replace the special - # marks with what the user's change markup. - return (num_lines[side],text) - - def _line_iterator(): - """Yields from/to lines of text with a change indication. - - This function is an iterator. It itself pulls lines from a - differencing iterator, processes them and yields them. When it can - it yields both a "from" and a "to" line, otherwise it will yield one - or the other. In addition to yielding the lines of from/to text, a - boolean flag is yielded to indicate if the text line(s) have - differences in them. - - Note, this function is purposefully not defined at the module scope so - that data it needs from its parent function (within whose context it - is defined) does not need to be of module scope. - """ - lines = [] - num_blanks_pending, num_blanks_to_yield = 0, 0 - while True: - # Load up next 4 lines so we can look ahead, create strings which - # are a concatenation of the first character of each of the 4 lines - # so we can do some very readable comparisons. - while len(lines) < 4: - lines.append(next(diff_lines_iterator, 'X')) - s = ''.join([line[0] for line in lines]) - if s.startswith('X'): - # When no more lines, pump out any remaining blank lines so the - # corresponding add/delete lines get a matching blank line so - # all line pairs get yielded at the next level. - num_blanks_to_yield = num_blanks_pending - elif s.startswith('-?+?'): - # simple intraline change - yield _make_line(lines,'?',0), _make_line(lines,'?',1), True - continue - elif s.startswith('--++'): - # in delete block, add block coming: we do NOT want to get - # caught up on blank lines yet, just process the delete line - num_blanks_pending -= 1 - yield _make_line(lines,'-',0), None, True - continue - elif s.startswith(('--?+', '--+', '- ')): - # in delete block and see an intraline change or unchanged line - # coming: yield the delete line and then blanks - from_line,to_line = _make_line(lines,'-',0), None - num_blanks_to_yield,num_blanks_pending = num_blanks_pending-1,0 - elif s.startswith('-+?'): - # intraline change - yield _make_line(lines,None,0), _make_line(lines,'?',1), True - continue - elif s.startswith('-?+'): - # intraline change - yield _make_line(lines,'?',0), _make_line(lines,None,1), True - continue - elif s.startswith('-'): - # delete FROM line - num_blanks_pending -= 1 - yield _make_line(lines,'-',0), None, True - continue - elif s.startswith('+--'): - # in add block, delete block coming: we do NOT want to get - # caught up on blank lines yet, just process the add line - num_blanks_pending += 1 - yield None, _make_line(lines,'+',1), True - continue - elif s.startswith(('+ ', '+-')): - # will be leaving an add block: yield blanks then add line - from_line, to_line = None, _make_line(lines,'+',1) - num_blanks_to_yield,num_blanks_pending = num_blanks_pending+1,0 - elif s.startswith('+'): - # inside an add block, yield the add line - num_blanks_pending += 1 - yield None, _make_line(lines,'+',1), True - continue - elif s.startswith(' '): - # unchanged text, yield it to both sides - yield _make_line(lines[:],None,0),_make_line(lines,None,1),False - continue - # Catch up on the blank lines so when we yield the next from/to - # pair, they are lined up. - while(num_blanks_to_yield < 0): - num_blanks_to_yield += 1 - yield None,('','\n'),True - while(num_blanks_to_yield > 0): - num_blanks_to_yield -= 1 - yield ('','\n'),None,True - if s.startswith('X'): - return - else: - yield from_line,to_line,True - - def _line_pair_iterator(): - """Yields from/to lines of text with a change indication. - - This function is an iterator. It itself pulls lines from the line - iterator. Its difference from that iterator is that this function - always yields a pair of from/to text lines (with the change - indication). If necessary it will collect single from/to lines - until it has a matching pair from/to pair to yield. - - Note, this function is purposefully not defined at the module scope so - that data it needs from its parent function (within whose context it - is defined) does not need to be of module scope. - """ - line_iterator = _line_iterator() - fromlines,tolines=[],[] - while True: - # Collecting lines of text until we have a from/to pair - while (len(fromlines)==0 or len(tolines)==0): - try: - from_line, to_line, found_diff = next(line_iterator) - except StopIteration: - return - if from_line is not None: - fromlines.append((from_line,found_diff)) - if to_line is not None: - tolines.append((to_line,found_diff)) - # Once we have a pair, remove them from the collection and yield it - from_line, fromDiff = fromlines.pop(0) - to_line, to_diff = tolines.pop(0) - yield (from_line,to_line,fromDiff or to_diff) - - # Handle case where user does not want context differencing, just yield - # them up without doing anything else with them. - line_pair_iterator = _line_pair_iterator() - if context is None: - yield from line_pair_iterator - # Handle case where user wants context differencing. We must do some - # storage of lines until we know for sure that they are to be yielded. - else: - context += 1 - lines_to_write = 0 - while True: - # Store lines up until we find a difference, note use of a - # circular queue because we only need to keep around what - # we need for context. - index, contextLines = 0, [None]*(context) - found_diff = False - while(found_diff is False): - try: - from_line, to_line, found_diff = next(line_pair_iterator) - except StopIteration: - return - i = index % context - contextLines[i] = (from_line, to_line, found_diff) - index += 1 - # Yield lines that we have collected so far, but first yield - # the user's separator. - if index > context: - yield None, None, None - lines_to_write = context - else: - lines_to_write = index - index = 0 - while(lines_to_write): - i = index % context - index += 1 - yield contextLines[i] - lines_to_write -= 1 - # Now yield the context lines after the change - lines_to_write = context-1 - try: - while(lines_to_write): - from_line, to_line, found_diff = next(line_pair_iterator) - # If another change within the context, extend the context - if found_diff: - lines_to_write = context-1 - else: - lines_to_write -= 1 - yield from_line, to_line, found_diff - except StopIteration: - # Catch exception from next() and return normally - return - - -_file_template = """ - - - - - - - - - - - - %(table)s%(legend)s - - -""" - -_styles = """ - table.diff {font-family:Courier; border:medium;} - .diff_header {background-color:#e0e0e0} - td.diff_header {text-align:right} - .diff_next {background-color:#c0c0c0} - .diff_add {background-color:#aaffaa} - .diff_chg {background-color:#ffff77} - .diff_sub {background-color:#ffaaaa}""" - -_table_template = """ - - - - %(header_row)s - -%(data_rows)s -
    """ - -_legend = """ - - - - -
    Legends
    - - - - -
    Colors
     Added 
    Changed
    Deleted
    - - - - -
    Links
    (f)irst change
    (n)ext change
    (t)op
    """ - -class HtmlDiff(object): - """For producing HTML side by side comparison with change highlights. - - This class can be used to create an HTML table (or a complete HTML file - containing the table) showing a side by side, line by line comparison - of text with inter-line and intra-line change highlights. The table can - be generated in either full or contextual difference mode. - - The following methods are provided for HTML generation: - - make_table -- generates HTML for a single side by side table - make_file -- generates complete HTML file with a single side by side table - - See tools/scripts/diff.py for an example usage of this class. - """ - - _file_template = _file_template - _styles = _styles - _table_template = _table_template - _legend = _legend - _default_prefix = 0 - - def __init__(self,tabsize=8,wrapcolumn=None,linejunk=None, - charjunk=IS_CHARACTER_JUNK): - """HtmlDiff instance initializer - - Arguments: - tabsize -- tab stop spacing, defaults to 8. - wrapcolumn -- column number where lines are broken and wrapped, - defaults to None where lines are not wrapped. - linejunk,charjunk -- keyword arguments passed into ndiff() (used by - HtmlDiff() to generate the side by side HTML differences). See - ndiff() documentation for argument default values and descriptions. - """ - self._tabsize = tabsize - self._wrapcolumn = wrapcolumn - self._linejunk = linejunk - self._charjunk = charjunk - - def make_file(self, fromlines, tolines, fromdesc='', todesc='', - context=False, numlines=5, *, charset='utf-8'): - """Returns HTML file of side by side comparison with change highlights - - Arguments: - fromlines -- list of "from" lines - tolines -- list of "to" lines - fromdesc -- "from" file column header string - todesc -- "to" file column header string - context -- set to True for contextual differences (defaults to False - which shows full differences). - numlines -- number of context lines. When context is set True, - controls number of lines displayed before and after the change. - When context is False, controls the number of lines to place - the "next" link anchors before the next change (so click of - "next" link jumps to just before the change). - charset -- charset of the HTML document - """ - - return (self._file_template % dict( - styles=self._styles, - legend=self._legend, - table=self.make_table(fromlines, tolines, fromdesc, todesc, - context=context, numlines=numlines), - charset=charset - )).encode(charset, 'xmlcharrefreplace').decode(charset) - - def _tab_newline_replace(self,fromlines,tolines): - """Returns from/to line lists with tabs expanded and newlines removed. - - Instead of tab characters being replaced by the number of spaces - needed to fill in to the next tab stop, this function will fill - the space with tab characters. This is done so that the difference - algorithms can identify changes in a file when tabs are replaced by - spaces and vice versa. At the end of the HTML generation, the tab - characters will be replaced with a nonbreakable space. - """ - def expand_tabs(line): - # hide real spaces - line = line.replace(' ','\0') - # expand tabs into spaces - line = line.expandtabs(self._tabsize) - # replace spaces from expanded tabs back into tab characters - # (we'll replace them with markup after we do differencing) - line = line.replace(' ','\t') - return line.replace('\0',' ').rstrip('\n') - fromlines = [expand_tabs(line) for line in fromlines] - tolines = [expand_tabs(line) for line in tolines] - return fromlines,tolines - - def _split_line(self,data_list,line_num,text): - """Builds list of text lines by splitting text lines at wrap point - - This function will determine if the input text line needs to be - wrapped (split) into separate lines. If so, the first wrap point - will be determined and the first line appended to the output - text line list. This function is used recursively to handle - the second part of the split line to further split it. - """ - # if blank line or context separator, just add it to the output list - if not line_num: - data_list.append((line_num,text)) - return - - # if line text doesn't need wrapping, just add it to the output list - size = len(text) - max = self._wrapcolumn - if (size <= max) or ((size -(text.count('\0')*3)) <= max): - data_list.append((line_num,text)) - return - - # scan text looking for the wrap point, keeping track if the wrap - # point is inside markers - i = 0 - n = 0 - mark = '' - while n < max and i < size: - if text[i] == '\0': - i += 1 - mark = text[i] - i += 1 - elif text[i] == '\1': - i += 1 - mark = '' - else: - i += 1 - n += 1 - - # wrap point is inside text, break it up into separate lines - line1 = text[:i] - line2 = text[i:] - - # if wrap point is inside markers, place end marker at end of first - # line and start marker at beginning of second line because each - # line will have its own table tag markup around it. - if mark: - line1 = line1 + '\1' - line2 = '\0' + mark + line2 - - # tack on first line onto the output list - data_list.append((line_num,line1)) - - # use this routine again to wrap the remaining text - self._split_line(data_list,'>',line2) - - def _line_wrapper(self,diffs): - """Returns iterator that splits (wraps) mdiff text lines""" - - # pull from/to data and flags from mdiff iterator - for fromdata,todata,flag in diffs: - # check for context separators and pass them through - if flag is None: - yield fromdata,todata,flag - continue - (fromline,fromtext),(toline,totext) = fromdata,todata - # for each from/to line split it at the wrap column to form - # list of text lines. - fromlist,tolist = [],[] - self._split_line(fromlist,fromline,fromtext) - self._split_line(tolist,toline,totext) - # yield from/to line in pairs inserting blank lines as - # necessary when one side has more wrapped lines - while fromlist or tolist: - if fromlist: - fromdata = fromlist.pop(0) - else: - fromdata = ('',' ') - if tolist: - todata = tolist.pop(0) - else: - todata = ('',' ') - yield fromdata,todata,flag - - def _collect_lines(self,diffs): - """Collects mdiff output into separate lists - - Before storing the mdiff from/to data into a list, it is converted - into a single line of text with HTML markup. - """ - - fromlist,tolist,flaglist = [],[],[] - # pull from/to data and flags from mdiff style iterator - for fromdata,todata,flag in diffs: - try: - # store HTML markup of the lines into the lists - fromlist.append(self._format_line(0,flag,*fromdata)) - tolist.append(self._format_line(1,flag,*todata)) - except TypeError: - # exceptions occur for lines where context separators go - fromlist.append(None) - tolist.append(None) - flaglist.append(flag) - return fromlist,tolist,flaglist - - def _format_line(self,side,flag,linenum,text): - """Returns HTML markup of "from" / "to" text lines - - side -- 0 or 1 indicating "from" or "to" text - flag -- indicates if difference on line - linenum -- line number (used for line number column) - text -- line text to be marked up - """ - try: - linenum = '%d' % linenum - id = ' id="%s%s"' % (self._prefix[side],linenum) - except TypeError: - # handle blank lines where linenum is '>' or '' - id = '' - # replace those things that would get confused with HTML symbols - text=text.replace("&","&").replace(">",">").replace("<","<") - - # make space non-breakable so they don't get compressed or line wrapped - text = text.replace(' ',' ').rstrip() - - return '%s%s' \ - % (id,linenum,text) - - def _make_prefix(self): - """Create unique anchor prefixes""" - - # Generate a unique anchor prefix so multiple tables - # can exist on the same HTML page without conflicts. - fromprefix = "from%d_" % HtmlDiff._default_prefix - toprefix = "to%d_" % HtmlDiff._default_prefix - HtmlDiff._default_prefix += 1 - # store prefixes so line format method has access - self._prefix = [fromprefix,toprefix] - - def _convert_flags(self,fromlist,tolist,flaglist,context,numlines): - """Makes list of "next" links""" - - # all anchor names will be generated using the unique "to" prefix - toprefix = self._prefix[1] - - # process change flags, generating middle column of next anchors/links - next_id = ['']*len(flaglist) - next_href = ['']*len(flaglist) - num_chg, in_change = 0, False - last = 0 - for i,flag in enumerate(flaglist): - if flag: - if not in_change: - in_change = True - last = i - # at the beginning of a change, drop an anchor a few lines - # (the context lines) before the change for the previous - # link - i = max([0,i-numlines]) - next_id[i] = ' id="difflib_chg_%s_%d"' % (toprefix,num_chg) - # at the beginning of a change, drop a link to the next - # change - num_chg += 1 - next_href[last] = '
    n' % ( - toprefix,num_chg) - else: - in_change = False - # check for cases where there is no content to avoid exceptions - if not flaglist: - flaglist = [False] - next_id = [''] - next_href = [''] - last = 0 - if context: - fromlist = [' No Differences Found '] - tolist = fromlist - else: - fromlist = tolist = [' Empty File '] - # if not a change on first line, drop a link - if not flaglist[0]: - next_href[0] = 'f' % toprefix - # redo the last link to link to the top - next_href[last] = 't' % (toprefix) - - return fromlist,tolist,flaglist,next_href,next_id - - def make_table(self,fromlines,tolines,fromdesc='',todesc='',context=False, - numlines=5): - """Returns HTML table of side by side comparison with change highlights - - Arguments: - fromlines -- list of "from" lines - tolines -- list of "to" lines - fromdesc -- "from" file column header string - todesc -- "to" file column header string - context -- set to True for contextual differences (defaults to False - which shows full differences). - numlines -- number of context lines. When context is set True, - controls number of lines displayed before and after the change. - When context is False, controls the number of lines to place - the "next" link anchors before the next change (so click of - "next" link jumps to just before the change). - """ - - # make unique anchor prefixes so that multiple tables may exist - # on the same page without conflict. - self._make_prefix() - - # change tabs to spaces before it gets more difficult after we insert - # markup - fromlines,tolines = self._tab_newline_replace(fromlines,tolines) - - # create diffs iterator which generates side by side from/to data - if context: - context_lines = numlines - else: - context_lines = None - diffs = _mdiff(fromlines,tolines,context_lines,linejunk=self._linejunk, - charjunk=self._charjunk) - - # set up iterator to wrap lines that exceed desired width - if self._wrapcolumn: - diffs = self._line_wrapper(diffs) - - # collect up from/to lines and flags into lists (also format the lines) - fromlist,tolist,flaglist = self._collect_lines(diffs) - - # process change flags, generating middle column of next anchors/links - fromlist,tolist,flaglist,next_href,next_id = self._convert_flags( - fromlist,tolist,flaglist,context,numlines) - - s = [] - fmt = ' %s%s' + \ - '%s%s\n' - for i in range(len(flaglist)): - if flaglist[i] is None: - # mdiff yields None on separator lines skip the bogus ones - # generated for the first line - if i > 0: - s.append(' \n \n') - else: - s.append( fmt % (next_id[i],next_href[i],fromlist[i], - next_href[i],tolist[i])) - if fromdesc or todesc: - header_row = '%s%s%s%s' % ( - '
    ', - '%s' % fromdesc, - '
    ', - '%s' % todesc) - else: - header_row = '' - - table = self._table_template % dict( - data_rows=''.join(s), - header_row=header_row, - prefix=self._prefix[1]) - - return table.replace('\0+',''). \ - replace('\0-',''). \ - replace('\0^',''). \ - replace('\1',''). \ - replace('\t',' ') - -del re - -def restore(delta, which): - r""" - Generate one of the two sequences that generated a delta. - - Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract - lines originating from file 1 or 2 (parameter `which`), stripping off line - prefixes. - - Examples: - - >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(keepends=True), - ... 'ore\ntree\nemu\n'.splitlines(keepends=True)) - >>> diff = list(diff) - >>> print(''.join(restore(diff, 1)), end="") - one - two - three - >>> print(''.join(restore(diff, 2)), end="") - ore - tree - emu - """ - try: - tag = {1: "- ", 2: "+ "}[int(which)] - except KeyError: - raise ValueError('unknown delta choice (must be 1 or 2): %r' - % which) from None - prefixes = (" ", tag) - for line in delta: - if line[:2] in prefixes: - yield line[2:] - -def _test(): - import doctest, difflib - return doctest.testmod(difflib) - -if __name__ == "__main__": - _test() diff --git a/python/Lib/dis.py b/python/Lib/dis.py deleted file mode 100644 index 68ea9e4..0000000 --- a/python/Lib/dis.py +++ /dev/null @@ -1,775 +0,0 @@ -"""Disassembler of Python byte code into mnemonics.""" - -import sys -import types -import collections -import io - -from opcode import * -from opcode import ( - __all__ as _opcodes_all, - _cache_format, - _inline_cache_entries, - _nb_ops, - _specializations, - _specialized_instructions, -) - -__all__ = ["code_info", "dis", "disassemble", "distb", "disco", - "findlinestarts", "findlabels", "show_code", - "get_instructions", "Instruction", "Bytecode"] + _opcodes_all -del _opcodes_all - -_have_code = (types.MethodType, types.FunctionType, types.CodeType, - classmethod, staticmethod, type) - -FORMAT_VALUE = opmap['FORMAT_VALUE'] -FORMAT_VALUE_CONVERTERS = ( - (None, ''), - (str, 'str'), - (repr, 'repr'), - (ascii, 'ascii'), -) -MAKE_FUNCTION = opmap['MAKE_FUNCTION'] -MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure') - -LOAD_CONST = opmap['LOAD_CONST'] -LOAD_GLOBAL = opmap['LOAD_GLOBAL'] -BINARY_OP = opmap['BINARY_OP'] -JUMP_BACKWARD = opmap['JUMP_BACKWARD'] - -CACHE = opmap["CACHE"] - -_all_opname = list(opname) -_all_opmap = dict(opmap) -_empty_slot = [slot for slot, name in enumerate(_all_opname) if name.startswith("<")] -for spec_op, specialized in zip(_empty_slot, _specialized_instructions): - # fill opname and opmap - _all_opname[spec_op] = specialized - _all_opmap[specialized] = spec_op - -deoptmap = { - specialized: base for base, family in _specializations.items() for specialized in family -} - -def _try_compile(source, name): - """Attempts to compile the given source, first as an expression and - then as a statement if the first approach fails. - - Utility function to accept strings in functions that otherwise - expect code objects - """ - try: - c = compile(source, name, 'eval') - except SyntaxError: - c = compile(source, name, 'exec') - return c - -def dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False): - """Disassemble classes, methods, functions, and other compiled objects. - - With no argument, disassemble the last traceback. - - Compiled objects currently include generator objects, async generator - objects, and coroutine objects, all of which store their code object - in a special attribute. - """ - if x is None: - distb(file=file, show_caches=show_caches, adaptive=adaptive) - return - # Extract functions from methods. - if hasattr(x, '__func__'): - x = x.__func__ - # Extract compiled code objects from... - if hasattr(x, '__code__'): # ...a function, or - x = x.__code__ - elif hasattr(x, 'gi_code'): #...a generator object, or - x = x.gi_code - elif hasattr(x, 'ag_code'): #...an asynchronous generator object, or - x = x.ag_code - elif hasattr(x, 'cr_code'): #...a coroutine. - x = x.cr_code - # Perform the disassembly. - if hasattr(x, '__dict__'): # Class or module - items = sorted(x.__dict__.items()) - for name, x1 in items: - if isinstance(x1, _have_code): - print("Disassembly of %s:" % name, file=file) - try: - dis(x1, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive) - except TypeError as msg: - print("Sorry:", msg, file=file) - print(file=file) - elif hasattr(x, 'co_code'): # Code object - _disassemble_recursive(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive) - elif isinstance(x, (bytes, bytearray)): # Raw bytecode - _disassemble_bytes(x, file=file, show_caches=show_caches) - elif isinstance(x, str): # Source code - _disassemble_str(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive) - else: - raise TypeError("don't know how to disassemble %s objects" % - type(x).__name__) - -def distb(tb=None, *, file=None, show_caches=False, adaptive=False): - """Disassemble a traceback (default: last traceback).""" - if tb is None: - try: - tb = sys.last_traceback - except AttributeError: - raise RuntimeError("no last traceback to disassemble") from None - while tb.tb_next: tb = tb.tb_next - disassemble(tb.tb_frame.f_code, tb.tb_lasti, file=file, show_caches=show_caches, adaptive=adaptive) - -# The inspect module interrogates this dictionary to build its -# list of CO_* constants. It is also used by pretty_flags to -# turn the co_flags field into a human readable list. -COMPILER_FLAG_NAMES = { - 1: "OPTIMIZED", - 2: "NEWLOCALS", - 4: "VARARGS", - 8: "VARKEYWORDS", - 16: "NESTED", - 32: "GENERATOR", - 64: "NOFREE", - 128: "COROUTINE", - 256: "ITERABLE_COROUTINE", - 512: "ASYNC_GENERATOR", -} - -def pretty_flags(flags): - """Return pretty representation of code flags.""" - names = [] - for i in range(32): - flag = 1<" - -# Sentinel to represent values that cannot be calculated -UNKNOWN = _Unknown() - -def _get_code_object(x): - """Helper to handle methods, compiled or raw code objects, and strings.""" - # Extract functions from methods. - if hasattr(x, '__func__'): - x = x.__func__ - # Extract compiled code objects from... - if hasattr(x, '__code__'): # ...a function, or - x = x.__code__ - elif hasattr(x, 'gi_code'): #...a generator object, or - x = x.gi_code - elif hasattr(x, 'ag_code'): #...an asynchronous generator object, or - x = x.ag_code - elif hasattr(x, 'cr_code'): #...a coroutine. - x = x.cr_code - # Handle source code. - if isinstance(x, str): - x = _try_compile(x, "") - # By now, if we don't have a code object, we can't disassemble x. - if hasattr(x, 'co_code'): - return x - raise TypeError("don't know how to disassemble %s objects" % - type(x).__name__) - -def _deoptop(op): - name = _all_opname[op] - return _all_opmap[deoptmap[name]] if name in deoptmap else op - -def _get_code_array(co, adaptive): - return co._co_code_adaptive if adaptive else co.co_code - -def code_info(x): - """Formatted details of methods, functions, or code.""" - return _format_code_info(_get_code_object(x)) - -def _format_code_info(co): - lines = [] - lines.append("Name: %s" % co.co_name) - lines.append("Filename: %s" % co.co_filename) - lines.append("Argument count: %s" % co.co_argcount) - lines.append("Positional-only arguments: %s" % co.co_posonlyargcount) - lines.append("Kw-only arguments: %s" % co.co_kwonlyargcount) - lines.append("Number of locals: %s" % co.co_nlocals) - lines.append("Stack size: %s" % co.co_stacksize) - lines.append("Flags: %s" % pretty_flags(co.co_flags)) - if co.co_consts: - lines.append("Constants:") - for i_c in enumerate(co.co_consts): - lines.append("%4d: %r" % i_c) - if co.co_names: - lines.append("Names:") - for i_n in enumerate(co.co_names): - lines.append("%4d: %s" % i_n) - if co.co_varnames: - lines.append("Variable names:") - for i_n in enumerate(co.co_varnames): - lines.append("%4d: %s" % i_n) - if co.co_freevars: - lines.append("Free variables:") - for i_n in enumerate(co.co_freevars): - lines.append("%4d: %s" % i_n) - if co.co_cellvars: - lines.append("Cell variables:") - for i_n in enumerate(co.co_cellvars): - lines.append("%4d: %s" % i_n) - return "\n".join(lines) - -def show_code(co, *, file=None): - """Print details of methods, functions, or code to *file*. - - If *file* is not provided, the output is printed on stdout. - """ - print(code_info(co), file=file) - -Positions = collections.namedtuple( - 'Positions', - [ - 'lineno', - 'end_lineno', - 'col_offset', - 'end_col_offset', - ], - defaults=[None] * 4 -) - -_Instruction = collections.namedtuple( - "_Instruction", - [ - 'opname', - 'opcode', - 'arg', - 'argval', - 'argrepr', - 'offset', - 'starts_line', - 'is_jump_target', - 'positions' - ], - defaults=[None] -) - -_Instruction.opname.__doc__ = "Human readable name for operation" -_Instruction.opcode.__doc__ = "Numeric code for operation" -_Instruction.arg.__doc__ = "Numeric argument to operation (if any), otherwise None" -_Instruction.argval.__doc__ = "Resolved arg value (if known), otherwise same as arg" -_Instruction.argrepr.__doc__ = "Human readable description of operation argument" -_Instruction.offset.__doc__ = "Start index of operation within bytecode sequence" -_Instruction.starts_line.__doc__ = "Line started by this opcode (if any), otherwise None" -_Instruction.is_jump_target.__doc__ = "True if other code jumps to here, otherwise False" -_Instruction.positions.__doc__ = "dis.Positions object holding the span of source code covered by this instruction" - -_ExceptionTableEntry = collections.namedtuple("_ExceptionTableEntry", - "start end target depth lasti") - -_OPNAME_WIDTH = 20 -_OPARG_WIDTH = 5 - -class Instruction(_Instruction): - """Details for a bytecode operation - - Defined fields: - opname - human readable name for operation - opcode - numeric code for operation - arg - numeric argument to operation (if any), otherwise None - argval - resolved arg value (if known), otherwise same as arg - argrepr - human readable description of operation argument - offset - start index of operation within bytecode sequence - starts_line - line started by this opcode (if any), otherwise None - is_jump_target - True if other code jumps to here, otherwise False - positions - Optional dis.Positions object holding the span of source code - covered by this instruction - """ - - def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): - """Format instruction details for inclusion in disassembly output - - *lineno_width* sets the width of the line number field (0 omits it) - *mark_as_current* inserts a '-->' marker arrow as part of the line - *offset_width* sets the width of the instruction offset field - """ - fields = [] - # Column: Source code line number - if lineno_width: - if self.starts_line is not None: - lineno_fmt = "%%%dd" % lineno_width - fields.append(lineno_fmt % self.starts_line) - else: - fields.append(' ' * lineno_width) - # Column: Current instruction indicator - if mark_as_current: - fields.append('-->') - else: - fields.append(' ') - # Column: Jump target marker - if self.is_jump_target: - fields.append('>>') - else: - fields.append(' ') - # Column: Instruction offset from start of code sequence - fields.append(repr(self.offset).rjust(offset_width)) - # Column: Opcode name - fields.append(self.opname.ljust(_OPNAME_WIDTH)) - # Column: Opcode argument - if self.arg is not None: - fields.append(repr(self.arg).rjust(_OPARG_WIDTH)) - # Column: Opcode argument details - if self.argrepr: - fields.append('(' + self.argrepr + ')') - return ' '.join(fields).rstrip() - - -def get_instructions(x, *, first_line=None, show_caches=False, adaptive=False): - """Iterator for the opcodes in methods, functions or code - - Generates a series of Instruction named tuples giving the details of - each operations in the supplied code. - - If *first_line* is not None, it indicates the line number that should - be reported for the first source line in the disassembled code. - Otherwise, the source line information (if any) is taken directly from - the disassembled code object. - """ - co = _get_code_object(x) - linestarts = dict(findlinestarts(co)) - if first_line is not None: - line_offset = first_line - co.co_firstlineno - else: - line_offset = 0 - return _get_instructions_bytes(_get_code_array(co, adaptive), - co._varname_from_oparg, - co.co_names, co.co_consts, - linestarts, line_offset, - co_positions=co.co_positions(), - show_caches=show_caches) - -def _get_const_value(op, arg, co_consts): - """Helper to get the value of the const in a hasconst op. - - Returns the dereferenced constant if this is possible. - Otherwise (if it is a LOAD_CONST and co_consts is not - provided) returns the dis.UNKNOWN sentinel. - """ - assert op in hasconst - - argval = UNKNOWN - if op == LOAD_CONST: - if co_consts is not None: - argval = co_consts[arg] - return argval - -def _get_const_info(op, arg, co_consts): - """Helper to get optional details about const references - - Returns the dereferenced constant and its repr if the value - can be calculated. - Otherwise returns the sentinel value dis.UNKNOWN for the value - and an empty string for its repr. - """ - argval = _get_const_value(op, arg, co_consts) - argrepr = repr(argval) if argval is not UNKNOWN else '' - return argval, argrepr - -def _get_name_info(name_index, get_name, **extrainfo): - """Helper to get optional details about named references - - Returns the dereferenced name as both value and repr if the name - list is defined. - Otherwise returns the sentinel value dis.UNKNOWN for the value - and an empty string for its repr. - """ - if get_name is not None: - argval = get_name(name_index, **extrainfo) - return argval, argval - else: - return UNKNOWN, '' - -def _parse_varint(iterator): - b = next(iterator) - val = b & 63 - while b&64: - val <<= 6 - b = next(iterator) - val |= b&63 - return val - -def _parse_exception_table(code): - iterator = iter(code.co_exceptiontable) - entries = [] - try: - while True: - start = _parse_varint(iterator)*2 - length = _parse_varint(iterator)*2 - end = start + length - target = _parse_varint(iterator)*2 - dl = _parse_varint(iterator) - depth = dl >> 1 - lasti = bool(dl&1) - entries.append(_ExceptionTableEntry(start, end, target, depth, lasti)) - except StopIteration: - return entries - -def _is_backward_jump(op): - return 'JUMP_BACKWARD' in opname[op] - -def _get_instructions_bytes(code, varname_from_oparg=None, - names=None, co_consts=None, - linestarts=None, line_offset=0, - exception_entries=(), co_positions=None, - show_caches=False): - """Iterate over the instructions in a bytecode string. - - Generates a sequence of Instruction namedtuples giving the details of each - opcode. Additional information about the code's runtime environment - (e.g. variable names, co_consts) can be specified using optional - arguments. - - """ - co_positions = co_positions or iter(()) - get_name = None if names is None else names.__getitem__ - labels = set(findlabels(code)) - for start, end, target, _, _ in exception_entries: - for i in range(start, end): - labels.add(target) - starts_line = None - for offset, op, arg in _unpack_opargs(code): - if linestarts is not None: - starts_line = linestarts.get(offset, None) - if starts_line is not None: - starts_line += line_offset - is_jump_target = offset in labels - argval = None - argrepr = '' - positions = Positions(*next(co_positions, ())) - deop = _deoptop(op) - if arg is not None: - # Set argval to the dereferenced value of the argument when - # available, and argrepr to the string representation of argval. - # _disassemble_bytes needs the string repr of the - # raw name index for LOAD_GLOBAL, LOAD_CONST, etc. - argval = arg - if deop in hasconst: - argval, argrepr = _get_const_info(deop, arg, co_consts) - elif deop in hasname: - if deop == LOAD_GLOBAL: - argval, argrepr = _get_name_info(arg//2, get_name) - if (arg & 1) and argrepr: - argrepr = "NULL + " + argrepr - else: - argval, argrepr = _get_name_info(arg, get_name) - elif deop in hasjabs: - argval = arg*2 - argrepr = "to " + repr(argval) - elif deop in hasjrel: - signed_arg = -arg if _is_backward_jump(deop) else arg - argval = offset + 2 + signed_arg*2 - argrepr = "to " + repr(argval) - elif deop in haslocal or deop in hasfree: - argval, argrepr = _get_name_info(arg, varname_from_oparg) - elif deop in hascompare: - argval = cmp_op[arg] - argrepr = argval - elif deop == FORMAT_VALUE: - argval, argrepr = FORMAT_VALUE_CONVERTERS[arg & 0x3] - argval = (argval, bool(arg & 0x4)) - if argval[1]: - if argrepr: - argrepr += ', ' - argrepr += 'with format' - elif deop == MAKE_FUNCTION: - argrepr = ', '.join(s for i, s in enumerate(MAKE_FUNCTION_FLAGS) - if arg & (1< 0: - if depth is not None: - depth = depth - 1 - for x in co.co_consts: - if hasattr(x, 'co_code'): - print(file=file) - print("Disassembly of %r:" % (x,), file=file) - _disassemble_recursive( - x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive - ) - -def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, - names=None, co_consts=None, linestarts=None, - *, file=None, line_offset=0, exception_entries=(), - co_positions=None, show_caches=False): - # Omit the line number column entirely if we have no line number info - show_lineno = bool(linestarts) - if show_lineno: - maxlineno = max(linestarts.values()) + line_offset - if maxlineno >= 1000: - lineno_width = len(str(maxlineno)) - else: - lineno_width = 3 - else: - lineno_width = 0 - maxoffset = len(code) - 2 - if maxoffset >= 10000: - offset_width = len(str(maxoffset)) - else: - offset_width = 4 - for instr in _get_instructions_bytes(code, varname_from_oparg, names, - co_consts, linestarts, - line_offset=line_offset, - exception_entries=exception_entries, - co_positions=co_positions, - show_caches=show_caches): - new_source_line = (show_lineno and - instr.starts_line is not None and - instr.offset > 0) - if new_source_line: - print(file=file) - is_current_instr = instr.offset == lasti - print(instr._disassemble(lineno_width, is_current_instr, offset_width), - file=file) - if exception_entries: - print("ExceptionTable:", file=file) - for entry in exception_entries: - lasti = " lasti" if entry.lasti else "" - end = entry.end-2 - print(f" {entry.start} to {end} -> {entry.target} [{entry.depth}]{lasti}", file=file) - -def _disassemble_str(source, **kwargs): - """Compile the source string, then disassemble the code object.""" - _disassemble_recursive(_try_compile(source, ''), **kwargs) - -disco = disassemble # XXX For backwards compatibility - - -# Rely on C `int` being 32 bits for oparg -_INT_BITS = 32 -# Value for c int when it overflows -_INT_OVERFLOW = 2 ** (_INT_BITS - 1) - -def _unpack_opargs(code): - extended_arg = 0 - caches = 0 - for i in range(0, len(code), 2): - # Skip inline CACHE entries: - if caches: - caches -= 1 - continue - op = code[i] - deop = _deoptop(op) - caches = _inline_cache_entries[deop] - if deop >= HAVE_ARGUMENT: - arg = code[i+1] | extended_arg - extended_arg = (arg << 8) if deop == EXTENDED_ARG else 0 - # The oparg is stored as a signed integer - # If the value exceeds its upper limit, it will overflow and wrap - # to a negative integer - if extended_arg >= _INT_OVERFLOW: - extended_arg -= 2 * _INT_OVERFLOW - else: - arg = None - extended_arg = 0 - yield (i, op, arg) - -def findlabels(code): - """Detect all offsets in a byte code which are jump targets. - - Return the list of offsets. - - """ - labels = [] - for offset, op, arg in _unpack_opargs(code): - if arg is not None: - if op in hasjrel: - if _is_backward_jump(op): - arg = -arg - label = offset + 2 + arg*2 - elif op in hasjabs: - label = arg*2 - else: - continue - if label not in labels: - labels.append(label) - return labels - -def findlinestarts(code): - """Find the offsets in a byte code which are start of lines in the source. - - Generate pairs (offset, lineno) - """ - lastline = None - for start, end, line in code.co_lines(): - if line is not None and line != lastline: - lastline = line - yield start, line - return - -def _find_imports(co): - """Find import statements in the code - - Generate triplets (name, level, fromlist) where - name is the imported module and level, fromlist are - the corresponding args to __import__. - """ - IMPORT_NAME = opmap['IMPORT_NAME'] - LOAD_CONST = opmap['LOAD_CONST'] - - consts = co.co_consts - names = co.co_names - opargs = [(op, arg) for _, op, arg in _unpack_opargs(co.co_code) - if op != EXTENDED_ARG] - for i, (op, oparg) in enumerate(opargs): - if op == IMPORT_NAME and i >= 2: - from_op = opargs[i-1] - level_op = opargs[i-2] - if (from_op[0] in hasconst and level_op[0] in hasconst): - level = _get_const_value(level_op[0], level_op[1], consts) - fromlist = _get_const_value(from_op[0], from_op[1], consts) - yield (names[oparg], level, fromlist) - -def _find_store_names(co): - """Find names of variables which are written in the code - - Generate sequence of strings - """ - STORE_OPS = { - opmap['STORE_NAME'], - opmap['STORE_GLOBAL'] - } - - names = co.co_names - for _, op, arg in _unpack_opargs(co.co_code): - if op in STORE_OPS: - yield names[arg] - - -class Bytecode: - """The bytecode operations of a piece of code - - Instantiate this with a function, method, other compiled object, string of - code, or a code object (as returned by compile()). - - Iterating over this yields the bytecode operations as Instruction instances. - """ - def __init__(self, x, *, first_line=None, current_offset=None, show_caches=False, adaptive=False): - self.codeobj = co = _get_code_object(x) - if first_line is None: - self.first_line = co.co_firstlineno - self._line_offset = 0 - else: - self.first_line = first_line - self._line_offset = first_line - co.co_firstlineno - self._linestarts = dict(findlinestarts(co)) - self._original_object = x - self.current_offset = current_offset - self.exception_entries = _parse_exception_table(co) - self.show_caches = show_caches - self.adaptive = adaptive - - def __iter__(self): - co = self.codeobj - return _get_instructions_bytes(_get_code_array(co, self.adaptive), - co._varname_from_oparg, - co.co_names, co.co_consts, - self._linestarts, - line_offset=self._line_offset, - exception_entries=self.exception_entries, - co_positions=co.co_positions(), - show_caches=self.show_caches) - - def __repr__(self): - return "{}({!r})".format(self.__class__.__name__, - self._original_object) - - @classmethod - def from_traceback(cls, tb, *, show_caches=False, adaptive=False): - """ Construct a Bytecode from the given traceback """ - while tb.tb_next: - tb = tb.tb_next - return cls( - tb.tb_frame.f_code, current_offset=tb.tb_lasti, show_caches=show_caches, adaptive=adaptive - ) - - def info(self): - """Return formatted information about the code object.""" - return _format_code_info(self.codeobj) - - def dis(self): - """Return a formatted view of the bytecode operations.""" - co = self.codeobj - if self.current_offset is not None: - offset = self.current_offset - else: - offset = -1 - with io.StringIO() as output: - _disassemble_bytes(_get_code_array(co, self.adaptive), - varname_from_oparg=co._varname_from_oparg, - names=co.co_names, co_consts=co.co_consts, - linestarts=self._linestarts, - line_offset=self._line_offset, - file=output, - lasti=offset, - exception_entries=self.exception_entries, - co_positions=co.co_positions(), - show_caches=self.show_caches) - return output.getvalue() - - -def _test(): - """Simple test program to disassemble a file.""" - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument('infile', type=argparse.FileType('rb'), nargs='?', default='-') - args = parser.parse_args() - with args.infile as infile: - source = infile.read() - code = compile(source, args.infile.name, "exec") - dis(code) - -if __name__ == "__main__": - _test() diff --git a/python/Lib/distutils/README b/python/Lib/distutils/README deleted file mode 100644 index d6968be..0000000 --- a/python/Lib/distutils/README +++ /dev/null @@ -1,11 +0,0 @@ -This directory contains the Distutils package. - -There's a full documentation available at: - - https://docs.python.org/distutils/ - -The Distutils-SIG web page is also a good starting point: - - https://www.python.org/sigs/distutils-sig/ - -$Id$ diff --git a/python/Lib/distutils/__init__.py b/python/Lib/distutils/__init__.py deleted file mode 100644 index 2da35c6..0000000 --- a/python/Lib/distutils/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -"""distutils - -The main package for the Python Module Distribution Utilities. Normally -used from a setup script as - - from distutils.core import setup - - setup (...) -""" - -import sys -import warnings - -__version__ = sys.version[:sys.version.index(' ')] - -_DEPRECATION_MESSAGE = ("The distutils package is deprecated and slated for " - "removal in Python 3.12. Use setuptools or check " - "PEP 632 for potential alternatives") -warnings.warn(_DEPRECATION_MESSAGE, - DeprecationWarning, 2) diff --git a/python/Lib/distutils/_msvccompiler.py b/python/Lib/distutils/_msvccompiler.py deleted file mode 100644 index 62815d4..0000000 --- a/python/Lib/distutils/_msvccompiler.py +++ /dev/null @@ -1,539 +0,0 @@ -"""distutils._msvccompiler - -Contains MSVCCompiler, an implementation of the abstract CCompiler class -for Microsoft Visual Studio 2015. - -The module is compatible with VS 2015 and later. You can find legacy support -for older versions in distutils.msvc9compiler and distutils.msvccompiler. -""" - -# Written by Perry Stoll -# hacked by Robin Becker and Thomas Heller to do a better job of -# finding DevStudio (through the registry) -# ported to VS 2005 and VS 2008 by Christian Heimes -# ported to VS 2015 by Steve Dower - -import os -import subprocess -import winreg - -from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError -from distutils.ccompiler import CCompiler, gen_lib_options -from distutils import log -from distutils.util import get_platform - -from itertools import count - -def _find_vc2015(): - try: - key = winreg.OpenKeyEx( - winreg.HKEY_LOCAL_MACHINE, - r"Software\Microsoft\VisualStudio\SxS\VC7", - access=winreg.KEY_READ | winreg.KEY_WOW64_32KEY - ) - except OSError: - log.debug("Visual C++ is not registered") - return None, None - - best_version = 0 - best_dir = None - with key: - for i in count(): - try: - v, vc_dir, vt = winreg.EnumValue(key, i) - except OSError: - break - if v and vt == winreg.REG_SZ and os.path.isdir(vc_dir): - try: - version = int(float(v)) - except (ValueError, TypeError): - continue - if version >= 14 and version > best_version: - best_version, best_dir = version, vc_dir - return best_version, best_dir - -def _find_vc2017(): - """Returns "15, path" based on the result of invoking vswhere.exe - If no install is found, returns "None, None" - - The version is returned to avoid unnecessarily changing the function - result. It may be ignored when the path is not None. - - If vswhere.exe is not available, by definition, VS 2017 is not - installed. - """ - root = os.environ.get("ProgramFiles(x86)") or os.environ.get("ProgramFiles") - if not root: - return None, None - - try: - path = subprocess.check_output([ - os.path.join(root, "Microsoft Visual Studio", "Installer", "vswhere.exe"), - "-latest", - "-prerelease", - "-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", - "-property", "installationPath", - "-products", "*", - ], encoding="mbcs", errors="strict").strip() - except (subprocess.CalledProcessError, OSError, UnicodeDecodeError): - return None, None - - path = os.path.join(path, "VC", "Auxiliary", "Build") - if os.path.isdir(path): - return 15, path - - return None, None - -PLAT_SPEC_TO_RUNTIME = { - 'x86' : 'x86', - 'x86_amd64' : 'x64', - 'x86_arm' : 'arm', - 'x86_arm64' : 'arm64' -} - -def _find_vcvarsall(plat_spec): - # bpo-38597: Removed vcruntime return value - _, best_dir = _find_vc2017() - - if not best_dir: - best_version, best_dir = _find_vc2015() - - if not best_dir: - log.debug("No suitable Visual C++ version found") - return None, None - - vcvarsall = os.path.join(best_dir, "vcvarsall.bat") - if not os.path.isfile(vcvarsall): - log.debug("%s cannot be found", vcvarsall) - return None, None - - return vcvarsall, None - -def _get_vc_env(plat_spec): - if os.getenv("DISTUTILS_USE_SDK"): - return { - key.lower(): value - for key, value in os.environ.items() - } - - vcvarsall, _ = _find_vcvarsall(plat_spec) - if not vcvarsall: - raise DistutilsPlatformError("Unable to find vcvarsall.bat") - - try: - out = subprocess.check_output( - 'cmd /u /c "{}" {} && set'.format(vcvarsall, plat_spec), - stderr=subprocess.STDOUT, - ).decode('utf-16le', errors='replace') - except subprocess.CalledProcessError as exc: - log.error(exc.output) - raise DistutilsPlatformError("Error executing {}" - .format(exc.cmd)) - - env = { - key.lower(): value - for key, _, value in - (line.partition('=') for line in out.splitlines()) - if key and value - } - - return env - -def _find_exe(exe, paths=None): - """Return path to an MSVC executable program. - - Tries to find the program in several places: first, one of the - MSVC program search paths from the registry; next, the directories - in the PATH environment variable. If any of those work, return an - absolute path that is known to exist. If none of them work, just - return the original program name, 'exe'. - """ - if not paths: - paths = os.getenv('path').split(os.pathsep) - for p in paths: - fn = os.path.join(os.path.abspath(p), exe) - if os.path.isfile(fn): - return fn - return exe - -# A map keyed by get_platform() return values to values accepted by -# 'vcvarsall.bat'. Always cross-compile from x86 to work with the -# lighter-weight MSVC installs that do not include native 64-bit tools. -PLAT_TO_VCVARS = { - 'win32' : 'x86', - 'win-amd64' : 'x86_amd64', - 'win-arm32' : 'x86_arm', - 'win-arm64' : 'x86_arm64' -} - -class MSVCCompiler(CCompiler) : - """Concrete class that implements an interface to Microsoft Visual C++, - as defined by the CCompiler abstract class.""" - - compiler_type = 'msvc' - - # Just set this so CCompiler's constructor doesn't barf. We currently - # don't use the 'set_executables()' bureaucracy provided by CCompiler, - # as it really isn't necessary for this sort of single-compiler class. - # Would be nice to have a consistent interface with UnixCCompiler, - # though, so it's worth thinking about. - executables = {} - - # Private class data (need to distinguish C from C++ source for compiler) - _c_extensions = ['.c'] - _cpp_extensions = ['.cc', '.cpp', '.cxx'] - _rc_extensions = ['.rc'] - _mc_extensions = ['.mc'] - - # Needed for the filename generation methods provided by the - # base class, CCompiler. - src_extensions = (_c_extensions + _cpp_extensions + - _rc_extensions + _mc_extensions) - res_extension = '.res' - obj_extension = '.obj' - static_lib_extension = '.lib' - shared_lib_extension = '.dll' - static_lib_format = shared_lib_format = '%s%s' - exe_extension = '.exe' - - - def __init__(self, verbose=0, dry_run=0, force=0): - CCompiler.__init__ (self, verbose, dry_run, force) - # target platform (.plat_name is consistent with 'bdist') - self.plat_name = None - self.initialized = False - - def initialize(self, plat_name=None): - # multi-init means we would need to check platform same each time... - assert not self.initialized, "don't init multiple times" - if plat_name is None: - plat_name = get_platform() - # sanity check for platforms to prevent obscure errors later. - if plat_name not in PLAT_TO_VCVARS: - raise DistutilsPlatformError("--plat-name must be one of {}" - .format(tuple(PLAT_TO_VCVARS))) - - # Get the vcvarsall.bat spec for the requested platform. - plat_spec = PLAT_TO_VCVARS[plat_name] - - vc_env = _get_vc_env(plat_spec) - if not vc_env: - raise DistutilsPlatformError("Unable to find a compatible " - "Visual Studio installation.") - - self._paths = vc_env.get('path', '') - paths = self._paths.split(os.pathsep) - self.cc = _find_exe("cl.exe", paths) - self.linker = _find_exe("link.exe", paths) - self.lib = _find_exe("lib.exe", paths) - self.rc = _find_exe("rc.exe", paths) # resource compiler - self.mc = _find_exe("mc.exe", paths) # message compiler - self.mt = _find_exe("mt.exe", paths) # message compiler - - for dir in vc_env.get('include', '').split(os.pathsep): - if dir: - self.add_include_dir(dir.rstrip(os.sep)) - - for dir in vc_env.get('lib', '').split(os.pathsep): - if dir: - self.add_library_dir(dir.rstrip(os.sep)) - - self.preprocess_options = None - # bpo-38597: Always compile with dynamic linking - # Future releases of Python 3.x will include all past - # versions of vcruntime*.dll for compatibility. - self.compile_options = [ - '/nologo', '/Ox', '/W3', '/GL', '/DNDEBUG', '/MD' - ] - - self.compile_options_debug = [ - '/nologo', '/Od', '/MDd', '/Zi', '/W3', '/D_DEBUG' - ] - - ldflags = [ - '/nologo', '/INCREMENTAL:NO', '/LTCG' - ] - - ldflags_debug = [ - '/nologo', '/INCREMENTAL:NO', '/LTCG', '/DEBUG:FULL' - ] - - self.ldflags_exe = [*ldflags, '/MANIFEST:EMBED,ID=1'] - self.ldflags_exe_debug = [*ldflags_debug, '/MANIFEST:EMBED,ID=1'] - self.ldflags_shared = [*ldflags, '/DLL', '/MANIFEST:EMBED,ID=2', '/MANIFESTUAC:NO'] - self.ldflags_shared_debug = [*ldflags_debug, '/DLL', '/MANIFEST:EMBED,ID=2', '/MANIFESTUAC:NO'] - self.ldflags_static = [*ldflags] - self.ldflags_static_debug = [*ldflags_debug] - - self._ldflags = { - (CCompiler.EXECUTABLE, None): self.ldflags_exe, - (CCompiler.EXECUTABLE, False): self.ldflags_exe, - (CCompiler.EXECUTABLE, True): self.ldflags_exe_debug, - (CCompiler.SHARED_OBJECT, None): self.ldflags_shared, - (CCompiler.SHARED_OBJECT, False): self.ldflags_shared, - (CCompiler.SHARED_OBJECT, True): self.ldflags_shared_debug, - (CCompiler.SHARED_LIBRARY, None): self.ldflags_static, - (CCompiler.SHARED_LIBRARY, False): self.ldflags_static, - (CCompiler.SHARED_LIBRARY, True): self.ldflags_static_debug, - } - - self.initialized = True - - # -- Worker methods ------------------------------------------------ - - def object_filenames(self, - source_filenames, - strip_dir=0, - output_dir=''): - ext_map = { - **{ext: self.obj_extension for ext in self.src_extensions}, - **{ext: self.res_extension for ext in self._rc_extensions + self._mc_extensions}, - } - - output_dir = output_dir or '' - - def make_out_path(p): - base, ext = os.path.splitext(p) - if strip_dir: - base = os.path.basename(base) - else: - _, base = os.path.splitdrive(base) - if base.startswith((os.path.sep, os.path.altsep)): - base = base[1:] - try: - # XXX: This may produce absurdly long paths. We should check - # the length of the result and trim base until we fit within - # 260 characters. - return os.path.join(output_dir, base + ext_map[ext]) - except LookupError: - # Better to raise an exception instead of silently continuing - # and later complain about sources and targets having - # different lengths - raise CompileError("Don't know how to compile {}".format(p)) - - return list(map(make_out_path, source_filenames)) - - - def compile(self, sources, - output_dir=None, macros=None, include_dirs=None, debug=0, - extra_preargs=None, extra_postargs=None, depends=None): - - if not self.initialized: - self.initialize() - compile_info = self._setup_compile(output_dir, macros, include_dirs, - sources, depends, extra_postargs) - macros, objects, extra_postargs, pp_opts, build = compile_info - - compile_opts = extra_preargs or [] - compile_opts.append('/c') - if debug: - compile_opts.extend(self.compile_options_debug) - else: - compile_opts.extend(self.compile_options) - - - add_cpp_opts = False - - for obj in objects: - try: - src, ext = build[obj] - except KeyError: - continue - if debug: - # pass the full pathname to MSVC in debug mode, - # this allows the debugger to find the source file - # without asking the user to browse for it - src = os.path.abspath(src) - - if ext in self._c_extensions: - input_opt = "/Tc" + src - elif ext in self._cpp_extensions: - input_opt = "/Tp" + src - add_cpp_opts = True - elif ext in self._rc_extensions: - # compile .RC to .RES file - input_opt = src - output_opt = "/fo" + obj - try: - self.spawn([self.rc] + pp_opts + [output_opt, input_opt]) - except DistutilsExecError as msg: - raise CompileError(msg) - continue - elif ext in self._mc_extensions: - # Compile .MC to .RC file to .RES file. - # * '-h dir' specifies the directory for the - # generated include file - # * '-r dir' specifies the target directory of the - # generated RC file and the binary message resource - # it includes - # - # For now (since there are no options to change this), - # we use the source-directory for the include file and - # the build directory for the RC file and message - # resources. This works at least for win32all. - h_dir = os.path.dirname(src) - rc_dir = os.path.dirname(obj) - try: - # first compile .MC to .RC and .H file - self.spawn([self.mc, '-h', h_dir, '-r', rc_dir, src]) - base, _ = os.path.splitext(os.path.basename (src)) - rc_file = os.path.join(rc_dir, base + '.rc') - # then compile .RC to .RES file - self.spawn([self.rc, "/fo" + obj, rc_file]) - - except DistutilsExecError as msg: - raise CompileError(msg) - continue - else: - # how to handle this file? - raise CompileError("Don't know how to compile {} to {}" - .format(src, obj)) - - args = [self.cc] + compile_opts + pp_opts - if add_cpp_opts: - args.append('/EHsc') - args.append(input_opt) - args.append("/Fo" + obj) - args.extend(extra_postargs) - - try: - self.spawn(args) - except DistutilsExecError as msg: - raise CompileError(msg) - - return objects - - - def create_static_lib(self, - objects, - output_libname, - output_dir=None, - debug=0, - target_lang=None): - - if not self.initialized: - self.initialize() - objects, output_dir = self._fix_object_args(objects, output_dir) - output_filename = self.library_filename(output_libname, - output_dir=output_dir) - - if self._need_link(objects, output_filename): - lib_args = objects + ['/OUT:' + output_filename] - if debug: - pass # XXX what goes here? - try: - log.debug('Executing "%s" %s', self.lib, ' '.join(lib_args)) - self.spawn([self.lib] + lib_args) - except DistutilsExecError as msg: - raise LibError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - - def link(self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - - if not self.initialized: - self.initialize() - objects, output_dir = self._fix_object_args(objects, output_dir) - fixed_args = self._fix_lib_args(libraries, library_dirs, - runtime_library_dirs) - libraries, library_dirs, runtime_library_dirs = fixed_args - - if runtime_library_dirs: - self.warn("I don't know what to do with 'runtime_library_dirs': " - + str(runtime_library_dirs)) - - lib_opts = gen_lib_options(self, - library_dirs, runtime_library_dirs, - libraries) - if output_dir is not None: - output_filename = os.path.join(output_dir, output_filename) - - if self._need_link(objects, output_filename): - ldflags = self._ldflags[target_desc, debug] - - export_opts = ["/EXPORT:" + sym for sym in (export_symbols or [])] - - ld_args = (ldflags + lib_opts + export_opts + - objects + ['/OUT:' + output_filename]) - - # The MSVC linker generates .lib and .exp files, which cannot be - # suppressed by any linker switches. The .lib files may even be - # needed! Make sure they are generated in the temporary build - # directory. Since they have different names for debug and release - # builds, they can go into the same directory. - build_temp = os.path.dirname(objects[0]) - if export_symbols is not None: - (dll_name, dll_ext) = os.path.splitext( - os.path.basename(output_filename)) - implib_file = os.path.join( - build_temp, - self.library_filename(dll_name)) - ld_args.append ('/IMPLIB:' + implib_file) - - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - - output_dir = os.path.dirname(os.path.abspath(output_filename)) - self.mkpath(output_dir) - try: - log.debug('Executing "%s" %s', self.linker, ' '.join(ld_args)) - self.spawn([self.linker] + ld_args) - except DistutilsExecError as msg: - raise LinkError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - def spawn(self, cmd): - old_path = os.getenv('path') - try: - os.environ['path'] = self._paths - return super().spawn(cmd) - finally: - os.environ['path'] = old_path - - # -- Miscellaneous methods ----------------------------------------- - # These are all used by the 'gen_lib_options() function, in - # ccompiler.py. - - def library_dir_option(self, dir): - return "/LIBPATH:" + dir - - def runtime_library_dir_option(self, dir): - raise DistutilsPlatformError( - "don't know how to set runtime library search path for MSVC") - - def library_option(self, lib): - return self.library_filename(lib) - - def find_library_file(self, dirs, lib, debug=0): - # Prefer a debugging library if found (and requested), but deal - # with it if we don't have one. - if debug: - try_names = [lib + "_d", lib] - else: - try_names = [lib] - for dir in dirs: - for name in try_names: - libfile = os.path.join(dir, self.library_filename(name)) - if os.path.isfile(libfile): - return libfile - else: - # Oops, didn't find it in *any* of 'dirs' - return None diff --git a/python/Lib/distutils/archive_util.py b/python/Lib/distutils/archive_util.py deleted file mode 100644 index d54736f..0000000 --- a/python/Lib/distutils/archive_util.py +++ /dev/null @@ -1,256 +0,0 @@ -"""distutils.archive_util - -Utility functions for creating archive files (tarballs, zip files, -that sort of thing).""" - -import os -from warnings import warn -import sys - -try: - import zipfile -except ImportError: - zipfile = None - - -from distutils.errors import DistutilsExecError -from distutils.spawn import spawn -from distutils.dir_util import mkpath -from distutils import log - -try: - from pwd import getpwnam -except ImportError: - getpwnam = None - -try: - from grp import getgrnam -except ImportError: - getgrnam = None - -def _get_gid(name): - """Returns a gid, given a group name.""" - if getgrnam is None or name is None: - return None - try: - result = getgrnam(name) - except KeyError: - result = None - if result is not None: - return result[2] - return None - -def _get_uid(name): - """Returns an uid, given a user name.""" - if getpwnam is None or name is None: - return None - try: - result = getpwnam(name) - except KeyError: - result = None - if result is not None: - return result[2] - return None - -def make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, - owner=None, group=None): - """Create a (possibly compressed) tar file from all the files under - 'base_dir'. - - 'compress' must be "gzip" (the default), "bzip2", "xz", "compress", or - None. ("compress" will be deprecated in Python 3.2) - - 'owner' and 'group' can be used to define an owner and a group for the - archive that is being built. If not provided, the current owner and group - will be used. - - The output tar file will be named 'base_dir' + ".tar", possibly plus - the appropriate compression extension (".gz", ".bz2", ".xz" or ".Z"). - - Returns the output filename. - """ - tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', 'xz': 'xz', None: '', - 'compress': ''} - compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'xz': '.xz', - 'compress': '.Z'} - - # flags for compression program, each element of list will be an argument - if compress is not None and compress not in compress_ext.keys(): - raise ValueError( - "bad value for 'compress': must be None, 'gzip', 'bzip2', " - "'xz' or 'compress'") - - archive_name = base_name + '.tar' - if compress != 'compress': - archive_name += compress_ext.get(compress, '') - - mkpath(os.path.dirname(archive_name), dry_run=dry_run) - - # creating the tarball - import tarfile # late import so Python build itself doesn't break - - log.info('Creating tar archive') - - uid = _get_uid(owner) - gid = _get_gid(group) - - def _set_uid_gid(tarinfo): - if gid is not None: - tarinfo.gid = gid - tarinfo.gname = group - if uid is not None: - tarinfo.uid = uid - tarinfo.uname = owner - return tarinfo - - if not dry_run: - tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) - try: - tar.add(base_dir, filter=_set_uid_gid) - finally: - tar.close() - - # compression using `compress` - if compress == 'compress': - warn("'compress' will be deprecated.", PendingDeprecationWarning) - # the option varies depending on the platform - compressed_name = archive_name + compress_ext[compress] - if sys.platform == 'win32': - cmd = [compress, archive_name, compressed_name] - else: - cmd = [compress, '-f', archive_name] - spawn(cmd, dry_run=dry_run) - return compressed_name - - return archive_name - -def make_zipfile(base_name, base_dir, verbose=0, dry_run=0): - """Create a zip file from all the files under 'base_dir'. - - The output zip file will be named 'base_name' + ".zip". Uses either the - "zipfile" Python module (if available) or the InfoZIP "zip" utility - (if installed and found on the default search path). If neither tool is - available, raises DistutilsExecError. Returns the name of the output zip - file. - """ - zip_filename = base_name + ".zip" - mkpath(os.path.dirname(zip_filename), dry_run=dry_run) - - # If zipfile module is not available, try spawning an external - # 'zip' command. - if zipfile is None: - if verbose: - zipoptions = "-r" - else: - zipoptions = "-rq" - - try: - spawn(["zip", zipoptions, zip_filename, base_dir], - dry_run=dry_run) - except DistutilsExecError: - # XXX really should distinguish between "couldn't find - # external 'zip' command" and "zip failed". - raise DistutilsExecError(("unable to create zip file '%s': " - "could neither import the 'zipfile' module nor " - "find a standalone zip utility") % zip_filename) - - else: - log.info("creating '%s' and adding '%s' to it", - zip_filename, base_dir) - - if not dry_run: - try: - zip = zipfile.ZipFile(zip_filename, "w", - compression=zipfile.ZIP_DEFLATED) - except RuntimeError: - zip = zipfile.ZipFile(zip_filename, "w", - compression=zipfile.ZIP_STORED) - - with zip: - if base_dir != os.curdir: - path = os.path.normpath(os.path.join(base_dir, '')) - zip.write(path, path) - log.info("adding '%s'", path) - for dirpath, dirnames, filenames in os.walk(base_dir): - for name in dirnames: - path = os.path.normpath(os.path.join(dirpath, name, '')) - zip.write(path, path) - log.info("adding '%s'", path) - for name in filenames: - path = os.path.normpath(os.path.join(dirpath, name)) - if os.path.isfile(path): - zip.write(path, path) - log.info("adding '%s'", path) - - return zip_filename - -ARCHIVE_FORMATS = { - 'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), - 'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), - 'xztar': (make_tarball, [('compress', 'xz')], "xz'ed tar-file"), - 'ztar': (make_tarball, [('compress', 'compress')], "compressed tar file"), - 'tar': (make_tarball, [('compress', None)], "uncompressed tar file"), - 'zip': (make_zipfile, [],"ZIP file") - } - -def check_archive_formats(formats): - """Returns the first format from the 'format' list that is unknown. - - If all formats are known, returns None - """ - for format in formats: - if format not in ARCHIVE_FORMATS: - return format - return None - -def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, - dry_run=0, owner=None, group=None): - """Create an archive file (eg. zip or tar). - - 'base_name' is the name of the file to create, minus any format-specific - extension; 'format' is the archive format: one of "zip", "tar", "gztar", - "bztar", "xztar", or "ztar". - - 'root_dir' is a directory that will be the root directory of the - archive; ie. we typically chdir into 'root_dir' before creating the - archive. 'base_dir' is the directory where we start archiving from; - ie. 'base_dir' will be the common prefix of all files and - directories in the archive. 'root_dir' and 'base_dir' both default - to the current directory. Returns the name of the archive file. - - 'owner' and 'group' are used when creating a tar archive. By default, - uses the current owner and group. - """ - save_cwd = os.getcwd() - if root_dir is not None: - log.debug("changing into '%s'", root_dir) - base_name = os.path.abspath(base_name) - if not dry_run: - os.chdir(root_dir) - - if base_dir is None: - base_dir = os.curdir - - kwargs = {'dry_run': dry_run} - - try: - format_info = ARCHIVE_FORMATS[format] - except KeyError: - raise ValueError("unknown archive format '%s'" % format) - - func = format_info[0] - for arg, val in format_info[1]: - kwargs[arg] = val - - if format != 'zip': - kwargs['owner'] = owner - kwargs['group'] = group - - try: - filename = func(base_name, base_dir, **kwargs) - finally: - if root_dir is not None: - log.debug("changing back to '%s'", save_cwd) - os.chdir(save_cwd) - - return filename diff --git a/python/Lib/distutils/bcppcompiler.py b/python/Lib/distutils/bcppcompiler.py deleted file mode 100644 index c22ad4a..0000000 --- a/python/Lib/distutils/bcppcompiler.py +++ /dev/null @@ -1,393 +0,0 @@ -"""distutils.bcppcompiler - -Contains BorlandCCompiler, an implementation of the abstract CCompiler class -for the Borland C++ compiler. -""" - -# This implementation by Lyle Johnson, based on the original msvccompiler.py -# module and using the directions originally published by Gordon Williams. - -# XXX looks like there's a LOT of overlap between these two classes: -# someone should sit down and factor out the common code as -# WindowsCCompiler! --GPW - - -import os -from distutils.errors import \ - DistutilsExecError, \ - CompileError, LibError, LinkError, UnknownFileError -from distutils.ccompiler import \ - CCompiler, gen_preprocess_options -from distutils.file_util import write_file -from distutils.dep_util import newer -from distutils import log - -class BCPPCompiler(CCompiler) : - """Concrete class that implements an interface to the Borland C/C++ - compiler, as defined by the CCompiler abstract class. - """ - - compiler_type = 'bcpp' - - # Just set this so CCompiler's constructor doesn't barf. We currently - # don't use the 'set_executables()' bureaucracy provided by CCompiler, - # as it really isn't necessary for this sort of single-compiler class. - # Would be nice to have a consistent interface with UnixCCompiler, - # though, so it's worth thinking about. - executables = {} - - # Private class data (need to distinguish C from C++ source for compiler) - _c_extensions = ['.c'] - _cpp_extensions = ['.cc', '.cpp', '.cxx'] - - # Needed for the filename generation methods provided by the - # base class, CCompiler. - src_extensions = _c_extensions + _cpp_extensions - obj_extension = '.obj' - static_lib_extension = '.lib' - shared_lib_extension = '.dll' - static_lib_format = shared_lib_format = '%s%s' - exe_extension = '.exe' - - - def __init__ (self, - verbose=0, - dry_run=0, - force=0): - - CCompiler.__init__ (self, verbose, dry_run, force) - - # These executables are assumed to all be in the path. - # Borland doesn't seem to use any special registry settings to - # indicate their installation locations. - - self.cc = "bcc32.exe" - self.linker = "ilink32.exe" - self.lib = "tlib.exe" - - self.preprocess_options = None - self.compile_options = ['/tWM', '/O2', '/q', '/g0'] - self.compile_options_debug = ['/tWM', '/Od', '/q', '/g0'] - - self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x'] - self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x'] - self.ldflags_static = [] - self.ldflags_exe = ['/Gn', '/q', '/x'] - self.ldflags_exe_debug = ['/Gn', '/q', '/x','/r'] - - - # -- Worker methods ------------------------------------------------ - - def compile(self, sources, - output_dir=None, macros=None, include_dirs=None, debug=0, - extra_preargs=None, extra_postargs=None, depends=None): - - macros, objects, extra_postargs, pp_opts, build = \ - self._setup_compile(output_dir, macros, include_dirs, sources, - depends, extra_postargs) - compile_opts = extra_preargs or [] - compile_opts.append ('-c') - if debug: - compile_opts.extend (self.compile_options_debug) - else: - compile_opts.extend (self.compile_options) - - for obj in objects: - try: - src, ext = build[obj] - except KeyError: - continue - # XXX why do the normpath here? - src = os.path.normpath(src) - obj = os.path.normpath(obj) - # XXX _setup_compile() did a mkpath() too but before the normpath. - # Is it possible to skip the normpath? - self.mkpath(os.path.dirname(obj)) - - if ext == '.res': - # This is already a binary file -- skip it. - continue # the 'for' loop - if ext == '.rc': - # This needs to be compiled to a .res file -- do it now. - try: - self.spawn (["brcc32", "-fo", obj, src]) - except DistutilsExecError as msg: - raise CompileError(msg) - continue # the 'for' loop - - # The next two are both for the real compiler. - if ext in self._c_extensions: - input_opt = "" - elif ext in self._cpp_extensions: - input_opt = "-P" - else: - # Unknown file type -- no extra options. The compiler - # will probably fail, but let it just in case this is a - # file the compiler recognizes even if we don't. - input_opt = "" - - output_opt = "-o" + obj - - # Compiler command line syntax is: "bcc32 [options] file(s)". - # Note that the source file names must appear at the end of - # the command line. - try: - self.spawn ([self.cc] + compile_opts + pp_opts + - [input_opt, output_opt] + - extra_postargs + [src]) - except DistutilsExecError as msg: - raise CompileError(msg) - - return objects - - # compile () - - - def create_static_lib (self, - objects, - output_libname, - output_dir=None, - debug=0, - target_lang=None): - - (objects, output_dir) = self._fix_object_args (objects, output_dir) - output_filename = \ - self.library_filename (output_libname, output_dir=output_dir) - - if self._need_link (objects, output_filename): - lib_args = [output_filename, '/u'] + objects - if debug: - pass # XXX what goes here? - try: - self.spawn ([self.lib] + lib_args) - except DistutilsExecError as msg: - raise LibError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - # create_static_lib () - - - def link (self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - - # XXX this ignores 'build_temp'! should follow the lead of - # msvccompiler.py - - (objects, output_dir) = self._fix_object_args (objects, output_dir) - (libraries, library_dirs, runtime_library_dirs) = \ - self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) - - if runtime_library_dirs: - log.warn("I don't know what to do with 'runtime_library_dirs': %s", - str(runtime_library_dirs)) - - if output_dir is not None: - output_filename = os.path.join (output_dir, output_filename) - - if self._need_link (objects, output_filename): - - # Figure out linker args based on type of target. - if target_desc == CCompiler.EXECUTABLE: - startup_obj = 'c0w32' - if debug: - ld_args = self.ldflags_exe_debug[:] - else: - ld_args = self.ldflags_exe[:] - else: - startup_obj = 'c0d32' - if debug: - ld_args = self.ldflags_shared_debug[:] - else: - ld_args = self.ldflags_shared[:] - - - # Create a temporary exports file for use by the linker - if export_symbols is None: - def_file = '' - else: - head, tail = os.path.split (output_filename) - modname, ext = os.path.splitext (tail) - temp_dir = os.path.dirname(objects[0]) # preserve tree structure - def_file = os.path.join (temp_dir, '%s.def' % modname) - contents = ['EXPORTS'] - for sym in (export_symbols or []): - contents.append(' %s=_%s' % (sym, sym)) - self.execute(write_file, (def_file, contents), - "writing %s" % def_file) - - # Borland C++ has problems with '/' in paths - objects2 = map(os.path.normpath, objects) - # split objects in .obj and .res files - # Borland C++ needs them at different positions in the command line - objects = [startup_obj] - resources = [] - for file in objects2: - (base, ext) = os.path.splitext(os.path.normcase(file)) - if ext == '.res': - resources.append(file) - else: - objects.append(file) - - - for l in library_dirs: - ld_args.append("/L%s" % os.path.normpath(l)) - ld_args.append("/L.") # we sometimes use relative paths - - # list of object files - ld_args.extend(objects) - - # XXX the command-line syntax for Borland C++ is a bit wonky; - # certain filenames are jammed together in one big string, but - # comma-delimited. This doesn't mesh too well with the - # Unix-centric attitude (with a DOS/Windows quoting hack) of - # 'spawn()', so constructing the argument list is a bit - # awkward. Note that doing the obvious thing and jamming all - # the filenames and commas into one argument would be wrong, - # because 'spawn()' would quote any filenames with spaces in - # them. Arghghh!. Apparently it works fine as coded... - - # name of dll/exe file - ld_args.extend([',',output_filename]) - # no map file and start libraries - ld_args.append(',,') - - for lib in libraries: - # see if we find it and if there is a bcpp specific lib - # (xxx_bcpp.lib) - libfile = self.find_library_file(library_dirs, lib, debug) - if libfile is None: - ld_args.append(lib) - # probably a BCPP internal library -- don't warn - else: - # full name which prefers bcpp_xxx.lib over xxx.lib - ld_args.append(libfile) - - # some default libraries - ld_args.append ('import32') - ld_args.append ('cw32mt') - - # def file for export symbols - ld_args.extend([',',def_file]) - # add resource files - ld_args.append(',') - ld_args.extend(resources) - - - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - - self.mkpath (os.path.dirname (output_filename)) - try: - self.spawn ([self.linker] + ld_args) - except DistutilsExecError as msg: - raise LinkError(msg) - - else: - log.debug("skipping %s (up-to-date)", output_filename) - - # link () - - # -- Miscellaneous methods ----------------------------------------- - - - def find_library_file (self, dirs, lib, debug=0): - # List of effective library names to try, in order of preference: - # xxx_bcpp.lib is better than xxx.lib - # and xxx_d.lib is better than xxx.lib if debug is set - # - # The "_bcpp" suffix is to handle a Python installation for people - # with multiple compilers (primarily Distutils hackers, I suspect - # ;-). The idea is they'd have one static library for each - # compiler they care about, since (almost?) every Windows compiler - # seems to have a different format for static libraries. - if debug: - dlib = (lib + "_d") - try_names = (dlib + "_bcpp", lib + "_bcpp", dlib, lib) - else: - try_names = (lib + "_bcpp", lib) - - for dir in dirs: - for name in try_names: - libfile = os.path.join(dir, self.library_filename(name)) - if os.path.exists(libfile): - return libfile - else: - # Oops, didn't find it in *any* of 'dirs' - return None - - # overwrite the one from CCompiler to support rc and res-files - def object_filenames (self, - source_filenames, - strip_dir=0, - output_dir=''): - if output_dir is None: output_dir = '' - obj_names = [] - for src_name in source_filenames: - # use normcase to make sure '.rc' is really '.rc' and not '.RC' - (base, ext) = os.path.splitext (os.path.normcase(src_name)) - if ext not in (self.src_extensions + ['.rc','.res']): - raise UnknownFileError("unknown file type '%s' (from '%s')" % \ - (ext, src_name)) - if strip_dir: - base = os.path.basename (base) - if ext == '.res': - # these can go unchanged - obj_names.append (os.path.join (output_dir, base + ext)) - elif ext == '.rc': - # these need to be compiled to .res-files - obj_names.append (os.path.join (output_dir, base + '.res')) - else: - obj_names.append (os.path.join (output_dir, - base + self.obj_extension)) - return obj_names - - # object_filenames () - - def preprocess (self, - source, - output_file=None, - macros=None, - include_dirs=None, - extra_preargs=None, - extra_postargs=None): - - (_, macros, include_dirs) = \ - self._fix_compile_args(None, macros, include_dirs) - pp_opts = gen_preprocess_options(macros, include_dirs) - pp_args = ['cpp32.exe'] + pp_opts - if output_file is not None: - pp_args.append('-o' + output_file) - if extra_preargs: - pp_args[:0] = extra_preargs - if extra_postargs: - pp_args.extend(extra_postargs) - pp_args.append(source) - - # We need to preprocess: either we're being forced to, or the - # source file is newer than the target (or the target doesn't - # exist). - if self.force or output_file is None or newer(source, output_file): - if output_file: - self.mkpath(os.path.dirname(output_file)) - try: - self.spawn(pp_args) - except DistutilsExecError as msg: - print(msg) - raise CompileError(msg) - - # preprocess() diff --git a/python/Lib/distutils/ccompiler.py b/python/Lib/distutils/ccompiler.py deleted file mode 100644 index f8c8c6c..0000000 --- a/python/Lib/distutils/ccompiler.py +++ /dev/null @@ -1,1116 +0,0 @@ -"""distutils.ccompiler - -Contains CCompiler, an abstract base class that defines the interface -for the Distutils compiler abstraction model.""" - -import sys, os, re -from distutils.errors import * -from distutils.spawn import spawn -from distutils.file_util import move_file -from distutils.dir_util import mkpath -from distutils.dep_util import newer_group -from distutils.util import split_quoted, execute -from distutils import log - -class CCompiler: - """Abstract base class to define the interface that must be implemented - by real compiler classes. Also has some utility methods used by - several compiler classes. - - The basic idea behind a compiler abstraction class is that each - instance can be used for all the compile/link steps in building a - single project. Thus, attributes common to all of those compile and - link steps -- include directories, macros to define, libraries to link - against, etc. -- are attributes of the compiler instance. To allow for - variability in how individual files are treated, most of those - attributes may be varied on a per-compilation or per-link basis. - """ - - # 'compiler_type' is a class attribute that identifies this class. It - # keeps code that wants to know what kind of compiler it's dealing with - # from having to import all possible compiler classes just to do an - # 'isinstance'. In concrete CCompiler subclasses, 'compiler_type' - # should really, really be one of the keys of the 'compiler_class' - # dictionary (see below -- used by the 'new_compiler()' factory - # function) -- authors of new compiler interface classes are - # responsible for updating 'compiler_class'! - compiler_type = None - - # XXX things not handled by this compiler abstraction model: - # * client can't provide additional options for a compiler, - # e.g. warning, optimization, debugging flags. Perhaps this - # should be the domain of concrete compiler abstraction classes - # (UnixCCompiler, MSVCCompiler, etc.) -- or perhaps the base - # class should have methods for the common ones. - # * can't completely override the include or library searchg - # path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2". - # I'm not sure how widely supported this is even by Unix - # compilers, much less on other platforms. And I'm even less - # sure how useful it is; maybe for cross-compiling, but - # support for that is a ways off. (And anyways, cross - # compilers probably have a dedicated binary with the - # right paths compiled in. I hope.) - # * can't do really freaky things with the library list/library - # dirs, e.g. "-Ldir1 -lfoo -Ldir2 -lfoo" to link against - # different versions of libfoo.a in different locations. I - # think this is useless without the ability to null out the - # library search path anyways. - - - # Subclasses that rely on the standard filename generation methods - # implemented below should override these; see the comment near - # those methods ('object_filenames()' et. al.) for details: - src_extensions = None # list of strings - obj_extension = None # string - static_lib_extension = None - shared_lib_extension = None # string - static_lib_format = None # format string - shared_lib_format = None # prob. same as static_lib_format - exe_extension = None # string - - # Default language settings. language_map is used to detect a source - # file or Extension target language, checking source filenames. - # language_order is used to detect the language precedence, when deciding - # what language to use when mixing source types. For example, if some - # extension has two files with ".c" extension, and one with ".cpp", it - # is still linked as c++. - language_map = {".c" : "c", - ".cc" : "c++", - ".cpp" : "c++", - ".cxx" : "c++", - ".m" : "objc", - } - language_order = ["c++", "objc", "c"] - - def __init__(self, verbose=0, dry_run=0, force=0): - self.dry_run = dry_run - self.force = force - self.verbose = verbose - - # 'output_dir': a common output directory for object, library, - # shared object, and shared library files - self.output_dir = None - - # 'macros': a list of macro definitions (or undefinitions). A - # macro definition is a 2-tuple (name, value), where the value is - # either a string or None (no explicit value). A macro - # undefinition is a 1-tuple (name,). - self.macros = [] - - # 'include_dirs': a list of directories to search for include files - self.include_dirs = [] - - # 'libraries': a list of libraries to include in any link - # (library names, not filenames: eg. "foo" not "libfoo.a") - self.libraries = [] - - # 'library_dirs': a list of directories to search for libraries - self.library_dirs = [] - - # 'runtime_library_dirs': a list of directories to search for - # shared libraries/objects at runtime - self.runtime_library_dirs = [] - - # 'objects': a list of object files (or similar, such as explicitly - # named library files) to include on any link - self.objects = [] - - for key in self.executables.keys(): - self.set_executable(key, self.executables[key]) - - def set_executables(self, **kwargs): - """Define the executables (and options for them) that will be run - to perform the various stages of compilation. The exact set of - executables that may be specified here depends on the compiler - class (via the 'executables' class attribute), but most will have: - compiler the C/C++ compiler - linker_so linker used to create shared objects and libraries - linker_exe linker used to create binary executables - archiver static library creator - - On platforms with a command-line (Unix, DOS/Windows), each of these - is a string that will be split into executable name and (optional) - list of arguments. (Splitting the string is done similarly to how - Unix shells operate: words are delimited by spaces, but quotes and - backslashes can override this. See - 'distutils.util.split_quoted()'.) - """ - - # Note that some CCompiler implementation classes will define class - # attributes 'cpp', 'cc', etc. with hard-coded executable names; - # this is appropriate when a compiler class is for exactly one - # compiler/OS combination (eg. MSVCCompiler). Other compiler - # classes (UnixCCompiler, in particular) are driven by information - # discovered at run-time, since there are many different ways to do - # basically the same things with Unix C compilers. - - for key in kwargs: - if key not in self.executables: - raise ValueError("unknown executable '%s' for class %s" % - (key, self.__class__.__name__)) - self.set_executable(key, kwargs[key]) - - def set_executable(self, key, value): - if isinstance(value, str): - setattr(self, key, split_quoted(value)) - else: - setattr(self, key, value) - - def _find_macro(self, name): - i = 0 - for defn in self.macros: - if defn[0] == name: - return i - i += 1 - return None - - def _check_macro_definitions(self, definitions): - """Ensures that every element of 'definitions' is a valid macro - definition, ie. either (name,value) 2-tuple or a (name,) tuple. Do - nothing if all definitions are OK, raise TypeError otherwise. - """ - for defn in definitions: - if not (isinstance(defn, tuple) and - (len(defn) in (1, 2) and - (isinstance (defn[1], str) or defn[1] is None)) and - isinstance (defn[0], str)): - raise TypeError(("invalid macro definition '%s': " % defn) + \ - "must be tuple (string,), (string, string), or " + \ - "(string, None)") - - - # -- Bookkeeping methods ------------------------------------------- - - def define_macro(self, name, value=None): - """Define a preprocessor macro for all compilations driven by this - compiler object. The optional parameter 'value' should be a - string; if it is not supplied, then the macro will be defined - without an explicit value and the exact outcome depends on the - compiler used (XXX true? does ANSI say anything about this?) - """ - # Delete from the list of macro definitions/undefinitions if - # already there (so that this one will take precedence). - i = self._find_macro (name) - if i is not None: - del self.macros[i] - - self.macros.append((name, value)) - - def undefine_macro(self, name): - """Undefine a preprocessor macro for all compilations driven by - this compiler object. If the same macro is defined by - 'define_macro()' and undefined by 'undefine_macro()' the last call - takes precedence (including multiple redefinitions or - undefinitions). If the macro is redefined/undefined on a - per-compilation basis (ie. in the call to 'compile()'), then that - takes precedence. - """ - # Delete from the list of macro definitions/undefinitions if - # already there (so that this one will take precedence). - i = self._find_macro (name) - if i is not None: - del self.macros[i] - - undefn = (name,) - self.macros.append(undefn) - - def add_include_dir(self, dir): - """Add 'dir' to the list of directories that will be searched for - header files. The compiler is instructed to search directories in - the order in which they are supplied by successive calls to - 'add_include_dir()'. - """ - self.include_dirs.append(dir) - - def set_include_dirs(self, dirs): - """Set the list of directories that will be searched to 'dirs' (a - list of strings). Overrides any preceding calls to - 'add_include_dir()'; subsequence calls to 'add_include_dir()' add - to the list passed to 'set_include_dirs()'. This does not affect - any list of standard include directories that the compiler may - search by default. - """ - self.include_dirs = dirs[:] - - def add_library(self, libname): - """Add 'libname' to the list of libraries that will be included in - all links driven by this compiler object. Note that 'libname' - should *not* be the name of a file containing a library, but the - name of the library itself: the actual filename will be inferred by - the linker, the compiler, or the compiler class (depending on the - platform). - - The linker will be instructed to link against libraries in the - order they were supplied to 'add_library()' and/or - 'set_libraries()'. It is perfectly valid to duplicate library - names; the linker will be instructed to link against libraries as - many times as they are mentioned. - """ - self.libraries.append(libname) - - def set_libraries(self, libnames): - """Set the list of libraries to be included in all links driven by - this compiler object to 'libnames' (a list of strings). This does - not affect any standard system libraries that the linker may - include by default. - """ - self.libraries = libnames[:] - - def add_library_dir(self, dir): - """Add 'dir' to the list of directories that will be searched for - libraries specified to 'add_library()' and 'set_libraries()'. The - linker will be instructed to search for libraries in the order they - are supplied to 'add_library_dir()' and/or 'set_library_dirs()'. - """ - self.library_dirs.append(dir) - - def set_library_dirs(self, dirs): - """Set the list of library search directories to 'dirs' (a list of - strings). This does not affect any standard library search path - that the linker may search by default. - """ - self.library_dirs = dirs[:] - - def add_runtime_library_dir(self, dir): - """Add 'dir' to the list of directories that will be searched for - shared libraries at runtime. - """ - self.runtime_library_dirs.append(dir) - - def set_runtime_library_dirs(self, dirs): - """Set the list of directories to search for shared libraries at - runtime to 'dirs' (a list of strings). This does not affect any - standard search path that the runtime linker may search by - default. - """ - self.runtime_library_dirs = dirs[:] - - def add_link_object(self, object): - """Add 'object' to the list of object files (or analogues, such as - explicitly named library files or the output of "resource - compilers") to be included in every link driven by this compiler - object. - """ - self.objects.append(object) - - def set_link_objects(self, objects): - """Set the list of object files (or analogues) to be included in - every link to 'objects'. This does not affect any standard object - files that the linker may include by default (such as system - libraries). - """ - self.objects = objects[:] - - - # -- Private utility methods -------------------------------------- - # (here for the convenience of subclasses) - - # Helper method to prep compiler in subclass compile() methods - - def _setup_compile(self, outdir, macros, incdirs, sources, depends, - extra): - """Process arguments and decide which source files to compile.""" - if outdir is None: - outdir = self.output_dir - elif not isinstance(outdir, str): - raise TypeError("'output_dir' must be a string or None") - - if macros is None: - macros = self.macros - elif isinstance(macros, list): - macros = macros + (self.macros or []) - else: - raise TypeError("'macros' (if supplied) must be a list of tuples") - - if incdirs is None: - incdirs = self.include_dirs - elif isinstance(incdirs, (list, tuple)): - incdirs = list(incdirs) + (self.include_dirs or []) - else: - raise TypeError( - "'include_dirs' (if supplied) must be a list of strings") - - if extra is None: - extra = [] - - # Get the list of expected output (object) files - objects = self.object_filenames(sources, strip_dir=0, - output_dir=outdir) - assert len(objects) == len(sources) - - pp_opts = gen_preprocess_options(macros, incdirs) - - build = {} - for i in range(len(sources)): - src = sources[i] - obj = objects[i] - ext = os.path.splitext(src)[1] - self.mkpath(os.path.dirname(obj)) - build[obj] = (src, ext) - - return macros, objects, extra, pp_opts, build - - def _get_cc_args(self, pp_opts, debug, before): - # works for unixccompiler, cygwinccompiler - cc_args = pp_opts + ['-c'] - if debug: - cc_args[:0] = ['-g'] - if before: - cc_args[:0] = before - return cc_args - - def _fix_compile_args(self, output_dir, macros, include_dirs): - """Typecheck and fix-up some of the arguments to the 'compile()' - method, and return fixed-up values. Specifically: if 'output_dir' - is None, replaces it with 'self.output_dir'; ensures that 'macros' - is a list, and augments it with 'self.macros'; ensures that - 'include_dirs' is a list, and augments it with 'self.include_dirs'. - Guarantees that the returned values are of the correct type, - i.e. for 'output_dir' either string or None, and for 'macros' and - 'include_dirs' either list or None. - """ - if output_dir is None: - output_dir = self.output_dir - elif not isinstance(output_dir, str): - raise TypeError("'output_dir' must be a string or None") - - if macros is None: - macros = self.macros - elif isinstance(macros, list): - macros = macros + (self.macros or []) - else: - raise TypeError("'macros' (if supplied) must be a list of tuples") - - if include_dirs is None: - include_dirs = self.include_dirs - elif isinstance(include_dirs, (list, tuple)): - include_dirs = list(include_dirs) + (self.include_dirs or []) - else: - raise TypeError( - "'include_dirs' (if supplied) must be a list of strings") - - return output_dir, macros, include_dirs - - def _prep_compile(self, sources, output_dir, depends=None): - """Decide which source files must be recompiled. - - Determine the list of object files corresponding to 'sources', - and figure out which ones really need to be recompiled. - Return a list of all object files and a dictionary telling - which source files can be skipped. - """ - # Get the list of expected output (object) files - objects = self.object_filenames(sources, output_dir=output_dir) - assert len(objects) == len(sources) - - # Return an empty dict for the "which source files can be skipped" - # return value to preserve API compatibility. - return objects, {} - - def _fix_object_args(self, objects, output_dir): - """Typecheck and fix up some arguments supplied to various methods. - Specifically: ensure that 'objects' is a list; if output_dir is - None, replace with self.output_dir. Return fixed versions of - 'objects' and 'output_dir'. - """ - if not isinstance(objects, (list, tuple)): - raise TypeError("'objects' must be a list or tuple of strings") - objects = list(objects) - - if output_dir is None: - output_dir = self.output_dir - elif not isinstance(output_dir, str): - raise TypeError("'output_dir' must be a string or None") - - return (objects, output_dir) - - def _fix_lib_args(self, libraries, library_dirs, runtime_library_dirs): - """Typecheck and fix up some of the arguments supplied to the - 'link_*' methods. Specifically: ensure that all arguments are - lists, and augment them with their permanent versions - (eg. 'self.libraries' augments 'libraries'). Return a tuple with - fixed versions of all arguments. - """ - if libraries is None: - libraries = self.libraries - elif isinstance(libraries, (list, tuple)): - libraries = list (libraries) + (self.libraries or []) - else: - raise TypeError( - "'libraries' (if supplied) must be a list of strings") - - if library_dirs is None: - library_dirs = self.library_dirs - elif isinstance(library_dirs, (list, tuple)): - library_dirs = list (library_dirs) + (self.library_dirs or []) - else: - raise TypeError( - "'library_dirs' (if supplied) must be a list of strings") - - if runtime_library_dirs is None: - runtime_library_dirs = self.runtime_library_dirs - elif isinstance(runtime_library_dirs, (list, tuple)): - runtime_library_dirs = (list(runtime_library_dirs) + - (self.runtime_library_dirs or [])) - else: - raise TypeError("'runtime_library_dirs' (if supplied) " - "must be a list of strings") - - return (libraries, library_dirs, runtime_library_dirs) - - def _need_link(self, objects, output_file): - """Return true if we need to relink the files listed in 'objects' - to recreate 'output_file'. - """ - if self.force: - return True - else: - if self.dry_run: - newer = newer_group (objects, output_file, missing='newer') - else: - newer = newer_group (objects, output_file) - return newer - - def detect_language(self, sources): - """Detect the language of a given file, or list of files. Uses - language_map, and language_order to do the job. - """ - if not isinstance(sources, list): - sources = [sources] - lang = None - index = len(self.language_order) - for source in sources: - base, ext = os.path.splitext(source) - extlang = self.language_map.get(ext) - try: - extindex = self.language_order.index(extlang) - if extindex < index: - lang = extlang - index = extindex - except ValueError: - pass - return lang - - - # -- Worker methods ------------------------------------------------ - # (must be implemented by subclasses) - - def preprocess(self, source, output_file=None, macros=None, - include_dirs=None, extra_preargs=None, extra_postargs=None): - """Preprocess a single C/C++ source file, named in 'source'. - Output will be written to file named 'output_file', or stdout if - 'output_file' not supplied. 'macros' is a list of macro - definitions as for 'compile()', which will augment the macros set - with 'define_macro()' and 'undefine_macro()'. 'include_dirs' is a - list of directory names that will be added to the default list. - - Raises PreprocessError on failure. - """ - pass - - def compile(self, sources, output_dir=None, macros=None, - include_dirs=None, debug=0, extra_preargs=None, - extra_postargs=None, depends=None): - """Compile one or more source files. - - 'sources' must be a list of filenames, most likely C/C++ - files, but in reality anything that can be handled by a - particular compiler and compiler class (eg. MSVCCompiler can - handle resource files in 'sources'). Return a list of object - filenames, one per source filename in 'sources'. Depending on - the implementation, not all source files will necessarily be - compiled, but all corresponding object filenames will be - returned. - - If 'output_dir' is given, object files will be put under it, while - retaining their original path component. That is, "foo/bar.c" - normally compiles to "foo/bar.o" (for a Unix implementation); if - 'output_dir' is "build", then it would compile to - "build/foo/bar.o". - - 'macros', if given, must be a list of macro definitions. A macro - definition is either a (name, value) 2-tuple or a (name,) 1-tuple. - The former defines a macro; if the value is None, the macro is - defined without an explicit value. The 1-tuple case undefines a - macro. Later definitions/redefinitions/ undefinitions take - precedence. - - 'include_dirs', if given, must be a list of strings, the - directories to add to the default include file search path for this - compilation only. - - 'debug' is a boolean; if true, the compiler will be instructed to - output debug symbols in (or alongside) the object file(s). - - 'extra_preargs' and 'extra_postargs' are implementation- dependent. - On platforms that have the notion of a command-line (e.g. Unix, - DOS/Windows), they are most likely lists of strings: extra - command-line arguments to prepend/append to the compiler command - line. On other platforms, consult the implementation class - documentation. In any event, they are intended as an escape hatch - for those occasions when the abstract compiler framework doesn't - cut the mustard. - - 'depends', if given, is a list of filenames that all targets - depend on. If a source file is older than any file in - depends, then the source file will be recompiled. This - supports dependency tracking, but only at a coarse - granularity. - - Raises CompileError on failure. - """ - # A concrete compiler class can either override this method - # entirely or implement _compile(). - macros, objects, extra_postargs, pp_opts, build = \ - self._setup_compile(output_dir, macros, include_dirs, sources, - depends, extra_postargs) - cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) - - for obj in objects: - try: - src, ext = build[obj] - except KeyError: - continue - self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) - - # Return *all* object filenames, not just the ones we just built. - return objects - - def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): - """Compile 'src' to product 'obj'.""" - # A concrete compiler class that does not override compile() - # should implement _compile(). - pass - - def create_static_lib(self, objects, output_libname, output_dir=None, - debug=0, target_lang=None): - """Link a bunch of stuff together to create a static library file. - The "bunch of stuff" consists of the list of object files supplied - as 'objects', the extra object files supplied to - 'add_link_object()' and/or 'set_link_objects()', the libraries - supplied to 'add_library()' and/or 'set_libraries()', and the - libraries supplied as 'libraries' (if any). - - 'output_libname' should be a library name, not a filename; the - filename will be inferred from the library name. 'output_dir' is - the directory where the library file will be put. - - 'debug' is a boolean; if true, debugging information will be - included in the library (note that on most platforms, it is the - compile step where this matters: the 'debug' flag is included here - just for consistency). - - 'target_lang' is the target language for which the given objects - are being compiled. This allows specific linkage time treatment of - certain languages. - - Raises LibError on failure. - """ - pass - - - # values for target_desc parameter in link() - SHARED_OBJECT = "shared_object" - SHARED_LIBRARY = "shared_library" - EXECUTABLE = "executable" - - def link(self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - """Link a bunch of stuff together to create an executable or - shared library file. - - The "bunch of stuff" consists of the list of object files supplied - as 'objects'. 'output_filename' should be a filename. If - 'output_dir' is supplied, 'output_filename' is relative to it - (i.e. 'output_filename' can provide directory components if - needed). - - 'libraries' is a list of libraries to link against. These are - library names, not filenames, since they're translated into - filenames in a platform-specific way (eg. "foo" becomes "libfoo.a" - on Unix and "foo.lib" on DOS/Windows). However, they can include a - directory component, which means the linker will look in that - specific directory rather than searching all the normal locations. - - 'library_dirs', if supplied, should be a list of directories to - search for libraries that were specified as bare library names - (ie. no directory component). These are on top of the system - default and those supplied to 'add_library_dir()' and/or - 'set_library_dirs()'. 'runtime_library_dirs' is a list of - directories that will be embedded into the shared library and used - to search for other shared libraries that *it* depends on at - run-time. (This may only be relevant on Unix.) - - 'export_symbols' is a list of symbols that the shared library will - export. (This appears to be relevant only on Windows.) - - 'debug' is as for 'compile()' and 'create_static_lib()', with the - slight distinction that it actually matters on most platforms (as - opposed to 'create_static_lib()', which includes a 'debug' flag - mostly for form's sake). - - 'extra_preargs' and 'extra_postargs' are as for 'compile()' (except - of course that they supply command-line arguments for the - particular linker being used). - - 'target_lang' is the target language for which the given objects - are being compiled. This allows specific linkage time treatment of - certain languages. - - Raises LinkError on failure. - """ - raise NotImplementedError - - - # Old 'link_*()' methods, rewritten to use the new 'link()' method. - - def link_shared_lib(self, - objects, - output_libname, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - self.link(CCompiler.SHARED_LIBRARY, objects, - self.library_filename(output_libname, lib_type='shared'), - output_dir, - libraries, library_dirs, runtime_library_dirs, - export_symbols, debug, - extra_preargs, extra_postargs, build_temp, target_lang) - - - def link_shared_object(self, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - self.link(CCompiler.SHARED_OBJECT, objects, - output_filename, output_dir, - libraries, library_dirs, runtime_library_dirs, - export_symbols, debug, - extra_preargs, extra_postargs, build_temp, target_lang) - - - def link_executable(self, - objects, - output_progname, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - target_lang=None): - self.link(CCompiler.EXECUTABLE, objects, - self.executable_filename(output_progname), output_dir, - libraries, library_dirs, runtime_library_dirs, None, - debug, extra_preargs, extra_postargs, None, target_lang) - - - # -- Miscellaneous methods ----------------------------------------- - # These are all used by the 'gen_lib_options() function; there is - # no appropriate default implementation so subclasses should - # implement all of these. - - def library_dir_option(self, dir): - """Return the compiler option to add 'dir' to the list of - directories searched for libraries. - """ - raise NotImplementedError - - def runtime_library_dir_option(self, dir): - """Return the compiler option to add 'dir' to the list of - directories searched for runtime libraries. - """ - raise NotImplementedError - - def library_option(self, lib): - """Return the compiler option to add 'lib' to the list of libraries - linked into the shared library or executable. - """ - raise NotImplementedError - - def has_function(self, funcname, includes=None, include_dirs=None, - libraries=None, library_dirs=None): - """Return a boolean indicating whether funcname is supported on - the current platform. The optional arguments can be used to - augment the compilation environment. - """ - # this can't be included at module scope because it tries to - # import math which might not be available at that point - maybe - # the necessary logic should just be inlined? - import tempfile - if includes is None: - includes = [] - if include_dirs is None: - include_dirs = [] - if libraries is None: - libraries = [] - if library_dirs is None: - library_dirs = [] - fd, fname = tempfile.mkstemp(".c", funcname, text=True) - f = os.fdopen(fd, "w") - try: - for incl in includes: - f.write("""#include "%s"\n""" % incl) - f.write("""\ -int main (int argc, char **argv) { - %s(); - return 0; -} -""" % funcname) - finally: - f.close() - try: - objects = self.compile([fname], include_dirs=include_dirs) - except CompileError: - return False - - try: - self.link_executable(objects, "a.out", - libraries=libraries, - library_dirs=library_dirs) - except (LinkError, TypeError): - return False - return True - - def find_library_file (self, dirs, lib, debug=0): - """Search the specified list of directories for a static or shared - library file 'lib' and return the full path to that file. If - 'debug' true, look for a debugging version (if that makes sense on - the current platform). Return None if 'lib' wasn't found in any of - the specified directories. - """ - raise NotImplementedError - - # -- Filename generation methods ----------------------------------- - - # The default implementation of the filename generating methods are - # prejudiced towards the Unix/DOS/Windows view of the world: - # * object files are named by replacing the source file extension - # (eg. .c/.cpp -> .o/.obj) - # * library files (shared or static) are named by plugging the - # library name and extension into a format string, eg. - # "lib%s.%s" % (lib_name, ".a") for Unix static libraries - # * executables are named by appending an extension (possibly - # empty) to the program name: eg. progname + ".exe" for - # Windows - # - # To reduce redundant code, these methods expect to find - # several attributes in the current object (presumably defined - # as class attributes): - # * src_extensions - - # list of C/C++ source file extensions, eg. ['.c', '.cpp'] - # * obj_extension - - # object file extension, eg. '.o' or '.obj' - # * static_lib_extension - - # extension for static library files, eg. '.a' or '.lib' - # * shared_lib_extension - - # extension for shared library/object files, eg. '.so', '.dll' - # * static_lib_format - - # format string for generating static library filenames, - # eg. 'lib%s.%s' or '%s.%s' - # * shared_lib_format - # format string for generating shared library filenames - # (probably same as static_lib_format, since the extension - # is one of the intended parameters to the format string) - # * exe_extension - - # extension for executable files, eg. '' or '.exe' - - def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): - if output_dir is None: - output_dir = '' - obj_names = [] - for src_name in source_filenames: - base, ext = os.path.splitext(src_name) - base = os.path.splitdrive(base)[1] # Chop off the drive - base = base[os.path.isabs(base):] # If abs, chop off leading / - if ext not in self.src_extensions: - raise UnknownFileError( - "unknown file type '%s' (from '%s')" % (ext, src_name)) - if strip_dir: - base = os.path.basename(base) - obj_names.append(os.path.join(output_dir, - base + self.obj_extension)) - return obj_names - - def shared_object_filename(self, basename, strip_dir=0, output_dir=''): - assert output_dir is not None - if strip_dir: - basename = os.path.basename(basename) - return os.path.join(output_dir, basename + self.shared_lib_extension) - - def executable_filename(self, basename, strip_dir=0, output_dir=''): - assert output_dir is not None - if strip_dir: - basename = os.path.basename(basename) - return os.path.join(output_dir, basename + (self.exe_extension or '')) - - def library_filename(self, libname, lib_type='static', # or 'shared' - strip_dir=0, output_dir=''): - assert output_dir is not None - if lib_type not in ("static", "shared", "dylib", "xcode_stub"): - raise ValueError( - "'lib_type' must be \"static\", \"shared\", \"dylib\", or \"xcode_stub\"") - fmt = getattr(self, lib_type + "_lib_format") - ext = getattr(self, lib_type + "_lib_extension") - - dir, base = os.path.split(libname) - filename = fmt % (base, ext) - if strip_dir: - dir = '' - - return os.path.join(output_dir, dir, filename) - - - # -- Utility methods ----------------------------------------------- - - def announce(self, msg, level=1): - log.debug(msg) - - def debug_print(self, msg): - from distutils.debug import DEBUG - if DEBUG: - print(msg) - - def warn(self, msg): - sys.stderr.write("warning: %s\n" % msg) - - def execute(self, func, args, msg=None, level=1): - execute(func, args, msg, self.dry_run) - - def spawn(self, cmd): - spawn(cmd, dry_run=self.dry_run) - - def move_file(self, src, dst): - return move_file(src, dst, dry_run=self.dry_run) - - def mkpath (self, name, mode=0o777): - mkpath(name, mode, dry_run=self.dry_run) - - -# Map a sys.platform/os.name ('posix', 'nt') to the default compiler -# type for that platform. Keys are interpreted as re match -# patterns. Order is important; platform mappings are preferred over -# OS names. -_default_compilers = ( - - # Platform string mappings - - # on a cygwin built python we can use gcc like an ordinary UNIXish - # compiler - ('cygwin.*', 'unix'), - - # OS name mappings - ('posix', 'unix'), - ('nt', 'msvc'), - - ) - -def get_default_compiler(osname=None, platform=None): - """Determine the default compiler to use for the given platform. - - osname should be one of the standard Python OS names (i.e. the - ones returned by os.name) and platform the common value - returned by sys.platform for the platform in question. - - The default values are os.name and sys.platform in case the - parameters are not given. - """ - if osname is None: - osname = os.name - if platform is None: - platform = sys.platform - for pattern, compiler in _default_compilers: - if re.match(pattern, platform) is not None or \ - re.match(pattern, osname) is not None: - return compiler - # Default to Unix compiler - return 'unix' - -# Map compiler types to (module_name, class_name) pairs -- ie. where to -# find the code that implements an interface to this compiler. (The module -# is assumed to be in the 'distutils' package.) -compiler_class = { 'unix': ('unixccompiler', 'UnixCCompiler', - "standard UNIX-style compiler"), - 'msvc': ('_msvccompiler', 'MSVCCompiler', - "Microsoft Visual C++"), - 'cygwin': ('cygwinccompiler', 'CygwinCCompiler', - "Cygwin port of GNU C Compiler for Win32"), - 'mingw32': ('cygwinccompiler', 'Mingw32CCompiler', - "Mingw32 port of GNU C Compiler for Win32"), - 'bcpp': ('bcppcompiler', 'BCPPCompiler', - "Borland C++ Compiler"), - } - -def show_compilers(): - """Print list of available compilers (used by the "--help-compiler" - options to "build", "build_ext", "build_clib"). - """ - # XXX this "knows" that the compiler option it's describing is - # "--compiler", which just happens to be the case for the three - # commands that use it. - from distutils.fancy_getopt import FancyGetopt - compilers = [] - for compiler in compiler_class.keys(): - compilers.append(("compiler="+compiler, None, - compiler_class[compiler][2])) - compilers.sort() - pretty_printer = FancyGetopt(compilers) - pretty_printer.print_help("List of available compilers:") - - -def new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0): - """Generate an instance of some CCompiler subclass for the supplied - platform/compiler combination. 'plat' defaults to 'os.name' - (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler - for that platform. Currently only 'posix' and 'nt' are supported, and - the default compilers are "traditional Unix interface" (UnixCCompiler - class) and Visual C++ (MSVCCompiler class). Note that it's perfectly - possible to ask for a Unix compiler object under Windows, and a - Microsoft compiler object under Unix -- if you supply a value for - 'compiler', 'plat' is ignored. - """ - if plat is None: - plat = os.name - - try: - if compiler is None: - compiler = get_default_compiler(plat) - - (module_name, class_name, long_description) = compiler_class[compiler] - except KeyError: - msg = "don't know how to compile C/C++ code on platform '%s'" % plat - if compiler is not None: - msg = msg + " with '%s' compiler" % compiler - raise DistutilsPlatformError(msg) - - try: - module_name = "distutils." + module_name - __import__ (module_name) - module = sys.modules[module_name] - klass = vars(module)[class_name] - except ImportError: - raise DistutilsModuleError( - "can't compile C/C++ code: unable to load module '%s'" % \ - module_name) - except KeyError: - raise DistutilsModuleError( - "can't compile C/C++ code: unable to find class '%s' " - "in module '%s'" % (class_name, module_name)) - - # XXX The None is necessary to preserve backwards compatibility - # with classes that expect verbose to be the first positional - # argument. - return klass(None, dry_run, force) - - -def gen_preprocess_options(macros, include_dirs): - """Generate C pre-processor options (-D, -U, -I) as used by at least - two types of compilers: the typical Unix compiler and Visual C++. - 'macros' is the usual thing, a list of 1- or 2-tuples, where (name,) - means undefine (-U) macro 'name', and (name,value) means define (-D) - macro 'name' to 'value'. 'include_dirs' is just a list of directory - names to be added to the header file search path (-I). Returns a list - of command-line options suitable for either Unix compilers or Visual - C++. - """ - # XXX it would be nice (mainly aesthetic, and so we don't generate - # stupid-looking command lines) to go over 'macros' and eliminate - # redundant definitions/undefinitions (ie. ensure that only the - # latest mention of a particular macro winds up on the command - # line). I don't think it's essential, though, since most (all?) - # Unix C compilers only pay attention to the latest -D or -U - # mention of a macro on their command line. Similar situation for - # 'include_dirs'. I'm punting on both for now. Anyways, weeding out - # redundancies like this should probably be the province of - # CCompiler, since the data structures used are inherited from it - # and therefore common to all CCompiler classes. - pp_opts = [] - for macro in macros: - if not (isinstance(macro, tuple) and 1 <= len(macro) <= 2): - raise TypeError( - "bad macro definition '%s': " - "each element of 'macros' list must be a 1- or 2-tuple" - % macro) - - if len(macro) == 1: # undefine this macro - pp_opts.append("-U%s" % macro[0]) - elif len(macro) == 2: - if macro[1] is None: # define with no explicit value - pp_opts.append("-D%s" % macro[0]) - else: - # XXX *don't* need to be clever about quoting the - # macro value here, because we're going to avoid the - # shell at all costs when we spawn the command! - pp_opts.append("-D%s=%s" % macro) - - for dir in include_dirs: - pp_opts.append("-I%s" % dir) - return pp_opts - - -def gen_lib_options (compiler, library_dirs, runtime_library_dirs, libraries): - """Generate linker options for searching library directories and - linking with specific libraries. 'libraries' and 'library_dirs' are, - respectively, lists of library names (not filenames!) and search - directories. Returns a list of command-line options suitable for use - with some compiler (depending on the two format strings passed in). - """ - lib_opts = [] - - for dir in library_dirs: - lib_opts.append(compiler.library_dir_option(dir)) - - for dir in runtime_library_dirs: - opt = compiler.runtime_library_dir_option(dir) - if isinstance(opt, list): - lib_opts = lib_opts + opt - else: - lib_opts.append(opt) - - # XXX it's important that we *not* remove redundant library mentions! - # sometimes you really do have to say "-lfoo -lbar -lfoo" in order to - # resolve all symbols. I just hope we never have to say "-lfoo obj.o - # -lbar" to get things to work -- that's certainly a possibility, but a - # pretty nasty way to arrange your C code. - - for lib in libraries: - (lib_dir, lib_name) = os.path.split(lib) - if lib_dir: - lib_file = compiler.find_library_file([lib_dir], lib_name) - if lib_file: - lib_opts.append(lib_file) - else: - compiler.warn("no library file corresponding to " - "'%s' found (skipping)" % lib) - else: - lib_opts.append(compiler.library_option (lib)) - return lib_opts diff --git a/python/Lib/distutils/cmd.py b/python/Lib/distutils/cmd.py deleted file mode 100644 index 03a874e..0000000 --- a/python/Lib/distutils/cmd.py +++ /dev/null @@ -1,403 +0,0 @@ -"""distutils.cmd - -Provides the Command class, the base class for the command classes -in the distutils.command package. -""" - -import sys, os, re -from distutils.errors import DistutilsOptionError -from distutils import util, dir_util, file_util, archive_util, dep_util -from distutils import log - -class Command: - """Abstract base class for defining command classes, the "worker bees" - of the Distutils. A useful analogy for command classes is to think of - them as subroutines with local variables called "options". The options - are "declared" in 'initialize_options()' and "defined" (given their - final values, aka "finalized") in 'finalize_options()', both of which - must be defined by every command class. The distinction between the - two is necessary because option values might come from the outside - world (command line, config file, ...), and any options dependent on - other options must be computed *after* these outside influences have - been processed -- hence 'finalize_options()'. The "body" of the - subroutine, where it does all its work based on the values of its - options, is the 'run()' method, which must also be implemented by every - command class. - """ - - # 'sub_commands' formalizes the notion of a "family" of commands, - # eg. "install" as the parent with sub-commands "install_lib", - # "install_headers", etc. The parent of a family of commands - # defines 'sub_commands' as a class attribute; it's a list of - # (command_name : string, predicate : unbound_method | string | None) - # tuples, where 'predicate' is a method of the parent command that - # determines whether the corresponding command is applicable in the - # current situation. (Eg. we "install_headers" is only applicable if - # we have any C header files to install.) If 'predicate' is None, - # that command is always applicable. - # - # 'sub_commands' is usually defined at the *end* of a class, because - # predicates can be unbound methods, so they must already have been - # defined. The canonical example is the "install" command. - sub_commands = [] - - - # -- Creation/initialization methods ------------------------------- - - def __init__(self, dist): - """Create and initialize a new Command object. Most importantly, - invokes the 'initialize_options()' method, which is the real - initializer and depends on the actual command being - instantiated. - """ - # late import because of mutual dependence between these classes - from distutils.dist import Distribution - - if not isinstance(dist, Distribution): - raise TypeError("dist must be a Distribution instance") - if self.__class__ is Command: - raise RuntimeError("Command is an abstract class") - - self.distribution = dist - self.initialize_options() - - # Per-command versions of the global flags, so that the user can - # customize Distutils' behaviour command-by-command and let some - # commands fall back on the Distribution's behaviour. None means - # "not defined, check self.distribution's copy", while 0 or 1 mean - # false and true (duh). Note that this means figuring out the real - # value of each flag is a touch complicated -- hence "self._dry_run" - # will be handled by __getattr__, below. - # XXX This needs to be fixed. - self._dry_run = None - - # verbose is largely ignored, but needs to be set for - # backwards compatibility (I think)? - self.verbose = dist.verbose - - # Some commands define a 'self.force' option to ignore file - # timestamps, but methods defined *here* assume that - # 'self.force' exists for all commands. So define it here - # just to be safe. - self.force = None - - # The 'help' flag is just used for command-line parsing, so - # none of that complicated bureaucracy is needed. - self.help = 0 - - # 'finalized' records whether or not 'finalize_options()' has been - # called. 'finalize_options()' itself should not pay attention to - # this flag: it is the business of 'ensure_finalized()', which - # always calls 'finalize_options()', to respect/update it. - self.finalized = 0 - - # XXX A more explicit way to customize dry_run would be better. - def __getattr__(self, attr): - if attr == 'dry_run': - myval = getattr(self, "_" + attr) - if myval is None: - return getattr(self.distribution, attr) - else: - return myval - else: - raise AttributeError(attr) - - def ensure_finalized(self): - if not self.finalized: - self.finalize_options() - self.finalized = 1 - - # Subclasses must define: - # initialize_options() - # provide default values for all options; may be customized by - # setup script, by options from config file(s), or by command-line - # options - # finalize_options() - # decide on the final values for all options; this is called - # after all possible intervention from the outside world - # (command-line, option file, etc.) has been processed - # run() - # run the command: do whatever it is we're here to do, - # controlled by the command's various option values - - def initialize_options(self): - """Set default values for all the options that this command - supports. Note that these defaults may be overridden by other - commands, by the setup script, by config files, or by the - command-line. Thus, this is not the place to code dependencies - between options; generally, 'initialize_options()' implementations - are just a bunch of "self.foo = None" assignments. - - This method must be implemented by all command classes. - """ - raise RuntimeError("abstract method -- subclass %s must override" - % self.__class__) - - def finalize_options(self): - """Set final values for all the options that this command supports. - This is always called as late as possible, ie. after any option - assignments from the command-line or from other commands have been - done. Thus, this is the place to code option dependencies: if - 'foo' depends on 'bar', then it is safe to set 'foo' from 'bar' as - long as 'foo' still has the same value it was assigned in - 'initialize_options()'. - - This method must be implemented by all command classes. - """ - raise RuntimeError("abstract method -- subclass %s must override" - % self.__class__) - - - def dump_options(self, header=None, indent=""): - from distutils.fancy_getopt import longopt_xlate - if header is None: - header = "command options for '%s':" % self.get_command_name() - self.announce(indent + header, level=log.INFO) - indent = indent + " " - for (option, _, _) in self.user_options: - option = option.translate(longopt_xlate) - if option[-1] == "=": - option = option[:-1] - value = getattr(self, option) - self.announce(indent + "%s = %s" % (option, value), - level=log.INFO) - - def run(self): - """A command's raison d'etre: carry out the action it exists to - perform, controlled by the options initialized in - 'initialize_options()', customized by other commands, the setup - script, the command-line, and config files, and finalized in - 'finalize_options()'. All terminal output and filesystem - interaction should be done by 'run()'. - - This method must be implemented by all command classes. - """ - raise RuntimeError("abstract method -- subclass %s must override" - % self.__class__) - - def announce(self, msg, level=1): - """If the current verbosity level is of greater than or equal to - 'level' print 'msg' to stdout. - """ - log.log(level, msg) - - def debug_print(self, msg): - """Print 'msg' to stdout if the global DEBUG (taken from the - DISTUTILS_DEBUG environment variable) flag is true. - """ - from distutils.debug import DEBUG - if DEBUG: - print(msg) - sys.stdout.flush() - - - # -- Option validation methods ------------------------------------- - # (these are very handy in writing the 'finalize_options()' method) - # - # NB. the general philosophy here is to ensure that a particular option - # value meets certain type and value constraints. If not, we try to - # force it into conformance (eg. if we expect a list but have a string, - # split the string on comma and/or whitespace). If we can't force the - # option into conformance, raise DistutilsOptionError. Thus, command - # classes need do nothing more than (eg.) - # self.ensure_string_list('foo') - # and they can be guaranteed that thereafter, self.foo will be - # a list of strings. - - def _ensure_stringlike(self, option, what, default=None): - val = getattr(self, option) - if val is None: - setattr(self, option, default) - return default - elif not isinstance(val, str): - raise DistutilsOptionError("'%s' must be a %s (got `%s`)" - % (option, what, val)) - return val - - def ensure_string(self, option, default=None): - """Ensure that 'option' is a string; if not defined, set it to - 'default'. - """ - self._ensure_stringlike(option, "string", default) - - def ensure_string_list(self, option): - r"""Ensure that 'option' is a list of strings. If 'option' is - currently a string, we split it either on /,\s*/ or /\s+/, so - "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become - ["foo", "bar", "baz"]. - """ - val = getattr(self, option) - if val is None: - return - elif isinstance(val, str): - setattr(self, option, re.split(r',\s*|\s+', val)) - else: - if isinstance(val, list): - ok = all(isinstance(v, str) for v in val) - else: - ok = False - if not ok: - raise DistutilsOptionError( - "'%s' must be a list of strings (got %r)" - % (option, val)) - - def _ensure_tested_string(self, option, tester, what, error_fmt, - default=None): - val = self._ensure_stringlike(option, what, default) - if val is not None and not tester(val): - raise DistutilsOptionError(("error in '%s' option: " + error_fmt) - % (option, val)) - - def ensure_filename(self, option): - """Ensure that 'option' is the name of an existing file.""" - self._ensure_tested_string(option, os.path.isfile, - "filename", - "'%s' does not exist or is not a file") - - def ensure_dirname(self, option): - self._ensure_tested_string(option, os.path.isdir, - "directory name", - "'%s' does not exist or is not a directory") - - - # -- Convenience methods for commands ------------------------------ - - def get_command_name(self): - if hasattr(self, 'command_name'): - return self.command_name - else: - return self.__class__.__name__ - - def set_undefined_options(self, src_cmd, *option_pairs): - """Set the values of any "undefined" options from corresponding - option values in some other command object. "Undefined" here means - "is None", which is the convention used to indicate that an option - has not been changed between 'initialize_options()' and - 'finalize_options()'. Usually called from 'finalize_options()' for - options that depend on some other command rather than another - option of the same command. 'src_cmd' is the other command from - which option values will be taken (a command object will be created - for it if necessary); the remaining arguments are - '(src_option,dst_option)' tuples which mean "take the value of - 'src_option' in the 'src_cmd' command object, and copy it to - 'dst_option' in the current command object". - """ - # Option_pairs: list of (src_option, dst_option) tuples - src_cmd_obj = self.distribution.get_command_obj(src_cmd) - src_cmd_obj.ensure_finalized() - for (src_option, dst_option) in option_pairs: - if getattr(self, dst_option) is None: - setattr(self, dst_option, getattr(src_cmd_obj, src_option)) - - def get_finalized_command(self, command, create=1): - """Wrapper around Distribution's 'get_command_obj()' method: find - (create if necessary and 'create' is true) the command object for - 'command', call its 'ensure_finalized()' method, and return the - finalized command object. - """ - cmd_obj = self.distribution.get_command_obj(command, create) - cmd_obj.ensure_finalized() - return cmd_obj - - # XXX rename to 'get_reinitialized_command()'? (should do the - # same in dist.py, if so) - def reinitialize_command(self, command, reinit_subcommands=0): - return self.distribution.reinitialize_command(command, - reinit_subcommands) - - def run_command(self, command): - """Run some other command: uses the 'run_command()' method of - Distribution, which creates and finalizes the command object if - necessary and then invokes its 'run()' method. - """ - self.distribution.run_command(command) - - def get_sub_commands(self): - """Determine the sub-commands that are relevant in the current - distribution (ie., that need to be run). This is based on the - 'sub_commands' class attribute: each tuple in that list may include - a method that we call to determine if the subcommand needs to be - run for the current distribution. Return a list of command names. - """ - commands = [] - for (cmd_name, method) in self.sub_commands: - if method is None or method(self): - commands.append(cmd_name) - return commands - - - # -- External world manipulation ----------------------------------- - - def warn(self, msg): - log.warn("warning: %s: %s\n", self.get_command_name(), msg) - - def execute(self, func, args, msg=None, level=1): - util.execute(func, args, msg, dry_run=self.dry_run) - - def mkpath(self, name, mode=0o777): - dir_util.mkpath(name, mode, dry_run=self.dry_run) - - def copy_file(self, infile, outfile, preserve_mode=1, preserve_times=1, - link=None, level=1): - """Copy a file respecting verbose, dry-run and force flags. (The - former two default to whatever is in the Distribution object, and - the latter defaults to false for commands that don't define it.)""" - return file_util.copy_file(infile, outfile, preserve_mode, - preserve_times, not self.force, link, - dry_run=self.dry_run) - - def copy_tree(self, infile, outfile, preserve_mode=1, preserve_times=1, - preserve_symlinks=0, level=1): - """Copy an entire directory tree respecting verbose, dry-run, - and force flags. - """ - return dir_util.copy_tree(infile, outfile, preserve_mode, - preserve_times, preserve_symlinks, - not self.force, dry_run=self.dry_run) - - def move_file (self, src, dst, level=1): - """Move a file respecting dry-run flag.""" - return file_util.move_file(src, dst, dry_run=self.dry_run) - - def spawn(self, cmd, search_path=1, level=1): - """Spawn an external command respecting dry-run flag.""" - from distutils.spawn import spawn - spawn(cmd, search_path, dry_run=self.dry_run) - - def make_archive(self, base_name, format, root_dir=None, base_dir=None, - owner=None, group=None): - return archive_util.make_archive(base_name, format, root_dir, base_dir, - dry_run=self.dry_run, - owner=owner, group=group) - - def make_file(self, infiles, outfile, func, args, - exec_msg=None, skip_msg=None, level=1): - """Special case of 'execute()' for operations that process one or - more input files and generate one output file. Works just like - 'execute()', except the operation is skipped and a different - message printed if 'outfile' already exists and is newer than all - files listed in 'infiles'. If the command defined 'self.force', - and it is true, then the command is unconditionally run -- does no - timestamp checks. - """ - if skip_msg is None: - skip_msg = "skipping %s (inputs unchanged)" % outfile - - # Allow 'infiles' to be a single string - if isinstance(infiles, str): - infiles = (infiles,) - elif not isinstance(infiles, (list, tuple)): - raise TypeError( - "'infiles' must be a string, or a list or tuple of strings") - - if exec_msg is None: - exec_msg = "generating %s from %s" % (outfile, ', '.join(infiles)) - - # If 'outfile' must be regenerated (either because it doesn't - # exist, is out-of-date, or the 'force' flag is true) then - # perform the action that presumably regenerates it - if self.force or dep_util.newer_group(infiles, outfile): - self.execute(func, args, exec_msg, level) - # Otherwise, print the "skip" message - else: - log.debug(skip_msg) diff --git a/python/Lib/distutils/command/__init__.py b/python/Lib/distutils/command/__init__.py deleted file mode 100644 index 892bdb9..0000000 --- a/python/Lib/distutils/command/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -"""distutils.command - -Package containing implementation of all the standard Distutils -commands.""" - -__all__ = ['build', - 'build_py', - 'build_ext', - 'build_clib', - 'build_scripts', - 'clean', - 'install', - 'install_lib', - 'install_headers', - 'install_scripts', - 'install_data', - 'sdist', - 'register', - 'bdist', - 'bdist_dumb', - 'bdist_rpm', - 'check', - 'upload', - # These two are reserved for future use: - #'bdist_sdux', - #'bdist_pkgtool', - # Note: - # bdist_packager is not included because it only provides - # an abstract base class - ] diff --git a/python/Lib/distutils/command/bdist.py b/python/Lib/distutils/command/bdist.py deleted file mode 100644 index 642832f..0000000 --- a/python/Lib/distutils/command/bdist.py +++ /dev/null @@ -1,138 +0,0 @@ -"""distutils.command.bdist - -Implements the Distutils 'bdist' command (create a built [binary] -distribution).""" - -import os -from distutils.core import Command -from distutils.errors import * -from distutils.util import get_platform - - -def show_formats(): - """Print list of available formats (arguments to "--format" option). - """ - from distutils.fancy_getopt import FancyGetopt - formats = [] - for format in bdist.format_commands: - formats.append(("formats=" + format, None, - bdist.format_command[format][1])) - pretty_printer = FancyGetopt(formats) - pretty_printer.print_help("List of available distribution formats:") - - -class bdist(Command): - - description = "create a built (binary) distribution" - - user_options = [('bdist-base=', 'b', - "temporary directory for creating built distributions"), - ('plat-name=', 'p', - "platform name to embed in generated filenames " - "(default: %s)" % get_platform()), - ('formats=', None, - "formats for distribution (comma-separated list)"), - ('dist-dir=', 'd', - "directory to put final built distributions in " - "[default: dist]"), - ('skip-build', None, - "skip rebuilding everything (for testing/debugging)"), - ('owner=', 'u', - "Owner name used when creating a tar file" - " [default: current user]"), - ('group=', 'g', - "Group name used when creating a tar file" - " [default: current group]"), - ] - - boolean_options = ['skip-build'] - - help_options = [ - ('help-formats', None, - "lists available distribution formats", show_formats), - ] - - # The following commands do not take a format option from bdist - no_format_option = ('bdist_rpm',) - - # This won't do in reality: will need to distinguish RPM-ish Linux, - # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS. - default_format = {'posix': 'gztar', - 'nt': 'zip'} - - # Establish the preferred order (for the --help-formats option). - format_commands = ['rpm', 'gztar', 'bztar', 'xztar', 'ztar', 'tar', 'zip'] - - # And the real information. - format_command = {'rpm': ('bdist_rpm', "RPM distribution"), - 'gztar': ('bdist_dumb', "gzip'ed tar file"), - 'bztar': ('bdist_dumb', "bzip2'ed tar file"), - 'xztar': ('bdist_dumb', "xz'ed tar file"), - 'ztar': ('bdist_dumb', "compressed tar file"), - 'tar': ('bdist_dumb', "tar file"), - 'zip': ('bdist_dumb', "ZIP file"), - } - - def initialize_options(self): - self.bdist_base = None - self.plat_name = None - self.formats = None - self.dist_dir = None - self.skip_build = 0 - self.group = None - self.owner = None - - def finalize_options(self): - # have to finalize 'plat_name' before 'bdist_base' - if self.plat_name is None: - if self.skip_build: - self.plat_name = get_platform() - else: - self.plat_name = self.get_finalized_command('build').plat_name - - # 'bdist_base' -- parent of per-built-distribution-format - # temporary directories (eg. we'll probably have - # "build/bdist./dumb", "build/bdist./rpm", etc.) - if self.bdist_base is None: - build_base = self.get_finalized_command('build').build_base - self.bdist_base = os.path.join(build_base, - 'bdist.' + self.plat_name) - - self.ensure_string_list('formats') - if self.formats is None: - try: - self.formats = [self.default_format[os.name]] - except KeyError: - raise DistutilsPlatformError( - "don't know how to create built distributions " - "on platform %s" % os.name) - - if self.dist_dir is None: - self.dist_dir = "dist" - - def run(self): - # Figure out which sub-commands we need to run. - commands = [] - for format in self.formats: - try: - commands.append(self.format_command[format][0]) - except KeyError: - raise DistutilsOptionError("invalid format '%s'" % format) - - # Reinitialize and run each command. - for i in range(len(self.formats)): - cmd_name = commands[i] - sub_cmd = self.reinitialize_command(cmd_name) - if cmd_name not in self.no_format_option: - sub_cmd.format = self.formats[i] - - # passing the owner and group names for tar archiving - if cmd_name == 'bdist_dumb': - sub_cmd.owner = self.owner - sub_cmd.group = self.group - - # If we're going to need to run this command again, tell it to - # keep its temporary files around so subsequent runs go faster. - if cmd_name in commands[i+1:]: - sub_cmd.keep_temp = 1 - self.run_command(cmd_name) diff --git a/python/Lib/distutils/command/bdist_dumb.py b/python/Lib/distutils/command/bdist_dumb.py deleted file mode 100644 index d387b35..0000000 --- a/python/Lib/distutils/command/bdist_dumb.py +++ /dev/null @@ -1,123 +0,0 @@ -"""distutils.command.bdist_dumb - -Implements the Distutils 'bdist_dumb' command (create a "dumb" built -distribution -- i.e., just an archive to be unpacked under $prefix or -$exec_prefix).""" - -import os -from distutils.core import Command -from distutils.util import get_platform -from distutils.dir_util import remove_tree, ensure_relative -from distutils.errors import * -from distutils.sysconfig import get_python_version -from distutils import log - -class bdist_dumb(Command): - - description = "create a \"dumb\" built distribution" - - user_options = [('bdist-dir=', 'd', - "temporary directory for creating the distribution"), - ('plat-name=', 'p', - "platform name to embed in generated filenames " - "(default: %s)" % get_platform()), - ('format=', 'f', - "archive format to create (tar, gztar, bztar, xztar, " - "ztar, zip)"), - ('keep-temp', 'k', - "keep the pseudo-installation tree around after " + - "creating the distribution archive"), - ('dist-dir=', 'd', - "directory to put final built distributions in"), - ('skip-build', None, - "skip rebuilding everything (for testing/debugging)"), - ('relative', None, - "build the archive using relative paths " - "(default: false)"), - ('owner=', 'u', - "Owner name used when creating a tar file" - " [default: current user]"), - ('group=', 'g', - "Group name used when creating a tar file" - " [default: current group]"), - ] - - boolean_options = ['keep-temp', 'skip-build', 'relative'] - - default_format = { 'posix': 'gztar', - 'nt': 'zip' } - - def initialize_options(self): - self.bdist_dir = None - self.plat_name = None - self.format = None - self.keep_temp = 0 - self.dist_dir = None - self.skip_build = None - self.relative = 0 - self.owner = None - self.group = None - - def finalize_options(self): - if self.bdist_dir is None: - bdist_base = self.get_finalized_command('bdist').bdist_base - self.bdist_dir = os.path.join(bdist_base, 'dumb') - - if self.format is None: - try: - self.format = self.default_format[os.name] - except KeyError: - raise DistutilsPlatformError( - "don't know how to create dumb built distributions " - "on platform %s" % os.name) - - self.set_undefined_options('bdist', - ('dist_dir', 'dist_dir'), - ('plat_name', 'plat_name'), - ('skip_build', 'skip_build')) - - def run(self): - if not self.skip_build: - self.run_command('build') - - install = self.reinitialize_command('install', reinit_subcommands=1) - install.root = self.bdist_dir - install.skip_build = self.skip_build - install.warn_dir = 0 - - log.info("installing to %s", self.bdist_dir) - self.run_command('install') - - # And make an archive relative to the root of the - # pseudo-installation tree. - archive_basename = "%s.%s" % (self.distribution.get_fullname(), - self.plat_name) - - pseudoinstall_root = os.path.join(self.dist_dir, archive_basename) - if not self.relative: - archive_root = self.bdist_dir - else: - if (self.distribution.has_ext_modules() and - (install.install_base != install.install_platbase)): - raise DistutilsPlatformError( - "can't make a dumb built distribution where " - "base and platbase are different (%s, %s)" - % (repr(install.install_base), - repr(install.install_platbase))) - else: - archive_root = os.path.join(self.bdist_dir, - ensure_relative(install.install_base)) - - # Make the archive - filename = self.make_archive(pseudoinstall_root, - self.format, root_dir=archive_root, - owner=self.owner, group=self.group) - if self.distribution.has_ext_modules(): - pyversion = get_python_version() - else: - pyversion = 'any' - self.distribution.dist_files.append(('bdist_dumb', pyversion, - filename)) - - if not self.keep_temp: - remove_tree(self.bdist_dir, dry_run=self.dry_run) diff --git a/python/Lib/distutils/command/bdist_rpm.py b/python/Lib/distutils/command/bdist_rpm.py deleted file mode 100644 index 0a6bd3e..0000000 --- a/python/Lib/distutils/command/bdist_rpm.py +++ /dev/null @@ -1,579 +0,0 @@ -"""distutils.command.bdist_rpm - -Implements the Distutils 'bdist_rpm' command (create RPM source and binary -distributions).""" - -import subprocess, sys, os -from distutils.core import Command -from distutils.debug import DEBUG -from distutils.file_util import write_file -from distutils.errors import * -from distutils.sysconfig import get_python_version -from distutils import log - -class bdist_rpm(Command): - - description = "create an RPM distribution" - - user_options = [ - ('bdist-base=', None, - "base directory for creating built distributions"), - ('rpm-base=', None, - "base directory for creating RPMs (defaults to \"rpm\" under " - "--bdist-base; must be specified for RPM 2)"), - ('dist-dir=', 'd', - "directory to put final RPM files in " - "(and .spec files if --spec-only)"), - ('python=', None, - "path to Python interpreter to hard-code in the .spec file " - "(default: \"python\")"), - ('fix-python', None, - "hard-code the exact path to the current Python interpreter in " - "the .spec file"), - ('spec-only', None, - "only regenerate spec file"), - ('source-only', None, - "only generate source RPM"), - ('binary-only', None, - "only generate binary RPM"), - ('use-bzip2', None, - "use bzip2 instead of gzip to create source distribution"), - - # More meta-data: too RPM-specific to put in the setup script, - # but needs to go in the .spec file -- so we make these options - # to "bdist_rpm". The idea is that packagers would put this - # info in setup.cfg, although they are of course free to - # supply it on the command line. - ('distribution-name=', None, - "name of the (Linux) distribution to which this " - "RPM applies (*not* the name of the module distribution!)"), - ('group=', None, - "package classification [default: \"Development/Libraries\"]"), - ('release=', None, - "RPM release number"), - ('serial=', None, - "RPM serial number"), - ('vendor=', None, - "RPM \"vendor\" (eg. \"Joe Blow \") " - "[default: maintainer or author from setup script]"), - ('packager=', None, - "RPM packager (eg. \"Jane Doe \") " - "[default: vendor]"), - ('doc-files=', None, - "list of documentation files (space or comma-separated)"), - ('changelog=', None, - "RPM changelog"), - ('icon=', None, - "name of icon file"), - ('provides=', None, - "capabilities provided by this package"), - ('requires=', None, - "capabilities required by this package"), - ('conflicts=', None, - "capabilities which conflict with this package"), - ('build-requires=', None, - "capabilities required to build this package"), - ('obsoletes=', None, - "capabilities made obsolete by this package"), - ('no-autoreq', None, - "do not automatically calculate dependencies"), - - # Actions to take when building RPM - ('keep-temp', 'k', - "don't clean up RPM build directory"), - ('no-keep-temp', None, - "clean up RPM build directory [default]"), - ('use-rpm-opt-flags', None, - "compile with RPM_OPT_FLAGS when building from source RPM"), - ('no-rpm-opt-flags', None, - "do not pass any RPM CFLAGS to compiler"), - ('rpm3-mode', None, - "RPM 3 compatibility mode (default)"), - ('rpm2-mode', None, - "RPM 2 compatibility mode"), - - # Add the hooks necessary for specifying custom scripts - ('prep-script=', None, - "Specify a script for the PREP phase of RPM building"), - ('build-script=', None, - "Specify a script for the BUILD phase of RPM building"), - - ('pre-install=', None, - "Specify a script for the pre-INSTALL phase of RPM building"), - ('install-script=', None, - "Specify a script for the INSTALL phase of RPM building"), - ('post-install=', None, - "Specify a script for the post-INSTALL phase of RPM building"), - - ('pre-uninstall=', None, - "Specify a script for the pre-UNINSTALL phase of RPM building"), - ('post-uninstall=', None, - "Specify a script for the post-UNINSTALL phase of RPM building"), - - ('clean-script=', None, - "Specify a script for the CLEAN phase of RPM building"), - - ('verify-script=', None, - "Specify a script for the VERIFY phase of the RPM build"), - - # Allow a packager to explicitly force an architecture - ('force-arch=', None, - "Force an architecture onto the RPM build process"), - - ('quiet', 'q', - "Run the INSTALL phase of RPM building in quiet mode"), - ] - - boolean_options = ['keep-temp', 'use-rpm-opt-flags', 'rpm3-mode', - 'no-autoreq', 'quiet'] - - negative_opt = {'no-keep-temp': 'keep-temp', - 'no-rpm-opt-flags': 'use-rpm-opt-flags', - 'rpm2-mode': 'rpm3-mode'} - - - def initialize_options(self): - self.bdist_base = None - self.rpm_base = None - self.dist_dir = None - self.python = None - self.fix_python = None - self.spec_only = None - self.binary_only = None - self.source_only = None - self.use_bzip2 = None - - self.distribution_name = None - self.group = None - self.release = None - self.serial = None - self.vendor = None - self.packager = None - self.doc_files = None - self.changelog = None - self.icon = None - - self.prep_script = None - self.build_script = None - self.install_script = None - self.clean_script = None - self.verify_script = None - self.pre_install = None - self.post_install = None - self.pre_uninstall = None - self.post_uninstall = None - self.prep = None - self.provides = None - self.requires = None - self.conflicts = None - self.build_requires = None - self.obsoletes = None - - self.keep_temp = 0 - self.use_rpm_opt_flags = 1 - self.rpm3_mode = 1 - self.no_autoreq = 0 - - self.force_arch = None - self.quiet = 0 - - def finalize_options(self): - self.set_undefined_options('bdist', ('bdist_base', 'bdist_base')) - if self.rpm_base is None: - if not self.rpm3_mode: - raise DistutilsOptionError( - "you must specify --rpm-base in RPM 2 mode") - self.rpm_base = os.path.join(self.bdist_base, "rpm") - - if self.python is None: - if self.fix_python: - self.python = sys.executable - else: - self.python = "python3" - elif self.fix_python: - raise DistutilsOptionError( - "--python and --fix-python are mutually exclusive options") - - if os.name != 'posix': - raise DistutilsPlatformError("don't know how to create RPM " - "distributions on platform %s" % os.name) - if self.binary_only and self.source_only: - raise DistutilsOptionError( - "cannot supply both '--source-only' and '--binary-only'") - - # don't pass CFLAGS to pure python distributions - if not self.distribution.has_ext_modules(): - self.use_rpm_opt_flags = 0 - - self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) - self.finalize_package_data() - - def finalize_package_data(self): - self.ensure_string('group', "Development/Libraries") - self.ensure_string('vendor', - "%s <%s>" % (self.distribution.get_contact(), - self.distribution.get_contact_email())) - self.ensure_string('packager') - self.ensure_string_list('doc_files') - if isinstance(self.doc_files, list): - for readme in ('README', 'README.txt'): - if os.path.exists(readme) and readme not in self.doc_files: - self.doc_files.append(readme) - - self.ensure_string('release', "1") - self.ensure_string('serial') # should it be an int? - - self.ensure_string('distribution_name') - - self.ensure_string('changelog') - # Format changelog correctly - self.changelog = self._format_changelog(self.changelog) - - self.ensure_filename('icon') - - self.ensure_filename('prep_script') - self.ensure_filename('build_script') - self.ensure_filename('install_script') - self.ensure_filename('clean_script') - self.ensure_filename('verify_script') - self.ensure_filename('pre_install') - self.ensure_filename('post_install') - self.ensure_filename('pre_uninstall') - self.ensure_filename('post_uninstall') - - # XXX don't forget we punted on summaries and descriptions -- they - # should be handled here eventually! - - # Now *this* is some meta-data that belongs in the setup script... - self.ensure_string_list('provides') - self.ensure_string_list('requires') - self.ensure_string_list('conflicts') - self.ensure_string_list('build_requires') - self.ensure_string_list('obsoletes') - - self.ensure_string('force_arch') - - def run(self): - if DEBUG: - print("before _get_package_data():") - print("vendor =", self.vendor) - print("packager =", self.packager) - print("doc_files =", self.doc_files) - print("changelog =", self.changelog) - - # make directories - if self.spec_only: - spec_dir = self.dist_dir - self.mkpath(spec_dir) - else: - rpm_dir = {} - for d in ('SOURCES', 'SPECS', 'BUILD', 'RPMS', 'SRPMS'): - rpm_dir[d] = os.path.join(self.rpm_base, d) - self.mkpath(rpm_dir[d]) - spec_dir = rpm_dir['SPECS'] - - # Spec file goes into 'dist_dir' if '--spec-only specified', - # build/rpm. otherwise. - spec_path = os.path.join(spec_dir, - "%s.spec" % self.distribution.get_name()) - self.execute(write_file, - (spec_path, - self._make_spec_file()), - "writing '%s'" % spec_path) - - if self.spec_only: # stop if requested - return - - # Make a source distribution and copy to SOURCES directory with - # optional icon. - saved_dist_files = self.distribution.dist_files[:] - sdist = self.reinitialize_command('sdist') - if self.use_bzip2: - sdist.formats = ['bztar'] - else: - sdist.formats = ['gztar'] - self.run_command('sdist') - self.distribution.dist_files = saved_dist_files - - source = sdist.get_archive_files()[0] - source_dir = rpm_dir['SOURCES'] - self.copy_file(source, source_dir) - - if self.icon: - if os.path.exists(self.icon): - self.copy_file(self.icon, source_dir) - else: - raise DistutilsFileError( - "icon file '%s' does not exist" % self.icon) - - # build package - log.info("building RPMs") - rpm_cmd = ['rpmbuild'] - - if self.source_only: # what kind of RPMs? - rpm_cmd.append('-bs') - elif self.binary_only: - rpm_cmd.append('-bb') - else: - rpm_cmd.append('-ba') - rpm_cmd.extend(['--define', '__python %s' % self.python]) - if self.rpm3_mode: - rpm_cmd.extend(['--define', - '_topdir %s' % os.path.abspath(self.rpm_base)]) - if not self.keep_temp: - rpm_cmd.append('--clean') - - if self.quiet: - rpm_cmd.append('--quiet') - - rpm_cmd.append(spec_path) - # Determine the binary rpm names that should be built out of this spec - # file - # Note that some of these may not be really built (if the file - # list is empty) - nvr_string = "%{name}-%{version}-%{release}" - src_rpm = nvr_string + ".src.rpm" - non_src_rpm = "%{arch}/" + nvr_string + ".%{arch}.rpm" - q_cmd = r"rpm -q --qf '%s %s\n' --specfile '%s'" % ( - src_rpm, non_src_rpm, spec_path) - - out = os.popen(q_cmd) - try: - binary_rpms = [] - source_rpm = None - while True: - line = out.readline() - if not line: - break - l = line.strip().split() - assert(len(l) == 2) - binary_rpms.append(l[1]) - # The source rpm is named after the first entry in the spec file - if source_rpm is None: - source_rpm = l[0] - - status = out.close() - if status: - raise DistutilsExecError("Failed to execute: %s" % repr(q_cmd)) - - finally: - out.close() - - self.spawn(rpm_cmd) - - if not self.dry_run: - if self.distribution.has_ext_modules(): - pyversion = get_python_version() - else: - pyversion = 'any' - - if not self.binary_only: - srpm = os.path.join(rpm_dir['SRPMS'], source_rpm) - assert(os.path.exists(srpm)) - self.move_file(srpm, self.dist_dir) - filename = os.path.join(self.dist_dir, source_rpm) - self.distribution.dist_files.append( - ('bdist_rpm', pyversion, filename)) - - if not self.source_only: - for rpm in binary_rpms: - rpm = os.path.join(rpm_dir['RPMS'], rpm) - if os.path.exists(rpm): - self.move_file(rpm, self.dist_dir) - filename = os.path.join(self.dist_dir, - os.path.basename(rpm)) - self.distribution.dist_files.append( - ('bdist_rpm', pyversion, filename)) - - def _dist_path(self, path): - return os.path.join(self.dist_dir, os.path.basename(path)) - - def _make_spec_file(self): - """Generate the text of an RPM spec file and return it as a - list of strings (one per line). - """ - # definitions and headers - spec_file = [ - '%define name ' + self.distribution.get_name(), - '%define version ' + self.distribution.get_version().replace('-','_'), - '%define unmangled_version ' + self.distribution.get_version(), - '%define release ' + self.release.replace('-','_'), - '', - 'Summary: ' + self.distribution.get_description(), - ] - - # Workaround for #14443 which affects some RPM based systems such as - # RHEL6 (and probably derivatives) - vendor_hook = subprocess.getoutput('rpm --eval %{__os_install_post}') - # Generate a potential replacement value for __os_install_post (whilst - # normalizing the whitespace to simplify the test for whether the - # invocation of brp-python-bytecompile passes in __python): - vendor_hook = '\n'.join([' %s \\' % line.strip() - for line in vendor_hook.splitlines()]) - problem = "brp-python-bytecompile \\\n" - fixed = "brp-python-bytecompile %{__python} \\\n" - fixed_hook = vendor_hook.replace(problem, fixed) - if fixed_hook != vendor_hook: - spec_file.append('# Workaround for http://bugs.python.org/issue14443') - spec_file.append('%define __os_install_post ' + fixed_hook + '\n') - - # put locale summaries into spec file - # XXX not supported for now (hard to put a dictionary - # in a config file -- arg!) - #for locale in self.summaries.keys(): - # spec_file.append('Summary(%s): %s' % (locale, - # self.summaries[locale])) - - spec_file.extend([ - 'Name: %{name}', - 'Version: %{version}', - 'Release: %{release}',]) - - # XXX yuck! this filename is available from the "sdist" command, - # but only after it has run: and we create the spec file before - # running "sdist", in case of --spec-only. - if self.use_bzip2: - spec_file.append('Source0: %{name}-%{unmangled_version}.tar.bz2') - else: - spec_file.append('Source0: %{name}-%{unmangled_version}.tar.gz') - - spec_file.extend([ - 'License: ' + self.distribution.get_license(), - 'Group: ' + self.group, - 'BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot', - 'Prefix: %{_prefix}', ]) - - if not self.force_arch: - # noarch if no extension modules - if not self.distribution.has_ext_modules(): - spec_file.append('BuildArch: noarch') - else: - spec_file.append( 'BuildArch: %s' % self.force_arch ) - - for field in ('Vendor', - 'Packager', - 'Provides', - 'Requires', - 'Conflicts', - 'Obsoletes', - ): - val = getattr(self, field.lower()) - if isinstance(val, list): - spec_file.append('%s: %s' % (field, ' '.join(val))) - elif val is not None: - spec_file.append('%s: %s' % (field, val)) - - - if self.distribution.get_url() != 'UNKNOWN': - spec_file.append('Url: ' + self.distribution.get_url()) - - if self.distribution_name: - spec_file.append('Distribution: ' + self.distribution_name) - - if self.build_requires: - spec_file.append('BuildRequires: ' + - ' '.join(self.build_requires)) - - if self.icon: - spec_file.append('Icon: ' + os.path.basename(self.icon)) - - if self.no_autoreq: - spec_file.append('AutoReq: 0') - - spec_file.extend([ - '', - '%description', - self.distribution.get_long_description() - ]) - - # put locale descriptions into spec file - # XXX again, suppressed because config file syntax doesn't - # easily support this ;-( - #for locale in self.descriptions.keys(): - # spec_file.extend([ - # '', - # '%description -l ' + locale, - # self.descriptions[locale], - # ]) - - # rpm scripts - # figure out default build script - def_setup_call = "%s %s" % (self.python,os.path.basename(sys.argv[0])) - def_build = "%s build" % def_setup_call - if self.use_rpm_opt_flags: - def_build = 'env CFLAGS="$RPM_OPT_FLAGS" ' + def_build - - # insert contents of files - - # XXX this is kind of misleading: user-supplied options are files - # that we open and interpolate into the spec file, but the defaults - # are just text that we drop in as-is. Hmmm. - - install_cmd = ('%s install -O1 --root=$RPM_BUILD_ROOT ' - '--record=INSTALLED_FILES') % def_setup_call - - script_options = [ - ('prep', 'prep_script', "%setup -n %{name}-%{unmangled_version}"), - ('build', 'build_script', def_build), - ('install', 'install_script', install_cmd), - ('clean', 'clean_script', "rm -rf $RPM_BUILD_ROOT"), - ('verifyscript', 'verify_script', None), - ('pre', 'pre_install', None), - ('post', 'post_install', None), - ('preun', 'pre_uninstall', None), - ('postun', 'post_uninstall', None), - ] - - for (rpm_opt, attr, default) in script_options: - # Insert contents of file referred to, if no file is referred to - # use 'default' as contents of script - val = getattr(self, attr) - if val or default: - spec_file.extend([ - '', - '%' + rpm_opt,]) - if val: - with open(val) as f: - spec_file.extend(f.read().split('\n')) - else: - spec_file.append(default) - - - # files section - spec_file.extend([ - '', - '%files -f INSTALLED_FILES', - '%defattr(-,root,root)', - ]) - - if self.doc_files: - spec_file.append('%doc ' + ' '.join(self.doc_files)) - - if self.changelog: - spec_file.extend([ - '', - '%changelog',]) - spec_file.extend(self.changelog) - - return spec_file - - def _format_changelog(self, changelog): - """Format the changelog correctly and convert it to a list of strings - """ - if not changelog: - return changelog - new_changelog = [] - for line in changelog.strip().split('\n'): - line = line.strip() - if line[0] == '*': - new_changelog.extend(['', line]) - elif line[0] == '-': - new_changelog.append(line) - else: - new_changelog.append(' ' + line) - - # strip trailing newline inserted by first changelog entry - if not new_changelog[0]: - del new_changelog[0] - - return new_changelog diff --git a/python/Lib/distutils/command/build.py b/python/Lib/distutils/command/build.py deleted file mode 100644 index 5660d12..0000000 --- a/python/Lib/distutils/command/build.py +++ /dev/null @@ -1,157 +0,0 @@ -"""distutils.command.build - -Implements the Distutils 'build' command.""" - -import sys, os -from distutils.core import Command -from distutils.errors import DistutilsOptionError -from distutils.util import get_platform - - -def show_compilers(): - from distutils.ccompiler import show_compilers - show_compilers() - - -class build(Command): - - description = "build everything needed to install" - - user_options = [ - ('build-base=', 'b', - "base directory for build library"), - ('build-purelib=', None, - "build directory for platform-neutral distributions"), - ('build-platlib=', None, - "build directory for platform-specific distributions"), - ('build-lib=', None, - "build directory for all distribution (defaults to either " + - "build-purelib or build-platlib"), - ('build-scripts=', None, - "build directory for scripts"), - ('build-temp=', 't', - "temporary build directory"), - ('plat-name=', 'p', - "platform name to build for, if supported " - "(default: %s)" % get_platform()), - ('compiler=', 'c', - "specify the compiler type"), - ('parallel=', 'j', - "number of parallel build jobs"), - ('debug', 'g', - "compile extensions and libraries with debugging information"), - ('force', 'f', - "forcibly build everything (ignore file timestamps)"), - ('executable=', 'e', - "specify final destination interpreter path (build.py)"), - ] - - boolean_options = ['debug', 'force'] - - help_options = [ - ('help-compiler', None, - "list available compilers", show_compilers), - ] - - def initialize_options(self): - self.build_base = 'build' - # these are decided only after 'build_base' has its final value - # (unless overridden by the user or client) - self.build_purelib = None - self.build_platlib = None - self.build_lib = None - self.build_temp = None - self.build_scripts = None - self.compiler = None - self.plat_name = None - self.debug = None - self.force = 0 - self.executable = None - self.parallel = None - - def finalize_options(self): - if self.plat_name is None: - self.plat_name = get_platform() - else: - # plat-name only supported for windows (other platforms are - # supported via ./configure flags, if at all). Avoid misleading - # other platforms. - if os.name != 'nt': - raise DistutilsOptionError( - "--plat-name only supported on Windows (try " - "using './configure --help' on your platform)") - - plat_specifier = ".%s-%d.%d" % (self.plat_name, *sys.version_info[:2]) - - # Make it so Python 2.x and Python 2.x with --with-pydebug don't - # share the same build directories. Doing so confuses the build - # process for C modules - if hasattr(sys, 'gettotalrefcount'): - plat_specifier += '-pydebug' - - # 'build_purelib' and 'build_platlib' just default to 'lib' and - # 'lib.' under the base build directory. We only use one of - # them for a given distribution, though -- - if self.build_purelib is None: - self.build_purelib = os.path.join(self.build_base, 'lib') - if self.build_platlib is None: - self.build_platlib = os.path.join(self.build_base, - 'lib' + plat_specifier) - - # 'build_lib' is the actual directory that we will use for this - # particular module distribution -- if user didn't supply it, pick - # one of 'build_purelib' or 'build_platlib'. - if self.build_lib is None: - if self.distribution.ext_modules: - self.build_lib = self.build_platlib - else: - self.build_lib = self.build_purelib - - # 'build_temp' -- temporary directory for compiler turds, - # "build/temp." - if self.build_temp is None: - self.build_temp = os.path.join(self.build_base, - 'temp' + plat_specifier) - if self.build_scripts is None: - self.build_scripts = os.path.join(self.build_base, - 'scripts-%d.%d' % sys.version_info[:2]) - - if self.executable is None and sys.executable: - self.executable = os.path.normpath(sys.executable) - - if isinstance(self.parallel, str): - try: - self.parallel = int(self.parallel) - except ValueError: - raise DistutilsOptionError("parallel should be an integer") - - def run(self): - # Run all relevant sub-commands. This will be some subset of: - # - build_py - pure Python modules - # - build_clib - standalone C libraries - # - build_ext - Python extensions - # - build_scripts - (Python) scripts - for cmd_name in self.get_sub_commands(): - self.run_command(cmd_name) - - - # -- Predicates for the sub-command list --------------------------- - - def has_pure_modules(self): - return self.distribution.has_pure_modules() - - def has_c_libraries(self): - return self.distribution.has_c_libraries() - - def has_ext_modules(self): - return self.distribution.has_ext_modules() - - def has_scripts(self): - return self.distribution.has_scripts() - - - sub_commands = [('build_py', has_pure_modules), - ('build_clib', has_c_libraries), - ('build_ext', has_ext_modules), - ('build_scripts', has_scripts), - ] diff --git a/python/Lib/distutils/command/build_clib.py b/python/Lib/distutils/command/build_clib.py deleted file mode 100644 index c5bebbf..0000000 --- a/python/Lib/distutils/command/build_clib.py +++ /dev/null @@ -1,209 +0,0 @@ -"""distutils.command.build_clib - -Implements the Distutils 'build_clib' command, to build a C/C++ library -that is included in the module distribution and needed by an extension -module.""" - - -# XXX this module has *lots* of code ripped-off quite transparently from -# build_ext.py -- not surprisingly really, as the work required to build -# a static library from a collection of C source files is not really all -# that different from what's required to build a shared object file from -# a collection of C source files. Nevertheless, I haven't done the -# necessary refactoring to account for the overlap in code between the -# two modules, mainly because a number of subtle details changed in the -# cut 'n paste. Sigh. - -import os -from distutils.core import Command -from distutils.errors import * -from distutils.sysconfig import customize_compiler -from distutils import log - -def show_compilers(): - from distutils.ccompiler import show_compilers - show_compilers() - - -class build_clib(Command): - - description = "build C/C++ libraries used by Python extensions" - - user_options = [ - ('build-clib=', 'b', - "directory to build C/C++ libraries to"), - ('build-temp=', 't', - "directory to put temporary build by-products"), - ('debug', 'g', - "compile with debugging information"), - ('force', 'f', - "forcibly build everything (ignore file timestamps)"), - ('compiler=', 'c', - "specify the compiler type"), - ] - - boolean_options = ['debug', 'force'] - - help_options = [ - ('help-compiler', None, - "list available compilers", show_compilers), - ] - - def initialize_options(self): - self.build_clib = None - self.build_temp = None - - # List of libraries to build - self.libraries = None - - # Compilation options for all libraries - self.include_dirs = None - self.define = None - self.undef = None - self.debug = None - self.force = 0 - self.compiler = None - - - def finalize_options(self): - # This might be confusing: both build-clib and build-temp default - # to build-temp as defined by the "build" command. This is because - # I think that C libraries are really just temporary build - # by-products, at least from the point of view of building Python - # extensions -- but I want to keep my options open. - self.set_undefined_options('build', - ('build_temp', 'build_clib'), - ('build_temp', 'build_temp'), - ('compiler', 'compiler'), - ('debug', 'debug'), - ('force', 'force')) - - self.libraries = self.distribution.libraries - if self.libraries: - self.check_library_list(self.libraries) - - if self.include_dirs is None: - self.include_dirs = self.distribution.include_dirs or [] - if isinstance(self.include_dirs, str): - self.include_dirs = self.include_dirs.split(os.pathsep) - - # XXX same as for build_ext -- what about 'self.define' and - # 'self.undef' ? - - - def run(self): - if not self.libraries: - return - - # Yech -- this is cut 'n pasted from build_ext.py! - from distutils.ccompiler import new_compiler - self.compiler = new_compiler(compiler=self.compiler, - dry_run=self.dry_run, - force=self.force) - customize_compiler(self.compiler) - - if self.include_dirs is not None: - self.compiler.set_include_dirs(self.include_dirs) - if self.define is not None: - # 'define' option is a list of (name,value) tuples - for (name,value) in self.define: - self.compiler.define_macro(name, value) - if self.undef is not None: - for macro in self.undef: - self.compiler.undefine_macro(macro) - - self.build_libraries(self.libraries) - - - def check_library_list(self, libraries): - """Ensure that the list of libraries is valid. - - `library` is presumably provided as a command option 'libraries'. - This method checks that it is a list of 2-tuples, where the tuples - are (library_name, build_info_dict). - - Raise DistutilsSetupError if the structure is invalid anywhere; - just returns otherwise. - """ - if not isinstance(libraries, list): - raise DistutilsSetupError( - "'libraries' option must be a list of tuples") - - for lib in libraries: - if not isinstance(lib, tuple) and len(lib) != 2: - raise DistutilsSetupError( - "each element of 'libraries' must a 2-tuple") - - name, build_info = lib - - if not isinstance(name, str): - raise DistutilsSetupError( - "first element of each tuple in 'libraries' " - "must be a string (the library name)") - - if '/' in name or (os.sep != '/' and os.sep in name): - raise DistutilsSetupError("bad library name '%s': " - "may not contain directory separators" % lib[0]) - - if not isinstance(build_info, dict): - raise DistutilsSetupError( - "second element of each tuple in 'libraries' " - "must be a dictionary (build info)") - - - def get_library_names(self): - # Assume the library list is valid -- 'check_library_list()' is - # called from 'finalize_options()', so it should be! - if not self.libraries: - return None - - lib_names = [] - for (lib_name, build_info) in self.libraries: - lib_names.append(lib_name) - return lib_names - - - def get_source_files(self): - self.check_library_list(self.libraries) - filenames = [] - for (lib_name, build_info) in self.libraries: - sources = build_info.get('sources') - if sources is None or not isinstance(sources, (list, tuple)): - raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " - "'sources' must be present and must be " - "a list of source filenames" % lib_name) - - filenames.extend(sources) - return filenames - - - def build_libraries(self, libraries): - for (lib_name, build_info) in libraries: - sources = build_info.get('sources') - if sources is None or not isinstance(sources, (list, tuple)): - raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " - "'sources' must be present and must be " - "a list of source filenames" % lib_name) - sources = list(sources) - - log.info("building '%s' library", lib_name) - - # First, compile the source code to object files in the library - # directory. (This should probably change to putting object - # files in a temporary build directory.) - macros = build_info.get('macros') - include_dirs = build_info.get('include_dirs') - objects = self.compiler.compile(sources, - output_dir=self.build_temp, - macros=macros, - include_dirs=include_dirs, - debug=self.debug) - - # Now "link" the object files together into a static library. - # (On Unix at least, this isn't really linking -- it just - # builds an archive. Whatever.) - self.compiler.create_static_lib(objects, lib_name, - output_dir=self.build_clib, - debug=self.debug) diff --git a/python/Lib/distutils/command/build_ext.py b/python/Lib/distutils/command/build_ext.py deleted file mode 100644 index d8c6d5a..0000000 --- a/python/Lib/distutils/command/build_ext.py +++ /dev/null @@ -1,754 +0,0 @@ -"""distutils.command.build_ext - -Implements the Distutils 'build_ext' command, for building extension -modules (currently limited to C extensions, should accommodate C++ -extensions ASAP).""" - -import contextlib -import os -import re -import sys -from distutils.core import Command -from distutils.errors import * -from distutils.sysconfig import customize_compiler, get_python_version -from distutils.sysconfig import get_config_h_filename -from distutils.dep_util import newer_group -from distutils.extension import Extension -from distutils.util import get_platform -from distutils import log - -from site import USER_BASE - -# An extension name is just a dot-separated list of Python NAMEs (ie. -# the same as a fully-qualified module name). -extension_name_re = re.compile \ - (r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$') - - -def show_compilers (): - from distutils.ccompiler import show_compilers - show_compilers() - - -class build_ext(Command): - - description = "build C/C++ extensions (compile/link to build directory)" - - # XXX thoughts on how to deal with complex command-line options like - # these, i.e. how to make it so fancy_getopt can suck them off the - # command line and make it look like setup.py defined the appropriate - # lists of tuples of what-have-you. - # - each command needs a callback to process its command-line options - # - Command.__init__() needs access to its share of the whole - # command line (must ultimately come from - # Distribution.parse_command_line()) - # - it then calls the current command class' option-parsing - # callback to deal with weird options like -D, which have to - # parse the option text and churn out some custom data - # structure - # - that data structure (in this case, a list of 2-tuples) - # will then be present in the command object by the time - # we get to finalize_options() (i.e. the constructor - # takes care of both command-line and client options - # in between initialize_options() and finalize_options()) - - sep_by = " (separated by '%s')" % os.pathsep - user_options = [ - ('build-lib=', 'b', - "directory for compiled extension modules"), - ('build-temp=', 't', - "directory for temporary files (build by-products)"), - ('plat-name=', 'p', - "platform name to cross-compile for, if supported " - "(default: %s)" % get_platform()), - ('inplace', 'i', - "ignore build-lib and put compiled extensions into the source " + - "directory alongside your pure Python modules"), - ('include-dirs=', 'I', - "list of directories to search for header files" + sep_by), - ('define=', 'D', - "C preprocessor macros to define"), - ('undef=', 'U', - "C preprocessor macros to undefine"), - ('libraries=', 'l', - "external C libraries to link with"), - ('library-dirs=', 'L', - "directories to search for external C libraries" + sep_by), - ('rpath=', 'R', - "directories to search for shared C libraries at runtime"), - ('link-objects=', 'O', - "extra explicit link objects to include in the link"), - ('debug', 'g', - "compile/link with debugging information"), - ('force', 'f', - "forcibly build everything (ignore file timestamps)"), - ('compiler=', 'c', - "specify the compiler type"), - ('parallel=', 'j', - "number of parallel build jobs"), - ('swig-cpp', None, - "make SWIG create C++ files (default is C)"), - ('swig-opts=', None, - "list of SWIG command line options"), - ('swig=', None, - "path to the SWIG executable"), - ('user', None, - "add user include, library and rpath") - ] - - boolean_options = ['inplace', 'debug', 'force', 'swig-cpp', 'user'] - - help_options = [ - ('help-compiler', None, - "list available compilers", show_compilers), - ] - - def initialize_options(self): - self.extensions = None - self.build_lib = None - self.plat_name = None - self.build_temp = None - self.inplace = 0 - self.package = None - - self.include_dirs = None - self.define = None - self.undef = None - self.libraries = None - self.library_dirs = None - self.rpath = None - self.link_objects = None - self.debug = None - self.force = None - self.compiler = None - self.swig = None - self.swig_cpp = None - self.swig_opts = None - self.user = None - self.parallel = None - - def finalize_options(self): - from distutils import sysconfig - - self.set_undefined_options('build', - ('build_lib', 'build_lib'), - ('build_temp', 'build_temp'), - ('compiler', 'compiler'), - ('debug', 'debug'), - ('force', 'force'), - ('parallel', 'parallel'), - ('plat_name', 'plat_name'), - ) - - if self.package is None: - self.package = self.distribution.ext_package - - self.extensions = self.distribution.ext_modules - - # Make sure Python's include directories (for Python.h, pyconfig.h, - # etc.) are in the include search path. - py_include = sysconfig.get_python_inc() - plat_py_include = sysconfig.get_python_inc(plat_specific=1) - if self.include_dirs is None: - self.include_dirs = self.distribution.include_dirs or [] - if isinstance(self.include_dirs, str): - self.include_dirs = self.include_dirs.split(os.pathsep) - - # If in a virtualenv, add its include directory - # Issue 16116 - if sys.exec_prefix != sys.base_exec_prefix: - self.include_dirs.append(os.path.join(sys.exec_prefix, 'include')) - - # Put the Python "system" include dir at the end, so that - # any local include dirs take precedence. - self.include_dirs.extend(py_include.split(os.path.pathsep)) - if plat_py_include != py_include: - self.include_dirs.extend( - plat_py_include.split(os.path.pathsep)) - - self.ensure_string_list('libraries') - self.ensure_string_list('link_objects') - - # Life is easier if we're not forever checking for None, so - # simplify these options to empty lists if unset - if self.libraries is None: - self.libraries = [] - if self.library_dirs is None: - self.library_dirs = [] - elif isinstance(self.library_dirs, str): - self.library_dirs = self.library_dirs.split(os.pathsep) - - if self.rpath is None: - self.rpath = [] - elif isinstance(self.rpath, str): - self.rpath = self.rpath.split(os.pathsep) - - # for extensions under windows use different directories - # for Release and Debug builds. - # also Python's library directory must be appended to library_dirs - if os.name == 'nt': - # the 'libs' directory is for binary installs - we assume that - # must be the *native* platform. But we don't really support - # cross-compiling via a binary install anyway, so we let it go. - self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs')) - if sys.base_exec_prefix != sys.prefix: # Issue 16116 - self.library_dirs.append(os.path.join(sys.base_exec_prefix, 'libs')) - if self.debug: - self.build_temp = os.path.join(self.build_temp, "Debug") - else: - self.build_temp = os.path.join(self.build_temp, "Release") - - # Append the source distribution include and library directories, - # this allows distutils on windows to work in the source tree - self.include_dirs.append(os.path.dirname(get_config_h_filename())) - _sys_home = getattr(sys, '_home', None) - if _sys_home: - self.library_dirs.append(_sys_home) - - # Use the .lib files for the correct architecture - if self.plat_name == 'win32': - suffix = 'win32' - else: - # win-amd64 - suffix = self.plat_name[4:] - new_lib = os.path.join(sys.exec_prefix, 'PCbuild') - if suffix: - new_lib = os.path.join(new_lib, suffix) - self.library_dirs.append(new_lib) - - # For extensions under Cygwin, Python's library directory must be - # appended to library_dirs - if sys.platform[:6] == 'cygwin': - if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): - # building third party extensions - self.library_dirs.append(os.path.join(sys.prefix, "lib", - "python" + get_python_version(), - "config")) - else: - # building python standard extensions - self.library_dirs.append('.') - - # For building extensions with a shared Python library, - # Python's library directory must be appended to library_dirs - # See Issues: #1600860, #4366 - if (sysconfig.get_config_var('Py_ENABLE_SHARED')): - if not sysconfig.python_build: - # building third party extensions - self.library_dirs.append(sysconfig.get_config_var('LIBDIR')) - else: - # building python standard extensions - self.library_dirs.append('.') - - # The argument parsing will result in self.define being a string, but - # it has to be a list of 2-tuples. All the preprocessor symbols - # specified by the 'define' option will be set to '1'. Multiple - # symbols can be separated with commas. - - if self.define: - defines = self.define.split(',') - self.define = [(symbol, '1') for symbol in defines] - - # The option for macros to undefine is also a string from the - # option parsing, but has to be a list. Multiple symbols can also - # be separated with commas here. - if self.undef: - self.undef = self.undef.split(',') - - if self.swig_opts is None: - self.swig_opts = [] - else: - self.swig_opts = self.swig_opts.split(' ') - - # Finally add the user include and library directories if requested - if self.user: - user_include = os.path.join(USER_BASE, "include") - user_lib = os.path.join(USER_BASE, "lib") - if os.path.isdir(user_include): - self.include_dirs.append(user_include) - if os.path.isdir(user_lib): - self.library_dirs.append(user_lib) - self.rpath.append(user_lib) - - if isinstance(self.parallel, str): - try: - self.parallel = int(self.parallel) - except ValueError: - raise DistutilsOptionError("parallel should be an integer") - - def run(self): - from distutils.ccompiler import new_compiler - - # 'self.extensions', as supplied by setup.py, is a list of - # Extension instances. See the documentation for Extension (in - # distutils.extension) for details. - # - # For backwards compatibility with Distutils 0.8.2 and earlier, we - # also allow the 'extensions' list to be a list of tuples: - # (ext_name, build_info) - # where build_info is a dictionary containing everything that - # Extension instances do except the name, with a few things being - # differently named. We convert these 2-tuples to Extension - # instances as needed. - - if not self.extensions: - return - - # If we were asked to build any C/C++ libraries, make sure that the - # directory where we put them is in the library search path for - # linking extensions. - if self.distribution.has_c_libraries(): - build_clib = self.get_finalized_command('build_clib') - self.libraries.extend(build_clib.get_library_names() or []) - self.library_dirs.append(build_clib.build_clib) - - # Setup the CCompiler object that we'll use to do all the - # compiling and linking - self.compiler = new_compiler(compiler=self.compiler, - verbose=self.verbose, - dry_run=self.dry_run, - force=self.force) - customize_compiler(self.compiler) - # If we are cross-compiling, init the compiler now (if we are not - # cross-compiling, init would not hurt, but people may rely on - # late initialization of compiler even if they shouldn't...) - if os.name == 'nt' and self.plat_name != get_platform(): - self.compiler.initialize(self.plat_name) - - # And make sure that any compile/link-related options (which might - # come from the command-line or from the setup script) are set in - # that CCompiler object -- that way, they automatically apply to - # all compiling and linking done here. - if self.include_dirs is not None: - self.compiler.set_include_dirs(self.include_dirs) - if self.define is not None: - # 'define' option is a list of (name,value) tuples - for (name, value) in self.define: - self.compiler.define_macro(name, value) - if self.undef is not None: - for macro in self.undef: - self.compiler.undefine_macro(macro) - if self.libraries is not None: - self.compiler.set_libraries(self.libraries) - if self.library_dirs is not None: - self.compiler.set_library_dirs(self.library_dirs) - if self.rpath is not None: - self.compiler.set_runtime_library_dirs(self.rpath) - if self.link_objects is not None: - self.compiler.set_link_objects(self.link_objects) - - # Now actually compile and link everything. - self.build_extensions() - - def check_extensions_list(self, extensions): - """Ensure that the list of extensions (presumably provided as a - command option 'extensions') is valid, i.e. it is a list of - Extension objects. We also support the old-style list of 2-tuples, - where the tuples are (ext_name, build_info), which are converted to - Extension instances here. - - Raise DistutilsSetupError if the structure is invalid anywhere; - just returns otherwise. - """ - if not isinstance(extensions, list): - raise DistutilsSetupError( - "'ext_modules' option must be a list of Extension instances") - - for i, ext in enumerate(extensions): - if isinstance(ext, Extension): - continue # OK! (assume type-checking done - # by Extension constructor) - - if not isinstance(ext, tuple) or len(ext) != 2: - raise DistutilsSetupError( - "each element of 'ext_modules' option must be an " - "Extension instance or 2-tuple") - - ext_name, build_info = ext - - log.warn("old-style (ext_name, build_info) tuple found in " - "ext_modules for extension '%s' " - "-- please convert to Extension instance", ext_name) - - if not (isinstance(ext_name, str) and - extension_name_re.match(ext_name)): - raise DistutilsSetupError( - "first element of each tuple in 'ext_modules' " - "must be the extension name (a string)") - - if not isinstance(build_info, dict): - raise DistutilsSetupError( - "second element of each tuple in 'ext_modules' " - "must be a dictionary (build info)") - - # OK, the (ext_name, build_info) dict is type-safe: convert it - # to an Extension instance. - ext = Extension(ext_name, build_info['sources']) - - # Easy stuff: one-to-one mapping from dict elements to - # instance attributes. - for key in ('include_dirs', 'library_dirs', 'libraries', - 'extra_objects', 'extra_compile_args', - 'extra_link_args'): - val = build_info.get(key) - if val is not None: - setattr(ext, key, val) - - # Medium-easy stuff: same syntax/semantics, different names. - ext.runtime_library_dirs = build_info.get('rpath') - if 'def_file' in build_info: - log.warn("'def_file' element of build info dict " - "no longer supported") - - # Non-trivial stuff: 'macros' split into 'define_macros' - # and 'undef_macros'. - macros = build_info.get('macros') - if macros: - ext.define_macros = [] - ext.undef_macros = [] - for macro in macros: - if not (isinstance(macro, tuple) and len(macro) in (1, 2)): - raise DistutilsSetupError( - "'macros' element of build info dict " - "must be 1- or 2-tuple") - if len(macro) == 1: - ext.undef_macros.append(macro[0]) - elif len(macro) == 2: - ext.define_macros.append(macro) - - extensions[i] = ext - - def get_source_files(self): - self.check_extensions_list(self.extensions) - filenames = [] - - # Wouldn't it be neat if we knew the names of header files too... - for ext in self.extensions: - filenames.extend(ext.sources) - return filenames - - def get_outputs(self): - # Sanity check the 'extensions' list -- can't assume this is being - # done in the same run as a 'build_extensions()' call (in fact, we - # can probably assume that it *isn't*!). - self.check_extensions_list(self.extensions) - - # And build the list of output (built) filenames. Note that this - # ignores the 'inplace' flag, and assumes everything goes in the - # "build" tree. - outputs = [] - for ext in self.extensions: - outputs.append(self.get_ext_fullpath(ext.name)) - return outputs - - def build_extensions(self): - # First, sanity-check the 'extensions' list - self.check_extensions_list(self.extensions) - if self.parallel: - self._build_extensions_parallel() - else: - self._build_extensions_serial() - - def _build_extensions_parallel(self): - workers = self.parallel - if self.parallel is True: - workers = os.cpu_count() # may return None - try: - from concurrent.futures import ThreadPoolExecutor - except ImportError: - workers = None - - if workers is None: - self._build_extensions_serial() - return - - with ThreadPoolExecutor(max_workers=workers) as executor: - futures = [executor.submit(self.build_extension, ext) - for ext in self.extensions] - for ext, fut in zip(self.extensions, futures): - with self._filter_build_errors(ext): - fut.result() - - def _build_extensions_serial(self): - for ext in self.extensions: - with self._filter_build_errors(ext): - self.build_extension(ext) - - @contextlib.contextmanager - def _filter_build_errors(self, ext): - try: - yield - except (CCompilerError, DistutilsError, CompileError) as e: - if not ext.optional: - raise - self.warn('building extension "%s" failed: %s' % - (ext.name, e)) - - def build_extension(self, ext): - sources = ext.sources - if sources is None or not isinstance(sources, (list, tuple)): - raise DistutilsSetupError( - "in 'ext_modules' option (extension '%s'), " - "'sources' must be present and must be " - "a list of source filenames" % ext.name) - # sort to make the resulting .so file build reproducible - sources = sorted(sources) - - ext_path = self.get_ext_fullpath(ext.name) - depends = sources + ext.depends - if not (self.force or newer_group(depends, ext_path, 'newer')): - log.debug("skipping '%s' extension (up-to-date)", ext.name) - return - else: - log.info("building '%s' extension", ext.name) - - # First, scan the sources for SWIG definition files (.i), run - # SWIG on 'em to create .c files, and modify the sources list - # accordingly. - sources = self.swig_sources(sources, ext) - - # Next, compile the source code to object files. - - # XXX not honouring 'define_macros' or 'undef_macros' -- the - # CCompiler API needs to change to accommodate this, and I - # want to do one thing at a time! - - # Two possible sources for extra compiler arguments: - # - 'extra_compile_args' in Extension object - # - CFLAGS environment variable (not particularly - # elegant, but people seem to expect it and I - # guess it's useful) - # The environment variable should take precedence, and - # any sensible compiler will give precedence to later - # command line args. Hence we combine them in order: - extra_args = ext.extra_compile_args or [] - - macros = ext.define_macros[:] - for undef in ext.undef_macros: - macros.append((undef,)) - - objects = self.compiler.compile(sources, - output_dir=self.build_temp, - macros=macros, - include_dirs=ext.include_dirs, - debug=self.debug, - extra_postargs=extra_args, - depends=ext.depends) - - # XXX outdated variable, kept here in case third-part code - # needs it. - self._built_objects = objects[:] - - # Now link the object files together into a "shared object" -- - # of course, first we have to figure out all the other things - # that go into the mix. - if ext.extra_objects: - objects.extend(ext.extra_objects) - extra_args = ext.extra_link_args or [] - - # Detect target language, if not provided - language = ext.language or self.compiler.detect_language(sources) - - self.compiler.link_shared_object( - objects, ext_path, - libraries=self.get_libraries(ext), - library_dirs=ext.library_dirs, - runtime_library_dirs=ext.runtime_library_dirs, - extra_postargs=extra_args, - export_symbols=self.get_export_symbols(ext), - debug=self.debug, - build_temp=self.build_temp, - target_lang=language) - - def swig_sources(self, sources, extension): - """Walk the list of source files in 'sources', looking for SWIG - interface (.i) files. Run SWIG on all that are found, and - return a modified 'sources' list with SWIG source files replaced - by the generated C (or C++) files. - """ - new_sources = [] - swig_sources = [] - swig_targets = {} - - # XXX this drops generated C/C++ files into the source tree, which - # is fine for developers who want to distribute the generated - # source -- but there should be an option to put SWIG output in - # the temp dir. - - if self.swig_cpp: - log.warn("--swig-cpp is deprecated - use --swig-opts=-c++") - - if self.swig_cpp or ('-c++' in self.swig_opts) or \ - ('-c++' in extension.swig_opts): - target_ext = '.cpp' - else: - target_ext = '.c' - - for source in sources: - (base, ext) = os.path.splitext(source) - if ext == ".i": # SWIG interface file - new_sources.append(base + '_wrap' + target_ext) - swig_sources.append(source) - swig_targets[source] = new_sources[-1] - else: - new_sources.append(source) - - if not swig_sources: - return new_sources - - swig = self.swig or self.find_swig() - swig_cmd = [swig, "-python"] - swig_cmd.extend(self.swig_opts) - if self.swig_cpp: - swig_cmd.append("-c++") - - # Do not override commandline arguments - if not self.swig_opts: - for o in extension.swig_opts: - swig_cmd.append(o) - - for source in swig_sources: - target = swig_targets[source] - log.info("swigging %s to %s", source, target) - self.spawn(swig_cmd + ["-o", target, source]) - - return new_sources - - def find_swig(self): - """Return the name of the SWIG executable. On Unix, this is - just "swig" -- it should be in the PATH. Tries a bit harder on - Windows. - """ - if os.name == "posix": - return "swig" - elif os.name == "nt": - # Look for SWIG in its standard installation directory on - # Windows (or so I presume!). If we find it there, great; - # if not, act like Unix and assume it's in the PATH. - for vers in ("1.3", "1.2", "1.1"): - fn = os.path.join("c:\\swig%s" % vers, "swig.exe") - if os.path.isfile(fn): - return fn - else: - return "swig.exe" - else: - raise DistutilsPlatformError( - "I don't know how to find (much less run) SWIG " - "on platform '%s'" % os.name) - - # -- Name generators ----------------------------------------------- - # (extension names, filenames, whatever) - def get_ext_fullpath(self, ext_name): - """Returns the path of the filename for a given extension. - - The file is located in `build_lib` or directly in the package - (inplace option). - """ - fullname = self.get_ext_fullname(ext_name) - modpath = fullname.split('.') - filename = self.get_ext_filename(modpath[-1]) - - if not self.inplace: - # no further work needed - # returning : - # build_dir/package/path/filename - filename = os.path.join(*modpath[:-1]+[filename]) - return os.path.join(self.build_lib, filename) - - # the inplace option requires to find the package directory - # using the build_py command for that - package = '.'.join(modpath[0:-1]) - build_py = self.get_finalized_command('build_py') - package_dir = os.path.abspath(build_py.get_package_dir(package)) - - # returning - # package_dir/filename - return os.path.join(package_dir, filename) - - def get_ext_fullname(self, ext_name): - """Returns the fullname of a given extension name. - - Adds the `package.` prefix""" - if self.package is None: - return ext_name - else: - return self.package + '.' + ext_name - - def get_ext_filename(self, ext_name): - r"""Convert the name of an extension (eg. "foo.bar") into the name - of the file from which it will be loaded (eg. "foo/bar.so", or - "foo\bar.pyd"). - """ - from distutils.sysconfig import get_config_var - ext_path = ext_name.split('.') - ext_suffix = get_config_var('EXT_SUFFIX') - return os.path.join(*ext_path) + ext_suffix - - def get_export_symbols(self, ext): - """Return the list of symbols that a shared extension has to - export. This either uses 'ext.export_symbols' or, if it's not - provided, "PyInit_" + module_name. Only relevant on Windows, where - the .pyd file (DLL) must export the module "PyInit_" function. - """ - suffix = '_' + ext.name.split('.')[-1] - try: - # Unicode module name support as defined in PEP-489 - # https://peps.python.org/pep-0489/#export-hook-name - suffix.encode('ascii') - except UnicodeEncodeError: - suffix = 'U' + suffix.encode('punycode').replace(b'-', b'_').decode('ascii') - - initfunc_name = "PyInit" + suffix - if initfunc_name not in ext.export_symbols: - ext.export_symbols.append(initfunc_name) - return ext.export_symbols - - def get_libraries(self, ext): - """Return the list of libraries to link against when building a - shared extension. On most platforms, this is just 'ext.libraries'; - on Windows, we add the Python library (eg. python20.dll). - """ - # The python library is always needed on Windows. For MSVC, this - # is redundant, since the library is mentioned in a pragma in - # pyconfig.h that MSVC groks. The other Windows compilers all seem - # to need it mentioned explicitly, though, so that's what we do. - # Append '_d' to the python import library on debug builds. - if sys.platform == "win32": - from distutils._msvccompiler import MSVCCompiler - if not isinstance(self.compiler, MSVCCompiler): - template = "python%d%d" - if self.debug: - template = template + '_d' - pythonlib = (template % - (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) - # don't extend ext.libraries, it may be shared with other - # extensions, it is a reference to the original list - return ext.libraries + [pythonlib] - else: - # On Android only the main executable and LD_PRELOADs are considered - # to be RTLD_GLOBAL, all the dependencies of the main executable - # remain RTLD_LOCAL and so the shared libraries must be linked with - # libpython when python is built with a shared python library (issue - # bpo-21536). - # On Cygwin (and if required, other POSIX-like platforms based on - # Windows like MinGW) it is simply necessary that all symbols in - # shared libraries are resolved at link time. - from distutils.sysconfig import get_config_var - link_libpython = False - if get_config_var('Py_ENABLE_SHARED'): - # A native build on an Android device or on Cygwin - if hasattr(sys, 'getandroidapilevel'): - link_libpython = True - elif sys.platform == 'cygwin': - link_libpython = True - elif '_PYTHON_HOST_PLATFORM' in os.environ: - # We are cross-compiling for one of the relevant platforms - if get_config_var('ANDROID_API_LEVEL') != 0: - link_libpython = True - elif get_config_var('MACHDEP') == 'cygwin': - link_libpython = True - - if link_libpython: - ldversion = get_config_var('LDVERSION') - return ext.libraries + ['python' + ldversion] - - return ext.libraries diff --git a/python/Lib/distutils/command/build_py.py b/python/Lib/distutils/command/build_py.py deleted file mode 100644 index dc05c58..0000000 --- a/python/Lib/distutils/command/build_py.py +++ /dev/null @@ -1,416 +0,0 @@ -"""distutils.command.build_py - -Implements the Distutils 'build_py' command.""" - -import os -import importlib.util -import sys -import glob - -from distutils.core import Command -from distutils.errors import * -from distutils.util import convert_path, Mixin2to3 -from distutils import log - -class build_py (Command): - - description = "\"build\" pure Python modules (copy to build directory)" - - user_options = [ - ('build-lib=', 'd', "directory to \"build\" (copy) to"), - ('compile', 'c', "compile .py to .pyc"), - ('no-compile', None, "don't compile .py files [default]"), - ('optimize=', 'O', - "also compile with optimization: -O1 for \"python -O\", " - "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), - ('force', 'f', "forcibly build everything (ignore file timestamps)"), - ] - - boolean_options = ['compile', 'force'] - negative_opt = {'no-compile' : 'compile'} - - def initialize_options(self): - self.build_lib = None - self.py_modules = None - self.package = None - self.package_data = None - self.package_dir = None - self.compile = 0 - self.optimize = 0 - self.force = None - - def finalize_options(self): - self.set_undefined_options('build', - ('build_lib', 'build_lib'), - ('force', 'force')) - - # Get the distribution options that are aliases for build_py - # options -- list of packages and list of modules. - self.packages = self.distribution.packages - self.py_modules = self.distribution.py_modules - self.package_data = self.distribution.package_data - self.package_dir = {} - if self.distribution.package_dir: - for name, path in self.distribution.package_dir.items(): - self.package_dir[name] = convert_path(path) - self.data_files = self.get_data_files() - - # Ick, copied straight from install_lib.py (fancy_getopt needs a - # type system! Hell, *everything* needs a type system!!!) - if not isinstance(self.optimize, int): - try: - self.optimize = int(self.optimize) - assert 0 <= self.optimize <= 2 - except (ValueError, AssertionError): - raise DistutilsOptionError("optimize must be 0, 1, or 2") - - def run(self): - # XXX copy_file by default preserves atime and mtime. IMHO this is - # the right thing to do, but perhaps it should be an option -- in - # particular, a site administrator might want installed files to - # reflect the time of installation rather than the last - # modification time before the installed release. - - # XXX copy_file by default preserves mode, which appears to be the - # wrong thing to do: if a file is read-only in the working - # directory, we want it to be installed read/write so that the next - # installation of the same module distribution can overwrite it - # without problems. (This might be a Unix-specific issue.) Thus - # we turn off 'preserve_mode' when copying to the build directory, - # since the build directory is supposed to be exactly what the - # installation will look like (ie. we preserve mode when - # installing). - - # Two options control which modules will be installed: 'packages' - # and 'py_modules'. The former lets us work with whole packages, not - # specifying individual modules at all; the latter is for - # specifying modules one-at-a-time. - - if self.py_modules: - self.build_modules() - if self.packages: - self.build_packages() - self.build_package_data() - - self.byte_compile(self.get_outputs(include_bytecode=0)) - - def get_data_files(self): - """Generate list of '(package,src_dir,build_dir,filenames)' tuples""" - data = [] - if not self.packages: - return data - for package in self.packages: - # Locate package source directory - src_dir = self.get_package_dir(package) - - # Compute package build directory - build_dir = os.path.join(*([self.build_lib] + package.split('.'))) - - # Length of path to strip from found files - plen = 0 - if src_dir: - plen = len(src_dir)+1 - - # Strip directory from globbed filenames - filenames = [ - file[plen:] for file in self.find_data_files(package, src_dir) - ] - data.append((package, src_dir, build_dir, filenames)) - return data - - def find_data_files(self, package, src_dir): - """Return filenames for package's data files in 'src_dir'""" - globs = (self.package_data.get('', []) - + self.package_data.get(package, [])) - files = [] - for pattern in globs: - # Each pattern has to be converted to a platform-specific path - filelist = glob.glob(os.path.join(glob.escape(src_dir), convert_path(pattern))) - # Files that match more than one pattern are only added once - files.extend([fn for fn in filelist if fn not in files - and os.path.isfile(fn)]) - return files - - def build_package_data(self): - """Copy data files into build directory""" - lastdir = None - for package, src_dir, build_dir, filenames in self.data_files: - for filename in filenames: - target = os.path.join(build_dir, filename) - self.mkpath(os.path.dirname(target)) - self.copy_file(os.path.join(src_dir, filename), target, - preserve_mode=False) - - def get_package_dir(self, package): - """Return the directory, relative to the top of the source - distribution, where package 'package' should be found - (at least according to the 'package_dir' option, if any).""" - path = package.split('.') - - if not self.package_dir: - if path: - return os.path.join(*path) - else: - return '' - else: - tail = [] - while path: - try: - pdir = self.package_dir['.'.join(path)] - except KeyError: - tail.insert(0, path[-1]) - del path[-1] - else: - tail.insert(0, pdir) - return os.path.join(*tail) - else: - # Oops, got all the way through 'path' without finding a - # match in package_dir. If package_dir defines a directory - # for the root (nameless) package, then fallback on it; - # otherwise, we might as well have not consulted - # package_dir at all, as we just use the directory implied - # by 'tail' (which should be the same as the original value - # of 'path' at this point). - pdir = self.package_dir.get('') - if pdir is not None: - tail.insert(0, pdir) - - if tail: - return os.path.join(*tail) - else: - return '' - - def check_package(self, package, package_dir): - # Empty dir name means current directory, which we can probably - # assume exists. Also, os.path.exists and isdir don't know about - # my "empty string means current dir" convention, so we have to - # circumvent them. - if package_dir != "": - if not os.path.exists(package_dir): - raise DistutilsFileError( - "package directory '%s' does not exist" % package_dir) - if not os.path.isdir(package_dir): - raise DistutilsFileError( - "supposed package directory '%s' exists, " - "but is not a directory" % package_dir) - - # Require __init__.py for all but the "root package" - if package: - init_py = os.path.join(package_dir, "__init__.py") - if os.path.isfile(init_py): - return init_py - else: - log.warn(("package init file '%s' not found " + - "(or not a regular file)"), init_py) - - # Either not in a package at all (__init__.py not expected), or - # __init__.py doesn't exist -- so don't return the filename. - return None - - def check_module(self, module, module_file): - if not os.path.isfile(module_file): - log.warn("file %s (for module %s) not found", module_file, module) - return False - else: - return True - - def find_package_modules(self, package, package_dir): - self.check_package(package, package_dir) - module_files = glob.glob(os.path.join(glob.escape(package_dir), "*.py")) - modules = [] - setup_script = os.path.abspath(self.distribution.script_name) - - for f in module_files: - abs_f = os.path.abspath(f) - if abs_f != setup_script: - module = os.path.splitext(os.path.basename(f))[0] - modules.append((package, module, f)) - else: - self.debug_print("excluding %s" % setup_script) - return modules - - def find_modules(self): - """Finds individually-specified Python modules, ie. those listed by - module name in 'self.py_modules'. Returns a list of tuples (package, - module_base, filename): 'package' is a tuple of the path through - package-space to the module; 'module_base' is the bare (no - packages, no dots) module name, and 'filename' is the path to the - ".py" file (relative to the distribution root) that implements the - module. - """ - # Map package names to tuples of useful info about the package: - # (package_dir, checked) - # package_dir - the directory where we'll find source files for - # this package - # checked - true if we have checked that the package directory - # is valid (exists, contains __init__.py, ... ?) - packages = {} - - # List of (package, module, filename) tuples to return - modules = [] - - # We treat modules-in-packages almost the same as toplevel modules, - # just the "package" for a toplevel is empty (either an empty - # string or empty list, depending on context). Differences: - # - don't check for __init__.py in directory for empty package - for module in self.py_modules: - path = module.split('.') - package = '.'.join(path[0:-1]) - module_base = path[-1] - - try: - (package_dir, checked) = packages[package] - except KeyError: - package_dir = self.get_package_dir(package) - checked = 0 - - if not checked: - init_py = self.check_package(package, package_dir) - packages[package] = (package_dir, 1) - if init_py: - modules.append((package, "__init__", init_py)) - - # XXX perhaps we should also check for just .pyc files - # (so greedy closed-source bastards can distribute Python - # modules too) - module_file = os.path.join(package_dir, module_base + ".py") - if not self.check_module(module, module_file): - continue - - modules.append((package, module_base, module_file)) - - return modules - - def find_all_modules(self): - """Compute the list of all modules that will be built, whether - they are specified one-module-at-a-time ('self.py_modules') or - by whole packages ('self.packages'). Return a list of tuples - (package, module, module_file), just like 'find_modules()' and - 'find_package_modules()' do.""" - modules = [] - if self.py_modules: - modules.extend(self.find_modules()) - if self.packages: - for package in self.packages: - package_dir = self.get_package_dir(package) - m = self.find_package_modules(package, package_dir) - modules.extend(m) - return modules - - def get_source_files(self): - return [module[-1] for module in self.find_all_modules()] - - def get_module_outfile(self, build_dir, package, module): - outfile_path = [build_dir] + list(package) + [module + ".py"] - return os.path.join(*outfile_path) - - def get_outputs(self, include_bytecode=1): - modules = self.find_all_modules() - outputs = [] - for (package, module, module_file) in modules: - package = package.split('.') - filename = self.get_module_outfile(self.build_lib, package, module) - outputs.append(filename) - if include_bytecode: - if self.compile: - outputs.append(importlib.util.cache_from_source( - filename, optimization='')) - if self.optimize > 0: - outputs.append(importlib.util.cache_from_source( - filename, optimization=self.optimize)) - - outputs += [ - os.path.join(build_dir, filename) - for package, src_dir, build_dir, filenames in self.data_files - for filename in filenames - ] - - return outputs - - def build_module(self, module, module_file, package): - if isinstance(package, str): - package = package.split('.') - elif not isinstance(package, (list, tuple)): - raise TypeError( - "'package' must be a string (dot-separated), list, or tuple") - - # Now put the module source file into the "build" area -- this is - # easy, we just copy it somewhere under self.build_lib (the build - # directory for Python source). - outfile = self.get_module_outfile(self.build_lib, package, module) - dir = os.path.dirname(outfile) - self.mkpath(dir) - return self.copy_file(module_file, outfile, preserve_mode=0) - - def build_modules(self): - modules = self.find_modules() - for (package, module, module_file) in modules: - # Now "build" the module -- ie. copy the source file to - # self.build_lib (the build directory for Python source). - # (Actually, it gets copied to the directory for this package - # under self.build_lib.) - self.build_module(module, module_file, package) - - def build_packages(self): - for package in self.packages: - # Get list of (package, module, module_file) tuples based on - # scanning the package directory. 'package' is only included - # in the tuple so that 'find_modules()' and - # 'find_package_tuples()' have a consistent interface; it's - # ignored here (apart from a sanity check). Also, 'module' is - # the *unqualified* module name (ie. no dots, no package -- we - # already know its package!), and 'module_file' is the path to - # the .py file, relative to the current directory - # (ie. including 'package_dir'). - package_dir = self.get_package_dir(package) - modules = self.find_package_modules(package, package_dir) - - # Now loop over the modules we found, "building" each one (just - # copy it to self.build_lib). - for (package_, module, module_file) in modules: - assert package == package_ - self.build_module(module, module_file, package) - - def byte_compile(self, files): - if sys.dont_write_bytecode: - self.warn('byte-compiling is disabled, skipping.') - return - - from distutils.util import byte_compile - prefix = self.build_lib - if prefix[-1] != os.sep: - prefix = prefix + os.sep - - # XXX this code is essentially the same as the 'byte_compile() - # method of the "install_lib" command, except for the determination - # of the 'prefix' string. Hmmm. - if self.compile: - byte_compile(files, optimize=0, - force=self.force, prefix=prefix, dry_run=self.dry_run) - if self.optimize > 0: - byte_compile(files, optimize=self.optimize, - force=self.force, prefix=prefix, dry_run=self.dry_run) - -class build_py_2to3(build_py, Mixin2to3): - def run(self): - self.updated_files = [] - - # Base class code - if self.py_modules: - self.build_modules() - if self.packages: - self.build_packages() - self.build_package_data() - - # 2to3 - self.run_2to3(self.updated_files) - - # Remaining base class code - self.byte_compile(self.get_outputs(include_bytecode=0)) - - def build_module(self, module, module_file, package): - res = build_py.build_module(self, module, module_file, package) - if res[1]: - # file was copied - self.updated_files.append(res[0]) - return res diff --git a/python/Lib/distutils/command/build_scripts.py b/python/Lib/distutils/command/build_scripts.py deleted file mode 100644 index 119f152..0000000 --- a/python/Lib/distutils/command/build_scripts.py +++ /dev/null @@ -1,160 +0,0 @@ -"""distutils.command.build_scripts - -Implements the Distutils 'build_scripts' command.""" - -import os, re -from stat import ST_MODE -from distutils import sysconfig -from distutils.core import Command -from distutils.dep_util import newer -from distutils.util import convert_path, Mixin2to3 -from distutils import log -import tokenize - -# check if Python is called on the first line with this expression -first_line_re = re.compile(b'^#!.*python[0-9.]*([ \t].*)?$') - -class build_scripts(Command): - - description = "\"build\" scripts (copy and fixup #! line)" - - user_options = [ - ('build-dir=', 'd', "directory to \"build\" (copy) to"), - ('force', 'f', "forcibly build everything (ignore file timestamps"), - ('executable=', 'e', "specify final destination interpreter path"), - ] - - boolean_options = ['force'] - - - def initialize_options(self): - self.build_dir = None - self.scripts = None - self.force = None - self.executable = None - self.outfiles = None - - def finalize_options(self): - self.set_undefined_options('build', - ('build_scripts', 'build_dir'), - ('force', 'force'), - ('executable', 'executable')) - self.scripts = self.distribution.scripts - - def get_source_files(self): - return self.scripts - - def run(self): - if not self.scripts: - return - self.copy_scripts() - - - def copy_scripts(self): - r"""Copy each script listed in 'self.scripts'; if it's marked as a - Python script in the Unix way (first line matches 'first_line_re', - ie. starts with "\#!" and contains "python"), then adjust the first - line to refer to the current Python interpreter as we copy. - """ - self.mkpath(self.build_dir) - outfiles = [] - updated_files = [] - for script in self.scripts: - adjust = False - script = convert_path(script) - outfile = os.path.join(self.build_dir, os.path.basename(script)) - outfiles.append(outfile) - - if not self.force and not newer(script, outfile): - log.debug("not copying %s (up-to-date)", script) - continue - - # Always open the file, but ignore failures in dry-run mode -- - # that way, we'll get accurate feedback if we can read the - # script. - try: - f = open(script, "rb") - except OSError: - if not self.dry_run: - raise - f = None - else: - encoding, lines = tokenize.detect_encoding(f.readline) - f.seek(0) - first_line = f.readline() - if not first_line: - self.warn("%s is an empty file (skipping)" % script) - continue - - match = first_line_re.match(first_line) - if match: - adjust = True - post_interp = match.group(1) or b'' - - if adjust: - log.info("copying and adjusting %s -> %s", script, - self.build_dir) - updated_files.append(outfile) - if not self.dry_run: - if not sysconfig.python_build: - executable = self.executable - else: - executable = os.path.join( - sysconfig.get_config_var("BINDIR"), - "python%s%s" % (sysconfig.get_config_var("VERSION"), - sysconfig.get_config_var("EXE"))) - executable = os.fsencode(executable) - shebang = b"#!" + executable + post_interp + b"\n" - # Python parser starts to read a script using UTF-8 until - # it gets a #coding:xxx cookie. The shebang has to be the - # first line of a file, the #coding:xxx cookie cannot be - # written before. So the shebang has to be decodable from - # UTF-8. - try: - shebang.decode('utf-8') - except UnicodeDecodeError: - raise ValueError( - "The shebang ({!r}) is not decodable " - "from utf-8".format(shebang)) - # If the script is encoded to a custom encoding (use a - # #coding:xxx cookie), the shebang has to be decodable from - # the script encoding too. - try: - shebang.decode(encoding) - except UnicodeDecodeError: - raise ValueError( - "The shebang ({!r}) is not decodable " - "from the script encoding ({})" - .format(shebang, encoding)) - with open(outfile, "wb") as outf: - outf.write(shebang) - outf.writelines(f.readlines()) - if f: - f.close() - else: - if f: - f.close() - updated_files.append(outfile) - self.copy_file(script, outfile) - - if os.name == 'posix': - for file in outfiles: - if self.dry_run: - log.info("changing mode of %s", file) - else: - oldmode = os.stat(file)[ST_MODE] & 0o7777 - newmode = (oldmode | 0o555) & 0o7777 - if newmode != oldmode: - log.info("changing mode of %s from %o to %o", - file, oldmode, newmode) - os.chmod(file, newmode) - # XXX should we modify self.outfiles? - return outfiles, updated_files - -class build_scripts_2to3(build_scripts, Mixin2to3): - - def copy_scripts(self): - outfiles, updated_files = build_scripts.copy_scripts(self) - if not self.dry_run: - self.run_2to3(updated_files) - return outfiles, updated_files diff --git a/python/Lib/distutils/command/check.py b/python/Lib/distutils/command/check.py deleted file mode 100644 index 49b0d4a..0000000 --- a/python/Lib/distutils/command/check.py +++ /dev/null @@ -1,148 +0,0 @@ -"""distutils.command.check - -Implements the Distutils 'check' command. -""" -from distutils.core import Command -from distutils.errors import DistutilsSetupError - -try: - # docutils is installed - from docutils.utils import Reporter - from docutils.parsers.rst import Parser - from docutils import frontend - from docutils import nodes - - class SilentReporter(Reporter): - - def __init__(self, source, report_level, halt_level, stream=None, - debug=0, encoding='ascii', error_handler='replace'): - self.messages = [] - Reporter.__init__(self, source, report_level, halt_level, stream, - debug, encoding, error_handler) - - def system_message(self, level, message, *children, **kwargs): - self.messages.append((level, message, children, kwargs)) - return nodes.system_message(message, level=level, - type=self.levels[level], - *children, **kwargs) - - HAS_DOCUTILS = True -except Exception: - # Catch all exceptions because exceptions besides ImportError probably - # indicate that docutils is not ported to Py3k. - HAS_DOCUTILS = False - -class check(Command): - """This command checks the meta-data of the package. - """ - description = ("perform some checks on the package") - user_options = [('metadata', 'm', 'Verify meta-data'), - ('restructuredtext', 'r', - ('Checks if long string meta-data syntax ' - 'are reStructuredText-compliant')), - ('strict', 's', - 'Will exit with an error if a check fails')] - - boolean_options = ['metadata', 'restructuredtext', 'strict'] - - def initialize_options(self): - """Sets default values for options.""" - self.restructuredtext = 0 - self.metadata = 1 - self.strict = 0 - self._warnings = 0 - - def finalize_options(self): - pass - - def warn(self, msg): - """Counts the number of warnings that occurs.""" - self._warnings += 1 - return Command.warn(self, msg) - - def run(self): - """Runs the command.""" - # perform the various tests - if self.metadata: - self.check_metadata() - if self.restructuredtext: - if HAS_DOCUTILS: - self.check_restructuredtext() - elif self.strict: - raise DistutilsSetupError('The docutils package is needed.') - - # let's raise an error in strict mode, if we have at least - # one warning - if self.strict and self._warnings > 0: - raise DistutilsSetupError('Please correct your package.') - - def check_metadata(self): - """Ensures that all required elements of meta-data are supplied. - - Required fields: - name, version, URL - - Recommended fields: - (author and author_email) or (maintainer and maintainer_email) - - Warns if any are missing. - """ - metadata = self.distribution.metadata - - missing = [] - for attr in ('name', 'version', 'url'): - if not (hasattr(metadata, attr) and getattr(metadata, attr)): - missing.append(attr) - - if missing: - self.warn("missing required meta-data: %s" % ', '.join(missing)) - if metadata.author: - if not metadata.author_email: - self.warn("missing meta-data: if 'author' supplied, " + - "'author_email' should be supplied too") - elif metadata.maintainer: - if not metadata.maintainer_email: - self.warn("missing meta-data: if 'maintainer' supplied, " + - "'maintainer_email' should be supplied too") - else: - self.warn("missing meta-data: either (author and author_email) " + - "or (maintainer and maintainer_email) " + - "should be supplied") - - def check_restructuredtext(self): - """Checks if the long string fields are reST-compliant.""" - data = self.distribution.get_long_description() - for warning in self._check_rst_data(data): - line = warning[-1].get('line') - if line is None: - warning = warning[1] - else: - warning = '%s (line %s)' % (warning[1], line) - self.warn(warning) - - def _check_rst_data(self, data): - """Returns warnings when the provided data doesn't compile.""" - # the include and csv_table directives need this to be a path - source_path = self.distribution.script_name or 'setup.py' - parser = Parser() - settings = frontend.OptionParser(components=(Parser,)).get_default_values() - settings.tab_width = 4 - settings.pep_references = None - settings.rfc_references = None - reporter = SilentReporter(source_path, - settings.report_level, - settings.halt_level, - stream=settings.warning_stream, - debug=settings.debug, - encoding=settings.error_encoding, - error_handler=settings.error_encoding_error_handler) - - document = nodes.document(settings, reporter, source=source_path) - document.note_source(source_path, -1) - try: - parser.parse(data, document) - except AttributeError as e: - reporter.messages.append( - (-1, 'Could not finish the parsing: %s.' % e, '', {})) - - return reporter.messages diff --git a/python/Lib/distutils/command/clean.py b/python/Lib/distutils/command/clean.py deleted file mode 100644 index 2e1ae3a..0000000 --- a/python/Lib/distutils/command/clean.py +++ /dev/null @@ -1,76 +0,0 @@ -"""distutils.command.clean - -Implements the Distutils 'clean' command.""" - -# contributed by Bastian Kleineidam , added 2000-03-18 - -import os -from distutils.core import Command -from distutils.dir_util import remove_tree -from distutils import log - -class clean(Command): - - description = "clean up temporary files from 'build' command" - user_options = [ - ('build-base=', 'b', - "base build directory (default: 'build.build-base')"), - ('build-lib=', None, - "build directory for all modules (default: 'build.build-lib')"), - ('build-temp=', 't', - "temporary build directory (default: 'build.build-temp')"), - ('build-scripts=', None, - "build directory for scripts (default: 'build.build-scripts')"), - ('bdist-base=', None, - "temporary directory for built distributions"), - ('all', 'a', - "remove all build output, not just temporary by-products") - ] - - boolean_options = ['all'] - - def initialize_options(self): - self.build_base = None - self.build_lib = None - self.build_temp = None - self.build_scripts = None - self.bdist_base = None - self.all = None - - def finalize_options(self): - self.set_undefined_options('build', - ('build_base', 'build_base'), - ('build_lib', 'build_lib'), - ('build_scripts', 'build_scripts'), - ('build_temp', 'build_temp')) - self.set_undefined_options('bdist', - ('bdist_base', 'bdist_base')) - - def run(self): - # remove the build/temp. directory (unless it's already - # gone) - if os.path.exists(self.build_temp): - remove_tree(self.build_temp, dry_run=self.dry_run) - else: - log.debug("'%s' does not exist -- can't clean it", - self.build_temp) - - if self.all: - # remove build directories - for directory in (self.build_lib, - self.bdist_base, - self.build_scripts): - if os.path.exists(directory): - remove_tree(directory, dry_run=self.dry_run) - else: - log.warn("'%s' does not exist -- can't clean it", - directory) - - # just for the heck of it, try to remove the base build directory: - # we might have emptied it right now, but if not we don't care - if not self.dry_run: - try: - os.rmdir(self.build_base) - log.info("removing '%s'", self.build_base) - except OSError: - pass diff --git a/python/Lib/distutils/command/command_template b/python/Lib/distutils/command/command_template deleted file mode 100644 index b9b3533..0000000 --- a/python/Lib/distutils/command/command_template +++ /dev/null @@ -1,33 +0,0 @@ -"""distutils.command.x - -Implements the Distutils 'x' command. -""" - -# created 2000/mm/dd, John Doe - -__revision__ = "$Id$" - -from distutils.core import Command - - -class x(Command): - - # Brief (40-50 characters) description of the command - description = "" - - # List of option tuples: long name, short name (None if no short - # name), and help string. - user_options = [('', '', - ""), - ] - - def initialize_options(self): - self. = None - self. = None - self. = None - - def finalize_options(self): - if self.x is None: - self.x = - - def run(self): diff --git a/python/Lib/distutils/command/config.py b/python/Lib/distutils/command/config.py deleted file mode 100644 index 0fd997c..0000000 --- a/python/Lib/distutils/command/config.py +++ /dev/null @@ -1,344 +0,0 @@ -"""distutils.command.config - -Implements the Distutils 'config' command, a (mostly) empty command class -that exists mainly to be sub-classed by specific module distributions and -applications. The idea is that while every "config" command is different, -at least they're all named the same, and users always see "config" in the -list of standard commands. Also, this is a good place to put common -configure-like tasks: "try to compile this C code", or "figure out where -this header file lives". -""" - -import os, re - -from distutils.core import Command -from distutils.errors import DistutilsExecError -from distutils.sysconfig import customize_compiler -from distutils import log - -LANG_EXT = {"c": ".c", "c++": ".cxx"} - -class config(Command): - - description = "prepare to build" - - user_options = [ - ('compiler=', None, - "specify the compiler type"), - ('cc=', None, - "specify the compiler executable"), - ('include-dirs=', 'I', - "list of directories to search for header files"), - ('define=', 'D', - "C preprocessor macros to define"), - ('undef=', 'U', - "C preprocessor macros to undefine"), - ('libraries=', 'l', - "external C libraries to link with"), - ('library-dirs=', 'L', - "directories to search for external C libraries"), - - ('noisy', None, - "show every action (compile, link, run, ...) taken"), - ('dump-source', None, - "dump generated source files before attempting to compile them"), - ] - - - # The three standard command methods: since the "config" command - # does nothing by default, these are empty. - - def initialize_options(self): - self.compiler = None - self.cc = None - self.include_dirs = None - self.libraries = None - self.library_dirs = None - - # maximal output for now - self.noisy = 1 - self.dump_source = 1 - - # list of temporary files generated along-the-way that we have - # to clean at some point - self.temp_files = [] - - def finalize_options(self): - if self.include_dirs is None: - self.include_dirs = self.distribution.include_dirs or [] - elif isinstance(self.include_dirs, str): - self.include_dirs = self.include_dirs.split(os.pathsep) - - if self.libraries is None: - self.libraries = [] - elif isinstance(self.libraries, str): - self.libraries = [self.libraries] - - if self.library_dirs is None: - self.library_dirs = [] - elif isinstance(self.library_dirs, str): - self.library_dirs = self.library_dirs.split(os.pathsep) - - def run(self): - pass - - # Utility methods for actual "config" commands. The interfaces are - # loosely based on Autoconf macros of similar names. Sub-classes - # may use these freely. - - def _check_compiler(self): - """Check that 'self.compiler' really is a CCompiler object; - if not, make it one. - """ - # We do this late, and only on-demand, because this is an expensive - # import. - from distutils.ccompiler import CCompiler, new_compiler - if not isinstance(self.compiler, CCompiler): - self.compiler = new_compiler(compiler=self.compiler, - dry_run=self.dry_run, force=1) - customize_compiler(self.compiler) - if self.include_dirs: - self.compiler.set_include_dirs(self.include_dirs) - if self.libraries: - self.compiler.set_libraries(self.libraries) - if self.library_dirs: - self.compiler.set_library_dirs(self.library_dirs) - - def _gen_temp_sourcefile(self, body, headers, lang): - filename = "_configtest" + LANG_EXT[lang] - with open(filename, "w") as file: - if headers: - for header in headers: - file.write("#include <%s>\n" % header) - file.write("\n") - file.write(body) - if body[-1] != "\n": - file.write("\n") - return filename - - def _preprocess(self, body, headers, include_dirs, lang): - src = self._gen_temp_sourcefile(body, headers, lang) - out = "_configtest.i" - self.temp_files.extend([src, out]) - self.compiler.preprocess(src, out, include_dirs=include_dirs) - return (src, out) - - def _compile(self, body, headers, include_dirs, lang): - src = self._gen_temp_sourcefile(body, headers, lang) - if self.dump_source: - dump_file(src, "compiling '%s':" % src) - (obj,) = self.compiler.object_filenames([src]) - self.temp_files.extend([src, obj]) - self.compiler.compile([src], include_dirs=include_dirs) - return (src, obj) - - def _link(self, body, headers, include_dirs, libraries, library_dirs, - lang): - (src, obj) = self._compile(body, headers, include_dirs, lang) - prog = os.path.splitext(os.path.basename(src))[0] - self.compiler.link_executable([obj], prog, - libraries=libraries, - library_dirs=library_dirs, - target_lang=lang) - - if self.compiler.exe_extension is not None: - prog = prog + self.compiler.exe_extension - self.temp_files.append(prog) - - return (src, obj, prog) - - def _clean(self, *filenames): - if not filenames: - filenames = self.temp_files - self.temp_files = [] - log.info("removing: %s", ' '.join(filenames)) - for filename in filenames: - try: - os.remove(filename) - except OSError: - pass - - - # XXX these ignore the dry-run flag: what to do, what to do? even if - # you want a dry-run build, you still need some sort of configuration - # info. My inclination is to make it up to the real config command to - # consult 'dry_run', and assume a default (minimal) configuration if - # true. The problem with trying to do it here is that you'd have to - # return either true or false from all the 'try' methods, neither of - # which is correct. - - # XXX need access to the header search path and maybe default macros. - - def try_cpp(self, body=None, headers=None, include_dirs=None, lang="c"): - """Construct a source file from 'body' (a string containing lines - of C/C++ code) and 'headers' (a list of header files to include) - and run it through the preprocessor. Return true if the - preprocessor succeeded, false if there were any errors. - ('body' probably isn't of much use, but what the heck.) - """ - from distutils.ccompiler import CompileError - self._check_compiler() - ok = True - try: - self._preprocess(body, headers, include_dirs, lang) - except CompileError: - ok = False - - self._clean() - return ok - - def search_cpp(self, pattern, body=None, headers=None, include_dirs=None, - lang="c"): - """Construct a source file (just like 'try_cpp()'), run it through - the preprocessor, and return true if any line of the output matches - 'pattern'. 'pattern' should either be a compiled regex object or a - string containing a regex. If both 'body' and 'headers' are None, - preprocesses an empty file -- which can be useful to determine the - symbols the preprocessor and compiler set by default. - """ - self._check_compiler() - src, out = self._preprocess(body, headers, include_dirs, lang) - - if isinstance(pattern, str): - pattern = re.compile(pattern) - - with open(out) as file: - match = False - while True: - line = file.readline() - if line == '': - break - if pattern.search(line): - match = True - break - - self._clean() - return match - - def try_compile(self, body, headers=None, include_dirs=None, lang="c"): - """Try to compile a source file built from 'body' and 'headers'. - Return true on success, false otherwise. - """ - from distutils.ccompiler import CompileError - self._check_compiler() - try: - self._compile(body, headers, include_dirs, lang) - ok = True - except CompileError: - ok = False - - log.info(ok and "success!" or "failure.") - self._clean() - return ok - - def try_link(self, body, headers=None, include_dirs=None, libraries=None, - library_dirs=None, lang="c"): - """Try to compile and link a source file, built from 'body' and - 'headers', to executable form. Return true on success, false - otherwise. - """ - from distutils.ccompiler import CompileError, LinkError - self._check_compiler() - try: - self._link(body, headers, include_dirs, - libraries, library_dirs, lang) - ok = True - except (CompileError, LinkError): - ok = False - - log.info(ok and "success!" or "failure.") - self._clean() - return ok - - def try_run(self, body, headers=None, include_dirs=None, libraries=None, - library_dirs=None, lang="c"): - """Try to compile, link to an executable, and run a program - built from 'body' and 'headers'. Return true on success, false - otherwise. - """ - from distutils.ccompiler import CompileError, LinkError - self._check_compiler() - try: - src, obj, exe = self._link(body, headers, include_dirs, - libraries, library_dirs, lang) - self.spawn([exe]) - ok = True - except (CompileError, LinkError, DistutilsExecError): - ok = False - - log.info(ok and "success!" or "failure.") - self._clean() - return ok - - - # -- High-level methods -------------------------------------------- - # (these are the ones that are actually likely to be useful - # when implementing a real-world config command!) - - def check_func(self, func, headers=None, include_dirs=None, - libraries=None, library_dirs=None, decl=0, call=0): - """Determine if function 'func' is available by constructing a - source file that refers to 'func', and compiles and links it. - If everything succeeds, returns true; otherwise returns false. - - The constructed source file starts out by including the header - files listed in 'headers'. If 'decl' is true, it then declares - 'func' (as "int func()"); you probably shouldn't supply 'headers' - and set 'decl' true in the same call, or you might get errors about - a conflicting declarations for 'func'. Finally, the constructed - 'main()' function either references 'func' or (if 'call' is true) - calls it. 'libraries' and 'library_dirs' are used when - linking. - """ - self._check_compiler() - body = [] - if decl: - body.append("int %s ();" % func) - body.append("int main () {") - if call: - body.append(" %s();" % func) - else: - body.append(" %s;" % func) - body.append("}") - body = "\n".join(body) + "\n" - - return self.try_link(body, headers, include_dirs, - libraries, library_dirs) - - def check_lib(self, library, library_dirs=None, headers=None, - include_dirs=None, other_libraries=[]): - """Determine if 'library' is available to be linked against, - without actually checking that any particular symbols are provided - by it. 'headers' will be used in constructing the source file to - be compiled, but the only effect of this is to check if all the - header files listed are available. Any libraries listed in - 'other_libraries' will be included in the link, in case 'library' - has symbols that depend on other libraries. - """ - self._check_compiler() - return self.try_link("int main (void) { }", headers, include_dirs, - [library] + other_libraries, library_dirs) - - def check_header(self, header, include_dirs=None, library_dirs=None, - lang="c"): - """Determine if the system header file named by 'header_file' - exists and can be found by the preprocessor; return true if so, - false otherwise. - """ - return self.try_cpp(body="/* No body */", headers=[header], - include_dirs=include_dirs) - -def dump_file(filename, head=None): - """Dumps a file content into log.info. - - If head is not None, will be dumped before the file content. - """ - if head is None: - log.info('%s', filename) - else: - log.info(head) - file = open(filename) - try: - log.info(file.read()) - finally: - file.close() diff --git a/python/Lib/distutils/command/install.py b/python/Lib/distutils/command/install.py deleted file mode 100644 index 0d8aa0f..0000000 --- a/python/Lib/distutils/command/install.py +++ /dev/null @@ -1,679 +0,0 @@ -"""distutils.command.install - -Implements the Distutils 'install' command.""" - -import sys -import sysconfig -import os -import re - -from distutils import log -from distutils.core import Command -from distutils.debug import DEBUG -from distutils.sysconfig import get_config_vars -from distutils.errors import DistutilsPlatformError -from distutils.file_util import write_file -from distutils.util import convert_path, subst_vars, change_root -from distutils.util import get_platform -from distutils.errors import DistutilsOptionError - -from site import USER_BASE -from site import USER_SITE - -HAS_USER_SITE = (USER_SITE is not None) - -# The keys to an installation scheme; if any new types of files are to be -# installed, be sure to add an entry to every scheme in -# sysconfig._INSTALL_SCHEMES, and to SCHEME_KEYS here. -SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data') - -# The following code provides backward-compatible INSTALL_SCHEMES -# while making the sysconfig module the single point of truth. -# This makes it easier for OS distributions where they need to -# alter locations for packages installations in a single place. -# Note that this module is deprecated (PEP 632); all consumers -# of this information should switch to using sysconfig directly. -INSTALL_SCHEMES = {"unix_prefix": {}, "unix_home": {}, "nt": {}} - -# Copy from sysconfig._INSTALL_SCHEMES -for key in SCHEME_KEYS: - for distutils_scheme_name, sys_scheme_name in ( - ("unix_prefix", "posix_prefix"), ("unix_home", "posix_home"), - ("nt", "nt")): - sys_key = key - sys_scheme = sysconfig._INSTALL_SCHEMES[sys_scheme_name] - if key == "headers" and key not in sys_scheme: - # On POSIX-y platforms, Python will: - # - Build from .h files in 'headers' (only there when - # building CPython) - # - Install .h files to 'include' - # When 'headers' is missing, fall back to 'include' - sys_key = 'include' - INSTALL_SCHEMES[distutils_scheme_name][key] = sys_scheme[sys_key] - -# Transformation to different template format -for main_key in INSTALL_SCHEMES: - for key, value in INSTALL_SCHEMES[main_key].items(): - # Change all ocurences of {variable} to $variable - value = re.sub(r"\{(.+?)\}", r"$\g<1>", value) - value = value.replace("$installed_base", "$base") - value = value.replace("$py_version_nodot_plat", "$py_version_nodot") - if key == "headers": - value += "/$dist_name" - if sys.version_info >= (3, 9) and key == "platlib": - # platlibdir is available since 3.9: bpo-1294959 - value = value.replace("/lib/", "/$platlibdir/") - INSTALL_SCHEMES[main_key][key] = value - -# The following part of INSTALL_SCHEMES has a different definition -# than the one in sysconfig, but because both depend on the site module, -# the outcomes should be the same. -if HAS_USER_SITE: - INSTALL_SCHEMES['nt_user'] = { - 'purelib': '$usersite', - 'platlib': '$usersite', - 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name', - 'scripts': '$userbase/Python$py_version_nodot/Scripts', - 'data' : '$userbase', - } - - INSTALL_SCHEMES['unix_user'] = { - 'purelib': '$usersite', - 'platlib': '$usersite', - 'headers': - '$userbase/include/python$py_version_short$abiflags/$dist_name', - 'scripts': '$userbase/bin', - 'data' : '$userbase', - } - - -class install(Command): - - description = "install everything from build directory" - - user_options = [ - # Select installation scheme and set base director(y|ies) - ('prefix=', None, - "installation prefix"), - ('exec-prefix=', None, - "(Unix only) prefix for platform-specific files"), - ('home=', None, - "(Unix only) home directory to install under"), - - # Or, just set the base director(y|ies) - ('install-base=', None, - "base installation directory (instead of --prefix or --home)"), - ('install-platbase=', None, - "base installation directory for platform-specific files " + - "(instead of --exec-prefix or --home)"), - ('root=', None, - "install everything relative to this alternate root directory"), - - # Or, explicitly set the installation scheme - ('install-purelib=', None, - "installation directory for pure Python module distributions"), - ('install-platlib=', None, - "installation directory for non-pure module distributions"), - ('install-lib=', None, - "installation directory for all module distributions " + - "(overrides --install-purelib and --install-platlib)"), - - ('install-headers=', None, - "installation directory for C/C++ headers"), - ('install-scripts=', None, - "installation directory for Python scripts"), - ('install-data=', None, - "installation directory for data files"), - - # Byte-compilation options -- see install_lib.py for details, as - # these are duplicated from there (but only install_lib does - # anything with them). - ('compile', 'c', "compile .py to .pyc [default]"), - ('no-compile', None, "don't compile .py files"), - ('optimize=', 'O', - "also compile with optimization: -O1 for \"python -O\", " - "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), - - # Miscellaneous control options - ('force', 'f', - "force installation (overwrite any existing files)"), - ('skip-build', None, - "skip rebuilding everything (for testing/debugging)"), - - # Where to install documentation (eventually!) - #('doc-format=', None, "format of documentation to generate"), - #('install-man=', None, "directory for Unix man pages"), - #('install-html=', None, "directory for HTML documentation"), - #('install-info=', None, "directory for GNU info files"), - - ('record=', None, - "filename in which to record list of installed files"), - ] - - boolean_options = ['compile', 'force', 'skip-build'] - - if HAS_USER_SITE: - user_options.append(('user', None, - "install in user site-package '%s'" % USER_SITE)) - boolean_options.append('user') - - negative_opt = {'no-compile' : 'compile'} - - - def initialize_options(self): - """Initializes options.""" - # High-level options: these select both an installation base - # and scheme. - self.prefix = None - self.exec_prefix = None - self.home = None - self.user = 0 - - # These select only the installation base; it's up to the user to - # specify the installation scheme (currently, that means supplying - # the --install-{platlib,purelib,scripts,data} options). - self.install_base = None - self.install_platbase = None - self.root = None - - # These options are the actual installation directories; if not - # supplied by the user, they are filled in using the installation - # scheme implied by prefix/exec-prefix/home and the contents of - # that installation scheme. - self.install_purelib = None # for pure module distributions - self.install_platlib = None # non-pure (dists w/ extensions) - self.install_headers = None # for C/C++ headers - self.install_lib = None # set to either purelib or platlib - self.install_scripts = None - self.install_data = None - if HAS_USER_SITE: - self.install_userbase = USER_BASE - self.install_usersite = USER_SITE - - self.compile = None - self.optimize = None - - # Deprecated - # These two are for putting non-packagized distributions into their - # own directory and creating a .pth file if it makes sense. - # 'extra_path' comes from the setup file; 'install_path_file' can - # be turned off if it makes no sense to install a .pth file. (But - # better to install it uselessly than to guess wrong and not - # install it when it's necessary and would be used!) Currently, - # 'install_path_file' is always true unless some outsider meddles - # with it. - self.extra_path = None - self.install_path_file = 1 - - # 'force' forces installation, even if target files are not - # out-of-date. 'skip_build' skips running the "build" command, - # handy if you know it's not necessary. 'warn_dir' (which is *not* - # a user option, it's just there so the bdist_* commands can turn - # it off) determines whether we warn about installing to a - # directory not in sys.path. - self.force = 0 - self.skip_build = 0 - self.warn_dir = 1 - - # These are only here as a conduit from the 'build' command to the - # 'install_*' commands that do the real work. ('build_base' isn't - # actually used anywhere, but it might be useful in future.) They - # are not user options, because if the user told the install - # command where the build directory is, that wouldn't affect the - # build command. - self.build_base = None - self.build_lib = None - - # Not defined yet because we don't know anything about - # documentation yet. - #self.install_man = None - #self.install_html = None - #self.install_info = None - - self.record = None - - - # -- Option finalizing methods ------------------------------------- - # (This is rather more involved than for most commands, - # because this is where the policy for installing third- - # party Python modules on various platforms given a wide - # array of user input is decided. Yes, it's quite complex!) - - def finalize_options(self): - """Finalizes options.""" - # This method (and its helpers, like 'finalize_unix()', - # 'finalize_other()', and 'select_scheme()') is where the default - # installation directories for modules, extension modules, and - # anything else we care to install from a Python module - # distribution. Thus, this code makes a pretty important policy - # statement about how third-party stuff is added to a Python - # installation! Note that the actual work of installation is done - # by the relatively simple 'install_*' commands; they just take - # their orders from the installation directory options determined - # here. - - # Check for errors/inconsistencies in the options; first, stuff - # that's wrong on any platform. - - if ((self.prefix or self.exec_prefix or self.home) and - (self.install_base or self.install_platbase)): - raise DistutilsOptionError( - "must supply either prefix/exec-prefix/home or " + - "install-base/install-platbase -- not both") - - if self.home and (self.prefix or self.exec_prefix): - raise DistutilsOptionError( - "must supply either home or prefix/exec-prefix -- not both") - - if self.user and (self.prefix or self.exec_prefix or self.home or - self.install_base or self.install_platbase): - raise DistutilsOptionError("can't combine user with prefix, " - "exec_prefix/home, or install_(plat)base") - - # Next, stuff that's wrong (or dubious) only on certain platforms. - if os.name != "posix": - if self.exec_prefix: - self.warn("exec-prefix option ignored on this platform") - self.exec_prefix = None - - # Now the interesting logic -- so interesting that we farm it out - # to other methods. The goal of these methods is to set the final - # values for the install_{lib,scripts,data,...} options, using as - # input a heady brew of prefix, exec_prefix, home, install_base, - # install_platbase, user-supplied versions of - # install_{purelib,platlib,lib,scripts,data,...}, and the - # INSTALL_SCHEME dictionary above. Phew! - - self.dump_dirs("pre-finalize_{unix,other}") - - if os.name == 'posix': - self.finalize_unix() - else: - self.finalize_other() - - self.dump_dirs("post-finalize_{unix,other}()") - - # Expand configuration variables, tilde, etc. in self.install_base - # and self.install_platbase -- that way, we can use $base or - # $platbase in the other installation directories and not worry - # about needing recursive variable expansion (shudder). - - py_version = sys.version.split()[0] - (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix') - try: - abiflags = sys.abiflags - except AttributeError: - # sys.abiflags may not be defined on all platforms. - abiflags = '' - self.config_vars = {'dist_name': self.distribution.get_name(), - 'dist_version': self.distribution.get_version(), - 'dist_fullname': self.distribution.get_fullname(), - 'py_version': py_version, - 'py_version_short': '%d.%d' % sys.version_info[:2], - 'py_version_nodot': '%d%d' % sys.version_info[:2], - 'sys_prefix': prefix, - 'prefix': prefix, - 'sys_exec_prefix': exec_prefix, - 'exec_prefix': exec_prefix, - 'abiflags': abiflags, - 'platlibdir': sys.platlibdir, - } - - if HAS_USER_SITE: - self.config_vars['userbase'] = self.install_userbase - self.config_vars['usersite'] = self.install_usersite - - if sysconfig.is_python_build(True): - self.config_vars['srcdir'] = sysconfig.get_config_var('srcdir') - - self.expand_basedirs() - - self.dump_dirs("post-expand_basedirs()") - - # Now define config vars for the base directories so we can expand - # everything else. - self.config_vars['base'] = self.install_base - self.config_vars['platbase'] = self.install_platbase - - if DEBUG: - from pprint import pprint - print("config vars:") - pprint(self.config_vars) - - # Expand "~" and configuration variables in the installation - # directories. - self.expand_dirs() - - self.dump_dirs("post-expand_dirs()") - - # Create directories in the home dir: - if self.user: - self.create_home_path() - - # Pick the actual directory to install all modules to: either - # install_purelib or install_platlib, depending on whether this - # module distribution is pure or not. Of course, if the user - # already specified install_lib, use their selection. - if self.install_lib is None: - if self.distribution.ext_modules: # has extensions: non-pure - self.install_lib = self.install_platlib - else: - self.install_lib = self.install_purelib - - - # Convert directories from Unix /-separated syntax to the local - # convention. - self.convert_paths('lib', 'purelib', 'platlib', - 'scripts', 'data', 'headers') - if HAS_USER_SITE: - self.convert_paths('userbase', 'usersite') - - # Deprecated - # Well, we're not actually fully completely finalized yet: we still - # have to deal with 'extra_path', which is the hack for allowing - # non-packagized module distributions (hello, Numerical Python!) to - # get their own directories. - self.handle_extra_path() - self.install_libbase = self.install_lib # needed for .pth file - self.install_lib = os.path.join(self.install_lib, self.extra_dirs) - - # If a new root directory was supplied, make all the installation - # dirs relative to it. - if self.root is not None: - self.change_roots('libbase', 'lib', 'purelib', 'platlib', - 'scripts', 'data', 'headers') - - self.dump_dirs("after prepending root") - - # Find out the build directories, ie. where to install from. - self.set_undefined_options('build', - ('build_base', 'build_base'), - ('build_lib', 'build_lib')) - - # Punt on doc directories for now -- after all, we're punting on - # documentation completely! - - def dump_dirs(self, msg): - """Dumps the list of user options.""" - if not DEBUG: - return - from distutils.fancy_getopt import longopt_xlate - log.debug(msg + ":") - for opt in self.user_options: - opt_name = opt[0] - if opt_name[-1] == "=": - opt_name = opt_name[0:-1] - if opt_name in self.negative_opt: - opt_name = self.negative_opt[opt_name] - opt_name = opt_name.translate(longopt_xlate) - val = not getattr(self, opt_name) - else: - opt_name = opt_name.translate(longopt_xlate) - val = getattr(self, opt_name) - log.debug(" %s: %s", opt_name, val) - - def finalize_unix(self): - """Finalizes options for posix platforms.""" - if self.install_base is not None or self.install_platbase is not None: - if ((self.install_lib is None and - self.install_purelib is None and - self.install_platlib is None) or - self.install_headers is None or - self.install_scripts is None or - self.install_data is None): - raise DistutilsOptionError( - "install-base or install-platbase supplied, but " - "installation scheme is incomplete") - return - - if self.user: - if self.install_userbase is None: - raise DistutilsPlatformError( - "User base directory is not specified") - self.install_base = self.install_platbase = self.install_userbase - self.select_scheme("unix_user") - elif self.home is not None: - self.install_base = self.install_platbase = self.home - self.select_scheme("unix_home") - else: - if self.prefix is None: - if self.exec_prefix is not None: - raise DistutilsOptionError( - "must not supply exec-prefix without prefix") - - self.prefix = os.path.normpath(sys.prefix) - self.exec_prefix = os.path.normpath(sys.exec_prefix) - - else: - if self.exec_prefix is None: - self.exec_prefix = self.prefix - - self.install_base = self.prefix - self.install_platbase = self.exec_prefix - self.select_scheme("unix_prefix") - - def finalize_other(self): - """Finalizes options for non-posix platforms""" - if self.user: - if self.install_userbase is None: - raise DistutilsPlatformError( - "User base directory is not specified") - self.install_base = self.install_platbase = self.install_userbase - self.select_scheme(os.name + "_user") - elif self.home is not None: - self.install_base = self.install_platbase = self.home - self.select_scheme("unix_home") - else: - if self.prefix is None: - self.prefix = os.path.normpath(sys.prefix) - - self.install_base = self.install_platbase = self.prefix - try: - self.select_scheme(os.name) - except KeyError: - raise DistutilsPlatformError( - "I don't know how to install stuff on '%s'" % os.name) - - def select_scheme(self, name): - """Sets the install directories by applying the install schemes.""" - # it's the caller's problem if they supply a bad name! - scheme = INSTALL_SCHEMES[name] - for key in SCHEME_KEYS: - attrname = 'install_' + key - if getattr(self, attrname) is None: - setattr(self, attrname, scheme[key]) - - def _expand_attrs(self, attrs): - for attr in attrs: - val = getattr(self, attr) - if val is not None: - if os.name == 'posix' or os.name == 'nt': - val = os.path.expanduser(val) - val = subst_vars(val, self.config_vars) - setattr(self, attr, val) - - def expand_basedirs(self): - """Calls `os.path.expanduser` on install_base, install_platbase and - root.""" - self._expand_attrs(['install_base', 'install_platbase', 'root']) - - def expand_dirs(self): - """Calls `os.path.expanduser` on install dirs.""" - self._expand_attrs(['install_purelib', 'install_platlib', - 'install_lib', 'install_headers', - 'install_scripts', 'install_data',]) - - def convert_paths(self, *names): - """Call `convert_path` over `names`.""" - for name in names: - attr = "install_" + name - setattr(self, attr, convert_path(getattr(self, attr))) - - def handle_extra_path(self): - """Set `path_file` and `extra_dirs` using `extra_path`.""" - if self.extra_path is None: - self.extra_path = self.distribution.extra_path - - if self.extra_path is not None: - log.warn( - "Distribution option extra_path is deprecated. " - "See issue27919 for details." - ) - if isinstance(self.extra_path, str): - self.extra_path = self.extra_path.split(',') - - if len(self.extra_path) == 1: - path_file = extra_dirs = self.extra_path[0] - elif len(self.extra_path) == 2: - path_file, extra_dirs = self.extra_path - else: - raise DistutilsOptionError( - "'extra_path' option must be a list, tuple, or " - "comma-separated string with 1 or 2 elements") - - # convert to local form in case Unix notation used (as it - # should be in setup scripts) - extra_dirs = convert_path(extra_dirs) - else: - path_file = None - extra_dirs = '' - - # XXX should we warn if path_file and not extra_dirs? (in which - # case the path file would be harmless but pointless) - self.path_file = path_file - self.extra_dirs = extra_dirs - - def change_roots(self, *names): - """Change the install directories pointed by name using root.""" - for name in names: - attr = "install_" + name - setattr(self, attr, change_root(self.root, getattr(self, attr))) - - def create_home_path(self): - """Create directories under ~.""" - if not self.user: - return - home = convert_path(os.path.expanduser("~")) - for name, path in self.config_vars.items(): - if path.startswith(home) and not os.path.isdir(path): - self.debug_print("os.makedirs('%s', 0o700)" % path) - os.makedirs(path, 0o700) - - # -- Command execution methods ------------------------------------- - - def run(self): - """Runs the command.""" - # Obviously have to build before we can install - if not self.skip_build: - self.run_command('build') - # If we built for any other platform, we can't install. - build_plat = self.distribution.get_command_obj('build').plat_name - # check warn_dir - it is a clue that the 'install' is happening - # internally, and not to sys.path, so we don't check the platform - # matches what we are running. - if self.warn_dir and build_plat != get_platform(): - raise DistutilsPlatformError("Can't install when " - "cross-compiling") - - # Run all sub-commands (at least those that need to be run) - for cmd_name in self.get_sub_commands(): - self.run_command(cmd_name) - - if self.path_file: - self.create_path_file() - - # write list of installed files, if requested. - if self.record: - outputs = self.get_outputs() - if self.root: # strip any package prefix - root_len = len(self.root) - for counter in range(len(outputs)): - outputs[counter] = outputs[counter][root_len:] - self.execute(write_file, - (self.record, outputs), - "writing list of installed files to '%s'" % - self.record) - - sys_path = map(os.path.normpath, sys.path) - sys_path = map(os.path.normcase, sys_path) - install_lib = os.path.normcase(os.path.normpath(self.install_lib)) - if (self.warn_dir and - not (self.path_file and self.install_path_file) and - install_lib not in sys_path): - log.debug(("modules installed to '%s', which is not in " - "Python's module search path (sys.path) -- " - "you'll have to change the search path yourself"), - self.install_lib) - - def create_path_file(self): - """Creates the .pth file""" - filename = os.path.join(self.install_libbase, - self.path_file + ".pth") - if self.install_path_file: - self.execute(write_file, - (filename, [self.extra_dirs]), - "creating %s" % filename) - else: - self.warn("path file '%s' not created" % filename) - - - # -- Reporting methods --------------------------------------------- - - def get_outputs(self): - """Assembles the outputs of all the sub-commands.""" - outputs = [] - for cmd_name in self.get_sub_commands(): - cmd = self.get_finalized_command(cmd_name) - # Add the contents of cmd.get_outputs(), ensuring - # that outputs doesn't contain duplicate entries - for filename in cmd.get_outputs(): - if filename not in outputs: - outputs.append(filename) - - if self.path_file and self.install_path_file: - outputs.append(os.path.join(self.install_libbase, - self.path_file + ".pth")) - - return outputs - - def get_inputs(self): - """Returns the inputs of all the sub-commands""" - # XXX gee, this looks familiar ;-( - inputs = [] - for cmd_name in self.get_sub_commands(): - cmd = self.get_finalized_command(cmd_name) - inputs.extend(cmd.get_inputs()) - - return inputs - - # -- Predicates for sub-command list ------------------------------- - - def has_lib(self): - """Returns true if the current distribution has any Python - modules to install.""" - return (self.distribution.has_pure_modules() or - self.distribution.has_ext_modules()) - - def has_headers(self): - """Returns true if the current distribution has any headers to - install.""" - return self.distribution.has_headers() - - def has_scripts(self): - """Returns true if the current distribution has any scripts to. - install.""" - return self.distribution.has_scripts() - - def has_data(self): - """Returns true if the current distribution has any data to. - install.""" - return self.distribution.has_data_files() - - # 'sub_commands': a list of commands this command might have to run to - # get its work done. See cmd.py for more info. - sub_commands = [('install_lib', has_lib), - ('install_headers', has_headers), - ('install_scripts', has_scripts), - ('install_data', has_data), - ('install_egg_info', lambda self:True), - ] diff --git a/python/Lib/distutils/command/install_data.py b/python/Lib/distutils/command/install_data.py deleted file mode 100644 index 60b0211..0000000 --- a/python/Lib/distutils/command/install_data.py +++ /dev/null @@ -1,79 +0,0 @@ -"""distutils.command.install_data - -Implements the Distutils 'install_data' command, for installing -platform-independent data files.""" - -# contributed by Bastian Kleineidam - -import os -from distutils.core import Command -from distutils.util import change_root, convert_path - -class install_data(Command): - - description = "install data files" - - user_options = [ - ('install-dir=', 'd', - "base directory for installing data files " - "(default: installation base dir)"), - ('root=', None, - "install everything relative to this alternate root directory"), - ('force', 'f', "force installation (overwrite existing files)"), - ] - - boolean_options = ['force'] - - def initialize_options(self): - self.install_dir = None - self.outfiles = [] - self.root = None - self.force = 0 - self.data_files = self.distribution.data_files - self.warn_dir = 1 - - def finalize_options(self): - self.set_undefined_options('install', - ('install_data', 'install_dir'), - ('root', 'root'), - ('force', 'force'), - ) - - def run(self): - self.mkpath(self.install_dir) - for f in self.data_files: - if isinstance(f, str): - # it's a simple file, so copy it - f = convert_path(f) - if self.warn_dir: - self.warn("setup script did not provide a directory for " - "'%s' -- installing right in '%s'" % - (f, self.install_dir)) - (out, _) = self.copy_file(f, self.install_dir) - self.outfiles.append(out) - else: - # it's a tuple with path to install to and a list of files - dir = convert_path(f[0]) - if not os.path.isabs(dir): - dir = os.path.join(self.install_dir, dir) - elif self.root: - dir = change_root(self.root, dir) - self.mkpath(dir) - - if f[1] == []: - # If there are no files listed, the user must be - # trying to create an empty directory, so add the - # directory to the list of output files. - self.outfiles.append(dir) - else: - # Copy files, adding them to the list of output files. - for data in f[1]: - data = convert_path(data) - (out, _) = self.copy_file(data, dir) - self.outfiles.append(out) - - def get_inputs(self): - return self.data_files or [] - - def get_outputs(self): - return self.outfiles diff --git a/python/Lib/distutils/command/install_egg_info.py b/python/Lib/distutils/command/install_egg_info.py deleted file mode 100644 index f2d52ac..0000000 --- a/python/Lib/distutils/command/install_egg_info.py +++ /dev/null @@ -1,77 +0,0 @@ -"""distutils.command.install_egg_info - -Implements the Distutils 'install_egg_info' command, for installing -a package's PKG-INFO metadata.""" - - -from distutils.cmd import Command -from distutils import log, dir_util -import os, sys, re - -class install_egg_info(Command): - """Install an .egg-info file for the package""" - - description = "Install package's PKG-INFO metadata as an .egg-info file" - user_options = [ - ('install-dir=', 'd', "directory to install to"), - ] - - def initialize_options(self): - self.install_dir = None - - def finalize_options(self): - self.set_undefined_options('install_lib',('install_dir','install_dir')) - basename = "%s-%s-py%d.%d.egg-info" % ( - to_filename(safe_name(self.distribution.get_name())), - to_filename(safe_version(self.distribution.get_version())), - *sys.version_info[:2] - ) - self.target = os.path.join(self.install_dir, basename) - self.outputs = [self.target] - - def run(self): - target = self.target - if os.path.isdir(target) and not os.path.islink(target): - dir_util.remove_tree(target, dry_run=self.dry_run) - elif os.path.exists(target): - self.execute(os.unlink,(self.target,),"Removing "+target) - elif not os.path.isdir(self.install_dir): - self.execute(os.makedirs, (self.install_dir,), - "Creating "+self.install_dir) - log.info("Writing %s", target) - if not self.dry_run: - with open(target, 'w', encoding='UTF-8') as f: - self.distribution.metadata.write_pkg_file(f) - - def get_outputs(self): - return self.outputs - - -# The following routines are taken from setuptools' pkg_resources module and -# can be replaced by importing them from pkg_resources once it is included -# in the stdlib. - -def safe_name(name): - """Convert an arbitrary string to a standard distribution name - - Any runs of non-alphanumeric/. characters are replaced with a single '-'. - """ - return re.sub('[^A-Za-z0-9.]+', '-', name) - - -def safe_version(version): - """Convert an arbitrary string to a standard version string - - Spaces become dots, and all other non-alphanumeric characters become - dashes, with runs of multiple dashes condensed to a single dash. - """ - version = version.replace(' ','.') - return re.sub('[^A-Za-z0-9.]+', '-', version) - - -def to_filename(name): - """Convert a project or version name to its filename-escaped form - - Any '-' characters are currently replaced with '_'. - """ - return name.replace('-','_') diff --git a/python/Lib/distutils/command/install_headers.py b/python/Lib/distutils/command/install_headers.py deleted file mode 100644 index 6a6e0a9..0000000 --- a/python/Lib/distutils/command/install_headers.py +++ /dev/null @@ -1,47 +0,0 @@ -"""distutils.command.install_headers - -Implements the Distutils 'install_headers' command, to install C/C++ header -files to the Python include directory.""" - -from distutils.core import Command - - -# XXX force is never used -class install_headers(Command): - - description = "install C/C++ header files" - - user_options = [('install-dir=', 'd', - "directory to install header files to"), - ('force', 'f', - "force installation (overwrite existing files)"), - ] - - boolean_options = ['force'] - - def initialize_options(self): - self.install_dir = None - self.force = 0 - self.outfiles = [] - - def finalize_options(self): - self.set_undefined_options('install', - ('install_headers', 'install_dir'), - ('force', 'force')) - - - def run(self): - headers = self.distribution.headers - if not headers: - return - - self.mkpath(self.install_dir) - for header in headers: - (out, _) = self.copy_file(header, self.install_dir) - self.outfiles.append(out) - - def get_inputs(self): - return self.distribution.headers or [] - - def get_outputs(self): - return self.outfiles diff --git a/python/Lib/distutils/command/install_lib.py b/python/Lib/distutils/command/install_lib.py deleted file mode 100644 index 080c8cd..0000000 --- a/python/Lib/distutils/command/install_lib.py +++ /dev/null @@ -1,217 +0,0 @@ -"""distutils.command.install_lib - -Implements the Distutils 'install_lib' command -(install all Python modules).""" - -import os -import importlib.util -import sys - -from distutils.core import Command -from distutils.errors import DistutilsOptionError - - -# Extension for Python source files. -PYTHON_SOURCE_EXTENSION = ".py" - -class install_lib(Command): - - description = "install all Python modules (extensions and pure Python)" - - # The byte-compilation options are a tad confusing. Here are the - # possible scenarios: - # 1) no compilation at all (--no-compile --no-optimize) - # 2) compile .pyc only (--compile --no-optimize; default) - # 3) compile .pyc and "opt-1" .pyc (--compile --optimize) - # 4) compile "opt-1" .pyc only (--no-compile --optimize) - # 5) compile .pyc and "opt-2" .pyc (--compile --optimize-more) - # 6) compile "opt-2" .pyc only (--no-compile --optimize-more) - # - # The UI for this is two options, 'compile' and 'optimize'. - # 'compile' is strictly boolean, and only decides whether to - # generate .pyc files. 'optimize' is three-way (0, 1, or 2), and - # decides both whether to generate .pyc files and what level of - # optimization to use. - - user_options = [ - ('install-dir=', 'd', "directory to install to"), - ('build-dir=','b', "build directory (where to install from)"), - ('force', 'f', "force installation (overwrite existing files)"), - ('compile', 'c', "compile .py to .pyc [default]"), - ('no-compile', None, "don't compile .py files"), - ('optimize=', 'O', - "also compile with optimization: -O1 for \"python -O\", " - "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), - ('skip-build', None, "skip the build steps"), - ] - - boolean_options = ['force', 'compile', 'skip-build'] - negative_opt = {'no-compile' : 'compile'} - - def initialize_options(self): - # let the 'install' command dictate our installation directory - self.install_dir = None - self.build_dir = None - self.force = 0 - self.compile = None - self.optimize = None - self.skip_build = None - - def finalize_options(self): - # Get all the information we need to install pure Python modules - # from the umbrella 'install' command -- build (source) directory, - # install (target) directory, and whether to compile .py files. - self.set_undefined_options('install', - ('build_lib', 'build_dir'), - ('install_lib', 'install_dir'), - ('force', 'force'), - ('compile', 'compile'), - ('optimize', 'optimize'), - ('skip_build', 'skip_build'), - ) - - if self.compile is None: - self.compile = True - if self.optimize is None: - self.optimize = False - - if not isinstance(self.optimize, int): - try: - self.optimize = int(self.optimize) - if self.optimize not in (0, 1, 2): - raise AssertionError - except (ValueError, AssertionError): - raise DistutilsOptionError("optimize must be 0, 1, or 2") - - def run(self): - # Make sure we have built everything we need first - self.build() - - # Install everything: simply dump the entire contents of the build - # directory to the installation directory (that's the beauty of - # having a build directory!) - outfiles = self.install() - - # (Optionally) compile .py to .pyc - if outfiles is not None and self.distribution.has_pure_modules(): - self.byte_compile(outfiles) - - # -- Top-level worker functions ------------------------------------ - # (called from 'run()') - - def build(self): - if not self.skip_build: - if self.distribution.has_pure_modules(): - self.run_command('build_py') - if self.distribution.has_ext_modules(): - self.run_command('build_ext') - - def install(self): - if os.path.isdir(self.build_dir): - outfiles = self.copy_tree(self.build_dir, self.install_dir) - else: - self.warn("'%s' does not exist -- no Python modules to install" % - self.build_dir) - return - return outfiles - - def byte_compile(self, files): - if sys.dont_write_bytecode: - self.warn('byte-compiling is disabled, skipping.') - return - - from distutils.util import byte_compile - - # Get the "--root" directory supplied to the "install" command, - # and use it as a prefix to strip off the purported filename - # encoded in bytecode files. This is far from complete, but it - # should at least generate usable bytecode in RPM distributions. - install_root = self.get_finalized_command('install').root - - if self.compile: - byte_compile(files, optimize=0, - force=self.force, prefix=install_root, - dry_run=self.dry_run) - if self.optimize > 0: - byte_compile(files, optimize=self.optimize, - force=self.force, prefix=install_root, - verbose=self.verbose, dry_run=self.dry_run) - - - # -- Utility methods ----------------------------------------------- - - def _mutate_outputs(self, has_any, build_cmd, cmd_option, output_dir): - if not has_any: - return [] - - build_cmd = self.get_finalized_command(build_cmd) - build_files = build_cmd.get_outputs() - build_dir = getattr(build_cmd, cmd_option) - - prefix_len = len(build_dir) + len(os.sep) - outputs = [] - for file in build_files: - outputs.append(os.path.join(output_dir, file[prefix_len:])) - - return outputs - - def _bytecode_filenames(self, py_filenames): - bytecode_files = [] - for py_file in py_filenames: - # Since build_py handles package data installation, the - # list of outputs can contain more than just .py files. - # Make sure we only report bytecode for the .py files. - ext = os.path.splitext(os.path.normcase(py_file))[1] - if ext != PYTHON_SOURCE_EXTENSION: - continue - if self.compile: - bytecode_files.append(importlib.util.cache_from_source( - py_file, optimization='')) - if self.optimize > 0: - bytecode_files.append(importlib.util.cache_from_source( - py_file, optimization=self.optimize)) - - return bytecode_files - - - # -- External interface -------------------------------------------- - # (called by outsiders) - - def get_outputs(self): - """Return the list of files that would be installed if this command - were actually run. Not affected by the "dry-run" flag or whether - modules have actually been built yet. - """ - pure_outputs = \ - self._mutate_outputs(self.distribution.has_pure_modules(), - 'build_py', 'build_lib', - self.install_dir) - if self.compile: - bytecode_outputs = self._bytecode_filenames(pure_outputs) - else: - bytecode_outputs = [] - - ext_outputs = \ - self._mutate_outputs(self.distribution.has_ext_modules(), - 'build_ext', 'build_lib', - self.install_dir) - - return pure_outputs + bytecode_outputs + ext_outputs - - def get_inputs(self): - """Get the list of files that are input to this command, ie. the - files that get installed as they are named in the build tree. - The files in this list correspond one-to-one to the output - filenames returned by 'get_outputs()'. - """ - inputs = [] - - if self.distribution.has_pure_modules(): - build_py = self.get_finalized_command('build_py') - inputs.extend(build_py.get_outputs()) - - if self.distribution.has_ext_modules(): - build_ext = self.get_finalized_command('build_ext') - inputs.extend(build_ext.get_outputs()) - - return inputs diff --git a/python/Lib/distutils/command/install_scripts.py b/python/Lib/distutils/command/install_scripts.py deleted file mode 100644 index 8ef5d7e..0000000 --- a/python/Lib/distutils/command/install_scripts.py +++ /dev/null @@ -1,60 +0,0 @@ -"""distutils.command.install_scripts - -Implements the Distutils 'install_scripts' command, for installing -Python scripts.""" - -# contributed by Bastian Kleineidam - -import os -from distutils.core import Command -from distutils import log -from stat import ST_MODE - - -class install_scripts(Command): - - description = "install scripts (Python or otherwise)" - - user_options = [ - ('install-dir=', 'd', "directory to install scripts to"), - ('build-dir=','b', "build directory (where to install from)"), - ('force', 'f', "force installation (overwrite existing files)"), - ('skip-build', None, "skip the build steps"), - ] - - boolean_options = ['force', 'skip-build'] - - def initialize_options(self): - self.install_dir = None - self.force = 0 - self.build_dir = None - self.skip_build = None - - def finalize_options(self): - self.set_undefined_options('build', ('build_scripts', 'build_dir')) - self.set_undefined_options('install', - ('install_scripts', 'install_dir'), - ('force', 'force'), - ('skip_build', 'skip_build'), - ) - - def run(self): - if not self.skip_build: - self.run_command('build_scripts') - self.outfiles = self.copy_tree(self.build_dir, self.install_dir) - if os.name == 'posix': - # Set the executable bits (owner, group, and world) on - # all the scripts we just installed. - for file in self.get_outputs(): - if self.dry_run: - log.info("changing mode of %s", file) - else: - mode = ((os.stat(file)[ST_MODE]) | 0o555) & 0o7777 - log.info("changing mode of %s to %o", file, mode) - os.chmod(file, mode) - - def get_inputs(self): - return self.distribution.scripts or [] - - def get_outputs(self): - return self.outfiles or [] diff --git a/python/Lib/distutils/command/register.py b/python/Lib/distutils/command/register.py deleted file mode 100644 index c2494da..0000000 --- a/python/Lib/distutils/command/register.py +++ /dev/null @@ -1,304 +0,0 @@ -"""distutils.command.register - -Implements the Distutils 'register' command (register with the repository). -""" - -# created 2002/10/21, Richard Jones - -import getpass -import io -import urllib.parse, urllib.request -from warnings import warn - -from distutils.core import PyPIRCCommand -from distutils.errors import * -from distutils import log - -class register(PyPIRCCommand): - - description = ("register the distribution with the Python package index") - user_options = PyPIRCCommand.user_options + [ - ('list-classifiers', None, - 'list the valid Trove classifiers'), - ('strict', None , - 'Will stop the registering if the meta-data are not fully compliant') - ] - boolean_options = PyPIRCCommand.boolean_options + [ - 'verify', 'list-classifiers', 'strict'] - - sub_commands = [('check', lambda self: True)] - - def initialize_options(self): - PyPIRCCommand.initialize_options(self) - self.list_classifiers = 0 - self.strict = 0 - - def finalize_options(self): - PyPIRCCommand.finalize_options(self) - # setting options for the `check` subcommand - check_options = {'strict': ('register', self.strict), - 'restructuredtext': ('register', 1)} - self.distribution.command_options['check'] = check_options - - def run(self): - self.finalize_options() - self._set_config() - - # Run sub commands - for cmd_name in self.get_sub_commands(): - self.run_command(cmd_name) - - if self.dry_run: - self.verify_metadata() - elif self.list_classifiers: - self.classifiers() - else: - self.send_metadata() - - def check_metadata(self): - """Deprecated API.""" - warn("distutils.command.register.check_metadata is deprecated, \ - use the check command instead", PendingDeprecationWarning) - check = self.distribution.get_command_obj('check') - check.ensure_finalized() - check.strict = self.strict - check.restructuredtext = 1 - check.run() - - def _set_config(self): - ''' Reads the configuration file and set attributes. - ''' - config = self._read_pypirc() - if config != {}: - self.username = config['username'] - self.password = config['password'] - self.repository = config['repository'] - self.realm = config['realm'] - self.has_config = True - else: - if self.repository not in ('pypi', self.DEFAULT_REPOSITORY): - raise ValueError('%s not found in .pypirc' % self.repository) - if self.repository == 'pypi': - self.repository = self.DEFAULT_REPOSITORY - self.has_config = False - - def classifiers(self): - ''' Fetch the list of classifiers from the server. - ''' - url = self.repository+'?:action=list_classifiers' - response = urllib.request.urlopen(url) - log.info(self._read_pypi_response(response)) - - def verify_metadata(self): - ''' Send the metadata to the package index server to be checked. - ''' - # send the info to the server and report the result - (code, result) = self.post_to_server(self.build_post_data('verify')) - log.info('Server response (%s): %s', code, result) - - def send_metadata(self): - ''' Send the metadata to the package index server. - - Well, do the following: - 1. figure who the user is, and then - 2. send the data as a Basic auth'ed POST. - - First we try to read the username/password from $HOME/.pypirc, - which is a ConfigParser-formatted file with a section - [distutils] containing username and password entries (both - in clear text). Eg: - - [distutils] - index-servers = - pypi - - [pypi] - username: fred - password: sekrit - - Otherwise, to figure who the user is, we offer the user three - choices: - - 1. use existing login, - 2. register as a new user, or - 3. set the password to a random string and email the user. - - ''' - # see if we can short-cut and get the username/password from the - # config - if self.has_config: - choice = '1' - username = self.username - password = self.password - else: - choice = 'x' - username = password = '' - - # get the user's login info - choices = '1 2 3 4'.split() - while choice not in choices: - self.announce('''\ -We need to know who you are, so please choose either: - 1. use your existing login, - 2. register as a new user, - 3. have the server generate a new password for you (and email it to you), or - 4. quit -Your selection [default 1]: ''', log.INFO) - choice = input() - if not choice: - choice = '1' - elif choice not in choices: - print('Please choose one of the four options!') - - if choice == '1': - # get the username and password - while not username: - username = input('Username: ') - while not password: - password = getpass.getpass('Password: ') - - # set up the authentication - auth = urllib.request.HTTPPasswordMgr() - host = urllib.parse.urlparse(self.repository)[1] - auth.add_password(self.realm, host, username, password) - # send the info to the server and report the result - code, result = self.post_to_server(self.build_post_data('submit'), - auth) - self.announce('Server response (%s): %s' % (code, result), - log.INFO) - - # possibly save the login - if code == 200: - if self.has_config: - # sharing the password in the distribution instance - # so the upload command can reuse it - self.distribution.password = password - else: - self.announce(('I can store your PyPI login so future ' - 'submissions will be faster.'), log.INFO) - self.announce('(the login will be stored in %s)' % \ - self._get_rc_file(), log.INFO) - choice = 'X' - while choice.lower() not in 'yn': - choice = input('Save your login (y/N)?') - if not choice: - choice = 'n' - if choice.lower() == 'y': - self._store_pypirc(username, password) - - elif choice == '2': - data = {':action': 'user'} - data['name'] = data['password'] = data['email'] = '' - data['confirm'] = None - while not data['name']: - data['name'] = input('Username: ') - while data['password'] != data['confirm']: - while not data['password']: - data['password'] = getpass.getpass('Password: ') - while not data['confirm']: - data['confirm'] = getpass.getpass(' Confirm: ') - if data['password'] != data['confirm']: - data['password'] = '' - data['confirm'] = None - print("Password and confirm don't match!") - while not data['email']: - data['email'] = input(' EMail: ') - code, result = self.post_to_server(data) - if code != 200: - log.info('Server response (%s): %s', code, result) - else: - log.info('You will receive an email shortly.') - log.info(('Follow the instructions in it to ' - 'complete registration.')) - elif choice == '3': - data = {':action': 'password_reset'} - data['email'] = '' - while not data['email']: - data['email'] = input('Your email address: ') - code, result = self.post_to_server(data) - log.info('Server response (%s): %s', code, result) - - def build_post_data(self, action): - # figure the data to send - the metadata plus some additional - # information used by the package server - meta = self.distribution.metadata - data = { - ':action': action, - 'metadata_version' : '1.0', - 'name': meta.get_name(), - 'version': meta.get_version(), - 'summary': meta.get_description(), - 'home_page': meta.get_url(), - 'author': meta.get_contact(), - 'author_email': meta.get_contact_email(), - 'license': meta.get_licence(), - 'description': meta.get_long_description(), - 'keywords': meta.get_keywords(), - 'platform': meta.get_platforms(), - 'classifiers': meta.get_classifiers(), - 'download_url': meta.get_download_url(), - # PEP 314 - 'provides': meta.get_provides(), - 'requires': meta.get_requires(), - 'obsoletes': meta.get_obsoletes(), - } - if data['provides'] or data['requires'] or data['obsoletes']: - data['metadata_version'] = '1.1' - return data - - def post_to_server(self, data, auth=None): - ''' Post a query to the server, and return a string response. - ''' - if 'name' in data: - self.announce('Registering %s to %s' % (data['name'], - self.repository), - log.INFO) - # Build up the MIME payload for the urllib2 POST data - boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' - sep_boundary = '\n--' + boundary - end_boundary = sep_boundary + '--' - body = io.StringIO() - for key, value in data.items(): - # handle multiple entries for the same name - if type(value) not in (type([]), type( () )): - value = [value] - for value in value: - value = str(value) - body.write(sep_boundary) - body.write('\nContent-Disposition: form-data; name="%s"'%key) - body.write("\n\n") - body.write(value) - if value and value[-1] == '\r': - body.write('\n') # write an extra newline (lurve Macs) - body.write(end_boundary) - body.write("\n") - body = body.getvalue().encode("utf-8") - - # build the Request - headers = { - 'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'%boundary, - 'Content-length': str(len(body)) - } - req = urllib.request.Request(self.repository, body, headers) - - # handle HTTP and include the Basic Auth handler - opener = urllib.request.build_opener( - urllib.request.HTTPBasicAuthHandler(password_mgr=auth) - ) - data = '' - try: - result = opener.open(req) - except urllib.error.HTTPError as e: - if self.show_response: - data = e.fp.read() - result = e.code, e.msg - except urllib.error.URLError as e: - result = 500, str(e) - else: - if self.show_response: - data = self._read_pypi_response(result) - result = 200, 'OK' - if self.show_response: - msg = '\n'.join(('-' * 75, data, '-' * 75)) - self.announce(msg, log.INFO) - return result diff --git a/python/Lib/distutils/command/sdist.py b/python/Lib/distutils/command/sdist.py deleted file mode 100644 index 8b81f9b..0000000 --- a/python/Lib/distutils/command/sdist.py +++ /dev/null @@ -1,494 +0,0 @@ -"""distutils.command.sdist - -Implements the Distutils 'sdist' command (create a source distribution).""" - -import os -import sys -from glob import glob -from warnings import warn - -from distutils.core import Command -from distutils import dir_util -from distutils import file_util -from distutils import archive_util -from distutils.text_file import TextFile -from distutils.filelist import FileList -from distutils import log -from distutils.util import convert_path -from distutils.errors import DistutilsTemplateError, DistutilsOptionError - - -def show_formats(): - """Print all possible values for the 'formats' option (used by - the "--help-formats" command-line option). - """ - from distutils.fancy_getopt import FancyGetopt - from distutils.archive_util import ARCHIVE_FORMATS - formats = [] - for format in ARCHIVE_FORMATS.keys(): - formats.append(("formats=" + format, None, - ARCHIVE_FORMATS[format][2])) - formats.sort() - FancyGetopt(formats).print_help( - "List of available source distribution formats:") - - -class sdist(Command): - - description = "create a source distribution (tarball, zip file, etc.)" - - def checking_metadata(self): - """Callable used for the check sub-command. - - Placed here so user_options can view it""" - return self.metadata_check - - user_options = [ - ('template=', 't', - "name of manifest template file [default: MANIFEST.in]"), - ('manifest=', 'm', - "name of manifest file [default: MANIFEST]"), - ('use-defaults', None, - "include the default file set in the manifest " - "[default; disable with --no-defaults]"), - ('no-defaults', None, - "don't include the default file set"), - ('prune', None, - "specifically exclude files/directories that should not be " - "distributed (build tree, RCS/CVS dirs, etc.) " - "[default; disable with --no-prune]"), - ('no-prune', None, - "don't automatically exclude anything"), - ('manifest-only', 'o', - "just regenerate the manifest and then stop " - "(implies --force-manifest)"), - ('force-manifest', 'f', - "forcibly regenerate the manifest and carry on as usual. " - "Deprecated: now the manifest is always regenerated."), - ('formats=', None, - "formats for source distribution (comma-separated list)"), - ('keep-temp', 'k', - "keep the distribution tree around after creating " + - "archive file(s)"), - ('dist-dir=', 'd', - "directory to put the source distribution archive(s) in " - "[default: dist]"), - ('metadata-check', None, - "Ensure that all required elements of meta-data " - "are supplied. Warn if any missing. [default]"), - ('owner=', 'u', - "Owner name used when creating a tar file [default: current user]"), - ('group=', 'g', - "Group name used when creating a tar file [default: current group]"), - ] - - boolean_options = ['use-defaults', 'prune', - 'manifest-only', 'force-manifest', - 'keep-temp', 'metadata-check'] - - help_options = [ - ('help-formats', None, - "list available distribution formats", show_formats), - ] - - negative_opt = {'no-defaults': 'use-defaults', - 'no-prune': 'prune' } - - sub_commands = [('check', checking_metadata)] - - READMES = ('README', 'README.txt', 'README.rst') - - def initialize_options(self): - # 'template' and 'manifest' are, respectively, the names of - # the manifest template and manifest file. - self.template = None - self.manifest = None - - # 'use_defaults': if true, we will include the default file set - # in the manifest - self.use_defaults = 1 - self.prune = 1 - - self.manifest_only = 0 - self.force_manifest = 0 - - self.formats = ['gztar'] - self.keep_temp = 0 - self.dist_dir = None - - self.archive_files = None - self.metadata_check = 1 - self.owner = None - self.group = None - - def finalize_options(self): - if self.manifest is None: - self.manifest = "MANIFEST" - if self.template is None: - self.template = "MANIFEST.in" - - self.ensure_string_list('formats') - - bad_format = archive_util.check_archive_formats(self.formats) - if bad_format: - raise DistutilsOptionError( - "unknown archive format '%s'" % bad_format) - - if self.dist_dir is None: - self.dist_dir = "dist" - - def run(self): - # 'filelist' contains the list of files that will make up the - # manifest - self.filelist = FileList() - - # Run sub commands - for cmd_name in self.get_sub_commands(): - self.run_command(cmd_name) - - # Do whatever it takes to get the list of files to process - # (process the manifest template, read an existing manifest, - # whatever). File list is accumulated in 'self.filelist'. - self.get_file_list() - - # If user just wanted us to regenerate the manifest, stop now. - if self.manifest_only: - return - - # Otherwise, go ahead and create the source distribution tarball, - # or zipfile, or whatever. - self.make_distribution() - - def check_metadata(self): - """Deprecated API.""" - warn("distutils.command.sdist.check_metadata is deprecated, \ - use the check command instead", PendingDeprecationWarning) - check = self.distribution.get_command_obj('check') - check.ensure_finalized() - check.run() - - def get_file_list(self): - """Figure out the list of files to include in the source - distribution, and put it in 'self.filelist'. This might involve - reading the manifest template (and writing the manifest), or just - reading the manifest, or just using the default file set -- it all - depends on the user's options. - """ - # new behavior when using a template: - # the file list is recalculated every time because - # even if MANIFEST.in or setup.py are not changed - # the user might have added some files in the tree that - # need to be included. - # - # This makes --force the default and only behavior with templates. - template_exists = os.path.isfile(self.template) - if not template_exists and self._manifest_is_not_generated(): - self.read_manifest() - self.filelist.sort() - self.filelist.remove_duplicates() - return - - if not template_exists: - self.warn(("manifest template '%s' does not exist " + - "(using default file list)") % - self.template) - self.filelist.findall() - - if self.use_defaults: - self.add_defaults() - - if template_exists: - self.read_template() - - if self.prune: - self.prune_file_list() - - self.filelist.sort() - self.filelist.remove_duplicates() - self.write_manifest() - - def add_defaults(self): - """Add all the default files to self.filelist: - - README or README.txt - - setup.py - - test/test*.py - - all pure Python modules mentioned in setup script - - all files pointed by package_data (build_py) - - all files defined in data_files. - - all files defined as scripts. - - all C sources listed as part of extensions or C libraries - in the setup script (doesn't catch C headers!) - Warns if (README or README.txt) or setup.py are missing; everything - else is optional. - """ - self._add_defaults_standards() - self._add_defaults_optional() - self._add_defaults_python() - self._add_defaults_data_files() - self._add_defaults_ext() - self._add_defaults_c_libs() - self._add_defaults_scripts() - - @staticmethod - def _cs_path_exists(fspath): - """ - Case-sensitive path existence check - - >>> sdist._cs_path_exists(__file__) - True - >>> sdist._cs_path_exists(__file__.upper()) - False - """ - if not os.path.exists(fspath): - return False - # make absolute so we always have a directory - abspath = os.path.abspath(fspath) - directory, filename = os.path.split(abspath) - return filename in os.listdir(directory) - - def _add_defaults_standards(self): - standards = [self.READMES, self.distribution.script_name] - for fn in standards: - if isinstance(fn, tuple): - alts = fn - got_it = False - for fn in alts: - if self._cs_path_exists(fn): - got_it = True - self.filelist.append(fn) - break - - if not got_it: - self.warn("standard file not found: should have one of " + - ', '.join(alts)) - else: - if self._cs_path_exists(fn): - self.filelist.append(fn) - else: - self.warn("standard file '%s' not found" % fn) - - def _add_defaults_optional(self): - optional = ['test/test*.py', 'setup.cfg'] - for pattern in optional: - files = filter(os.path.isfile, glob(pattern)) - self.filelist.extend(files) - - def _add_defaults_python(self): - # build_py is used to get: - # - python modules - # - files defined in package_data - build_py = self.get_finalized_command('build_py') - - # getting python files - if self.distribution.has_pure_modules(): - self.filelist.extend(build_py.get_source_files()) - - # getting package_data files - # (computed in build_py.data_files by build_py.finalize_options) - for pkg, src_dir, build_dir, filenames in build_py.data_files: - for filename in filenames: - self.filelist.append(os.path.join(src_dir, filename)) - - def _add_defaults_data_files(self): - # getting distribution.data_files - if self.distribution.has_data_files(): - for item in self.distribution.data_files: - if isinstance(item, str): - # plain file - item = convert_path(item) - if os.path.isfile(item): - self.filelist.append(item) - else: - # a (dirname, filenames) tuple - dirname, filenames = item - for f in filenames: - f = convert_path(f) - if os.path.isfile(f): - self.filelist.append(f) - - def _add_defaults_ext(self): - if self.distribution.has_ext_modules(): - build_ext = self.get_finalized_command('build_ext') - self.filelist.extend(build_ext.get_source_files()) - - def _add_defaults_c_libs(self): - if self.distribution.has_c_libraries(): - build_clib = self.get_finalized_command('build_clib') - self.filelist.extend(build_clib.get_source_files()) - - def _add_defaults_scripts(self): - if self.distribution.has_scripts(): - build_scripts = self.get_finalized_command('build_scripts') - self.filelist.extend(build_scripts.get_source_files()) - - def read_template(self): - """Read and parse manifest template file named by self.template. - - (usually "MANIFEST.in") The parsing and processing is done by - 'self.filelist', which updates itself accordingly. - """ - log.info("reading manifest template '%s'", self.template) - template = TextFile(self.template, strip_comments=1, skip_blanks=1, - join_lines=1, lstrip_ws=1, rstrip_ws=1, - collapse_join=1) - - try: - while True: - line = template.readline() - if line is None: # end of file - break - - try: - self.filelist.process_template_line(line) - # the call above can raise a DistutilsTemplateError for - # malformed lines, or a ValueError from the lower-level - # convert_path function - except (DistutilsTemplateError, ValueError) as msg: - self.warn("%s, line %d: %s" % (template.filename, - template.current_line, - msg)) - finally: - template.close() - - def prune_file_list(self): - """Prune off branches that might slip into the file list as created - by 'read_template()', but really don't belong there: - * the build tree (typically "build") - * the release tree itself (only an issue if we ran "sdist" - previously with --keep-temp, or it aborted) - * any RCS, CVS, .svn, .hg, .git, .bzr, _darcs directories - """ - build = self.get_finalized_command('build') - base_dir = self.distribution.get_fullname() - - self.filelist.exclude_pattern(None, prefix=build.build_base) - self.filelist.exclude_pattern(None, prefix=base_dir) - - if sys.platform == 'win32': - seps = r'/|\\' - else: - seps = '/' - - vcs_dirs = ['RCS', 'CVS', r'\.svn', r'\.hg', r'\.git', r'\.bzr', - '_darcs'] - vcs_ptrn = r'(^|%s)(%s)(%s).*' % (seps, '|'.join(vcs_dirs), seps) - self.filelist.exclude_pattern(vcs_ptrn, is_regex=1) - - def write_manifest(self): - """Write the file list in 'self.filelist' (presumably as filled in - by 'add_defaults()' and 'read_template()') to the manifest file - named by 'self.manifest'. - """ - if self._manifest_is_not_generated(): - log.info("not writing to manually maintained " - "manifest file '%s'" % self.manifest) - return - - content = self.filelist.files[:] - content.insert(0, '# file GENERATED by distutils, do NOT edit') - self.execute(file_util.write_file, (self.manifest, content), - "writing manifest file '%s'" % self.manifest) - - def _manifest_is_not_generated(self): - # check for special comment used in 3.1.3 and higher - if not os.path.isfile(self.manifest): - return False - - fp = open(self.manifest) - try: - first_line = fp.readline() - finally: - fp.close() - return first_line != '# file GENERATED by distutils, do NOT edit\n' - - def read_manifest(self): - """Read the manifest file (named by 'self.manifest') and use it to - fill in 'self.filelist', the list of files to include in the source - distribution. - """ - log.info("reading manifest file '%s'", self.manifest) - with open(self.manifest) as manifest: - for line in manifest: - # ignore comments and blank lines - line = line.strip() - if line.startswith('#') or not line: - continue - self.filelist.append(line) - - def make_release_tree(self, base_dir, files): - """Create the directory tree that will become the source - distribution archive. All directories implied by the filenames in - 'files' are created under 'base_dir', and then we hard link or copy - (if hard linking is unavailable) those files into place. - Essentially, this duplicates the developer's source tree, but in a - directory named after the distribution, containing only the files - to be distributed. - """ - # Create all the directories under 'base_dir' necessary to - # put 'files' there; the 'mkpath()' is just so we don't die - # if the manifest happens to be empty. - self.mkpath(base_dir) - dir_util.create_tree(base_dir, files, dry_run=self.dry_run) - - # And walk over the list of files, either making a hard link (if - # os.link exists) to each one that doesn't already exist in its - # corresponding location under 'base_dir', or copying each file - # that's out-of-date in 'base_dir'. (Usually, all files will be - # out-of-date, because by default we blow away 'base_dir' when - # we're done making the distribution archives.) - - if hasattr(os, 'link'): # can make hard links on this system - link = 'hard' - msg = "making hard links in %s..." % base_dir - else: # nope, have to copy - link = None - msg = "copying files to %s..." % base_dir - - if not files: - log.warn("no files to distribute -- empty manifest?") - else: - log.info(msg) - for file in files: - if not os.path.isfile(file): - log.warn("'%s' not a regular file -- skipping", file) - else: - dest = os.path.join(base_dir, file) - self.copy_file(file, dest, link=link) - - self.distribution.metadata.write_pkg_info(base_dir) - - def make_distribution(self): - """Create the source distribution(s). First, we create the release - tree with 'make_release_tree()'; then, we create all required - archive files (according to 'self.formats') from the release tree. - Finally, we clean up by blowing away the release tree (unless - 'self.keep_temp' is true). The list of archive files created is - stored so it can be retrieved later by 'get_archive_files()'. - """ - # Don't warn about missing meta-data here -- should be (and is!) - # done elsewhere. - base_dir = self.distribution.get_fullname() - base_name = os.path.join(self.dist_dir, base_dir) - - self.make_release_tree(base_dir, self.filelist.files) - archive_files = [] # remember names of files we create - # tar archive must be created last to avoid overwrite and remove - if 'tar' in self.formats: - self.formats.append(self.formats.pop(self.formats.index('tar'))) - - for fmt in self.formats: - file = self.make_archive(base_name, fmt, base_dir=base_dir, - owner=self.owner, group=self.group) - archive_files.append(file) - self.distribution.dist_files.append(('sdist', '', file)) - - self.archive_files = archive_files - - if not self.keep_temp: - dir_util.remove_tree(base_dir, dry_run=self.dry_run) - - def get_archive_files(self): - """Return the list of archive files created when the command - was run, or None if the command hasn't run yet. - """ - return self.archive_files diff --git a/python/Lib/distutils/command/upload.py b/python/Lib/distutils/command/upload.py deleted file mode 100644 index b2ef9a1..0000000 --- a/python/Lib/distutils/command/upload.py +++ /dev/null @@ -1,215 +0,0 @@ -""" -distutils.command.upload - -Implements the Distutils 'upload' subcommand (upload package to a package -index). -""" - -import os -import io -import hashlib -from base64 import standard_b64encode -from urllib.error import HTTPError -from urllib.request import urlopen, Request -from urllib.parse import urlparse -from distutils.errors import DistutilsError, DistutilsOptionError -from distutils.core import PyPIRCCommand -from distutils.spawn import spawn -from distutils import log - - -# PyPI Warehouse supports MD5, SHA256, and Blake2 (blake2-256) -# https://bugs.python.org/issue40698 -_FILE_CONTENT_DIGESTS = { - "md5_digest": getattr(hashlib, "md5", None), - "sha256_digest": getattr(hashlib, "sha256", None), - "blake2_256_digest": getattr(hashlib, "blake2b", None), -} - - -class upload(PyPIRCCommand): - - description = "upload binary package to PyPI" - - user_options = PyPIRCCommand.user_options + [ - ('sign', 's', - 'sign files to upload using gpg'), - ('identity=', 'i', 'GPG identity used to sign files'), - ] - - boolean_options = PyPIRCCommand.boolean_options + ['sign'] - - def initialize_options(self): - PyPIRCCommand.initialize_options(self) - self.username = '' - self.password = '' - self.show_response = 0 - self.sign = False - self.identity = None - - def finalize_options(self): - PyPIRCCommand.finalize_options(self) - if self.identity and not self.sign: - raise DistutilsOptionError( - "Must use --sign for --identity to have meaning" - ) - config = self._read_pypirc() - if config != {}: - self.username = config['username'] - self.password = config['password'] - self.repository = config['repository'] - self.realm = config['realm'] - - # getting the password from the distribution - # if previously set by the register command - if not self.password and self.distribution.password: - self.password = self.distribution.password - - def run(self): - if not self.distribution.dist_files: - msg = ("Must create and upload files in one command " - "(e.g. setup.py sdist upload)") - raise DistutilsOptionError(msg) - for command, pyversion, filename in self.distribution.dist_files: - self.upload_file(command, pyversion, filename) - - def upload_file(self, command, pyversion, filename): - # Makes sure the repository URL is compliant - schema, netloc, url, params, query, fragments = \ - urlparse(self.repository) - if params or query or fragments: - raise AssertionError("Incompatible url %s" % self.repository) - - if schema not in ('http', 'https'): - raise AssertionError("unsupported schema " + schema) - - # Sign if requested - if self.sign: - gpg_args = ["gpg", "--detach-sign", "-a", filename] - if self.identity: - gpg_args[2:2] = ["--local-user", self.identity] - spawn(gpg_args, - dry_run=self.dry_run) - - # Fill in the data - send all the meta-data in case we need to - # register a new release - f = open(filename,'rb') - try: - content = f.read() - finally: - f.close() - - meta = self.distribution.metadata - data = { - # action - ':action': 'file_upload', - 'protocol_version': '1', - - # identify release - 'name': meta.get_name(), - 'version': meta.get_version(), - - # file content - 'content': (os.path.basename(filename),content), - 'filetype': command, - 'pyversion': pyversion, - - # additional meta-data - 'metadata_version': '1.0', - 'summary': meta.get_description(), - 'home_page': meta.get_url(), - 'author': meta.get_contact(), - 'author_email': meta.get_contact_email(), - 'license': meta.get_licence(), - 'description': meta.get_long_description(), - 'keywords': meta.get_keywords(), - 'platform': meta.get_platforms(), - 'classifiers': meta.get_classifiers(), - 'download_url': meta.get_download_url(), - # PEP 314 - 'provides': meta.get_provides(), - 'requires': meta.get_requires(), - 'obsoletes': meta.get_obsoletes(), - } - - data['comment'] = '' - - # file content digests - for digest_name, digest_cons in _FILE_CONTENT_DIGESTS.items(): - if digest_cons is None: - continue - try: - data[digest_name] = digest_cons(content).hexdigest() - except ValueError: - # hash digest not available or blocked by security policy - pass - - if self.sign: - with open(filename + ".asc", "rb") as f: - data['gpg_signature'] = (os.path.basename(filename) + ".asc", - f.read()) - - # set up the authentication - user_pass = (self.username + ":" + self.password).encode('ascii') - # The exact encoding of the authentication string is debated. - # Anyway PyPI only accepts ascii for both username or password. - auth = "Basic " + standard_b64encode(user_pass).decode('ascii') - - # Build up the MIME payload for the POST data - boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' - sep_boundary = b'\r\n--' + boundary.encode('ascii') - end_boundary = sep_boundary + b'--\r\n' - body = io.BytesIO() - for key, value in data.items(): - title = '\r\nContent-Disposition: form-data; name="%s"' % key - # handle multiple entries for the same name - if not isinstance(value, list): - value = [value] - for value in value: - if type(value) is tuple: - title += '; filename="%s"' % value[0] - value = value[1] - else: - value = str(value).encode('utf-8') - body.write(sep_boundary) - body.write(title.encode('utf-8')) - body.write(b"\r\n\r\n") - body.write(value) - body.write(end_boundary) - body = body.getvalue() - - msg = "Submitting %s to %s" % (filename, self.repository) - self.announce(msg, log.INFO) - - # build the Request - headers = { - 'Content-type': 'multipart/form-data; boundary=%s' % boundary, - 'Content-length': str(len(body)), - 'Authorization': auth, - } - - request = Request(self.repository, data=body, - headers=headers) - # send the data - try: - result = urlopen(request) - status = result.getcode() - reason = result.msg - except HTTPError as e: - status = e.code - reason = e.msg - except OSError as e: - self.announce(str(e), log.ERROR) - raise - - if status == 200: - self.announce('Server response (%s): %s' % (status, reason), - log.INFO) - if self.show_response: - text = self._read_pypi_response(result) - msg = '\n'.join(('-' * 75, text, '-' * 75)) - self.announce(msg, log.INFO) - else: - msg = 'Upload failed (%s): %s' % (status, reason) - self.announce(msg, log.ERROR) - raise DistutilsError(msg) diff --git a/python/Lib/distutils/config.py b/python/Lib/distutils/config.py deleted file mode 100644 index bce57d8..0000000 --- a/python/Lib/distutils/config.py +++ /dev/null @@ -1,133 +0,0 @@ -"""distutils.pypirc - -Provides the PyPIRCCommand class, the base class for the command classes -that uses .pypirc in the distutils.command package. -""" -import os -from configparser import RawConfigParser -import warnings - -from distutils.cmd import Command - -DEFAULT_PYPIRC = """\ -[distutils] -index-servers = - pypi - -[pypi] -username:%s -password:%s -""" - -class PyPIRCCommand(Command): - """Base command that knows how to handle the .pypirc file - """ - DEFAULT_REPOSITORY = 'https://upload.pypi.org/legacy/' - DEFAULT_REALM = 'pypi' - repository = None - realm = None - - user_options = [ - ('repository=', 'r', - "url of repository [default: %s]" % \ - DEFAULT_REPOSITORY), - ('show-response', None, - 'display full response text from server')] - - boolean_options = ['show-response'] - - def _get_rc_file(self): - """Returns rc file path.""" - return os.path.join(os.path.expanduser('~'), '.pypirc') - - def _store_pypirc(self, username, password): - """Creates a default .pypirc file.""" - rc = self._get_rc_file() - with os.fdopen(os.open(rc, os.O_CREAT | os.O_WRONLY, 0o600), 'w') as f: - f.write(DEFAULT_PYPIRC % (username, password)) - - def _read_pypirc(self): - """Reads the .pypirc file.""" - rc = self._get_rc_file() - if os.path.exists(rc): - self.announce('Using PyPI login from %s' % rc) - repository = self.repository or self.DEFAULT_REPOSITORY - - config = RawConfigParser() - config.read(rc) - sections = config.sections() - if 'distutils' in sections: - # let's get the list of servers - index_servers = config.get('distutils', 'index-servers') - _servers = [server.strip() for server in - index_servers.split('\n') - if server.strip() != ''] - if _servers == []: - # nothing set, let's try to get the default pypi - if 'pypi' in sections: - _servers = ['pypi'] - else: - # the file is not properly defined, returning - # an empty dict - return {} - for server in _servers: - current = {'server': server} - current['username'] = config.get(server, 'username') - - # optional params - for key, default in (('repository', - self.DEFAULT_REPOSITORY), - ('realm', self.DEFAULT_REALM), - ('password', None)): - if config.has_option(server, key): - current[key] = config.get(server, key) - else: - current[key] = default - - # work around people having "repository" for the "pypi" - # section of their config set to the HTTP (rather than - # HTTPS) URL - if (server == 'pypi' and - repository in (self.DEFAULT_REPOSITORY, 'pypi')): - current['repository'] = self.DEFAULT_REPOSITORY - return current - - if (current['server'] == repository or - current['repository'] == repository): - return current - elif 'server-login' in sections: - # old format - server = 'server-login' - if config.has_option(server, 'repository'): - repository = config.get(server, 'repository') - else: - repository = self.DEFAULT_REPOSITORY - return {'username': config.get(server, 'username'), - 'password': config.get(server, 'password'), - 'repository': repository, - 'server': server, - 'realm': self.DEFAULT_REALM} - - return {} - - def _read_pypi_response(self, response): - """Read and decode a PyPI HTTP response.""" - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - import cgi - content_type = response.getheader('content-type', 'text/plain') - encoding = cgi.parse_header(content_type)[1].get('charset', 'ascii') - return response.read().decode(encoding) - - def initialize_options(self): - """Initialize options.""" - self.repository = None - self.realm = None - self.show_response = 0 - - def finalize_options(self): - """Finalizes options.""" - if self.repository is None: - self.repository = self.DEFAULT_REPOSITORY - if self.realm is None: - self.realm = self.DEFAULT_REALM diff --git a/python/Lib/distutils/core.py b/python/Lib/distutils/core.py deleted file mode 100644 index fc5341b..0000000 --- a/python/Lib/distutils/core.py +++ /dev/null @@ -1,234 +0,0 @@ -"""distutils.core - -The only module that needs to be imported to use the Distutils; provides -the 'setup' function (which is to be called from the setup script). Also -indirectly provides the Distribution and Command classes, although they are -really defined in distutils.dist and distutils.cmd. -""" - -import os -import sys - -from distutils.debug import DEBUG -from distutils.errors import * - -# Mainly import these so setup scripts can "from distutils.core import" them. -from distutils.dist import Distribution -from distutils.cmd import Command -from distutils.config import PyPIRCCommand -from distutils.extension import Extension - -# This is a barebones help message generated displayed when the user -# runs the setup script with no arguments at all. More useful help -# is generated with various --help options: global help, list commands, -# and per-command help. -USAGE = """\ -usage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] - or: %(script)s --help [cmd1 cmd2 ...] - or: %(script)s --help-commands - or: %(script)s cmd --help -""" - -def gen_usage (script_name): - script = os.path.basename(script_name) - return USAGE % vars() - - -# Some mild magic to control the behaviour of 'setup()' from 'run_setup()'. -_setup_stop_after = None -_setup_distribution = None - -# Legal keyword arguments for the setup() function -setup_keywords = ('distclass', 'script_name', 'script_args', 'options', - 'name', 'version', 'author', 'author_email', - 'maintainer', 'maintainer_email', 'url', 'license', - 'description', 'long_description', 'keywords', - 'platforms', 'classifiers', 'download_url', - 'requires', 'provides', 'obsoletes', - ) - -# Legal keyword arguments for the Extension constructor -extension_keywords = ('name', 'sources', 'include_dirs', - 'define_macros', 'undef_macros', - 'library_dirs', 'libraries', 'runtime_library_dirs', - 'extra_objects', 'extra_compile_args', 'extra_link_args', - 'swig_opts', 'export_symbols', 'depends', 'language') - -def setup (**attrs): - """The gateway to the Distutils: do everything your setup script needs - to do, in a highly flexible and user-driven way. Briefly: create a - Distribution instance; find and parse config files; parse the command - line; run each Distutils command found there, customized by the options - supplied to 'setup()' (as keyword arguments), in config files, and on - the command line. - - The Distribution instance might be an instance of a class supplied via - the 'distclass' keyword argument to 'setup'; if no such class is - supplied, then the Distribution class (in dist.py) is instantiated. - All other arguments to 'setup' (except for 'cmdclass') are used to set - attributes of the Distribution instance. - - The 'cmdclass' argument, if supplied, is a dictionary mapping command - names to command classes. Each command encountered on the command line - will be turned into a command class, which is in turn instantiated; any - class found in 'cmdclass' is used in place of the default, which is - (for command 'foo_bar') class 'foo_bar' in module - 'distutils.command.foo_bar'. The command class must provide a - 'user_options' attribute which is a list of option specifiers for - 'distutils.fancy_getopt'. Any command-line options between the current - and the next command are used to set attributes of the current command - object. - - When the entire command-line has been successfully parsed, calls the - 'run()' method on each command object in turn. This method will be - driven entirely by the Distribution object (which each command object - has a reference to, thanks to its constructor), and the - command-specific options that became attributes of each command - object. - """ - - global _setup_stop_after, _setup_distribution - - # Determine the distribution class -- either caller-supplied or - # our Distribution (see below). - klass = attrs.get('distclass') - if klass: - del attrs['distclass'] - else: - klass = Distribution - - if 'script_name' not in attrs: - attrs['script_name'] = os.path.basename(sys.argv[0]) - if 'script_args' not in attrs: - attrs['script_args'] = sys.argv[1:] - - # Create the Distribution instance, using the remaining arguments - # (ie. everything except distclass) to initialize it - try: - _setup_distribution = dist = klass(attrs) - except DistutilsSetupError as msg: - if 'name' not in attrs: - raise SystemExit("error in setup command: %s" % msg) - else: - raise SystemExit("error in %s setup command: %s" % \ - (attrs['name'], msg)) - - if _setup_stop_after == "init": - return dist - - # Find and parse the config file(s): they will override options from - # the setup script, but be overridden by the command line. - dist.parse_config_files() - - if DEBUG: - print("options (after parsing config files):") - dist.dump_option_dicts() - - if _setup_stop_after == "config": - return dist - - # Parse the command line and override config files; any - # command-line errors are the end user's fault, so turn them into - # SystemExit to suppress tracebacks. - try: - ok = dist.parse_command_line() - except DistutilsArgError as msg: - raise SystemExit(gen_usage(dist.script_name) + "\nerror: %s" % msg) - - if DEBUG: - print("options (after parsing command line):") - dist.dump_option_dicts() - - if _setup_stop_after == "commandline": - return dist - - # And finally, run all the commands found on the command line. - if ok: - try: - dist.run_commands() - except KeyboardInterrupt: - raise SystemExit("interrupted") - except OSError as exc: - if DEBUG: - sys.stderr.write("error: %s\n" % (exc,)) - raise - else: - raise SystemExit("error: %s" % (exc,)) - - except (DistutilsError, - CCompilerError) as msg: - if DEBUG: - raise - else: - raise SystemExit("error: " + str(msg)) - - return dist - -# setup () - - -def run_setup (script_name, script_args=None, stop_after="run"): - """Run a setup script in a somewhat controlled environment, and - return the Distribution instance that drives things. This is useful - if you need to find out the distribution meta-data (passed as - keyword args from 'script' to 'setup()', or the contents of the - config files or command-line. - - 'script_name' is a file that will be read and run with 'exec()'; - 'sys.argv[0]' will be replaced with 'script' for the duration of the - call. 'script_args' is a list of strings; if supplied, - 'sys.argv[1:]' will be replaced by 'script_args' for the duration of - the call. - - 'stop_after' tells 'setup()' when to stop processing; possible - values: - init - stop after the Distribution instance has been created and - populated with the keyword arguments to 'setup()' - config - stop after config files have been parsed (and their data - stored in the Distribution instance) - commandline - stop after the command-line ('sys.argv[1:]' or 'script_args') - have been parsed (and the data stored in the Distribution) - run [default] - stop after all commands have been run (the same as if 'setup()' - had been called in the usual way - - Returns the Distribution instance, which provides all information - used to drive the Distutils. - """ - if stop_after not in ('init', 'config', 'commandline', 'run'): - raise ValueError("invalid value for 'stop_after': %r" % (stop_after,)) - - global _setup_stop_after, _setup_distribution - _setup_stop_after = stop_after - - save_argv = sys.argv.copy() - g = {'__file__': script_name} - try: - try: - sys.argv[0] = script_name - if script_args is not None: - sys.argv[1:] = script_args - with open(script_name, 'rb') as f: - exec(f.read(), g) - finally: - sys.argv = save_argv - _setup_stop_after = None - except SystemExit: - # Hmm, should we do something if exiting with a non-zero code - # (ie. error)? - pass - - if _setup_distribution is None: - raise RuntimeError(("'distutils.core.setup()' was never called -- " - "perhaps '%s' is not a Distutils setup script?") % \ - script_name) - - # I wonder if the setup script's namespace -- g and l -- would be of - # any interest to callers? - #print "_setup_distribution:", _setup_distribution - return _setup_distribution - -# run_setup () diff --git a/python/Lib/distutils/cygwinccompiler.py b/python/Lib/distutils/cygwinccompiler.py deleted file mode 100644 index 4139ab1..0000000 --- a/python/Lib/distutils/cygwinccompiler.py +++ /dev/null @@ -1,403 +0,0 @@ -"""distutils.cygwinccompiler - -Provides the CygwinCCompiler class, a subclass of UnixCCompiler that -handles the Cygwin port of the GNU C compiler to Windows. It also contains -the Mingw32CCompiler class which handles the mingw32 port of GCC (same as -cygwin in no-cygwin mode). -""" - -# problems: -# -# * if you use a msvc compiled python version (1.5.2) -# 1. you have to insert a __GNUC__ section in its config.h -# 2. you have to generate an import library for its dll -# - create a def-file for python??.dll -# - create an import library using -# dlltool --dllname python15.dll --def python15.def \ -# --output-lib libpython15.a -# -# see also http://starship.python.net/crew/kernr/mingw32/Notes.html -# -# * We put export_symbols in a def-file, and don't use -# --export-all-symbols because it doesn't worked reliable in some -# tested configurations. And because other windows compilers also -# need their symbols specified this no serious problem. -# -# tested configurations: -# -# * cygwin gcc 2.91.57/ld 2.9.4/dllwrap 0.2.4 works -# (after patching python's config.h and for C++ some other include files) -# see also http://starship.python.net/crew/kernr/mingw32/Notes.html -# * mingw32 gcc 2.95.2/ld 2.9.4/dllwrap 0.2.4 works -# (ld doesn't support -shared, so we use dllwrap) -# * cygwin gcc 2.95.2/ld 2.10.90/dllwrap 2.10.90 works now -# - its dllwrap doesn't work, there is a bug in binutils 2.10.90 -# see also http://sources.redhat.com/ml/cygwin/2000-06/msg01274.html -# - using gcc -mdll instead dllwrap doesn't work without -static because -# it tries to link against dlls instead their import libraries. (If -# it finds the dll first.) -# By specifying -static we force ld to link against the import libraries, -# this is windows standard and there are normally not the necessary symbols -# in the dlls. -# *** only the version of June 2000 shows these problems -# * cygwin gcc 3.2/ld 2.13.90 works -# (ld supports -shared) -# * mingw gcc 3.2/ld 2.13 works -# (ld supports -shared) - -import os -import sys -import copy -from subprocess import Popen, PIPE, check_output -import re - -from distutils.unixccompiler import UnixCCompiler -from distutils.file_util import write_file -from distutils.errors import (DistutilsExecError, CCompilerError, - CompileError, UnknownFileError) -from distutils.version import LooseVersion -from distutils.spawn import find_executable - -def get_msvcr(): - """Include the appropriate MSVC runtime library if Python was built - with MSVC 7.0 or later. - """ - msc_pos = sys.version.find('MSC v.') - if msc_pos != -1: - msc_ver = sys.version[msc_pos+6:msc_pos+10] - if msc_ver == '1300': - # MSVC 7.0 - return ['msvcr70'] - elif msc_ver == '1310': - # MSVC 7.1 - return ['msvcr71'] - elif msc_ver == '1400': - # VS2005 / MSVC 8.0 - return ['msvcr80'] - elif msc_ver == '1500': - # VS2008 / MSVC 9.0 - return ['msvcr90'] - elif msc_ver == '1600': - # VS2010 / MSVC 10.0 - return ['msvcr100'] - else: - raise ValueError("Unknown MS Compiler version %s " % msc_ver) - - -class CygwinCCompiler(UnixCCompiler): - """ Handles the Cygwin port of the GNU C compiler to Windows. - """ - compiler_type = 'cygwin' - obj_extension = ".o" - static_lib_extension = ".a" - shared_lib_extension = ".dll" - static_lib_format = "lib%s%s" - shared_lib_format = "%s%s" - exe_extension = ".exe" - - def __init__(self, verbose=0, dry_run=0, force=0): - - UnixCCompiler.__init__(self, verbose, dry_run, force) - - status, details = check_config_h() - self.debug_print("Python's GCC status: %s (details: %s)" % - (status, details)) - if status is not CONFIG_H_OK: - self.warn( - "Python's pyconfig.h doesn't seem to support your compiler. " - "Reason: %s. " - "Compiling may fail because of undefined preprocessor macros." - % details) - - self.gcc_version, self.ld_version, self.dllwrap_version = \ - get_versions() - self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" % - (self.gcc_version, - self.ld_version, - self.dllwrap_version) ) - - # ld_version >= "2.10.90" and < "2.13" should also be able to use - # gcc -mdll instead of dllwrap - # Older dllwraps had own version numbers, newer ones use the - # same as the rest of binutils ( also ld ) - # dllwrap 2.10.90 is buggy - if self.ld_version >= "2.10.90": - self.linker_dll = "gcc" - else: - self.linker_dll = "dllwrap" - - # ld_version >= "2.13" support -shared so use it instead of - # -mdll -static - if self.ld_version >= "2.13": - shared_option = "-shared" - else: - shared_option = "-mdll -static" - - # Hard-code GCC because that's what this is all about. - # XXX optimization, warnings etc. should be customizable. - self.set_executables(compiler='gcc -mcygwin -O -Wall', - compiler_so='gcc -mcygwin -mdll -O -Wall', - compiler_cxx='g++ -mcygwin -O -Wall', - linker_exe='gcc -mcygwin', - linker_so=('%s -mcygwin %s' % - (self.linker_dll, shared_option))) - - # cygwin and mingw32 need different sets of libraries - if self.gcc_version == "2.91.57": - # cygwin shouldn't need msvcrt, but without the dlls will crash - # (gcc version 2.91.57) -- perhaps something about initialization - self.dll_libraries=["msvcrt"] - self.warn( - "Consider upgrading to a newer version of gcc") - else: - # Include the appropriate MSVC runtime library if Python was built - # with MSVC 7.0 or later. - self.dll_libraries = get_msvcr() - - def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): - """Compiles the source by spawning GCC and windres if needed.""" - if ext == '.rc' or ext == '.res': - # gcc needs '.res' and '.rc' compiled to object files !!! - try: - self.spawn(["windres", "-i", src, "-o", obj]) - except DistutilsExecError as msg: - raise CompileError(msg) - else: # for other files use the C-compiler - try: - self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + - extra_postargs) - except DistutilsExecError as msg: - raise CompileError(msg) - - def link(self, target_desc, objects, output_filename, output_dir=None, - libraries=None, library_dirs=None, runtime_library_dirs=None, - export_symbols=None, debug=0, extra_preargs=None, - extra_postargs=None, build_temp=None, target_lang=None): - """Link the objects.""" - # use separate copies, so we can modify the lists - extra_preargs = copy.copy(extra_preargs or []) - libraries = copy.copy(libraries or []) - objects = copy.copy(objects or []) - - # Additional libraries - libraries.extend(self.dll_libraries) - - # handle export symbols by creating a def-file - # with executables this only works with gcc/ld as linker - if ((export_symbols is not None) and - (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): - # (The linker doesn't do anything if output is up-to-date. - # So it would probably better to check if we really need this, - # but for this we had to insert some unchanged parts of - # UnixCCompiler, and this is not what we want.) - - # we want to put some files in the same directory as the - # object files are, build_temp doesn't help much - # where are the object files - temp_dir = os.path.dirname(objects[0]) - # name of dll to give the helper files the same base name - (dll_name, dll_extension) = os.path.splitext( - os.path.basename(output_filename)) - - # generate the filenames for these files - def_file = os.path.join(temp_dir, dll_name + ".def") - lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a") - - # Generate .def file - contents = [ - "LIBRARY %s" % os.path.basename(output_filename), - "EXPORTS"] - for sym in export_symbols: - contents.append(sym) - self.execute(write_file, (def_file, contents), - "writing %s" % def_file) - - # next add options for def-file and to creating import libraries - - # dllwrap uses different options than gcc/ld - if self.linker_dll == "dllwrap": - extra_preargs.extend(["--output-lib", lib_file]) - # for dllwrap we have to use a special option - extra_preargs.extend(["--def", def_file]) - # we use gcc/ld here and can be sure ld is >= 2.9.10 - else: - # doesn't work: bfd_close build\...\libfoo.a: Invalid operation - #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file]) - # for gcc/ld the def-file is specified as any object files - objects.append(def_file) - - #end: if ((export_symbols is not None) and - # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): - - # who wants symbols and a many times larger output file - # should explicitly switch the debug mode on - # otherwise we let dllwrap/ld strip the output file - # (On my machine: 10KiB < stripped_file < ??100KiB - # unstripped_file = stripped_file + XXX KiB - # ( XXX=254 for a typical python extension)) - if not debug: - extra_preargs.append("-s") - - UnixCCompiler.link(self, target_desc, objects, output_filename, - output_dir, libraries, library_dirs, - runtime_library_dirs, - None, # export_symbols, we do this in our def-file - debug, extra_preargs, extra_postargs, build_temp, - target_lang) - - # -- Miscellaneous methods ----------------------------------------- - - def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): - """Adds supports for rc and res files.""" - if output_dir is None: - output_dir = '' - obj_names = [] - for src_name in source_filenames: - # use normcase to make sure '.rc' is really '.rc' and not '.RC' - base, ext = os.path.splitext(os.path.normcase(src_name)) - if ext not in (self.src_extensions + ['.rc','.res']): - raise UnknownFileError("unknown file type '%s' (from '%s')" % \ - (ext, src_name)) - if strip_dir: - base = os.path.basename (base) - if ext in ('.res', '.rc'): - # these need to be compiled to object files - obj_names.append (os.path.join(output_dir, - base + ext + self.obj_extension)) - else: - obj_names.append (os.path.join(output_dir, - base + self.obj_extension)) - return obj_names - -# the same as cygwin plus some additional parameters -class Mingw32CCompiler(CygwinCCompiler): - """ Handles the Mingw32 port of the GNU C compiler to Windows. - """ - compiler_type = 'mingw32' - - def __init__(self, verbose=0, dry_run=0, force=0): - - CygwinCCompiler.__init__ (self, verbose, dry_run, force) - - # ld_version >= "2.13" support -shared so use it instead of - # -mdll -static - if self.ld_version >= "2.13": - shared_option = "-shared" - else: - shared_option = "-mdll -static" - - # A real mingw32 doesn't need to specify a different entry point, - # but cygwin 2.91.57 in no-cygwin-mode needs it. - if self.gcc_version <= "2.91.57": - entry_point = '--entry _DllMain@12' - else: - entry_point = '' - - if is_cygwingcc(): - raise CCompilerError( - 'Cygwin gcc cannot be used with --compiler=mingw32') - - self.set_executables(compiler='gcc -O -Wall', - compiler_so='gcc -mdll -O -Wall', - compiler_cxx='g++ -O -Wall', - linker_exe='gcc', - linker_so='%s %s %s' - % (self.linker_dll, shared_option, - entry_point)) - # Maybe we should also append -mthreads, but then the finished - # dlls need another dll (mingwm10.dll see Mingw32 docs) - # (-mthreads: Support thread-safe exception handling on `Mingw32') - - # no additional libraries needed - self.dll_libraries=[] - - # Include the appropriate MSVC runtime library if Python was built - # with MSVC 7.0 or later. - self.dll_libraries = get_msvcr() - -# Because these compilers aren't configured in Python's pyconfig.h file by -# default, we should at least warn the user if he is using an unmodified -# version. - -CONFIG_H_OK = "ok" -CONFIG_H_NOTOK = "not ok" -CONFIG_H_UNCERTAIN = "uncertain" - -def check_config_h(): - """Check if the current Python installation appears amenable to building - extensions with GCC. - - Returns a tuple (status, details), where 'status' is one of the following - constants: - - - CONFIG_H_OK: all is well, go ahead and compile - - CONFIG_H_NOTOK: doesn't look good - - CONFIG_H_UNCERTAIN: not sure -- unable to read pyconfig.h - - 'details' is a human-readable string explaining the situation. - - Note there are two ways to conclude "OK": either 'sys.version' contains - the string "GCC" (implying that this Python was built with GCC), or the - installed "pyconfig.h" contains the string "__GNUC__". - """ - - # XXX since this function also checks sys.version, it's not strictly a - # "pyconfig.h" check -- should probably be renamed... - - from distutils import sysconfig - - # if sys.version contains GCC then python was compiled with GCC, and the - # pyconfig.h file should be OK - if "GCC" in sys.version: - return CONFIG_H_OK, "sys.version mentions 'GCC'" - - # let's see if __GNUC__ is mentioned in python.h - fn = sysconfig.get_config_h_filename() - try: - config_h = open(fn) - try: - if "__GNUC__" in config_h.read(): - return CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn - else: - return CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn - finally: - config_h.close() - except OSError as exc: - return (CONFIG_H_UNCERTAIN, - "couldn't read '%s': %s" % (fn, exc.strerror)) - -RE_VERSION = re.compile(br'(\d+\.\d+(\.\d+)*)') - -def _find_exe_version(cmd): - """Find the version of an executable by running `cmd` in the shell. - - If the command is not found, or the output does not match - `RE_VERSION`, returns None. - """ - executable = cmd.split()[0] - if find_executable(executable) is None: - return None - out = Popen(cmd, shell=True, stdout=PIPE).stdout - try: - out_string = out.read() - finally: - out.close() - result = RE_VERSION.search(out_string) - if result is None: - return None - # LooseVersion works with strings - # so we need to decode our bytes - return LooseVersion(result.group(1).decode()) - -def get_versions(): - """ Try to find out the versions of gcc, ld and dllwrap. - - If not possible it returns None for it. - """ - commands = ['gcc -dumpversion', 'ld -v', 'dllwrap --version'] - return tuple([_find_exe_version(cmd) for cmd in commands]) - -def is_cygwingcc(): - '''Try to determine if the gcc that would be used is from cygwin.''' - out_string = check_output(['gcc', '-dumpmachine']) - return out_string.strip().endswith(b'cygwin') diff --git a/python/Lib/distutils/debug.py b/python/Lib/distutils/debug.py deleted file mode 100644 index c967472..0000000 --- a/python/Lib/distutils/debug.py +++ /dev/null @@ -1,5 +0,0 @@ -import os - -# If DISTUTILS_DEBUG is anything other than the empty string, we run in -# debug mode. -DEBUG = os.environ.get('DISTUTILS_DEBUG') diff --git a/python/Lib/distutils/dep_util.py b/python/Lib/distutils/dep_util.py deleted file mode 100644 index 76887db..0000000 --- a/python/Lib/distutils/dep_util.py +++ /dev/null @@ -1,92 +0,0 @@ -"""distutils.dep_util - -Utility functions for simple, timestamp-based dependency of files -and groups of files; also, function based entirely on such -timestamp dependency analysis.""" - -import os -from distutils.errors import DistutilsFileError - - -def newer (source, target): - """Return true if 'source' exists and is more recently modified than - 'target', or if 'source' exists and 'target' doesn't. Return false if - both exist and 'target' is the same age or younger than 'source'. - Raise DistutilsFileError if 'source' does not exist. - """ - if not os.path.exists(source): - raise DistutilsFileError("file '%s' does not exist" % - os.path.abspath(source)) - if not os.path.exists(target): - return 1 - - from stat import ST_MTIME - mtime1 = os.stat(source)[ST_MTIME] - mtime2 = os.stat(target)[ST_MTIME] - - return mtime1 > mtime2 - -# newer () - - -def newer_pairwise (sources, targets): - """Walk two filename lists in parallel, testing if each source is newer - than its corresponding target. Return a pair of lists (sources, - targets) where source is newer than target, according to the semantics - of 'newer()'. - """ - if len(sources) != len(targets): - raise ValueError("'sources' and 'targets' must be same length") - - # build a pair of lists (sources, targets) where source is newer - n_sources = [] - n_targets = [] - for i in range(len(sources)): - if newer(sources[i], targets[i]): - n_sources.append(sources[i]) - n_targets.append(targets[i]) - - return (n_sources, n_targets) - -# newer_pairwise () - - -def newer_group (sources, target, missing='error'): - """Return true if 'target' is out-of-date with respect to any file - listed in 'sources'. In other words, if 'target' exists and is newer - than every file in 'sources', return false; otherwise return true. - 'missing' controls what we do when a source file is missing; the - default ("error") is to blow up with an OSError from inside 'stat()'; - if it is "ignore", we silently drop any missing source files; if it is - "newer", any missing source files make us assume that 'target' is - out-of-date (this is handy in "dry-run" mode: it'll make you pretend to - carry out commands that wouldn't work because inputs are missing, but - that doesn't matter because you're not actually going to run the - commands). - """ - # If the target doesn't even exist, then it's definitely out-of-date. - if not os.path.exists(target): - return 1 - - # Otherwise we have to find out the hard way: if *any* source file - # is more recent than 'target', then 'target' is out-of-date and - # we can immediately return true. If we fall through to the end - # of the loop, then 'target' is up-to-date and we return false. - from stat import ST_MTIME - target_mtime = os.stat(target)[ST_MTIME] - for source in sources: - if not os.path.exists(source): - if missing == 'error': # blow up when we stat() the file - pass - elif missing == 'ignore': # missing source dropped from - continue # target's dependency list - elif missing == 'newer': # missing source means target is - return 1 # out-of-date - - source_mtime = os.stat(source)[ST_MTIME] - if source_mtime > target_mtime: - return 1 - else: - return 0 - -# newer_group () diff --git a/python/Lib/distutils/dir_util.py b/python/Lib/distutils/dir_util.py deleted file mode 100644 index 72cdaf0..0000000 --- a/python/Lib/distutils/dir_util.py +++ /dev/null @@ -1,210 +0,0 @@ -"""distutils.dir_util - -Utility functions for manipulating directories and directory trees.""" - -import os -import errno -from distutils.errors import DistutilsFileError, DistutilsInternalError -from distutils import log - -# cache for by mkpath() -- in addition to cheapening redundant calls, -# eliminates redundant "creating /foo/bar/baz" messages in dry-run mode -_path_created = {} - -# I don't use os.makedirs because a) it's new to Python 1.5.2, and -# b) it blows up if the directory already exists (I want to silently -# succeed in that case). -def mkpath(name, mode=0o777, verbose=1, dry_run=0): - """Create a directory and any missing ancestor directories. - - If the directory already exists (or if 'name' is the empty string, which - means the current directory, which of course exists), then do nothing. - Raise DistutilsFileError if unable to create some directory along the way - (eg. some sub-path exists, but is a file rather than a directory). - If 'verbose' is true, print a one-line summary of each mkdir to stdout. - Return the list of directories actually created. - """ - - global _path_created - - # Detect a common bug -- name is None - if not isinstance(name, str): - raise DistutilsInternalError( - "mkpath: 'name' must be a string (got %r)" % (name,)) - - # XXX what's the better way to handle verbosity? print as we create - # each directory in the path (the current behaviour), or only announce - # the creation of the whole path? (quite easy to do the latter since - # we're not using a recursive algorithm) - - name = os.path.normpath(name) - created_dirs = [] - if os.path.isdir(name) or name == '': - return created_dirs - if _path_created.get(os.path.abspath(name)): - return created_dirs - - (head, tail) = os.path.split(name) - tails = [tail] # stack of lone dirs to create - - while head and tail and not os.path.isdir(head): - (head, tail) = os.path.split(head) - tails.insert(0, tail) # push next higher dir onto stack - - # now 'head' contains the deepest directory that already exists - # (that is, the child of 'head' in 'name' is the highest directory - # that does *not* exist) - for d in tails: - #print "head = %s, d = %s: " % (head, d), - head = os.path.join(head, d) - abs_head = os.path.abspath(head) - - if _path_created.get(abs_head): - continue - - if verbose >= 1: - log.info("creating %s", head) - - if not dry_run: - try: - os.mkdir(head, mode) - except OSError as exc: - if not (exc.errno == errno.EEXIST and os.path.isdir(head)): - raise DistutilsFileError( - "could not create '%s': %s" % (head, exc.args[-1])) - created_dirs.append(head) - - _path_created[abs_head] = 1 - return created_dirs - -def create_tree(base_dir, files, mode=0o777, verbose=1, dry_run=0): - """Create all the empty directories under 'base_dir' needed to put 'files' - there. - - 'base_dir' is just the name of a directory which doesn't necessarily - exist yet; 'files' is a list of filenames to be interpreted relative to - 'base_dir'. 'base_dir' + the directory portion of every file in 'files' - will be created if it doesn't already exist. 'mode', 'verbose' and - 'dry_run' flags are as for 'mkpath()'. - """ - # First get the list of directories to create - need_dir = set() - for file in files: - need_dir.add(os.path.join(base_dir, os.path.dirname(file))) - - # Now create them - for dir in sorted(need_dir): - mkpath(dir, mode, verbose=verbose, dry_run=dry_run) - -def copy_tree(src, dst, preserve_mode=1, preserve_times=1, - preserve_symlinks=0, update=0, verbose=1, dry_run=0): - """Copy an entire directory tree 'src' to a new location 'dst'. - - Both 'src' and 'dst' must be directory names. If 'src' is not a - directory, raise DistutilsFileError. If 'dst' does not exist, it is - created with 'mkpath()'. The end result of the copy is that every - file in 'src' is copied to 'dst', and directories under 'src' are - recursively copied to 'dst'. Return the list of files that were - copied or might have been copied, using their output name. The - return value is unaffected by 'update' or 'dry_run': it is simply - the list of all files under 'src', with the names changed to be - under 'dst'. - - 'preserve_mode' and 'preserve_times' are the same as for - 'copy_file'; note that they only apply to regular files, not to - directories. If 'preserve_symlinks' is true, symlinks will be - copied as symlinks (on platforms that support them!); otherwise - (the default), the destination of the symlink will be copied. - 'update' and 'verbose' are the same as for 'copy_file'. - """ - from distutils.file_util import copy_file - - if not dry_run and not os.path.isdir(src): - raise DistutilsFileError( - "cannot copy tree '%s': not a directory" % src) - try: - names = os.listdir(src) - except OSError as e: - if dry_run: - names = [] - else: - raise DistutilsFileError( - "error listing files in '%s': %s" % (src, e.strerror)) - - if not dry_run: - mkpath(dst, verbose=verbose) - - outputs = [] - - for n in names: - src_name = os.path.join(src, n) - dst_name = os.path.join(dst, n) - - if n.startswith('.nfs'): - # skip NFS rename files - continue - - if preserve_symlinks and os.path.islink(src_name): - link_dest = os.readlink(src_name) - if verbose >= 1: - log.info("linking %s -> %s", dst_name, link_dest) - if not dry_run: - os.symlink(link_dest, dst_name) - outputs.append(dst_name) - - elif os.path.isdir(src_name): - outputs.extend( - copy_tree(src_name, dst_name, preserve_mode, - preserve_times, preserve_symlinks, update, - verbose=verbose, dry_run=dry_run)) - else: - copy_file(src_name, dst_name, preserve_mode, - preserve_times, update, verbose=verbose, - dry_run=dry_run) - outputs.append(dst_name) - - return outputs - -def _build_cmdtuple(path, cmdtuples): - """Helper for remove_tree().""" - for f in os.listdir(path): - real_f = os.path.join(path,f) - if os.path.isdir(real_f) and not os.path.islink(real_f): - _build_cmdtuple(real_f, cmdtuples) - else: - cmdtuples.append((os.remove, real_f)) - cmdtuples.append((os.rmdir, path)) - -def remove_tree(directory, verbose=1, dry_run=0): - """Recursively remove an entire directory tree. - - Any errors are ignored (apart from being reported to stdout if 'verbose' - is true). - """ - global _path_created - - if verbose >= 1: - log.info("removing '%s' (and everything under it)", directory) - if dry_run: - return - cmdtuples = [] - _build_cmdtuple(directory, cmdtuples) - for cmd in cmdtuples: - try: - cmd[0](cmd[1]) - # remove dir from cache if it's already there - abspath = os.path.abspath(cmd[1]) - if abspath in _path_created: - del _path_created[abspath] - except OSError as exc: - log.warn("error removing %s: %s", directory, exc) - -def ensure_relative(path): - """Take the full path 'path', and make it a relative path. - - This is useful to make 'path' the second argument to os.path.join(). - """ - drive, path = os.path.splitdrive(path) - if path[0:1] == os.sep: - path = drive + path[1:] - return path diff --git a/python/Lib/distutils/dist.py b/python/Lib/distutils/dist.py deleted file mode 100644 index 63d8197..0000000 --- a/python/Lib/distutils/dist.py +++ /dev/null @@ -1,1256 +0,0 @@ -"""distutils.dist - -Provides the Distribution class, which represents the module distribution -being built/installed/distributed. -""" - -import sys -import os -import re -from email import message_from_file - -try: - import warnings -except ImportError: - warnings = None - -from distutils.errors import * -from distutils.fancy_getopt import FancyGetopt, translate_longopt -from distutils.util import check_environ, strtobool, rfc822_escape -from distutils import log -from distutils.debug import DEBUG - -# Regex to define acceptable Distutils command names. This is not *quite* -# the same as a Python NAME -- I don't allow leading underscores. The fact -# that they're very similar is no coincidence; the default naming scheme is -# to look for a Python module named after the command. -command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$') - - -def _ensure_list(value, fieldname): - if isinstance(value, str): - # a string containing comma separated values is okay. It will - # be converted to a list by Distribution.finalize_options(). - pass - elif not isinstance(value, list): - # passing a tuple or an iterator perhaps, warn and convert - typename = type(value).__name__ - msg = f"Warning: '{fieldname}' should be a list, got type '{typename}'" - log.log(log.WARN, msg) - value = list(value) - return value - - -class Distribution: - """The core of the Distutils. Most of the work hiding behind 'setup' - is really done within a Distribution instance, which farms the work out - to the Distutils commands specified on the command line. - - Setup scripts will almost never instantiate Distribution directly, - unless the 'setup()' function is totally inadequate to their needs. - However, it is conceivable that a setup script might wish to subclass - Distribution for some specialized purpose, and then pass the subclass - to 'setup()' as the 'distclass' keyword argument. If so, it is - necessary to respect the expectations that 'setup' has of Distribution. - See the code for 'setup()', in core.py, for details. - """ - - # 'global_options' describes the command-line options that may be - # supplied to the setup script prior to any actual commands. - # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of - # these global options. This list should be kept to a bare minimum, - # since every global option is also valid as a command option -- and we - # don't want to pollute the commands with too many options that they - # have minimal control over. - # The fourth entry for verbose means that it can be repeated. - global_options = [ - ('verbose', 'v', "run verbosely (default)", 1), - ('quiet', 'q', "run quietly (turns verbosity off)"), - ('dry-run', 'n', "don't actually do anything"), - ('help', 'h', "show detailed help message"), - ('no-user-cfg', None, - 'ignore pydistutils.cfg in your home directory'), - ] - - # 'common_usage' is a short (2-3 line) string describing the common - # usage of the setup script. - common_usage = """\ -Common commands: (see '--help-commands' for more) - - setup.py build will build the package underneath 'build/' - setup.py install will install the package -""" - - # options that are not propagated to the commands - display_options = [ - ('help-commands', None, - "list all available commands"), - ('name', None, - "print package name"), - ('version', 'V', - "print package version"), - ('fullname', None, - "print -"), - ('author', None, - "print the author's name"), - ('author-email', None, - "print the author's email address"), - ('maintainer', None, - "print the maintainer's name"), - ('maintainer-email', None, - "print the maintainer's email address"), - ('contact', None, - "print the maintainer's name if known, else the author's"), - ('contact-email', None, - "print the maintainer's email address if known, else the author's"), - ('url', None, - "print the URL for this package"), - ('license', None, - "print the license of the package"), - ('licence', None, - "alias for --license"), - ('description', None, - "print the package description"), - ('long-description', None, - "print the long package description"), - ('platforms', None, - "print the list of platforms"), - ('classifiers', None, - "print the list of classifiers"), - ('keywords', None, - "print the list of keywords"), - ('provides', None, - "print the list of packages/modules provided"), - ('requires', None, - "print the list of packages/modules required"), - ('obsoletes', None, - "print the list of packages/modules made obsolete") - ] - display_option_names = [translate_longopt(x[0]) for x in display_options] - - # negative options are options that exclude other options - negative_opt = {'quiet': 'verbose'} - - # -- Creation/initialization methods ------------------------------- - - def __init__(self, attrs=None): - """Construct a new Distribution instance: initialize all the - attributes of a Distribution, and then use 'attrs' (a dictionary - mapping attribute names to values) to assign some of those - attributes their "real" values. (Any attributes not mentioned in - 'attrs' will be assigned to some null value: 0, None, an empty list - or dictionary, etc.) Most importantly, initialize the - 'command_obj' attribute to the empty dictionary; this will be - filled in with real command objects by 'parse_command_line()'. - """ - - # Default values for our command-line options - self.verbose = 1 - self.dry_run = 0 - self.help = 0 - for attr in self.display_option_names: - setattr(self, attr, 0) - - # Store the distribution meta-data (name, version, author, and so - # forth) in a separate object -- we're getting to have enough - # information here (and enough command-line options) that it's - # worth it. Also delegate 'get_XXX()' methods to the 'metadata' - # object in a sneaky and underhanded (but efficient!) way. - self.metadata = DistributionMetadata() - for basename in self.metadata._METHOD_BASENAMES: - method_name = "get_" + basename - setattr(self, method_name, getattr(self.metadata, method_name)) - - # 'cmdclass' maps command names to class objects, so we - # can 1) quickly figure out which class to instantiate when - # we need to create a new command object, and 2) have a way - # for the setup script to override command classes - self.cmdclass = {} - - # 'command_packages' is a list of packages in which commands - # are searched for. The factory for command 'foo' is expected - # to be named 'foo' in the module 'foo' in one of the packages - # named here. This list is searched from the left; an error - # is raised if no named package provides the command being - # searched for. (Always access using get_command_packages().) - self.command_packages = None - - # 'script_name' and 'script_args' are usually set to sys.argv[0] - # and sys.argv[1:], but they can be overridden when the caller is - # not necessarily a setup script run from the command-line. - self.script_name = None - self.script_args = None - - # 'command_options' is where we store command options between - # parsing them (from config files, the command-line, etc.) and when - # they are actually needed -- ie. when the command in question is - # instantiated. It is a dictionary of dictionaries of 2-tuples: - # command_options = { command_name : { option : (source, value) } } - self.command_options = {} - - # 'dist_files' is the list of (command, pyversion, file) that - # have been created by any dist commands run so far. This is - # filled regardless of whether the run is dry or not. pyversion - # gives sysconfig.get_python_version() if the dist file is - # specific to a Python version, 'any' if it is good for all - # Python versions on the target platform, and '' for a source - # file. pyversion should not be used to specify minimum or - # maximum required Python versions; use the metainfo for that - # instead. - self.dist_files = [] - - # These options are really the business of various commands, rather - # than of the Distribution itself. We provide aliases for them in - # Distribution as a convenience to the developer. - self.packages = None - self.package_data = {} - self.package_dir = None - self.py_modules = None - self.libraries = None - self.headers = None - self.ext_modules = None - self.ext_package = None - self.include_dirs = None - self.extra_path = None - self.scripts = None - self.data_files = None - self.password = '' - - # And now initialize bookkeeping stuff that can't be supplied by - # the caller at all. 'command_obj' maps command names to - # Command instances -- that's how we enforce that every command - # class is a singleton. - self.command_obj = {} - - # 'have_run' maps command names to boolean values; it keeps track - # of whether we have actually run a particular command, to make it - # cheap to "run" a command whenever we think we might need to -- if - # it's already been done, no need for expensive filesystem - # operations, we just check the 'have_run' dictionary and carry on. - # It's only safe to query 'have_run' for a command class that has - # been instantiated -- a false value will be inserted when the - # command object is created, and replaced with a true value when - # the command is successfully run. Thus it's probably best to use - # '.get()' rather than a straight lookup. - self.have_run = {} - - # Now we'll use the attrs dictionary (ultimately, keyword args from - # the setup script) to possibly override any or all of these - # distribution options. - - if attrs: - # Pull out the set of command options and work on them - # specifically. Note that this order guarantees that aliased - # command options will override any supplied redundantly - # through the general options dictionary. - options = attrs.get('options') - if options is not None: - del attrs['options'] - for (command, cmd_options) in options.items(): - opt_dict = self.get_option_dict(command) - for (opt, val) in cmd_options.items(): - opt_dict[opt] = ("setup script", val) - - if 'licence' in attrs: - attrs['license'] = attrs['licence'] - del attrs['licence'] - msg = "'licence' distribution option is deprecated; use 'license'" - if warnings is not None: - warnings.warn(msg) - else: - sys.stderr.write(msg + "\n") - - # Now work on the rest of the attributes. Any attribute that's - # not already defined is invalid! - for (key, val) in attrs.items(): - if hasattr(self.metadata, "set_" + key): - getattr(self.metadata, "set_" + key)(val) - elif hasattr(self.metadata, key): - setattr(self.metadata, key, val) - elif hasattr(self, key): - setattr(self, key, val) - else: - msg = "Unknown distribution option: %s" % repr(key) - warnings.warn(msg) - - # no-user-cfg is handled before other command line args - # because other args override the config files, and this - # one is needed before we can load the config files. - # If attrs['script_args'] wasn't passed, assume false. - # - # This also make sure we just look at the global options - self.want_user_cfg = True - - if self.script_args is not None: - for arg in self.script_args: - if not arg.startswith('-'): - break - if arg == '--no-user-cfg': - self.want_user_cfg = False - break - - self.finalize_options() - - def get_option_dict(self, command): - """Get the option dictionary for a given command. If that - command's option dictionary hasn't been created yet, then create it - and return the new dictionary; otherwise, return the existing - option dictionary. - """ - dict = self.command_options.get(command) - if dict is None: - dict = self.command_options[command] = {} - return dict - - def dump_option_dicts(self, header=None, commands=None, indent=""): - from pprint import pformat - - if commands is None: # dump all command option dicts - commands = sorted(self.command_options.keys()) - - if header is not None: - self.announce(indent + header) - indent = indent + " " - - if not commands: - self.announce(indent + "no commands known yet") - return - - for cmd_name in commands: - opt_dict = self.command_options.get(cmd_name) - if opt_dict is None: - self.announce(indent + - "no option dict for '%s' command" % cmd_name) - else: - self.announce(indent + - "option dict for '%s' command:" % cmd_name) - out = pformat(opt_dict) - for line in out.split('\n'): - self.announce(indent + " " + line) - - # -- Config file finding/parsing methods --------------------------- - - def find_config_files(self): - """Find as many configuration files as should be processed for this - platform, and return a list of filenames in the order in which they - should be parsed. The filenames returned are guaranteed to exist - (modulo nasty race conditions). - - There are three possible config files: distutils.cfg in the - Distutils installation directory (ie. where the top-level - Distutils __inst__.py file lives), a file in the user's home - directory named .pydistutils.cfg on Unix and pydistutils.cfg - on Windows/Mac; and setup.cfg in the current directory. - - The file in the user's home directory can be disabled with the - --no-user-cfg option. - """ - files = [] - check_environ() - - # Where to look for the system-wide Distutils config file - sys_dir = os.path.dirname(sys.modules['distutils'].__file__) - - # Look for the system config file - sys_file = os.path.join(sys_dir, "distutils.cfg") - if os.path.isfile(sys_file): - files.append(sys_file) - - # What to call the per-user config file - if os.name == 'posix': - user_filename = ".pydistutils.cfg" - else: - user_filename = "pydistutils.cfg" - - # And look for the user config file - if self.want_user_cfg: - user_file = os.path.join(os.path.expanduser('~'), user_filename) - if os.path.isfile(user_file): - files.append(user_file) - - # All platforms support local setup.cfg - local_file = "setup.cfg" - if os.path.isfile(local_file): - files.append(local_file) - - if DEBUG: - self.announce("using config files: %s" % ', '.join(files)) - - return files - - def parse_config_files(self, filenames=None): - from configparser import ConfigParser - - # Ignore install directory options if we have a venv - if sys.prefix != sys.base_prefix: - ignore_options = [ - 'install-base', 'install-platbase', 'install-lib', - 'install-platlib', 'install-purelib', 'install-headers', - 'install-scripts', 'install-data', 'prefix', 'exec-prefix', - 'home', 'user', 'root'] - else: - ignore_options = [] - - ignore_options = frozenset(ignore_options) - - if filenames is None: - filenames = self.find_config_files() - - if DEBUG: - self.announce("Distribution.parse_config_files():") - - parser = ConfigParser() - for filename in filenames: - if DEBUG: - self.announce(" reading %s" % filename) - parser.read(filename) - for section in parser.sections(): - options = parser.options(section) - opt_dict = self.get_option_dict(section) - - for opt in options: - if opt != '__name__' and opt not in ignore_options: - val = parser.get(section,opt) - opt = opt.replace('-', '_') - opt_dict[opt] = (filename, val) - - # Make the ConfigParser forget everything (so we retain - # the original filenames that options come from) - parser.__init__() - - # If there was a "global" section in the config file, use it - # to set Distribution options. - - if 'global' in self.command_options: - for (opt, (src, val)) in self.command_options['global'].items(): - alias = self.negative_opt.get(opt) - try: - if alias: - setattr(self, alias, not strtobool(val)) - elif opt in ('verbose', 'dry_run'): # ugh! - setattr(self, opt, strtobool(val)) - else: - setattr(self, opt, val) - except ValueError as msg: - raise DistutilsOptionError(msg) - - # -- Command-line parsing methods ---------------------------------- - - def parse_command_line(self): - """Parse the setup script's command line, taken from the - 'script_args' instance attribute (which defaults to 'sys.argv[1:]' - -- see 'setup()' in core.py). This list is first processed for - "global options" -- options that set attributes of the Distribution - instance. Then, it is alternately scanned for Distutils commands - and options for that command. Each new command terminates the - options for the previous command. The allowed options for a - command are determined by the 'user_options' attribute of the - command class -- thus, we have to be able to load command classes - in order to parse the command line. Any error in that 'options' - attribute raises DistutilsGetoptError; any error on the - command-line raises DistutilsArgError. If no Distutils commands - were found on the command line, raises DistutilsArgError. Return - true if command-line was successfully parsed and we should carry - on with executing commands; false if no errors but we shouldn't - execute commands (currently, this only happens if user asks for - help). - """ - # - # We now have enough information to show the Macintosh dialog - # that allows the user to interactively specify the "command line". - # - toplevel_options = self._get_toplevel_options() - - # We have to parse the command line a bit at a time -- global - # options, then the first command, then its options, and so on -- - # because each command will be handled by a different class, and - # the options that are valid for a particular class aren't known - # until we have loaded the command class, which doesn't happen - # until we know what the command is. - - self.commands = [] - parser = FancyGetopt(toplevel_options + self.display_options) - parser.set_negative_aliases(self.negative_opt) - parser.set_aliases({'licence': 'license'}) - args = parser.getopt(args=self.script_args, object=self) - option_order = parser.get_option_order() - log.set_verbosity(self.verbose) - - # for display options we return immediately - if self.handle_display_options(option_order): - return - while args: - args = self._parse_command_opts(parser, args) - if args is None: # user asked for help (and got it) - return - - # Handle the cases of --help as a "global" option, ie. - # "setup.py --help" and "setup.py --help command ...". For the - # former, we show global options (--verbose, --dry-run, etc.) - # and display-only options (--name, --version, etc.); for the - # latter, we omit the display-only options and show help for - # each command listed on the command line. - if self.help: - self._show_help(parser, - display_options=len(self.commands) == 0, - commands=self.commands) - return - - # Oops, no commands found -- an end-user error - if not self.commands: - raise DistutilsArgError("no commands supplied") - - # All is well: return true - return True - - def _get_toplevel_options(self): - """Return the non-display options recognized at the top level. - - This includes options that are recognized *only* at the top - level as well as options recognized for commands. - """ - return self.global_options + [ - ("command-packages=", None, - "list of packages that provide distutils commands"), - ] - - def _parse_command_opts(self, parser, args): - """Parse the command-line options for a single command. - 'parser' must be a FancyGetopt instance; 'args' must be the list - of arguments, starting with the current command (whose options - we are about to parse). Returns a new version of 'args' with - the next command at the front of the list; will be the empty - list if there are no more commands on the command line. Returns - None if the user asked for help on this command. - """ - # late import because of mutual dependence between these modules - from distutils.cmd import Command - - # Pull the current command from the head of the command line - command = args[0] - if not command_re.match(command): - raise SystemExit("invalid command name '%s'" % command) - self.commands.append(command) - - # Dig up the command class that implements this command, so we - # 1) know that it's a valid command, and 2) know which options - # it takes. - try: - cmd_class = self.get_command_class(command) - except DistutilsModuleError as msg: - raise DistutilsArgError(msg) - - # Require that the command class be derived from Command -- want - # to be sure that the basic "command" interface is implemented. - if not issubclass(cmd_class, Command): - raise DistutilsClassError( - "command class %s must subclass Command" % cmd_class) - - # Also make sure that the command object provides a list of its - # known options. - if not (hasattr(cmd_class, 'user_options') and - isinstance(cmd_class.user_options, list)): - msg = ("command class %s must provide " - "'user_options' attribute (a list of tuples)") - raise DistutilsClassError(msg % cmd_class) - - # If the command class has a list of negative alias options, - # merge it in with the global negative aliases. - negative_opt = self.negative_opt - if hasattr(cmd_class, 'negative_opt'): - negative_opt = negative_opt.copy() - negative_opt.update(cmd_class.negative_opt) - - # Check for help_options in command class. They have a different - # format (tuple of four) so we need to preprocess them here. - if (hasattr(cmd_class, 'help_options') and - isinstance(cmd_class.help_options, list)): - help_options = fix_help_options(cmd_class.help_options) - else: - help_options = [] - - # All commands support the global options too, just by adding - # in 'global_options'. - parser.set_option_table(self.global_options + - cmd_class.user_options + - help_options) - parser.set_negative_aliases(negative_opt) - (args, opts) = parser.getopt(args[1:]) - if hasattr(opts, 'help') and opts.help: - self._show_help(parser, display_options=0, commands=[cmd_class]) - return - - if (hasattr(cmd_class, 'help_options') and - isinstance(cmd_class.help_options, list)): - help_option_found=0 - for (help_option, short, desc, func) in cmd_class.help_options: - if hasattr(opts, parser.get_attr_name(help_option)): - help_option_found=1 - if callable(func): - func() - else: - raise DistutilsClassError( - "invalid help function %r for help option '%s': " - "must be a callable object (function, etc.)" - % (func, help_option)) - - if help_option_found: - return - - # Put the options from the command-line into their official - # holding pen, the 'command_options' dictionary. - opt_dict = self.get_option_dict(command) - for (name, value) in vars(opts).items(): - opt_dict[name] = ("command line", value) - - return args - - def finalize_options(self): - """Set final values for all the options on the Distribution - instance, analogous to the .finalize_options() method of Command - objects. - """ - for attr in ('keywords', 'platforms'): - value = getattr(self.metadata, attr) - if value is None: - continue - if isinstance(value, str): - value = [elm.strip() for elm in value.split(',')] - setattr(self.metadata, attr, value) - - def _show_help(self, parser, global_options=1, display_options=1, - commands=[]): - """Show help for the setup script command-line in the form of - several lists of command-line options. 'parser' should be a - FancyGetopt instance; do not expect it to be returned in the - same state, as its option table will be reset to make it - generate the correct help text. - - If 'global_options' is true, lists the global options: - --verbose, --dry-run, etc. If 'display_options' is true, lists - the "display-only" options: --name, --version, etc. Finally, - lists per-command help for every command name or command class - in 'commands'. - """ - # late import because of mutual dependence between these modules - from distutils.core import gen_usage - from distutils.cmd import Command - - if global_options: - if display_options: - options = self._get_toplevel_options() - else: - options = self.global_options - parser.set_option_table(options) - parser.print_help(self.common_usage + "\nGlobal options:") - print('') - - if display_options: - parser.set_option_table(self.display_options) - parser.print_help( - "Information display options (just display " + - "information, ignore any commands)") - print('') - - for command in self.commands: - if isinstance(command, type) and issubclass(command, Command): - klass = command - else: - klass = self.get_command_class(command) - if (hasattr(klass, 'help_options') and - isinstance(klass.help_options, list)): - parser.set_option_table(klass.user_options + - fix_help_options(klass.help_options)) - else: - parser.set_option_table(klass.user_options) - parser.print_help("Options for '%s' command:" % klass.__name__) - print('') - - print(gen_usage(self.script_name)) - - def handle_display_options(self, option_order): - """If there were any non-global "display-only" options - (--help-commands or the metadata display options) on the command - line, display the requested info and return true; else return - false. - """ - from distutils.core import gen_usage - - # User just wants a list of commands -- we'll print it out and stop - # processing now (ie. if they ran "setup --help-commands foo bar", - # we ignore "foo bar"). - if self.help_commands: - self.print_commands() - print('') - print(gen_usage(self.script_name)) - return 1 - - # If user supplied any of the "display metadata" options, then - # display that metadata in the order in which the user supplied the - # metadata options. - any_display_options = 0 - is_display_option = {} - for option in self.display_options: - is_display_option[option[0]] = 1 - - for (opt, val) in option_order: - if val and is_display_option.get(opt): - opt = translate_longopt(opt) - value = getattr(self.metadata, "get_"+opt)() - if opt in ['keywords', 'platforms']: - print(','.join(value)) - elif opt in ('classifiers', 'provides', 'requires', - 'obsoletes'): - print('\n'.join(value)) - else: - print(value) - any_display_options = 1 - - return any_display_options - - def print_command_list(self, commands, header, max_length): - """Print a subset of the list of all commands -- used by - 'print_commands()'. - """ - print(header + ":") - - for cmd in commands: - klass = self.cmdclass.get(cmd) - if not klass: - klass = self.get_command_class(cmd) - try: - description = klass.description - except AttributeError: - description = "(no description available)" - - print(" %-*s %s" % (max_length, cmd, description)) - - def print_commands(self): - """Print out a help message listing all available commands with a - description of each. The list is divided into "standard commands" - (listed in distutils.command.__all__) and "extra commands" - (mentioned in self.cmdclass, but not a standard command). The - descriptions come from the command class attribute - 'description'. - """ - import distutils.command - std_commands = distutils.command.__all__ - is_std = {} - for cmd in std_commands: - is_std[cmd] = 1 - - extra_commands = [] - for cmd in self.cmdclass.keys(): - if not is_std.get(cmd): - extra_commands.append(cmd) - - max_length = 0 - for cmd in (std_commands + extra_commands): - if len(cmd) > max_length: - max_length = len(cmd) - - self.print_command_list(std_commands, - "Standard commands", - max_length) - if extra_commands: - print() - self.print_command_list(extra_commands, - "Extra commands", - max_length) - - def get_command_list(self): - """Get a list of (command, description) tuples. - The list is divided into "standard commands" (listed in - distutils.command.__all__) and "extra commands" (mentioned in - self.cmdclass, but not a standard command). The descriptions come - from the command class attribute 'description'. - """ - # Currently this is only used on Mac OS, for the Mac-only GUI - # Distutils interface (by Jack Jansen) - import distutils.command - std_commands = distutils.command.__all__ - is_std = {} - for cmd in std_commands: - is_std[cmd] = 1 - - extra_commands = [] - for cmd in self.cmdclass.keys(): - if not is_std.get(cmd): - extra_commands.append(cmd) - - rv = [] - for cmd in (std_commands + extra_commands): - klass = self.cmdclass.get(cmd) - if not klass: - klass = self.get_command_class(cmd) - try: - description = klass.description - except AttributeError: - description = "(no description available)" - rv.append((cmd, description)) - return rv - - # -- Command class/object methods ---------------------------------- - - def get_command_packages(self): - """Return a list of packages from which commands are loaded.""" - pkgs = self.command_packages - if not isinstance(pkgs, list): - if pkgs is None: - pkgs = '' - pkgs = [pkg.strip() for pkg in pkgs.split(',') if pkg != ''] - if "distutils.command" not in pkgs: - pkgs.insert(0, "distutils.command") - self.command_packages = pkgs - return pkgs - - def get_command_class(self, command): - """Return the class that implements the Distutils command named by - 'command'. First we check the 'cmdclass' dictionary; if the - command is mentioned there, we fetch the class object from the - dictionary and return it. Otherwise we load the command module - ("distutils.command." + command) and fetch the command class from - the module. The loaded class is also stored in 'cmdclass' - to speed future calls to 'get_command_class()'. - - Raises DistutilsModuleError if the expected module could not be - found, or if that module does not define the expected class. - """ - klass = self.cmdclass.get(command) - if klass: - return klass - - for pkgname in self.get_command_packages(): - module_name = "%s.%s" % (pkgname, command) - klass_name = command - - try: - __import__(module_name) - module = sys.modules[module_name] - except ImportError: - continue - - try: - klass = getattr(module, klass_name) - except AttributeError: - raise DistutilsModuleError( - "invalid command '%s' (no class '%s' in module '%s')" - % (command, klass_name, module_name)) - - self.cmdclass[command] = klass - return klass - - raise DistutilsModuleError("invalid command '%s'" % command) - - def get_command_obj(self, command, create=1): - """Return the command object for 'command'. Normally this object - is cached on a previous call to 'get_command_obj()'; if no command - object for 'command' is in the cache, then we either create and - return it (if 'create' is true) or return None. - """ - cmd_obj = self.command_obj.get(command) - if not cmd_obj and create: - if DEBUG: - self.announce("Distribution.get_command_obj(): " - "creating '%s' command object" % command) - - klass = self.get_command_class(command) - cmd_obj = self.command_obj[command] = klass(self) - self.have_run[command] = 0 - - # Set any options that were supplied in config files - # or on the command line. (NB. support for error - # reporting is lame here: any errors aren't reported - # until 'finalize_options()' is called, which means - # we won't report the source of the error.) - options = self.command_options.get(command) - if options: - self._set_command_options(cmd_obj, options) - - return cmd_obj - - def _set_command_options(self, command_obj, option_dict=None): - """Set the options for 'command_obj' from 'option_dict'. Basically - this means copying elements of a dictionary ('option_dict') to - attributes of an instance ('command'). - - 'command_obj' must be a Command instance. If 'option_dict' is not - supplied, uses the standard option dictionary for this command - (from 'self.command_options'). - """ - command_name = command_obj.get_command_name() - if option_dict is None: - option_dict = self.get_option_dict(command_name) - - if DEBUG: - self.announce(" setting options for '%s' command:" % command_name) - for (option, (source, value)) in option_dict.items(): - if DEBUG: - self.announce(" %s = %s (from %s)" % (option, value, - source)) - try: - bool_opts = [translate_longopt(o) - for o in command_obj.boolean_options] - except AttributeError: - bool_opts = [] - try: - neg_opt = command_obj.negative_opt - except AttributeError: - neg_opt = {} - - try: - is_string = isinstance(value, str) - if option in neg_opt and is_string: - setattr(command_obj, neg_opt[option], not strtobool(value)) - elif option in bool_opts and is_string: - setattr(command_obj, option, strtobool(value)) - elif hasattr(command_obj, option): - setattr(command_obj, option, value) - else: - raise DistutilsOptionError( - "error in %s: command '%s' has no such option '%s'" - % (source, command_name, option)) - except ValueError as msg: - raise DistutilsOptionError(msg) - - def reinitialize_command(self, command, reinit_subcommands=0): - """Reinitializes a command to the state it was in when first - returned by 'get_command_obj()': ie., initialized but not yet - finalized. This provides the opportunity to sneak option - values in programmatically, overriding or supplementing - user-supplied values from the config files and command line. - You'll have to re-finalize the command object (by calling - 'finalize_options()' or 'ensure_finalized()') before using it for - real. - - 'command' should be a command name (string) or command object. If - 'reinit_subcommands' is true, also reinitializes the command's - sub-commands, as declared by the 'sub_commands' class attribute (if - it has one). See the "install" command for an example. Only - reinitializes the sub-commands that actually matter, ie. those - whose test predicates return true. - - Returns the reinitialized command object. - """ - from distutils.cmd import Command - if not isinstance(command, Command): - command_name = command - command = self.get_command_obj(command_name) - else: - command_name = command.get_command_name() - - if not command.finalized: - return command - command.initialize_options() - command.finalized = 0 - self.have_run[command_name] = 0 - self._set_command_options(command) - - if reinit_subcommands: - for sub in command.get_sub_commands(): - self.reinitialize_command(sub, reinit_subcommands) - - return command - - # -- Methods that operate on the Distribution ---------------------- - - def announce(self, msg, level=log.INFO): - log.log(level, msg) - - def run_commands(self): - """Run each command that was seen on the setup script command line. - Uses the list of commands found and cache of command objects - created by 'get_command_obj()'. - """ - for cmd in self.commands: - self.run_command(cmd) - - # -- Methods that operate on its Commands -------------------------- - - def run_command(self, command): - """Do whatever it takes to run a command (including nothing at all, - if the command has already been run). Specifically: if we have - already created and run the command named by 'command', return - silently without doing anything. If the command named by 'command' - doesn't even have a command object yet, create one. Then invoke - 'run()' on that command object (or an existing one). - """ - # Already been here, done that? then return silently. - if self.have_run.get(command): - return - - log.info("running %s", command) - cmd_obj = self.get_command_obj(command) - cmd_obj.ensure_finalized() - cmd_obj.run() - self.have_run[command] = 1 - - # -- Distribution query methods ------------------------------------ - - def has_pure_modules(self): - return len(self.packages or self.py_modules or []) > 0 - - def has_ext_modules(self): - return self.ext_modules and len(self.ext_modules) > 0 - - def has_c_libraries(self): - return self.libraries and len(self.libraries) > 0 - - def has_modules(self): - return self.has_pure_modules() or self.has_ext_modules() - - def has_headers(self): - return self.headers and len(self.headers) > 0 - - def has_scripts(self): - return self.scripts and len(self.scripts) > 0 - - def has_data_files(self): - return self.data_files and len(self.data_files) > 0 - - def is_pure(self): - return (self.has_pure_modules() and - not self.has_ext_modules() and - not self.has_c_libraries()) - - # -- Metadata query methods ---------------------------------------- - - # If you're looking for 'get_name()', 'get_version()', and so forth, - # they are defined in a sneaky way: the constructor binds self.get_XXX - # to self.metadata.get_XXX. The actual code is in the - # DistributionMetadata class, below. - -class DistributionMetadata: - """Dummy class to hold the distribution meta-data: name, version, - author, and so forth. - """ - - _METHOD_BASENAMES = ("name", "version", "author", "author_email", - "maintainer", "maintainer_email", "url", - "license", "description", "long_description", - "keywords", "platforms", "fullname", "contact", - "contact_email", "classifiers", "download_url", - # PEP 314 - "provides", "requires", "obsoletes", - ) - - def __init__(self, path=None): - if path is not None: - self.read_pkg_file(open(path)) - else: - self.name = None - self.version = None - self.author = None - self.author_email = None - self.maintainer = None - self.maintainer_email = None - self.url = None - self.license = None - self.description = None - self.long_description = None - self.keywords = None - self.platforms = None - self.classifiers = None - self.download_url = None - # PEP 314 - self.provides = None - self.requires = None - self.obsoletes = None - - def read_pkg_file(self, file): - """Reads the metadata values from a file object.""" - msg = message_from_file(file) - - def _read_field(name): - value = msg[name] - if value == 'UNKNOWN': - return None - return value - - def _read_list(name): - values = msg.get_all(name, None) - if values == []: - return None - return values - - metadata_version = msg['metadata-version'] - self.name = _read_field('name') - self.version = _read_field('version') - self.description = _read_field('summary') - # we are filling author only. - self.author = _read_field('author') - self.maintainer = None - self.author_email = _read_field('author-email') - self.maintainer_email = None - self.url = _read_field('home-page') - self.license = _read_field('license') - - if 'download-url' in msg: - self.download_url = _read_field('download-url') - else: - self.download_url = None - - self.long_description = _read_field('description') - self.description = _read_field('summary') - - if 'keywords' in msg: - self.keywords = _read_field('keywords').split(',') - - self.platforms = _read_list('platform') - self.classifiers = _read_list('classifier') - - # PEP 314 - these fields only exist in 1.1 - if metadata_version == '1.1': - self.requires = _read_list('requires') - self.provides = _read_list('provides') - self.obsoletes = _read_list('obsoletes') - else: - self.requires = None - self.provides = None - self.obsoletes = None - - def write_pkg_info(self, base_dir): - """Write the PKG-INFO file into the release tree. - """ - with open(os.path.join(base_dir, 'PKG-INFO'), 'w', - encoding='UTF-8') as pkg_info: - self.write_pkg_file(pkg_info) - - def write_pkg_file(self, file): - """Write the PKG-INFO format data to a file object. - """ - version = '1.0' - if (self.provides or self.requires or self.obsoletes or - self.classifiers or self.download_url): - version = '1.1' - - file.write('Metadata-Version: %s\n' % version) - file.write('Name: %s\n' % self.get_name()) - file.write('Version: %s\n' % self.get_version()) - file.write('Summary: %s\n' % self.get_description()) - file.write('Home-page: %s\n' % self.get_url()) - file.write('Author: %s\n' % self.get_contact()) - file.write('Author-email: %s\n' % self.get_contact_email()) - file.write('License: %s\n' % self.get_license()) - if self.download_url: - file.write('Download-URL: %s\n' % self.download_url) - - long_desc = rfc822_escape(self.get_long_description()) - file.write('Description: %s\n' % long_desc) - - keywords = ','.join(self.get_keywords()) - if keywords: - file.write('Keywords: %s\n' % keywords) - - self._write_list(file, 'Platform', self.get_platforms()) - self._write_list(file, 'Classifier', self.get_classifiers()) - - # PEP 314 - self._write_list(file, 'Requires', self.get_requires()) - self._write_list(file, 'Provides', self.get_provides()) - self._write_list(file, 'Obsoletes', self.get_obsoletes()) - - def _write_list(self, file, name, values): - for value in values: - file.write('%s: %s\n' % (name, value)) - - # -- Metadata query methods ---------------------------------------- - - def get_name(self): - return self.name or "UNKNOWN" - - def get_version(self): - return self.version or "0.0.0" - - def get_fullname(self): - return "%s-%s" % (self.get_name(), self.get_version()) - - def get_author(self): - return self.author or "UNKNOWN" - - def get_author_email(self): - return self.author_email or "UNKNOWN" - - def get_maintainer(self): - return self.maintainer or "UNKNOWN" - - def get_maintainer_email(self): - return self.maintainer_email or "UNKNOWN" - - def get_contact(self): - return self.maintainer or self.author or "UNKNOWN" - - def get_contact_email(self): - return self.maintainer_email or self.author_email or "UNKNOWN" - - def get_url(self): - return self.url or "UNKNOWN" - - def get_license(self): - return self.license or "UNKNOWN" - get_licence = get_license - - def get_description(self): - return self.description or "UNKNOWN" - - def get_long_description(self): - return self.long_description or "UNKNOWN" - - def get_keywords(self): - return self.keywords or [] - - def set_keywords(self, value): - self.keywords = _ensure_list(value, 'keywords') - - def get_platforms(self): - return self.platforms or ["UNKNOWN"] - - def set_platforms(self, value): - self.platforms = _ensure_list(value, 'platforms') - - def get_classifiers(self): - return self.classifiers or [] - - def set_classifiers(self, value): - self.classifiers = _ensure_list(value, 'classifiers') - - def get_download_url(self): - return self.download_url or "UNKNOWN" - - # PEP 314 - def get_requires(self): - return self.requires or [] - - def set_requires(self, value): - import distutils.versionpredicate - for v in value: - distutils.versionpredicate.VersionPredicate(v) - self.requires = list(value) - - def get_provides(self): - return self.provides or [] - - def set_provides(self, value): - value = [v.strip() for v in value] - for v in value: - import distutils.versionpredicate - distutils.versionpredicate.split_provision(v) - self.provides = value - - def get_obsoletes(self): - return self.obsoletes or [] - - def set_obsoletes(self, value): - import distutils.versionpredicate - for v in value: - distutils.versionpredicate.VersionPredicate(v) - self.obsoletes = list(value) - -def fix_help_options(options): - """Convert a 4-tuple 'help_options' list as found in various command - classes to the 3-tuple form required by FancyGetopt. - """ - new_options = [] - for help_tuple in options: - new_options.append(help_tuple[0:3]) - return new_options diff --git a/python/Lib/distutils/errors.py b/python/Lib/distutils/errors.py deleted file mode 100644 index e78d108..0000000 --- a/python/Lib/distutils/errors.py +++ /dev/null @@ -1,97 +0,0 @@ -"""distutils.errors - -Provides exceptions used by the Distutils modules. Note that Distutils -modules may raise standard exceptions; in particular, SystemExit is -usually raised for errors that are obviously the end-user's fault -(eg. bad command-line arguments). - -This module is safe to use in "from ... import *" mode; it only exports -symbols whose names start with "Distutils" and end with "Error".""" - -class DistutilsError (Exception): - """The root of all Distutils evil.""" - pass - -class DistutilsModuleError (DistutilsError): - """Unable to load an expected module, or to find an expected class - within some module (in particular, command modules and classes).""" - pass - -class DistutilsClassError (DistutilsError): - """Some command class (or possibly distribution class, if anyone - feels a need to subclass Distribution) is found not to be holding - up its end of the bargain, ie. implementing some part of the - "command "interface.""" - pass - -class DistutilsGetoptError (DistutilsError): - """The option table provided to 'fancy_getopt()' is bogus.""" - pass - -class DistutilsArgError (DistutilsError): - """Raised by fancy_getopt in response to getopt.error -- ie. an - error in the command line usage.""" - pass - -class DistutilsFileError (DistutilsError): - """Any problems in the filesystem: expected file not found, etc. - Typically this is for problems that we detect before OSError - could be raised.""" - pass - -class DistutilsOptionError (DistutilsError): - """Syntactic/semantic errors in command options, such as use of - mutually conflicting options, or inconsistent options, - badly-spelled values, etc. No distinction is made between option - values originating in the setup script, the command line, config - files, or what-have-you -- but if we *know* something originated in - the setup script, we'll raise DistutilsSetupError instead.""" - pass - -class DistutilsSetupError (DistutilsError): - """For errors that can be definitely blamed on the setup script, - such as invalid keyword arguments to 'setup()'.""" - pass - -class DistutilsPlatformError (DistutilsError): - """We don't know how to do something on the current platform (but - we do know how to do it on some platform) -- eg. trying to compile - C files on a platform not supported by a CCompiler subclass.""" - pass - -class DistutilsExecError (DistutilsError): - """Any problems executing an external program (such as the C - compiler, when compiling C files).""" - pass - -class DistutilsInternalError (DistutilsError): - """Internal inconsistencies or impossibilities (obviously, this - should never be seen if the code is working!).""" - pass - -class DistutilsTemplateError (DistutilsError): - """Syntax error in a file list template.""" - -class DistutilsByteCompileError(DistutilsError): - """Byte compile error.""" - -# Exception classes used by the CCompiler implementation classes -class CCompilerError (Exception): - """Some compile/link operation failed.""" - -class PreprocessError (CCompilerError): - """Failure to preprocess one or more C/C++ files.""" - -class CompileError (CCompilerError): - """Failure to compile one or more C/C++ source files.""" - -class LibError (CCompilerError): - """Failure to create a static library from one or more C/C++ object - files.""" - -class LinkError (CCompilerError): - """Failure to link one or more C/C++ object files into an executable - or shared library file.""" - -class UnknownFileError (CCompilerError): - """Attempt to process an unknown file type.""" diff --git a/python/Lib/distutils/extension.py b/python/Lib/distutils/extension.py deleted file mode 100644 index 860d603..0000000 --- a/python/Lib/distutils/extension.py +++ /dev/null @@ -1,241 +0,0 @@ -"""distutils.extension - -Provides the Extension class, used to describe C/C++ extension -modules in setup scripts.""" - -import os -import re -import warnings - -# This class is really only used by the "build_ext" command, so it might -# make sense to put it in distutils.command.build_ext. However, that -# module is already big enough, and I want to make this class a bit more -# complex to simplify some common cases ("foo" module in "foo.c") and do -# better error-checking ("foo.c" actually exists). -# -# Also, putting this in build_ext.py means every setup script would have to -# import that large-ish module (indirectly, through distutils.core) in -# order to do anything. - -class Extension: - """Just a collection of attributes that describes an extension - module and everything needed to build it (hopefully in a portable - way, but there are hooks that let you be as unportable as you need). - - Instance attributes: - name : string - the full name of the extension, including any packages -- ie. - *not* a filename or pathname, but Python dotted name - sources : [string] - list of source filenames, relative to the distribution root - (where the setup script lives), in Unix form (slash-separated) - for portability. Source files may be C, C++, SWIG (.i), - platform-specific resource files, or whatever else is recognized - by the "build_ext" command as source for a Python extension. - include_dirs : [string] - list of directories to search for C/C++ header files (in Unix - form for portability) - define_macros : [(name : string, value : string|None)] - list of macros to define; each macro is defined using a 2-tuple, - where 'value' is either the string to define it to or None to - define it without a particular value (equivalent of "#define - FOO" in source or -DFOO on Unix C compiler command line) - undef_macros : [string] - list of macros to undefine explicitly - library_dirs : [string] - list of directories to search for C/C++ libraries at link time - libraries : [string] - list of library names (not filenames or paths) to link against - runtime_library_dirs : [string] - list of directories to search for C/C++ libraries at run time - (for shared extensions, this is when the extension is loaded) - extra_objects : [string] - list of extra files to link with (eg. object files not implied - by 'sources', static library that must be explicitly specified, - binary resource files, etc.) - extra_compile_args : [string] - any extra platform- and compiler-specific information to use - when compiling the source files in 'sources'. For platforms and - compilers where "command line" makes sense, this is typically a - list of command-line arguments, but for other platforms it could - be anything. - extra_link_args : [string] - any extra platform- and compiler-specific information to use - when linking object files together to create the extension (or - to create a new static Python interpreter). Similar - interpretation as for 'extra_compile_args'. - export_symbols : [string] - list of symbols to be exported from a shared extension. Not - used on all platforms, and not generally necessary for Python - extensions, which typically export exactly one symbol: "init" + - extension_name. - swig_opts : [string] - any extra options to pass to SWIG if a source file has the .i - extension. - depends : [string] - list of files that the extension depends on - language : string - extension language (i.e. "c", "c++", "objc"). Will be detected - from the source extensions if not provided. - optional : boolean - specifies that a build failure in the extension should not abort the - build process, but simply not install the failing extension. - """ - - # When adding arguments to this constructor, be sure to update - # setup_keywords in core.py. - def __init__(self, name, sources, - include_dirs=None, - define_macros=None, - undef_macros=None, - library_dirs=None, - libraries=None, - runtime_library_dirs=None, - extra_objects=None, - extra_compile_args=None, - extra_link_args=None, - export_symbols=None, - swig_opts = None, - depends=None, - language=None, - optional=None, - **kw # To catch unknown keywords - ): - if not isinstance(name, str): - raise AssertionError("'name' must be a string") - if not (isinstance(sources, list) and - all(isinstance(v, str) for v in sources)): - raise AssertionError("'sources' must be a list of strings") - - self.name = name - self.sources = sources - self.include_dirs = include_dirs or [] - self.define_macros = define_macros or [] - self.undef_macros = undef_macros or [] - self.library_dirs = library_dirs or [] - self.libraries = libraries or [] - self.runtime_library_dirs = runtime_library_dirs or [] - self.extra_objects = extra_objects or [] - self.extra_compile_args = extra_compile_args or [] - self.extra_link_args = extra_link_args or [] - self.export_symbols = export_symbols or [] - self.swig_opts = swig_opts or [] - self.depends = depends or [] - self.language = language - self.optional = optional - - # If there are unknown keyword options, warn about them - if len(kw) > 0: - options = [repr(option) for option in kw] - options = ', '.join(sorted(options)) - msg = "Unknown Extension options: %s" % options - warnings.warn(msg) - - def __repr__(self): - return '<%s.%s(%r) at %#x>' % ( - self.__class__.__module__, - self.__class__.__qualname__, - self.name, - id(self)) - - -def read_setup_file(filename): - """Reads a Setup file and returns Extension instances.""" - from distutils.sysconfig import (parse_makefile, expand_makefile_vars, - _variable_rx) - - from distutils.text_file import TextFile - from distutils.util import split_quoted - - # First pass over the file to gather "VAR = VALUE" assignments. - vars = parse_makefile(filename) - - # Second pass to gobble up the real content: lines of the form - # ... [ ...] [ ...] [ ...] - file = TextFile(filename, - strip_comments=1, skip_blanks=1, join_lines=1, - lstrip_ws=1, rstrip_ws=1) - try: - extensions = [] - - while True: - line = file.readline() - if line is None: # eof - break - if re.match(_variable_rx, line): # VAR=VALUE, handled in first pass - continue - - if line[0] == line[-1] == "*": - file.warn("'%s' lines not handled yet" % line) - continue - - line = expand_makefile_vars(line, vars) - words = split_quoted(line) - - # NB. this parses a slightly different syntax than the old - # makesetup script: here, there must be exactly one extension per - # line, and it must be the first word of the line. I have no idea - # why the old syntax supported multiple extensions per line, as - # they all wind up being the same. - - module = words[0] - ext = Extension(module, []) - append_next_word = None - - for word in words[1:]: - if append_next_word is not None: - append_next_word.append(word) - append_next_word = None - continue - - suffix = os.path.splitext(word)[1] - switch = word[0:2] ; value = word[2:] - - if suffix in (".c", ".cc", ".cpp", ".cxx", ".c++", ".m", ".mm"): - # hmm, should we do something about C vs. C++ sources? - # or leave it up to the CCompiler implementation to - # worry about? - ext.sources.append(word) - elif switch == "-I": - ext.include_dirs.append(value) - elif switch == "-D": - equals = value.find("=") - if equals == -1: # bare "-DFOO" -- no value - ext.define_macros.append((value, None)) - else: # "-DFOO=blah" - ext.define_macros.append((value[0:equals], - value[equals+2:])) - elif switch == "-U": - ext.undef_macros.append(value) - elif switch == "-C": # only here 'cause makesetup has it! - ext.extra_compile_args.append(word) - elif switch == "-l": - ext.libraries.append(value) - elif switch == "-L": - ext.library_dirs.append(value) - elif switch == "-R": - ext.runtime_library_dirs.append(value) - elif word == "-rpath": - append_next_word = ext.runtime_library_dirs - elif word == "-Xlinker": - append_next_word = ext.extra_link_args - elif word == "-Xcompiler": - append_next_word = ext.extra_compile_args - elif switch == "-u": - ext.extra_link_args.append(word) - if not value: - append_next_word = ext.extra_link_args - elif suffix in (".a", ".so", ".sl", ".o", ".dylib"): - # NB. a really faithful emulation of makesetup would - # append a .o file to extra_objects only if it - # had a slash in it; otherwise, it would s/.o/.c/ - # and append it to sources. Hmmmm. - ext.extra_objects.append(word) - else: - file.warn("unrecognized argument '%s'" % word) - - extensions.append(ext) - finally: - file.close() - - return extensions diff --git a/python/Lib/distutils/fancy_getopt.py b/python/Lib/distutils/fancy_getopt.py deleted file mode 100644 index a749dc7..0000000 --- a/python/Lib/distutils/fancy_getopt.py +++ /dev/null @@ -1,457 +0,0 @@ -"""distutils.fancy_getopt - -Wrapper around the standard getopt module that provides the following -additional features: - * short and long options are tied together - * options have help strings, so fancy_getopt could potentially - create a complete usage summary - * options set attributes of a passed-in object -""" - -import sys, string, re -import getopt -from distutils.errors import * - -# Much like command_re in distutils.core, this is close to but not quite -# the same as a Python NAME -- except, in the spirit of most GNU -# utilities, we use '-' in place of '_'. (The spirit of LISP lives on!) -# The similarities to NAME are again not a coincidence... -longopt_pat = r'[a-zA-Z](?:[a-zA-Z0-9-]*)' -longopt_re = re.compile(r'^%s$' % longopt_pat) - -# For recognizing "negative alias" options, eg. "quiet=!verbose" -neg_alias_re = re.compile("^(%s)=!(%s)$" % (longopt_pat, longopt_pat)) - -# This is used to translate long options to legitimate Python identifiers -# (for use as attributes of some object). -longopt_xlate = str.maketrans('-', '_') - -class FancyGetopt: - """Wrapper around the standard 'getopt()' module that provides some - handy extra functionality: - * short and long options are tied together - * options have help strings, and help text can be assembled - from them - * options set attributes of a passed-in object - * boolean options can have "negative aliases" -- eg. if - --quiet is the "negative alias" of --verbose, then "--quiet" - on the command line sets 'verbose' to false - """ - - def __init__(self, option_table=None): - # The option table is (currently) a list of tuples. The - # tuples may have 3 or four values: - # (long_option, short_option, help_string [, repeatable]) - # if an option takes an argument, its long_option should have '=' - # appended; short_option should just be a single character, no ':' - # in any case. If a long_option doesn't have a corresponding - # short_option, short_option should be None. All option tuples - # must have long options. - self.option_table = option_table - - # 'option_index' maps long option names to entries in the option - # table (ie. those 3-tuples). - self.option_index = {} - if self.option_table: - self._build_index() - - # 'alias' records (duh) alias options; {'foo': 'bar'} means - # --foo is an alias for --bar - self.alias = {} - - # 'negative_alias' keeps track of options that are the boolean - # opposite of some other option - self.negative_alias = {} - - # These keep track of the information in the option table. We - # don't actually populate these structures until we're ready to - # parse the command-line, since the 'option_table' passed in here - # isn't necessarily the final word. - self.short_opts = [] - self.long_opts = [] - self.short2long = {} - self.attr_name = {} - self.takes_arg = {} - - # And 'option_order' is filled up in 'getopt()'; it records the - # original order of options (and their values) on the command-line, - # but expands short options, converts aliases, etc. - self.option_order = [] - - def _build_index(self): - self.option_index.clear() - for option in self.option_table: - self.option_index[option[0]] = option - - def set_option_table(self, option_table): - self.option_table = option_table - self._build_index() - - def add_option(self, long_option, short_option=None, help_string=None): - if long_option in self.option_index: - raise DistutilsGetoptError( - "option conflict: already an option '%s'" % long_option) - else: - option = (long_option, short_option, help_string) - self.option_table.append(option) - self.option_index[long_option] = option - - def has_option(self, long_option): - """Return true if the option table for this parser has an - option with long name 'long_option'.""" - return long_option in self.option_index - - def get_attr_name(self, long_option): - """Translate long option name 'long_option' to the form it - has as an attribute of some object: ie., translate hyphens - to underscores.""" - return long_option.translate(longopt_xlate) - - def _check_alias_dict(self, aliases, what): - assert isinstance(aliases, dict) - for (alias, opt) in aliases.items(): - if alias not in self.option_index: - raise DistutilsGetoptError(("invalid %s '%s': " - "option '%s' not defined") % (what, alias, alias)) - if opt not in self.option_index: - raise DistutilsGetoptError(("invalid %s '%s': " - "aliased option '%s' not defined") % (what, alias, opt)) - - def set_aliases(self, alias): - """Set the aliases for this option parser.""" - self._check_alias_dict(alias, "alias") - self.alias = alias - - def set_negative_aliases(self, negative_alias): - """Set the negative aliases for this option parser. - 'negative_alias' should be a dictionary mapping option names to - option names, both the key and value must already be defined - in the option table.""" - self._check_alias_dict(negative_alias, "negative alias") - self.negative_alias = negative_alias - - def _grok_option_table(self): - """Populate the various data structures that keep tabs on the - option table. Called by 'getopt()' before it can do anything - worthwhile. - """ - self.long_opts = [] - self.short_opts = [] - self.short2long.clear() - self.repeat = {} - - for option in self.option_table: - if len(option) == 3: - long, short, help = option - repeat = 0 - elif len(option) == 4: - long, short, help, repeat = option - else: - # the option table is part of the code, so simply - # assert that it is correct - raise ValueError("invalid option tuple: %r" % (option,)) - - # Type- and value-check the option names - if not isinstance(long, str) or len(long) < 2: - raise DistutilsGetoptError(("invalid long option '%s': " - "must be a string of length >= 2") % long) - - if (not ((short is None) or - (isinstance(short, str) and len(short) == 1))): - raise DistutilsGetoptError("invalid short option '%s': " - "must a single character or None" % short) - - self.repeat[long] = repeat - self.long_opts.append(long) - - if long[-1] == '=': # option takes an argument? - if short: short = short + ':' - long = long[0:-1] - self.takes_arg[long] = 1 - else: - # Is option is a "negative alias" for some other option (eg. - # "quiet" == "!verbose")? - alias_to = self.negative_alias.get(long) - if alias_to is not None: - if self.takes_arg[alias_to]: - raise DistutilsGetoptError( - "invalid negative alias '%s': " - "aliased option '%s' takes a value" - % (long, alias_to)) - - self.long_opts[-1] = long # XXX redundant?! - self.takes_arg[long] = 0 - - # If this is an alias option, make sure its "takes arg" flag is - # the same as the option it's aliased to. - alias_to = self.alias.get(long) - if alias_to is not None: - if self.takes_arg[long] != self.takes_arg[alias_to]: - raise DistutilsGetoptError( - "invalid alias '%s': inconsistent with " - "aliased option '%s' (one of them takes a value, " - "the other doesn't" - % (long, alias_to)) - - # Now enforce some bondage on the long option name, so we can - # later translate it to an attribute name on some object. Have - # to do this a bit late to make sure we've removed any trailing - # '='. - if not longopt_re.match(long): - raise DistutilsGetoptError( - "invalid long option name '%s' " - "(must be letters, numbers, hyphens only" % long) - - self.attr_name[long] = self.get_attr_name(long) - if short: - self.short_opts.append(short) - self.short2long[short[0]] = long - - def getopt(self, args=None, object=None): - """Parse command-line options in args. Store as attributes on object. - - If 'args' is None or not supplied, uses 'sys.argv[1:]'. If - 'object' is None or not supplied, creates a new OptionDummy - object, stores option values there, and returns a tuple (args, - object). If 'object' is supplied, it is modified in place and - 'getopt()' just returns 'args'; in both cases, the returned - 'args' is a modified copy of the passed-in 'args' list, which - is left untouched. - """ - if args is None: - args = sys.argv[1:] - if object is None: - object = OptionDummy() - created_object = True - else: - created_object = False - - self._grok_option_table() - - short_opts = ' '.join(self.short_opts) - try: - opts, args = getopt.getopt(args, short_opts, self.long_opts) - except getopt.error as msg: - raise DistutilsArgError(msg) - - for opt, val in opts: - if len(opt) == 2 and opt[0] == '-': # it's a short option - opt = self.short2long[opt[1]] - else: - assert len(opt) > 2 and opt[:2] == '--' - opt = opt[2:] - - alias = self.alias.get(opt) - if alias: - opt = alias - - if not self.takes_arg[opt]: # boolean option? - assert val == '', "boolean option can't have value" - alias = self.negative_alias.get(opt) - if alias: - opt = alias - val = 0 - else: - val = 1 - - attr = self.attr_name[opt] - # The only repeating option at the moment is 'verbose'. - # It has a negative option -q quiet, which should set verbose = 0. - if val and self.repeat.get(attr) is not None: - val = getattr(object, attr, 0) + 1 - setattr(object, attr, val) - self.option_order.append((opt, val)) - - # for opts - if created_object: - return args, object - else: - return args - - def get_option_order(self): - """Returns the list of (option, value) tuples processed by the - previous run of 'getopt()'. Raises RuntimeError if - 'getopt()' hasn't been called yet. - """ - if self.option_order is None: - raise RuntimeError("'getopt()' hasn't been called yet") - else: - return self.option_order - - def generate_help(self, header=None): - """Generate help text (a list of strings, one per suggested line of - output) from the option table for this FancyGetopt object. - """ - # Blithely assume the option table is good: probably wouldn't call - # 'generate_help()' unless you've already called 'getopt()'. - - # First pass: determine maximum length of long option names - max_opt = 0 - for option in self.option_table: - long = option[0] - short = option[1] - l = len(long) - if long[-1] == '=': - l = l - 1 - if short is not None: - l = l + 5 # " (-x)" where short == 'x' - if l > max_opt: - max_opt = l - - opt_width = max_opt + 2 + 2 + 2 # room for indent + dashes + gutter - - # Typical help block looks like this: - # --foo controls foonabulation - # Help block for longest option looks like this: - # --flimflam set the flim-flam level - # and with wrapped text: - # --flimflam set the flim-flam level (must be between - # 0 and 100, except on Tuesdays) - # Options with short names will have the short name shown (but - # it doesn't contribute to max_opt): - # --foo (-f) controls foonabulation - # If adding the short option would make the left column too wide, - # we push the explanation off to the next line - # --flimflam (-l) - # set the flim-flam level - # Important parameters: - # - 2 spaces before option block start lines - # - 2 dashes for each long option name - # - min. 2 spaces between option and explanation (gutter) - # - 5 characters (incl. space) for short option name - - # Now generate lines of help text. (If 80 columns were good enough - # for Jesus, then 78 columns are good enough for me!) - line_width = 78 - text_width = line_width - opt_width - big_indent = ' ' * opt_width - if header: - lines = [header] - else: - lines = ['Option summary:'] - - for option in self.option_table: - long, short, help = option[:3] - text = wrap_text(help, text_width) - if long[-1] == '=': - long = long[0:-1] - - # Case 1: no short option at all (makes life easy) - if short is None: - if text: - lines.append(" --%-*s %s" % (max_opt, long, text[0])) - else: - lines.append(" --%-*s " % (max_opt, long)) - - # Case 2: we have a short option, so we have to include it - # just after the long option - else: - opt_names = "%s (-%s)" % (long, short) - if text: - lines.append(" --%-*s %s" % - (max_opt, opt_names, text[0])) - else: - lines.append(" --%-*s" % opt_names) - - for l in text[1:]: - lines.append(big_indent + l) - return lines - - def print_help(self, header=None, file=None): - if file is None: - file = sys.stdout - for line in self.generate_help(header): - file.write(line + "\n") - - -def fancy_getopt(options, negative_opt, object, args): - parser = FancyGetopt(options) - parser.set_negative_aliases(negative_opt) - return parser.getopt(args, object) - - -WS_TRANS = {ord(_wschar) : ' ' for _wschar in string.whitespace} - -def wrap_text(text, width): - """wrap_text(text : string, width : int) -> [string] - - Split 'text' into multiple lines of no more than 'width' characters - each, and return the list of strings that results. - """ - if text is None: - return [] - if len(text) <= width: - return [text] - - text = text.expandtabs() - text = text.translate(WS_TRANS) - chunks = re.split(r'( +|-+)', text) - chunks = [ch for ch in chunks if ch] # ' - ' results in empty strings - lines = [] - - while chunks: - cur_line = [] # list of chunks (to-be-joined) - cur_len = 0 # length of current line - - while chunks: - l = len(chunks[0]) - if cur_len + l <= width: # can squeeze (at least) this chunk in - cur_line.append(chunks[0]) - del chunks[0] - cur_len = cur_len + l - else: # this line is full - # drop last chunk if all space - if cur_line and cur_line[-1][0] == ' ': - del cur_line[-1] - break - - if chunks: # any chunks left to process? - # if the current line is still empty, then we had a single - # chunk that's too big too fit on a line -- so we break - # down and break it up at the line width - if cur_len == 0: - cur_line.append(chunks[0][0:width]) - chunks[0] = chunks[0][width:] - - # all-whitespace chunks at the end of a line can be discarded - # (and we know from the re.split above that if a chunk has - # *any* whitespace, it is *all* whitespace) - if chunks[0][0] == ' ': - del chunks[0] - - # and store this line in the list-of-all-lines -- as a single - # string, of course! - lines.append(''.join(cur_line)) - - return lines - - -def translate_longopt(opt): - """Convert a long option name to a valid Python identifier by - changing "-" to "_". - """ - return opt.translate(longopt_xlate) - - -class OptionDummy: - """Dummy class just used as a place to hold command-line option - values as instance attributes.""" - - def __init__(self, options=[]): - """Create a new OptionDummy instance. The attributes listed in - 'options' will be initialized to None.""" - for opt in options: - setattr(self, opt, None) - - -if __name__ == "__main__": - text = """\ -Tra-la-la, supercalifragilisticexpialidocious. -How *do* you spell that odd word, anyways? -(Someone ask Mary -- she'll know [or she'll -say, "How should I know?"].)""" - - for w in (10, 20, 30, 40): - print("width: %d" % w) - print("\n".join(wrap_text(text, w))) - print() diff --git a/python/Lib/distutils/file_util.py b/python/Lib/distutils/file_util.py deleted file mode 100644 index dfd19fc..0000000 --- a/python/Lib/distutils/file_util.py +++ /dev/null @@ -1,238 +0,0 @@ -"""distutils.file_util - -Utility functions for operating on single files. -""" - -import os -from distutils.errors import DistutilsFileError -from distutils import log - -# for generating verbose output in 'copy_file()' -_copy_action = { None: 'copying', - 'hard': 'hard linking', - 'sym': 'symbolically linking' } - - -def _copy_file_contents(src, dst, buffer_size=16*1024): - """Copy the file 'src' to 'dst'; both must be filenames. Any error - opening either file, reading from 'src', or writing to 'dst', raises - DistutilsFileError. Data is read/written in chunks of 'buffer_size' - bytes (default 16k). No attempt is made to handle anything apart from - regular files. - """ - # Stolen from shutil module in the standard library, but with - # custom error-handling added. - fsrc = None - fdst = None - try: - try: - fsrc = open(src, 'rb') - except OSError as e: - raise DistutilsFileError("could not open '%s': %s" % (src, e.strerror)) - - if os.path.exists(dst): - try: - os.unlink(dst) - except OSError as e: - raise DistutilsFileError( - "could not delete '%s': %s" % (dst, e.strerror)) - - try: - fdst = open(dst, 'wb') - except OSError as e: - raise DistutilsFileError( - "could not create '%s': %s" % (dst, e.strerror)) - - while True: - try: - buf = fsrc.read(buffer_size) - except OSError as e: - raise DistutilsFileError( - "could not read from '%s': %s" % (src, e.strerror)) - - if not buf: - break - - try: - fdst.write(buf) - except OSError as e: - raise DistutilsFileError( - "could not write to '%s': %s" % (dst, e.strerror)) - finally: - if fdst: - fdst.close() - if fsrc: - fsrc.close() - -def copy_file(src, dst, preserve_mode=1, preserve_times=1, update=0, - link=None, verbose=1, dry_run=0): - """Copy a file 'src' to 'dst'. If 'dst' is a directory, then 'src' is - copied there with the same name; otherwise, it must be a filename. (If - the file exists, it will be ruthlessly clobbered.) If 'preserve_mode' - is true (the default), the file's mode (type and permission bits, or - whatever is analogous on the current platform) is copied. If - 'preserve_times' is true (the default), the last-modified and - last-access times are copied as well. If 'update' is true, 'src' will - only be copied if 'dst' does not exist, or if 'dst' does exist but is - older than 'src'. - - 'link' allows you to make hard links (os.link) or symbolic links - (os.symlink) instead of copying: set it to "hard" or "sym"; if it is - None (the default), files are copied. Don't set 'link' on systems that - don't support it: 'copy_file()' doesn't check if hard or symbolic - linking is available. If hardlink fails, falls back to - _copy_file_contents(). - - Under Mac OS, uses the native file copy function in macostools; on - other systems, uses '_copy_file_contents()' to copy file contents. - - Return a tuple (dest_name, copied): 'dest_name' is the actual name of - the output file, and 'copied' is true if the file was copied (or would - have been copied, if 'dry_run' true). - """ - # XXX if the destination file already exists, we clobber it if - # copying, but blow up if linking. Hmmm. And I don't know what - # macostools.copyfile() does. Should definitely be consistent, and - # should probably blow up if destination exists and we would be - # changing it (ie. it's not already a hard/soft link to src OR - # (not update) and (src newer than dst). - - from distutils.dep_util import newer - from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE - - if not os.path.isfile(src): - raise DistutilsFileError( - "can't copy '%s': doesn't exist or not a regular file" % src) - - if os.path.isdir(dst): - dir = dst - dst = os.path.join(dst, os.path.basename(src)) - else: - dir = os.path.dirname(dst) - - if update and not newer(src, dst): - if verbose >= 1: - log.debug("not copying %s (output up-to-date)", src) - return (dst, 0) - - try: - action = _copy_action[link] - except KeyError: - raise ValueError("invalid value '%s' for 'link' argument" % link) - - if verbose >= 1: - if os.path.basename(dst) == os.path.basename(src): - log.info("%s %s -> %s", action, src, dir) - else: - log.info("%s %s -> %s", action, src, dst) - - if dry_run: - return (dst, 1) - - # If linking (hard or symbolic), use the appropriate system call - # (Unix only, of course, but that's the caller's responsibility) - elif link == 'hard': - if not (os.path.exists(dst) and os.path.samefile(src, dst)): - try: - os.link(src, dst) - return (dst, 1) - except OSError: - # If hard linking fails, fall back on copying file - # (some special filesystems don't support hard linking - # even under Unix, see issue #8876). - pass - elif link == 'sym': - if not (os.path.exists(dst) and os.path.samefile(src, dst)): - os.symlink(src, dst) - return (dst, 1) - - # Otherwise (non-Mac, not linking), copy the file contents and - # (optionally) copy the times and mode. - _copy_file_contents(src, dst) - if preserve_mode or preserve_times: - st = os.stat(src) - - # According to David Ascher , utime() should be done - # before chmod() (at least under NT). - if preserve_times: - os.utime(dst, (st[ST_ATIME], st[ST_MTIME])) - if preserve_mode: - os.chmod(dst, S_IMODE(st[ST_MODE])) - - return (dst, 1) - - -# XXX I suspect this is Unix-specific -- need porting help! -def move_file (src, dst, - verbose=1, - dry_run=0): - - """Move a file 'src' to 'dst'. If 'dst' is a directory, the file will - be moved into it with the same name; otherwise, 'src' is just renamed - to 'dst'. Return the new full name of the file. - - Handles cross-device moves on Unix using 'copy_file()'. What about - other systems??? - """ - from os.path import exists, isfile, isdir, basename, dirname - import errno - - if verbose >= 1: - log.info("moving %s -> %s", src, dst) - - if dry_run: - return dst - - if not isfile(src): - raise DistutilsFileError("can't move '%s': not a regular file" % src) - - if isdir(dst): - dst = os.path.join(dst, basename(src)) - elif exists(dst): - raise DistutilsFileError( - "can't move '%s': destination '%s' already exists" % - (src, dst)) - - if not isdir(dirname(dst)): - raise DistutilsFileError( - "can't move '%s': destination '%s' not a valid path" % - (src, dst)) - - copy_it = False - try: - os.rename(src, dst) - except OSError as e: - (num, msg) = e.args - if num == errno.EXDEV: - copy_it = True - else: - raise DistutilsFileError( - "couldn't move '%s' to '%s': %s" % (src, dst, msg)) - - if copy_it: - copy_file(src, dst, verbose=verbose) - try: - os.unlink(src) - except OSError as e: - (num, msg) = e.args - try: - os.unlink(dst) - except OSError: - pass - raise DistutilsFileError( - "couldn't move '%s' to '%s' by copy/delete: " - "delete '%s' failed: %s" - % (src, dst, src, msg)) - return dst - - -def write_file (filename, contents): - """Create a file with the specified name and write 'contents' (a - sequence of strings without line terminators) to it. - """ - f = open(filename, "w") - try: - for line in contents: - f.write(line + "\n") - finally: - f.close() diff --git a/python/Lib/distutils/filelist.py b/python/Lib/distutils/filelist.py deleted file mode 100644 index 27180a5..0000000 --- a/python/Lib/distutils/filelist.py +++ /dev/null @@ -1,327 +0,0 @@ -"""distutils.filelist - -Provides the FileList class, used for poking about the filesystem -and building lists of files. -""" - -import os, re -import fnmatch -import functools -from distutils.util import convert_path -from distutils.errors import DistutilsTemplateError, DistutilsInternalError -from distutils import log - -class FileList: - """A list of files built by on exploring the filesystem and filtered by - applying various patterns to what we find there. - - Instance attributes: - dir - directory from which files will be taken -- only used if - 'allfiles' not supplied to constructor - files - list of filenames currently being built/filtered/manipulated - allfiles - complete list of files under consideration (ie. without any - filtering applied) - """ - - def __init__(self, warn=None, debug_print=None): - # ignore argument to FileList, but keep them for backwards - # compatibility - self.allfiles = None - self.files = [] - - def set_allfiles(self, allfiles): - self.allfiles = allfiles - - def findall(self, dir=os.curdir): - self.allfiles = findall(dir) - - def debug_print(self, msg): - """Print 'msg' to stdout if the global DEBUG (taken from the - DISTUTILS_DEBUG environment variable) flag is true. - """ - from distutils.debug import DEBUG - if DEBUG: - print(msg) - - # -- List-like methods --------------------------------------------- - - def append(self, item): - self.files.append(item) - - def extend(self, items): - self.files.extend(items) - - def sort(self): - # Not a strict lexical sort! - sortable_files = sorted(map(os.path.split, self.files)) - self.files = [] - for sort_tuple in sortable_files: - self.files.append(os.path.join(*sort_tuple)) - - - # -- Other miscellaneous utility methods --------------------------- - - def remove_duplicates(self): - # Assumes list has been sorted! - for i in range(len(self.files) - 1, 0, -1): - if self.files[i] == self.files[i - 1]: - del self.files[i] - - - # -- "File template" methods --------------------------------------- - - def _parse_template_line(self, line): - words = line.split() - action = words[0] - - patterns = dir = dir_pattern = None - - if action in ('include', 'exclude', - 'global-include', 'global-exclude'): - if len(words) < 2: - raise DistutilsTemplateError( - "'%s' expects ..." % action) - patterns = [convert_path(w) for w in words[1:]] - elif action in ('recursive-include', 'recursive-exclude'): - if len(words) < 3: - raise DistutilsTemplateError( - "'%s' expects

    Gf|3I*brB<5 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

    TooOF1Gf84Jf5le%r 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

j$QfrYjaI$?N#S5VG4ZzgH(`#X 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�E7}B%Re``zye5NU0d`j-SAv!&QDvha0ygIO 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 diff --git a/python/DLLs/_elementtree.pyd b/python/DLLs/_elementtree.pyd deleted file mode 100644 index 3d46cf68ee53a815ccfe51988fe68579c6413b6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126848 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