diff --git a/uno/.gitrepo b/uno/.gitrepo deleted file mode 100644 index 787df601..00000000 --- a/uno/.gitrepo +++ /dev/null @@ -1,12 +0,0 @@ -; DO NOT EDIT (unless you know what you are doing) -; -; This subdirectory is a git "subrepo", and this file is maintained by the -; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme -; -[subrepo] - remote = https://github.com/prrvchr/uno.git - branch = master - commit = cc757633452c98b2639eb75d5ce8ac4857620807 - method = merge - cmdver = 0.4.3 - parent = 569deb02b5a5214571427d4fea1e142f4f874d6e diff --git a/uno/LICENSE b/uno/LICENSE deleted file mode 100644 index f288702d..00000000 --- a/uno/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/uno/dialog/addressbook/DialogStrings_en_US.default b/uno/dialog/addressbook/DialogStrings_en_US.default deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/dialog/addressbook/DialogStrings_en_US.properties b/uno/dialog/addressbook/DialogStrings_en_US.properties deleted file mode 100644 index a5cb9a4d..00000000 --- a/uno/dialog/addressbook/DialogStrings_en_US.properties +++ /dev/null @@ -1,48 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.FixedLine1.HelpText= -OptionsDialog.FixedLine1.Label=View data -OptionsDialog.CommandButton1.HelpText= -OptionsDialog.CommandButton1.Label=View DataBase - -LogWindow.HelpText= -LogWindow.Title= -LogWindow.FixedLine1.HelpText= -LogWindow.FixedLine1.Label=Logger settings -LogWindow.Label1.HelpText= -LogWindow.Label1.Label=Available loggers: -LogWindow.ListBox1.HelpText= -LogWindow.ListBox1.Text= -LogWindow.CheckBox1.HelpText= -LogWindow.CheckBox1.Label=Activate log -LogWindow.Label2.HelpText= -LogWindow.Label2.Label=Output: -LogWindow.OptionButton1.HelpText= -LogWindow.OptionButton1.Label=Console -LogWindow.OptionButton2.HelpText= -LogWindow.OptionButton2.Label=File -LogWindow.CommandButton1.HelpText= -LogWindow.CommandButton1.Label=View log -LogWindow.Label3.HelpText= -LogWindow.Label3.Label=Level: -LogWindow.ListBox2.HelpText= -LogWindow.ListBox2.Text= -LogWindow.ListBox2.StringItemList.0=Sever -LogWindow.ListBox2.StringItemList.1=Warning -LogWindow.ListBox2.StringItemList.2=Info -LogWindow.ListBox2.StringItemList.3=Config -LogWindow.ListBox2.StringItemList.4=Fine -LogWindow.ListBox2.StringItemList.5=Finer -LogWindow.ListBox2.StringItemList.6=Finest -LogWindow.ListBox2.StringItemList.7=All - -LogDialog.HelpText= -LogDialog.Title=Log file - %s -LogDialog.TextField1.HelpText= -LogDialog.TextField1.Text= -LogDialog.CommandButton1.HelpText= -LogDialog.CommandButton1.Label=System Info -LogDialog.CommandButton2.HelpText= -LogDialog.CommandButton2.Label=Reload -LogDialog.CommandButton3.HelpText= -LogDialog.CommandButton3.Label=Close diff --git a/uno/dialog/addressbook/DialogStrings_fr_FR.properties b/uno/dialog/addressbook/DialogStrings_fr_FR.properties deleted file mode 100644 index 1622bfba..00000000 --- a/uno/dialog/addressbook/DialogStrings_fr_FR.properties +++ /dev/null @@ -1,48 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.FixedLine1.HelpText= -OptionsDialog.FixedLine1.Label=Voir les donn\u00e9es -OptionsDialog.CommandButton1.HelpText= -OptionsDialog.CommandButton1.Label=Voir la base de donn\u00e9es - -LogWindow.HelpText= -LogWindow.Title= -LogWindow.FixedLine1.HelpText= -LogWindow.FixedLine1.Label=Options de journalisation -LogWindow.Label1.HelpText= -LogWindow.Label1.Label=Journal disponible: -LogWindow.ListBox1.HelpText= -LogWindow.ListBox1.Text= -LogWindow.CheckBox1.HelpText= -LogWindow.CheckBox1.Label=Activer le journal -LogWindow.Label2.HelpText= -LogWindow.Label2.Label=Sortie: -LogWindow.OptionButton1.HelpText= -LogWindow.OptionButton1.Label=Console -LogWindow.OptionButton2.HelpText= -LogWindow.OptionButton2.Label=Fichier -LogWindow.CommandButton1.HelpText= -LogWindow.CommandButton1.Label=Voir journal -LogWindow.Label3.HelpText= -LogWindow.Label3.Label=Seuil: -LogWindow.ListBox2.HelpText= -LogWindow.ListBox2.Text= -LogWindow.ListBox2.StringItemList.0=Grave -LogWindow.ListBox2.StringItemList.1=Alerte -LogWindow.ListBox2.StringItemList.2=Info -LogWindow.ListBox2.StringItemList.3=Config -LogWindow.ListBox2.StringItemList.4=Basique -LogWindow.ListBox2.StringItemList.5=Fin -LogWindow.ListBox2.StringItemList.6=Tr\u00e9s fin -LogWindow.ListBox2.StringItemList.7=Tout - -LogDialog.HelpText= -LogDialog.Title=Fichier journal - %s -LogDialog.TextField1.HelpText= -LogDialog.TextField1.Text= -LogDialog.CommandButton1.HelpText= -LogDialog.CommandButton1.Label=Info syst\u00e8me -LogDialog.CommandButton2.HelpText= -LogDialog.CommandButton2.Label=Recharger -LogDialog.CommandButton3.HelpText= -LogDialog.CommandButton3.Label=Fermer diff --git a/uno/dialog/addressbook/OptionsDialog.xdl b/uno/dialog/addressbook/OptionsDialog.xdl deleted file mode 100644 index c71d3afd..00000000 --- a/uno/dialog/addressbook/OptionsDialog.xdl +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/uno/dialog/addressbook/OptionsDialog_en_US.default b/uno/dialog/addressbook/OptionsDialog_en_US.default deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/dialog/addressbook/OptionsDialog_en_US.properties b/uno/dialog/addressbook/OptionsDialog_en_US.properties deleted file mode 100644 index aa0dad4d..00000000 --- a/uno/dialog/addressbook/OptionsDialog_en_US.properties +++ /dev/null @@ -1,6 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.FixedLine1.HelpText= -OptionsDialog.FixedLine1.Label=View data -OptionsDialog.CommandButton1.HelpText= -OptionsDialog.CommandButton1.Label=View DataBase diff --git a/uno/dialog/addressbook/OptionsDialog_fr_FR.properties b/uno/dialog/addressbook/OptionsDialog_fr_FR.properties deleted file mode 100644 index 7ef8f96c..00000000 --- a/uno/dialog/addressbook/OptionsDialog_fr_FR.properties +++ /dev/null @@ -1,6 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.FixedLine1.HelpText= -OptionsDialog.FixedLine1.Label=Voir les donn\u00e9es -OptionsDialog.CommandButton1.HelpText= -OptionsDialog.CommandButton1.Label=Voir la base de donn\u00e9es diff --git a/uno/dialog/card/OptionsDialog.xdl b/uno/dialog/card/OptionsDialog.xdl deleted file mode 100644 index 42765b61..00000000 --- a/uno/dialog/card/OptionsDialog.xdl +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/uno/dialog/embedded/OptionsDialog.xdl b/uno/dialog/embedded/OptionsDialog.xdl deleted file mode 100644 index 61526513..00000000 --- a/uno/dialog/embedded/OptionsDialog.xdl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/uno/dialog/embedded/OptionsDialog_en_US.default b/uno/dialog/embedded/OptionsDialog_en_US.default deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/dialog/embedded/OptionsDialog_en_US.properties b/uno/dialog/embedded/OptionsDialog_en_US.properties deleted file mode 100644 index c078b893..00000000 --- a/uno/dialog/embedded/OptionsDialog_en_US.properties +++ /dev/null @@ -1,6 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.Label1.HelpText= -OptionsDialog.Label1.Label=Driver version: -OptionsDialog.Label2.HelpText= -OptionsDialog.Label2.Label= diff --git a/uno/dialog/embedded/OptionsDialog_fr_FR.properties b/uno/dialog/embedded/OptionsDialog_fr_FR.properties deleted file mode 100644 index 1b4de163..00000000 --- a/uno/dialog/embedded/OptionsDialog_fr_FR.properties +++ /dev/null @@ -1,6 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.Label1.HelpText= -OptionsDialog.Label1.Label=Version du pilote: -OptionsDialog.Label2.HelpText= -OptionsDialog.Label2.Label= diff --git a/uno/dialog/grid/GridWindow.xdl b/uno/dialog/grid/GridWindow.xdl deleted file mode 100644 index 7ebddc42..00000000 --- a/uno/dialog/grid/GridWindow.xdl +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - diff --git a/uno/dialog/grid/GridWindow_en_US.default b/uno/dialog/grid/GridWindow_en_US.default deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/dialog/grid/GridWindow_en_US.properties b/uno/dialog/grid/GridWindow_en_US.properties deleted file mode 100644 index 9c3c60b4..00000000 --- a/uno/dialog/grid/GridWindow_en_US.properties +++ /dev/null @@ -1,8 +0,0 @@ -GridWindow.HelpText= -GridWindow.Title= -GridWindow.CommandButton1.HelpText=Organize columns -GridWindow.CommandButton1.Label=+ -GridWindow.Label1.HelpText=Columns to display -GridWindow.Label1.Label=Show columns: -GridWindow.ListBox1.HelpText=Define the name of the columns to display -GridWindow.ListBox1.Text= diff --git a/uno/dialog/grid/GridWindow_fr_FR.properties b/uno/dialog/grid/GridWindow_fr_FR.properties deleted file mode 100644 index 5c5089cc..00000000 --- a/uno/dialog/grid/GridWindow_fr_FR.properties +++ /dev/null @@ -1,8 +0,0 @@ -GridWindow.HelpText= -GridWindow.Title= -GridWindow.CommandButton1.HelpText=Organiser les colonnes -GridWindow.CommandButton1.Label=+ -GridWindow.Label1.HelpText=Colonnes \u00e0 afficher -GridWindow.Label1.Label=Afficher les colonnes: -GridWindow.ListBox1.HelpText=D\u00e9finir le nom des colonnes \u00e0 afficher -GridWindow.ListBox1.Text= diff --git a/uno/dialog/grid/column-0.png b/uno/dialog/grid/column-0.png deleted file mode 100644 index e2d508b9..00000000 Binary files a/uno/dialog/grid/column-0.png and /dev/null differ diff --git a/uno/dialog/grid/column-1.png b/uno/dialog/grid/column-1.png deleted file mode 100644 index 714a3e70..00000000 Binary files a/uno/dialog/grid/column-1.png and /dev/null differ diff --git a/uno/dialog/grid/privilege-0.png b/uno/dialog/grid/privilege-0.png deleted file mode 100644 index 5c408f0a..00000000 Binary files a/uno/dialog/grid/privilege-0.png and /dev/null differ diff --git a/uno/dialog/grid/privilege-1.png b/uno/dialog/grid/privilege-1.png deleted file mode 100644 index a89d5122..00000000 Binary files a/uno/dialog/grid/privilege-1.png and /dev/null differ diff --git a/uno/dialog/grid/privilege-2.png b/uno/dialog/grid/privilege-2.png deleted file mode 100644 index 423e0d1f..00000000 Binary files a/uno/dialog/grid/privilege-2.png and /dev/null differ diff --git a/uno/dialog/grid/privilege-3.png b/uno/dialog/grid/privilege-3.png deleted file mode 100644 index e1397f3f..00000000 Binary files a/uno/dialog/grid/privilege-3.png and /dev/null differ diff --git a/uno/dialog/grid/privilege-4.png b/uno/dialog/grid/privilege-4.png deleted file mode 100644 index 9c4f074f..00000000 Binary files a/uno/dialog/grid/privilege-4.png and /dev/null differ diff --git a/uno/dialog/grid/privilege-5.png b/uno/dialog/grid/privilege-5.png deleted file mode 100644 index 6e5c4d00..00000000 Binary files a/uno/dialog/grid/privilege-5.png and /dev/null differ diff --git a/uno/dialog/jdbc/OptionDialog.xdl b/uno/dialog/jdbc/OptionDialog.xdl deleted file mode 100644 index d5b8a387..00000000 --- a/uno/dialog/jdbc/OptionDialog.xdl +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/uno/dialog/jdbc/OptionDialog_en_US.default b/uno/dialog/jdbc/OptionDialog_en_US.default deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/dialog/jdbc/OptionDialog_en_US.properties b/uno/dialog/jdbc/OptionDialog_en_US.properties deleted file mode 100644 index aebd193f..00000000 --- a/uno/dialog/jdbc/OptionDialog_en_US.properties +++ /dev/null @@ -1,26 +0,0 @@ -OptionDialog.HelpText= -OptionDialog.Title= -OptionDialog.FixedLine1.HelpText= -OptionDialog.FixedLine1.Label=UNO Services -OptionDialog.Label1.HelpText= -OptionDialog.Label1.Label=Driver: -OptionDialog.OptionButton1.HelpText= -OptionDialog.OptionButton1.Label=com.sun.star.sdbc.Driver -OptionDialog.OptionButton2.HelpText= -OptionDialog.OptionButton2.Label=com.sun.star.sdbcx.Driver -OptionDialog.Label2.HelpText= -OptionDialog.Label2.Label=API level: -OptionDialog.OptionButton3.HelpText= -OptionDialog.OptionButton3.Label=css.sdbc -OptionDialog.OptionButton4.HelpText= -OptionDialog.OptionButton4.Label=css.sdbcx -OptionDialog.OptionButton5.HelpText= -OptionDialog.OptionButton5.Label=css.sdb -OptionDialog.CheckBox1.HelpText= -OptionDialog.CheckBox1.Label=View system tables -OptionDialog.CheckBox2.HelpText= -OptionDialog.CheckBox2.Label=Use bookmarks -OptionDialog.CheckBox3.HelpText= -OptionDialog.CheckBox3.Label=Force SQL mode -OptionDialog.Label3.HelpText= -OptionDialog.Label3.Label=Changes will take effect after restarting LibreOffice... diff --git a/uno/dialog/jdbc/OptionDialog_fr_FR.properties b/uno/dialog/jdbc/OptionDialog_fr_FR.properties deleted file mode 100644 index 57923b97..00000000 --- a/uno/dialog/jdbc/OptionDialog_fr_FR.properties +++ /dev/null @@ -1,26 +0,0 @@ -OptionDialog.HelpText= -OptionDialog.Title= -OptionDialog.FixedLine1.HelpText= -OptionDialog.FixedLine1.Label=Services UNO -OptionDialog.Label1.HelpText= -OptionDialog.Label1.Label=Pilote: -OptionDialog.OptionButton1.HelpText= -OptionDialog.OptionButton1.Label=com.sun.star.sdbc.Driver -OptionDialog.OptionButton2.HelpText= -OptionDialog.OptionButton2.Label=com.sun.star.sdbcx.Driver -OptionDialog.Label2.HelpText= -OptionDialog.Label2.Label=Niveau API: -OptionDialog.OptionButton3.HelpText= -OptionDialog.OptionButton3.Label=css.sdbc -OptionDialog.OptionButton4.HelpText= -OptionDialog.OptionButton4.Label=css.sdbcx -OptionDialog.OptionButton5.HelpText= -OptionDialog.OptionButton5.Label=css.sdb -OptionDialog.CheckBox1.HelpText= -OptionDialog.CheckBox1.Label=Voir les tables syst\u00e8me -OptionDialog.CheckBox2.HelpText= -OptionDialog.CheckBox2.Label=Utiliser les signets -OptionDialog.CheckBox3.HelpText= -OptionDialog.CheckBox3.Label=Forcer le mode SQL -OptionDialog.Label3.HelpText= -OptionDialog.Label3.Label=Les modifications prendront effet apr\u00e8s le red\u00e9marrage de LibreOffice... diff --git a/uno/dialog/logger/LogDialog.xdl b/uno/dialog/logger/LogDialog.xdl deleted file mode 100644 index 54a0f572..00000000 --- a/uno/dialog/logger/LogDialog.xdl +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - diff --git a/uno/dialog/logger/LogDialog_en_US.default b/uno/dialog/logger/LogDialog_en_US.default deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/dialog/logger/LogDialog_en_US.properties b/uno/dialog/logger/LogDialog_en_US.properties deleted file mode 100644 index 724a8b7f..00000000 --- a/uno/dialog/logger/LogDialog_en_US.properties +++ /dev/null @@ -1,8 +0,0 @@ -LogDialog.HelpText= -LogDialog.Title=Log file - %s -LogDialog.TextField1.HelpText= -LogDialog.TextField1.Text= -LogDialog.CommandButton1.HelpText= -LogDialog.CommandButton1.Label=System Info -LogDialog.CommandButton2.HelpText= -LogDialog.CommandButton2.Label=Close diff --git a/uno/dialog/logger/LogDialog_fr_FR.properties b/uno/dialog/logger/LogDialog_fr_FR.properties deleted file mode 100644 index a4b7599d..00000000 --- a/uno/dialog/logger/LogDialog_fr_FR.properties +++ /dev/null @@ -1,8 +0,0 @@ -LogDialog.HelpText= -LogDialog.Title=Fichier journal - %s -LogDialog.TextField1.HelpText= -LogDialog.TextField1.Text= -LogDialog.CommandButton1.HelpText= -LogDialog.CommandButton1.Label=Info syst\u00e8me -LogDialog.CommandButton2.HelpText= -LogDialog.CommandButton2.Label=Fermer diff --git a/uno/dialog/logger/LogWindow.xdl b/uno/dialog/logger/LogWindow.xdl deleted file mode 100644 index 8313cd32..00000000 --- a/uno/dialog/logger/LogWindow.xdl +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/uno/dialog/logger/LogWindow_en_US.default b/uno/dialog/logger/LogWindow_en_US.default deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/dialog/logger/LogWindow_en_US.properties b/uno/dialog/logger/LogWindow_en_US.properties deleted file mode 100644 index d1e37198..00000000 --- a/uno/dialog/logger/LogWindow_en_US.properties +++ /dev/null @@ -1,31 +0,0 @@ -LogWindow.HelpText= -LogWindow.Title= -LogWindow.FixedLine1.HelpText= -LogWindow.FixedLine1.Label=Logger settings -LogWindow.Label1.HelpText= -LogWindow.Label1.Label=Available loggers: -LogWindow.ListBox1.HelpText= -LogWindow.ListBox1.Text= -LogWindow.CheckBox1.HelpText= -LogWindow.CheckBox1.Label=Enable logger -LogWindow.Label2.HelpText= -LogWindow.Label2.Label=Output: -LogWindow.OptionButton1.HelpText= -LogWindow.OptionButton1.Label=Console -LogWindow.OptionButton2.HelpText= -LogWindow.OptionButton2.Label=File -LogWindow.CommandButton1.HelpText= -LogWindow.CommandButton1.Label=View log -LogWindow.Label3.HelpText= -LogWindow.Label3.Label=Level: -LogWindow.ListBox2.HelpText= -LogWindow.ListBox2.Text= -LogWindow.ListBox2.StringItemList.0=Sever -LogWindow.ListBox2.StringItemList.1=Warning -LogWindow.ListBox2.StringItemList.2=Info -LogWindow.ListBox2.StringItemList.3=Config -LogWindow.ListBox2.StringItemList.4=Fine -LogWindow.ListBox2.StringItemList.5=Finer -LogWindow.ListBox2.StringItemList.6=Finest -LogWindow.ListBox2.StringItemList.7=All - diff --git a/uno/dialog/logger/LogWindow_fr_FR.properties b/uno/dialog/logger/LogWindow_fr_FR.properties deleted file mode 100644 index 3af69fce..00000000 --- a/uno/dialog/logger/LogWindow_fr_FR.properties +++ /dev/null @@ -1,31 +0,0 @@ -LogWindow.HelpText= -LogWindow.Title= -LogWindow.FixedLine1.HelpText= -LogWindow.FixedLine1.Label=Options de journalisation -LogWindow.Label1.HelpText= -LogWindow.Label1.Label=Journaux disponibles: -LogWindow.ListBox1.HelpText= -LogWindow.ListBox1.Text= -LogWindow.CheckBox1.HelpText= -LogWindow.CheckBox1.Label=Activer le journal -LogWindow.Label2.HelpText= -LogWindow.Label2.Label=Sortie: -LogWindow.OptionButton1.HelpText= -LogWindow.OptionButton1.Label=Console -LogWindow.OptionButton2.HelpText= -LogWindow.OptionButton2.Label=Fichier -LogWindow.CommandButton1.HelpText= -LogWindow.CommandButton1.Label=Voir journal -LogWindow.Label3.HelpText= -LogWindow.Label3.Label=Seuil: -LogWindow.ListBox2.HelpText= -LogWindow.ListBox2.Text= -LogWindow.ListBox2.StringItemList.0=Grave -LogWindow.ListBox2.StringItemList.1=Alerte -LogWindow.ListBox2.StringItemList.2=Info -LogWindow.ListBox2.StringItemList.3=Config -LogWindow.ListBox2.StringItemList.4=Basique -LogWindow.ListBox2.StringItemList.5=Fin -LogWindow.ListBox2.StringItemList.6=Tr\u00e9s fin -LogWindow.ListBox2.StringItemList.7=Tout - diff --git a/uno/dialog/ucb/DialogStrings_en_US.default b/uno/dialog/ucb/DialogStrings_en_US.default deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/dialog/ucb/DialogStrings_en_US.properties b/uno/dialog/ucb/DialogStrings_en_US.properties deleted file mode 100644 index 744963c8..00000000 --- a/uno/dialog/ucb/DialogStrings_en_US.properties +++ /dev/null @@ -1,53 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.FixedLine1.HelpText= -OptionsDialog.FixedLine1.Label=gDriveOOo settings -OptionsDialog.Label1.HelpText= -OptionsDialog.Label1.Label=Replication interval: -OptionsDialog.NumericField1.HelpText=Replication interval in minutes -OptionsDialog.Label2.HelpText= -OptionsDialog.Label2.Label=View datasource: -OptionsDialog.CommandButton1.HelpText= -OptionsDialog.CommandButton1.Label=View DataBase - -LogWindow.HelpText= -LogWindow.Title= -LogWindow.FixedLine1.HelpText= -LogWindow.FixedLine1.Label=Logger settings -LogWindow.Label1.HelpText= -LogWindow.Label1.Label=Available loggers: -LogWindow.ListBox1.HelpText= -LogWindow.ListBox1.Text= -LogWindow.CheckBox1.HelpText= -LogWindow.CheckBox1.Label=Enable logger -LogWindow.Label2.HelpText= -LogWindow.Label2.Label=Output: -LogWindow.OptionButton1.HelpText= -LogWindow.OptionButton1.Label=Console -LogWindow.OptionButton2.HelpText= -LogWindow.OptionButton2.Label=File -LogWindow.CommandButton1.HelpText= -LogWindow.CommandButton1.Label=View log -LogWindow.Label3.HelpText= -LogWindow.Label3.Label=Level: -LogWindow.ListBox2.HelpText= -LogWindow.ListBox2.Text= -LogWindow.ListBox2.StringItemList.0=Sever -LogWindow.ListBox2.StringItemList.1=Warning -LogWindow.ListBox2.StringItemList.2=Info -LogWindow.ListBox2.StringItemList.3=Config -LogWindow.ListBox2.StringItemList.4=Fine -LogWindow.ListBox2.StringItemList.5=Finer -LogWindow.ListBox2.StringItemList.6=Finest -LogWindow.ListBox2.StringItemList.7=All - -LogDialog.HelpText= -LogDialog.Title=Log file - %s -LogDialog.TextField1.HelpText= -LogDialog.TextField1.Text= -LogDialog.CommandButton1.HelpText= -LogDialog.CommandButton1.Label=System Info -LogDialog.CommandButton2.HelpText= -LogDialog.CommandButton2.Label=Clear -LogDialog.CommandButton3.HelpText= -LogDialog.CommandButton3.Label=Close diff --git a/uno/dialog/ucb/DialogStrings_fr_FR.properties b/uno/dialog/ucb/DialogStrings_fr_FR.properties deleted file mode 100644 index a91d7b93..00000000 --- a/uno/dialog/ucb/DialogStrings_fr_FR.properties +++ /dev/null @@ -1,53 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.FixedLine1.HelpText= -OptionsDialog.FixedLine1.Label=Options gDriveOOo -OptionsDialog.Label1.HelpText= -OptionsDialog.Label1.Label=Intervalle de r\u00e9plication: -OptionsDialog.NumericField1.HelpText=Intervalle de r\u00e9plication en minutes -OptionsDialog.Label2.HelpText= -OptionsDialog.Label2.Label=Voir la source de donn\u00e9es: -OptionsDialog.CommandButton1.HelpText= -OptionsDialog.CommandButton1.Label=Voir la base de donn\u00e9es - -LogWindow.HelpText= -LogWindow.Title= -LogWindow.FixedLine1.HelpText= -LogWindow.FixedLine1.Label=Options de journalisation -LogWindow.Label1.HelpText= -LogWindow.Label1.Label=Journaux disponibles: -LogWindow.ListBox1.HelpText= -LogWindow.ListBox1.Text= -LogWindow.CheckBox1.HelpText= -LogWindow.CheckBox1.Label=Activer le journal -LogWindow.Label2.HelpText= -LogWindow.Label2.Label=Sortie: -LogWindow.OptionButton1.HelpText= -LogWindow.OptionButton1.Label=Console -LogWindow.OptionButton2.HelpText= -LogWindow.OptionButton2.Label=Fichier -LogWindow.CommandButton1.HelpText= -LogWindow.CommandButton1.Label=Voir journal -LogWindow.Label3.HelpText= -LogWindow.Label3.Label=Seuil: -LogWindow.ListBox2.HelpText= -LogWindow.ListBox2.Text= -LogWindow.ListBox2.StringItemList.0=Grave -LogWindow.ListBox2.StringItemList.1=Alerte -LogWindow.ListBox2.StringItemList.2=Info -LogWindow.ListBox2.StringItemList.3=Config -LogWindow.ListBox2.StringItemList.4=Basique -LogWindow.ListBox2.StringItemList.5=Fin -LogWindow.ListBox2.StringItemList.6=Tr\u00e9s fin -LogWindow.ListBox2.StringItemList.7=Tout - -LogDialog.HelpText= -LogDialog.Title=Fichier journal - %s -LogDialog.TextField1.HelpText= -LogDialog.TextField1.Text= -LogDialog.CommandButton1.HelpText= -LogDialog.CommandButton1.Label=Info syst\u00e8me -LogDialog.CommandButton2.HelpText= -LogDialog.CommandButton2.Label=Effacer -LogDialog.CommandButton3.HelpText= -LogDialog.CommandButton3.Label=Fermer diff --git a/uno/dialog/ucb/OptionsDialog.xdl b/uno/dialog/ucb/OptionsDialog.xdl deleted file mode 100644 index eade868f..00000000 --- a/uno/dialog/ucb/OptionsDialog.xdl +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/uno/dialog/ucb/OptionsDialog_en_US.default b/uno/dialog/ucb/OptionsDialog_en_US.default deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/dialog/ucb/OptionsDialog_en_US.properties b/uno/dialog/ucb/OptionsDialog_en_US.properties deleted file mode 100644 index 666840b6..00000000 --- a/uno/dialog/ucb/OptionsDialog_en_US.properties +++ /dev/null @@ -1,12 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.FixedLine1.HelpText= -OptionsDialog.FixedLine1.Label=gDriveOOo settings -OptionsDialog.Label1.HelpText= -OptionsDialog.Label1.Label=Replication interval: -OptionsDialog.NumericField1.HelpText=Replication interval in minutes -OptionsDialog.Label2.HelpText= -OptionsDialog.Label2.Label=View datasource: -OptionsDialog.CommandButton1.HelpText= -OptionsDialog.CommandButton1.Label=View DataBase - diff --git a/uno/dialog/ucb/OptionsDialog_fr_FR.properties b/uno/dialog/ucb/OptionsDialog_fr_FR.properties deleted file mode 100644 index 334f3955..00000000 --- a/uno/dialog/ucb/OptionsDialog_fr_FR.properties +++ /dev/null @@ -1,12 +0,0 @@ -OptionsDialog.HelpText= -OptionsDialog.Title= -OptionsDialog.FixedLine1.HelpText= -OptionsDialog.FixedLine1.Label=Options gDriveOOo -OptionsDialog.Label1.HelpText= -OptionsDialog.Label1.Label=Intervalle de r\u00e9plication: -OptionsDialog.NumericField1.HelpText=Intervalle de r\u00e9plication en minutes -OptionsDialog.Label2.HelpText= -OptionsDialog.Label2.Label=Voir la source de donn\u00e9es: -OptionsDialog.CommandButton1.HelpText= -OptionsDialog.CommandButton1.Label=Voir la base de donn\u00e9es - diff --git a/uno/dialog/wizard/Wizard.xdl b/uno/dialog/wizard/Wizard.xdl deleted file mode 100644 index 28685eaf..00000000 --- a/uno/dialog/wizard/Wizard.xdl +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/uno/dialog/wizard/Wizard_en_US.default b/uno/dialog/wizard/Wizard_en_US.default deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/dialog/wizard/Wizard_en_US.properties b/uno/dialog/wizard/Wizard_en_US.properties deleted file mode 100644 index a08f1aea..00000000 --- a/uno/dialog/wizard/Wizard_en_US.properties +++ /dev/null @@ -1,15 +0,0 @@ -Wizard.HelpText= -Wizard.Title= -Wizard.Roadmap.Text=Steps -Wizard.FixedLine1.HelpText= -Wizard.FixedLine1.Label= -Wizard.CommandButton5.HelpText= -Wizard.CommandButton5.Label=Help -Wizard.CommandButton4.HelpText= -Wizard.CommandButton4.Label=< Back -Wizard.CommandButton3.HelpText= -Wizard.CommandButton3.Label=Next > -Wizard.CommandButton2.HelpText= -Wizard.CommandButton2.Label=Finish -Wizard.CommandButton1.HelpText= -Wizard.CommandButton1.Label=Cancel diff --git a/uno/dialog/wizard/Wizard_fr_FR.properties b/uno/dialog/wizard/Wizard_fr_FR.properties deleted file mode 100644 index 4a12f9db..00000000 --- a/uno/dialog/wizard/Wizard_fr_FR.properties +++ /dev/null @@ -1,15 +0,0 @@ -Wizard.HelpText= -Wizard.Title= -Wizard.Roadmap.Text=\u00c9tapes -Wizard.FixedLine1.HelpText= -Wizard.FixedLine1.Label= -Wizard.CommandButton5.HelpText= -Wizard.CommandButton5.Label=Aide -Wizard.CommandButton4.HelpText= -Wizard.CommandButton4.Label=< Pr\u00e9c\u00e9dant -Wizard.CommandButton3.HelpText= -Wizard.CommandButton3.Label=Suivant > -Wizard.CommandButton2.HelpText= -Wizard.CommandButton2.Label=Terminer -Wizard.CommandButton1.HelpText= -Wizard.CommandButton1.Label=Annuler diff --git a/uno/lib/java/helper/Array.java b/uno/lib/java/helper/Array.java deleted file mode 100644 index 937df1b9..00000000 --- a/uno/lib/java/helper/Array.java +++ /dev/null @@ -1,114 +0,0 @@ -/* -╔════════════════════════════════════════════════════════════════════════════════════╗ -║ ║ -║ Copyright (c) 2020-24 https://prrvchr.github.io ║ -║ ║ -║ 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. ║ -║ ║ -╚════════════════════════════════════════════════════════════════════════════════════╝ -*/ -package io.github.prrvchr.uno.helper; - -import java.util.Arrays; - -import com.sun.star.container.XNameAccess; -import com.sun.star.lib.uno.helper.WeakBase; -import com.sun.star.sdbc.DataType; -import com.sun.star.sdbc.SQLException; -import com.sun.star.sdbc.XArray; -import com.sun.star.sdbc.XResultSet; - - -public class Array - extends WeakBase - implements XArray -{ - - private Object[] m_Array = null; - private String m_Type = null; - - // The constructor method: - public Array(java.sql.Array array) - throws SQLException - { - try { - m_Array = (Object[]) array.getArray(); - m_Type = array.getBaseTypeName(); - } - catch (java.sql.SQLException e) { - throw UnoHelper.getSQLException(e, this); - } - - } - public Array(Object[] array, - String type) - { - m_Array = array; - m_Type = type; - } - - @Override - public Object[] getArray(XNameAccess map) - throws SQLException - { - return m_Array; - } - - @Override - public Object[] getArrayAtIndex(int index, int count, XNameAccess map) - throws SQLException - { - return Arrays.copyOfRange(m_Array, index, index + count); - } - - @Override - public int getBaseType() - throws SQLException - { - try { - return UnoHelper.getConstantValue(DataType.class, m_Type); - } - catch (java.sql.SQLException e) { - throw UnoHelper.getSQLException(e, this); - } - } - - @Override - public String getBaseTypeName() - throws SQLException - { - return m_Type; - } - - @Override - public XResultSet getResultSet(XNameAccess map) - throws SQLException - { - return null; - } - - @Override - public XResultSet getResultSetAtIndex(int index, int count, XNameAccess map) - throws SQLException - { - return null; - } - - -} \ No newline at end of file diff --git a/uno/lib/java/helper/EventLogger.java b/uno/lib/java/helper/EventLogger.java deleted file mode 100644 index 198a167b..00000000 --- a/uno/lib/java/helper/EventLogger.java +++ /dev/null @@ -1,337 +0,0 @@ -/* -╔════════════════════════════════════════════════════════════════════════════════════╗ -║ ║ -║ Copyright (c) 2020-24 https://prrvchr.github.io ║ -║ ║ -║ 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. ║ -║ ║ -╚════════════════════════════════════════════════════════════════════════════════════╝ -*/ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ -package io.github.prrvchr.uno.helper; - -import java.io.PrintWriter; -import java.io.StringWriter; - -import com.sun.star.logging.LogLevel; -import com.sun.star.logging.XLogHandler; -import com.sun.star.logging.XLogger; -import com.sun.star.logging.XLoggerPool; -import com.sun.star.uno.DeploymentException; -import com.sun.star.uno.Exception; -import com.sun.star.uno.UnoRuntime; -import com.sun.star.uno.XComponentContext; - - -public class EventLogger -{ - protected XComponentContext m_xContext; - private static XLoggerPool m_xPool; - private static String m_service = "io.github.prrvchr.jdbcDriverOOo.LoggerPool"; - private String m_name; - private XLogger m_xLogger; - - // The constructor method: - public EventLogger(XComponentContext context) - throws com.sun.star.uno.Exception - { - this(context, ""); - } - /** - * Creates an EventLogger instance working with a css.logging.XLogger - * instance given by name. - * - * @param context - * the component context to create services. - * @param name - * the name of the logger to create. If empty, the office-wide default logger will be used. - * @throws com.sun.star.uno.Exception - * @throws com.sun.star.uno.Exception - */ - public EventLogger(XComponentContext context, - String name) - { - m_xContext = context; - m_name = name; - if (m_xPool == null) { - m_xPool = _getLoggerPool(); - } - if (!name.isEmpty()) { - m_xLogger = m_xPool.getNamedLogger(name); - } - else { - m_xLogger = m_xPool.getDefaultLogger(); - } - } - - /** - * Returns the name of the logger - */ - public String getName() - { - return m_name; - } - - /// Returns the current log level threshold of the logger. - public int getLogLevel() - { - try { - if (m_xLogger != null) { - return m_xLogger.getLevel(); - } - } - catch (com.sun.star.uno.RuntimeException exception) { - } - return LogLevel.OFF; - } - - /// Sets a new log level threshold of the logger. - void setLogLevel(int level) - { - try { - if (m_xLogger != null) { - m_xLogger.setLevel(level); - } - } - catch (com.sun.star.uno.RuntimeException exception) { - } - } - - /// Determines whether an event with the given level would be logged. - public boolean isLoggable(int level) - { - if (m_xLogger == null) { - return false; - } - try { - return m_xLogger.isLoggable(level); - } - catch (com.sun.star.uno.RuntimeException exception) { - } - return false; - } - - /** - * Adds the given log handler to the logger's set of handlers. - * - * Note that normally, you would not use this method: The logger implementations - * initialize themselves from the configuration, where usually, a default log handler - * is specified. In this case, the logger will create and use this handler. - * - * @return - * true if and only if the addition was successful (as far as this can be detected - * from outside the XLogger's implementation. - */ - public boolean addLogHandler(XLogHandler logHandler) - { - try { - if (m_xLogger != null) { - m_xLogger.addLogHandler(logHandler); - return true; - } - } - catch (com.sun.star.uno.RuntimeException exception) { - } - return false; - } - - /** removes the given log handler from the logger's set of handlers. - * - * @return - * true if and only if the addition was successful (as far as this can be detected - * from outside the XLogger's implementation. - */ - public boolean removeLogHandler(XLogHandler logHandler) - { - try { - if (m_xLogger != null) { - m_xLogger.removeLogHandler(logHandler); - return true; - } - } - catch (com.sun.star.uno.RuntimeException exception) { - } - return false; - } - - /** - * Logs a given message with its arguments, without the caller's class and method. - * @param level the log level - * @param message the message to log - * @param arguments the arguments to log, which are converted to strings and replace $1$, $2$, up to $n$ in the message - * @return whether logging succeeded - */ - public boolean log(int level, - String message, - Object... arguments) - { - if (isLoggable(level)) { - return _log(level, null, null, message, arguments); - } - return false; - } - - /** - * Logs the given exception. - * @param level the log level - * @param exception the exception - * @return whether logging succeeded - */ - public boolean log(int level, - Throwable exception) - { - return log(level, "", exception); - } - - /** - * Logs the given message and exception. - * @param level the log level - * @param message the message - * @param exception the exception - * @return whether logging succeeded - */ - public boolean log(int level, - String message, - Throwable exception) - { - if (isLoggable(level)) { - StringWriter stringWriter = new StringWriter(); - PrintWriter printerWriter = new PrintWriter(stringWriter); - exception.printStackTrace(printerWriter); - message += "\n" + stringWriter.getBuffer().toString(); - return _log(level, null, null, message); - } - return false; - } - - /** - * Logs a given message with its arguments, with the caller's class and method - * taken from a (relatively costly!) stack trace. - * @param level the log level - * @param message the message to log - * @param arguments the arguments to log, which are converted to strings and replace $1$, $2$, up to $n$ in the message - * @return whether logging succeeded - */ - public boolean logp(int level, - String message, - Object...arguments) - { - if (isLoggable(level)) { - StackTraceElement caller = Thread.currentThread().getStackTrace()[2]; - return _log(level, caller.getClassName(), caller.getMethodName(), message, arguments); - } - return false; - } - - /** - * Logs the given exception, with the caller's class and method. - * @param level the log level - * @param exception the exception - * @return whether logging succeeded - */ - public boolean logp(int level, - Throwable exception) - { - return logp(level, "", exception); - } - - /** - * Logs the given message and exception, with the caller's class and method. - * @param level the log level - * @param message the message - * @param exception the exception - * @return whether logging succeeded - */ - public boolean logp(int level, - String message, - Throwable exception) - { - if (isLoggable(level)) { - StringWriter stringWriter = new StringWriter(); - PrintWriter printerWriter = new PrintWriter(stringWriter); - exception.printStackTrace(printerWriter); - message += "\n" + stringWriter.getBuffer().toString(); - StackTraceElement caller = Thread.currentThread().getStackTrace()[2]; - return _log(level, caller.getClassName(), caller.getMethodName(), message); - } - return false; - } - - protected boolean _log(int level, - String clazz, - String method, - String message, - Object... arguments) - { - if (m_xLogger == null) { - return false; - } - if (arguments.length > 0) { - try { - message = String.format(message, arguments); - } - catch (java.lang.Exception e){ - System.out.println("EventLogger._log ERROR with message: " + message); - // pass - } - } - if (clazz != null && method != null) { - m_xLogger.logp(level, clazz, method, message); - } - else { - m_xLogger.log(level, message); - } - return true; - } - - private XLoggerPool _getLoggerPool() - { - XLoggerPool pool = null; - try { - Object object = m_xContext.getServiceManager().createInstanceWithContext(m_service, m_xContext); - pool = UnoRuntime.queryInterface(XLoggerPool.class, object); - } - catch (Exception e) {} - if (pool == null) { - throw new DeploymentException("component context fails to supply singleton com.sun.star.logging.LoggerPool of type com.sun.star.logging.XLoggerPool", - m_xContext); - } - return pool; - } - -} diff --git a/uno/lib/java/helper/OfficeResourceBundle.java b/uno/lib/java/helper/OfficeResourceBundle.java deleted file mode 100644 index 1c72ebc8..00000000 --- a/uno/lib/java/helper/OfficeResourceBundle.java +++ /dev/null @@ -1,177 +0,0 @@ -/* -╔════════════════════════════════════════════════════════════════════════════════════╗ -║ ║ -║ Copyright (c) 2020-24 https://prrvchr.github.io ║ -║ ║ -║ 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. ║ -║ ║ -╚════════════════════════════════════════════════════════════════════════════════════╝ -*/ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ -package io.github.prrvchr.uno.helper; - -import com.sun.star.container.NoSuchElementException; -import com.sun.star.lang.NullPointerException; -import com.sun.star.resource.MissingResourceException; -import com.sun.star.resource.XStringResourceResolver; -import com.sun.star.uno.Exception; -import com.sun.star.uno.XComponentContext; - - -public class OfficeResourceBundle - implements AutoCloseable -{ - - private XComponentContext m_xContext; - private String m_identifier; - private String m_path; - private String m_basename; - private boolean m_attempted; - private XStringResourceResolver m_xResolver; - - /** constructs a resource bundle - @param context - the component context to operate in - @param basename - the base name of the resource file which should be accessed - @throws com.sun.star.lang.NullPointerException - if the given component context is null - */ - public OfficeResourceBundle(XComponentContext context, - String identifier, - String path, - String basename) - throws NullPointerException - { - if (context == null) { - throw new NullPointerException(); - } - m_xContext = context; - m_identifier = identifier; - m_path = path; - m_basename = basename; - m_attempted = false; - } - - @Override - public void close() { - UnoHelper.disposeComponent(m_xResolver); - } - - /** - * Return the bundle's base name as passed to the constructor. - */ - public String getBaseName() { - return m_basename; - } - - /** - * Return the extension identifier name as passed to the constructor. - */ - public String getIdentifier() { - return m_identifier; - } - - /** loads the string with the given resource id from the resource bundle - @param id - the id of the string to load - @return - the requested resource string. If no string with the given id exists in the resource bundle, - an empty string is returned. - * @throws Exception - * @throws NoSuchElementException - * @throws MissingResourceException - */ - public String loadString( int id ) - throws MissingResourceException, - NoSuchElementException, - Exception - { - synchronized (this) { - String string = ""; - if (loadResolver()) { - string = m_xResolver.resolveString(getStringResourceKey(id)); - } - return string; - } - } - - /** determines whether the resource bundle has a string with the given id - @param id - the id of the string whose existence is to be checked - @return - true if and only if a string with the given ID exists in the resource - bundle. - * @throws Exception - * @throws NoSuchElementException - */ - public boolean hasString( int id ) - throws NoSuchElementException, - Exception - { - synchronized (this) { - boolean has = false; - if (loadResolver()) { - has = m_xResolver.hasEntryForId(getStringResourceKey(id)); - } - return has; - } - } - - private String getStringResourceKey(int id) - { - return Integer.toString(id); - } - - private boolean loadResolver() - throws NoSuchElementException, - Exception - { - if (m_attempted) { - return m_xResolver != null; - } - m_attempted = true; - XStringResourceResolver resolver = UnoHelper.getResourceResolver(m_xContext, m_identifier, m_path, m_basename); - if (resolver != null) { - m_xResolver = resolver; - return true; - } - return false; - } - -} diff --git a/uno/lib/java/helper/PropertySet.java b/uno/lib/java/helper/PropertySet.java deleted file mode 100644 index 34c32562..00000000 --- a/uno/lib/java/helper/PropertySet.java +++ /dev/null @@ -1,228 +0,0 @@ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ -/* -╔════════════════════════════════════════════════════════════════════════════════════╗ -║ ║ -║ Copyright (c) 2020-24 https://prrvchr.github.io ║ -║ ║ -║ 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. ║ -║ ║ -╚════════════════════════════════════════════════════════════════════════════════════╝ -*/ -package io.github.prrvchr.uno.helper; - -import java.util.Map; - -import com.sun.star.beans.PropertyVetoException; -import com.sun.star.beans.UnknownPropertyException; -import com.sun.star.beans.XFastPropertySet; -import com.sun.star.beans.XMultiPropertySet; -import com.sun.star.beans.XPropertiesChangeListener; -import com.sun.star.beans.XPropertyChangeListener; -import com.sun.star.beans.XPropertySet; -import com.sun.star.beans.XPropertySetInfo; -import com.sun.star.beans.XVetoableChangeListener; -import com.sun.star.lang.DisposedException; -import com.sun.star.lang.IllegalArgumentException; -import com.sun.star.lang.WrappedTargetException; -import com.sun.star.lib.uno.helper.ComponentBase; - - -public abstract class PropertySet - extends ComponentBase - implements XPropertySet, - XFastPropertySet, - XMultiPropertySet -{ - - private final PropertySetAdapter m_adapter; - - protected PropertySet() - { - m_adapter = new PropertySetAdapter(this, this); - } - - protected void registerProperties(Map properties) - { - m_adapter.registerProperties(properties); - } - - - @Override - protected void postDisposing() - { - super.postDisposing(); - m_adapter.dispose(); - } - - public synchronized void addPropertyChangeListener(String name, - XPropertyChangeListener listener) - throws UnknownPropertyException, - WrappedTargetException - { - // XXX: Only add listeners if you are not disposed - if (!bDisposed) { - m_adapter.addPropertyChangeListener(name, listener); - } - } - - public synchronized void addVetoableChangeListener(String name, - XVetoableChangeListener listener) - throws UnknownPropertyException, - WrappedTargetException - { - // XXX: Only add listeners if you are not disposed - if (!bDisposed) { - m_adapter.addVetoableChangeListener(name, listener); - } - } - - public synchronized void addPropertiesChangeListener(String[] names, - XPropertiesChangeListener listener) - { - // XXX: Only add listeners if you are not disposed - if (!bDisposed) { - m_adapter.addPropertiesChangeListener(names, listener); - } - } - - public XPropertySetInfo getPropertySetInfo() - { - return m_adapter.getPropertySetInfo(); - } - - public synchronized Object getPropertyValue(String name) - throws UnknownPropertyException, - WrappedTargetException - { - checkDisposed(); - return m_adapter.getPropertyValue(name); - } - - @Override - public synchronized Object getFastPropertyValue(int handle) - throws UnknownPropertyException, - WrappedTargetException - { - checkDisposed(); - return m_adapter.getFastPropertyValue(handle); - } - - public synchronized Object[] getPropertyValues(String[] names) - { - checkDisposed(); - return m_adapter.getPropertyValues(names); - } - - public synchronized void removePropertyChangeListener(String name, - XPropertyChangeListener listener) - throws UnknownPropertyException, - WrappedTargetException - { - // XXX: All listeners are automatically released in a dispose call - if (!bDisposed) { - m_adapter.removePropertyChangeListener(name, listener); - } - } - - public synchronized void removeVetoableChangeListener(String name, - XVetoableChangeListener listener) - throws UnknownPropertyException, - WrappedTargetException - { - // XXX: All listeners are automatically released in a dispose call - if (!bDisposed) { - m_adapter.removeVetoableChangeListener(name, listener); - } - } - - public synchronized void removePropertiesChangeListener(XPropertiesChangeListener listener) - { - // XXX: All listeners are automatically released in a dispose call - if (!bDisposed) { - m_adapter.removePropertiesChangeListener(listener); - } - } - - public synchronized void setPropertyValue(String name, - Object value) - throws UnknownPropertyException, - PropertyVetoException, - IllegalArgumentException, - WrappedTargetException - { - checkDisposed(); - m_adapter.setPropertyValue(name, value); - } - - public synchronized void setFastPropertyValue(int handle, - Object value) - throws UnknownPropertyException, - PropertyVetoException, - IllegalArgumentException, - WrappedTargetException - { - checkDisposed(); - m_adapter.setFastPropertyValue(handle, value); - } - - public synchronized void setPropertyValues(String[] names, - Object[] values) - throws PropertyVetoException, - IllegalArgumentException, - WrappedTargetException - { - checkDisposed(); - m_adapter.setPropertyValues(names, values); - } - - public synchronized void firePropertiesChangeEvent(String[] names, - XPropertiesChangeListener listener) - { - checkDisposed(); - m_adapter.firePropertiesChangeEvent(names, listener); - } - - // XXX: Checks whether this component (which you should have locked, prior to this call, and until you are done using) is disposed, throwing DisposedException if it is. */ - protected synchronized final void checkDisposed() - { - if (bInDispose || bDisposed) { - throw new DisposedException(); - } - } - -} diff --git a/uno/lib/java/helper/PropertySetAdapter.java b/uno/lib/java/helper/PropertySetAdapter.java deleted file mode 100644 index 6a1c6db5..00000000 --- a/uno/lib/java/helper/PropertySetAdapter.java +++ /dev/null @@ -1,545 +0,0 @@ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ -/* -╔════════════════════════════════════════════════════════════════════════════════════╗ -║ ║ -║ Copyright (c) 2020-24 https://prrvchr.github.io ║ -║ ║ -║ 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. ║ -║ ║ -╚════════════════════════════════════════════════════════════════════════════════════╝ -*/ -package io.github.prrvchr.uno.helper; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -import com.sun.star.beans.Property; -import com.sun.star.beans.PropertyAttribute; -import com.sun.star.beans.PropertyChangeEvent; -import com.sun.star.beans.PropertyVetoException; -import com.sun.star.beans.UnknownPropertyException; -import com.sun.star.beans.XFastPropertySet; -import com.sun.star.beans.XMultiPropertySet; -import com.sun.star.beans.XPropertiesChangeListener; -import com.sun.star.beans.XPropertyChangeListener; -import com.sun.star.beans.XPropertySet; -import com.sun.star.beans.XPropertySetInfo; -import com.sun.star.beans.XVetoableChangeListener; -import com.sun.star.lang.EventObject; -import com.sun.star.lang.IllegalArgumentException; -import com.sun.star.lang.WrappedTargetException; -import com.sun.star.lib.uno.helper.InterfaceContainer; -import com.sun.star.lib.uno.helper.MultiTypeInterfaceContainer; -import com.sun.star.uno.Any; -import com.sun.star.uno.AnyConverter; -import com.sun.star.uno.Type; -import com.sun.star.uno.TypeClass; -import com.sun.star.uno.XInterface; - - -public class PropertySetAdapter - implements XPropertySet, - XFastPropertySet, - XMultiPropertySet -{ - - private final Object lock; - private final Object eventSource; - // XXX: After registerListeners(), these are read-only: - private final Map propertiesByName = new HashMap(); - private final Map propertiesByHandle = new HashMap(); - private AtomicInteger nextHandle = new AtomicInteger(1); - // XXX: Interface containers are locked internally: - protected final MultiTypeInterfaceContainer boundListeners = new MultiTypeInterfaceContainer(); - protected final MultiTypeInterfaceContainer vetoableListeners = new MultiTypeInterfaceContainer(); - protected final InterfaceContainer propertiesChangeListeners = new InterfaceContainer(); - private final PropertySetInfo propertySetInfo = new PropertySetInfo(); - - public static interface PropertyGetter - { - Object getValue() throws WrappedTargetException; - } - - public static interface PropertySetter - { - void setValue(Object value) throws PropertyVetoException, IllegalArgumentException, WrappedTargetException; - } - - private static class PropertyData - { - Property property; - PropertyGetter getter; - PropertySetter setter; - - PropertyData(Property property, PropertyGetter getter, PropertySetter setter) - { - this.property = property; - this.getter = getter; - this.setter = setter; - } - } - - private static final Comparator propertyNameComparator = new Comparator() - { - @Override - public int compare(Property first, - Property second) - { - return first.Name.compareTo(second.Name); - } - }; - - private class PropertySetInfo implements XPropertySetInfo - { - @Override - public Property[] getProperties() - { - Property[] properties = new Property[propertiesByName.size()]; - int next = 0; - for (Map.Entry entry : propertiesByName.entrySet()) { - properties[next++] = entry.getValue().property; - } - Arrays.sort(properties, propertyNameComparator); - return properties; - } - - @Override - public Property getPropertyByName(String propertyName) - throws UnknownPropertyException - { - PropertyData propertyData = getPropertyData(propertyName); - return propertyData.property; - } - - @Override - public boolean hasPropertyByName(String name) - { - boolean value = propertiesByName.containsKey(name); - if (!value) { - System.out.println("beans.PropertySetAdapter.hasPropertyByName() ERROR *******************************************\n" + lock.getClass().getName() + " : " + name); - } - return value; - } - } - - /** - * Creates a new instance. - * @param lock the lock that will be held while calling the getters and setters - * @param eventSource the com.sun.star.lang.EventObject Source field, to use in events sent to listeners - */ - public PropertySetAdapter(Object lock, - Object eventSource) - { - this.lock = lock; - this.eventSource = eventSource; - } - - public void dispose() - { - // XXX: Create an event with this as sender - EventObject event = new EventObject(eventSource); - - // XXX: Inform all listeners to release this object - boundListeners.disposeAndClear(event); - vetoableListeners.disposeAndClear(event); - } - - public void registerProperties(Map properties) - { - List names = new ArrayList(properties.keySet()); - Collections.sort(names); - for (String name: names) { - PropertyWrapper property = properties.get(name); - // XXX: registerProperty() should only be called from one thread, but just in case: - int handle = nextHandle.getAndIncrement(); - registerProperty(name, handle, property.getType(), property.getAttribute(), property.getGetter(), property.getSetter()); - } - } - - private void registerProperty(String name, - int handle, - Type type, - short attributes, - PropertyGetter getter, - PropertySetter setter) - { - Property property = new Property(name, handle, type, attributes); - PropertyData data = new PropertyData(property, getter, setter); - propertiesByName.put(name, data); - propertiesByHandle.put(property.Handle, data); - } - - @Override - public void addPropertyChangeListener(String name, - XPropertyChangeListener listener) - throws UnknownPropertyException, - WrappedTargetException - { - PropertyData data = getPropertyData(name); - if ((data.property.Attributes & PropertyAttribute.BOUND) != 0) { - boundListeners.addInterface(name, listener); - } // XXX: else ignore silently - } - - @Override - public void addVetoableChangeListener(String name, - XVetoableChangeListener listener) - throws UnknownPropertyException, - WrappedTargetException - { - PropertyData data = getPropertyData(name); - if ((data.property.Attributes & PropertyAttribute.CONSTRAINED) != 0) { - vetoableListeners.addInterface(name, listener); - } // else ignore silently - } - - @Override - public void addPropertiesChangeListener(String[] names, - XPropertiesChangeListener listener) - { - propertiesChangeListeners.add(listener); - } - - @Override - public XPropertySetInfo getPropertySetInfo() - { - return propertySetInfo; - } - - private PropertyData getPropertyData(String name) - throws UnknownPropertyException - { - PropertyData data = propertiesByName.get(name); - if (data == null) { - System.out.println("beans.PropertySetAdapter.getPropertyData() ERROR Property Name: " + name); - throw new UnknownPropertyException(name); - } - return data; - } - - private PropertyData getPropertyData(int handle) - throws UnknownPropertyException - { - PropertyData data = propertiesByHandle.get(handle); - if (data == null) { - System.out.println("beans.PropertySetAdapter.getPropertyData() ERROR Property handle: " + handle); - throw new UnknownPropertyException(Integer.toString(handle)); - } - return data; - } - - private Object getPropertyValue(PropertyData data) - throws WrappedTargetException - { - Object value; - synchronized (lock) { - value = data.getter.getValue(); - } - - // XXX: null must not be returned. Either a void any is returned - // XXX: or an any containing an interface type and a null reference. - if (value == null) { - if (data.property.Type.getTypeClass() == TypeClass.INTERFACE) { - value = new Any(data.property.Type, null); - } - else { - value = new Any(new Type(void.class), null); - } - } - return value; - } - - @Override - public Object getPropertyValue(String name) - throws UnknownPropertyException, - WrappedTargetException - { - PropertyData propertyData = getPropertyData(name); - return getPropertyValue(propertyData); - } - - @Override - public Object getFastPropertyValue(int handle) - throws UnknownPropertyException, - WrappedTargetException - { - - PropertyData propertyData = getPropertyData(handle); - return getPropertyValue(propertyData); - } - - @Override - public Object[] getPropertyValues(String[] names) - { - Object[] values = new Object[names.length]; - for (int i = 0; i < names.length; i++) { - Object value = null; - try { - value = getPropertyValue(names[i]); - } - catch (UnknownPropertyException | WrappedTargetException e) { - System.out.println("beans.PropertySetAdapter.getPropertyValues() ERROR\n" + UnoHelper.getStackTrace(e)); - } - values[i] = value; - } - return values; - } - - @Override - public void removePropertyChangeListener(String name, - XPropertyChangeListener listener) - throws UnknownPropertyException, - WrappedTargetException - { - // XXX: Check existence: - getPropertyData(name); - boundListeners.removeInterface(name, listener); - } - - @Override - public synchronized void removeVetoableChangeListener(String name, - XVetoableChangeListener listener) - throws UnknownPropertyException, - WrappedTargetException - { - // XXX: Check existence: - getPropertyData(name); - vetoableListeners.removeInterface(name, listener); - } - - @Override - public void removePropertiesChangeListener(XPropertiesChangeListener listener) - { - propertiesChangeListeners.remove(listener); - } - - @Override - public void setPropertyValue(String name, - Object value) - throws UnknownPropertyException, - PropertyVetoException, - IllegalArgumentException, - WrappedTargetException - { - PropertyData propertyData = getPropertyData(name); - setPropertyValue(propertyData, value); - } - - @Override - public void setFastPropertyValue(int handle, - Object value) - throws UnknownPropertyException, - PropertyVetoException, - IllegalArgumentException, - WrappedTargetException - { - PropertyData propertyData = getPropertyData(handle); - setPropertyValue(propertyData, value); - } - - private void setPropertyValue(PropertyData data, - Object value) - throws UnknownPropertyException, - PropertyVetoException, - IllegalArgumentException, - WrappedTargetException - { - if ((data.property.Attributes & PropertyAttribute.READONLY) != 0) { - throw new PropertyVetoException(); - } - // XXX: The value may be null only if MAYBEVOID attribute is set - boolean isvoid = false; - if (value instanceof Any) { - isvoid = ((Any) value).getObject() == null; - } - else { - isvoid = value == null; - } - if (isvoid && (data.property.Attributes & PropertyAttribute.MAYBEVOID) == 0) { - System.out.println("beans.PropertySetAdapter.setPropertyValue() ERROR: Property Name: " + data.property.Name); - throw new IllegalArgumentException("The property must have a value; the MAYBEVOID attribute is not set!"); - } - - // XXX: Check if the argument is allowed - boolean isValueOk = false; - if (value instanceof Any) { - isValueOk = checkType(((Any) value).getObject()); - } - else { - isValueOk = checkType(value); - } - if (!isValueOk) { - throw new IllegalArgumentException("No valid UNO type"); - } - - Object[] futureValue = new Object[] { AnyConverter.toObject(data.property.Type, value) }; - Object[] currentValue = new Object[] { getPropertyValue(data.property.Name) }; - Property[] properties = new Property[] { data.property }; - - fire(properties, currentValue, futureValue, false); - synchronized (lock) { - data.setter.setValue(futureValue[0]); - } - fire(properties, currentValue, futureValue, true); - } - - @Override - public void setPropertyValues(String[] names, - Object[] values) - throws PropertyVetoException, - IllegalArgumentException, - WrappedTargetException - { - for (int i = 0; i < names.length; i++) { - try { - setPropertyValue(names[i], values[i]); - } - catch (UnknownPropertyException e) { - continue; - } - } - } - - private boolean checkType(Object obj) { - if (obj == null || - obj instanceof Boolean || - obj instanceof Character || - obj instanceof Number || - obj instanceof String || - obj instanceof XInterface || - obj instanceof Type || - obj instanceof com.sun.star.uno.Enum || - obj.getClass().isArray()) - return true; - return false; - } - - @Override - public void firePropertiesChangeEvent(String[] names, - XPropertiesChangeListener listener) - { - PropertyChangeEvent[] events = new PropertyChangeEvent[names.length]; - int count = 0; - for (String name : names) { - try { - PropertyData data = getPropertyData(name); - Object value = getPropertyValue(name); - events[count++] = new PropertyChangeEvent(eventSource, name, false, - data.property.Handle, value, value); - } - catch (UnknownPropertyException e) { - } - catch (WrappedTargetException e) { - } - } - if (count > 0) { - if (events.length != count) { - PropertyChangeEvent[] tmp = new PropertyChangeEvent[count]; - System.arraycopy(events, 0, tmp, 0, count); - events = tmp; - } - listener.propertiesChange(events); - } - } - - private void fire(Property[] properties, - Object[] oldvalues, - Object[] newvalues, - boolean changed) - throws PropertyVetoException - { - PropertyChangeEvent[] events = new PropertyChangeEvent[properties.length]; - int count = 0; - for (int i = 0; i < properties.length; i++) { - if ((!changed && (properties[i].Attributes & PropertyAttribute.CONSTRAINED) != 0) || - (changed && (properties[i].Attributes & PropertyAttribute.BOUND) != 0)) { - events[count++] = new PropertyChangeEvent( - eventSource, properties[i].Name, false, properties[i].Handle, oldvalues[i], newvalues[i]); - } - } - for (int i = 0; i < count; i++) { - fireListeners(changed, events[i].PropertyName, events[i]); - fireListeners(changed, "", events[i]); - } - if (changed && count > 0) { - if (count != events.length) { - PropertyChangeEvent[] tmp = new PropertyChangeEvent[count]; - System.arraycopy(events, 0, tmp, 0, count); - events = tmp; - } - for (Iterator it = propertiesChangeListeners.iterator(); it.hasNext();) { - XPropertiesChangeListener listener = (XPropertiesChangeListener) it.next(); - listener.propertiesChange(events); - } - } - } - - private void fireListeners(boolean changed, - String key, - PropertyChangeEvent event) - throws PropertyVetoException - { - InterfaceContainer listeners; - if (changed) { - listeners = boundListeners.getContainer(key); - } - else { - listeners = vetoableListeners.getContainer(key); - } - if (listeners != null) { - Iterator it = listeners.iterator(); - while (it.hasNext()) { - Object listener = it.next(); - if (changed) { - ((XPropertyChangeListener)listener).propertyChange(event); - } - else { - ((XVetoableChangeListener)listener).vetoableChange(event); - } - } - } - } - -} diff --git a/uno/lib/java/helper/PropertyWrapper.java b/uno/lib/java/helper/PropertyWrapper.java deleted file mode 100644 index fd101b78..00000000 --- a/uno/lib/java/helper/PropertyWrapper.java +++ /dev/null @@ -1,80 +0,0 @@ -/* -╔════════════════════════════════════════════════════════════════════════════════════╗ -║ ║ -║ Copyright (c) 2020-24 https://prrvchr.github.io ║ -║ ║ -║ 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. ║ -║ ║ -╚════════════════════════════════════════════════════════════════════════════════════╝ -*/ -package io.github.prrvchr.uno.helper; - -import com.sun.star.uno.Type; - -import io.github.prrvchr.uno.helper.PropertySetAdapter.PropertyGetter; -import io.github.prrvchr.uno.helper.PropertySetAdapter.PropertySetter; - - -public class PropertyWrapper -{ - - private final Type m_type; - private final short m_attributes; - private final PropertyGetter m_getter; - private final PropertySetter m_setter; - - // The constructor method: - public PropertyWrapper(Type type, - PropertyGetter getter, - PropertySetter setter) - { - this(type, (short) 0, getter, setter); - } - - public PropertyWrapper(Type type, - short attributes, - PropertyGetter getter, - PropertySetter setter) - { - m_type = type; - m_attributes = attributes; - m_getter = getter; - m_setter = setter; - } - - public Type getType() - { - return m_type; - } - - public short getAttribute() - { - return m_attributes; - } - - public PropertyGetter getGetter() - { - return m_getter; - } - - public PropertySetter getSetter() - { - return m_setter; - } -} diff --git a/uno/lib/java/helper/RegistrationHelper.java b/uno/lib/java/helper/RegistrationHelper.java deleted file mode 100644 index 08dd275e..00000000 --- a/uno/lib/java/helper/RegistrationHelper.java +++ /dev/null @@ -1,173 +0,0 @@ -/* -╔════════════════════════════════════════════════════════════════════════════════════╗ -║ ║ -║ Copyright (c) 2020-24 https://prrvchr.github.io ║ -║ ║ -║ 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. ║ -║ ║ -╚════════════════════════════════════════════════════════════════════════════════════╝ -*/ -package io.github.prrvchr.uno.helper; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.lang.reflect.Method; -import java.util.ArrayList; - -import com.sun.star.lang.XSingleComponentFactory; -import com.sun.star.registry.XRegistryKey; - -/** - * Component main registration class. - * - *

This class should not be modified.

- * - * @author Cedric Bosdonnat aka. cedricbosdo - * - */ -public class RegistrationHelper -{ - - /** - * Get a component factory for the implementations handled by this class. - * - *

This method calls all the methods of the same name from the classes listed - * in the RegistrationHandler.classes file. This method - * should not be modified.

- * - * @param pImplementationName the name of the implementation to create. - * - * @return the factory which can create the implementation. - */ - - public static XSingleComponentFactory __getComponentFactory(final InputStream in, - final String name) - { - XSingleComponentFactory factory = null; - final Class[] classes = _findServicesImplementationClasses(in); - int i = 0; - while (i < classes.length && factory == null) - { - final Class clazz = classes[i]; - if (name.equals(clazz.getCanonicalName())) - { - try - { - final Class[] types = new Class[]{String.class}; - final Method method = clazz.getMethod("__getComponentFactory", types); - final Object object = method.invoke(null, name); - factory = (XSingleComponentFactory)object; - } - catch (Exception e) - { - // Nothing to do: skip - System.err.println("Error happened"); - e.printStackTrace(); - } - } - i++; - } - return factory; - } - - /** - * Writes the services implementation informations to the UNO registry. - * - *

This method calls all the methods of the same name from the classes listed - * in the RegistrationHandler.classes file. This method - * should not be modified.

- * - * @param pRegistryKey the root registry key where to write the informations. - * - * @return true if the informations have been successfully written - * to the registry key, false otherwise. - */ - - public static boolean __writeRegistryServiceInfo(final InputStream in, - final XRegistryKey key) - { - final Class[] classes = _findServicesImplementationClasses(in); - boolean success = true; - int i = 0; - while (i < classes.length && success) - { - final Class clazz = classes[i]; - try - { - final Class[] types = new Class[]{XRegistryKey.class}; - final Method method = clazz.getMethod("__writeRegistryServiceInfo", types); - final Object object = method.invoke(null, key); - success = success && ((Boolean)object).booleanValue(); - } catch (Exception e) - { - success = false; - e.printStackTrace(); - } - i++; - } - return success; - } - - /** - * @return all the UNO implementation classes. - */ - - private static Class[] _findServicesImplementationClasses(final InputStream in) - { - final ArrayList> classes = new ArrayList>(); - final LineNumberReader reader = new LineNumberReader(new InputStreamReader(in)); - try { - String line = reader.readLine(); - while (line != null) { - if (!line.equals("")) { - line = line.trim(); - try { - final Class clazz = Class.forName(line); - final Class[] rtypes = new Class[]{XRegistryKey.class}; - final Class[] ftypes = new Class[]{String.class}; - final Method registry = clazz.getMethod("__writeRegistryServiceInfo", rtypes); - final Method factory = clazz.getMethod("__getComponentFactory", ftypes); - if (registry != null && factory != null) { - classes.add(clazz); - } - } - catch (LinkageError | ClassNotFoundException | NoSuchMethodException e) { - e.printStackTrace(); - } - } - line = reader.readLine(); - } - } - catch (IOException e) { - e.printStackTrace(); - } - finally { - try { - reader.close(); - in.close(); - } - catch (Exception e) {}; - } - return classes.toArray(new Class[classes.size()]); - } - - -} diff --git a/uno/lib/java/helper/ResourceBasedEventLogger.java b/uno/lib/java/helper/ResourceBasedEventLogger.java deleted file mode 100644 index 41d1cee0..00000000 --- a/uno/lib/java/helper/ResourceBasedEventLogger.java +++ /dev/null @@ -1,221 +0,0 @@ -/* -╔════════════════════════════════════════════════════════════════════════════════════╗ -║ ║ -║ Copyright (c) 2020-24 https://prrvchr.github.io ║ -║ ║ -║ 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. ║ -║ ║ -╚════════════════════════════════════════════════════════════════════════════════════╝ -*/ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ -package io.github.prrvchr.uno.helper; - -import java.io.PrintWriter; -import java.io.StringWriter; - -import com.sun.star.lang.NullPointerException; -import com.sun.star.resource.MissingResourceException; -import com.sun.star.uno.Exception; -import com.sun.star.uno.XComponentContext; - - -public class ResourceBasedEventLogger - extends EventLogger -{ - private String m_basename; - private String m_identifier; - private String m_path; - private OfficeResourceBundle m_Bundle; - - // The constructor method: - public ResourceBasedEventLogger(ResourceBasedEventLogger logger) - { - this(logger.m_xContext, logger.m_identifier, logger.m_path, logger.m_basename, logger.getName()); - } - public ResourceBasedEventLogger(XComponentContext context, - String identifier, - String path, - String basename, - String logger) - { - super(context, logger); - m_identifier = identifier; - m_path = path; - m_basename = basename; - try { - m_Bundle = new OfficeResourceBundle(context, identifier, path, basename); - } - catch (NullPointerException e) { - throw new RuntimeException(e); - } - } - - /** - * Logs a given message, without the caller's class and method. - * @param level the log level - * @param message the message to log - * @return whether logging succeeded - */ - public boolean log(int level, - String message) - { - if (isLoggable(level)) { - return _log(level, null, null, message); - } - return false; - } - - /** - * Logs a given message with its arguments, with the caller's class and method - * taken from a (relatively costly!) stack trace. - * @param level the log level - * @param class name who log this message - * @param method name who log this message - * @param message the message to log - * @return whether logging succeeded - */ - public boolean logp(int level, - String cls, - String method, - String message) - { - if (isLoggable(level)) { - return _log(level, cls, method, message); - } - return false; - } - - /** - * Logs a given resource bundle id with its arguments, without the caller's class and method. - * @param level the log level - * @param id the resource ID of the message to log - * @param arguments the arguments to log, which are converted to strings and replace $1$, $2$, up to $n$ in the message - * @return whether logging succeeded - */ - public boolean logrb(int level, - int id, - Object... arguments) - { - if (isLoggable(level)) { - return _log(level, null, null, loadStringMessage(id), arguments); - } - return false; - } - - /** - * Logs a given resource id with its arguments, with the caller's class and method - * taken from a (relatively costly!) stack trace. - * @param level the log level - * @param id the resource ID of the message to log - * @param arguments the arguments to log, which are converted to strings and replace $1$, $2$, up to $n$ in the message - * @return whether logging succeeded - */ - public boolean logprb(int level, - int id, - Object... arguments) - { - if (isLoggable(level)) { - StackTraceElement caller = Thread.currentThread().getStackTrace()[2]; - return _log(level, caller.getClassName(), caller.getMethodName(), loadStringMessage(id), arguments); - } - return false; - } - - - /** - * Logs a given message with its arguments, with the caller's class and method - * taken from a (relatively costly!) stack trace. - * @param level the log level - * @param class name who log this message - * @param method name who log this message - * @param id the resource string id to log - * @param arguments the arguments to log, which are converted to strings and replace $1$, $2$, up to $n$ in the message - * @return whether logging succeeded - */ - public boolean logprb(int level, - String cls, - String method, - int id, - Object...arguments) - { - if (isLoggable(level)) { - return _log(level, cls, method, loadStringMessage(id), arguments); - } - return false; - } - - protected boolean logprb(int level, - StackTraceElement caller, - int id, - Object... arguments) - { - if (isLoggable(level)) { - return _log(level, caller.getClassName(), caller.getMethodName(), loadStringMessage(id), arguments); - } - return false; - } - - public String getStringResource(int id, Object... arguments) - { - String message = loadStringMessage(id); - if (arguments.length > 0) { - try { - message = String.format(message, arguments); - } - catch (java.lang.Exception e) { - // pass - } - } - return message; - } - - private String loadStringMessage(int id) - { - String message; - try { - message = m_Bundle.loadString(id); - } - catch (MissingResourceException | Exception e) { - StringWriter writer = new StringWriter(); - e.printStackTrace(new PrintWriter(writer)); - message = String.format("\n%s", m_basename, id, writer.getBuffer().toString()); - } - return message; - } - -} diff --git a/uno/lib/java/helper/ServiceInfo.java b/uno/lib/java/helper/ServiceInfo.java deleted file mode 100644 index 4b1fbaef..00000000 --- a/uno/lib/java/helper/ServiceInfo.java +++ /dev/null @@ -1,55 +0,0 @@ -/* -╔════════════════════════════════════════════════════════════════════════════════════╗ -║ ║ -║ Copyright (c) 2020-24 https://prrvchr.github.io ║ -║ ║ -║ 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. ║ -║ ║ -╚════════════════════════════════════════════════════════════════════════════════════╝ -*/ -package io.github.prrvchr.uno.helper; - - -public final class ServiceInfo -{ - - // com.sun.star.lang.XServiceInfo: - public static String getImplementationName(final String name) - { - return name; - } - - public static String[] getSupportedServiceNames(final String[] services) - { - return services.clone(); - } - - public static boolean supportsService(final String[] services, - final String service) - { - for (int i = 0; i < services.length; i++) - { - if (service.equals(services[i])) - return true; - } - return false; - } - - -} diff --git a/uno/lib/java/helper/SharedResources.java b/uno/lib/java/helper/SharedResources.java deleted file mode 100644 index 8761e9e8..00000000 --- a/uno/lib/java/helper/SharedResources.java +++ /dev/null @@ -1,142 +0,0 @@ -/* -╔════════════════════════════════════════════════════════════════════════════════════╗ -║ ║ -║ Copyright (c) 2020-24 https://prrvchr.github.io ║ -║ ║ -║ 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. ║ -║ ║ -╚════════════════════════════════════════════════════════════════════════════════════╝ -*/ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ -package io.github.prrvchr.uno.helper; - -import com.sun.star.lang.NullPointerException; -import com.sun.star.uno.XComponentContext; - -/** - * helper class for accessing resources shared by different libraries - * in the connectivity module. - */ -public class SharedResources -{ - private static SharedResources m_instance; - private static OfficeResourceBundle m_bundle; - private static int m_refcount = 0; - - // The private constructor method: - private SharedResources(XComponentContext context, - String identifier, - String path, - String basename) - { - try { - m_bundle = new OfficeResourceBundle(context, identifier, path, basename); - } - catch (NullPointerException nullPointerException) { - } - } - - // FIXME: the C++ implementation gets the XComponentContext using ::comphelper::getProcessServiceFactory(), we don't. - public synchronized static void registerClient(XComponentContext context, - String identifier, - String path, - String basename) - { - if (m_instance == null) { - m_instance = new SharedResources(context, identifier, path, basename); - } - ++m_refcount; - } - - public synchronized static void revokeClient() - { - if (--m_refcount == 0) { - m_bundle.close(); - m_instance = null; - } - } - - public synchronized static SharedResources getInstance() - { - return m_instance; - } - - /** loads a string from the shared resource file - @param id - the resource ID of the string - @return - the string from the resource file - */ - public String getResource(int id) - { - return loadStringMessage(id); - } - - /** loads a string from the shared resource file, and replaces all substitutes - - @param id - the resource ID of the string to load - @param substitutes - A varargs String of substitutions. - - @return - the string from the resource file, with applied string substitution - */ - public String getResourceWithSubstitution(int id, - Object... substitutes) - { - return loadStringMessage(id, substitutes); - } - - private String loadStringMessage(int id, - Object... substitutes) - { - String message = ""; - try { - message = m_bundle.loadString(id); - if (substitutes.length > 0) { - message = String.format(message, substitutes); - } - } - catch (java.lang.Exception e) { - message = String.format("", m_bundle.getBaseName(), id); - } - return message; - } - -} diff --git a/uno/lib/java/helper/UnoHelper.java b/uno/lib/java/helper/UnoHelper.java deleted file mode 100644 index e0caed8c..00000000 --- a/uno/lib/java/helper/UnoHelper.java +++ /dev/null @@ -1,969 +0,0 @@ -package io.github.prrvchr.uno.helper; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.lang.IllegalAccessException; -import java.net.URL; -import java.net.URLClassLoader; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Map; - -import com.sun.star.beans.Property; -import com.sun.star.beans.NamedValue; -import com.sun.star.beans.PropertyAttribute; -import com.sun.star.beans.PropertyValue; -import com.sun.star.beans.XIntrospection; -import com.sun.star.beans.XPropertySet; -import com.sun.star.beans.XPropertySetInfo; -import com.sun.star.container.NoSuchElementException; -import com.sun.star.container.XHierarchicalNameAccess; -import com.sun.star.deployment.XPackageInformationProvider; -import com.sun.star.i18n.XLocaleData; -import com.sun.star.lang.IllegalArgumentException; -import com.sun.star.lang.Locale; -import com.sun.star.lang.WrappedTargetException; -import com.sun.star.lang.XComponent; -import com.sun.star.lang.XMultiComponentFactory; -import com.sun.star.lang.XMultiServiceFactory; -import com.sun.star.lang.XServiceInfo; -import com.sun.star.logging.LogLevel; -import com.sun.star.resource.XStringResourceResolver; -import com.sun.star.sdbc.SQLException; -import com.sun.star.sdbc.XRow; -import com.sun.star.uno.AnyConverter; -import com.sun.star.uno.Exception; -import com.sun.star.uno.RuntimeException; -import com.sun.star.uno.Type; -import com.sun.star.uno.UnoRuntime; -import com.sun.star.uno.XComponentContext; -import com.sun.star.uno.XInterface; - -import io.github.prrvchr.css.util.Date; -import io.github.prrvchr.css.util.DateTime; -import io.github.prrvchr.css.util.DateTimeWithTimezone; -import io.github.prrvchr.css.util.Time; -import io.github.prrvchr.css.util.TimeWithTimezone; - - -public class UnoHelper -{ - - public static void ensure(boolean condition, String message) { - ensure(condition, message, null); - } - - public static void ensure(Object reference, String message) { - ensure(reference, message, null); - } - - public static void ensure(boolean condition, String message, EventLogger logger) { - if (!condition) { - RuntimeException error = new com.sun.star.uno.RuntimeException(message); - if (logger != null) { - logger.logp(LogLevel.SEVERE, error); - } - throw error; - } - } - - public static void ensure(Object reference, String message, EventLogger logger) { - if (reference == null) { - RuntimeException error = new com.sun.star.uno.RuntimeException(message); - if (logger != null) { - logger.logp(LogLevel.SEVERE, error); - } - throw error; - } - } - - public static void disposeComponent(final Object object) { - final XComponent component = UnoRuntime.queryInterface(XComponent.class, object); - if (component != null) { - component.dispose(); - } - } - - public static void copyProperties(final XPropertySet src, - final XPropertySet dst) - { - if (src == null || dst == null) { - return; - } - - XPropertySetInfo srcPropertySetInfo = src.getPropertySetInfo(); - XPropertySetInfo dstPropertySetInfo = dst.getPropertySetInfo(); - - for (Property srcProperty : srcPropertySetInfo.getProperties()) { - if (dstPropertySetInfo.hasPropertyByName(srcProperty.Name)) { - try { - Property dstProperty = dstPropertySetInfo.getPropertyByName(srcProperty.Name); - System.out.println("UnoHelper.copyProperties() Property: " + srcProperty.Name); - if ((dstProperty.Attributes & PropertyAttribute.READONLY) == 0) { - Object value = src.getPropertyValue(srcProperty.Name); - if ((dstProperty.Attributes & PropertyAttribute.MAYBEVOID) == 0 || value != null) { - dst.setPropertyValue(srcProperty.Name, value); - } - } - } - catch (Exception e) { - String error = "Could not copy property '" + srcProperty.Name + "' to the destination set"; - XServiceInfo serviceInfo = UnoRuntime.queryInterface(XServiceInfo.class, dst); - if (serviceInfo != null) { - error += " (a '" + serviceInfo.getImplementationName() + "' implementation)"; - } - System.out.println("UnoHelper.copyProperties() ERROR: " + error); - } - } - } - } - - public static void disposeComponent(final XComponent component) - { - if (component != null) { - component.dispose(); - } - } - - public static Object createService(XComponentContext context, - String name) - { - Object service = null; - try { - XMultiComponentFactory manager = context.getServiceManager(); - service = manager.createInstanceWithContext(name, context); - } - catch (java.lang.Exception e) { - e.printStackTrace(); - } - return service; - } - - public static Object createService(XComponentContext context, - String name, - Object... arguments) - { - Object service = null; - try { - XMultiComponentFactory manager = context.getServiceManager(); - service = manager.createInstanceWithArgumentsAndContext(name, arguments, context); - } - catch (java.lang.Exception e) { - e.printStackTrace(); - } - return service; - } - - public static XMultiServiceFactory getMultiServiceFactory(XComponentContext context, - String service) - { - return (XMultiServiceFactory) UnoRuntime.queryInterface(XMultiServiceFactory.class, createService(context, service)); - } - - public static XHierarchicalNameAccess getConfiguration(final XComponentContext context, - final String path) - throws Exception - { - return getConfiguration(context, path, false, null); - } - - public static XHierarchicalNameAccess getConfiguration(final XComponentContext context, - final String path, - final boolean update) - throws Exception - { - return getConfiguration(context, path, update, null); - } - - public static XHierarchicalNameAccess getConfiguration(final XComponentContext context, - final String path, - final boolean update, - final String language) - throws Exception - { - String service = "com.sun.star.configuration.Configuration"; - final XMultiServiceFactory provider = getMultiServiceFactory(context, service + "Provider"); - ArrayList arguments = new ArrayList<>(Arrays.asList(new NamedValue("nodepath", path))); - if (language != null) { - arguments.add(new NamedValue("Locale", language)); - } - service += update ? "UpdateAccess" : "Access"; - Object config = provider.createInstanceWithArguments(service, arguments.toArray()); - return (XHierarchicalNameAccess) UnoRuntime.queryInterface(XHierarchicalNameAccess.class, config); - } - - public static String getPackageLocation(XComponentContext context, String identifier, String path) - { - String location = getPackageLocation(context, identifier); - return location + "/" + path + "/"; - } - - public static String getPackageLocation(XComponentContext context, String identifier) - { - String location = ""; - XPackageInformationProvider provider = null; - String service = "/singletons/com.sun.star.deployment.PackageInformationProvider"; - provider = (XPackageInformationProvider) UnoRuntime.queryInterface(XPackageInformationProvider.class, context.getValueByName(service)); - if (provider != null) { - location = provider.getPackageLocation(identifier); - } - return location; - } - - public static Locale getCurrentLocale(XComponentContext context) - throws NoSuchElementException, - Exception - { - String nodepath = "/org.openoffice.Setup/L10N"; - String config = ""; - config = (String) getConfiguration(context, nodepath).getByHierarchicalName("ooLocale"); - String[] parts = config.split("-"); - Locale locale = new Locale(parts[0], "", ""); - if (parts.length > 1) { - locale.Country = parts[1]; - } - else { - Object service = createService(context, "com.sun.star.i18n.LocaleData"); - XLocaleData data = (XLocaleData) UnoRuntime.queryInterface(XLocaleData.class, service); - locale.Country = data.getLanguageCountryInfo(locale).Country; - } - return locale; - } - - public static XStringResourceResolver getResourceResolver(XComponentContext ctx, - String identifier, - String path, - String filename) - throws NoSuchElementException, - Exception - { - Locale locale = getCurrentLocale(ctx); - return getResourceResolver(ctx, identifier, path, filename, locale); - } - - public static XStringResourceResolver getResourceResolver(XComponentContext ctx, - String identifier, - String path, - String filename, - Locale locale) - { - String name = "com.sun.star.resource.StringResourceWithLocation"; - String location = getPackageLocation(ctx, identifier, path); - Object service = createService(ctx, name, location, true, locale, filename, "", null); - return (XStringResourceResolver) UnoRuntime.queryInterface(XStringResourceResolver.class, service); - } - - public static URL getDriverURL(String location) - { - URL url = null; - try { - url = new URL("jar:" + location + "!/"); - } - catch (java.lang.Exception e) { - e.printStackTrace(); - } - return url; - } - - public static URL getDriverURL(String location, String jar) - { - return getDriverURL(location + jar); - } - - public static URL getDriverURL(String location, String path, String jar) - { - return getDriverURL(location + "/" + path + "/" + jar); - } - - public static String getDefaultPropertyValue(PropertyValue[] properties, String name, String value) - throws IllegalArgumentException - { - for (PropertyValue property : properties) { - if (property.Name.equals(name)) { - return AnyConverter.toString(property.Value); - } - } - return value; - } - - public static boolean getDefaultPropertyValue(PropertyValue[] properties, String name, boolean value) - throws IllegalArgumentException - { - for (PropertyValue property : properties) { - if (property.Name.equals(name)) { - return AnyConverter.toBoolean(property.Value); - } - } - return value; - } - - public static Object getDefaultDriverInfo(PropertyValue[] properties, String name, Object value) - throws IllegalArgumentException - { - for (PropertyValue property : properties) { - if (property.Name.equals(name)) { - return property.Value; - } - } - return value; - } - - public static Property getProperty(String name, String type) - { - short attributes = 0; - return getProperty(name, type, attributes); - } - - public static Property getProperty(String name, int handle, String type) - { - short attributes = 0; - return getProperty(name, handle, type, attributes); - } - - public static Property getProperty(String name, String type, short attributes) - { - int handle = -1; - return getProperty(name, handle, type, attributes); - } - - public static Property getProperty(String name, int handle, String type, short attributes) - { - Property property = new Property(); - property.Name = name; - property.Handle = handle; - property.Type = new Type(type); - property.Attributes = attributes; - return property; - } - - public static String getStackTrace(Throwable e) - { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - e.printStackTrace(pw); - return sw.toString(); - } - - public static WrappedTargetException getWrappedException(java.lang.Exception e) - { - WrappedTargetException exception = null; - if (e != null) { - Exception ex = new Exception(e.getMessage()); - exception = getWrappedException(ex); - } - return exception; - } - - public static WrappedTargetException getWrappedException(Exception e) - { - WrappedTargetException exception = null; - if (e != null) { - exception = new WrappedTargetException(e.getMessage()); - exception.Context = e.Context; - exception.TargetException = e; - } - return exception; - } - - public static java.sql.SQLException getSQLException(java.lang.Throwable e) - { - return new java.sql.SQLException(e.getLocalizedMessage(), e); - } - - public static SQLException getSQLException(java.sql.SQLException e) - { - return getUnoSQLException(e.getLocalizedMessage()); - } - - public static SQLException getSQLException(Exception e, XInterface component) - { - SQLException exception = getUnoSQLException(e.getMessage()); - exception.Context = component; - return exception; - } - - public static SQLException getSQLException(java.sql.SQLException e, XInterface component) - { - SQLException exception = null; - if (e != null) { - exception = getUnoSQLException(e.getLocalizedMessage()); - exception.Context = component; - String state = e.getSQLState(); - if (state != null) { - exception.SQLState = state; - } - exception.ErrorCode = e.getErrorCode(); - SQLException ex = getNextSQLException(e.getNextException(), component); - if (ex != null) { - exception.NextException = ex; - } - } - return exception; - } - - public static SQLException getUnoSQLException(String msg) - { - return msg != null ? new SQLException(msg) : new SQLException(); - } - - public static SQLException getSQLException(java.lang.Exception e, - XInterface component) - { - SQLException exception = getUnoSQLException(e.getMessage()); - exception.Context = component; - return exception; - } - - private static SQLException getNextSQLException(java.sql.SQLException e, - XInterface component) - { - SQLException exception = null; - if (e != null) { - exception = getSQLException(e, component); - } - return exception; - } - - public static SQLException getLoggedSQLException(XInterface component, - ResourceBasedEventLogger logger, - java.sql.SQLException throwable) - { - - SQLException exception = getSQLException(throwable, component); - logger.log(LogLevel.SEVERE, throwable); - return exception; - } - - public static String getObjectString(Object object) - { - String value = null; - if (AnyConverter.isString(object)) { - value = AnyConverter.toString(object); - System.out.println("UnoHelper.getObjectString() 1"); - } - return value; - } - - public static com.sun.star.util.Date getUnoDate(java.time.LocalDate date) - { - com.sun.star.util.Date value = new com.sun.star.util.Date(); - if (date != null) { - value.Year = (short) date.getYear(); - value.Month = (short) date.getMonthValue(); - value.Day = (short) date.getDayOfMonth(); - } - return value; - } - - public static com.sun.star.util.Time getUnoTime(java.time.LocalTime time) - { - com.sun.star.util.Time value = new com.sun.star.util.Time(); - if (time != null) { - value.Hours = (short) time.getHour(); - value.Minutes = (short) time.getMinute(); - value.Seconds = (short) time.getSecond(); - //value.NanoSeconds = time.getNano(); - //value.HundredthSeconds = 0; - } - return value; - } - - public static com.sun.star.util.DateTime getUnoDateTime(java.time.LocalDateTime datetime) - { - com.sun.star.util.DateTime value = new com.sun.star.util.DateTime(); - if (datetime != null) { - value.Year = (short) datetime.getYear(); - value.Month = (short) datetime.getMonthValue(); - value.Day = (short) datetime.getDayOfMonth(); - value.Hours = (short) datetime.getHour(); - value.Minutes = (short) datetime.getMinute(); - value.Seconds = (short) datetime.getSecond(); - //value.NanoSeconds = datetime.getNano(); - //value.HundredthSeconds = 0; - } - return value; - } - - public static com.sun.star.util.TimeWithTimezone getUnoTimeWithTimezone(java.time.OffsetTime time) - { - com.sun.star.util.TimeWithTimezone value = new com.sun.star.util.TimeWithTimezone(); - if (time != null) { - value.TimeInTZ = getUnoTime(time.toLocalTime()); - value.Timezone = getUnoTimezone(time.getOffset()); - } - return value; - } - - public static io.github.prrvchr.css.util.TimeWithTimezone getTimeWithTimezone(java.time.OffsetTime time) - { - io.github.prrvchr.css.util.TimeWithTimezone value = new io.github.prrvchr.css.util.TimeWithTimezone(); - if (time != null) { - value.TimeInTZ = getTime(time.toLocalTime()); - value.Timezone = getUnoTimezone(time.getOffset()); - } - return value; - } - - public static io.github.prrvchr.css.util.Time getTime(java.time.LocalTime time) - { - io.github.prrvchr.css.util.Time value = new io.github.prrvchr.css.util.Time(); - if (time != null) { - value.Hours = (short) time.getHour(); - value.Minutes = (short) time.getMinute(); - value.Seconds = (short) time.getSecond(); - value.NanoSeconds = time.getNano(); - } - return value; - } - - public static io.github.prrvchr.css.util.DateTimeWithTimezone getDateTimeWithTimezone(OffsetDateTime datetime) - { - io.github.prrvchr.css.util.DateTimeWithTimezone value = new io.github.prrvchr.css.util.DateTimeWithTimezone(); - if (datetime != null) { - value.DateTimeInTZ = getDateTime(datetime.toLocalDateTime()); - value.Timezone = getUnoTimezone(datetime.getOffset()); - } - return value; - } - - public static io.github.prrvchr.css.util.DateTime getDateTime(java.time.LocalDateTime datetime) - { - io.github.prrvchr.css.util.DateTime value = new io.github.prrvchr.css.util.DateTime(); - if (datetime != null) { - value.Year = (short) datetime.getYear(); - value.Month = (short) datetime.getMonthValue(); - value.Day = (short) datetime.getDayOfMonth(); - value.Hours = (short) datetime.getHour(); - value.Minutes = (short) datetime.getMinute(); - value.Seconds = (short) datetime.getSecond(); - value.NanoSeconds = datetime.getNano(); - value.IsUTC = false; - } - return value; - } - - public static com.sun.star.util.DateTimeWithTimezone getUnoDateTimeWithTimezone(OffsetDateTime datetime) - { - com.sun.star.util.DateTimeWithTimezone value = new com.sun.star.util.DateTimeWithTimezone(); - if (datetime != null) { - value.DateTimeInTZ = getUnoDateTime(datetime.toLocalDateTime()); - value.Timezone = getUnoTimezone(datetime.getOffset()); - } - return value; - } - - public static short getUnoTimezone(java.time.ZoneOffset offset) - { - return (short) (offset.getTotalSeconds() / 60); - } - - public static java.time.LocalDate getJavaLocalDate(com.sun.star.util.Date date) - { - return java.time.LocalDate.of(date.Year, date.Month, date.Day); - } - - public static java.time.LocalDate getJavaLocalDate(Date date) - { - return java.time.LocalDate.of(date.Year, date.Month, date.Day); - } - - public static java.time.LocalTime getJavaLocalTime(com.sun.star.util.Time time) - { - //return java.time.LocalTime.of(time.Hours, time.Minutes, time.Seconds, time.NanoSeconds); - return java.time.LocalTime.of(time.Hours, time.Minutes, time.Seconds); - } - - public static java.time.LocalTime getJavaLocalTime(Time time) - { - return java.time.LocalTime.of(time.Hours, time.Minutes, time.Seconds, time.NanoSeconds); - } - - public static java.time.LocalDateTime getJavaLocalDateTime(com.sun.star.util.DateTime timestamp) - { - //return java.time.LocalDateTime.of(timestamp.Year, timestamp.Month, timestamp.Day, timestamp.Hours, timestamp.Minutes, timestamp.Seconds, timestamp.NanoSeconds); - return java.time.LocalDateTime.of(timestamp.Year, timestamp.Month, timestamp.Day, timestamp.Hours, timestamp.Minutes, timestamp.Seconds); - } - - public static java.time.LocalDateTime getJavaLocalDateTime(DateTime timestamp) - { - return java.time.LocalDateTime.of(timestamp.Year, timestamp.Month, timestamp.Day, timestamp.Hours, timestamp.Minutes, timestamp.Seconds, timestamp.NanoSeconds); - } - - public static java.time.ZoneOffset getJavaZoneOffset(int offset) - { - return java.time.ZoneOffset.ofTotalSeconds(offset * 60); - } - - public static java.time.OffsetTime getJavaOffsetTime(com.sun.star.util.TimeWithTimezone time) - { - return java.time.OffsetTime.of(getJavaLocalTime(time.TimeInTZ), getJavaZoneOffset(time.Timezone)); - } - - public static java.time.OffsetTime getJavaOffsetTime(TimeWithTimezone time) - { - return java.time.OffsetTime.of(getJavaLocalTime(time.TimeInTZ), getJavaZoneOffset(time.Timezone)); - } - - public static OffsetDateTime getJavaOffsetDateTime(com.sun.star.util.DateTimeWithTimezone datetime) - { - return OffsetDateTime.of(getJavaLocalDateTime(datetime.DateTimeInTZ), getJavaZoneOffset(datetime.Timezone)); - } - - public static OffsetDateTime getJavaOffsetDateTime(DateTimeWithTimezone datetime) - { - return OffsetDateTime.of(getJavaLocalDateTime(datetime.DateTimeInTZ), getJavaZoneOffset(datetime.Timezone)); - } - - public static Object getObjectFromResult(java.sql.ResultSet result, int index) - { - Object value = null; - try { - value = result.getObject(index); - } - catch (java.sql.SQLException e) { - e.getStackTrace(); - } - return value; - } - - public static String getResultSetValue(java.sql.ResultSet result, int index) - { - String value = null; - try { - value = result.getString(index); - } - catch (java.sql.SQLException e) { - e.getStackTrace(); - } - return value; - } - - public static Object getResultValue(java.sql.ResultSet result, int index) - { - boolean retrieved = true; - Object value = null; - try { - switch (result.getMetaData().getColumnType(index)) { - case java.sql.Types.CHAR: - case java.sql.Types.VARCHAR: - value = result.getString(index); - break; - case java.sql.Types.BOOLEAN: - value = result.getBoolean(index); - break; - case java.sql.Types.TINYINT: - value = result.getByte(index); - break; - case java.sql.Types.SMALLINT: - value = result.getShort(index); - break; - case java.sql.Types.INTEGER: - value = result.getInt(index); - break; - case java.sql.Types.BIGINT: - value = result.getLong(index); - break; - case java.sql.Types.FLOAT: - value = result.getFloat(index); - break; - case java.sql.Types.DOUBLE: - value = result.getDouble(index); - break; - case java.sql.Types.TIMESTAMP: - value = result.getTimestamp(index); - break; - case java.sql.Types.TIME: - value = result.getTime(index); - break; - case java.sql.Types.DATE: - value = result.getDate(index); - break; - case java.sql.Types.BINARY: - value = result.getBytes(index); - break; - case java.sql.Types.TIME_WITH_TIMEZONE: - case java.sql.Types.TIMESTAMP_WITH_TIMEZONE: - value = result.getObject(index); - break; - default: - retrieved = false; - } - if(retrieved && result.wasNull()) value = null; - } - catch (java.sql.SQLException e) { - e.getStackTrace(); - } - return value; - } - - public static Object getRowValue(XRow row, int dbtype, int index) - throws SQLException - { - return getRowValue(row, dbtype, index, null); - } - - public static Object getRowValue(XRow row, int dbtype, int index, Object value) - throws SQLException - { - boolean retrieved = true; - switch (dbtype) { - case java.sql.Types.CHAR: - case java.sql.Types.VARCHAR: - value = row.getString(index); - break; - case java.sql.Types.BOOLEAN: - value = row.getBoolean(index); - break; - case java.sql.Types.TINYINT: - value = row.getByte(index); - break; - case java.sql.Types.SMALLINT: - value = row.getShort(index); - break; - case java.sql.Types.INTEGER: - value = row.getInt(index); - break; - case java.sql.Types.BIGINT: - value = row.getLong(index); - break; - case java.sql.Types.FLOAT: - value = row.getFloat(index); - break; - case java.sql.Types.DOUBLE: - value = row.getDouble(index); - break; - case java.sql.Types.TIMESTAMP: - value = row.getTimestamp(index); - break; - case java.sql.Types.TIME: - value = row.getTime(index); - break; - case java.sql.Types.DATE: - value = row.getDate(index); - break; - case java.sql.Types.BINARY: - value = row.getBytes(index); - break; - case java.sql.Types.ARRAY: - value = row.getArray(index); - break; - case java.sql.Types.TIME_WITH_TIMEZONE: - case java.sql.Types.TIMESTAMP_WITH_TIMEZONE: - value = row.getObject(index, null); - break; - default: - retrieved = false; - } - if(retrieved && row.wasNull()) value = null; - return value; - } - - public static DateTimeWithTimezone currentDateTimeInTZ() - { - return currentDateTimeInTZ(true); - } - - public static DateTimeWithTimezone currentDateTimeInTZ(boolean utc) - { - DateTimeWithTimezone dtz = new DateTimeWithTimezone(); - OffsetDateTime now = utc ? OffsetDateTime.now(java.time.ZoneOffset.UTC) : OffsetDateTime.now(); - dtz.DateTimeInTZ = _currentDateTime(now, utc); - dtz.Timezone = utc ? 0 : (short) (now.getOffset().getTotalSeconds() / 60); - return dtz; - } - - public static com.sun.star.util.DateTime currentUnoDateTime() - { - OffsetDateTime now = OffsetDateTime.now(java.time.ZoneOffset.UTC); - com.sun.star.util.DateTime dt = new com.sun.star.util.DateTime(); - dt.Year = (short) now.getYear(); - dt.Month = (short) now.getMonthValue(); - dt.Day = (short) now.getDayOfMonth(); - dt.Hours = (short) now.getHour(); - dt.Minutes = (short) now.getMinute(); - dt.Seconds = (short) now.getSecond(); - return dt; - } - - public static DateTime currentDateTime(boolean utc) - { - OffsetDateTime now = utc ? OffsetDateTime.now(java.time.ZoneOffset.UTC) : OffsetDateTime.now(); - return _currentDateTime(now, utc); - } - - private static DateTime _currentDateTime(OffsetDateTime now, - boolean utc) - { - DateTime dt = new DateTime(); - dt.Year = (short) now.getYear(); - dt.Month = (short) now.getMonthValue(); - dt.Day = (short) now.getDayOfMonth(); - dt.Hours = (short) now.getHour(); - dt.Minutes = (short) now.getMinute(); - dt.Seconds = (short) now.getSecond(); - dt.NanoSeconds = now.getNano(); - dt.IsUTC = utc; - return dt; - } - - public static Integer getConstantValue(Class clazz, String name) - throws java.sql.SQLException - { - int value = 0; - if (name != null && !name.isBlank()) { - try { - value = (int) clazz.getDeclaredField(name).get(null); - } - catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) { - e.printStackTrace(System.out); - } - } - return value; - } - - public static int mapSQLDataType(int type) - { - Map maps = Map.ofEntries(Map.entry(-16, -1), - Map.entry(-15, 1), - Map.entry(-9, 12), - Map.entry(-8, 4), - Map.entry(70, 1111), - Map.entry(2009, 1111), - Map.entry(2011, 2005), - Map.entry(2012, 2006), - Map.entry(2013, 12), - Map.entry(2014, 12)); - if (maps.containsKey(type)) { - System.out.println("UnoHelper.mapSQLDataType() Type: " + type); - type = maps.get(type); - } - return type; - } - - public static String mapSQLDataTypeName(String name, int type) - { - //String name = null; - //Map maps = _getUnoSQLDataType(); - //if (!maps.containsValue(name)) - // if (maps.containsKey(type)) - // { - // //name = maps.get(type); - // System.out.println("UnoHelper.mapSQLDataTypeName() 1 ************************* Name: " + name + " Type: " + type); - // } - // else - // System.out.println("UnoHelper.mapSQLDataTypeName() 2 ************************* Name: " + name + " Type: " + type); - return name; - } - - public static Map _getUnoSQLDataType() - { - Map maps = Map.ofEntries(Map.entry(-7, "BIT"), - Map.entry(-6, "TINYINT"), - Map.entry(-5, "BIGINT"), - Map.entry(-4, "LONGVARBINARY"), - Map.entry(-3, "VARBINARY"), - Map.entry(-2, "BINARY"), - Map.entry(-1, "LONGVARCHAR"), - Map.entry(0, "SQLNULL"), - Map.entry(1, "CHAR"), - Map.entry(2, "NUMERIC"), - Map.entry(3, "DECIMAL"), - Map.entry(4, "INTEGER"), - Map.entry(5, "SMALLINT"), - Map.entry(6, "FLOAT"), - Map.entry(7, "REAL"), - Map.entry(8, "DOUBLE"), - Map.entry(12, "VARCHAR"), - Map.entry(16, "BOOLEAN"), - Map.entry(91, "DATE"), - Map.entry(92, "TIME"), - Map.entry(93, "TIMESTAMP"), - Map.entry(1111, "OTHER"), - Map.entry(2000, "OBJECT"), - Map.entry(2001, "DISTINCT"), - Map.entry(2002, "STRUCT"), - Map.entry(2003, "ARRAY"), - Map.entry(2004, "BLOB"), - Map.entry(2005, "CLOB"), - Map.entry(2006, "REF")); - return maps; - } - - public static String getClassPath() - { - StringBuffer buffer = new StringBuffer(); - ClassLoader cl = ClassLoader.getSystemClassLoader(); - URL[] urls = ((URLClassLoader)cl).getURLs(); - for (URL url : urls) { - buffer.append(url.getFile()); - buffer.append(System.getProperty("path.separator")); - } - return buffer.toString(); - } - - public static void inspect(XComponentContext context, XInterface descriptor) - { - String service = "mytools.Mri"; - Object object = UnoHelper.createService(context, service); - XIntrospection mri = (XIntrospection) UnoRuntime.queryInterface(XIntrospection.class, object); - mri.inspect(descriptor); - } - - public static String getConfigurationOption(XHierarchicalNameAccess config, - String property, - String value) - { - String option = value; - try { - if (config.hasByHierarchicalName(property)) { - option = AnyConverter.toString(config.getByHierarchicalName(property)); - } - } - catch (Exception e) { - e.printStackTrace(); - } - return option; - } - - public static boolean getConfigurationOption(XHierarchicalNameAccess config, - String property, - boolean value) - { - boolean option = value; - try { - if (config.hasByHierarchicalName(property)) { - option = AnyConverter.toBoolean(config.getByHierarchicalName(property)); - } - } - catch (Exception e) { - e.printStackTrace(); - } - return option; - } - - public static String getCaller() - { - StackWalker stackWalker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - StackWalker.StackFrame frame = stackWalker.walk(stream1 -> stream1.skip(2) - .findFirst() - .orElse(null)); - if (frame == null) { - return "caller: null"; - } - return String.format("caller: %s#%s, %s", - frame.getClassName(), - frame.getMethodName(), - frame.getLineNumber()); - } - - public static void printStackTrace() - { - Thread thread = Thread.currentThread(); - StackTraceElement[] stackTrace = thread.getStackTrace(); - for (int i = 1; i < stackTrace.length; i++) { - System.out.println(stackTrace[i].getClassName() + " " + stackTrace[i].getMethodName() + " " + stackTrace[i].getLineNumber()); - } - } - -} diff --git a/uno/lib/python/PySocks-1.7.1.dist-info/LICENSE b/uno/lib/python/PySocks-1.7.1.dist-info/LICENSE deleted file mode 100644 index 04b6b1f3..00000000 --- a/uno/lib/python/PySocks-1.7.1.dist-info/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright 2006 Dan-Haim. 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. Neither the name of Dan Haim nor the names of his contributors may be used - to endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY DAN HAIM "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 DAN HAIM OR HIS 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, 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 DAMANGE. diff --git a/uno/lib/python/PySocks-1.7.1.dist-info/METADATA b/uno/lib/python/PySocks-1.7.1.dist-info/METADATA deleted file mode 100644 index ae2ae341..00000000 --- a/uno/lib/python/PySocks-1.7.1.dist-info/METADATA +++ /dev/null @@ -1,321 +0,0 @@ -Metadata-Version: 2.1 -Name: PySocks -Version: 1.7.1 -Summary: A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information. -Home-page: https://github.com/Anorov/PySocks -Author: Anorov -Author-email: anorov.vorona@gmail.com -License: BSD -Keywords: socks,proxy -Platform: UNKNOWN -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* -Description-Content-Type: text/markdown - -PySocks -======= - -PySocks lets you send traffic through SOCKS and HTTP proxy servers. It is a modern fork of [SocksiPy](http://socksipy.sourceforge.net/) with bug fixes and extra features. - -Acts as a drop-in replacement to the socket module. Seamlessly configure SOCKS proxies for any socket object by calling `socket_object.set_proxy()`. - ----------------- - -Features -======== - -* SOCKS proxy client for Python 2.7 and 3.4+ -* TCP supported -* UDP mostly supported (issues may occur in some edge cases) -* HTTP proxy client included but not supported or recommended (you should use urllib2's or requests' own HTTP proxy interface) -* urllib2 handler included. `pip install` / `setup.py install` will automatically install the `sockshandler` module. - -Installation -============ - - pip install PySocks - -Or download the tarball / `git clone` and... - - python setup.py install - -These will install both the `socks` and `sockshandler` modules. - -Alternatively, include just `socks.py` in your project. - --------------------------------------------- - -*Warning:* PySocks/SocksiPy only supports HTTP proxies that use CONNECT tunneling. Certain HTTP proxies may not work with this library. If you wish to use HTTP (not SOCKS) proxies, it is recommended that you rely on your HTTP client's native proxy support (`proxies` dict for `requests`, or `urllib2.ProxyHandler` for `urllib2`) instead. - --------------------------------------------- - -Usage -===== - -## socks.socksocket ## - - import socks - - s = socks.socksocket() # Same API as socket.socket in the standard lib - - s.set_proxy(socks.SOCKS5, "localhost") # SOCKS4 and SOCKS5 use port 1080 by default - # Or - s.set_proxy(socks.SOCKS4, "localhost", 4444) - # Or - s.set_proxy(socks.HTTP, "5.5.5.5", 8888) - - # Can be treated identical to a regular socket object - s.connect(("www.somesite.com", 80)) - s.sendall("GET / HTTP/1.1 ...") - print s.recv(4096) - -## Monkeypatching ## - -To monkeypatch the entire standard library with a single default proxy: - - import urllib2 - import socket - import socks - - socks.set_default_proxy(socks.SOCKS5, "localhost") - socket.socket = socks.socksocket - - urllib2.urlopen("http://www.somesite.com/") # All requests will pass through the SOCKS proxy - -Note that monkeypatching may not work for all standard modules or for all third party modules, and generally isn't recommended. Monkeypatching is usually an anti-pattern in Python. - -## urllib2 Handler ## - -Example use case with the `sockshandler` urllib2 handler. Note that you must import both `socks` and `sockshandler`, as the handler is its own module separate from PySocks. The module is included in the PyPI package. - - import urllib2 - import socks - from sockshandler import SocksiPyHandler - - opener = urllib2.build_opener(SocksiPyHandler(socks.SOCKS5, "127.0.0.1", 9050)) - print opener.open("http://www.somesite.com/") # All requests made by the opener will pass through the SOCKS proxy - --------------------------------------------- - -Original SocksiPy README attached below, amended to reflect API changes. - --------------------------------------------- - -SocksiPy - -A Python SOCKS module. - -(C) 2006 Dan-Haim. All rights reserved. - -See LICENSE file for details. - - -*WHAT IS A SOCKS PROXY?* - -A SOCKS proxy is a proxy server at the TCP level. In other words, it acts as -a tunnel, relaying all traffic going through it without modifying it. -SOCKS proxies can be used to relay traffic using any network protocol that -uses TCP. - -*WHAT IS SOCKSIPY?* - -This Python module allows you to create TCP connections through a SOCKS -proxy without any special effort. -It also supports relaying UDP packets with a SOCKS5 proxy. - -*PROXY COMPATIBILITY* - -SocksiPy is compatible with three different types of proxies: - -1. SOCKS Version 4 (SOCKS4), including the SOCKS4a extension. -2. SOCKS Version 5 (SOCKS5). -3. HTTP Proxies which support tunneling using the CONNECT method. - -*SYSTEM REQUIREMENTS* - -Being written in Python, SocksiPy can run on any platform that has a Python -interpreter and TCP/IP support. -This module has been tested with Python 2.3 and should work with greater versions -just as well. - - -INSTALLATION -------------- - -Simply copy the file "socks.py" to your Python's `lib/site-packages` directory, -and you're ready to go. [Editor's note: it is better to use `python setup.py install` for PySocks] - - -USAGE ------- - -First load the socks module with the command: - - >>> import socks - >>> - -The socks module provides a class called `socksocket`, which is the base to all of the module's functionality. - -The `socksocket` object has the same initialization parameters as the normal socket -object to ensure maximal compatibility, however it should be noted that `socksocket` will only function with family being `AF_INET` and -type being either `SOCK_STREAM` or `SOCK_DGRAM`. -Generally, it is best to initialize the `socksocket` object with no parameters - - >>> s = socks.socksocket() - >>> - -The `socksocket` object has an interface which is very similiar to socket's (in fact -the `socksocket` class is derived from socket) with a few extra methods. -To select the proxy server you would like to use, use the `set_proxy` method, whose -syntax is: - - set_proxy(proxy_type, addr[, port[, rdns[, username[, password]]]]) - -Explanation of the parameters: - -`proxy_type` - The type of the proxy server. This can be one of three possible -choices: `PROXY_TYPE_SOCKS4`, `PROXY_TYPE_SOCKS5` and `PROXY_TYPE_HTTP` for SOCKS4, -SOCKS5 and HTTP servers respectively. `SOCKS4`, `SOCKS5`, and `HTTP` are all aliases, respectively. - -`addr` - The IP address or DNS name of the proxy server. - -`port` - The port of the proxy server. Defaults to 1080 for socks and 8080 for http. - -`rdns` - This is a boolean flag than modifies the behavior regarding DNS resolving. -If it is set to True, DNS resolving will be preformed remotely, on the server. -If it is set to False, DNS resolving will be preformed locally. Please note that -setting this to True with SOCKS4 servers actually use an extension to the protocol, -called SOCKS4a, which may not be supported on all servers (SOCKS5 and http servers -always support DNS). The default is True. - -`username` - For SOCKS5 servers, this allows simple username / password authentication -with the server. For SOCKS4 servers, this parameter will be sent as the userid. -This parameter is ignored if an HTTP server is being used. If it is not provided, -authentication will not be used (servers may accept unauthenticated requests). - -`password` - This parameter is valid only for SOCKS5 servers and specifies the -respective password for the username provided. - -Example of usage: - - >>> s.set_proxy(socks.SOCKS5, "socks.example.com") # uses default port 1080 - >>> s.set_proxy(socks.SOCKS4, "socks.test.com", 1081) - -After the set_proxy method has been called, simply call the connect method with the -traditional parameters to establish a connection through the proxy: - - >>> s.connect(("www.sourceforge.net", 80)) - >>> - -Connection will take a bit longer to allow negotiation with the proxy server. -Please note that calling connect without calling `set_proxy` earlier will connect -without a proxy (just like a regular socket). - -Errors: Any errors in the connection process will trigger exceptions. The exception -may either be generated by the underlying socket layer or may be custom module -exceptions, whose details follow: - -class `ProxyError` - This is a base exception class. It is not raised directly but -rather all other exception classes raised by this module are derived from it. -This allows an easy way to catch all proxy-related errors. It descends from `IOError`. - -All `ProxyError` exceptions have an attribute `socket_err`, which will contain either a -caught `socket.error` exception, or `None` if there wasn't any. - -class `GeneralProxyError` - When thrown, it indicates a problem which does not fall -into another category. - -* `Sent invalid data` - This error means that unexpected data has been received from -the server. The most common reason is that the server specified as the proxy is -not really a SOCKS4/SOCKS5/HTTP proxy, or maybe the proxy type specified is wrong. - -* `Connection closed unexpectedly` - The proxy server unexpectedly closed the connection. -This may indicate that the proxy server is experiencing network or software problems. - -* `Bad proxy type` - This will be raised if the type of the proxy supplied to the -set_proxy function was not one of `SOCKS4`/`SOCKS5`/`HTTP`. - -* `Bad input` - This will be raised if the `connect()` method is called with bad input -parameters. - -class `SOCKS5AuthError` - This indicates that the connection through a SOCKS5 server -failed due to an authentication problem. - -* `Authentication is required` - This will happen if you use a SOCKS5 server which -requires authentication without providing a username / password at all. - -* `All offered authentication methods were rejected` - This will happen if the proxy -requires a special authentication method which is not supported by this module. - -* `Unknown username or invalid password` - Self descriptive. - -class `SOCKS5Error` - This will be raised for SOCKS5 errors which are not related to -authentication. -The parameter is a tuple containing a code, as given by the server, -and a description of the -error. The possible errors, according to the RFC, are: - -* `0x01` - General SOCKS server failure - If for any reason the proxy server is unable to -fulfill your request (internal server error). -* `0x02` - connection not allowed by ruleset - If the address you're trying to connect to -is blacklisted on the server or requires authentication. -* `0x03` - Network unreachable - The target could not be contacted. A router on the network -had replied with a destination net unreachable error. -* `0x04` - Host unreachable - The target could not be contacted. A router on the network -had replied with a destination host unreachable error. -* `0x05` - Connection refused - The target server has actively refused the connection -(the requested port is closed). -* `0x06` - TTL expired - The TTL value of the SYN packet from the proxy to the target server -has expired. This usually means that there are network problems causing the packet -to be caught in a router-to-router "ping-pong". -* `0x07` - Command not supported - For instance if the server does not support UDP. -* `0x08` - Address type not supported - The client has provided an invalid address type. -When using this module, this error should not occur. - -class `SOCKS4Error` - This will be raised for SOCKS4 errors. The parameter is a tuple -containing a code and a description of the error, as given by the server. The -possible error, according to the specification are: - -* `0x5B` - Request rejected or failed - Will be raised in the event of an failure for any -reason other then the two mentioned next. -* `0x5C` - request rejected because SOCKS server cannot connect to identd on the client - -The Socks server had tried an ident lookup on your computer and has failed. In this -case you should run an identd server and/or configure your firewall to allow incoming -connections to local port 113 from the remote server. -* `0x5D` - request rejected because the client program and identd report different user-ids - -The Socks server had performed an ident lookup on your computer and has received a -different userid than the one you have provided. Change your userid (through the -username parameter of the set_proxy method) to match and try again. - -class `HTTPError` - This will be raised for HTTP errors. The message will contain -the HTTP status code and provided error message. - -After establishing the connection, the object behaves like a standard socket. - -Methods like `makefile()` and `settimeout()` should behave just like regular sockets. -Call the `close()` method to close the connection. - -In addition to the `socksocket` class, an additional function worth mentioning is the -`set_default_proxy` function. The parameters are the same as the `set_proxy` method. -This function will set default proxy settings for newly created `socksocket` objects, -in which the proxy settings haven't been changed via the `set_proxy` method. -This is quite useful if you wish to force 3rd party modules to use a SOCKS proxy, -by overriding the socket object. -For example: - - >>> socks.set_default_proxy(socks.SOCKS5, "socks.example.com") - >>> socket.socket = socks.socksocket - >>> urllib.urlopen("http://www.sourceforge.net/") - - -PROBLEMS ---------- - -Please open a GitHub issue at https://github.com/Anorov/PySocks - - diff --git a/uno/lib/python/PySocks-1.7.1.dist-info/RECORD b/uno/lib/python/PySocks-1.7.1.dist-info/RECORD deleted file mode 100644 index fc9dff1a..00000000 --- a/uno/lib/python/PySocks-1.7.1.dist-info/RECORD +++ /dev/null @@ -1,7 +0,0 @@ -socks.py,sha256=xOYn27t9IGrbTBzWsUUuPa0YBuplgiUykzkOB5V5iFY,31086 -sockshandler.py,sha256=2SYGj-pwt1kjgLoZAmyeaEXCeZDWRmfVS_QG6kErGtY,3966 -PySocks-1.7.1.dist-info/LICENSE,sha256=cCfiFOAU63i3rcwc7aWspxOnn8T2oMUsnaWz5wfm_-k,1401 -PySocks-1.7.1.dist-info/METADATA,sha256=zbQMizjPOOP4DhEiEX24XXjNrYuIxF9UGUpN0uFDB6Y,13235 -PySocks-1.7.1.dist-info/WHEEL,sha256=t_MpApv386-8PVts2R6wsTifdIn0vbUDTVv61IbqFC8,92 -PySocks-1.7.1.dist-info/top_level.txt,sha256=TKSOIfCFBoK9EY8FBYbYqC3PWd3--G15ph9n8-QHPDk,19 -PySocks-1.7.1.dist-info/RECORD,, diff --git a/uno/lib/python/PySocks-1.7.1.dist-info/WHEEL b/uno/lib/python/PySocks-1.7.1.dist-info/WHEEL deleted file mode 100644 index 129a6735..00000000 --- a/uno/lib/python/PySocks-1.7.1.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.33.3) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/uno/lib/python/PySocks-1.7.1.dist-info/top_level.txt b/uno/lib/python/PySocks-1.7.1.dist-info/top_level.txt deleted file mode 100644 index 9476163a..00000000 --- a/uno/lib/python/PySocks-1.7.1.dist-info/top_level.txt +++ /dev/null @@ -1,2 +0,0 @@ -socks -sockshandler diff --git a/uno/lib/python/_cffi_backend.cp38-win32.pyd b/uno/lib/python/_cffi_backend.cp38-win32.pyd deleted file mode 100644 index a88b9341..00000000 Binary files a/uno/lib/python/_cffi_backend.cp38-win32.pyd and /dev/null differ diff --git a/uno/lib/python/_cffi_backend.cp38-win_amd64.pyd b/uno/lib/python/_cffi_backend.cp38-win_amd64.pyd deleted file mode 100644 index 0f17c588..00000000 Binary files a/uno/lib/python/_cffi_backend.cp38-win_amd64.pyd and /dev/null differ diff --git a/uno/lib/python/_cffi_backend.cp39-win32.pyd b/uno/lib/python/_cffi_backend.cp39-win32.pyd deleted file mode 100644 index 48ca71b1..00000000 Binary files a/uno/lib/python/_cffi_backend.cp39-win32.pyd and /dev/null differ diff --git a/uno/lib/python/_cffi_backend.cp39-win_amd64.pyd b/uno/lib/python/_cffi_backend.cp39-win_amd64.pyd deleted file mode 100644 index a857f16c..00000000 Binary files a/uno/lib/python/_cffi_backend.cp39-win_amd64.pyd and /dev/null differ diff --git a/uno/lib/python/_cffi_backend.cpython-3.8.so b/uno/lib/python/_cffi_backend.cpython-3.8.so deleted file mode 120000 index c79f7057..00000000 --- a/uno/lib/python/_cffi_backend.cpython-3.8.so +++ /dev/null @@ -1 +0,0 @@ -_cffi_backend.cpython-38-x86_64-linux-gnu.so \ No newline at end of file diff --git a/uno/lib/python/_cffi_backend.cpython-310-x86_64-linux-gnu.so b/uno/lib/python/_cffi_backend.cpython-310-x86_64-linux-gnu.so deleted file mode 100755 index da35b48d..00000000 Binary files a/uno/lib/python/_cffi_backend.cpython-310-x86_64-linux-gnu.so and /dev/null differ diff --git a/uno/lib/python/_cffi_backend.cpython-311-x86_64-linux-gnu.so b/uno/lib/python/_cffi_backend.cpython-311-x86_64-linux-gnu.so deleted file mode 100755 index b3521bbd..00000000 Binary files a/uno/lib/python/_cffi_backend.cpython-311-x86_64-linux-gnu.so and /dev/null differ diff --git a/uno/lib/python/_cffi_backend.cpython-312-x86_64-linux-gnu.so b/uno/lib/python/_cffi_backend.cpython-312-x86_64-linux-gnu.so deleted file mode 100755 index 6bf6e4f6..00000000 Binary files a/uno/lib/python/_cffi_backend.cpython-312-x86_64-linux-gnu.so and /dev/null differ diff --git a/uno/lib/python/_cffi_backend.cpython-38-darwin.so b/uno/lib/python/_cffi_backend.cpython-38-darwin.so deleted file mode 100755 index 415042af..00000000 Binary files a/uno/lib/python/_cffi_backend.cpython-38-darwin.so and /dev/null differ diff --git a/uno/lib/python/_cffi_backend.cpython-38-x86_64-linux-gnu.so b/uno/lib/python/_cffi_backend.cpython-38-x86_64-linux-gnu.so deleted file mode 100755 index 09c1afff..00000000 Binary files a/uno/lib/python/_cffi_backend.cpython-38-x86_64-linux-gnu.so and /dev/null differ diff --git a/uno/lib/python/_cffi_backend.cpython-39-x86_64-linux-gnu.so b/uno/lib/python/_cffi_backend.cpython-39-x86_64-linux-gnu.so deleted file mode 100755 index 693f602f..00000000 Binary files a/uno/lib/python/_cffi_backend.cpython-39-x86_64-linux-gnu.so and /dev/null differ diff --git a/uno/lib/python/_distutils_hack/__init__.py b/uno/lib/python/_distutils_hack/__init__.py deleted file mode 100644 index b05d04e9..00000000 --- a/uno/lib/python/_distutils_hack/__init__.py +++ /dev/null @@ -1,240 +0,0 @@ -# don't import any costly modules -import os -import sys - -report_url = ( - "https://github.com/pypa/setuptools/issues/new?" - "template=distutils-deprecation.yml" -) - - -def warn_distutils_present(): - if 'distutils' not in sys.modules: - return - import warnings - - warnings.warn( - "Distutils was imported before Setuptools, but importing Setuptools " - "also replaces the `distutils` module in `sys.modules`. This may lead " - "to undesirable behaviors or errors. To avoid these issues, avoid " - "using distutils directly, ensure that setuptools is installed in the " - "traditional way (e.g. not an editable install), and/or make sure " - "that setuptools is always imported before distutils." - ) - - -def clear_distutils(): - if 'distutils' not in sys.modules: - return - import warnings - - warnings.warn( - "Setuptools is replacing distutils. Support for replacing " - "an already imported distutils is deprecated. In the future, " - "this condition will fail. " - f"Register concerns at {report_url}" - ) - mods = [ - name - for name in sys.modules - if name == "distutils" or name.startswith("distutils.") - ] - for name in mods: - del sys.modules[name] - - -def enabled(): - """ - Allow selection of distutils by environment variable. - """ - which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'local') - if which == 'stdlib': - import warnings - - warnings.warn( - "Reliance on distutils from stdlib is deprecated. Users " - "must rely on setuptools to provide the distutils module. " - "Avoid importing distutils or import setuptools first, " - "and avoid setting SETUPTOOLS_USE_DISTUTILS=stdlib. " - f"Register concerns at {report_url}" - ) - return which == 'local' - - -def ensure_local_distutils(): - import importlib - - clear_distutils() - - # With the DistutilsMetaFinder in place, - # perform an import to cause distutils to be - # loaded from setuptools._distutils. Ref #2906. - with shim(): - importlib.import_module('distutils') - - # check that submodules load as expected - core = importlib.import_module('distutils.core') - assert '_distutils' in core.__file__, core.__file__ - assert 'setuptools._distutils.log' not in sys.modules - - -def do_override(): - """ - Ensure that the local copy of distutils is preferred over stdlib. - - See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401 - for more motivation. - """ - if enabled(): - warn_distutils_present() - ensure_local_distutils() - - -class _TrivialRe: - def __init__(self, *patterns): - self._patterns = patterns - - def match(self, string): - return all(pat in string for pat in self._patterns) - - -class DistutilsMetaFinder: - def find_spec(self, fullname, path, target=None): - # optimization: only consider top level modules and those - # found in the CPython test suite. - if path is not None and not fullname.startswith('test.'): - return None - - method_name = 'spec_for_{fullname}'.format(**locals()) - method = getattr(self, method_name, lambda: None) - return method() - - def spec_for_distutils(self): - if self.is_cpython(): - return None - - import importlib - import importlib.abc - import importlib.util - - try: - mod = importlib.import_module('setuptools._distutils') - except Exception: - # There are a couple of cases where setuptools._distutils - # may not be present: - # - An older Setuptools without a local distutils is - # taking precedence. Ref #2957. - # - Path manipulation during sitecustomize removes - # setuptools from the path but only after the hook - # has been loaded. Ref #2980. - # In either case, fall back to stdlib behavior. - return None - - class DistutilsLoader(importlib.abc.Loader): - def create_module(self, spec): - mod.__name__ = 'distutils' - return mod - - def exec_module(self, module): - pass - - return importlib.util.spec_from_loader( - 'distutils', DistutilsLoader(), origin=mod.__file__ - ) - - @staticmethod - def is_cpython(): - """ - Suppress supplying distutils for CPython (build and tests). - Ref #2965 and #3007. - """ - return os.path.isfile('pybuilddir.txt') - - def spec_for_pip(self): - """ - Ensure stdlib distutils when running under pip. - See pypa/pip#8761 for rationale. - """ - if sys.version_info >= (3, 12) or self.pip_imported_during_build(): - return - clear_distutils() - self.spec_for_distutils = lambda: None - - @classmethod - def pip_imported_during_build(cls): - """ - Detect if pip is being imported in a build script. Ref #2355. - """ - import traceback - - return any( - cls.frame_file_is_setup(frame) for frame, line in traceback.walk_stack(None) - ) - - @staticmethod - def frame_file_is_setup(frame): - """ - Return True if the indicated frame suggests a setup.py file. - """ - # some frames may not have __file__ (#2940) - return frame.f_globals.get('__file__', '').endswith('setup.py') - - def spec_for_sensitive_tests(self): - """ - Ensure stdlib distutils when running select tests under CPython. - - python/cpython#91169 - """ - clear_distutils() - self.spec_for_distutils = lambda: None - - sensitive_tests = ( - [ - 'test.test_distutils', - 'test.test_peg_generator', - 'test.test_importlib', - ] - if sys.version_info < (3, 10) - else [ - 'test.test_distutils', - ] - ) - - -for name in DistutilsMetaFinder.sensitive_tests: - setattr( - DistutilsMetaFinder, - f'spec_for_{name}', - DistutilsMetaFinder.spec_for_sensitive_tests, - ) - - -DISTUTILS_FINDER = DistutilsMetaFinder() - - -def add_shim(): - DISTUTILS_FINDER in sys.meta_path or insert_shim() - - -class shim: - def __enter__(self): - insert_shim() - - def __exit__(self, exc, value, tb): - _remove_shim() - - -def insert_shim(): - sys.meta_path.insert(0, DISTUTILS_FINDER) - - -def _remove_shim(): - try: - sys.meta_path.remove(DISTUTILS_FINDER) - except ValueError: - pass - - -if sys.version_info < (3, 12): - # DistutilsMetaFinder can only be disabled in Python < 3.12 (PEP 632) - remove_shim = _remove_shim diff --git a/uno/lib/python/_distutils_hack/override.py b/uno/lib/python/_distutils_hack/override.py deleted file mode 100644 index 2cc433a4..00000000 --- a/uno/lib/python/_distutils_hack/override.py +++ /dev/null @@ -1 +0,0 @@ -__import__('_distutils_hack').do_override() diff --git a/uno/lib/python/attr/__init__.py b/uno/lib/python/attr/__init__.py deleted file mode 100644 index 51b1c255..00000000 --- a/uno/lib/python/attr/__init__.py +++ /dev/null @@ -1,103 +0,0 @@ -# SPDX-License-Identifier: MIT - -""" -Classes Without Boilerplate -""" - -from functools import partial -from typing import Callable - -from . import converters, exceptions, filters, setters, validators -from ._cmp import cmp_using -from ._compat import Protocol -from ._config import get_run_validators, set_run_validators -from ._funcs import asdict, assoc, astuple, evolve, has, resolve_types -from ._make import ( - NOTHING, - Attribute, - Converter, - Factory, - attrib, - attrs, - fields, - fields_dict, - make_class, - validate, -) -from ._next_gen import define, field, frozen, mutable -from ._version_info import VersionInfo - - -s = attributes = attrs -ib = attr = attrib -dataclass = partial(attrs, auto_attribs=True) # happy Easter ;) - - -class AttrsInstance(Protocol): - pass - - -__all__ = [ - "Attribute", - "AttrsInstance", - "Converter", - "Factory", - "NOTHING", - "asdict", - "assoc", - "astuple", - "attr", - "attrib", - "attributes", - "attrs", - "cmp_using", - "converters", - "define", - "evolve", - "exceptions", - "field", - "fields", - "fields_dict", - "filters", - "frozen", - "get_run_validators", - "has", - "ib", - "make_class", - "mutable", - "resolve_types", - "s", - "set_run_validators", - "setters", - "validate", - "validators", -] - - -def _make_getattr(mod_name: str) -> Callable: - """ - Create a metadata proxy for packaging information that uses *mod_name* in - its warnings and errors. - """ - - def __getattr__(name: str) -> str: - if name not in ("__version__", "__version_info__"): - msg = f"module {mod_name} has no attribute {name}" - raise AttributeError(msg) - - try: - from importlib.metadata import metadata - except ImportError: - from importlib_metadata import metadata - - meta = metadata("attrs") - - if name == "__version_info__": - return VersionInfo._from_version_string(meta["version"]) - - return meta["version"] - - return __getattr__ - - -__getattr__ = _make_getattr(__name__) diff --git a/uno/lib/python/attr/__init__.pyi b/uno/lib/python/attr/__init__.pyi deleted file mode 100644 index 6ae0a83d..00000000 --- a/uno/lib/python/attr/__init__.pyi +++ /dev/null @@ -1,388 +0,0 @@ -import enum -import sys - -from typing import ( - Any, - Callable, - Generic, - Mapping, - Protocol, - Sequence, - TypeVar, - overload, -) - -# `import X as X` is required to make these public -from . import converters as converters -from . import exceptions as exceptions -from . import filters as filters -from . import setters as setters -from . import validators as validators -from ._cmp import cmp_using as cmp_using -from ._typing_compat import AttrsInstance_ -from ._version_info import VersionInfo -from attrs import ( - define as define, - field as field, - mutable as mutable, - frozen as frozen, - _EqOrderType, - _ValidatorType, - _ConverterType, - _ReprArgType, - _OnSetAttrType, - _OnSetAttrArgType, - _FieldTransformer, - _ValidatorArgType, -) - -if sys.version_info >= (3, 10): - from typing import TypeGuard -else: - from typing_extensions import TypeGuard - -if sys.version_info >= (3, 11): - from typing import dataclass_transform -else: - from typing_extensions import dataclass_transform - -__version__: str -__version_info__: VersionInfo -__title__: str -__description__: str -__url__: str -__uri__: str -__author__: str -__email__: str -__license__: str -__copyright__: str - -_T = TypeVar("_T") -_C = TypeVar("_C", bound=type) - -_FilterType = Callable[["Attribute[_T]", _T], bool] - -# We subclass this here to keep the protocol's qualified name clean. -class AttrsInstance(AttrsInstance_, Protocol): - pass - -_A = TypeVar("_A", bound=type[AttrsInstance]) - -class _Nothing(enum.Enum): - NOTHING = enum.auto() - -NOTHING = _Nothing.NOTHING - -# NOTE: Factory lies about its return type to make this possible: -# `x: List[int] # = Factory(list)` -# Work around mypy issue #4554 in the common case by using an overload. -if sys.version_info >= (3, 8): - from typing import Literal - @overload - def Factory(factory: Callable[[], _T]) -> _T: ... - @overload - def Factory( - factory: Callable[[Any], _T], - takes_self: Literal[True], - ) -> _T: ... - @overload - def Factory( - factory: Callable[[], _T], - takes_self: Literal[False], - ) -> _T: ... - -else: - @overload - def Factory(factory: Callable[[], _T]) -> _T: ... - @overload - def Factory( - factory: Union[Callable[[Any], _T], Callable[[], _T]], - takes_self: bool = ..., - ) -> _T: ... - -In = TypeVar("In") -Out = TypeVar("Out") - -class Converter(Generic[In, Out]): - @overload - def __init__(self, converter: Callable[[In], Out]) -> None: ... - @overload - def __init__( - self, - converter: Callable[[In, AttrsInstance, Attribute], Out], - *, - takes_self: Literal[True], - takes_field: Literal[True], - ) -> None: ... - @overload - def __init__( - self, - converter: Callable[[In, Attribute], Out], - *, - takes_field: Literal[True], - ) -> None: ... - @overload - def __init__( - self, - converter: Callable[[In, AttrsInstance], Out], - *, - takes_self: Literal[True], - ) -> None: ... - -class Attribute(Generic[_T]): - name: str - default: _T | None - validator: _ValidatorType[_T] | None - repr: _ReprArgType - cmp: _EqOrderType - eq: _EqOrderType - order: _EqOrderType - hash: bool | None - init: bool - converter: _ConverterType | Converter[Any, _T] | None - metadata: dict[Any, Any] - type: type[_T] | None - kw_only: bool - on_setattr: _OnSetAttrType - alias: str | None - - def evolve(self, **changes: Any) -> "Attribute[Any]": ... - -# NOTE: We had several choices for the annotation to use for type arg: -# 1) Type[_T] -# - Pros: Handles simple cases correctly -# - Cons: Might produce less informative errors in the case of conflicting -# TypeVars e.g. `attr.ib(default='bad', type=int)` -# 2) Callable[..., _T] -# - Pros: Better error messages than #1 for conflicting TypeVars -# - Cons: Terrible error messages for validator checks. -# e.g. attr.ib(type=int, validator=validate_str) -# -> error: Cannot infer function type argument -# 3) type (and do all of the work in the mypy plugin) -# - Pros: Simple here, and we could customize the plugin with our own errors. -# - Cons: Would need to write mypy plugin code to handle all the cases. -# We chose option #1. - -# `attr` lies about its return type to make the following possible: -# attr() -> Any -# attr(8) -> int -# attr(validator=) -> Whatever the callable expects. -# This makes this type of assignments possible: -# x: int = attr(8) -# -# This form catches explicit None or no default but with no other arguments -# returns Any. -@overload -def attrib( - default: None = ..., - validator: None = ..., - repr: _ReprArgType = ..., - cmp: _EqOrderType | None = ..., - hash: bool | None = ..., - init: bool = ..., - metadata: Mapping[Any, Any] | None = ..., - type: None = ..., - converter: None = ..., - factory: None = ..., - kw_only: bool = ..., - eq: _EqOrderType | None = ..., - order: _EqOrderType | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - alias: str | None = ..., -) -> Any: ... - -# This form catches an explicit None or no default and infers the type from the -# other arguments. -@overload -def attrib( - default: None = ..., - validator: _ValidatorArgType[_T] | None = ..., - repr: _ReprArgType = ..., - cmp: _EqOrderType | None = ..., - hash: bool | None = ..., - init: bool = ..., - metadata: Mapping[Any, Any] | None = ..., - type: type[_T] | None = ..., - converter: _ConverterType | Converter[Any, _T] | None = ..., - factory: Callable[[], _T] | None = ..., - kw_only: bool = ..., - eq: _EqOrderType | None = ..., - order: _EqOrderType | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - alias: str | None = ..., -) -> _T: ... - -# This form catches an explicit default argument. -@overload -def attrib( - default: _T, - validator: _ValidatorArgType[_T] | None = ..., - repr: _ReprArgType = ..., - cmp: _EqOrderType | None = ..., - hash: bool | None = ..., - init: bool = ..., - metadata: Mapping[Any, Any] | None = ..., - type: type[_T] | None = ..., - converter: _ConverterType | Converter[Any, _T] | None = ..., - factory: Callable[[], _T] | None = ..., - kw_only: bool = ..., - eq: _EqOrderType | None = ..., - order: _EqOrderType | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - alias: str | None = ..., -) -> _T: ... - -# This form covers type=non-Type: e.g. forward references (str), Any -@overload -def attrib( - default: _T | None = ..., - validator: _ValidatorArgType[_T] | None = ..., - repr: _ReprArgType = ..., - cmp: _EqOrderType | None = ..., - hash: bool | None = ..., - init: bool = ..., - metadata: Mapping[Any, Any] | None = ..., - type: object = ..., - converter: _ConverterType | Converter[Any, _T] | None = ..., - factory: Callable[[], _T] | None = ..., - kw_only: bool = ..., - eq: _EqOrderType | None = ..., - order: _EqOrderType | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - alias: str | None = ..., -) -> Any: ... -@overload -@dataclass_transform(order_default=True, field_specifiers=(attrib, field)) -def attrs( - maybe_cls: _C, - these: dict[str, Any] | None = ..., - repr_ns: str | None = ..., - repr: bool = ..., - cmp: _EqOrderType | None = ..., - hash: bool | None = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: _EqOrderType | None = ..., - order: _EqOrderType | None = ..., - auto_detect: bool = ..., - collect_by_mro: bool = ..., - getstate_setstate: bool | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - field_transformer: _FieldTransformer | None = ..., - match_args: bool = ..., - unsafe_hash: bool | None = ..., -) -> _C: ... -@overload -@dataclass_transform(order_default=True, field_specifiers=(attrib, field)) -def attrs( - maybe_cls: None = ..., - these: dict[str, Any] | None = ..., - repr_ns: str | None = ..., - repr: bool = ..., - cmp: _EqOrderType | None = ..., - hash: bool | None = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: _EqOrderType | None = ..., - order: _EqOrderType | None = ..., - auto_detect: bool = ..., - collect_by_mro: bool = ..., - getstate_setstate: bool | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - field_transformer: _FieldTransformer | None = ..., - match_args: bool = ..., - unsafe_hash: bool | None = ..., -) -> Callable[[_C], _C]: ... -def fields(cls: type[AttrsInstance]) -> Any: ... -def fields_dict(cls: type[AttrsInstance]) -> dict[str, Attribute[Any]]: ... -def validate(inst: AttrsInstance) -> None: ... -def resolve_types( - cls: _A, - globalns: dict[str, Any] | None = ..., - localns: dict[str, Any] | None = ..., - attribs: list[Attribute[Any]] | None = ..., - include_extras: bool = ..., -) -> _A: ... - -# TODO: add support for returning a proper attrs class from the mypy plugin -# we use Any instead of _CountingAttr so that e.g. `make_class('Foo', -# [attr.ib()])` is valid -def make_class( - name: str, - attrs: list[str] | tuple[str, ...] | dict[str, Any], - bases: tuple[type, ...] = ..., - class_body: dict[str, Any] | None = ..., - repr_ns: str | None = ..., - repr: bool = ..., - cmp: _EqOrderType | None = ..., - hash: bool | None = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: _EqOrderType | None = ..., - order: _EqOrderType | None = ..., - collect_by_mro: bool = ..., - on_setattr: _OnSetAttrArgType | None = ..., - field_transformer: _FieldTransformer | None = ..., -) -> type: ... - -# _funcs -- - -# TODO: add support for returning TypedDict from the mypy plugin -# FIXME: asdict/astuple do not honor their factory args. Waiting on one of -# these: -# https://github.com/python/mypy/issues/4236 -# https://github.com/python/typing/issues/253 -# XXX: remember to fix attrs.asdict/astuple too! -def asdict( - inst: AttrsInstance, - recurse: bool = ..., - filter: _FilterType[Any] | None = ..., - dict_factory: type[Mapping[Any, Any]] = ..., - retain_collection_types: bool = ..., - value_serializer: Callable[[type, Attribute[Any], Any], Any] | None = ..., - tuple_keys: bool | None = ..., -) -> dict[str, Any]: ... - -# TODO: add support for returning NamedTuple from the mypy plugin -def astuple( - inst: AttrsInstance, - recurse: bool = ..., - filter: _FilterType[Any] | None = ..., - tuple_factory: type[Sequence[Any]] = ..., - retain_collection_types: bool = ..., -) -> tuple[Any, ...]: ... -def has(cls: type) -> TypeGuard[type[AttrsInstance]]: ... -def assoc(inst: _T, **changes: Any) -> _T: ... -def evolve(inst: _T, **changes: Any) -> _T: ... - -# _config -- - -def set_run_validators(run: bool) -> None: ... -def get_run_validators() -> bool: ... - -# aliases -- - -s = attributes = attrs -ib = attr = attrib -dataclass = attrs # Technically, partial(attrs, auto_attribs=True) ;) diff --git a/uno/lib/python/attr/_cmp.py b/uno/lib/python/attr/_cmp.py deleted file mode 100644 index f367bb3a..00000000 --- a/uno/lib/python/attr/_cmp.py +++ /dev/null @@ -1,160 +0,0 @@ -# SPDX-License-Identifier: MIT - - -import functools -import types - -from ._make import _make_ne - - -_operation_names = {"eq": "==", "lt": "<", "le": "<=", "gt": ">", "ge": ">="} - - -def cmp_using( - eq=None, - lt=None, - le=None, - gt=None, - ge=None, - require_same_type=True, - class_name="Comparable", -): - """ - Create a class that can be passed into `attrs.field`'s ``eq``, ``order``, - and ``cmp`` arguments to customize field comparison. - - The resulting class will have a full set of ordering methods if at least - one of ``{lt, le, gt, ge}`` and ``eq`` are provided. - - Args: - eq (typing.Callable | None): - Callable used to evaluate equality of two objects. - - lt (typing.Callable | None): - Callable used to evaluate whether one object is less than another - object. - - le (typing.Callable | None): - Callable used to evaluate whether one object is less than or equal - to another object. - - gt (typing.Callable | None): - Callable used to evaluate whether one object is greater than - another object. - - ge (typing.Callable | None): - Callable used to evaluate whether one object is greater than or - equal to another object. - - require_same_type (bool): - When `True`, equality and ordering methods will return - `NotImplemented` if objects are not of the same type. - - class_name (str | None): Name of class. Defaults to "Comparable". - - See `comparison` for more details. - - .. versionadded:: 21.1.0 - """ - - body = { - "__slots__": ["value"], - "__init__": _make_init(), - "_requirements": [], - "_is_comparable_to": _is_comparable_to, - } - - # Add operations. - num_order_functions = 0 - has_eq_function = False - - if eq is not None: - has_eq_function = True - body["__eq__"] = _make_operator("eq", eq) - body["__ne__"] = _make_ne() - - if lt is not None: - num_order_functions += 1 - body["__lt__"] = _make_operator("lt", lt) - - if le is not None: - num_order_functions += 1 - body["__le__"] = _make_operator("le", le) - - if gt is not None: - num_order_functions += 1 - body["__gt__"] = _make_operator("gt", gt) - - if ge is not None: - num_order_functions += 1 - body["__ge__"] = _make_operator("ge", ge) - - type_ = types.new_class( - class_name, (object,), {}, lambda ns: ns.update(body) - ) - - # Add same type requirement. - if require_same_type: - type_._requirements.append(_check_same_type) - - # Add total ordering if at least one operation was defined. - if 0 < num_order_functions < 4: - if not has_eq_function: - # functools.total_ordering requires __eq__ to be defined, - # so raise early error here to keep a nice stack. - msg = "eq must be define is order to complete ordering from lt, le, gt, ge." - raise ValueError(msg) - type_ = functools.total_ordering(type_) - - return type_ - - -def _make_init(): - """ - Create __init__ method. - """ - - def __init__(self, value): - """ - Initialize object with *value*. - """ - self.value = value - - return __init__ - - -def _make_operator(name, func): - """ - Create operator method. - """ - - def method(self, other): - if not self._is_comparable_to(other): - return NotImplemented - - result = func(self.value, other.value) - if result is NotImplemented: - return NotImplemented - - return result - - method.__name__ = f"__{name}__" - method.__doc__ = ( - f"Return a {_operation_names[name]} b. Computed by attrs." - ) - - return method - - -def _is_comparable_to(self, other): - """ - Check whether `other` is comparable to `self`. - """ - return all(func(self, other) for func in self._requirements) - - -def _check_same_type(self, other): - """ - Return True if *self* and *other* are of the same type, False otherwise. - """ - return other.value.__class__ is self.value.__class__ diff --git a/uno/lib/python/attr/_cmp.pyi b/uno/lib/python/attr/_cmp.pyi deleted file mode 100644 index cc7893b0..00000000 --- a/uno/lib/python/attr/_cmp.pyi +++ /dev/null @@ -1,13 +0,0 @@ -from typing import Any, Callable - -_CompareWithType = Callable[[Any, Any], bool] - -def cmp_using( - eq: _CompareWithType | None = ..., - lt: _CompareWithType | None = ..., - le: _CompareWithType | None = ..., - gt: _CompareWithType | None = ..., - ge: _CompareWithType | None = ..., - require_same_type: bool = ..., - class_name: str = ..., -) -> type: ... diff --git a/uno/lib/python/attr/_compat.py b/uno/lib/python/attr/_compat.py deleted file mode 100644 index 104eeb07..00000000 --- a/uno/lib/python/attr/_compat.py +++ /dev/null @@ -1,103 +0,0 @@ -# SPDX-License-Identifier: MIT - -import inspect -import platform -import sys -import threading - -from collections.abc import Mapping, Sequence # noqa: F401 -from typing import _GenericAlias - - -PYPY = platform.python_implementation() == "PyPy" -PY_3_8_PLUS = sys.version_info[:2] >= (3, 8) -PY_3_9_PLUS = sys.version_info[:2] >= (3, 9) -PY_3_10_PLUS = sys.version_info[:2] >= (3, 10) -PY_3_11_PLUS = sys.version_info[:2] >= (3, 11) -PY_3_12_PLUS = sys.version_info[:2] >= (3, 12) -PY_3_13_PLUS = sys.version_info[:2] >= (3, 13) -PY_3_14_PLUS = sys.version_info[:2] >= (3, 14) - - -if sys.version_info < (3, 8): - try: - from typing_extensions import Protocol - except ImportError: # pragma: no cover - Protocol = object -else: - from typing import Protocol # noqa: F401 - -if PY_3_14_PLUS: # pragma: no cover - import annotationlib - - _get_annotations = annotationlib.get_annotations - -else: - - def _get_annotations(cls): - """ - Get annotations for *cls*. - """ - return cls.__dict__.get("__annotations__", {}) - - -class _AnnotationExtractor: - """ - Extract type annotations from a callable, returning None whenever there - is none. - """ - - __slots__ = ["sig"] - - def __init__(self, callable): - try: - self.sig = inspect.signature(callable) - except (ValueError, TypeError): # inspect failed - self.sig = None - - def get_first_param_type(self): - """ - Return the type annotation of the first argument if it's not empty. - """ - if not self.sig: - return None - - params = list(self.sig.parameters.values()) - if params and params[0].annotation is not inspect.Parameter.empty: - return params[0].annotation - - return None - - def get_return_type(self): - """ - Return the return type if it's not empty. - """ - if ( - self.sig - and self.sig.return_annotation is not inspect.Signature.empty - ): - return self.sig.return_annotation - - return None - - -# Thread-local global to track attrs instances which are already being repr'd. -# This is needed because there is no other (thread-safe) way to pass info -# about the instances that are already being repr'd through the call stack -# in order to ensure we don't perform infinite recursion. -# -# For instance, if an instance contains a dict which contains that instance, -# we need to know that we're already repr'ing the outside instance from within -# the dict's repr() call. -# -# This lives here rather than in _make.py so that the functions in _make.py -# don't have a direct reference to the thread-local in their globals dict. -# If they have such a reference, it breaks cloudpickle. -repr_context = threading.local() - - -def get_generic_base(cl): - """If this is a generic class (A[str]), return the generic base for it.""" - if cl.__class__ is _GenericAlias: - return cl.__origin__ - return None diff --git a/uno/lib/python/attr/_config.py b/uno/lib/python/attr/_config.py deleted file mode 100644 index 9c245b14..00000000 --- a/uno/lib/python/attr/_config.py +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-License-Identifier: MIT - -__all__ = ["set_run_validators", "get_run_validators"] - -_run_validators = True - - -def set_run_validators(run): - """ - Set whether or not validators are run. By default, they are run. - - .. deprecated:: 21.3.0 It will not be removed, but it also will not be - moved to new ``attrs`` namespace. Use `attrs.validators.set_disabled()` - instead. - """ - if not isinstance(run, bool): - msg = "'run' must be bool." - raise TypeError(msg) - global _run_validators - _run_validators = run - - -def get_run_validators(): - """ - Return whether or not validators are run. - - .. deprecated:: 21.3.0 It will not be removed, but it also will not be - moved to new ``attrs`` namespace. Use `attrs.validators.get_disabled()` - instead. - """ - return _run_validators diff --git a/uno/lib/python/attr/_funcs.py b/uno/lib/python/attr/_funcs.py deleted file mode 100644 index 355cef44..00000000 --- a/uno/lib/python/attr/_funcs.py +++ /dev/null @@ -1,522 +0,0 @@ -# SPDX-License-Identifier: MIT - - -import copy - -from ._compat import PY_3_9_PLUS, get_generic_base -from ._make import _OBJ_SETATTR, NOTHING, fields -from .exceptions import AttrsAttributeNotFoundError - - -def asdict( - inst, - recurse=True, - filter=None, - dict_factory=dict, - retain_collection_types=False, - value_serializer=None, -): - """ - Return the *attrs* attribute values of *inst* as a dict. - - Optionally recurse into other *attrs*-decorated classes. - - Args: - inst: Instance of an *attrs*-decorated class. - - recurse (bool): Recurse into classes that are also *attrs*-decorated. - - filter (~typing.Callable): - A callable whose return code determines whether an attribute or - element is included (`True`) or dropped (`False`). Is called with - the `attrs.Attribute` as the first argument and the value as the - second argument. - - dict_factory (~typing.Callable): - A callable to produce dictionaries from. For example, to produce - ordered dictionaries instead of normal Python dictionaries, pass in - ``collections.OrderedDict``. - - retain_collection_types (bool): - Do not convert to `list` when encountering an attribute whose type - is `tuple` or `set`. Only meaningful if *recurse* is `True`. - - value_serializer (typing.Callable | None): - A hook that is called for every attribute or dict key/value. It - receives the current instance, field and value and must return the - (updated) value. The hook is run *after* the optional *filter* has - been applied. - - Returns: - Return type of *dict_factory*. - - Raises: - attrs.exceptions.NotAnAttrsClassError: - If *cls* is not an *attrs* class. - - .. versionadded:: 16.0.0 *dict_factory* - .. versionadded:: 16.1.0 *retain_collection_types* - .. versionadded:: 20.3.0 *value_serializer* - .. versionadded:: 21.3.0 - If a dict has a collection for a key, it is serialized as a tuple. - """ - attrs = fields(inst.__class__) - rv = dict_factory() - for a in attrs: - v = getattr(inst, a.name) - if filter is not None and not filter(a, v): - continue - - if value_serializer is not None: - v = value_serializer(inst, a, v) - - if recurse is True: - if has(v.__class__): - rv[a.name] = asdict( - v, - recurse=True, - filter=filter, - dict_factory=dict_factory, - retain_collection_types=retain_collection_types, - value_serializer=value_serializer, - ) - elif isinstance(v, (tuple, list, set, frozenset)): - cf = v.__class__ if retain_collection_types is True else list - items = [ - _asdict_anything( - i, - is_key=False, - filter=filter, - dict_factory=dict_factory, - retain_collection_types=retain_collection_types, - value_serializer=value_serializer, - ) - for i in v - ] - try: - rv[a.name] = cf(items) - except TypeError: - if not issubclass(cf, tuple): - raise - # Workaround for TypeError: cf.__new__() missing 1 required - # positional argument (which appears, for a namedturle) - rv[a.name] = cf(*items) - elif isinstance(v, dict): - df = dict_factory - rv[a.name] = df( - ( - _asdict_anything( - kk, - is_key=True, - filter=filter, - dict_factory=df, - retain_collection_types=retain_collection_types, - value_serializer=value_serializer, - ), - _asdict_anything( - vv, - is_key=False, - filter=filter, - dict_factory=df, - retain_collection_types=retain_collection_types, - value_serializer=value_serializer, - ), - ) - for kk, vv in v.items() - ) - else: - rv[a.name] = v - else: - rv[a.name] = v - return rv - - -def _asdict_anything( - val, - is_key, - filter, - dict_factory, - retain_collection_types, - value_serializer, -): - """ - ``asdict`` only works on attrs instances, this works on anything. - """ - if getattr(val.__class__, "__attrs_attrs__", None) is not None: - # Attrs class. - rv = asdict( - val, - recurse=True, - filter=filter, - dict_factory=dict_factory, - retain_collection_types=retain_collection_types, - value_serializer=value_serializer, - ) - elif isinstance(val, (tuple, list, set, frozenset)): - if retain_collection_types is True: - cf = val.__class__ - elif is_key: - cf = tuple - else: - cf = list - - rv = cf( - [ - _asdict_anything( - i, - is_key=False, - filter=filter, - dict_factory=dict_factory, - retain_collection_types=retain_collection_types, - value_serializer=value_serializer, - ) - for i in val - ] - ) - elif isinstance(val, dict): - df = dict_factory - rv = df( - ( - _asdict_anything( - kk, - is_key=True, - filter=filter, - dict_factory=df, - retain_collection_types=retain_collection_types, - value_serializer=value_serializer, - ), - _asdict_anything( - vv, - is_key=False, - filter=filter, - dict_factory=df, - retain_collection_types=retain_collection_types, - value_serializer=value_serializer, - ), - ) - for kk, vv in val.items() - ) - else: - rv = val - if value_serializer is not None: - rv = value_serializer(None, None, rv) - - return rv - - -def astuple( - inst, - recurse=True, - filter=None, - tuple_factory=tuple, - retain_collection_types=False, -): - """ - Return the *attrs* attribute values of *inst* as a tuple. - - Optionally recurse into other *attrs*-decorated classes. - - Args: - inst: Instance of an *attrs*-decorated class. - - recurse (bool): - Recurse into classes that are also *attrs*-decorated. - - filter (~typing.Callable): - A callable whose return code determines whether an attribute or - element is included (`True`) or dropped (`False`). Is called with - the `attrs.Attribute` as the first argument and the value as the - second argument. - - tuple_factory (~typing.Callable): - A callable to produce tuples from. For example, to produce lists - instead of tuples. - - retain_collection_types (bool): - Do not convert to `list` or `dict` when encountering an attribute - which type is `tuple`, `dict` or `set`. Only meaningful if - *recurse* is `True`. - - Returns: - Return type of *tuple_factory* - - Raises: - attrs.exceptions.NotAnAttrsClassError: - If *cls* is not an *attrs* class. - - .. versionadded:: 16.2.0 - """ - attrs = fields(inst.__class__) - rv = [] - retain = retain_collection_types # Very long. :/ - for a in attrs: - v = getattr(inst, a.name) - if filter is not None and not filter(a, v): - continue - if recurse is True: - if has(v.__class__): - rv.append( - astuple( - v, - recurse=True, - filter=filter, - tuple_factory=tuple_factory, - retain_collection_types=retain, - ) - ) - elif isinstance(v, (tuple, list, set, frozenset)): - cf = v.__class__ if retain is True else list - items = [ - ( - astuple( - j, - recurse=True, - filter=filter, - tuple_factory=tuple_factory, - retain_collection_types=retain, - ) - if has(j.__class__) - else j - ) - for j in v - ] - try: - rv.append(cf(items)) - except TypeError: - if not issubclass(cf, tuple): - raise - # Workaround for TypeError: cf.__new__() missing 1 required - # positional argument (which appears, for a namedturle) - rv.append(cf(*items)) - elif isinstance(v, dict): - df = v.__class__ if retain is True else dict - rv.append( - df( - ( - ( - astuple( - kk, - tuple_factory=tuple_factory, - retain_collection_types=retain, - ) - if has(kk.__class__) - else kk - ), - ( - astuple( - vv, - tuple_factory=tuple_factory, - retain_collection_types=retain, - ) - if has(vv.__class__) - else vv - ), - ) - for kk, vv in v.items() - ) - ) - else: - rv.append(v) - else: - rv.append(v) - - return rv if tuple_factory is list else tuple_factory(rv) - - -def has(cls): - """ - Check whether *cls* is a class with *attrs* attributes. - - Args: - cls (type): Class to introspect. - - Raises: - TypeError: If *cls* is not a class. - - Returns: - bool: - """ - attrs = getattr(cls, "__attrs_attrs__", None) - if attrs is not None: - return True - - # No attrs, maybe it's a specialized generic (A[str])? - generic_base = get_generic_base(cls) - if generic_base is not None: - generic_attrs = getattr(generic_base, "__attrs_attrs__", None) - if generic_attrs is not None: - # Stick it on here for speed next time. - cls.__attrs_attrs__ = generic_attrs - return generic_attrs is not None - return False - - -def assoc(inst, **changes): - """ - Copy *inst* and apply *changes*. - - This is different from `evolve` that applies the changes to the arguments - that create the new instance. - - `evolve`'s behavior is preferable, but there are `edge cases`_ where it - doesn't work. Therefore `assoc` is deprecated, but will not be removed. - - .. _`edge cases`: https://github.com/python-attrs/attrs/issues/251 - - Args: - inst: Instance of a class with *attrs* attributes. - - changes: Keyword changes in the new copy. - - Returns: - A copy of inst with *changes* incorporated. - - Raises: - attrs.exceptions.AttrsAttributeNotFoundError: - If *attr_name* couldn't be found on *cls*. - - attrs.exceptions.NotAnAttrsClassError: - If *cls* is not an *attrs* class. - - .. deprecated:: 17.1.0 - Use `attrs.evolve` instead if you can. This function will not be - removed du to the slightly different approach compared to - `attrs.evolve`, though. - """ - new = copy.copy(inst) - attrs = fields(inst.__class__) - for k, v in changes.items(): - a = getattr(attrs, k, NOTHING) - if a is NOTHING: - msg = f"{k} is not an attrs attribute on {new.__class__}." - raise AttrsAttributeNotFoundError(msg) - _OBJ_SETATTR(new, k, v) - return new - - -def evolve(*args, **changes): - """ - Create a new instance, based on the first positional argument with - *changes* applied. - - Args: - - inst: - Instance of a class with *attrs* attributes. *inst* must be passed - as a positional argument. - - changes: - Keyword changes in the new copy. - - Returns: - A copy of inst with *changes* incorporated. - - Raises: - TypeError: - If *attr_name* couldn't be found in the class ``__init__``. - - attrs.exceptions.NotAnAttrsClassError: - If *cls* is not an *attrs* class. - - .. versionadded:: 17.1.0 - .. deprecated:: 23.1.0 - It is now deprecated to pass the instance using the keyword argument - *inst*. It will raise a warning until at least April 2024, after which - it will become an error. Always pass the instance as a positional - argument. - .. versionchanged:: 24.1.0 - *inst* can't be passed as a keyword argument anymore. - """ - try: - (inst,) = args - except ValueError: - msg = ( - f"evolve() takes 1 positional argument, but {len(args)} were given" - ) - raise TypeError(msg) from None - - cls = inst.__class__ - attrs = fields(cls) - for a in attrs: - if not a.init: - continue - attr_name = a.name # To deal with private attributes. - init_name = a.alias - if init_name not in changes: - changes[init_name] = getattr(inst, attr_name) - - return cls(**changes) - - -def resolve_types( - cls, globalns=None, localns=None, attribs=None, include_extras=True -): - """ - Resolve any strings and forward annotations in type annotations. - - This is only required if you need concrete types in :class:`Attribute`'s - *type* field. In other words, you don't need to resolve your types if you - only use them for static type checking. - - With no arguments, names will be looked up in the module in which the class - was created. If this is not what you want, for example, if the name only - exists inside a method, you may pass *globalns* or *localns* to specify - other dictionaries in which to look up these names. See the docs of - `typing.get_type_hints` for more details. - - Args: - cls (type): Class to resolve. - - globalns (dict | None): Dictionary containing global variables. - - localns (dict | None): Dictionary containing local variables. - - attribs (list | None): - List of attribs for the given class. This is necessary when calling - from inside a ``field_transformer`` since *cls* is not an *attrs* - class yet. - - include_extras (bool): - Resolve more accurately, if possible. Pass ``include_extras`` to - ``typing.get_hints``, if supported by the typing module. On - supported Python versions (3.9+), this resolves the types more - accurately. - - Raises: - TypeError: If *cls* is not a class. - - attrs.exceptions.NotAnAttrsClassError: - If *cls* is not an *attrs* class and you didn't pass any attribs. - - NameError: If types cannot be resolved because of missing variables. - - Returns: - *cls* so you can use this function also as a class decorator. Please - note that you have to apply it **after** `attrs.define`. That means the - decorator has to come in the line **before** `attrs.define`. - - .. versionadded:: 20.1.0 - .. versionadded:: 21.1.0 *attribs* - .. versionadded:: 23.1.0 *include_extras* - """ - # Since calling get_type_hints is expensive we cache whether we've - # done it already. - if getattr(cls, "__attrs_types_resolved__", None) != cls: - import typing - - kwargs = {"globalns": globalns, "localns": localns} - - if PY_3_9_PLUS: - kwargs["include_extras"] = include_extras - - hints = typing.get_type_hints(cls, **kwargs) - for field in fields(cls) if attribs is None else attribs: - if field.name in hints: - # Since fields have been frozen we must work around it. - _OBJ_SETATTR(field, "type", hints[field.name]) - # We store the class we resolved so that subclasses know they haven't - # been resolved. - cls.__attrs_types_resolved__ = cls - - # Return the class so you can use it as a decorator too. - return cls diff --git a/uno/lib/python/attr/_make.py b/uno/lib/python/attr/_make.py deleted file mode 100644 index bf00c5f8..00000000 --- a/uno/lib/python/attr/_make.py +++ /dev/null @@ -1,2960 +0,0 @@ -# SPDX-License-Identifier: MIT - -from __future__ import annotations - -import abc -import contextlib -import copy -import enum -import functools -import inspect -import itertools -import linecache -import sys -import types -import typing - -from operator import itemgetter - -# We need to import _compat itself in addition to the _compat members to avoid -# having the thread-local in the globals here. -from . import _compat, _config, setters -from ._compat import ( - PY_3_8_PLUS, - PY_3_10_PLUS, - PY_3_11_PLUS, - _AnnotationExtractor, - _get_annotations, - get_generic_base, -) -from .exceptions import ( - DefaultAlreadySetError, - FrozenInstanceError, - NotAnAttrsClassError, - UnannotatedAttributeError, -) - - -# This is used at least twice, so cache it here. -_OBJ_SETATTR = object.__setattr__ -_INIT_FACTORY_PAT = "__attr_factory_%s" -_CLASSVAR_PREFIXES = ( - "typing.ClassVar", - "t.ClassVar", - "ClassVar", - "typing_extensions.ClassVar", -) -# we don't use a double-underscore prefix because that triggers -# name mangling when trying to create a slot for the field -# (when slots=True) -_HASH_CACHE_FIELD = "_attrs_cached_hash" - -_EMPTY_METADATA_SINGLETON = types.MappingProxyType({}) - -# Unique object for unequivocal getattr() defaults. -_SENTINEL = object() - -_DEFAULT_ON_SETATTR = setters.pipe(setters.convert, setters.validate) - - -class _Nothing(enum.Enum): - """ - Sentinel to indicate the lack of a value when `None` is ambiguous. - - If extending attrs, you can use ``typing.Literal[NOTHING]`` to show - that a value may be ``NOTHING``. - - .. versionchanged:: 21.1.0 ``bool(NOTHING)`` is now False. - .. versionchanged:: 22.2.0 ``NOTHING`` is now an ``enum.Enum`` variant. - """ - - NOTHING = enum.auto() - - def __repr__(self): - return "NOTHING" - - def __bool__(self): - return False - - -NOTHING = _Nothing.NOTHING -""" -Sentinel to indicate the lack of a value when `None` is ambiguous. -""" - - -class _CacheHashWrapper(int): - """ - An integer subclass that pickles / copies as None - - This is used for non-slots classes with ``cache_hash=True``, to avoid - serializing a potentially (even likely) invalid hash value. Since `None` - is the default value for uncalculated hashes, whenever this is copied, - the copy's value for the hash should automatically reset. - - See GH #613 for more details. - """ - - def __reduce__(self, _none_constructor=type(None), _args=()): # noqa: B008 - return _none_constructor, _args - - -def attrib( - default=NOTHING, - validator=None, - repr=True, - cmp=None, - hash=None, - init=True, - metadata=None, - type=None, - converter=None, - factory=None, - kw_only=False, - eq=None, - order=None, - on_setattr=None, - alias=None, -): - """ - Create a new field / attribute on a class. - - Identical to `attrs.field`, except it's not keyword-only. - - Consider using `attrs.field` in new code (``attr.ib`` will *never* go away, - though). - - .. warning:: - - Does **nothing** unless the class is also decorated with - `attr.s` (or similar)! - - - .. versionadded:: 15.2.0 *convert* - .. versionadded:: 16.3.0 *metadata* - .. versionchanged:: 17.1.0 *validator* can be a ``list`` now. - .. versionchanged:: 17.1.0 - *hash* is `None` and therefore mirrors *eq* by default. - .. versionadded:: 17.3.0 *type* - .. deprecated:: 17.4.0 *convert* - .. versionadded:: 17.4.0 - *converter* as a replacement for the deprecated *convert* to achieve - consistency with other noun-based arguments. - .. versionadded:: 18.1.0 - ``factory=f`` is syntactic sugar for ``default=attr.Factory(f)``. - .. versionadded:: 18.2.0 *kw_only* - .. versionchanged:: 19.2.0 *convert* keyword argument removed. - .. versionchanged:: 19.2.0 *repr* also accepts a custom callable. - .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. - .. versionadded:: 19.2.0 *eq* and *order* - .. versionadded:: 20.1.0 *on_setattr* - .. versionchanged:: 20.3.0 *kw_only* backported to Python 2 - .. versionchanged:: 21.1.0 - *eq*, *order*, and *cmp* also accept a custom callable - .. versionchanged:: 21.1.0 *cmp* undeprecated - .. versionadded:: 22.2.0 *alias* - """ - eq, eq_key, order, order_key = _determine_attrib_eq_order( - cmp, eq, order, True - ) - - if hash is not None and hash is not True and hash is not False: - msg = "Invalid value for hash. Must be True, False, or None." - raise TypeError(msg) - - if factory is not None: - if default is not NOTHING: - msg = ( - "The `default` and `factory` arguments are mutually exclusive." - ) - raise ValueError(msg) - if not callable(factory): - msg = "The `factory` argument must be a callable." - raise ValueError(msg) - default = Factory(factory) - - if metadata is None: - metadata = {} - - # Apply syntactic sugar by auto-wrapping. - if isinstance(on_setattr, (list, tuple)): - on_setattr = setters.pipe(*on_setattr) - - if validator and isinstance(validator, (list, tuple)): - validator = and_(*validator) - - if converter and isinstance(converter, (list, tuple)): - converter = pipe(*converter) - - return _CountingAttr( - default=default, - validator=validator, - repr=repr, - cmp=None, - hash=hash, - init=init, - converter=converter, - metadata=metadata, - type=type, - kw_only=kw_only, - eq=eq, - eq_key=eq_key, - order=order, - order_key=order_key, - on_setattr=on_setattr, - alias=alias, - ) - - -def _compile_and_eval(script, globs, locs=None, filename=""): - """ - Evaluate the script with the given global (globs) and local (locs) - variables. - """ - bytecode = compile(script, filename, "exec") - eval(bytecode, globs, locs) - - -def _make_method(name, script, filename, globs, locals=None): - """ - Create the method with the script given and return the method object. - """ - locs = {} if locals is None else locals - - # In order of debuggers like PDB being able to step through the code, - # we add a fake linecache entry. - count = 1 - base_filename = filename - while True: - linecache_tuple = ( - len(script), - None, - script.splitlines(True), - filename, - ) - old_val = linecache.cache.setdefault(filename, linecache_tuple) - if old_val == linecache_tuple: - break - - filename = f"{base_filename[:-1]}-{count}>" - count += 1 - - _compile_and_eval(script, globs, locs, filename) - - return locs[name] - - -def _make_attr_tuple_class(cls_name, attr_names): - """ - Create a tuple subclass to hold `Attribute`s for an `attrs` class. - - The subclass is a bare tuple with properties for names. - - class MyClassAttributes(tuple): - __slots__ = () - x = property(itemgetter(0)) - """ - attr_class_name = f"{cls_name}Attributes" - attr_class_template = [ - f"class {attr_class_name}(tuple):", - " __slots__ = ()", - ] - if attr_names: - for i, attr_name in enumerate(attr_names): - attr_class_template.append( - f" {attr_name} = _attrs_property(_attrs_itemgetter({i}))" - ) - else: - attr_class_template.append(" pass") - globs = {"_attrs_itemgetter": itemgetter, "_attrs_property": property} - _compile_and_eval("\n".join(attr_class_template), globs) - return globs[attr_class_name] - - -# Tuple class for extracted attributes from a class definition. -# `base_attrs` is a subset of `attrs`. -_Attributes = _make_attr_tuple_class( - "_Attributes", - [ - # all attributes to build dunder methods for - "attrs", - # attributes that have been inherited - "base_attrs", - # map inherited attributes to their originating classes - "base_attrs_map", - ], -) - - -def _is_class_var(annot): - """ - Check whether *annot* is a typing.ClassVar. - - The string comparison hack is used to avoid evaluating all string - annotations which would put attrs-based classes at a performance - disadvantage compared to plain old classes. - """ - annot = str(annot) - - # Annotation can be quoted. - if annot.startswith(("'", '"')) and annot.endswith(("'", '"')): - annot = annot[1:-1] - - return annot.startswith(_CLASSVAR_PREFIXES) - - -def _has_own_attribute(cls, attrib_name): - """ - Check whether *cls* defines *attrib_name* (and doesn't just inherit it). - """ - return attrib_name in cls.__dict__ - - -def _collect_base_attrs(cls, taken_attr_names): - """ - Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. - """ - base_attrs = [] - base_attr_map = {} # A dictionary of base attrs to their classes. - - # Traverse the MRO and collect attributes. - for base_cls in reversed(cls.__mro__[1:-1]): - for a in getattr(base_cls, "__attrs_attrs__", []): - if a.inherited or a.name in taken_attr_names: - continue - - a = a.evolve(inherited=True) # noqa: PLW2901 - base_attrs.append(a) - base_attr_map[a.name] = base_cls - - # For each name, only keep the freshest definition i.e. the furthest at the - # back. base_attr_map is fine because it gets overwritten with every new - # instance. - filtered = [] - seen = set() - for a in reversed(base_attrs): - if a.name in seen: - continue - filtered.insert(0, a) - seen.add(a.name) - - return filtered, base_attr_map - - -def _collect_base_attrs_broken(cls, taken_attr_names): - """ - Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. - - N.B. *taken_attr_names* will be mutated. - - Adhere to the old incorrect behavior. - - Notably it collects from the front and considers inherited attributes which - leads to the buggy behavior reported in #428. - """ - base_attrs = [] - base_attr_map = {} # A dictionary of base attrs to their classes. - - # Traverse the MRO and collect attributes. - for base_cls in cls.__mro__[1:-1]: - for a in getattr(base_cls, "__attrs_attrs__", []): - if a.name in taken_attr_names: - continue - - a = a.evolve(inherited=True) # noqa: PLW2901 - taken_attr_names.add(a.name) - base_attrs.append(a) - base_attr_map[a.name] = base_cls - - return base_attrs, base_attr_map - - -def _transform_attrs( - cls, these, auto_attribs, kw_only, collect_by_mro, field_transformer -): - """ - Transform all `_CountingAttr`s on a class into `Attribute`s. - - If *these* is passed, use that and don't look for them on the class. - - If *collect_by_mro* is True, collect them in the correct MRO order, - otherwise use the old -- incorrect -- order. See #428. - - Return an `_Attributes`. - """ - cd = cls.__dict__ - anns = _get_annotations(cls) - - if these is not None: - ca_list = list(these.items()) - elif auto_attribs is True: - ca_names = { - name - for name, attr in cd.items() - if isinstance(attr, _CountingAttr) - } - ca_list = [] - annot_names = set() - for attr_name, type in anns.items(): - if _is_class_var(type): - continue - annot_names.add(attr_name) - a = cd.get(attr_name, NOTHING) - - if not isinstance(a, _CountingAttr): - a = attrib() if a is NOTHING else attrib(default=a) - ca_list.append((attr_name, a)) - - unannotated = ca_names - annot_names - if len(unannotated) > 0: - raise UnannotatedAttributeError( - "The following `attr.ib`s lack a type annotation: " - + ", ".join( - sorted(unannotated, key=lambda n: cd.get(n).counter) - ) - + "." - ) - else: - ca_list = sorted( - ( - (name, attr) - for name, attr in cd.items() - if isinstance(attr, _CountingAttr) - ), - key=lambda e: e[1].counter, - ) - - own_attrs = [ - Attribute.from_counting_attr( - name=attr_name, ca=ca, type=anns.get(attr_name) - ) - for attr_name, ca in ca_list - ] - - if collect_by_mro: - base_attrs, base_attr_map = _collect_base_attrs( - cls, {a.name for a in own_attrs} - ) - else: - base_attrs, base_attr_map = _collect_base_attrs_broken( - cls, {a.name for a in own_attrs} - ) - - if kw_only: - own_attrs = [a.evolve(kw_only=True) for a in own_attrs] - base_attrs = [a.evolve(kw_only=True) for a in base_attrs] - - attrs = base_attrs + own_attrs - - # Mandatory vs non-mandatory attr order only matters when they are part of - # the __init__ signature and when they aren't kw_only (which are moved to - # the end and can be mandatory or non-mandatory in any order, as they will - # be specified as keyword args anyway). Check the order of those attrs: - had_default = False - for a in (a for a in attrs if a.init is not False and a.kw_only is False): - if had_default is True and a.default is NOTHING: - msg = f"No mandatory attributes allowed after an attribute with a default value or factory. Attribute in question: {a!r}" - raise ValueError(msg) - - if had_default is False and a.default is not NOTHING: - had_default = True - - if field_transformer is not None: - attrs = field_transformer(cls, attrs) - - # Resolve default field alias after executing field_transformer. - # This allows field_transformer to differentiate between explicit vs - # default aliases and supply their own defaults. - attrs = [ - a.evolve(alias=_default_init_alias_for(a.name)) if not a.alias else a - for a in attrs - ] - - # Create AttrsClass *after* applying the field_transformer since it may - # add or remove attributes! - attr_names = [a.name for a in attrs] - AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names) - - return _Attributes((AttrsClass(attrs), base_attrs, base_attr_map)) - - -def _make_cached_property_getattr(cached_properties, original_getattr, cls): - lines = [ - # Wrapped to get `__class__` into closure cell for super() - # (It will be replaced with the newly constructed class after construction). - "def wrapper(_cls):", - " __class__ = _cls", - " def __getattr__(self, item, cached_properties=cached_properties, original_getattr=original_getattr, _cached_setattr_get=_cached_setattr_get):", - " func = cached_properties.get(item)", - " if func is not None:", - " result = func(self)", - " _setter = _cached_setattr_get(self)", - " _setter(item, result)", - " return result", - ] - if original_getattr is not None: - lines.append( - " return original_getattr(self, item)", - ) - else: - lines.extend( - [ - " try:", - " return super().__getattribute__(item)", - " except AttributeError:", - " if not hasattr(super(), '__getattr__'):", - " raise", - " return super().__getattr__(item)", - " original_error = f\"'{self.__class__.__name__}' object has no attribute '{item}'\"", - " raise AttributeError(original_error)", - ] - ) - - lines.extend( - [ - " return __getattr__", - "__getattr__ = wrapper(_cls)", - ] - ) - - unique_filename = _generate_unique_filename(cls, "getattr") - - glob = { - "cached_properties": cached_properties, - "_cached_setattr_get": _OBJ_SETATTR.__get__, - "original_getattr": original_getattr, - } - - return _make_method( - "__getattr__", - "\n".join(lines), - unique_filename, - glob, - locals={ - "_cls": cls, - }, - ) - - -def _frozen_setattrs(self, name, value): - """ - Attached to frozen classes as __setattr__. - """ - if isinstance(self, BaseException) and name in ( - "__cause__", - "__context__", - "__traceback__", - ): - BaseException.__setattr__(self, name, value) - return - - raise FrozenInstanceError() - - -def _frozen_delattrs(self, name): - """ - Attached to frozen classes as __delattr__. - """ - raise FrozenInstanceError() - - -class _ClassBuilder: - """ - Iteratively build *one* class. - """ - - __slots__ = ( - "_attr_names", - "_attrs", - "_base_attr_map", - "_base_names", - "_cache_hash", - "_cls", - "_cls_dict", - "_delete_attribs", - "_frozen", - "_has_pre_init", - "_pre_init_has_args", - "_has_post_init", - "_is_exc", - "_on_setattr", - "_slots", - "_weakref_slot", - "_wrote_own_setattr", - "_has_custom_setattr", - ) - - def __init__( - self, - cls, - these, - slots, - frozen, - weakref_slot, - getstate_setstate, - auto_attribs, - kw_only, - cache_hash, - is_exc, - collect_by_mro, - on_setattr, - has_custom_setattr, - field_transformer, - ): - attrs, base_attrs, base_map = _transform_attrs( - cls, - these, - auto_attribs, - kw_only, - collect_by_mro, - field_transformer, - ) - - self._cls = cls - self._cls_dict = dict(cls.__dict__) if slots else {} - self._attrs = attrs - self._base_names = {a.name for a in base_attrs} - self._base_attr_map = base_map - self._attr_names = tuple(a.name for a in attrs) - self._slots = slots - self._frozen = frozen - self._weakref_slot = weakref_slot - self._cache_hash = cache_hash - self._has_pre_init = bool(getattr(cls, "__attrs_pre_init__", False)) - self._pre_init_has_args = False - if self._has_pre_init: - # Check if the pre init method has more arguments than just `self` - # We want to pass arguments if pre init expects arguments - pre_init_func = cls.__attrs_pre_init__ - pre_init_signature = inspect.signature(pre_init_func) - self._pre_init_has_args = len(pre_init_signature.parameters) > 1 - self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False)) - self._delete_attribs = not bool(these) - self._is_exc = is_exc - self._on_setattr = on_setattr - - self._has_custom_setattr = has_custom_setattr - self._wrote_own_setattr = False - - self._cls_dict["__attrs_attrs__"] = self._attrs - - if frozen: - self._cls_dict["__setattr__"] = _frozen_setattrs - self._cls_dict["__delattr__"] = _frozen_delattrs - - self._wrote_own_setattr = True - elif on_setattr in ( - _DEFAULT_ON_SETATTR, - setters.validate, - setters.convert, - ): - has_validator = has_converter = False - for a in attrs: - if a.validator is not None: - has_validator = True - if a.converter is not None: - has_converter = True - - if has_validator and has_converter: - break - if ( - ( - on_setattr == _DEFAULT_ON_SETATTR - and not (has_validator or has_converter) - ) - or (on_setattr == setters.validate and not has_validator) - or (on_setattr == setters.convert and not has_converter) - ): - # If class-level on_setattr is set to convert + validate, but - # there's no field to convert or validate, pretend like there's - # no on_setattr. - self._on_setattr = None - - if getstate_setstate: - ( - self._cls_dict["__getstate__"], - self._cls_dict["__setstate__"], - ) = self._make_getstate_setstate() - - def __repr__(self): - return f"<_ClassBuilder(cls={self._cls.__name__})>" - - def build_class(self): - """ - Finalize class based on the accumulated configuration. - - Builder cannot be used after calling this method. - """ - if self._slots is True: - cls = self._create_slots_class() - else: - cls = self._patch_original_class() - if PY_3_10_PLUS: - cls = abc.update_abstractmethods(cls) - - # The method gets only called if it's not inherited from a base class. - # _has_own_attribute does NOT work properly for classmethods. - if ( - getattr(cls, "__attrs_init_subclass__", None) - and "__attrs_init_subclass__" not in cls.__dict__ - ): - cls.__attrs_init_subclass__() - - return cls - - def _patch_original_class(self): - """ - Apply accumulated methods and return the class. - """ - cls = self._cls - base_names = self._base_names - - # Clean class of attribute definitions (`attr.ib()`s). - if self._delete_attribs: - for name in self._attr_names: - if ( - name not in base_names - and getattr(cls, name, _SENTINEL) is not _SENTINEL - ): - # An AttributeError can happen if a base class defines a - # class variable and we want to set an attribute with the - # same name by using only a type annotation. - with contextlib.suppress(AttributeError): - delattr(cls, name) - - # Attach our dunder methods. - for name, value in self._cls_dict.items(): - setattr(cls, name, value) - - # If we've inherited an attrs __setattr__ and don't write our own, - # reset it to object's. - if not self._wrote_own_setattr and getattr( - cls, "__attrs_own_setattr__", False - ): - cls.__attrs_own_setattr__ = False - - if not self._has_custom_setattr: - cls.__setattr__ = _OBJ_SETATTR - - return cls - - def _create_slots_class(self): - """ - Build and return a new class with a `__slots__` attribute. - """ - cd = { - k: v - for k, v in self._cls_dict.items() - if k not in (*tuple(self._attr_names), "__dict__", "__weakref__") - } - - # If our class doesn't have its own implementation of __setattr__ - # (either from the user or by us), check the bases, if one of them has - # an attrs-made __setattr__, that needs to be reset. We don't walk the - # MRO because we only care about our immediate base classes. - # XXX: This can be confused by subclassing a slotted attrs class with - # XXX: a non-attrs class and subclass the resulting class with an attrs - # XXX: class. See `test_slotted_confused` for details. For now that's - # XXX: OK with us. - if not self._wrote_own_setattr: - cd["__attrs_own_setattr__"] = False - - if not self._has_custom_setattr: - for base_cls in self._cls.__bases__: - if base_cls.__dict__.get("__attrs_own_setattr__", False): - cd["__setattr__"] = _OBJ_SETATTR - break - - # Traverse the MRO to collect existing slots - # and check for an existing __weakref__. - existing_slots = {} - weakref_inherited = False - for base_cls in self._cls.__mro__[1:-1]: - if base_cls.__dict__.get("__weakref__", None) is not None: - weakref_inherited = True - existing_slots.update( - { - name: getattr(base_cls, name) - for name in getattr(base_cls, "__slots__", []) - } - ) - - base_names = set(self._base_names) - - names = self._attr_names - if ( - self._weakref_slot - and "__weakref__" not in getattr(self._cls, "__slots__", ()) - and "__weakref__" not in names - and not weakref_inherited - ): - names += ("__weakref__",) - - if PY_3_8_PLUS: - cached_properties = { - name: cached_property.func - for name, cached_property in cd.items() - if isinstance(cached_property, functools.cached_property) - } - else: - # `functools.cached_property` was introduced in 3.8. - # So can't be used before this. - cached_properties = {} - - # Collect methods with a `__class__` reference that are shadowed in the new class. - # To know to update them. - additional_closure_functions_to_update = [] - if cached_properties: - class_annotations = _get_annotations(self._cls) - for name, func in cached_properties.items(): - # Add cached properties to names for slotting. - names += (name,) - # Clear out function from class to avoid clashing. - del cd[name] - additional_closure_functions_to_update.append(func) - annotation = inspect.signature(func).return_annotation - if annotation is not inspect.Parameter.empty: - class_annotations[name] = annotation - - original_getattr = cd.get("__getattr__") - if original_getattr is not None: - additional_closure_functions_to_update.append(original_getattr) - - cd["__getattr__"] = _make_cached_property_getattr( - cached_properties, original_getattr, self._cls - ) - - # We only add the names of attributes that aren't inherited. - # Setting __slots__ to inherited attributes wastes memory. - slot_names = [name for name in names if name not in base_names] - - # There are slots for attributes from current class - # that are defined in parent classes. - # As their descriptors may be overridden by a child class, - # we collect them here and update the class dict - reused_slots = { - slot: slot_descriptor - for slot, slot_descriptor in existing_slots.items() - if slot in slot_names - } - slot_names = [name for name in slot_names if name not in reused_slots] - cd.update(reused_slots) - if self._cache_hash: - slot_names.append(_HASH_CACHE_FIELD) - - cd["__slots__"] = tuple(slot_names) - - cd["__qualname__"] = self._cls.__qualname__ - - # Create new class based on old class and our methods. - cls = type(self._cls)(self._cls.__name__, self._cls.__bases__, cd) - - # The following is a fix for - # . - # If a method mentions `__class__` or uses the no-arg super(), the - # compiler will bake a reference to the class in the method itself - # as `method.__closure__`. Since we replace the class with a - # clone, we rewrite these references so it keeps working. - for item in itertools.chain( - cls.__dict__.values(), additional_closure_functions_to_update - ): - if isinstance(item, (classmethod, staticmethod)): - # Class- and staticmethods hide their functions inside. - # These might need to be rewritten as well. - closure_cells = getattr(item.__func__, "__closure__", None) - elif isinstance(item, property): - # Workaround for property `super()` shortcut (PY3-only). - # There is no universal way for other descriptors. - closure_cells = getattr(item.fget, "__closure__", None) - else: - closure_cells = getattr(item, "__closure__", None) - - if not closure_cells: # Catch None or the empty list. - continue - for cell in closure_cells: - try: - match = cell.cell_contents is self._cls - except ValueError: # noqa: PERF203 - # ValueError: Cell is empty - pass - else: - if match: - cell.cell_contents = cls - return cls - - def add_repr(self, ns): - self._cls_dict["__repr__"] = self._add_method_dunders( - _make_repr(self._attrs, ns, self._cls) - ) - return self - - def add_str(self): - repr = self._cls_dict.get("__repr__") - if repr is None: - msg = "__str__ can only be generated if a __repr__ exists." - raise ValueError(msg) - - def __str__(self): - return self.__repr__() - - self._cls_dict["__str__"] = self._add_method_dunders(__str__) - return self - - def _make_getstate_setstate(self): - """ - Create custom __setstate__ and __getstate__ methods. - """ - # __weakref__ is not writable. - state_attr_names = tuple( - an for an in self._attr_names if an != "__weakref__" - ) - - def slots_getstate(self): - """ - Automatically created by attrs. - """ - return {name: getattr(self, name) for name in state_attr_names} - - hash_caching_enabled = self._cache_hash - - def slots_setstate(self, state): - """ - Automatically created by attrs. - """ - __bound_setattr = _OBJ_SETATTR.__get__(self) - if isinstance(state, tuple): - # Backward compatibility with attrs instances pickled with - # attrs versions before v22.2.0 which stored tuples. - for name, value in zip(state_attr_names, state): - __bound_setattr(name, value) - else: - for name in state_attr_names: - if name in state: - __bound_setattr(name, state[name]) - - # The hash code cache is not included when the object is - # serialized, but it still needs to be initialized to None to - # indicate that the first call to __hash__ should be a cache - # miss. - if hash_caching_enabled: - __bound_setattr(_HASH_CACHE_FIELD, None) - - return slots_getstate, slots_setstate - - def make_unhashable(self): - self._cls_dict["__hash__"] = None - return self - - def add_hash(self): - self._cls_dict["__hash__"] = self._add_method_dunders( - _make_hash( - self._cls, - self._attrs, - frozen=self._frozen, - cache_hash=self._cache_hash, - ) - ) - - return self - - def add_init(self): - self._cls_dict["__init__"] = self._add_method_dunders( - _make_init( - self._cls, - self._attrs, - self._has_pre_init, - self._pre_init_has_args, - self._has_post_init, - self._frozen, - self._slots, - self._cache_hash, - self._base_attr_map, - self._is_exc, - self._on_setattr, - attrs_init=False, - ) - ) - - return self - - def add_match_args(self): - self._cls_dict["__match_args__"] = tuple( - field.name - for field in self._attrs - if field.init and not field.kw_only - ) - - def add_attrs_init(self): - self._cls_dict["__attrs_init__"] = self._add_method_dunders( - _make_init( - self._cls, - self._attrs, - self._has_pre_init, - self._pre_init_has_args, - self._has_post_init, - self._frozen, - self._slots, - self._cache_hash, - self._base_attr_map, - self._is_exc, - self._on_setattr, - attrs_init=True, - ) - ) - - return self - - def add_eq(self): - cd = self._cls_dict - - cd["__eq__"] = self._add_method_dunders( - _make_eq(self._cls, self._attrs) - ) - cd["__ne__"] = self._add_method_dunders(_make_ne()) - - return self - - def add_order(self): - cd = self._cls_dict - - cd["__lt__"], cd["__le__"], cd["__gt__"], cd["__ge__"] = ( - self._add_method_dunders(meth) - for meth in _make_order(self._cls, self._attrs) - ) - - return self - - def add_setattr(self): - if self._frozen: - return self - - sa_attrs = {} - for a in self._attrs: - on_setattr = a.on_setattr or self._on_setattr - if on_setattr and on_setattr is not setters.NO_OP: - sa_attrs[a.name] = a, on_setattr - - if not sa_attrs: - return self - - if self._has_custom_setattr: - # We need to write a __setattr__ but there already is one! - msg = "Can't combine custom __setattr__ with on_setattr hooks." - raise ValueError(msg) - - # docstring comes from _add_method_dunders - def __setattr__(self, name, val): - try: - a, hook = sa_attrs[name] - except KeyError: - nval = val - else: - nval = hook(self, a, val) - - _OBJ_SETATTR(self, name, nval) - - self._cls_dict["__attrs_own_setattr__"] = True - self._cls_dict["__setattr__"] = self._add_method_dunders(__setattr__) - self._wrote_own_setattr = True - - return self - - def _add_method_dunders(self, method): - """ - Add __module__ and __qualname__ to a *method* if possible. - """ - with contextlib.suppress(AttributeError): - method.__module__ = self._cls.__module__ - - with contextlib.suppress(AttributeError): - method.__qualname__ = f"{self._cls.__qualname__}.{method.__name__}" - - with contextlib.suppress(AttributeError): - method.__doc__ = ( - "Method generated by attrs for class " - f"{self._cls.__qualname__}." - ) - - return method - - -def _determine_attrs_eq_order(cmp, eq, order, default_eq): - """ - Validate the combination of *cmp*, *eq*, and *order*. Derive the effective - values of eq and order. If *eq* is None, set it to *default_eq*. - """ - if cmp is not None and any((eq is not None, order is not None)): - msg = "Don't mix `cmp` with `eq' and `order`." - raise ValueError(msg) - - # cmp takes precedence due to bw-compatibility. - if cmp is not None: - return cmp, cmp - - # If left None, equality is set to the specified default and ordering - # mirrors equality. - if eq is None: - eq = default_eq - - if order is None: - order = eq - - if eq is False and order is True: - msg = "`order` can only be True if `eq` is True too." - raise ValueError(msg) - - return eq, order - - -def _determine_attrib_eq_order(cmp, eq, order, default_eq): - """ - Validate the combination of *cmp*, *eq*, and *order*. Derive the effective - values of eq and order. If *eq* is None, set it to *default_eq*. - """ - if cmp is not None and any((eq is not None, order is not None)): - msg = "Don't mix `cmp` with `eq' and `order`." - raise ValueError(msg) - - def decide_callable_or_boolean(value): - """ - Decide whether a key function is used. - """ - if callable(value): - value, key = True, value - else: - key = None - return value, key - - # cmp takes precedence due to bw-compatibility. - if cmp is not None: - cmp, cmp_key = decide_callable_or_boolean(cmp) - return cmp, cmp_key, cmp, cmp_key - - # If left None, equality is set to the specified default and ordering - # mirrors equality. - if eq is None: - eq, eq_key = default_eq, None - else: - eq, eq_key = decide_callable_or_boolean(eq) - - if order is None: - order, order_key = eq, eq_key - else: - order, order_key = decide_callable_or_boolean(order) - - if eq is False and order is True: - msg = "`order` can only be True if `eq` is True too." - raise ValueError(msg) - - return eq, eq_key, order, order_key - - -def _determine_whether_to_implement( - cls, flag, auto_detect, dunders, default=True -): - """ - Check whether we should implement a set of methods for *cls*. - - *flag* is the argument passed into @attr.s like 'init', *auto_detect* the - same as passed into @attr.s and *dunders* is a tuple of attribute names - whose presence signal that the user has implemented it themselves. - - Return *default* if no reason for either for or against is found. - """ - if flag is True or flag is False: - return flag - - if flag is None and auto_detect is False: - return default - - # Logically, flag is None and auto_detect is True here. - for dunder in dunders: - if _has_own_attribute(cls, dunder): - return False - - return default - - -def attrs( - maybe_cls=None, - these=None, - repr_ns=None, - repr=None, - cmp=None, - hash=None, - init=None, - slots=False, - frozen=False, - weakref_slot=True, - str=False, - auto_attribs=False, - kw_only=False, - cache_hash=False, - auto_exc=False, - eq=None, - order=None, - auto_detect=False, - collect_by_mro=False, - getstate_setstate=None, - on_setattr=None, - field_transformer=None, - match_args=True, - unsafe_hash=None, -): - r""" - A class decorator that adds :term:`dunder methods` according to the - specified attributes using `attr.ib` or the *these* argument. - - Consider using `attrs.define` / `attrs.frozen` in new code (``attr.s`` will - *never* go away, though). - - Args: - repr_ns (str): - When using nested classes, there was no way in Python 2 to - automatically detect that. This argument allows to set a custom - name for a more meaningful ``repr`` output. This argument is - pointless in Python 3 and is therefore deprecated. - - .. caution:: - Refer to `attrs.define` for the rest of the parameters, but note that they - can have different defaults. - - Notably, leaving *on_setattr* as `None` will **not** add any hooks. - - .. versionadded:: 16.0.0 *slots* - .. versionadded:: 16.1.0 *frozen* - .. versionadded:: 16.3.0 *str* - .. versionadded:: 16.3.0 Support for ``__attrs_post_init__``. - .. versionchanged:: 17.1.0 - *hash* supports `None` as value which is also the default now. - .. versionadded:: 17.3.0 *auto_attribs* - .. versionchanged:: 18.1.0 - If *these* is passed, no attributes are deleted from the class body. - .. versionchanged:: 18.1.0 If *these* is ordered, the order is retained. - .. versionadded:: 18.2.0 *weakref_slot* - .. deprecated:: 18.2.0 - ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now raise a - `DeprecationWarning` if the classes compared are subclasses of - each other. ``__eq`` and ``__ne__`` never tried to compared subclasses - to each other. - .. versionchanged:: 19.2.0 - ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now do not consider - subclasses comparable anymore. - .. versionadded:: 18.2.0 *kw_only* - .. versionadded:: 18.2.0 *cache_hash* - .. versionadded:: 19.1.0 *auto_exc* - .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. - .. versionadded:: 19.2.0 *eq* and *order* - .. versionadded:: 20.1.0 *auto_detect* - .. versionadded:: 20.1.0 *collect_by_mro* - .. versionadded:: 20.1.0 *getstate_setstate* - .. versionadded:: 20.1.0 *on_setattr* - .. versionadded:: 20.3.0 *field_transformer* - .. versionchanged:: 21.1.0 - ``init=False`` injects ``__attrs_init__`` - .. versionchanged:: 21.1.0 Support for ``__attrs_pre_init__`` - .. versionchanged:: 21.1.0 *cmp* undeprecated - .. versionadded:: 21.3.0 *match_args* - .. versionadded:: 22.2.0 - *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance). - .. deprecated:: 24.1.0 *repr_ns* - .. versionchanged:: 24.1.0 - Instances are not compared as tuples of attributes anymore, but using a - big ``and`` condition. This is faster and has more correct behavior for - uncomparable values like `math.nan`. - .. versionadded:: 24.1.0 - If a class has an *inherited* classmethod called - ``__attrs_init_subclass__``, it is executed after the class is created. - .. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*. - """ - if repr_ns is not None: - import warnings - - warnings.warn( - DeprecationWarning( - "The `repr_ns` argument is deprecated and will be removed in or after August 2025." - ), - stacklevel=2, - ) - - eq_, order_ = _determine_attrs_eq_order(cmp, eq, order, None) - - # unsafe_hash takes precedence due to PEP 681. - if unsafe_hash is not None: - hash = unsafe_hash - - if isinstance(on_setattr, (list, tuple)): - on_setattr = setters.pipe(*on_setattr) - - def wrap(cls): - is_frozen = frozen or _has_frozen_base_class(cls) - is_exc = auto_exc is True and issubclass(cls, BaseException) - has_own_setattr = auto_detect and _has_own_attribute( - cls, "__setattr__" - ) - - if has_own_setattr and is_frozen: - msg = "Can't freeze a class with a custom __setattr__." - raise ValueError(msg) - - builder = _ClassBuilder( - cls, - these, - slots, - is_frozen, - weakref_slot, - _determine_whether_to_implement( - cls, - getstate_setstate, - auto_detect, - ("__getstate__", "__setstate__"), - default=slots, - ), - auto_attribs, - kw_only, - cache_hash, - is_exc, - collect_by_mro, - on_setattr, - has_own_setattr, - field_transformer, - ) - if _determine_whether_to_implement( - cls, repr, auto_detect, ("__repr__",) - ): - builder.add_repr(repr_ns) - if str is True: - builder.add_str() - - eq = _determine_whether_to_implement( - cls, eq_, auto_detect, ("__eq__", "__ne__") - ) - if not is_exc and eq is True: - builder.add_eq() - if not is_exc and _determine_whether_to_implement( - cls, order_, auto_detect, ("__lt__", "__le__", "__gt__", "__ge__") - ): - builder.add_order() - - builder.add_setattr() - - nonlocal hash - if ( - hash is None - and auto_detect is True - and _has_own_attribute(cls, "__hash__") - ): - hash = False - - if hash is not True and hash is not False and hash is not None: - # Can't use `hash in` because 1 == True for example. - msg = "Invalid value for hash. Must be True, False, or None." - raise TypeError(msg) - - if hash is False or (hash is None and eq is False) or is_exc: - # Don't do anything. Should fall back to __object__'s __hash__ - # which is by id. - if cache_hash: - msg = "Invalid value for cache_hash. To use hash caching, hashing must be either explicitly or implicitly enabled." - raise TypeError(msg) - elif hash is True or ( - hash is None and eq is True and is_frozen is True - ): - # Build a __hash__ if told so, or if it's safe. - builder.add_hash() - else: - # Raise TypeError on attempts to hash. - if cache_hash: - msg = "Invalid value for cache_hash. To use hash caching, hashing must be either explicitly or implicitly enabled." - raise TypeError(msg) - builder.make_unhashable() - - if _determine_whether_to_implement( - cls, init, auto_detect, ("__init__",) - ): - builder.add_init() - else: - builder.add_attrs_init() - if cache_hash: - msg = "Invalid value for cache_hash. To use hash caching, init must be True." - raise TypeError(msg) - - if ( - PY_3_10_PLUS - and match_args - and not _has_own_attribute(cls, "__match_args__") - ): - builder.add_match_args() - - return builder.build_class() - - # maybe_cls's type depends on the usage of the decorator. It's a class - # if it's used as `@attrs` but `None` if used as `@attrs()`. - if maybe_cls is None: - return wrap - - return wrap(maybe_cls) - - -_attrs = attrs -""" -Internal alias so we can use it in functions that take an argument called -*attrs*. -""" - - -def _has_frozen_base_class(cls): - """ - Check whether *cls* has a frozen ancestor by looking at its - __setattr__. - """ - return cls.__setattr__ is _frozen_setattrs - - -def _generate_unique_filename(cls, func_name): - """ - Create a "filename" suitable for a function being generated. - """ - return ( - f"" - ) - - -def _make_hash(cls, attrs, frozen, cache_hash): - attrs = tuple( - a for a in attrs if a.hash is True or (a.hash is None and a.eq is True) - ) - - tab = " " - - unique_filename = _generate_unique_filename(cls, "hash") - type_hash = hash(unique_filename) - # If eq is custom generated, we need to include the functions in globs - globs = {} - - hash_def = "def __hash__(self" - hash_func = "hash((" - closing_braces = "))" - if not cache_hash: - hash_def += "):" - else: - hash_def += ", *" - - hash_def += ", _cache_wrapper=__import__('attr._make')._make._CacheHashWrapper):" - hash_func = "_cache_wrapper(" + hash_func - closing_braces += ")" - - method_lines = [hash_def] - - def append_hash_computation_lines(prefix, indent): - """ - Generate the code for actually computing the hash code. - Below this will either be returned directly or used to compute - a value which is then cached, depending on the value of cache_hash - """ - - method_lines.extend( - [ - indent + prefix + hash_func, - indent + f" {type_hash},", - ] - ) - - for a in attrs: - if a.eq_key: - cmp_name = f"_{a.name}_key" - globs[cmp_name] = a.eq_key - method_lines.append( - indent + f" {cmp_name}(self.{a.name})," - ) - else: - method_lines.append(indent + f" self.{a.name},") - - method_lines.append(indent + " " + closing_braces) - - if cache_hash: - method_lines.append(tab + f"if self.{_HASH_CACHE_FIELD} is None:") - if frozen: - append_hash_computation_lines( - f"object.__setattr__(self, '{_HASH_CACHE_FIELD}', ", tab * 2 - ) - method_lines.append(tab * 2 + ")") # close __setattr__ - else: - append_hash_computation_lines( - f"self.{_HASH_CACHE_FIELD} = ", tab * 2 - ) - method_lines.append(tab + f"return self.{_HASH_CACHE_FIELD}") - else: - append_hash_computation_lines("return ", tab) - - script = "\n".join(method_lines) - return _make_method("__hash__", script, unique_filename, globs) - - -def _add_hash(cls, attrs): - """ - Add a hash method to *cls*. - """ - cls.__hash__ = _make_hash(cls, attrs, frozen=False, cache_hash=False) - return cls - - -def _make_ne(): - """ - Create __ne__ method. - """ - - def __ne__(self, other): - """ - Check equality and either forward a NotImplemented or - return the result negated. - """ - result = self.__eq__(other) - if result is NotImplemented: - return NotImplemented - - return not result - - return __ne__ - - -def _make_eq(cls, attrs): - """ - Create __eq__ method for *cls* with *attrs*. - """ - attrs = [a for a in attrs if a.eq] - - unique_filename = _generate_unique_filename(cls, "eq") - lines = [ - "def __eq__(self, other):", - " if other.__class__ is not self.__class__:", - " return NotImplemented", - ] - - # We can't just do a big self.x = other.x and... clause due to - # irregularities like nan == nan is false but (nan,) == (nan,) is true. - globs = {} - if attrs: - lines.append(" return (") - for a in attrs: - if a.eq_key: - cmp_name = f"_{a.name}_key" - # Add the key function to the global namespace - # of the evaluated function. - globs[cmp_name] = a.eq_key - lines.append( - f" {cmp_name}(self.{a.name}) == {cmp_name}(other.{a.name})" - ) - else: - lines.append(f" self.{a.name} == other.{a.name}") - if a is not attrs[-1]: - lines[-1] = f"{lines[-1]} and" - lines.append(" )") - else: - lines.append(" return True") - - script = "\n".join(lines) - - return _make_method("__eq__", script, unique_filename, globs) - - -def _make_order(cls, attrs): - """ - Create ordering methods for *cls* with *attrs*. - """ - attrs = [a for a in attrs if a.order] - - def attrs_to_tuple(obj): - """ - Save us some typing. - """ - return tuple( - key(value) if key else value - for value, key in ( - (getattr(obj, a.name), a.order_key) for a in attrs - ) - ) - - def __lt__(self, other): - """ - Automatically created by attrs. - """ - if other.__class__ is self.__class__: - return attrs_to_tuple(self) < attrs_to_tuple(other) - - return NotImplemented - - def __le__(self, other): - """ - Automatically created by attrs. - """ - if other.__class__ is self.__class__: - return attrs_to_tuple(self) <= attrs_to_tuple(other) - - return NotImplemented - - def __gt__(self, other): - """ - Automatically created by attrs. - """ - if other.__class__ is self.__class__: - return attrs_to_tuple(self) > attrs_to_tuple(other) - - return NotImplemented - - def __ge__(self, other): - """ - Automatically created by attrs. - """ - if other.__class__ is self.__class__: - return attrs_to_tuple(self) >= attrs_to_tuple(other) - - return NotImplemented - - return __lt__, __le__, __gt__, __ge__ - - -def _add_eq(cls, attrs=None): - """ - Add equality methods to *cls* with *attrs*. - """ - if attrs is None: - attrs = cls.__attrs_attrs__ - - cls.__eq__ = _make_eq(cls, attrs) - cls.__ne__ = _make_ne() - - return cls - - -def _make_repr(attrs, ns, cls): - unique_filename = _generate_unique_filename(cls, "repr") - # Figure out which attributes to include, and which function to use to - # format them. The a.repr value can be either bool or a custom - # callable. - attr_names_with_reprs = tuple( - (a.name, (repr if a.repr is True else a.repr), a.init) - for a in attrs - if a.repr is not False - ) - globs = { - name + "_repr": r for name, r, _ in attr_names_with_reprs if r != repr - } - globs["_compat"] = _compat - globs["AttributeError"] = AttributeError - globs["NOTHING"] = NOTHING - attribute_fragments = [] - for name, r, i in attr_names_with_reprs: - accessor = ( - "self." + name if i else 'getattr(self, "' + name + '", NOTHING)' - ) - fragment = ( - "%s={%s!r}" % (name, accessor) - if r == repr - else "%s={%s_repr(%s)}" % (name, name, accessor) - ) - attribute_fragments.append(fragment) - repr_fragment = ", ".join(attribute_fragments) - - if ns is None: - cls_name_fragment = '{self.__class__.__qualname__.rsplit(">.", 1)[-1]}' - else: - cls_name_fragment = ns + ".{self.__class__.__name__}" - - lines = [ - "def __repr__(self):", - " try:", - " already_repring = _compat.repr_context.already_repring", - " except AttributeError:", - " already_repring = {id(self),}", - " _compat.repr_context.already_repring = already_repring", - " else:", - " if id(self) in already_repring:", - " return '...'", - " else:", - " already_repring.add(id(self))", - " try:", - f" return f'{cls_name_fragment}({repr_fragment})'", - " finally:", - " already_repring.remove(id(self))", - ] - - return _make_method( - "__repr__", "\n".join(lines), unique_filename, globs=globs - ) - - -def _add_repr(cls, ns=None, attrs=None): - """ - Add a repr method to *cls*. - """ - if attrs is None: - attrs = cls.__attrs_attrs__ - - cls.__repr__ = _make_repr(attrs, ns, cls) - return cls - - -def fields(cls): - """ - Return the tuple of *attrs* attributes for a class. - - The tuple also allows accessing the fields by their names (see below for - examples). - - Args: - cls (type): Class to introspect. - - Raises: - TypeError: If *cls* is not a class. - - attrs.exceptions.NotAnAttrsClassError: - If *cls* is not an *attrs* class. - - Returns: - tuple (with name accessors) of `attrs.Attribute` - - .. versionchanged:: 16.2.0 Returned tuple allows accessing the fields - by name. - .. versionchanged:: 23.1.0 Add support for generic classes. - """ - generic_base = get_generic_base(cls) - - if generic_base is None and not isinstance(cls, type): - msg = "Passed object must be a class." - raise TypeError(msg) - - attrs = getattr(cls, "__attrs_attrs__", None) - - if attrs is None: - if generic_base is not None: - attrs = getattr(generic_base, "__attrs_attrs__", None) - if attrs is not None: - # Even though this is global state, stick it on here to speed - # it up. We rely on `cls` being cached for this to be - # efficient. - cls.__attrs_attrs__ = attrs - return attrs - msg = f"{cls!r} is not an attrs-decorated class." - raise NotAnAttrsClassError(msg) - - return attrs - - -def fields_dict(cls): - """ - Return an ordered dictionary of *attrs* attributes for a class, whose keys - are the attribute names. - - Args: - cls (type): Class to introspect. - - Raises: - TypeError: If *cls* is not a class. - - attrs.exceptions.NotAnAttrsClassError: - If *cls* is not an *attrs* class. - - Returns: - dict[str, attrs.Attribute]: Dict of attribute name to definition - - .. versionadded:: 18.1.0 - """ - if not isinstance(cls, type): - msg = "Passed object must be a class." - raise TypeError(msg) - attrs = getattr(cls, "__attrs_attrs__", None) - if attrs is None: - msg = f"{cls!r} is not an attrs-decorated class." - raise NotAnAttrsClassError(msg) - return {a.name: a for a in attrs} - - -def validate(inst): - """ - Validate all attributes on *inst* that have a validator. - - Leaves all exceptions through. - - Args: - inst: Instance of a class with *attrs* attributes. - """ - if _config._run_validators is False: - return - - for a in fields(inst.__class__): - v = a.validator - if v is not None: - v(inst, a, getattr(inst, a.name)) - - -def _is_slot_attr(a_name, base_attr_map): - """ - Check if the attribute name comes from a slot class. - """ - cls = base_attr_map.get(a_name) - return cls and "__slots__" in cls.__dict__ - - -def _make_init( - cls, - attrs, - pre_init, - pre_init_has_args, - post_init, - frozen, - slots, - cache_hash, - base_attr_map, - is_exc, - cls_on_setattr, - attrs_init, -): - has_cls_on_setattr = ( - cls_on_setattr is not None and cls_on_setattr is not setters.NO_OP - ) - - if frozen and has_cls_on_setattr: - msg = "Frozen classes can't use on_setattr." - raise ValueError(msg) - - needs_cached_setattr = cache_hash or frozen - filtered_attrs = [] - attr_dict = {} - for a in attrs: - if not a.init and a.default is NOTHING: - continue - - filtered_attrs.append(a) - attr_dict[a.name] = a - - if a.on_setattr is not None: - if frozen is True: - msg = "Frozen classes can't use on_setattr." - raise ValueError(msg) - - needs_cached_setattr = True - elif has_cls_on_setattr and a.on_setattr is not setters.NO_OP: - needs_cached_setattr = True - - unique_filename = _generate_unique_filename(cls, "init") - - script, globs, annotations = _attrs_to_init_script( - filtered_attrs, - frozen, - slots, - pre_init, - pre_init_has_args, - post_init, - cache_hash, - base_attr_map, - is_exc, - needs_cached_setattr, - has_cls_on_setattr, - "__attrs_init__" if attrs_init else "__init__", - ) - if cls.__module__ in sys.modules: - # This makes typing.get_type_hints(CLS.__init__) resolve string types. - globs.update(sys.modules[cls.__module__].__dict__) - - globs.update({"NOTHING": NOTHING, "attr_dict": attr_dict}) - - if needs_cached_setattr: - # Save the lookup overhead in __init__ if we need to circumvent - # setattr hooks. - globs["_cached_setattr_get"] = _OBJ_SETATTR.__get__ - - init = _make_method( - "__attrs_init__" if attrs_init else "__init__", - script, - unique_filename, - globs, - ) - init.__annotations__ = annotations - - return init - - -def _setattr(attr_name: str, value_var: str, has_on_setattr: bool) -> str: - """ - Use the cached object.setattr to set *attr_name* to *value_var*. - """ - return f"_setattr('{attr_name}', {value_var})" - - -def _setattr_with_converter( - attr_name: str, value_var: str, has_on_setattr: bool, converter: Converter -) -> str: - """ - Use the cached object.setattr to set *attr_name* to *value_var*, but run - its converter first. - """ - return f"_setattr('{attr_name}', {converter._fmt_converter_call(attr_name, value_var)})" - - -def _assign(attr_name: str, value: str, has_on_setattr: bool) -> str: - """ - Unless *attr_name* has an on_setattr hook, use normal assignment. Otherwise - relegate to _setattr. - """ - if has_on_setattr: - return _setattr(attr_name, value, True) - - return f"self.{attr_name} = {value}" - - -def _assign_with_converter( - attr_name: str, value_var: str, has_on_setattr: bool, converter: Converter -) -> str: - """ - Unless *attr_name* has an on_setattr hook, use normal assignment after - conversion. Otherwise relegate to _setattr_with_converter. - """ - if has_on_setattr: - return _setattr_with_converter(attr_name, value_var, True, converter) - - return f"self.{attr_name} = {converter._fmt_converter_call(attr_name, value_var)}" - - -def _determine_setters( - frozen: bool, slots: bool, base_attr_map: dict[str, type] -): - """ - Determine the correct setter functions based on whether a class is frozen - and/or slotted. - """ - if frozen is True: - if slots is True: - return (), _setattr, _setattr_with_converter - - # Dict frozen classes assign directly to __dict__. - # But only if the attribute doesn't come from an ancestor slot - # class. - # Note _inst_dict will be used again below if cache_hash is True - - def fmt_setter( - attr_name: str, value_var: str, has_on_setattr: bool - ) -> str: - if _is_slot_attr(attr_name, base_attr_map): - return _setattr(attr_name, value_var, has_on_setattr) - - return f"_inst_dict['{attr_name}'] = {value_var}" - - def fmt_setter_with_converter( - attr_name: str, - value_var: str, - has_on_setattr: bool, - converter: Converter, - ) -> str: - if has_on_setattr or _is_slot_attr(attr_name, base_attr_map): - return _setattr_with_converter( - attr_name, value_var, has_on_setattr, converter - ) - - return f"_inst_dict['{attr_name}'] = {converter._fmt_converter_call(attr_name, value_var)}" - - return ( - ("_inst_dict = self.__dict__",), - fmt_setter, - fmt_setter_with_converter, - ) - - # Not frozen -- we can just assign directly. - return (), _assign, _assign_with_converter - - -def _attrs_to_init_script( - attrs: list[Attribute], - is_frozen: bool, - is_slotted: bool, - call_pre_init: bool, - pre_init_has_args: bool, - call_post_init: bool, - does_cache_hash: bool, - base_attr_map: dict[str, type], - is_exc: bool, - needs_cached_setattr: bool, - has_cls_on_setattr: bool, - method_name: str, -) -> tuple[str, dict, dict]: - """ - Return a script of an initializer for *attrs*, a dict of globals, and - annotations for the initializer. - - The globals are required by the generated script. - """ - lines = ["self.__attrs_pre_init__()"] if call_pre_init else [] - - if needs_cached_setattr: - lines.append( - # Circumvent the __setattr__ descriptor to save one lookup per - # assignment. Note _setattr will be used again below if - # does_cache_hash is True. - "_setattr = _cached_setattr_get(self)" - ) - - extra_lines, fmt_setter, fmt_setter_with_converter = _determine_setters( - is_frozen, is_slotted, base_attr_map - ) - lines.extend(extra_lines) - - args = [] - kw_only_args = [] - attrs_to_validate = [] - - # This is a dictionary of names to validator and converter callables. - # Injecting this into __init__ globals lets us avoid lookups. - names_for_globals = {} - annotations = {"return": None} - - for a in attrs: - if a.validator: - attrs_to_validate.append(a) - - attr_name = a.name - has_on_setattr = a.on_setattr is not None or ( - a.on_setattr is not setters.NO_OP and has_cls_on_setattr - ) - # a.alias is set to maybe-mangled attr_name in _ClassBuilder if not - # explicitly provided - arg_name = a.alias - - has_factory = isinstance(a.default, Factory) - maybe_self = "self" if has_factory and a.default.takes_self else "" - - if a.converter and not isinstance(a.converter, Converter): - converter = Converter(a.converter) - else: - converter = a.converter - - if a.init is False: - if has_factory: - init_factory_name = _INIT_FACTORY_PAT % (a.name,) - if converter is not None: - lines.append( - fmt_setter_with_converter( - attr_name, - init_factory_name + f"({maybe_self})", - has_on_setattr, - converter, - ) - ) - names_for_globals[converter._get_global_name(a.name)] = ( - converter.converter - ) - else: - lines.append( - fmt_setter( - attr_name, - init_factory_name + f"({maybe_self})", - has_on_setattr, - ) - ) - names_for_globals[init_factory_name] = a.default.factory - elif converter is not None: - lines.append( - fmt_setter_with_converter( - attr_name, - f"attr_dict['{attr_name}'].default", - has_on_setattr, - converter, - ) - ) - names_for_globals[converter._get_global_name(a.name)] = ( - converter.converter - ) - else: - lines.append( - fmt_setter( - attr_name, - f"attr_dict['{attr_name}'].default", - has_on_setattr, - ) - ) - elif a.default is not NOTHING and not has_factory: - arg = f"{arg_name}=attr_dict['{attr_name}'].default" - if a.kw_only: - kw_only_args.append(arg) - else: - args.append(arg) - - if converter is not None: - lines.append( - fmt_setter_with_converter( - attr_name, arg_name, has_on_setattr, converter - ) - ) - names_for_globals[converter._get_global_name(a.name)] = ( - converter.converter - ) - else: - lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) - - elif has_factory: - arg = f"{arg_name}=NOTHING" - if a.kw_only: - kw_only_args.append(arg) - else: - args.append(arg) - lines.append(f"if {arg_name} is not NOTHING:") - - init_factory_name = _INIT_FACTORY_PAT % (a.name,) - if converter is not None: - lines.append( - " " - + fmt_setter_with_converter( - attr_name, arg_name, has_on_setattr, converter - ) - ) - lines.append("else:") - lines.append( - " " - + fmt_setter_with_converter( - attr_name, - init_factory_name + "(" + maybe_self + ")", - has_on_setattr, - converter, - ) - ) - names_for_globals[converter._get_global_name(a.name)] = ( - converter.converter - ) - else: - lines.append( - " " + fmt_setter(attr_name, arg_name, has_on_setattr) - ) - lines.append("else:") - lines.append( - " " - + fmt_setter( - attr_name, - init_factory_name + "(" + maybe_self + ")", - has_on_setattr, - ) - ) - names_for_globals[init_factory_name] = a.default.factory - else: - if a.kw_only: - kw_only_args.append(arg_name) - else: - args.append(arg_name) - - if converter is not None: - lines.append( - fmt_setter_with_converter( - attr_name, arg_name, has_on_setattr, converter - ) - ) - names_for_globals[converter._get_global_name(a.name)] = ( - converter.converter - ) - else: - lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) - - if a.init is True: - if a.type is not None and converter is None: - annotations[arg_name] = a.type - elif converter is not None and converter._first_param_type: - # Use the type from the converter if present. - annotations[arg_name] = converter._first_param_type - - if attrs_to_validate: # we can skip this if there are no validators. - names_for_globals["_config"] = _config - lines.append("if _config._run_validators is True:") - for a in attrs_to_validate: - val_name = "__attr_validator_" + a.name - attr_name = "__attr_" + a.name - lines.append(f" {val_name}(self, {attr_name}, self.{a.name})") - names_for_globals[val_name] = a.validator - names_for_globals[attr_name] = a - - if call_post_init: - lines.append("self.__attrs_post_init__()") - - # Because this is set only after __attrs_post_init__ is called, a crash - # will result if post-init tries to access the hash code. This seemed - # preferable to setting this beforehand, in which case alteration to field - # values during post-init combined with post-init accessing the hash code - # would result in silent bugs. - if does_cache_hash: - if is_frozen: - if is_slotted: - init_hash_cache = f"_setattr('{_HASH_CACHE_FIELD}', None)" - else: - init_hash_cache = f"_inst_dict['{_HASH_CACHE_FIELD}'] = None" - else: - init_hash_cache = f"self.{_HASH_CACHE_FIELD} = None" - lines.append(init_hash_cache) - - # For exceptions we rely on BaseException.__init__ for proper - # initialization. - if is_exc: - vals = ",".join(f"self.{a.name}" for a in attrs if a.init) - - lines.append(f"BaseException.__init__(self, {vals})") - - args = ", ".join(args) - pre_init_args = args - if kw_only_args: - # leading comma & kw_only args - args += f"{', ' if args else ''}*, {', '.join(kw_only_args)}" - pre_init_kw_only_args = ", ".join( - [ - f"{kw_arg_name}={kw_arg_name}" - # We need to remove the defaults from the kw_only_args. - for kw_arg_name in (kwa.split("=")[0] for kwa in kw_only_args) - ] - ) - pre_init_args += ", " if pre_init_args else "" - pre_init_args += pre_init_kw_only_args - - if call_pre_init and pre_init_has_args: - # If pre init method has arguments, pass same arguments as `__init__`. - lines[0] = f"self.__attrs_pre_init__({pre_init_args})" - - # Python 3.7 doesn't allow backslashes in f strings. - NL = "\n " - return ( - f"""def {method_name}(self, {args}): - {NL.join(lines) if lines else 'pass'} -""", - names_for_globals, - annotations, - ) - - -def _default_init_alias_for(name: str) -> str: - """ - The default __init__ parameter name for a field. - - This performs private-name adjustment via leading-unscore stripping, - and is the default value of Attribute.alias if not provided. - """ - - return name.lstrip("_") - - -class Attribute: - """ - *Read-only* representation of an attribute. - - .. warning:: - - You should never instantiate this class yourself. - - The class has *all* arguments of `attr.ib` (except for ``factory`` which is - only syntactic sugar for ``default=Factory(...)`` plus the following: - - - ``name`` (`str`): The name of the attribute. - - ``alias`` (`str`): The __init__ parameter name of the attribute, after - any explicit overrides and default private-attribute-name handling. - - ``inherited`` (`bool`): Whether or not that attribute has been inherited - from a base class. - - ``eq_key`` and ``order_key`` (`typing.Callable` or `None`): The - callables that are used for comparing and ordering objects by this - attribute, respectively. These are set by passing a callable to - `attr.ib`'s ``eq``, ``order``, or ``cmp`` arguments. See also - :ref:`comparison customization `. - - Instances of this class are frequently used for introspection purposes - like: - - - `fields` returns a tuple of them. - - Validators get them passed as the first argument. - - The :ref:`field transformer ` hook receives a list of - them. - - The ``alias`` property exposes the __init__ parameter name of the field, - with any overrides and default private-attribute handling applied. - - - .. versionadded:: 20.1.0 *inherited* - .. versionadded:: 20.1.0 *on_setattr* - .. versionchanged:: 20.2.0 *inherited* is not taken into account for - equality checks and hashing anymore. - .. versionadded:: 21.1.0 *eq_key* and *order_key* - .. versionadded:: 22.2.0 *alias* - - For the full version history of the fields, see `attr.ib`. - """ - - __slots__ = ( - "name", - "default", - "validator", - "repr", - "eq", - "eq_key", - "order", - "order_key", - "hash", - "init", - "metadata", - "type", - "converter", - "kw_only", - "inherited", - "on_setattr", - "alias", - ) - - def __init__( - self, - name, - default, - validator, - repr, - cmp, # XXX: unused, remove along with other cmp code. - hash, - init, - inherited, - metadata=None, - type=None, - converter=None, - kw_only=False, - eq=None, - eq_key=None, - order=None, - order_key=None, - on_setattr=None, - alias=None, - ): - eq, eq_key, order, order_key = _determine_attrib_eq_order( - cmp, eq_key or eq, order_key or order, True - ) - - # Cache this descriptor here to speed things up later. - bound_setattr = _OBJ_SETATTR.__get__(self) - - # Despite the big red warning, people *do* instantiate `Attribute` - # themselves. - bound_setattr("name", name) - bound_setattr("default", default) - bound_setattr("validator", validator) - bound_setattr("repr", repr) - bound_setattr("eq", eq) - bound_setattr("eq_key", eq_key) - bound_setattr("order", order) - bound_setattr("order_key", order_key) - bound_setattr("hash", hash) - bound_setattr("init", init) - bound_setattr("converter", converter) - bound_setattr( - "metadata", - ( - types.MappingProxyType(dict(metadata)) # Shallow copy - if metadata - else _EMPTY_METADATA_SINGLETON - ), - ) - bound_setattr("type", type) - bound_setattr("kw_only", kw_only) - bound_setattr("inherited", inherited) - bound_setattr("on_setattr", on_setattr) - bound_setattr("alias", alias) - - def __setattr__(self, name, value): - raise FrozenInstanceError() - - @classmethod - def from_counting_attr(cls, name, ca, type=None): - # type holds the annotated value. deal with conflicts: - if type is None: - type = ca.type - elif ca.type is not None: - msg = "Type annotation and type argument cannot both be present" - raise ValueError(msg) - inst_dict = { - k: getattr(ca, k) - for k in Attribute.__slots__ - if k - not in ( - "name", - "validator", - "default", - "type", - "inherited", - ) # exclude methods and deprecated alias - } - return cls( - name=name, - validator=ca._validator, - default=ca._default, - type=type, - cmp=None, - inherited=False, - **inst_dict, - ) - - # Don't use attrs.evolve since fields(Attribute) doesn't work - def evolve(self, **changes): - """ - Copy *self* and apply *changes*. - - This works similarly to `attrs.evolve` but that function does not work - with {class}`Attribute`. - - It is mainly meant to be used for `transform-fields`. - - .. versionadded:: 20.3.0 - """ - new = copy.copy(self) - - new._setattrs(changes.items()) - - return new - - # Don't use _add_pickle since fields(Attribute) doesn't work - def __getstate__(self): - """ - Play nice with pickle. - """ - return tuple( - getattr(self, name) if name != "metadata" else dict(self.metadata) - for name in self.__slots__ - ) - - def __setstate__(self, state): - """ - Play nice with pickle. - """ - self._setattrs(zip(self.__slots__, state)) - - def _setattrs(self, name_values_pairs): - bound_setattr = _OBJ_SETATTR.__get__(self) - for name, value in name_values_pairs: - if name != "metadata": - bound_setattr(name, value) - else: - bound_setattr( - name, - ( - types.MappingProxyType(dict(value)) - if value - else _EMPTY_METADATA_SINGLETON - ), - ) - - -_a = [ - Attribute( - name=name, - default=NOTHING, - validator=None, - repr=True, - cmp=None, - eq=True, - order=False, - hash=(name != "metadata"), - init=True, - inherited=False, - alias=_default_init_alias_for(name), - ) - for name in Attribute.__slots__ -] - -Attribute = _add_hash( - _add_eq( - _add_repr(Attribute, attrs=_a), - attrs=[a for a in _a if a.name != "inherited"], - ), - attrs=[a for a in _a if a.hash and a.name != "inherited"], -) - - -class _CountingAttr: - """ - Intermediate representation of attributes that uses a counter to preserve - the order in which the attributes have been defined. - - *Internal* data structure of the attrs library. Running into is most - likely the result of a bug like a forgotten `@attr.s` decorator. - """ - - __slots__ = ( - "counter", - "_default", - "repr", - "eq", - "eq_key", - "order", - "order_key", - "hash", - "init", - "metadata", - "_validator", - "converter", - "type", - "kw_only", - "on_setattr", - "alias", - ) - __attrs_attrs__ = ( - *tuple( - Attribute( - name=name, - alias=_default_init_alias_for(name), - default=NOTHING, - validator=None, - repr=True, - cmp=None, - hash=True, - init=True, - kw_only=False, - eq=True, - eq_key=None, - order=False, - order_key=None, - inherited=False, - on_setattr=None, - ) - for name in ( - "counter", - "_default", - "repr", - "eq", - "order", - "hash", - "init", - "on_setattr", - "alias", - ) - ), - Attribute( - name="metadata", - alias="metadata", - default=None, - validator=None, - repr=True, - cmp=None, - hash=False, - init=True, - kw_only=False, - eq=True, - eq_key=None, - order=False, - order_key=None, - inherited=False, - on_setattr=None, - ), - ) - cls_counter = 0 - - def __init__( - self, - default, - validator, - repr, - cmp, - hash, - init, - converter, - metadata, - type, - kw_only, - eq, - eq_key, - order, - order_key, - on_setattr, - alias, - ): - _CountingAttr.cls_counter += 1 - self.counter = _CountingAttr.cls_counter - self._default = default - self._validator = validator - self.converter = converter - self.repr = repr - self.eq = eq - self.eq_key = eq_key - self.order = order - self.order_key = order_key - self.hash = hash - self.init = init - self.metadata = metadata - self.type = type - self.kw_only = kw_only - self.on_setattr = on_setattr - self.alias = alias - - def validator(self, meth): - """ - Decorator that adds *meth* to the list of validators. - - Returns *meth* unchanged. - - .. versionadded:: 17.1.0 - """ - if self._validator is None: - self._validator = meth - else: - self._validator = and_(self._validator, meth) - return meth - - def default(self, meth): - """ - Decorator that allows to set the default for an attribute. - - Returns *meth* unchanged. - - Raises: - DefaultAlreadySetError: If default has been set before. - - .. versionadded:: 17.1.0 - """ - if self._default is not NOTHING: - raise DefaultAlreadySetError() - - self._default = Factory(meth, takes_self=True) - - return meth - - -_CountingAttr = _add_eq(_add_repr(_CountingAttr)) - - -class Factory: - """ - Stores a factory callable. - - If passed as the default value to `attrs.field`, the factory is used to - generate a new value. - - Args: - factory (typing.Callable): - A callable that takes either none or exactly one mandatory - positional argument depending on *takes_self*. - - takes_self (bool): - Pass the partially initialized instance that is being initialized - as a positional argument. - - .. versionadded:: 17.1.0 *takes_self* - """ - - __slots__ = ("factory", "takes_self") - - def __init__(self, factory, takes_self=False): - self.factory = factory - self.takes_self = takes_self - - def __getstate__(self): - """ - Play nice with pickle. - """ - return tuple(getattr(self, name) for name in self.__slots__) - - def __setstate__(self, state): - """ - Play nice with pickle. - """ - for name, value in zip(self.__slots__, state): - setattr(self, name, value) - - -_f = [ - Attribute( - name=name, - default=NOTHING, - validator=None, - repr=True, - cmp=None, - eq=True, - order=False, - hash=True, - init=True, - inherited=False, - ) - for name in Factory.__slots__ -] - -Factory = _add_hash(_add_eq(_add_repr(Factory, attrs=_f), attrs=_f), attrs=_f) - - -class Converter: - """ - Stores a converter callable. - - Allows for the wrapped converter to take additional arguments. The - arguments are passed in the order they are documented. - - Args: - converter (Callable): A callable that converts the passed value. - - takes_self (bool): - Pass the partially initialized instance that is being initialized - as a positional argument. (default: `False`) - - takes_field (bool): - Pass the field definition (an :class:`Attribute`) into the - converter as a positional argument. (default: `False`) - - .. versionadded:: 24.1.0 - """ - - __slots__ = ( - "converter", - "takes_self", - "takes_field", - "_first_param_type", - "_global_name", - "__call__", - ) - - def __init__(self, converter, *, takes_self=False, takes_field=False): - self.converter = converter - self.takes_self = takes_self - self.takes_field = takes_field - - ex = _AnnotationExtractor(converter) - self._first_param_type = ex.get_first_param_type() - - if not (self.takes_self or self.takes_field): - self.__call__ = lambda value, _, __: self.converter(value) - elif self.takes_self and not self.takes_field: - self.__call__ = lambda value, instance, __: self.converter( - value, instance - ) - elif not self.takes_self and self.takes_field: - self.__call__ = lambda value, __, field: self.converter( - value, field - ) - else: - self.__call__ = lambda value, instance, field: self.converter( - value, instance, field - ) - - rt = ex.get_return_type() - if rt is not None: - self.__call__.__annotations__["return"] = rt - - @staticmethod - def _get_global_name(attr_name: str) -> str: - """ - Return the name that a converter for an attribute name *attr_name* - would have. - """ - return f"__attr_converter_{attr_name}" - - def _fmt_converter_call(self, attr_name: str, value_var: str) -> str: - """ - Return a string that calls the converter for an attribute name - *attr_name* and the value in variable named *value_var* according to - `self.takes_self` and `self.takes_field`. - """ - if not (self.takes_self or self.takes_field): - return f"{self._get_global_name(attr_name)}({value_var})" - - if self.takes_self and self.takes_field: - return f"{self._get_global_name(attr_name)}({value_var}, self, attr_dict['{attr_name}'])" - - if self.takes_self: - return f"{self._get_global_name(attr_name)}({value_var}, self)" - - return f"{self._get_global_name(attr_name)}({value_var}, attr_dict['{attr_name}'])" - - def __getstate__(self): - """ - Return a dict containing only converter and takes_self -- the rest gets - computed when loading. - """ - return { - "converter": self.converter, - "takes_self": self.takes_self, - "takes_field": self.takes_field, - } - - def __setstate__(self, state): - """ - Load instance from state. - """ - self.__init__(**state) - - -_f = [ - Attribute( - name=name, - default=NOTHING, - validator=None, - repr=True, - cmp=None, - eq=True, - order=False, - hash=True, - init=True, - inherited=False, - ) - for name in ("converter", "takes_self", "takes_field") -] - -Converter = _add_hash( - _add_eq(_add_repr(Converter, attrs=_f), attrs=_f), attrs=_f -) - - -def make_class( - name, attrs, bases=(object,), class_body=None, **attributes_arguments -): - r""" - A quick way to create a new class called *name* with *attrs*. - - Args: - name (str): The name for the new class. - - attrs( list | dict): - A list of names or a dictionary of mappings of names to `attr.ib`\ - s / `attrs.field`\ s. - - The order is deduced from the order of the names or attributes - inside *attrs*. Otherwise the order of the definition of the - attributes is used. - - bases (tuple[type, ...]): Classes that the new class will subclass. - - class_body (dict): - An optional dictionary of class attributes for the new class. - - attributes_arguments: Passed unmodified to `attr.s`. - - Returns: - type: A new class with *attrs*. - - .. versionadded:: 17.1.0 *bases* - .. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained. - .. versionchanged:: 23.2.0 *class_body* - """ - if isinstance(attrs, dict): - cls_dict = attrs - elif isinstance(attrs, (list, tuple)): - cls_dict = {a: attrib() for a in attrs} - else: - msg = "attrs argument must be a dict or a list." - raise TypeError(msg) - - pre_init = cls_dict.pop("__attrs_pre_init__", None) - post_init = cls_dict.pop("__attrs_post_init__", None) - user_init = cls_dict.pop("__init__", None) - - body = {} - if class_body is not None: - body.update(class_body) - if pre_init is not None: - body["__attrs_pre_init__"] = pre_init - if post_init is not None: - body["__attrs_post_init__"] = post_init - if user_init is not None: - body["__init__"] = user_init - - type_ = types.new_class(name, bases, {}, lambda ns: ns.update(body)) - - # For pickling to work, the __module__ variable needs to be set to the - # frame where the class is created. Bypass this step in environments where - # sys._getframe is not defined (Jython for example) or sys._getframe is not - # defined for arguments greater than 0 (IronPython). - with contextlib.suppress(AttributeError, ValueError): - type_.__module__ = sys._getframe(1).f_globals.get( - "__name__", "__main__" - ) - - # We do it here for proper warnings with meaningful stacklevel. - cmp = attributes_arguments.pop("cmp", None) - ( - attributes_arguments["eq"], - attributes_arguments["order"], - ) = _determine_attrs_eq_order( - cmp, - attributes_arguments.get("eq"), - attributes_arguments.get("order"), - True, - ) - - cls = _attrs(these=cls_dict, **attributes_arguments)(type_) - # Only add type annotations now or "_attrs()" will complain: - cls.__annotations__ = { - k: v.type for k, v in cls_dict.items() if v.type is not None - } - return cls - - -# These are required by within this module so we define them here and merely -# import into .validators / .converters. - - -@attrs(slots=True, unsafe_hash=True) -class _AndValidator: - """ - Compose many validators to a single one. - """ - - _validators = attrib() - - def __call__(self, inst, attr, value): - for v in self._validators: - v(inst, attr, value) - - -def and_(*validators): - """ - A validator that composes multiple validators into one. - - When called on a value, it runs all wrapped validators. - - Args: - validators (~collections.abc.Iterable[typing.Callable]): - Arbitrary number of validators. - - .. versionadded:: 17.1.0 - """ - vals = [] - for validator in validators: - vals.extend( - validator._validators - if isinstance(validator, _AndValidator) - else [validator] - ) - - return _AndValidator(tuple(vals)) - - -def pipe(*converters): - """ - A converter that composes multiple converters into one. - - When called on a value, it runs all wrapped converters, returning the - *last* value. - - Type annotations will be inferred from the wrapped converters', if they - have any. - - converters (~collections.abc.Iterable[typing.Callable]): - Arbitrary number of converters. - - .. versionadded:: 20.1.0 - """ - - def pipe_converter(val, inst, field): - for c in converters: - val = c(val, inst, field) if isinstance(c, Converter) else c(val) - - return val - - if not converters: - # If the converter list is empty, pipe_converter is the identity. - A = typing.TypeVar("A") - pipe_converter.__annotations__.update({"val": A, "return": A}) - else: - # Get parameter type from first converter. - t = _AnnotationExtractor(converters[0]).get_first_param_type() - if t: - pipe_converter.__annotations__["val"] = t - - last = converters[-1] - if not PY_3_11_PLUS and isinstance(last, Converter): - last = last.__call__ - - # Get return type from last converter. - rt = _AnnotationExtractor(last).get_return_type() - if rt: - pipe_converter.__annotations__["return"] = rt - - return Converter(pipe_converter, takes_self=True, takes_field=True) diff --git a/uno/lib/python/attr/_next_gen.py b/uno/lib/python/attr/_next_gen.py deleted file mode 100644 index dbb65cc9..00000000 --- a/uno/lib/python/attr/_next_gen.py +++ /dev/null @@ -1,631 +0,0 @@ -# SPDX-License-Identifier: MIT - -""" -These are keyword-only APIs that call `attr.s` and `attr.ib` with different -default values. -""" - - -from functools import partial - -from . import setters -from ._funcs import asdict as _asdict -from ._funcs import astuple as _astuple -from ._make import ( - _DEFAULT_ON_SETATTR, - NOTHING, - _frozen_setattrs, - attrib, - attrs, -) -from .exceptions import UnannotatedAttributeError - - -def define( - maybe_cls=None, - *, - these=None, - repr=None, - unsafe_hash=None, - hash=None, - init=None, - slots=True, - frozen=False, - weakref_slot=True, - str=False, - auto_attribs=None, - kw_only=False, - cache_hash=False, - auto_exc=True, - eq=None, - order=False, - auto_detect=True, - getstate_setstate=None, - on_setattr=None, - field_transformer=None, - match_args=True, -): - r""" - A class decorator that adds :term:`dunder methods` according to - :term:`fields ` specified using :doc:`type annotations `, - `field()` calls, or the *these* argument. - - Since *attrs* patches or replaces an existing class, you cannot use - `object.__init_subclass__` with *attrs* classes, because it runs too early. - As a replacement, you can define ``__attrs_init_subclass__`` on your class. - It will be called by *attrs* classes that subclass it after they're - created. See also :ref:`init-subclass`. - - Args: - slots (bool): - Create a :term:`slotted class ` that's more - memory-efficient. Slotted classes are generally superior to the - default dict classes, but have some gotchas you should know about, - so we encourage you to read the :term:`glossary entry `. - - auto_detect (bool): - Instead of setting the *init*, *repr*, *eq*, and *hash* arguments - explicitly, assume they are set to True **unless any** of the - involved methods for one of the arguments is implemented in the - *current* class (meaning, it is *not* inherited from some base - class). - - So, for example by implementing ``__eq__`` on a class yourself, - *attrs* will deduce ``eq=False`` and will create *neither* - ``__eq__`` *nor* ``__ne__`` (but Python classes come with a - sensible ``__ne__`` by default, so it *should* be enough to only - implement ``__eq__`` in most cases). - - Passing True or False` to *init*, *repr*, *eq*, *cmp*, or *hash* - overrides whatever *auto_detect* would determine. - - auto_exc (bool): - If the class subclasses `BaseException` (which implicitly includes - any subclass of any exception), the following happens to behave - like a well-behaved Python exception class: - - - the values for *eq*, *order*, and *hash* are ignored and the - instances compare and hash by the instance's ids [#]_ , - - all attributes that are either passed into ``__init__`` or have a - default value are additionally available as a tuple in the - ``args`` attribute, - - the value of *str* is ignored leaving ``__str__`` to base - classes. - - .. [#] - Note that *attrs* will *not* remove existing implementations of - ``__hash__`` or the equality methods. It just won't add own - ones. - - on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]): - A callable that is run whenever the user attempts to set an - attribute (either by assignment like ``i.x = 42`` or by using - `setattr` like ``setattr(i, "x", 42)``). It receives the same - arguments as validators: the instance, the attribute that is being - modified, and the new value. - - If no exception is raised, the attribute is set to the return value - of the callable. - - If a list of callables is passed, they're automatically wrapped in - an `attrs.setters.pipe`. - - If left None, the default behavior is to run converters and - validators whenever an attribute is set. - - init (bool): - Create a ``__init__`` method that initializes the *attrs* - attributes. Leading underscores are stripped for the argument name, - unless an alias is set on the attribute. - - .. seealso:: - `init` shows advanced ways to customize the generated - ``__init__`` method, including executing code before and after. - - repr(bool): - Create a ``__repr__`` method with a human readable representation - of *attrs* attributes. - - str (bool): - Create a ``__str__`` method that is identical to ``__repr__``. This - is usually not necessary except for `Exception`\ s. - - eq (bool | None): - If True or None (default), add ``__eq__`` and ``__ne__`` methods - that check two instances for equality. - - .. seealso:: - `comparison` describes how to customize the comparison behavior - going as far comparing NumPy arrays. - - order (bool | None): - If True, add ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` - methods that behave like *eq* above and allow instances to be - ordered. - - They compare the instances as if they were tuples of their *attrs* - attributes if and only if the types of both classes are - *identical*. - - If `None` mirror value of *eq*. - - .. seealso:: `comparison` - - cmp (bool | None): - Setting *cmp* is equivalent to setting *eq* and *order* to the same - value. Must not be mixed with *eq* or *order*. - - unsafe_hash (bool | None): - If None (default), the ``__hash__`` method is generated according - how *eq* and *frozen* are set. - - 1. If *both* are True, *attrs* will generate a ``__hash__`` for - you. - 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set - to None, marking it unhashable (which it is). - 3. If *eq* is False, ``__hash__`` will be left untouched meaning - the ``__hash__`` method of the base class will be used. If the - base class is `object`, this means it will fall back to id-based - hashing. - - Although not recommended, you can decide for yourself and force - *attrs* to create one (for example, if the class is immutable even - though you didn't freeze it programmatically) by passing True or - not. Both of these cases are rather special and should be used - carefully. - - .. seealso:: - - - Our documentation on `hashing`, - - Python's documentation on `object.__hash__`, - - and the `GitHub issue that led to the default \ behavior - `_ for more - details. - - hash (bool | None): - Deprecated alias for *unsafe_hash*. *unsafe_hash* takes precedence. - - cache_hash (bool): - Ensure that the object's hash code is computed only once and stored - on the object. If this is set to True, hashing must be either - explicitly or implicitly enabled for this class. If the hash code - is cached, avoid any reassignments of fields involved in hash code - computation or mutations of the objects those fields point to after - object creation. If such changes occur, the behavior of the - object's hash code is undefined. - - frozen (bool): - Make instances immutable after initialization. If someone attempts - to modify a frozen instance, `attrs.exceptions.FrozenInstanceError` - is raised. - - .. note:: - - 1. This is achieved by installing a custom ``__setattr__`` - method on your class, so you can't implement your own. - - 2. True immutability is impossible in Python. - - 3. This *does* have a minor a runtime performance `impact - ` when initializing new instances. In other - words: ``__init__`` is slightly slower with ``frozen=True``. - - 4. If a class is frozen, you cannot modify ``self`` in - ``__attrs_post_init__`` or a self-written ``__init__``. You - can circumvent that limitation by using - ``object.__setattr__(self, "attribute_name", value)``. - - 5. Subclasses of a frozen class are frozen too. - - kw_only (bool): - Make all attributes keyword-only in the generated ``__init__`` (if - *init* is False, this parameter is ignored). - - weakref_slot (bool): - Make instances weak-referenceable. This has no effect unless - *slots* is True. - - field_transformer (~typing.Callable | None): - A function that is called with the original class object and all - fields right before *attrs* finalizes the class. You can use this, - for example, to automatically add converters or validators to - fields based on their types. - - .. seealso:: `transform-fields` - - match_args (bool): - If True (default), set ``__match_args__`` on the class to support - :pep:`634` (*Structural Pattern Matching*). It is a tuple of all - non-keyword-only ``__init__`` parameter names on Python 3.10 and - later. Ignored on older Python versions. - - collect_by_mro (bool): - If True, *attrs* collects attributes from base classes correctly - according to the `method resolution order - `_. If False, *attrs* - will mimic the (wrong) behavior of `dataclasses` and :pep:`681`. - - See also `issue #428 - `_. - - getstate_setstate (bool | None): - .. note:: - - This is usually only interesting for slotted classes and you - should probably just set *auto_detect* to True. - - If True, ``__getstate__`` and ``__setstate__`` are generated and - attached to the class. This is necessary for slotted classes to be - pickleable. If left None, it's True by default for slotted classes - and False for dict classes. - - If *auto_detect* is True, and *getstate_setstate* is left None, and - **either** ``__getstate__`` or ``__setstate__`` is detected - directly on the class (meaning: not inherited), it is set to False - (this is usually what you want). - - auto_attribs (bool | None): - If True, look at type annotations to determine which attributes to - use, like `dataclasses`. If False, it will only look for explicit - :func:`field` class attributes, like classic *attrs*. - - If left None, it will guess: - - 1. If any attributes are annotated and no unannotated - `attrs.field`\ s are found, it assumes *auto_attribs=True*. - 2. Otherwise it assumes *auto_attribs=False* and tries to collect - `attrs.field`\ s. - - If *attrs* decides to look at type annotations, **all** fields - **must** be annotated. If *attrs* encounters a field that is set to - a :func:`field` / `attr.ib` but lacks a type annotation, an - `attrs.exceptions.UnannotatedAttributeError` is raised. Use - ``field_name: typing.Any = field(...)`` if you don't want to set a - type. - - .. warning:: - - For features that use the attribute name to create decorators - (for example, :ref:`validators `), you still *must* - assign :func:`field` / `attr.ib` to them. Otherwise Python will - either not find the name or try to use the default value to - call, for example, ``validator`` on it. - - Attributes annotated as `typing.ClassVar`, and attributes that are - neither annotated nor set to an `field()` are **ignored**. - - these (dict[str, object]): - A dictionary of name to the (private) return value of `field()` - mappings. This is useful to avoid the definition of your attributes - within the class body because you can't (for example, if you want - to add ``__repr__`` methods to Django models) or don't want to. - - If *these* is not `None`, *attrs* will *not* search the class body - for attributes and will *not* remove any attributes from it. - - The order is deduced from the order of the attributes inside - *these*. - - Arguably, this is a rather obscure feature. - - .. versionadded:: 20.1.0 - .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``. - .. versionadded:: 22.2.0 - *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance). - .. versionchanged:: 24.1.0 - Instances are not compared as tuples of attributes anymore, but using a - big ``and`` condition. This is faster and has more correct behavior for - uncomparable values like `math.nan`. - .. versionadded:: 24.1.0 - If a class has an *inherited* classmethod called - ``__attrs_init_subclass__``, it is executed after the class is created. - .. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*. - - .. note:: - - The main differences to the classic `attr.s` are: - - - Automatically detect whether or not *auto_attribs* should be `True` - (c.f. *auto_attribs* parameter). - - Converters and validators run when attributes are set by default -- - if *frozen* is `False`. - - *slots=True* - - Usually, this has only upsides and few visible effects in everyday - programming. But it *can* lead to some surprising behaviors, so - please make sure to read :term:`slotted classes`. - - - *auto_exc=True* - - *auto_detect=True* - - *order=False* - - Some options that were only relevant on Python 2 or were kept around - for backwards-compatibility have been removed. - - """ - - def do_it(cls, auto_attribs): - return attrs( - maybe_cls=cls, - these=these, - repr=repr, - hash=hash, - unsafe_hash=unsafe_hash, - init=init, - slots=slots, - frozen=frozen, - weakref_slot=weakref_slot, - str=str, - auto_attribs=auto_attribs, - kw_only=kw_only, - cache_hash=cache_hash, - auto_exc=auto_exc, - eq=eq, - order=order, - auto_detect=auto_detect, - collect_by_mro=True, - getstate_setstate=getstate_setstate, - on_setattr=on_setattr, - field_transformer=field_transformer, - match_args=match_args, - ) - - def wrap(cls): - """ - Making this a wrapper ensures this code runs during class creation. - - We also ensure that frozen-ness of classes is inherited. - """ - nonlocal frozen, on_setattr - - had_on_setattr = on_setattr not in (None, setters.NO_OP) - - # By default, mutable classes convert & validate on setattr. - if frozen is False and on_setattr is None: - on_setattr = _DEFAULT_ON_SETATTR - - # However, if we subclass a frozen class, we inherit the immutability - # and disable on_setattr. - for base_cls in cls.__bases__: - if base_cls.__setattr__ is _frozen_setattrs: - if had_on_setattr: - msg = "Frozen classes can't use on_setattr (frozen-ness was inherited)." - raise ValueError(msg) - - on_setattr = setters.NO_OP - break - - if auto_attribs is not None: - return do_it(cls, auto_attribs) - - try: - return do_it(cls, True) - except UnannotatedAttributeError: - return do_it(cls, False) - - # maybe_cls's type depends on the usage of the decorator. It's a class - # if it's used as `@attrs` but `None` if used as `@attrs()`. - if maybe_cls is None: - return wrap - - return wrap(maybe_cls) - - -mutable = define -frozen = partial(define, frozen=True, on_setattr=None) - - -def field( - *, - default=NOTHING, - validator=None, - repr=True, - hash=None, - init=True, - metadata=None, - type=None, - converter=None, - factory=None, - kw_only=False, - eq=None, - order=None, - on_setattr=None, - alias=None, -): - """ - Create a new :term:`field` / :term:`attribute` on a class. - - .. warning:: - - Does **nothing** unless the class is also decorated with - `attrs.define` (or similar)! - - Args: - default: - A value that is used if an *attrs*-generated ``__init__`` is used - and no value is passed while instantiating or the attribute is - excluded using ``init=False``. - - If the value is an instance of `attrs.Factory`, its callable will - be used to construct a new value (useful for mutable data types - like lists or dicts). - - If a default is not set (or set manually to `attrs.NOTHING`), a - value *must* be supplied when instantiating; otherwise a - `TypeError` will be raised. - - .. seealso:: `defaults` - - factory (~typing.Callable): - Syntactic sugar for ``default=attr.Factory(factory)``. - - validator (~typing.Callable | list[~typing.Callable]): - Callable that is called by *attrs*-generated ``__init__`` methods - after the instance has been initialized. They receive the - initialized instance, the :func:`~attrs.Attribute`, and the passed - value. - - The return value is *not* inspected so the validator has to throw - an exception itself. - - If a `list` is passed, its items are treated as validators and must - all pass. - - Validators can be globally disabled and re-enabled using - `attrs.validators.get_disabled` / `attrs.validators.set_disabled`. - - The validator can also be set using decorator notation as shown - below. - - .. seealso:: :ref:`validators` - - repr (bool | ~typing.Callable): - Include this attribute in the generated ``__repr__`` method. If - True, include the attribute; if False, omit it. By default, the - built-in ``repr()`` function is used. To override how the attribute - value is formatted, pass a ``callable`` that takes a single value - and returns a string. Note that the resulting string is used as-is, - which means it will be used directly *instead* of calling - ``repr()`` (the default). - - eq (bool | ~typing.Callable): - If True (default), include this attribute in the generated - ``__eq__`` and ``__ne__`` methods that check two instances for - equality. To override how the attribute value is compared, pass a - callable that takes a single value and returns the value to be - compared. - - .. seealso:: `comparison` - - order (bool | ~typing.Callable): - If True (default), include this attributes in the generated - ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. To - override how the attribute value is ordered, pass a callable that - takes a single value and returns the value to be ordered. - - .. seealso:: `comparison` - - cmp(bool | ~typing.Callable): - Setting *cmp* is equivalent to setting *eq* and *order* to the same - value. Must not be mixed with *eq* or *order*. - - .. seealso:: `comparison` - - hash (bool | None): - Include this attribute in the generated ``__hash__`` method. If - None (default), mirror *eq*'s value. This is the correct behavior - according the Python spec. Setting this value to anything else - than None is *discouraged*. - - .. seealso:: `hashing` - - init (bool): - Include this attribute in the generated ``__init__`` method. - - It is possible to set this to False and set a default value. In - that case this attributed is unconditionally initialized with the - specified default value or factory. - - .. seealso:: `init` - - converter (typing.Callable | Converter): - A callable that is called by *attrs*-generated ``__init__`` methods - to convert attribute's value to the desired format. - - If a vanilla callable is passed, it is given the passed-in value as - the only positional argument. It is possible to receive additional - arguments by wrapping the callable in a `Converter`. - - Either way, the returned value will be used as the new value of the - attribute. The value is converted before being passed to the - validator, if any. - - .. seealso:: :ref:`converters` - - metadata (dict | None): - An arbitrary mapping, to be used by third-party code. - - .. seealso:: `extending-metadata`. - - type (type): - The type of the attribute. Nowadays, the preferred method to - specify the type is using a variable annotation (see :pep:`526`). - This argument is provided for backwards-compatibility and for usage - with `make_class`. Regardless of the approach used, the type will - be stored on ``Attribute.type``. - - Please note that *attrs* doesn't do anything with this metadata by - itself. You can use it as part of your own code or for `static type - checking `. - - kw_only (bool): - Make this attribute keyword-only in the generated ``__init__`` (if - ``init`` is False, this parameter is ignored). - - on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]): - Allows to overwrite the *on_setattr* setting from `attr.s`. If left - None, the *on_setattr* value from `attr.s` is used. Set to - `attrs.setters.NO_OP` to run **no** `setattr` hooks for this - attribute -- regardless of the setting in `define()`. - - alias (str | None): - Override this attribute's parameter name in the generated - ``__init__`` method. If left None, default to ``name`` stripped - of leading underscores. See `private-attributes`. - - .. versionadded:: 20.1.0 - .. versionchanged:: 21.1.0 - *eq*, *order*, and *cmp* also accept a custom callable - .. versionadded:: 22.2.0 *alias* - .. versionadded:: 23.1.0 - The *type* parameter has been re-added; mostly for `attrs.make_class`. - Please note that type checkers ignore this metadata. - - .. seealso:: - - `attr.ib` - """ - return attrib( - default=default, - validator=validator, - repr=repr, - hash=hash, - init=init, - metadata=metadata, - type=type, - converter=converter, - factory=factory, - kw_only=kw_only, - eq=eq, - order=order, - on_setattr=on_setattr, - alias=alias, - ) - - -def asdict(inst, *, recurse=True, filter=None, value_serializer=None): - """ - Same as `attr.asdict`, except that collections types are always retained - and dict is always used as *dict_factory*. - - .. versionadded:: 21.3.0 - """ - return _asdict( - inst=inst, - recurse=recurse, - filter=filter, - value_serializer=value_serializer, - retain_collection_types=True, - ) - - -def astuple(inst, *, recurse=True, filter=None): - """ - Same as `attr.astuple`, except that collections types are always retained - and `tuple` is always used as the *tuple_factory*. - - .. versionadded:: 21.3.0 - """ - return _astuple( - inst=inst, recurse=recurse, filter=filter, retain_collection_types=True - ) diff --git a/uno/lib/python/attr/_typing_compat.pyi b/uno/lib/python/attr/_typing_compat.pyi deleted file mode 100644 index ca7b71e9..00000000 --- a/uno/lib/python/attr/_typing_compat.pyi +++ /dev/null @@ -1,15 +0,0 @@ -from typing import Any, ClassVar, Protocol - -# MYPY is a special constant in mypy which works the same way as `TYPE_CHECKING`. -MYPY = False - -if MYPY: - # A protocol to be able to statically accept an attrs class. - class AttrsInstance_(Protocol): - __attrs_attrs__: ClassVar[Any] - -else: - # For type checkers without plug-in support use an empty protocol that - # will (hopefully) be combined into a union. - class AttrsInstance_(Protocol): - pass diff --git a/uno/lib/python/attr/_version_info.py b/uno/lib/python/attr/_version_info.py deleted file mode 100644 index 51a1312f..00000000 --- a/uno/lib/python/attr/_version_info.py +++ /dev/null @@ -1,86 +0,0 @@ -# SPDX-License-Identifier: MIT - - -from functools import total_ordering - -from ._funcs import astuple -from ._make import attrib, attrs - - -@total_ordering -@attrs(eq=False, order=False, slots=True, frozen=True) -class VersionInfo: - """ - A version object that can be compared to tuple of length 1--4: - - >>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2) - True - >>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1) - True - >>> vi = attr.VersionInfo(19, 2, 0, "final") - >>> vi < (19, 1, 1) - False - >>> vi < (19,) - False - >>> vi == (19, 2,) - True - >>> vi == (19, 2, 1) - False - - .. versionadded:: 19.2 - """ - - year = attrib(type=int) - minor = attrib(type=int) - micro = attrib(type=int) - releaselevel = attrib(type=str) - - @classmethod - def _from_version_string(cls, s): - """ - Parse *s* and return a _VersionInfo. - """ - v = s.split(".") - if len(v) == 3: - v.append("final") - - return cls( - year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3] - ) - - def _ensure_tuple(self, other): - """ - Ensure *other* is a tuple of a valid length. - - Returns a possibly transformed *other* and ourselves as a tuple of - the same length as *other*. - """ - - if self.__class__ is other.__class__: - other = astuple(other) - - if not isinstance(other, tuple): - raise NotImplementedError - - if not (1 <= len(other) <= 4): - raise NotImplementedError - - return astuple(self)[: len(other)], other - - def __eq__(self, other): - try: - us, them = self._ensure_tuple(other) - except NotImplementedError: - return NotImplemented - - return us == them - - def __lt__(self, other): - try: - us, them = self._ensure_tuple(other) - except NotImplementedError: - return NotImplemented - - # Since alphabetically "dev0" < "final" < "post1" < "post2", we don't - # have to do anything special with releaselevel for now. - return us < them diff --git a/uno/lib/python/attr/_version_info.pyi b/uno/lib/python/attr/_version_info.pyi deleted file mode 100644 index 45ced086..00000000 --- a/uno/lib/python/attr/_version_info.pyi +++ /dev/null @@ -1,9 +0,0 @@ -class VersionInfo: - @property - def year(self) -> int: ... - @property - def minor(self) -> int: ... - @property - def micro(self) -> int: ... - @property - def releaselevel(self) -> str: ... diff --git a/uno/lib/python/attr/converters.py b/uno/lib/python/attr/converters.py deleted file mode 100644 index 92383110..00000000 --- a/uno/lib/python/attr/converters.py +++ /dev/null @@ -1,151 +0,0 @@ -# SPDX-License-Identifier: MIT - -""" -Commonly useful converters. -""" - - -import typing - -from ._compat import _AnnotationExtractor -from ._make import NOTHING, Factory, pipe - - -__all__ = [ - "default_if_none", - "optional", - "pipe", - "to_bool", -] - - -def optional(converter): - """ - A converter that allows an attribute to be optional. An optional attribute - is one which can be set to `None`. - - Type annotations will be inferred from the wrapped converter's, if it has - any. - - Args: - converter (typing.Callable): - the converter that is used for non-`None` values. - - .. versionadded:: 17.1.0 - """ - - def optional_converter(val): - if val is None: - return None - return converter(val) - - xtr = _AnnotationExtractor(converter) - - t = xtr.get_first_param_type() - if t: - optional_converter.__annotations__["val"] = typing.Optional[t] - - rt = xtr.get_return_type() - if rt: - optional_converter.__annotations__["return"] = typing.Optional[rt] - - return optional_converter - - -def default_if_none(default=NOTHING, factory=None): - """ - A converter that allows to replace `None` values by *default* or the result - of *factory*. - - Args: - default: - Value to be used if `None` is passed. Passing an instance of - `attrs.Factory` is supported, however the ``takes_self`` option is - *not*. - - factory (typing.Callable): - A callable that takes no parameters whose result is used if `None` - is passed. - - Raises: - TypeError: If **neither** *default* or *factory* is passed. - - TypeError: If **both** *default* and *factory* are passed. - - ValueError: - If an instance of `attrs.Factory` is passed with - ``takes_self=True``. - - .. versionadded:: 18.2.0 - """ - if default is NOTHING and factory is None: - msg = "Must pass either `default` or `factory`." - raise TypeError(msg) - - if default is not NOTHING and factory is not None: - msg = "Must pass either `default` or `factory` but not both." - raise TypeError(msg) - - if factory is not None: - default = Factory(factory) - - if isinstance(default, Factory): - if default.takes_self: - msg = "`takes_self` is not supported by default_if_none." - raise ValueError(msg) - - def default_if_none_converter(val): - if val is not None: - return val - - return default.factory() - - else: - - def default_if_none_converter(val): - if val is not None: - return val - - return default - - return default_if_none_converter - - -def to_bool(val): - """ - Convert "boolean" strings (for example, from environment variables) to real - booleans. - - Values mapping to `True`: - - - ``True`` - - ``"true"`` / ``"t"`` - - ``"yes"`` / ``"y"`` - - ``"on"`` - - ``"1"`` - - ``1`` - - Values mapping to `False`: - - - ``False`` - - ``"false"`` / ``"f"`` - - ``"no"`` / ``"n"`` - - ``"off"`` - - ``"0"`` - - ``0`` - - Raises: - ValueError: For any other value. - - .. versionadded:: 21.3.0 - """ - if isinstance(val, str): - val = val.lower() - - if val in (True, "true", "t", "yes", "y", "on", "1", 1): - return True - if val in (False, "false", "f", "no", "n", "off", "0", 0): - return False - - msg = f"Cannot convert value to bool: {val!r}" - raise ValueError(msg) diff --git a/uno/lib/python/attr/converters.pyi b/uno/lib/python/attr/converters.pyi deleted file mode 100644 index 9ef478f2..00000000 --- a/uno/lib/python/attr/converters.pyi +++ /dev/null @@ -1,13 +0,0 @@ -from typing import Callable, TypeVar, overload - -from attrs import _ConverterType - -_T = TypeVar("_T") - -def pipe(*validators: _ConverterType) -> _ConverterType: ... -def optional(converter: _ConverterType) -> _ConverterType: ... -@overload -def default_if_none(default: _T) -> _ConverterType: ... -@overload -def default_if_none(*, factory: Callable[[], _T]) -> _ConverterType: ... -def to_bool(val: str) -> bool: ... diff --git a/uno/lib/python/attr/exceptions.py b/uno/lib/python/attr/exceptions.py deleted file mode 100644 index 3b7abb81..00000000 --- a/uno/lib/python/attr/exceptions.py +++ /dev/null @@ -1,95 +0,0 @@ -# SPDX-License-Identifier: MIT - -from __future__ import annotations - -from typing import ClassVar - - -class FrozenError(AttributeError): - """ - A frozen/immutable instance or attribute have been attempted to be - modified. - - It mirrors the behavior of ``namedtuples`` by using the same error message - and subclassing `AttributeError`. - - .. versionadded:: 20.1.0 - """ - - msg = "can't set attribute" - args: ClassVar[tuple[str]] = [msg] - - -class FrozenInstanceError(FrozenError): - """ - A frozen instance has been attempted to be modified. - - .. versionadded:: 16.1.0 - """ - - -class FrozenAttributeError(FrozenError): - """ - A frozen attribute has been attempted to be modified. - - .. versionadded:: 20.1.0 - """ - - -class AttrsAttributeNotFoundError(ValueError): - """ - An *attrs* function couldn't find an attribute that the user asked for. - - .. versionadded:: 16.2.0 - """ - - -class NotAnAttrsClassError(ValueError): - """ - A non-*attrs* class has been passed into an *attrs* function. - - .. versionadded:: 16.2.0 - """ - - -class DefaultAlreadySetError(RuntimeError): - """ - A default has been set when defining the field and is attempted to be reset - using the decorator. - - .. versionadded:: 17.1.0 - """ - - -class UnannotatedAttributeError(RuntimeError): - """ - A class with ``auto_attribs=True`` has a field without a type annotation. - - .. versionadded:: 17.3.0 - """ - - -class PythonTooOldError(RuntimeError): - """ - It was attempted to use an *attrs* feature that requires a newer Python - version. - - .. versionadded:: 18.2.0 - """ - - -class NotCallableError(TypeError): - """ - A field requiring a callable has been set with a value that is not - callable. - - .. versionadded:: 19.2.0 - """ - - def __init__(self, msg, value): - super(TypeError, self).__init__(msg, value) - self.msg = msg - self.value = value - - def __str__(self): - return str(self.msg) diff --git a/uno/lib/python/attr/exceptions.pyi b/uno/lib/python/attr/exceptions.pyi deleted file mode 100644 index f2680118..00000000 --- a/uno/lib/python/attr/exceptions.pyi +++ /dev/null @@ -1,17 +0,0 @@ -from typing import Any - -class FrozenError(AttributeError): - msg: str = ... - -class FrozenInstanceError(FrozenError): ... -class FrozenAttributeError(FrozenError): ... -class AttrsAttributeNotFoundError(ValueError): ... -class NotAnAttrsClassError(ValueError): ... -class DefaultAlreadySetError(RuntimeError): ... -class UnannotatedAttributeError(RuntimeError): ... -class PythonTooOldError(RuntimeError): ... - -class NotCallableError(TypeError): - msg: str = ... - value: Any = ... - def __init__(self, msg: str, value: Any) -> None: ... diff --git a/uno/lib/python/attr/filters.py b/uno/lib/python/attr/filters.py deleted file mode 100644 index 689b1705..00000000 --- a/uno/lib/python/attr/filters.py +++ /dev/null @@ -1,72 +0,0 @@ -# SPDX-License-Identifier: MIT - -""" -Commonly useful filters for `attrs.asdict` and `attrs.astuple`. -""" - -from ._make import Attribute - - -def _split_what(what): - """ - Returns a tuple of `frozenset`s of classes and attributes. - """ - return ( - frozenset(cls for cls in what if isinstance(cls, type)), - frozenset(cls for cls in what if isinstance(cls, str)), - frozenset(cls for cls in what if isinstance(cls, Attribute)), - ) - - -def include(*what): - """ - Create a filter that only allows *what*. - - Args: - what (list[type, str, attrs.Attribute]): - What to include. Can be a type, a name, or an attribute. - - Returns: - Callable: - A callable that can be passed to `attrs.asdict`'s and - `attrs.astuple`'s *filter* argument. - - .. versionchanged:: 23.1.0 Accept strings with field names. - """ - cls, names, attrs = _split_what(what) - - def include_(attribute, value): - return ( - value.__class__ in cls - or attribute.name in names - or attribute in attrs - ) - - return include_ - - -def exclude(*what): - """ - Create a filter that does **not** allow *what*. - - Args: - what (list[type, str, attrs.Attribute]): - What to exclude. Can be a type, a name, or an attribute. - - Returns: - Callable: - A callable that can be passed to `attrs.asdict`'s and - `attrs.astuple`'s *filter* argument. - - .. versionchanged:: 23.3.0 Accept field name string as input argument - """ - cls, names, attrs = _split_what(what) - - def exclude_(attribute, value): - return not ( - value.__class__ in cls - or attribute.name in names - or attribute in attrs - ) - - return exclude_ diff --git a/uno/lib/python/attr/filters.pyi b/uno/lib/python/attr/filters.pyi deleted file mode 100644 index 974abdcd..00000000 --- a/uno/lib/python/attr/filters.pyi +++ /dev/null @@ -1,6 +0,0 @@ -from typing import Any - -from . import Attribute, _FilterType - -def include(*what: type | str | Attribute[Any]) -> _FilterType[Any]: ... -def exclude(*what: type | str | Attribute[Any]) -> _FilterType[Any]: ... diff --git a/uno/lib/python/attr/py.typed b/uno/lib/python/attr/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/lib/python/attr/setters.py b/uno/lib/python/attr/setters.py deleted file mode 100644 index a9ce0169..00000000 --- a/uno/lib/python/attr/setters.py +++ /dev/null @@ -1,79 +0,0 @@ -# SPDX-License-Identifier: MIT - -""" -Commonly used hooks for on_setattr. -""" - -from . import _config -from .exceptions import FrozenAttributeError - - -def pipe(*setters): - """ - Run all *setters* and return the return value of the last one. - - .. versionadded:: 20.1.0 - """ - - def wrapped_pipe(instance, attrib, new_value): - rv = new_value - - for setter in setters: - rv = setter(instance, attrib, rv) - - return rv - - return wrapped_pipe - - -def frozen(_, __, ___): - """ - Prevent an attribute to be modified. - - .. versionadded:: 20.1.0 - """ - raise FrozenAttributeError() - - -def validate(instance, attrib, new_value): - """ - Run *attrib*'s validator on *new_value* if it has one. - - .. versionadded:: 20.1.0 - """ - if _config._run_validators is False: - return new_value - - v = attrib.validator - if not v: - return new_value - - v(instance, attrib, new_value) - - return new_value - - -def convert(instance, attrib, new_value): - """ - Run *attrib*'s converter -- if it has one -- on *new_value* and return the - result. - - .. versionadded:: 20.1.0 - """ - c = attrib.converter - if c: - # This can be removed once we drop 3.8 and use attrs.Converter instead. - from ._make import Converter - - if not isinstance(c, Converter): - return c(new_value) - - return c(new_value, instance, attrib) - - return new_value - - -# Sentinel for disabling class-wide *on_setattr* hooks for certain attributes. -# Sphinx's autodata stopped working, so the docstring is inlined in the API -# docs. -NO_OP = object() diff --git a/uno/lib/python/attr/setters.pyi b/uno/lib/python/attr/setters.pyi deleted file mode 100644 index 73abf36e..00000000 --- a/uno/lib/python/attr/setters.pyi +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Any, NewType, NoReturn, TypeVar - -from . import Attribute -from attrs import _OnSetAttrType - -_T = TypeVar("_T") - -def frozen( - instance: Any, attribute: Attribute[Any], new_value: Any -) -> NoReturn: ... -def pipe(*setters: _OnSetAttrType) -> _OnSetAttrType: ... -def validate(instance: Any, attribute: Attribute[_T], new_value: _T) -> _T: ... - -# convert is allowed to return Any, because they can be chained using pipe. -def convert( - instance: Any, attribute: Attribute[Any], new_value: Any -) -> Any: ... - -_NoOpType = NewType("_NoOpType", object) -NO_OP: _NoOpType diff --git a/uno/lib/python/attr/validators.py b/uno/lib/python/attr/validators.py deleted file mode 100644 index 8a56717d..00000000 --- a/uno/lib/python/attr/validators.py +++ /dev/null @@ -1,711 +0,0 @@ -# SPDX-License-Identifier: MIT - -""" -Commonly useful validators. -""" - - -import operator -import re - -from contextlib import contextmanager -from re import Pattern - -from ._config import get_run_validators, set_run_validators -from ._make import _AndValidator, and_, attrib, attrs -from .converters import default_if_none -from .exceptions import NotCallableError - - -__all__ = [ - "and_", - "deep_iterable", - "deep_mapping", - "disabled", - "ge", - "get_disabled", - "gt", - "in_", - "instance_of", - "is_callable", - "le", - "lt", - "matches_re", - "max_len", - "min_len", - "not_", - "optional", - "or_", - "set_disabled", -] - - -def set_disabled(disabled): - """ - Globally disable or enable running validators. - - By default, they are run. - - Args: - disabled (bool): If `True`, disable running all validators. - - .. warning:: - - This function is not thread-safe! - - .. versionadded:: 21.3.0 - """ - set_run_validators(not disabled) - - -def get_disabled(): - """ - Return a bool indicating whether validators are currently disabled or not. - - Returns: - bool:`True` if validators are currently disabled. - - .. versionadded:: 21.3.0 - """ - return not get_run_validators() - - -@contextmanager -def disabled(): - """ - Context manager that disables running validators within its context. - - .. warning:: - - This context manager is not thread-safe! - - .. versionadded:: 21.3.0 - """ - set_run_validators(False) - try: - yield - finally: - set_run_validators(True) - - -@attrs(repr=False, slots=True, unsafe_hash=True) -class _InstanceOfValidator: - type = attrib() - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if not isinstance(value, self.type): - msg = f"'{attr.name}' must be {self.type!r} (got {value!r} that is a {value.__class__!r})." - raise TypeError( - msg, - attr, - self.type, - value, - ) - - def __repr__(self): - return f"" - - -def instance_of(type): - """ - A validator that raises a `TypeError` if the initializer is called with a - wrong type for this particular attribute (checks are performed using - `isinstance` therefore it's also valid to pass a tuple of types). - - Args: - type (type | tuple[type]): The type to check for. - - Raises: - TypeError: - With a human readable error message, the attribute (of type - `attrs.Attribute`), the expected type, and the value it got. - """ - return _InstanceOfValidator(type) - - -@attrs(repr=False, frozen=True, slots=True) -class _MatchesReValidator: - pattern = attrib() - match_func = attrib() - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if not self.match_func(value): - msg = f"'{attr.name}' must match regex {self.pattern.pattern!r} ({value!r} doesn't)" - raise ValueError( - msg, - attr, - self.pattern, - value, - ) - - def __repr__(self): - return f"" - - -def matches_re(regex, flags=0, func=None): - r""" - A validator that raises `ValueError` if the initializer is called with a - string that doesn't match *regex*. - - Args: - regex (str, re.Pattern): - A regex string or precompiled pattern to match against - - flags (int): - Flags that will be passed to the underlying re function (default 0) - - func (typing.Callable): - Which underlying `re` function to call. Valid options are - `re.fullmatch`, `re.search`, and `re.match`; the default `None` - means `re.fullmatch`. For performance reasons, the pattern is - always precompiled using `re.compile`. - - .. versionadded:: 19.2.0 - .. versionchanged:: 21.3.0 *regex* can be a pre-compiled pattern. - """ - valid_funcs = (re.fullmatch, None, re.search, re.match) - if func not in valid_funcs: - msg = "'func' must be one of {}.".format( - ", ".join( - sorted(e and e.__name__ or "None" for e in set(valid_funcs)) - ) - ) - raise ValueError(msg) - - if isinstance(regex, Pattern): - if flags: - msg = "'flags' can only be used with a string pattern; pass flags to re.compile() instead" - raise TypeError(msg) - pattern = regex - else: - pattern = re.compile(regex, flags) - - if func is re.match: - match_func = pattern.match - elif func is re.search: - match_func = pattern.search - else: - match_func = pattern.fullmatch - - return _MatchesReValidator(pattern, match_func) - - -@attrs(repr=False, slots=True, unsafe_hash=True) -class _OptionalValidator: - validator = attrib() - - def __call__(self, inst, attr, value): - if value is None: - return - - self.validator(inst, attr, value) - - def __repr__(self): - return f"" - - -def optional(validator): - """ - A validator that makes an attribute optional. An optional attribute is one - which can be set to `None` in addition to satisfying the requirements of - the sub-validator. - - Args: - validator - (typing.Callable | tuple[typing.Callable] | list[typing.Callable]): - A validator (or validators) that is used for non-`None` values. - - .. versionadded:: 15.1.0 - .. versionchanged:: 17.1.0 *validator* can be a list of validators. - .. versionchanged:: 23.1.0 *validator* can also be a tuple of validators. - """ - if isinstance(validator, (list, tuple)): - return _OptionalValidator(_AndValidator(validator)) - - return _OptionalValidator(validator) - - -@attrs(repr=False, slots=True, unsafe_hash=True) -class _InValidator: - options = attrib() - _original_options = attrib(hash=False) - - def __call__(self, inst, attr, value): - try: - in_options = value in self.options - except TypeError: # e.g. `1 in "abc"` - in_options = False - - if not in_options: - msg = f"'{attr.name}' must be in {self._original_options!r} (got {value!r})" - raise ValueError( - msg, - attr, - self._original_options, - value, - ) - - def __repr__(self): - return f"" - - -def in_(options): - """ - A validator that raises a `ValueError` if the initializer is called with a - value that does not belong in the *options* provided. - - The check is performed using ``value in options``, so *options* has to - support that operation. - - To keep the validator hashable, dicts, lists, and sets are transparently - transformed into a `tuple`. - - Args: - options: Allowed options. - - Raises: - ValueError: - With a human readable error message, the attribute (of type - `attrs.Attribute`), the expected options, and the value it got. - - .. versionadded:: 17.1.0 - .. versionchanged:: 22.1.0 - The ValueError was incomplete until now and only contained the human - readable error message. Now it contains all the information that has - been promised since 17.1.0. - .. versionchanged:: 24.1.0 - *options* that are a list, dict, or a set are now transformed into a - tuple to keep the validator hashable. - """ - repr_options = options - if isinstance(options, (list, dict, set)): - options = tuple(options) - - return _InValidator(options, repr_options) - - -@attrs(repr=False, slots=False, unsafe_hash=True) -class _IsCallableValidator: - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if not callable(value): - message = ( - "'{name}' must be callable " - "(got {value!r} that is a {actual!r})." - ) - raise NotCallableError( - msg=message.format( - name=attr.name, value=value, actual=value.__class__ - ), - value=value, - ) - - def __repr__(self): - return "" - - -def is_callable(): - """ - A validator that raises a `attrs.exceptions.NotCallableError` if the - initializer is called with a value for this particular attribute that is - not callable. - - .. versionadded:: 19.1.0 - - Raises: - attrs.exceptions.NotCallableError: - With a human readable error message containing the attribute - (`attrs.Attribute`) name, and the value it got. - """ - return _IsCallableValidator() - - -@attrs(repr=False, slots=True, unsafe_hash=True) -class _DeepIterable: - member_validator = attrib(validator=is_callable()) - iterable_validator = attrib( - default=None, validator=optional(is_callable()) - ) - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if self.iterable_validator is not None: - self.iterable_validator(inst, attr, value) - - for member in value: - self.member_validator(inst, attr, member) - - def __repr__(self): - iterable_identifier = ( - "" - if self.iterable_validator is None - else f" {self.iterable_validator!r}" - ) - return ( - f"" - ) - - -def deep_iterable(member_validator, iterable_validator=None): - """ - A validator that performs deep validation of an iterable. - - Args: - member_validator: Validator to apply to iterable members. - - iterable_validator: - Validator to apply to iterable itself (optional). - - Raises - TypeError: if any sub-validators fail - - .. versionadded:: 19.1.0 - """ - if isinstance(member_validator, (list, tuple)): - member_validator = and_(*member_validator) - return _DeepIterable(member_validator, iterable_validator) - - -@attrs(repr=False, slots=True, unsafe_hash=True) -class _DeepMapping: - key_validator = attrib(validator=is_callable()) - value_validator = attrib(validator=is_callable()) - mapping_validator = attrib(default=None, validator=optional(is_callable())) - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if self.mapping_validator is not None: - self.mapping_validator(inst, attr, value) - - for key in value: - self.key_validator(inst, attr, key) - self.value_validator(inst, attr, value[key]) - - def __repr__(self): - return f"" - - -def deep_mapping(key_validator, value_validator, mapping_validator=None): - """ - A validator that performs deep validation of a dictionary. - - Args: - key_validator: Validator to apply to dictionary keys. - - value_validator: Validator to apply to dictionary values. - - mapping_validator: - Validator to apply to top-level mapping attribute (optional). - - .. versionadded:: 19.1.0 - - Raises: - TypeError: if any sub-validators fail - """ - return _DeepMapping(key_validator, value_validator, mapping_validator) - - -@attrs(repr=False, frozen=True, slots=True) -class _NumberValidator: - bound = attrib() - compare_op = attrib() - compare_func = attrib() - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if not self.compare_func(value, self.bound): - msg = f"'{attr.name}' must be {self.compare_op} {self.bound}: {value}" - raise ValueError(msg) - - def __repr__(self): - return f"" - - -def lt(val): - """ - A validator that raises `ValueError` if the initializer is called with a - number larger or equal to *val*. - - The validator uses `operator.lt` to compare the values. - - Args: - val: Exclusive upper bound for values. - - .. versionadded:: 21.3.0 - """ - return _NumberValidator(val, "<", operator.lt) - - -def le(val): - """ - A validator that raises `ValueError` if the initializer is called with a - number greater than *val*. - - The validator uses `operator.le` to compare the values. - - Args: - val: Inclusive upper bound for values. - - .. versionadded:: 21.3.0 - """ - return _NumberValidator(val, "<=", operator.le) - - -def ge(val): - """ - A validator that raises `ValueError` if the initializer is called with a - number smaller than *val*. - - The validator uses `operator.ge` to compare the values. - - Args: - val: Inclusive lower bound for values - - .. versionadded:: 21.3.0 - """ - return _NumberValidator(val, ">=", operator.ge) - - -def gt(val): - """ - A validator that raises `ValueError` if the initializer is called with a - number smaller or equal to *val*. - - The validator uses `operator.ge` to compare the values. - - Args: - val: Exclusive lower bound for values - - .. versionadded:: 21.3.0 - """ - return _NumberValidator(val, ">", operator.gt) - - -@attrs(repr=False, frozen=True, slots=True) -class _MaxLengthValidator: - max_length = attrib() - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if len(value) > self.max_length: - msg = f"Length of '{attr.name}' must be <= {self.max_length}: {len(value)}" - raise ValueError(msg) - - def __repr__(self): - return f"" - - -def max_len(length): - """ - A validator that raises `ValueError` if the initializer is called - with a string or iterable that is longer than *length*. - - Args: - length (int): Maximum length of the string or iterable - - .. versionadded:: 21.3.0 - """ - return _MaxLengthValidator(length) - - -@attrs(repr=False, frozen=True, slots=True) -class _MinLengthValidator: - min_length = attrib() - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if len(value) < self.min_length: - msg = f"Length of '{attr.name}' must be >= {self.min_length}: {len(value)}" - raise ValueError(msg) - - def __repr__(self): - return f"" - - -def min_len(length): - """ - A validator that raises `ValueError` if the initializer is called - with a string or iterable that is shorter than *length*. - - Args: - length (int): Minimum length of the string or iterable - - .. versionadded:: 22.1.0 - """ - return _MinLengthValidator(length) - - -@attrs(repr=False, slots=True, unsafe_hash=True) -class _SubclassOfValidator: - type = attrib() - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if not issubclass(value, self.type): - msg = f"'{attr.name}' must be a subclass of {self.type!r} (got {value!r})." - raise TypeError( - msg, - attr, - self.type, - value, - ) - - def __repr__(self): - return f"" - - -def _subclass_of(type): - """ - A validator that raises a `TypeError` if the initializer is called with a - wrong type for this particular attribute (checks are performed using - `issubclass` therefore it's also valid to pass a tuple of types). - - Args: - type (type | tuple[type, ...]): The type(s) to check for. - - Raises: - TypeError: - With a human readable error message, the attribute (of type - `attrs.Attribute`), the expected type, and the value it got. - """ - return _SubclassOfValidator(type) - - -@attrs(repr=False, slots=True, unsafe_hash=True) -class _NotValidator: - validator = attrib() - msg = attrib( - converter=default_if_none( - "not_ validator child '{validator!r}' " - "did not raise a captured error" - ) - ) - exc_types = attrib( - validator=deep_iterable( - member_validator=_subclass_of(Exception), - iterable_validator=instance_of(tuple), - ), - ) - - def __call__(self, inst, attr, value): - try: - self.validator(inst, attr, value) - except self.exc_types: - pass # suppress error to invert validity - else: - raise ValueError( - self.msg.format( - validator=self.validator, - exc_types=self.exc_types, - ), - attr, - self.validator, - value, - self.exc_types, - ) - - def __repr__(self): - return f"" - - -def not_(validator, *, msg=None, exc_types=(ValueError, TypeError)): - """ - A validator that wraps and logically 'inverts' the validator passed to it. - It will raise a `ValueError` if the provided validator *doesn't* raise a - `ValueError` or `TypeError` (by default), and will suppress the exception - if the provided validator *does*. - - Intended to be used with existing validators to compose logic without - needing to create inverted variants, for example, ``not_(in_(...))``. - - Args: - validator: A validator to be logically inverted. - - msg (str): - Message to raise if validator fails. Formatted with keys - ``exc_types`` and ``validator``. - - exc_types (tuple[type, ...]): - Exception type(s) to capture. Other types raised by child - validators will not be intercepted and pass through. - - Raises: - ValueError: - With a human readable error message, the attribute (of type - `attrs.Attribute`), the validator that failed to raise an - exception, the value it got, and the expected exception types. - - .. versionadded:: 22.2.0 - """ - try: - exc_types = tuple(exc_types) - except TypeError: - exc_types = (exc_types,) - return _NotValidator(validator, msg, exc_types) - - -@attrs(repr=False, slots=True, unsafe_hash=True) -class _OrValidator: - validators = attrib() - - def __call__(self, inst, attr, value): - for v in self.validators: - try: - v(inst, attr, value) - except Exception: # noqa: BLE001, PERF203, S112 - continue - else: - return - - msg = f"None of {self.validators!r} satisfied for value {value!r}" - raise ValueError(msg) - - def __repr__(self): - return f"" - - -def or_(*validators): - """ - A validator that composes multiple validators into one. - - When called on a value, it runs all wrapped validators until one of them is - satisfied. - - Args: - validators (~collections.abc.Iterable[typing.Callable]): - Arbitrary number of validators. - - Raises: - ValueError: - If no validator is satisfied. Raised with a human-readable error - message listing all the wrapped validators and the value that - failed all of them. - - .. versionadded:: 24.1.0 - """ - vals = [] - for v in validators: - vals.extend(v.validators if isinstance(v, _OrValidator) else [v]) - - return _OrValidator(tuple(vals)) diff --git a/uno/lib/python/attr/validators.pyi b/uno/lib/python/attr/validators.pyi deleted file mode 100644 index a314110e..00000000 --- a/uno/lib/python/attr/validators.pyi +++ /dev/null @@ -1,83 +0,0 @@ -from typing import ( - Any, - AnyStr, - Callable, - Container, - ContextManager, - Iterable, - Mapping, - Match, - Pattern, - TypeVar, - overload, -) - -from attrs import _ValidatorType -from attrs import _ValidatorArgType - -_T = TypeVar("_T") -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") -_T3 = TypeVar("_T3") -_I = TypeVar("_I", bound=Iterable) -_K = TypeVar("_K") -_V = TypeVar("_V") -_M = TypeVar("_M", bound=Mapping) - -def set_disabled(run: bool) -> None: ... -def get_disabled() -> bool: ... -def disabled() -> ContextManager[None]: ... - -# To be more precise on instance_of use some overloads. -# If there are more than 3 items in the tuple then we fall back to Any -@overload -def instance_of(type: type[_T]) -> _ValidatorType[_T]: ... -@overload -def instance_of(type: tuple[type[_T]]) -> _ValidatorType[_T]: ... -@overload -def instance_of( - type: tuple[type[_T1], type[_T2]] -) -> _ValidatorType[_T1 | _T2]: ... -@overload -def instance_of( - type: tuple[type[_T1], type[_T2], type[_T3]] -) -> _ValidatorType[_T1 | _T2 | _T3]: ... -@overload -def instance_of(type: tuple[type, ...]) -> _ValidatorType[Any]: ... -def optional( - validator: ( - _ValidatorType[_T] - | list[_ValidatorType[_T]] - | tuple[_ValidatorType[_T]] - ), -) -> _ValidatorType[_T | None]: ... -def in_(options: Container[_T]) -> _ValidatorType[_T]: ... -def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ... -def matches_re( - regex: Pattern[AnyStr] | AnyStr, - flags: int = ..., - func: Callable[[AnyStr, AnyStr, int], Match[AnyStr] | None] | None = ..., -) -> _ValidatorType[AnyStr]: ... -def deep_iterable( - member_validator: _ValidatorArgType[_T], - iterable_validator: _ValidatorType[_I] | None = ..., -) -> _ValidatorType[_I]: ... -def deep_mapping( - key_validator: _ValidatorType[_K], - value_validator: _ValidatorType[_V], - mapping_validator: _ValidatorType[_M] | None = ..., -) -> _ValidatorType[_M]: ... -def is_callable() -> _ValidatorType[_T]: ... -def lt(val: _T) -> _ValidatorType[_T]: ... -def le(val: _T) -> _ValidatorType[_T]: ... -def ge(val: _T) -> _ValidatorType[_T]: ... -def gt(val: _T) -> _ValidatorType[_T]: ... -def max_len(length: int) -> _ValidatorType[_T]: ... -def min_len(length: int) -> _ValidatorType[_T]: ... -def not_( - validator: _ValidatorType[_T], - *, - msg: str | None = None, - exc_types: type[Exception] | Iterable[type[Exception]] = ..., -) -> _ValidatorType[_T]: ... -def or_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ... diff --git a/uno/lib/python/attrs-24.2.0.dist-info/METADATA b/uno/lib/python/attrs-24.2.0.dist-info/METADATA deleted file mode 100644 index a85b3786..00000000 --- a/uno/lib/python/attrs-24.2.0.dist-info/METADATA +++ /dev/null @@ -1,242 +0,0 @@ -Metadata-Version: 2.3 -Name: attrs -Version: 24.2.0 -Summary: Classes Without Boilerplate -Project-URL: Documentation, https://www.attrs.org/ -Project-URL: Changelog, https://www.attrs.org/en/stable/changelog.html -Project-URL: GitHub, https://github.com/python-attrs/attrs -Project-URL: Funding, https://github.com/sponsors/hynek -Project-URL: Tidelift, https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=pypi -Author-email: Hynek Schlawack -License-Expression: MIT -License-File: LICENSE -Keywords: attribute,boilerplate,class -Classifier: Development Status :: 5 - Production/Stable -Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Typing :: Typed -Requires-Python: >=3.7 -Requires-Dist: importlib-metadata; python_version < '3.8' -Provides-Extra: benchmark -Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'benchmark' -Requires-Dist: hypothesis; extra == 'benchmark' -Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.9') and extra == 'benchmark' -Requires-Dist: pympler; extra == 'benchmark' -Requires-Dist: pytest-codspeed; extra == 'benchmark' -Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.9' and python_version < '3.13') and extra == 'benchmark' -Requires-Dist: pytest-xdist[psutil]; extra == 'benchmark' -Requires-Dist: pytest>=4.3.0; extra == 'benchmark' -Provides-Extra: cov -Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'cov' -Requires-Dist: coverage[toml]>=5.3; extra == 'cov' -Requires-Dist: hypothesis; extra == 'cov' -Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.9') and extra == 'cov' -Requires-Dist: pympler; extra == 'cov' -Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.9' and python_version < '3.13') and extra == 'cov' -Requires-Dist: pytest-xdist[psutil]; extra == 'cov' -Requires-Dist: pytest>=4.3.0; extra == 'cov' -Provides-Extra: dev -Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'dev' -Requires-Dist: hypothesis; extra == 'dev' -Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.9') and extra == 'dev' -Requires-Dist: pre-commit; extra == 'dev' -Requires-Dist: pympler; extra == 'dev' -Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.9' and python_version < '3.13') and extra == 'dev' -Requires-Dist: pytest-xdist[psutil]; extra == 'dev' -Requires-Dist: pytest>=4.3.0; extra == 'dev' -Provides-Extra: docs -Requires-Dist: cogapp; extra == 'docs' -Requires-Dist: furo; extra == 'docs' -Requires-Dist: myst-parser; extra == 'docs' -Requires-Dist: sphinx; extra == 'docs' -Requires-Dist: sphinx-notfound-page; extra == 'docs' -Requires-Dist: sphinxcontrib-towncrier; extra == 'docs' -Requires-Dist: towncrier<24.7; extra == 'docs' -Provides-Extra: tests -Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'tests' -Requires-Dist: hypothesis; extra == 'tests' -Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.9') and extra == 'tests' -Requires-Dist: pympler; extra == 'tests' -Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.9' and python_version < '3.13') and extra == 'tests' -Requires-Dist: pytest-xdist[psutil]; extra == 'tests' -Requires-Dist: pytest>=4.3.0; extra == 'tests' -Provides-Extra: tests-mypy -Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.9') and extra == 'tests-mypy' -Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.9' and python_version < '3.13') and extra == 'tests-mypy' -Description-Content-Type: text/markdown - -

- - attrs - -

- - -*attrs* is the Python package that will bring back the **joy** of **writing classes** by relieving you from the drudgery of implementing object protocols (aka [dunder methods](https://www.attrs.org/en/latest/glossary.html#term-dunder-methods)). -[Trusted by NASA](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/customizing-your-profile/personalizing-your-profile#list-of-qualifying-repositories-for-mars-2020-helicopter-contributor-achievement) for Mars missions since 2020! - -Its main goal is to help you to write **concise** and **correct** software without slowing down your code. - - -## Sponsors - -*attrs* would not be possible without our [amazing sponsors](https://github.com/sponsors/hynek). -Especially those generously supporting us at the *The Organization* tier and higher: - - - -

- - - - - - - - -

- - - -

- Please consider joining them to help make attrs’s maintenance more sustainable! -

- - - -## Example - -*attrs* gives you a class decorator and a way to declaratively define the attributes on that class: - - - -```pycon ->>> from attrs import asdict, define, make_class, Factory - ->>> @define -... class SomeClass: -... a_number: int = 42 -... list_of_numbers: list[int] = Factory(list) -... -... def hard_math(self, another_number): -... return self.a_number + sum(self.list_of_numbers) * another_number - - ->>> sc = SomeClass(1, [1, 2, 3]) ->>> sc -SomeClass(a_number=1, list_of_numbers=[1, 2, 3]) - ->>> sc.hard_math(3) -19 ->>> sc == SomeClass(1, [1, 2, 3]) -True ->>> sc != SomeClass(2, [3, 2, 1]) -True - ->>> asdict(sc) -{'a_number': 1, 'list_of_numbers': [1, 2, 3]} - ->>> SomeClass() -SomeClass(a_number=42, list_of_numbers=[]) - ->>> C = make_class("C", ["a", "b"]) ->>> C("foo", "bar") -C(a='foo', b='bar') -``` - -After *declaring* your attributes, *attrs* gives you: - -- a concise and explicit overview of the class's attributes, -- a nice human-readable `__repr__`, -- equality-checking methods, -- an initializer, -- and much more, - -*without* writing dull boilerplate code again and again and *without* runtime performance penalties. - ---- - -This example uses *attrs*'s modern APIs that have been introduced in version 20.1.0, and the *attrs* package import name that has been added in version 21.3.0. -The classic APIs (`@attr.s`, `attr.ib`, plus their serious-business aliases) and the `attr` package import name will remain **indefinitely**. - -Check out [*On The Core API Names*](https://www.attrs.org/en/latest/names.html) for an in-depth explanation! - - -### Hate Type Annotations!? - -No problem! -Types are entirely **optional** with *attrs*. -Simply assign `attrs.field()` to the attributes instead of annotating them with types: - -```python -from attrs import define, field - -@define -class SomeClass: - a_number = field(default=42) - list_of_numbers = field(factory=list) -``` - - -## Data Classes - -On the tin, *attrs* might remind you of `dataclasses` (and indeed, `dataclasses` [are a descendant](https://hynek.me/articles/import-attrs/) of *attrs*). -In practice it does a lot more and is more flexible. -For instance, it allows you to define [special handling of NumPy arrays for equality checks](https://www.attrs.org/en/stable/comparison.html#customization), allows more ways to [plug into the initialization process](https://www.attrs.org/en/stable/init.html#hooking-yourself-into-initialization), has a replacement for `__init_subclass__`, and allows for stepping through the generated methods using a debugger. - -For more details, please refer to our [comparison page](https://www.attrs.org/en/stable/why.html#data-classes), but generally speaking, we are more likely to commit crimes against nature to make things work that one would expect to work, but that are quite complicated in practice. - - -## Project Information - -- [**Changelog**](https://www.attrs.org/en/stable/changelog.html) -- [**Documentation**](https://www.attrs.org/) -- [**PyPI**](https://pypi.org/project/attrs/) -- [**Source Code**](https://github.com/python-attrs/attrs) -- [**Contributing**](https://github.com/python-attrs/attrs/blob/main/.github/CONTRIBUTING.md) -- [**Third-party Extensions**](https://github.com/python-attrs/attrs/wiki/Extensions-to-attrs) -- **Get Help**: use the `python-attrs` tag on [Stack Overflow](https://stackoverflow.com/questions/tagged/python-attrs) - - -### *attrs* for Enterprise - -Available as part of the Tidelift Subscription. - -The maintainers of *attrs* and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. -Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. -[Learn more](https://tidelift.com/?utm_source=lifter&utm_medium=referral&utm_campaign=hynek). - -## Release Information - -### Deprecations - -- Given the amount of warnings raised in the broader ecosystem, we've decided to only soft-deprecate the *hash* argument to `@define` / `@attr.s`. - Please don't use it in new code, but we don't intend to remove it anymore. - [#1330](https://github.com/python-attrs/attrs/issues/1330) - - -### Changes - -- `attrs.converters.pipe()` (and its syntactic sugar of passing a list for `attrs.field()`'s / `attr.ib()`'s *converter* argument) works again when passing `attrs.setters.convert` to *on_setattr* (which is default for `attrs.define`). - [#1328](https://github.com/python-attrs/attrs/issues/1328) -- Restored support for PEP [649](https://peps.python.org/pep-0649/) / [749](https://peps.python.org/pep-0749/)-implementing Pythons -- currently 3.14-dev. - [#1329](https://github.com/python-attrs/attrs/issues/1329) - - - ---- - -[Full changelog →](https://www.attrs.org/en/stable/changelog.html) diff --git a/uno/lib/python/attrs-24.2.0.dist-info/RECORD b/uno/lib/python/attrs-24.2.0.dist-info/RECORD deleted file mode 100644 index 6e36e4bd..00000000 --- a/uno/lib/python/attrs-24.2.0.dist-info/RECORD +++ /dev/null @@ -1,35 +0,0 @@ -attr/__init__.py,sha256=l8Ewh5KZE7CCY0i1iDfSCnFiUTIkBVoqsXjX9EZnIVA,2087 -attr/__init__.pyi,sha256=aTVHBPX6krCGvbQvOl_UKqEzmi2HFsaIVm2WKmAiqVs,11434 -attr/_cmp.py,sha256=3umHiBtgsEYtvNP_8XrQwTCdFoZIX4DEur76N-2a3X8,4123 -attr/_cmp.pyi,sha256=U-_RU_UZOyPUEQzXE6RMYQQcjkZRY25wTH99sN0s7MM,368 -attr/_compat.py,sha256=n2Uk3c-ywv0PkFfGlvqR7SzDXp4NOhWmNV_ZK6YfWoM,2958 -attr/_config.py,sha256=z81Vt-GeT_2taxs1XZfmHx9TWlSxjPb6eZH1LTGsS54,843 -attr/_funcs.py,sha256=SGDmNlED1TM3tgO9Ap2mfRfVI24XEAcrNQs7o2eBXHQ,17386 -attr/_make.py,sha256=BjENJz5eJoojJVbCoupWjXLLEZJ7VID89lisLbQUlmQ,91479 -attr/_next_gen.py,sha256=dhGb96VFg4kXBkS9Zdz1A2uxVJ99q_RT1hw3kLA9-uI,24630 -attr/_typing_compat.pyi,sha256=XDP54TUn-ZKhD62TOQebmzrwFyomhUCoGRpclb6alRA,469 -attr/_version_info.py,sha256=exSqb3b5E-fMSsgZAlEw9XcLpEgobPORCZpcaEglAM4,2121 -attr/_version_info.pyi,sha256=x_M3L3WuB7r_ULXAWjx959udKQ4HLB8l-hsc1FDGNvk,209 -attr/converters.py,sha256=vNa58pZi9V6uxBzl4t1QrHbQfkT4iRFAodyXe7lcgg0,3506 -attr/converters.pyi,sha256=mpDoVFO3Cpx8xYSSV0iZFl7IAHuoNBglxKfxHvLj_sY,410 -attr/exceptions.py,sha256=HRFq4iybmv7-DcZwyjl6M1euM2YeJVK_hFxuaBGAngI,1977 -attr/exceptions.pyi,sha256=zZq8bCUnKAy9mDtBEw42ZhPhAUIHoTKedDQInJD883M,539 -attr/filters.py,sha256=ZBiKWLp3R0LfCZsq7X11pn9WX8NslS2wXM4jsnLOGc8,1795 -attr/filters.pyi,sha256=3J5BG-dTxltBk1_-RuNRUHrv2qu1v8v4aDNAQ7_mifA,208 -attr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -attr/setters.py,sha256=faMQeiBo_nbXYnPaQ1pq8PXeA7Zr-uNsVsPMiKCmxhc,1619 -attr/setters.pyi,sha256=NnVkaFU1BB4JB8E4JuXyrzTUgvtMpj8p3wBdJY7uix4,584 -attr/validators.py,sha256=985eTP6RHyon61YEauMJgyNy1rEOhJWiSXMJgRxPtrQ,20045 -attr/validators.pyi,sha256=LjKf7AoXZfvGSfT3LRs61Qfln94konYyMUPoJJjOxK4,2502 -attrs/__init__.py,sha256=5FHo-EMFOX-g4ialSK4fwOjuoHzLISJDZCwoOl02Ty8,1071 -attrs/__init__.pyi,sha256=o3l92VsD9kHz8sldEtb_tllBTs3TeL-vIBMTxo2Zc_4,7703 -attrs/converters.py,sha256=8kQljrVwfSTRu8INwEk8SI0eGrzmWftsT7rM0EqyohM,76 -attrs/exceptions.py,sha256=ACCCmg19-vDFaDPY9vFl199SPXCQMN_bENs4DALjzms,76 -attrs/filters.py,sha256=VOUMZug9uEU6dUuA0dF1jInUK0PL3fLgP0VBS5d-CDE,73 -attrs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -attrs/setters.py,sha256=eL1YidYQV3T2h9_SYIZSZR1FAcHGb1TuCTy0E0Lv2SU,73 -attrs/validators.py,sha256=xcy6wD5TtTkdCG1f4XWbocPSO0faBjk5IfVJfP6SUj0,76 -attrs-24.2.0.dist-info/METADATA,sha256=3Jgk4lr9Y1SAqAcwOLPN_mpW0wc6VOGm-yHt1LsPIHw,11524 -attrs-24.2.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87 -attrs-24.2.0.dist-info/licenses/LICENSE,sha256=iCEVyV38KvHutnFPjsbVy8q_Znyv-HKfQkINpj9xTp8,1109 -attrs-24.2.0.dist-info/RECORD,, diff --git a/uno/lib/python/attrs-24.2.0.dist-info/WHEEL b/uno/lib/python/attrs-24.2.0.dist-info/WHEEL deleted file mode 100644 index cdd68a49..00000000 --- a/uno/lib/python/attrs-24.2.0.dist-info/WHEEL +++ /dev/null @@ -1,4 +0,0 @@ -Wheel-Version: 1.0 -Generator: hatchling 1.25.0 -Root-Is-Purelib: true -Tag: py3-none-any diff --git a/uno/lib/python/attrs-24.2.0.dist-info/licenses/LICENSE b/uno/lib/python/attrs-24.2.0.dist-info/licenses/LICENSE deleted file mode 100644 index 2bd6453d..00000000 --- a/uno/lib/python/attrs-24.2.0.dist-info/licenses/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Hynek Schlawack and the attrs contributors - -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. diff --git a/uno/lib/python/attrs/__init__.py b/uno/lib/python/attrs/__init__.py deleted file mode 100644 index 963b1972..00000000 --- a/uno/lib/python/attrs/__init__.py +++ /dev/null @@ -1,67 +0,0 @@ -# SPDX-License-Identifier: MIT - -from attr import ( - NOTHING, - Attribute, - AttrsInstance, - Converter, - Factory, - _make_getattr, - assoc, - cmp_using, - define, - evolve, - field, - fields, - fields_dict, - frozen, - has, - make_class, - mutable, - resolve_types, - validate, -) -from attr._next_gen import asdict, astuple - -from . import converters, exceptions, filters, setters, validators - - -__all__ = [ - "__author__", - "__copyright__", - "__description__", - "__doc__", - "__email__", - "__license__", - "__title__", - "__url__", - "__version__", - "__version_info__", - "asdict", - "assoc", - "astuple", - "Attribute", - "AttrsInstance", - "cmp_using", - "Converter", - "converters", - "define", - "evolve", - "exceptions", - "Factory", - "field", - "fields_dict", - "fields", - "filters", - "frozen", - "has", - "make_class", - "mutable", - "NOTHING", - "resolve_types", - "setters", - "validate", - "validators", -] - -__getattr__ = _make_getattr(__name__) diff --git a/uno/lib/python/attrs/__init__.pyi b/uno/lib/python/attrs/__init__.pyi deleted file mode 100644 index b2670de2..00000000 --- a/uno/lib/python/attrs/__init__.pyi +++ /dev/null @@ -1,252 +0,0 @@ -import sys - -from typing import ( - Any, - Callable, - Mapping, - Sequence, - overload, - TypeVar, -) - -# Because we need to type our own stuff, we have to make everything from -# attr explicitly public too. -from attr import __author__ as __author__ -from attr import __copyright__ as __copyright__ -from attr import __description__ as __description__ -from attr import __email__ as __email__ -from attr import __license__ as __license__ -from attr import __title__ as __title__ -from attr import __url__ as __url__ -from attr import __version__ as __version__ -from attr import __version_info__ as __version_info__ -from attr import assoc as assoc -from attr import Attribute as Attribute -from attr import AttrsInstance as AttrsInstance -from attr import cmp_using as cmp_using -from attr import converters as converters -from attr import Converter as Converter -from attr import evolve as evolve -from attr import exceptions as exceptions -from attr import Factory as Factory -from attr import fields as fields -from attr import fields_dict as fields_dict -from attr import filters as filters -from attr import has as has -from attr import make_class as make_class -from attr import NOTHING as NOTHING -from attr import resolve_types as resolve_types -from attr import setters as setters -from attr import validate as validate -from attr import validators as validators -from attr import attrib, asdict as asdict, astuple as astuple - -if sys.version_info >= (3, 11): - from typing import dataclass_transform -else: - from typing_extensions import dataclass_transform - -_T = TypeVar("_T") -_C = TypeVar("_C", bound=type) - -_EqOrderType = bool | Callable[[Any], Any] -_ValidatorType = Callable[[Any, "Attribute[_T]", _T], Any] -_ConverterType = Callable[[Any], Any] -_ReprType = Callable[[Any], str] -_ReprArgType = bool | _ReprType -_OnSetAttrType = Callable[[Any, "Attribute[Any]", Any], Any] -_OnSetAttrArgType = _OnSetAttrType | list[_OnSetAttrType] | setters._NoOpType -_FieldTransformer = Callable[ - [type, list["Attribute[Any]"]], list["Attribute[Any]"] -] -# FIXME: in reality, if multiple validators are passed they must be in a list -# or tuple, but those are invariant and so would prevent subtypes of -# _ValidatorType from working when passed in a list or tuple. -_ValidatorArgType = _ValidatorType[_T] | Sequence[_ValidatorType[_T]] - -@overload -def field( - *, - default: None = ..., - validator: None = ..., - repr: _ReprArgType = ..., - hash: bool | None = ..., - init: bool = ..., - metadata: Mapping[Any, Any] | None = ..., - converter: None = ..., - factory: None = ..., - kw_only: bool = ..., - eq: bool | None = ..., - order: bool | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - alias: str | None = ..., - type: type | None = ..., -) -> Any: ... - -# This form catches an explicit None or no default and infers the type from the -# other arguments. -@overload -def field( - *, - default: None = ..., - validator: _ValidatorArgType[_T] | None = ..., - repr: _ReprArgType = ..., - hash: bool | None = ..., - init: bool = ..., - metadata: Mapping[Any, Any] | None = ..., - converter: _ConverterType | Converter[Any, _T] | None = ..., - factory: Callable[[], _T] | None = ..., - kw_only: bool = ..., - eq: _EqOrderType | None = ..., - order: _EqOrderType | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - alias: str | None = ..., - type: type | None = ..., -) -> _T: ... - -# This form catches an explicit default argument. -@overload -def field( - *, - default: _T, - validator: _ValidatorArgType[_T] | None = ..., - repr: _ReprArgType = ..., - hash: bool | None = ..., - init: bool = ..., - metadata: Mapping[Any, Any] | None = ..., - converter: _ConverterType | Converter[Any, _T] | None = ..., - factory: Callable[[], _T] | None = ..., - kw_only: bool = ..., - eq: _EqOrderType | None = ..., - order: _EqOrderType | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - alias: str | None = ..., - type: type | None = ..., -) -> _T: ... - -# This form covers type=non-Type: e.g. forward references (str), Any -@overload -def field( - *, - default: _T | None = ..., - validator: _ValidatorArgType[_T] | None = ..., - repr: _ReprArgType = ..., - hash: bool | None = ..., - init: bool = ..., - metadata: Mapping[Any, Any] | None = ..., - converter: _ConverterType | Converter[Any, _T] | None = ..., - factory: Callable[[], _T] | None = ..., - kw_only: bool = ..., - eq: _EqOrderType | None = ..., - order: _EqOrderType | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - alias: str | None = ..., - type: type | None = ..., -) -> Any: ... -@overload -@dataclass_transform(field_specifiers=(attrib, field)) -def define( - maybe_cls: _C, - *, - these: dict[str, Any] | None = ..., - repr: bool = ..., - unsafe_hash: bool | None = ..., - hash: bool | None = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: bool | None = ..., - order: bool | None = ..., - auto_detect: bool = ..., - getstate_setstate: bool | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - field_transformer: _FieldTransformer | None = ..., - match_args: bool = ..., -) -> _C: ... -@overload -@dataclass_transform(field_specifiers=(attrib, field)) -def define( - maybe_cls: None = ..., - *, - these: dict[str, Any] | None = ..., - repr: bool = ..., - unsafe_hash: bool | None = ..., - hash: bool | None = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: bool | None = ..., - order: bool | None = ..., - auto_detect: bool = ..., - getstate_setstate: bool | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - field_transformer: _FieldTransformer | None = ..., - match_args: bool = ..., -) -> Callable[[_C], _C]: ... - -mutable = define - -@overload -@dataclass_transform(frozen_default=True, field_specifiers=(attrib, field)) -def frozen( - maybe_cls: _C, - *, - these: dict[str, Any] | None = ..., - repr: bool = ..., - unsafe_hash: bool | None = ..., - hash: bool | None = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: bool | None = ..., - order: bool | None = ..., - auto_detect: bool = ..., - getstate_setstate: bool | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - field_transformer: _FieldTransformer | None = ..., - match_args: bool = ..., -) -> _C: ... -@overload -@dataclass_transform(frozen_default=True, field_specifiers=(attrib, field)) -def frozen( - maybe_cls: None = ..., - *, - these: dict[str, Any] | None = ..., - repr: bool = ..., - unsafe_hash: bool | None = ..., - hash: bool | None = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: bool | None = ..., - order: bool | None = ..., - auto_detect: bool = ..., - getstate_setstate: bool | None = ..., - on_setattr: _OnSetAttrArgType | None = ..., - field_transformer: _FieldTransformer | None = ..., - match_args: bool = ..., -) -> Callable[[_C], _C]: ... diff --git a/uno/lib/python/attrs/converters.py b/uno/lib/python/attrs/converters.py deleted file mode 100644 index 7821f6c0..00000000 --- a/uno/lib/python/attrs/converters.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: MIT - -from attr.converters import * # noqa: F403 diff --git a/uno/lib/python/attrs/exceptions.py b/uno/lib/python/attrs/exceptions.py deleted file mode 100644 index 3323f9d2..00000000 --- a/uno/lib/python/attrs/exceptions.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: MIT - -from attr.exceptions import * # noqa: F403 diff --git a/uno/lib/python/attrs/filters.py b/uno/lib/python/attrs/filters.py deleted file mode 100644 index 3080f483..00000000 --- a/uno/lib/python/attrs/filters.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: MIT - -from attr.filters import * # noqa: F403 diff --git a/uno/lib/python/attrs/py.typed b/uno/lib/python/attrs/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/lib/python/attrs/setters.py b/uno/lib/python/attrs/setters.py deleted file mode 100644 index f3d73bb7..00000000 --- a/uno/lib/python/attrs/setters.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: MIT - -from attr.setters import * # noqa: F403 diff --git a/uno/lib/python/attrs/validators.py b/uno/lib/python/attrs/validators.py deleted file mode 100644 index 037e124f..00000000 --- a/uno/lib/python/attrs/validators.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: MIT - -from attr.validators import * # noqa: F403 diff --git a/uno/lib/python/beautifulsoup4-4.12.3.dist-info/METADATA b/uno/lib/python/beautifulsoup4-4.12.3.dist-info/METADATA deleted file mode 100644 index a2681d72..00000000 --- a/uno/lib/python/beautifulsoup4-4.12.3.dist-info/METADATA +++ /dev/null @@ -1,122 +0,0 @@ -Metadata-Version: 2.1 -Name: beautifulsoup4 -Version: 4.12.3 -Summary: Screen-scraping library -Project-URL: Download, https://www.crummy.com/software/BeautifulSoup/bs4/download/ -Project-URL: Homepage, https://www.crummy.com/software/BeautifulSoup/bs4/ -Author-email: Leonard Richardson -License: MIT License -License-File: AUTHORS -License-File: LICENSE -Keywords: HTML,XML,parse,soup -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Text Processing :: Markup :: HTML -Classifier: Topic :: Text Processing :: Markup :: SGML -Classifier: Topic :: Text Processing :: Markup :: XML -Requires-Python: >=3.6.0 -Requires-Dist: soupsieve>1.2 -Provides-Extra: cchardet -Requires-Dist: cchardet; extra == 'cchardet' -Provides-Extra: chardet -Requires-Dist: chardet; extra == 'chardet' -Provides-Extra: charset-normalizer -Requires-Dist: charset-normalizer; extra == 'charset-normalizer' -Provides-Extra: html5lib -Requires-Dist: html5lib; extra == 'html5lib' -Provides-Extra: lxml -Requires-Dist: lxml; extra == 'lxml' -Description-Content-Type: text/markdown - -Beautiful Soup is a library that makes it easy to scrape information -from web pages. It sits atop an HTML or XML parser, providing Pythonic -idioms for iterating, searching, and modifying the parse tree. - -# Quick start - -``` ->>> from bs4 import BeautifulSoup ->>> soup = BeautifulSoup("

SomebadHTML") ->>> print(soup.prettify()) - - -

- Some - - bad - - HTML - - -

- - ->>> soup.find(text="bad") -'bad' ->>> soup.i -HTML -# ->>> soup = BeautifulSoup("SomebadXML", "xml") -# ->>> print(soup.prettify()) - - - Some - - bad - - XML - - -``` - -To go beyond the basics, [comprehensive documentation is available](https://www.crummy.com/software/BeautifulSoup/bs4/doc/). - -# Links - -* [Homepage](https://www.crummy.com/software/BeautifulSoup/bs4/) -* [Documentation](https://www.crummy.com/software/BeautifulSoup/bs4/doc/) -* [Discussion group](https://groups.google.com/group/beautifulsoup/) -* [Development](https://code.launchpad.net/beautifulsoup/) -* [Bug tracker](https://bugs.launchpad.net/beautifulsoup/) -* [Complete changelog](https://bazaar.launchpad.net/~leonardr/beautifulsoup/bs4/view/head:/CHANGELOG) - -# Note on Python 2 sunsetting - -Beautiful Soup's support for Python 2 was discontinued on December 31, -2020: one year after the sunset date for Python 2 itself. From this -point onward, new Beautiful Soup development will exclusively target -Python 3. The final release of Beautiful Soup 4 to support Python 2 -was 4.9.3. - -# Supporting the project - -If you use Beautiful Soup as part of your professional work, please consider a -[Tidelift subscription](https://tidelift.com/subscription/pkg/pypi-beautifulsoup4?utm_source=pypi-beautifulsoup4&utm_medium=referral&utm_campaign=readme). -This will support many of the free software projects your organization -depends on, not just Beautiful Soup. - -If you use Beautiful Soup for personal projects, the best way to say -thank you is to read -[Tool Safety](https://www.crummy.com/software/BeautifulSoup/zine/), a zine I -wrote about what Beautiful Soup has taught me about software -development. - -# Building the documentation - -The bs4/doc/ directory contains full documentation in Sphinx -format. Run `make html` in that directory to create HTML -documentation. - -# Running the unit tests - -Beautiful Soup supports unit test discovery using Pytest: - -``` -$ pytest -``` - diff --git a/uno/lib/python/beautifulsoup4-4.12.3.dist-info/RECORD b/uno/lib/python/beautifulsoup4-4.12.3.dist-info/RECORD deleted file mode 100644 index ff5b56cc..00000000 --- a/uno/lib/python/beautifulsoup4-4.12.3.dist-info/RECORD +++ /dev/null @@ -1,50 +0,0 @@ -bs4/__init__.py,sha256=kq32cCtQiNjjU9XwjD0b1jdXN5WEC87nJqSSW3PhVkM,33822 -bs4/css.py,sha256=gqGaHRrKeCRF3gDqxzeU0uclOCeSsTpuW9gUaSnJeWc,10077 -bs4/dammit.py,sha256=G0cQfsEqfwJ-FIQMkXgCJwSHMn7t9vPepCrud6fZEKk,41158 -bs4/diagnose.py,sha256=uAwdDugL_67tB-BIwDIFLFbiuzGxP2wQzJJ4_bGYUrA,7195 -bs4/element.py,sha256=Dsol2iehkSjk10GzYgwFyjUEgpqmYZpyaAmbL0rWM2w,92845 -bs4/formatter.py,sha256=Bu4utAQYT9XDJaPPpTRM-dyxJDVLdxf_as-IU5gSY8A,7188 -bs4/builder/__init__.py,sha256=nwb35ftjcwzOs2WkjVm1zvfi7FxSyJP-nN1YheIVT14,24566 -bs4/builder/_html5lib.py,sha256=0w-hmPM5wWR2iDuRCR6MvY6ZPXbg_hgddym-YWqj03s,19114 -bs4/builder/_htmlparser.py,sha256=_VD5Z08j6A9YYMR4y7ZTfdMzwiCBsSUQAPuHiYB-WZI,14923 -bs4/builder/_lxml.py,sha256=yKdMx1kdX7H2CopwSWEYm4Sgrfkd-WDj8HbskcaLauU,14948 -bs4/tests/__init__.py,sha256=NydTegds_r7MoOEuQLS6TFmTA9TwK3KxJhwEkqjCGTQ,48392 -bs4/tests/test_builder.py,sha256=nc2JE5EMrEf-p24qhf2R8qAV5PpFiOuNpYCmtmCjlTI,1115 -bs4/tests/test_builder_registry.py,sha256=7WLj2prjSHGphebnrjQuI6JYr03Uy_c9_CkaFSQ9HRo,5114 -bs4/tests/test_css.py,sha256=jCcgIWem3lyPa5AjhAk9S6fWI07hk1rg0v8coD7bEtI,17279 -bs4/tests/test_dammit.py,sha256=MbSmRN6VEP0Rm56-w6Ja0TW8eC-8ZxOJ-wXWVf_hRi8,15451 -bs4/tests/test_docs.py,sha256=xoAxnUfoQ7aRqGImwW_9BJDU8WNMZHIuvWqVepvWXt8,1127 -bs4/tests/test_element.py,sha256=92oRSRoGk8gIXAbAGHErKzocx2MK32TqcQdUJ-dGQMo,2377 -bs4/tests/test_formatter.py,sha256=eTzj91Lmhv90z-WiHjK3sBJZm0hRk0crFY1TZaXstCY,4148 -bs4/tests/test_fuzz.py,sha256=_K2utiYVkZ22mvh03g8CBioFU1QDJaff1vTaDyXhxNk,6972 -bs4/tests/test_html5lib.py,sha256=2-ipm-_MaPt37WTxEd5DodUTNhS4EbLFKPRaO6XSCW4,8322 -bs4/tests/test_htmlparser.py,sha256=wnngcIlzjEwH21JFfu_mgt6JdpLt0ncJfLcGT7HeGw0,6256 -bs4/tests/test_lxml.py,sha256=nQCmLt7bWk0id7xMumZw--PzEe1xF9PTQn3lvHyNC6I,7635 -bs4/tests/test_navigablestring.py,sha256=RGSgziNf7cZnYdEPsoqL1B2I68TUJp1JmEQVxbh_ryA,5081 -bs4/tests/test_pageelement.py,sha256=VdGjUxx3RhjqmNsJ92ao6VZC_YD7T8mdLkDZjosOYeE,14274 -bs4/tests/test_soup.py,sha256=JmnAPLE1_GXm0wmwEUN7icdvBz9HDch-qoU2mT_TDrs,19877 -bs4/tests/test_tag.py,sha256=FBPDUisDCbFmvl5HmTtN49CGo3YoUXh5Wiuw5FMLS5E,9616 -bs4/tests/test_tree.py,sha256=n9nTQOzJb3-ZnZ6AkmMdZQ5TYcTUPnqHoVgal0mYXfg,48129 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase,sha256=yUdXkbpNK7LVOQ0LBHMoqZ1rWaBfSXWytoO_xdSm7Ho,15 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-4818336571064320.testcase,sha256=Uv_dx4a43TSfoNkjU-jHW2nSXkqHFg4XdAw7SWVObUk,23 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-4999465949331456.testcase,sha256=OEyVA0Ej4FxswOElrUNt0In4s4YhrmtaxE_NHGZvGtg,30 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase,sha256=G4vpNBOz-RwMpi6ewEgNEa13zX0sXhmL7VHOyIcdKVQ,15347 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase,sha256=3d8z65o4p7Rur-RmCHoOjzqaYQ8EAtjmiBYTHNyAdl4,19469 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase,sha256=NfGIlit1k40Ip3mlnBkYOkIDJX6gHtjlErwl7gsBjAQ,12 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase,sha256=xy4i1U0nhFHcnyc5pRKS6JRMvuoCNUur-Scor6UxIGw,4317 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase,sha256=Q-UTYpQBUsWoMgIUspUlzveSI-41s4ABC3jajRb-K0o,11502 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase,sha256=2bq3S8KxZgk8EajLReHD8m4_0Lj_nrkyJAxB_z_U0D0,5 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5843991618256896.testcase,sha256=MZDu31LPLfgu6jP9IZkrlwNes3f_sL8WFP5BChkUKdY,35 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5984173902397440.testcase,sha256=w58r-s6besG5JwPXpnz37W2YTj9-_qxFbk6hiEnKeIQ,51495 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-6124268085182464.testcase,sha256=q8rkdMECEXKcqVhOf5zWHkSBTQeOPt0JiLg2TZiPCuk,10380 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-6241471367348224.testcase,sha256=QfzoOxKwNuqG-4xIrea6MOQLXhfAAOQJ0r9u-J6kSNs,19 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-6306874195312640.testcase,sha256=MJ2pHFuuCQUiQz1Kor2sof7LWeRERQ6QK43YNqQHg9o,47 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase,sha256=EItOpSdeD4ewK-qgJ9vtxennwn_huguzXgctrUT7fqE,3546 -bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase,sha256=a2aJTG4FceGSJXsjtxoS8S4jk_8rZsS3aznLkeO2_dY,124 -bs4/tests/fuzz/crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase,sha256=jRFRtCKlP3-3EDLc_iVRTcE6JNymv0rYcVM6qRaPrxI,2607 -bs4/tests/fuzz/crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase,sha256=7NsdCiXWAhNkmoW1pvF7rbZExyLAQIWtDtSHXIsH6YU,103 -beautifulsoup4-4.12.3.dist-info/METADATA,sha256=UkOS1koIjlakIy9Q1u2yCNwDEFOUZSrLcsbV-mTInz4,3790 -beautifulsoup4-4.12.3.dist-info/WHEEL,sha256=mRYSEL3Ih6g5a_CVMIcwiF__0Ae4_gLYh01YFNwiq1k,87 -beautifulsoup4-4.12.3.dist-info/licenses/AUTHORS,sha256=uSIdbrBb1sobdXl7VrlUvuvim2dN9kF3MH4Edn0WKGE,2176 -beautifulsoup4-4.12.3.dist-info/licenses/LICENSE,sha256=VbTY1LHlvIbRDvrJG3TIe8t3UmsPW57a-LnNKtxzl7I,1441 -beautifulsoup4-4.12.3.dist-info/RECORD,, diff --git a/uno/lib/python/beautifulsoup4-4.12.3.dist-info/WHEEL b/uno/lib/python/beautifulsoup4-4.12.3.dist-info/WHEEL deleted file mode 100644 index 2860816a..00000000 --- a/uno/lib/python/beautifulsoup4-4.12.3.dist-info/WHEEL +++ /dev/null @@ -1,4 +0,0 @@ -Wheel-Version: 1.0 -Generator: hatchling 1.21.0 -Root-Is-Purelib: true -Tag: py3-none-any diff --git a/uno/lib/python/beautifulsoup4-4.12.3.dist-info/licenses/AUTHORS b/uno/lib/python/beautifulsoup4-4.12.3.dist-info/licenses/AUTHORS deleted file mode 100644 index 1f14fe07..00000000 --- a/uno/lib/python/beautifulsoup4-4.12.3.dist-info/licenses/AUTHORS +++ /dev/null @@ -1,49 +0,0 @@ -Behold, mortal, the origins of Beautiful Soup... -================================================ - -Leonard Richardson is the primary maintainer. - -Aaron DeVore and Isaac Muse have made significant contributions to the -code base. - -Mark Pilgrim provided the encoding detection code that forms the base -of UnicodeDammit. - -Thomas Kluyver and Ezio Melotti finished the work of getting Beautiful -Soup 4 working under Python 3. - -Simon Willison wrote soupselect, which was used to make Beautiful Soup -support CSS selectors. Isaac Muse wrote SoupSieve, which made it -possible to _remove_ the CSS selector code from Beautiful Soup. - -Sam Ruby helped with a lot of edge cases. - -Jonathan Ellis was awarded the prestigious Beau Potage D'Or for his -work in solving the nestable tags conundrum. - -An incomplete list of people have contributed patches to Beautiful -Soup: - - Istvan Albert, Andrew Lin, Anthony Baxter, Oliver Beattie, Andrew -Boyko, Tony Chang, Francisco Canas, "Delong", Zephyr Fang, Fuzzy, -Roman Gaufman, Yoni Gilad, Richie Hindle, Toshihiro Kamiya, Peteris -Krumins, Kent Johnson, Marek Kapolka, Andreas Kostyrka, Roel Kramer, -Ben Last, Robert Leftwich, Stefaan Lippens, "liquider", Staffan -Malmgren, Ksenia Marasanova, JP Moins, Adam Monsen, John Nagle, "Jon", -Ed Oskiewicz, Martijn Peters, Greg Phillips, Giles Radford, Stefano -Revera, Arthur Rudolph, Marko Samastur, James Salter, Jouni Seppnen, -Alexander Schmolck, Tim Shirley, Geoffrey Sneddon, Ville Skytt, -"Vikas", Jens Svalgaard, Andy Theyers, Eric Weiser, Glyn Webster, John -Wiseman, Paul Wright, Danny Yoo - -An incomplete list of people who made suggestions or found bugs or -found ways to break Beautiful Soup: - - Hanno Bck, Matteo Bertini, Chris Curvey, Simon Cusack, Bruce Eckel, - Matt Ernst, Michael Foord, Tom Harris, Bill de hOra, Donald Howes, - Matt Patterson, Scott Roberts, Steve Strassmann, Mike Williams, - warchild at redho dot com, Sami Kuisma, Carlos Rocha, Bob Hutchison, - Joren Mc, Michal Migurski, John Kleven, Tim Heaney, Tripp Lilley, Ed - Summers, Dennis Sutch, Chris Smith, Aaron Swartz, Stuart - Turner, Greg Edwards, Kevin J Kalupson, Nikos Kouremenos, Artur de - Sousa Rocha, Yichun Wei, Per Vognsen diff --git a/uno/lib/python/beautifulsoup4-4.12.3.dist-info/licenses/LICENSE b/uno/lib/python/beautifulsoup4-4.12.3.dist-info/licenses/LICENSE deleted file mode 100644 index 08e3a9cf..00000000 --- a/uno/lib/python/beautifulsoup4-4.12.3.dist-info/licenses/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -Beautiful Soup is made available under the MIT license: - - Copyright (c) Leonard Richardson - - 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. - -Beautiful Soup incorporates code from the html5lib library, which is -also made available under the MIT license. Copyright (c) James Graham -and other contributors - -Beautiful Soup has an optional dependency on the soupsieve library, -which is also made available under the MIT license. Copyright (c) -Isaac Muse diff --git a/uno/lib/python/bs4/__init__.py b/uno/lib/python/bs4/__init__.py deleted file mode 100644 index d8ad5e1d..00000000 --- a/uno/lib/python/bs4/__init__.py +++ /dev/null @@ -1,840 +0,0 @@ -"""Beautiful Soup Elixir and Tonic - "The Screen-Scraper's Friend". - -http://www.crummy.com/software/BeautifulSoup/ - -Beautiful Soup uses a pluggable XML or HTML parser to parse a -(possibly invalid) document into a tree representation. Beautiful Soup -provides methods and Pythonic idioms that make it easy to navigate, -search, and modify the parse tree. - -Beautiful Soup works with Python 3.6 and up. It works better if lxml -and/or html5lib is installed. - -For more than you ever wanted to know about Beautiful Soup, see the -documentation: http://www.crummy.com/software/BeautifulSoup/bs4/doc/ -""" - -__author__ = "Leonard Richardson (leonardr@segfault.org)" -__version__ = "4.12.3" -__copyright__ = "Copyright (c) 2004-2024 Leonard Richardson" -# Use of this source code is governed by the MIT license. -__license__ = "MIT" - -__all__ = ['BeautifulSoup'] - -from collections import Counter -import os -import re -import sys -import traceback -import warnings - -# The very first thing we do is give a useful error if someone is -# running this code under Python 2. -if sys.version_info.major < 3: - raise ImportError('You are trying to use a Python 3-specific version of Beautiful Soup under Python 2. This will not work. The final version of Beautiful Soup to support Python 2 was 4.9.3.') - -from .builder import ( - builder_registry, - ParserRejectedMarkup, - XMLParsedAsHTMLWarning, - HTMLParserTreeBuilder -) -from .dammit import UnicodeDammit -from .element import ( - CData, - Comment, - CSS, - DEFAULT_OUTPUT_ENCODING, - Declaration, - Doctype, - NavigableString, - PageElement, - ProcessingInstruction, - PYTHON_SPECIFIC_ENCODINGS, - ResultSet, - Script, - Stylesheet, - SoupStrainer, - Tag, - TemplateString, - ) - -# Define some custom warnings. -class GuessedAtParserWarning(UserWarning): - """The warning issued when BeautifulSoup has to guess what parser to - use -- probably because no parser was specified in the constructor. - """ - -class MarkupResemblesLocatorWarning(UserWarning): - """The warning issued when BeautifulSoup is given 'markup' that - actually looks like a resource locator -- a URL or a path to a file - on disk. - """ - - -class BeautifulSoup(Tag): - """A data structure representing a parsed HTML or XML document. - - Most of the methods you'll call on a BeautifulSoup object are inherited from - PageElement or Tag. - - Internally, this class defines the basic interface called by the - tree builders when converting an HTML/XML document into a data - structure. The interface abstracts away the differences between - parsers. To write a new tree builder, you'll need to understand - these methods as a whole. - - These methods will be called by the BeautifulSoup constructor: - * reset() - * feed(markup) - - The tree builder may call these methods from its feed() implementation: - * handle_starttag(name, attrs) # See note about return value - * handle_endtag(name) - * handle_data(data) # Appends to the current data node - * endData(containerClass) # Ends the current data node - - No matter how complicated the underlying parser is, you should be - able to build a tree using 'start tag' events, 'end tag' events, - 'data' events, and "done with data" events. - - If you encounter an empty-element tag (aka a self-closing tag, - like HTML's
tag), call handle_starttag and then - handle_endtag. - """ - - # Since BeautifulSoup subclasses Tag, it's possible to treat it as - # a Tag with a .name. This name makes it clear the BeautifulSoup - # object isn't a real markup tag. - ROOT_TAG_NAME = '[document]' - - # If the end-user gives no indication which tree builder they - # want, look for one with these features. - DEFAULT_BUILDER_FEATURES = ['html', 'fast'] - - # A string containing all ASCII whitespace characters, used in - # endData() to detect data chunks that seem 'empty'. - ASCII_SPACES = '\x20\x0a\x09\x0c\x0d' - - NO_PARSER_SPECIFIED_WARNING = "No parser was explicitly specified, so I'm using the best available %(markup_type)s parser for this system (\"%(parser)s\"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.\n\nThe code that caused this warning is on line %(line_number)s of the file %(filename)s. To get rid of this warning, pass the additional argument 'features=\"%(parser)s\"' to the BeautifulSoup constructor.\n" - - def __init__(self, markup="", features=None, builder=None, - parse_only=None, from_encoding=None, exclude_encodings=None, - element_classes=None, **kwargs): - """Constructor. - - :param markup: A string or a file-like object representing - markup to be parsed. - - :param features: Desirable features of the parser to be - used. This may be the name of a specific parser ("lxml", - "lxml-xml", "html.parser", or "html5lib") or it may be the - type of markup to be used ("html", "html5", "xml"). It's - recommended that you name a specific parser, so that - Beautiful Soup gives you the same results across platforms - and virtual environments. - - :param builder: A TreeBuilder subclass to instantiate (or - instance to use) instead of looking one up based on - `features`. You only need to use this if you've implemented a - custom TreeBuilder. - - :param parse_only: A SoupStrainer. Only parts of the document - matching the SoupStrainer will be considered. This is useful - when parsing part of a document that would otherwise be too - large to fit into memory. - - :param from_encoding: A string indicating the encoding of the - document to be parsed. Pass this in if Beautiful Soup is - guessing wrongly about the document's encoding. - - :param exclude_encodings: A list of strings indicating - encodings known to be wrong. Pass this in if you don't know - the document's encoding but you know Beautiful Soup's guess is - wrong. - - :param element_classes: A dictionary mapping BeautifulSoup - classes like Tag and NavigableString, to other classes you'd - like to be instantiated instead as the parse tree is - built. This is useful for subclassing Tag or NavigableString - to modify default behavior. - - :param kwargs: For backwards compatibility purposes, the - constructor accepts certain keyword arguments used in - Beautiful Soup 3. None of these arguments do anything in - Beautiful Soup 4; they will result in a warning and then be - ignored. - - Apart from this, any keyword arguments passed into the - BeautifulSoup constructor are propagated to the TreeBuilder - constructor. This makes it possible to configure a - TreeBuilder by passing in arguments, not just by saying which - one to use. - """ - if 'convertEntities' in kwargs: - del kwargs['convertEntities'] - warnings.warn( - "BS4 does not respect the convertEntities argument to the " - "BeautifulSoup constructor. Entities are always converted " - "to Unicode characters.") - - if 'markupMassage' in kwargs: - del kwargs['markupMassage'] - warnings.warn( - "BS4 does not respect the markupMassage argument to the " - "BeautifulSoup constructor. The tree builder is responsible " - "for any necessary markup massage.") - - if 'smartQuotesTo' in kwargs: - del kwargs['smartQuotesTo'] - warnings.warn( - "BS4 does not respect the smartQuotesTo argument to the " - "BeautifulSoup constructor. Smart quotes are always converted " - "to Unicode characters.") - - if 'selfClosingTags' in kwargs: - del kwargs['selfClosingTags'] - warnings.warn( - "BS4 does not respect the selfClosingTags argument to the " - "BeautifulSoup constructor. The tree builder is responsible " - "for understanding self-closing tags.") - - if 'isHTML' in kwargs: - del kwargs['isHTML'] - warnings.warn( - "BS4 does not respect the isHTML argument to the " - "BeautifulSoup constructor. Suggest you use " - "features='lxml' for HTML and features='lxml-xml' for " - "XML.") - - def deprecated_argument(old_name, new_name): - if old_name in kwargs: - warnings.warn( - 'The "%s" argument to the BeautifulSoup constructor ' - 'has been renamed to "%s."' % (old_name, new_name), - DeprecationWarning, stacklevel=3 - ) - return kwargs.pop(old_name) - return None - - parse_only = parse_only or deprecated_argument( - "parseOnlyThese", "parse_only") - - from_encoding = from_encoding or deprecated_argument( - "fromEncoding", "from_encoding") - - if from_encoding and isinstance(markup, str): - warnings.warn("You provided Unicode markup but also provided a value for from_encoding. Your from_encoding will be ignored.") - from_encoding = None - - self.element_classes = element_classes or dict() - - # We need this information to track whether or not the builder - # was specified well enough that we can omit the 'you need to - # specify a parser' warning. - original_builder = builder - original_features = features - - if isinstance(builder, type): - # A builder class was passed in; it needs to be instantiated. - builder_class = builder - builder = None - elif builder is None: - if isinstance(features, str): - features = [features] - if features is None or len(features) == 0: - features = self.DEFAULT_BUILDER_FEATURES - builder_class = builder_registry.lookup(*features) - if builder_class is None: - raise FeatureNotFound( - "Couldn't find a tree builder with the features you " - "requested: %s. Do you need to install a parser library?" - % ",".join(features)) - - # At this point either we have a TreeBuilder instance in - # builder, or we have a builder_class that we can instantiate - # with the remaining **kwargs. - if builder is None: - builder = builder_class(**kwargs) - if not original_builder and not ( - original_features == builder.NAME or - original_features in builder.ALTERNATE_NAMES - ) and markup: - # The user did not tell us which TreeBuilder to use, - # and we had to guess. Issue a warning. - if builder.is_xml: - markup_type = "XML" - else: - markup_type = "HTML" - - # This code adapted from warnings.py so that we get the same line - # of code as our warnings.warn() call gets, even if the answer is wrong - # (as it may be in a multithreading situation). - caller = None - try: - caller = sys._getframe(1) - except ValueError: - pass - if caller: - globals = caller.f_globals - line_number = caller.f_lineno - else: - globals = sys.__dict__ - line_number= 1 - filename = globals.get('__file__') - if filename: - fnl = filename.lower() - if fnl.endswith((".pyc", ".pyo")): - filename = filename[:-1] - if filename: - # If there is no filename at all, the user is most likely in a REPL, - # and the warning is not necessary. - values = dict( - filename=filename, - line_number=line_number, - parser=builder.NAME, - markup_type=markup_type - ) - warnings.warn( - self.NO_PARSER_SPECIFIED_WARNING % values, - GuessedAtParserWarning, stacklevel=2 - ) - else: - if kwargs: - warnings.warn("Keyword arguments to the BeautifulSoup constructor will be ignored. These would normally be passed into the TreeBuilder constructor, but a TreeBuilder instance was passed in as `builder`.") - - self.builder = builder - self.is_xml = builder.is_xml - self.known_xml = self.is_xml - self._namespaces = dict() - self.parse_only = parse_only - - if hasattr(markup, 'read'): # It's a file-type object. - markup = markup.read() - elif len(markup) <= 256 and ( - (isinstance(markup, bytes) and not b'<' in markup) - or (isinstance(markup, str) and not '<' in markup) - ): - # Issue warnings for a couple beginner problems - # involving passing non-markup to Beautiful Soup. - # Beautiful Soup will still parse the input as markup, - # since that is sometimes the intended behavior. - if not self._markup_is_url(markup): - self._markup_resembles_filename(markup) - - rejections = [] - success = False - for (self.markup, self.original_encoding, self.declared_html_encoding, - self.contains_replacement_characters) in ( - self.builder.prepare_markup( - markup, from_encoding, exclude_encodings=exclude_encodings)): - self.reset() - self.builder.initialize_soup(self) - try: - self._feed() - success = True - break - except ParserRejectedMarkup as e: - rejections.append(e) - pass - - if not success: - other_exceptions = [str(e) for e in rejections] - raise ParserRejectedMarkup( - "The markup you provided was rejected by the parser. Trying a different parser or a different encoding may help.\n\nOriginal exception(s) from parser:\n " + "\n ".join(other_exceptions) - ) - - # Clear out the markup and remove the builder's circular - # reference to this object. - self.markup = None - self.builder.soup = None - - def _clone(self): - """Create a new BeautifulSoup object with the same TreeBuilder, - but not associated with any markup. - - This is the first step of the deepcopy process. - """ - clone = type(self)("", None, self.builder) - - # Keep track of the encoding of the original document, - # since we won't be parsing it again. - clone.original_encoding = self.original_encoding - return clone - - def __getstate__(self): - # Frequently a tree builder can't be pickled. - d = dict(self.__dict__) - if 'builder' in d and d['builder'] is not None and not self.builder.picklable: - d['builder'] = type(self.builder) - # Store the contents as a Unicode string. - d['contents'] = [] - d['markup'] = self.decode() - - # If _most_recent_element is present, it's a Tag object left - # over from initial parse. It might not be picklable and we - # don't need it. - if '_most_recent_element' in d: - del d['_most_recent_element'] - return d - - def __setstate__(self, state): - # If necessary, restore the TreeBuilder by looking it up. - self.__dict__ = state - if isinstance(self.builder, type): - self.builder = self.builder() - elif not self.builder: - # We don't know which builder was used to build this - # parse tree, so use a default we know is always available. - self.builder = HTMLParserTreeBuilder() - self.builder.soup = self - self.reset() - self._feed() - return state - - - @classmethod - def _decode_markup(cls, markup): - """Ensure `markup` is bytes so it's safe to send into warnings.warn. - - TODO: warnings.warn had this problem back in 2010 but it might not - anymore. - """ - if isinstance(markup, bytes): - decoded = markup.decode('utf-8', 'replace') - else: - decoded = markup - return decoded - - @classmethod - def _markup_is_url(cls, markup): - """Error-handling method to raise a warning if incoming markup looks - like a URL. - - :param markup: A string. - :return: Whether or not the markup resembles a URL - closely enough to justify a warning. - """ - if isinstance(markup, bytes): - space = b' ' - cant_start_with = (b"http:", b"https:") - elif isinstance(markup, str): - space = ' ' - cant_start_with = ("http:", "https:") - else: - return False - - if any(markup.startswith(prefix) for prefix in cant_start_with): - if not space in markup: - warnings.warn( - 'The input looks more like a URL than markup. You may want to use' - ' an HTTP client like requests to get the document behind' - ' the URL, and feed that document to Beautiful Soup.', - MarkupResemblesLocatorWarning, - stacklevel=3 - ) - return True - return False - - @classmethod - def _markup_resembles_filename(cls, markup): - """Error-handling method to raise a warning if incoming markup - resembles a filename. - - :param markup: A bytestring or string. - :return: Whether or not the markup resembles a filename - closely enough to justify a warning. - """ - path_characters = '/\\' - extensions = ['.html', '.htm', '.xml', '.xhtml', '.txt'] - if isinstance(markup, bytes): - path_characters = path_characters.encode("utf8") - extensions = [x.encode('utf8') for x in extensions] - filelike = False - if any(x in markup for x in path_characters): - filelike = True - else: - lower = markup.lower() - if any(lower.endswith(ext) for ext in extensions): - filelike = True - if filelike: - warnings.warn( - 'The input looks more like a filename than markup. You may' - ' want to open this file and pass the filehandle into' - ' Beautiful Soup.', - MarkupResemblesLocatorWarning, stacklevel=3 - ) - return True - return False - - def _feed(self): - """Internal method that parses previously set markup, creating a large - number of Tag and NavigableString objects. - """ - # Convert the document to Unicode. - self.builder.reset() - - self.builder.feed(self.markup) - # Close out any unfinished strings and close all the open tags. - self.endData() - while self.currentTag.name != self.ROOT_TAG_NAME: - self.popTag() - - def reset(self): - """Reset this object to a state as though it had never parsed any - markup. - """ - Tag.__init__(self, self, self.builder, self.ROOT_TAG_NAME) - self.hidden = 1 - self.builder.reset() - self.current_data = [] - self.currentTag = None - self.tagStack = [] - self.open_tag_counter = Counter() - self.preserve_whitespace_tag_stack = [] - self.string_container_stack = [] - self._most_recent_element = None - self.pushTag(self) - - def new_tag(self, name, namespace=None, nsprefix=None, attrs={}, - sourceline=None, sourcepos=None, **kwattrs): - """Create a new Tag associated with this BeautifulSoup object. - - :param name: The name of the new Tag. - :param namespace: The URI of the new Tag's XML namespace, if any. - :param prefix: The prefix for the new Tag's XML namespace, if any. - :param attrs: A dictionary of this Tag's attribute values; can - be used instead of `kwattrs` for attributes like 'class' - that are reserved words in Python. - :param sourceline: The line number where this tag was - (purportedly) found in its source document. - :param sourcepos: The character position within `sourceline` where this - tag was (purportedly) found. - :param kwattrs: Keyword arguments for the new Tag's attribute values. - - """ - kwattrs.update(attrs) - return self.element_classes.get(Tag, Tag)( - None, self.builder, name, namespace, nsprefix, kwattrs, - sourceline=sourceline, sourcepos=sourcepos - ) - - def string_container(self, base_class=None): - container = base_class or NavigableString - - # There may be a general override of NavigableString. - container = self.element_classes.get( - container, container - ) - - # On top of that, we may be inside a tag that needs a special - # container class. - if self.string_container_stack and container is NavigableString: - container = self.builder.string_containers.get( - self.string_container_stack[-1].name, container - ) - return container - - def new_string(self, s, subclass=None): - """Create a new NavigableString associated with this BeautifulSoup - object. - """ - container = self.string_container(subclass) - return container(s) - - def insert_before(self, *args): - """This method is part of the PageElement API, but `BeautifulSoup` doesn't implement - it because there is nothing before or after it in the parse tree. - """ - raise NotImplementedError("BeautifulSoup objects don't support insert_before().") - - def insert_after(self, *args): - """This method is part of the PageElement API, but `BeautifulSoup` doesn't implement - it because there is nothing before or after it in the parse tree. - """ - raise NotImplementedError("BeautifulSoup objects don't support insert_after().") - - def popTag(self): - """Internal method called by _popToTag when a tag is closed.""" - tag = self.tagStack.pop() - if tag.name in self.open_tag_counter: - self.open_tag_counter[tag.name] -= 1 - if self.preserve_whitespace_tag_stack and tag == self.preserve_whitespace_tag_stack[-1]: - self.preserve_whitespace_tag_stack.pop() - if self.string_container_stack and tag == self.string_container_stack[-1]: - self.string_container_stack.pop() - #print("Pop", tag.name) - if self.tagStack: - self.currentTag = self.tagStack[-1] - return self.currentTag - - def pushTag(self, tag): - """Internal method called by handle_starttag when a tag is opened.""" - #print("Push", tag.name) - if self.currentTag is not None: - self.currentTag.contents.append(tag) - self.tagStack.append(tag) - self.currentTag = self.tagStack[-1] - if tag.name != self.ROOT_TAG_NAME: - self.open_tag_counter[tag.name] += 1 - if tag.name in self.builder.preserve_whitespace_tags: - self.preserve_whitespace_tag_stack.append(tag) - if tag.name in self.builder.string_containers: - self.string_container_stack.append(tag) - - def endData(self, containerClass=None): - """Method called by the TreeBuilder when the end of a data segment - occurs. - """ - if self.current_data: - current_data = ''.join(self.current_data) - # If whitespace is not preserved, and this string contains - # nothing but ASCII spaces, replace it with a single space - # or newline. - if not self.preserve_whitespace_tag_stack: - strippable = True - for i in current_data: - if i not in self.ASCII_SPACES: - strippable = False - break - if strippable: - if '\n' in current_data: - current_data = '\n' - else: - current_data = ' ' - - # Reset the data collector. - self.current_data = [] - - # Should we add this string to the tree at all? - if self.parse_only and len(self.tagStack) <= 1 and \ - (not self.parse_only.text or \ - not self.parse_only.search(current_data)): - return - - containerClass = self.string_container(containerClass) - o = containerClass(current_data) - self.object_was_parsed(o) - - def object_was_parsed(self, o, parent=None, most_recent_element=None): - """Method called by the TreeBuilder to integrate an object into the parse tree.""" - if parent is None: - parent = self.currentTag - if most_recent_element is not None: - previous_element = most_recent_element - else: - previous_element = self._most_recent_element - - next_element = previous_sibling = next_sibling = None - if isinstance(o, Tag): - next_element = o.next_element - next_sibling = o.next_sibling - previous_sibling = o.previous_sibling - if previous_element is None: - previous_element = o.previous_element - - fix = parent.next_element is not None - - o.setup(parent, previous_element, next_element, previous_sibling, next_sibling) - - self._most_recent_element = o - parent.contents.append(o) - - # Check if we are inserting into an already parsed node. - if fix: - self._linkage_fixer(parent) - - def _linkage_fixer(self, el): - """Make sure linkage of this fragment is sound.""" - - first = el.contents[0] - child = el.contents[-1] - descendant = child - - if child is first and el.parent is not None: - # Parent should be linked to first child - el.next_element = child - # We are no longer linked to whatever this element is - prev_el = child.previous_element - if prev_el is not None and prev_el is not el: - prev_el.next_element = None - # First child should be linked to the parent, and no previous siblings. - child.previous_element = el - child.previous_sibling = None - - # We have no sibling as we've been appended as the last. - child.next_sibling = None - - # This index is a tag, dig deeper for a "last descendant" - if isinstance(child, Tag) and child.contents: - descendant = child._last_descendant(False) - - # As the final step, link last descendant. It should be linked - # to the parent's next sibling (if found), else walk up the chain - # and find a parent with a sibling. It should have no next sibling. - descendant.next_element = None - descendant.next_sibling = None - target = el - while True: - if target is None: - break - elif target.next_sibling is not None: - descendant.next_element = target.next_sibling - target.next_sibling.previous_element = child - break - target = target.parent - - def _popToTag(self, name, nsprefix=None, inclusivePop=True): - """Pops the tag stack up to and including the most recent - instance of the given tag. - - If there are no open tags with the given name, nothing will be - popped. - - :param name: Pop up to the most recent tag with this name. - :param nsprefix: The namespace prefix that goes with `name`. - :param inclusivePop: It this is false, pops the tag stack up - to but *not* including the most recent instqance of the - given tag. - - """ - #print("Popping to %s" % name) - if name == self.ROOT_TAG_NAME: - # The BeautifulSoup object itself can never be popped. - return - - most_recently_popped = None - - stack_size = len(self.tagStack) - for i in range(stack_size - 1, 0, -1): - if not self.open_tag_counter.get(name): - break - t = self.tagStack[i] - if (name == t.name and nsprefix == t.prefix): - if inclusivePop: - most_recently_popped = self.popTag() - break - most_recently_popped = self.popTag() - - return most_recently_popped - - def handle_starttag(self, name, namespace, nsprefix, attrs, sourceline=None, - sourcepos=None, namespaces=None): - """Called by the tree builder when a new tag is encountered. - - :param name: Name of the tag. - :param nsprefix: Namespace prefix for the tag. - :param attrs: A dictionary of attribute values. - :param sourceline: The line number where this tag was found in its - source document. - :param sourcepos: The character position within `sourceline` where this - tag was found. - :param namespaces: A dictionary of all namespace prefix mappings - currently in scope in the document. - - If this method returns None, the tag was rejected by an active - SoupStrainer. You should proceed as if the tag had not occurred - in the document. For instance, if this was a self-closing tag, - don't call handle_endtag. - """ - # print("Start tag %s: %s" % (name, attrs)) - self.endData() - - if (self.parse_only and len(self.tagStack) <= 1 - and (self.parse_only.text - or not self.parse_only.search_tag(name, attrs))): - return None - - tag = self.element_classes.get(Tag, Tag)( - self, self.builder, name, namespace, nsprefix, attrs, - self.currentTag, self._most_recent_element, - sourceline=sourceline, sourcepos=sourcepos, - namespaces=namespaces - ) - if tag is None: - return tag - if self._most_recent_element is not None: - self._most_recent_element.next_element = tag - self._most_recent_element = tag - self.pushTag(tag) - return tag - - def handle_endtag(self, name, nsprefix=None): - """Called by the tree builder when an ending tag is encountered. - - :param name: Name of the tag. - :param nsprefix: Namespace prefix for the tag. - """ - #print("End tag: " + name) - self.endData() - self._popToTag(name, nsprefix) - - def handle_data(self, data): - """Called by the tree builder when a chunk of textual data is encountered.""" - self.current_data.append(data) - - def decode(self, pretty_print=False, - eventual_encoding=DEFAULT_OUTPUT_ENCODING, - formatter="minimal", iterator=None): - """Returns a string or Unicode representation of the parse tree - as an HTML or XML document. - - :param pretty_print: If this is True, indentation will be used to - make the document more readable. - :param eventual_encoding: The encoding of the final document. - If this is None, the document will be a Unicode string. - """ - if self.is_xml: - # Print the XML declaration - encoding_part = '' - if eventual_encoding in PYTHON_SPECIFIC_ENCODINGS: - # This is a special Python encoding; it can't actually - # go into an XML document because it means nothing - # outside of Python. - eventual_encoding = None - if eventual_encoding != None: - encoding_part = ' encoding="%s"' % eventual_encoding - prefix = '\n' % encoding_part - else: - prefix = '' - if not pretty_print: - indent_level = None - else: - indent_level = 0 - return prefix + super(BeautifulSoup, self).decode( - indent_level, eventual_encoding, formatter, iterator) - -# Aliases to make it easier to get started quickly, e.g. 'from bs4 import _soup' -_s = BeautifulSoup -_soup = BeautifulSoup - -class BeautifulStoneSoup(BeautifulSoup): - """Deprecated interface to an XML parser.""" - - def __init__(self, *args, **kwargs): - kwargs['features'] = 'xml' - warnings.warn( - 'The BeautifulStoneSoup class is deprecated. Instead of using ' - 'it, pass features="xml" into the BeautifulSoup constructor.', - DeprecationWarning, stacklevel=2 - ) - super(BeautifulStoneSoup, self).__init__(*args, **kwargs) - - -class StopParsing(Exception): - """Exception raised by a TreeBuilder if it's unable to continue parsing.""" - pass - -class FeatureNotFound(ValueError): - """Exception raised by the BeautifulSoup constructor if no parser with the - requested features is found. - """ - pass - - -#If this file is run as a script, act as an HTML pretty-printer. -if __name__ == '__main__': - import sys - soup = BeautifulSoup(sys.stdin) - print((soup.prettify())) diff --git a/uno/lib/python/bs4/builder/__init__.py b/uno/lib/python/bs4/builder/__init__.py deleted file mode 100644 index ffb31fc2..00000000 --- a/uno/lib/python/bs4/builder/__init__.py +++ /dev/null @@ -1,636 +0,0 @@ -# Use of this source code is governed by the MIT license. -__license__ = "MIT" - -from collections import defaultdict -import itertools -import re -import warnings -import sys -from bs4.element import ( - CharsetMetaAttributeValue, - ContentMetaAttributeValue, - RubyParenthesisString, - RubyTextString, - Stylesheet, - Script, - TemplateString, - nonwhitespace_re -) - -__all__ = [ - 'HTMLTreeBuilder', - 'SAXTreeBuilder', - 'TreeBuilder', - 'TreeBuilderRegistry', - ] - -# Some useful features for a TreeBuilder to have. -FAST = 'fast' -PERMISSIVE = 'permissive' -STRICT = 'strict' -XML = 'xml' -HTML = 'html' -HTML_5 = 'html5' - -class XMLParsedAsHTMLWarning(UserWarning): - """The warning issued when an HTML parser is used to parse - XML that is not XHTML. - """ - MESSAGE = """It looks like you're parsing an XML document using an HTML parser. If this really is an HTML document (maybe it's XHTML?), you can ignore or filter this warning. If it's XML, you should know that using an XML parser will be more reliable. To parse this document as XML, make sure you have the lxml package installed, and pass the keyword argument `features="xml"` into the BeautifulSoup constructor.""" - - -class TreeBuilderRegistry(object): - """A way of looking up TreeBuilder subclasses by their name or by desired - features. - """ - - def __init__(self): - self.builders_for_feature = defaultdict(list) - self.builders = [] - - def register(self, treebuilder_class): - """Register a treebuilder based on its advertised features. - - :param treebuilder_class: A subclass of Treebuilder. its .features - attribute should list its features. - """ - for feature in treebuilder_class.features: - self.builders_for_feature[feature].insert(0, treebuilder_class) - self.builders.insert(0, treebuilder_class) - - def lookup(self, *features): - """Look up a TreeBuilder subclass with the desired features. - - :param features: A list of features to look for. If none are - provided, the most recently registered TreeBuilder subclass - will be used. - :return: A TreeBuilder subclass, or None if there's no - registered subclass with all the requested features. - """ - if len(self.builders) == 0: - # There are no builders at all. - return None - - if len(features) == 0: - # They didn't ask for any features. Give them the most - # recently registered builder. - return self.builders[0] - - # Go down the list of features in order, and eliminate any builders - # that don't match every feature. - features = list(features) - features.reverse() - candidates = None - candidate_set = None - while len(features) > 0: - feature = features.pop() - we_have_the_feature = self.builders_for_feature.get(feature, []) - if len(we_have_the_feature) > 0: - if candidates is None: - candidates = we_have_the_feature - candidate_set = set(candidates) - else: - # Eliminate any candidates that don't have this feature. - candidate_set = candidate_set.intersection( - set(we_have_the_feature)) - - # The only valid candidates are the ones in candidate_set. - # Go through the original list of candidates and pick the first one - # that's in candidate_set. - if candidate_set is None: - return None - for candidate in candidates: - if candidate in candidate_set: - return candidate - return None - -# The BeautifulSoup class will take feature lists from developers and use them -# to look up builders in this registry. -builder_registry = TreeBuilderRegistry() - -class TreeBuilder(object): - """Turn a textual document into a Beautiful Soup object tree.""" - - NAME = "[Unknown tree builder]" - ALTERNATE_NAMES = [] - features = [] - - is_xml = False - picklable = False - empty_element_tags = None # A tag will be considered an empty-element - # tag when and only when it has no contents. - - # A value for these tag/attribute combinations is a space- or - # comma-separated list of CDATA, rather than a single CDATA. - DEFAULT_CDATA_LIST_ATTRIBUTES = defaultdict(list) - - # Whitespace should be preserved inside these tags. - DEFAULT_PRESERVE_WHITESPACE_TAGS = set() - - # The textual contents of tags with these names should be - # instantiated with some class other than NavigableString. - DEFAULT_STRING_CONTAINERS = {} - - USE_DEFAULT = object() - - # Most parsers don't keep track of line numbers. - TRACKS_LINE_NUMBERS = False - - def __init__(self, multi_valued_attributes=USE_DEFAULT, - preserve_whitespace_tags=USE_DEFAULT, - store_line_numbers=USE_DEFAULT, - string_containers=USE_DEFAULT, - ): - """Constructor. - - :param multi_valued_attributes: If this is set to None, the - TreeBuilder will not turn any values for attributes like - 'class' into lists. Setting this to a dictionary will - customize this behavior; look at DEFAULT_CDATA_LIST_ATTRIBUTES - for an example. - - Internally, these are called "CDATA list attributes", but that - probably doesn't make sense to an end-user, so the argument name - is `multi_valued_attributes`. - - :param preserve_whitespace_tags: A list of tags to treat - the way
 tags are treated in HTML. Tags in this list
-         are immune from pretty-printing; their contents will always be
-         output as-is.
-
-        :param string_containers: A dictionary mapping tag names to
-        the classes that should be instantiated to contain the textual
-        contents of those tags. The default is to use NavigableString
-        for every tag, no matter what the name. You can override the
-        default by changing DEFAULT_STRING_CONTAINERS.
-
-        :param store_line_numbers: If the parser keeps track of the
-         line numbers and positions of the original markup, that
-         information will, by default, be stored in each corresponding
-         `Tag` object. You can turn this off by passing
-         store_line_numbers=False. If the parser you're using doesn't 
-         keep track of this information, then setting store_line_numbers=True
-         will do nothing.
-        """
-        self.soup = None
-        if multi_valued_attributes is self.USE_DEFAULT:
-            multi_valued_attributes = self.DEFAULT_CDATA_LIST_ATTRIBUTES
-        self.cdata_list_attributes = multi_valued_attributes
-        if preserve_whitespace_tags is self.USE_DEFAULT:
-            preserve_whitespace_tags = self.DEFAULT_PRESERVE_WHITESPACE_TAGS
-        self.preserve_whitespace_tags = preserve_whitespace_tags
-        if store_line_numbers == self.USE_DEFAULT:
-            store_line_numbers = self.TRACKS_LINE_NUMBERS
-        self.store_line_numbers = store_line_numbers 
-        if string_containers == self.USE_DEFAULT:
-            string_containers = self.DEFAULT_STRING_CONTAINERS
-        self.string_containers = string_containers
-        
-    def initialize_soup(self, soup):
-        """The BeautifulSoup object has been initialized and is now
-        being associated with the TreeBuilder.
-
-        :param soup: A BeautifulSoup object.
-        """
-        self.soup = soup
-        
-    def reset(self):
-        """Do any work necessary to reset the underlying parser
-        for a new document.
-
-        By default, this does nothing.
-        """
-        pass
-
-    def can_be_empty_element(self, tag_name):
-        """Might a tag with this name be an empty-element tag?
-
-        The final markup may or may not actually present this tag as
-        self-closing.
-
-        For instance: an HTMLBuilder does not consider a 

tag to be - an empty-element tag (it's not in - HTMLBuilder.empty_element_tags). This means an empty

tag - will be presented as "

", not "

" or "

". - - The default implementation has no opinion about which tags are - empty-element tags, so a tag will be presented as an - empty-element tag if and only if it has no children. - "" will become "", and "bar" will - be left alone. - - :param tag_name: The name of a markup tag. - """ - if self.empty_element_tags is None: - return True - return tag_name in self.empty_element_tags - - def feed(self, markup): - """Run some incoming markup through some parsing process, - populating the `BeautifulSoup` object in self.soup. - - This method is not implemented in TreeBuilder; it must be - implemented in subclasses. - - :return: None. - """ - raise NotImplementedError() - - def prepare_markup(self, markup, user_specified_encoding=None, - document_declared_encoding=None, exclude_encodings=None): - """Run any preliminary steps necessary to make incoming markup - acceptable to the parser. - - :param markup: Some markup -- probably a bytestring. - :param user_specified_encoding: The user asked to try this encoding. - :param document_declared_encoding: The markup itself claims to be - in this encoding. NOTE: This argument is not used by the - calling code and can probably be removed. - :param exclude_encodings: The user asked _not_ to try any of - these encodings. - - :yield: A series of 4-tuples: - (markup, encoding, declared encoding, - has undergone character replacement) - - Each 4-tuple represents a strategy for converting the - document to Unicode and parsing it. Each strategy will be tried - in turn. - - By default, the only strategy is to parse the markup - as-is. See `LXMLTreeBuilderForXML` and - `HTMLParserTreeBuilder` for implementations that take into - account the quirks of particular parsers. - """ - yield markup, None, None, False - - def test_fragment_to_document(self, fragment): - """Wrap an HTML fragment to make it look like a document. - - Different parsers do this differently. For instance, lxml - introduces an empty tag, and html5lib - doesn't. Abstracting this away lets us write simple tests - which run HTML fragments through the parser and compare the - results against other HTML fragments. - - This method should not be used outside of tests. - - :param fragment: A string -- fragment of HTML. - :return: A string -- a full HTML document. - """ - return fragment - - def set_up_substitutions(self, tag): - """Set up any substitutions that will need to be performed on - a `Tag` when it's output as a string. - - By default, this does nothing. See `HTMLTreeBuilder` for a - case where this is used. - - :param tag: A `Tag` - :return: Whether or not a substitution was performed. - """ - return False - - def _replace_cdata_list_attribute_values(self, tag_name, attrs): - """When an attribute value is associated with a tag that can - have multiple values for that attribute, convert the string - value to a list of strings. - - Basically, replaces class="foo bar" with class=["foo", "bar"] - - NOTE: This method modifies its input in place. - - :param tag_name: The name of a tag. - :param attrs: A dictionary containing the tag's attributes. - Any appropriate attribute values will be modified in place. - """ - if not attrs: - return attrs - if self.cdata_list_attributes: - universal = self.cdata_list_attributes.get('*', []) - tag_specific = self.cdata_list_attributes.get( - tag_name.lower(), None) - for attr in list(attrs.keys()): - if attr in universal or (tag_specific and attr in tag_specific): - # We have a "class"-type attribute whose string - # value is a whitespace-separated list of - # values. Split it into a list. - value = attrs[attr] - if isinstance(value, str): - values = nonwhitespace_re.findall(value) - else: - # html5lib sometimes calls setAttributes twice - # for the same tag when rearranging the parse - # tree. On the second call the attribute value - # here is already a list. If this happens, - # leave the value alone rather than trying to - # split it again. - values = value - attrs[attr] = values - return attrs - -class SAXTreeBuilder(TreeBuilder): - """A Beautiful Soup treebuilder that listens for SAX events. - - This is not currently used for anything, but it demonstrates - how a simple TreeBuilder would work. - """ - - def feed(self, markup): - raise NotImplementedError() - - def close(self): - pass - - def startElement(self, name, attrs): - attrs = dict((key[1], value) for key, value in list(attrs.items())) - #print("Start %s, %r" % (name, attrs)) - self.soup.handle_starttag(name, attrs) - - def endElement(self, name): - #print("End %s" % name) - self.soup.handle_endtag(name) - - def startElementNS(self, nsTuple, nodeName, attrs): - # Throw away (ns, nodeName) for now. - self.startElement(nodeName, attrs) - - def endElementNS(self, nsTuple, nodeName): - # Throw away (ns, nodeName) for now. - self.endElement(nodeName) - #handler.endElementNS((ns, node.nodeName), node.nodeName) - - def startPrefixMapping(self, prefix, nodeValue): - # Ignore the prefix for now. - pass - - def endPrefixMapping(self, prefix): - # Ignore the prefix for now. - # handler.endPrefixMapping(prefix) - pass - - def characters(self, content): - self.soup.handle_data(content) - - def startDocument(self): - pass - - def endDocument(self): - pass - - -class HTMLTreeBuilder(TreeBuilder): - """This TreeBuilder knows facts about HTML. - - Such as which tags are empty-element tags. - """ - - empty_element_tags = set([ - # These are from HTML5. - 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr', - - # These are from earlier versions of HTML and are removed in HTML5. - 'basefont', 'bgsound', 'command', 'frame', 'image', 'isindex', 'nextid', 'spacer' - ]) - - # The HTML standard defines these as block-level elements. Beautiful - # Soup does not treat these elements differently from other elements, - # but it may do so eventually, and this information is available if - # you need to use it. - block_elements = set(["address", "article", "aside", "blockquote", "canvas", "dd", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hr", "li", "main", "nav", "noscript", "ol", "output", "p", "pre", "section", "table", "tfoot", "ul", "video"]) - - # These HTML tags need special treatment so they can be - # represented by a string class other than NavigableString. - # - # For some of these tags, it's because the HTML standard defines - # an unusual content model for them. I made this list by going - # through the HTML spec - # (https://html.spec.whatwg.org/#metadata-content) and looking for - # "metadata content" elements that can contain strings. - # - # The Ruby tags ( and ) are here despite being normal - # "phrasing content" tags, because the content they contain is - # qualitatively different from other text in the document, and it - # can be useful to be able to distinguish it. - # - # TODO: Arguably

 and
-            # 
-
This numeric entity is missing the final semicolon:
- -
a
-
This document contains (do you see it?)
-
This document ends with That attribute value was bogus
-The doctype is invalid because it contains extra whitespace -
That boolean attribute had no value
-
Here's a nonexistent entity: &#foo; (do you see it?)
-
This document ends before the entity finishes: > -

Paragraphs shouldn't contain block display elements, but this one does:

you see?

-Multiple values for the same attribute. -
Here's a table
-
-
This tag contains nothing but whitespace:
-

This p tag is cut off by

the end of the blockquote tag
-
Here's a nested table:
foo
This table contains bare markup
- -
This document contains a surprise doctype
- -
Tag name contains Unicode characters
- - -""" - - -class SoupTest(object): - - @property - def default_builder(self): - return default_builder - - def soup(self, markup, **kwargs): - """Build a Beautiful Soup object from markup.""" - builder = kwargs.pop('builder', self.default_builder) - return BeautifulSoup(markup, builder=builder, **kwargs) - - def document_for(self, markup, **kwargs): - """Turn an HTML fragment into a document. - - The details depend on the builder. - """ - return self.default_builder(**kwargs).test_fragment_to_document(markup) - - def assert_soup(self, to_parse, compare_parsed_to=None): - """Parse some markup using Beautiful Soup and verify that - the output markup is as expected. - """ - builder = self.default_builder - obj = BeautifulSoup(to_parse, builder=builder) - if compare_parsed_to is None: - compare_parsed_to = to_parse - - # Verify that the documents come out the same. - assert obj.decode() == self.document_for(compare_parsed_to) - - # Also run some checks on the BeautifulSoup object itself: - - # Verify that every tag that was opened was eventually closed. - - # There are no tags in the open tag counter. - assert all(v==0 for v in list(obj.open_tag_counter.values())) - - # The only tag in the tag stack is the one for the root - # document. - assert [obj.ROOT_TAG_NAME] == [x.name for x in obj.tagStack] - - assertSoupEquals = assert_soup - - def assertConnectedness(self, element): - """Ensure that next_element and previous_element are properly - set for all descendants of the given element. - """ - earlier = None - for e in element.descendants: - if earlier: - assert e == earlier.next_element - assert earlier == e.previous_element - earlier = e - - def linkage_validator(self, el, _recursive_call=False): - """Ensure proper linkage throughout the document.""" - descendant = None - # Document element should have no previous element or previous sibling. - # It also shouldn't have a next sibling. - if el.parent is None: - assert el.previous_element is None,\ - "Bad previous_element\nNODE: {}\nPREV: {}\nEXPECTED: {}".format( - el, el.previous_element, None - ) - assert el.previous_sibling is None,\ - "Bad previous_sibling\nNODE: {}\nPREV: {}\nEXPECTED: {}".format( - el, el.previous_sibling, None - ) - assert el.next_sibling is None,\ - "Bad next_sibling\nNODE: {}\nNEXT: {}\nEXPECTED: {}".format( - el, el.next_sibling, None - ) - - idx = 0 - child = None - last_child = None - last_idx = len(el.contents) - 1 - for child in el.contents: - descendant = None - - # Parent should link next element to their first child - # That child should have no previous sibling - if idx == 0: - if el.parent is not None: - assert el.next_element is child,\ - "Bad next_element\nNODE: {}\nNEXT: {}\nEXPECTED: {}".format( - el, el.next_element, child - ) - assert child.previous_element is el,\ - "Bad previous_element\nNODE: {}\nPREV: {}\nEXPECTED: {}".format( - child, child.previous_element, el - ) - assert child.previous_sibling is None,\ - "Bad previous_sibling\nNODE: {}\nPREV {}\nEXPECTED: {}".format( - child, child.previous_sibling, None - ) - - # If not the first child, previous index should link as sibling to this index - # Previous element should match the last index or the last bubbled up descendant - else: - assert child.previous_sibling is el.contents[idx - 1],\ - "Bad previous_sibling\nNODE: {}\nPREV {}\nEXPECTED {}".format( - child, child.previous_sibling, el.contents[idx - 1] - ) - assert el.contents[idx - 1].next_sibling is child,\ - "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format( - el.contents[idx - 1], el.contents[idx - 1].next_sibling, child - ) - - if last_child is not None: - assert child.previous_element is last_child,\ - "Bad previous_element\nNODE: {}\nPREV {}\nEXPECTED {}\nCONTENTS {}".format( - child, child.previous_element, last_child, child.parent.contents - ) - assert last_child.next_element is child,\ - "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format( - last_child, last_child.next_element, child - ) - - if isinstance(child, Tag) and child.contents: - descendant = self.linkage_validator(child, True) - # A bubbled up descendant should have no next siblings - assert descendant.next_sibling is None,\ - "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format( - descendant, descendant.next_sibling, None - ) - - # Mark last child as either the bubbled up descendant or the current child - if descendant is not None: - last_child = descendant - else: - last_child = child - - # If last child, there are non next siblings - if idx == last_idx: - assert child.next_sibling is None,\ - "Bad next_sibling\nNODE: {}\nNEXT {}\nEXPECTED {}".format( - child, child.next_sibling, None - ) - idx += 1 - - child = descendant if descendant is not None else child - if child is None: - child = el - - if not _recursive_call and child is not None: - target = el - while True: - if target is None: - assert child.next_element is None, \ - "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format( - child, child.next_element, None - ) - break - elif target.next_sibling is not None: - assert child.next_element is target.next_sibling, \ - "Bad next_element\nNODE: {}\nNEXT {}\nEXPECTED {}".format( - child, child.next_element, target.next_sibling - ) - break - target = target.parent - - # We are done, so nothing to return - return None - else: - # Return the child to the recursive caller - return child - - def assert_selects(self, tags, should_match): - """Make sure that the given tags have the correct text. - - This is used in tests that define a bunch of tags, each - containing a single string, and then select certain strings by - some mechanism. - """ - assert [tag.string for tag in tags] == should_match - - def assert_selects_ids(self, tags, should_match): - """Make sure that the given tags have the correct IDs. - - This is used in tests that define a bunch of tags, each - containing a single string, and then select certain strings by - some mechanism. - """ - assert [tag['id'] for tag in tags] == should_match - - -class TreeBuilderSmokeTest(object): - # Tests that are common to HTML and XML tree builders. - - @pytest.mark.parametrize( - "multi_valued_attributes", - [None, {}, dict(b=['class']), {'*': ['notclass']}] - ) - def test_attribute_not_multi_valued(self, multi_valued_attributes): - markup = '' - soup = self.soup(markup, multi_valued_attributes=multi_valued_attributes) - assert soup.a['class'] == 'a b c' - - @pytest.mark.parametrize( - "multi_valued_attributes", [dict(a=['class']), {'*': ['class']}] - ) - def test_attribute_multi_valued(self, multi_valued_attributes): - markup = '' - soup = self.soup( - markup, multi_valued_attributes=multi_valued_attributes - ) - assert soup.a['class'] == ['a', 'b', 'c'] - - def test_invalid_doctype(self): - markup = 'content' - markup = '' - soup = self.soup(markup) - -class HTMLTreeBuilderSmokeTest(TreeBuilderSmokeTest): - - """A basic test of a treebuilder's competence. - - Any HTML treebuilder, present or future, should be able to pass - these tests. With invalid markup, there's room for interpretation, - and different parsers can handle it differently. But with the - markup in these tests, there's not much room for interpretation. - """ - - def test_empty_element_tags(self): - """Verify that all HTML4 and HTML5 empty element (aka void element) tags - are handled correctly. - """ - for name in [ - 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr', - 'spacer', 'frame' - ]: - soup = self.soup("") - new_tag = soup.new_tag(name) - assert new_tag.is_empty_element == True - - def test_special_string_containers(self): - soup = self.soup( - "" - ) - assert isinstance(soup.style.string, Stylesheet) - assert isinstance(soup.script.string, Script) - - soup = self.soup( - "" - ) - assert isinstance(soup.style.string, Stylesheet) - # The contents of the style tag resemble an HTML comment, but - # it's not treated as a comment. - assert soup.style.string == "" - assert isinstance(soup.style.string, Stylesheet) - - def test_pickle_and_unpickle_identity(self): - # Pickling a tree, then unpickling it, yields a tree identical - # to the original. - tree = self.soup("foo") - dumped = pickle.dumps(tree, 2) - loaded = pickle.loads(dumped) - assert loaded.__class__ == BeautifulSoup - assert loaded.decode() == tree.decode() - - def assertDoctypeHandled(self, doctype_fragment): - """Assert that a given doctype string is handled correctly.""" - doctype_str, soup = self._document_with_doctype(doctype_fragment) - - # Make sure a Doctype object was created. - doctype = soup.contents[0] - assert doctype.__class__ == Doctype - assert doctype == doctype_fragment - assert soup.encode("utf8")[:len(doctype_str)] == doctype_str - - # Make sure that the doctype was correctly associated with the - # parse tree and that the rest of the document parsed. - assert soup.p.contents[0] == 'foo' - - def _document_with_doctype(self, doctype_fragment, doctype_string="DOCTYPE"): - """Generate and parse a document with the given doctype.""" - doctype = '' % (doctype_string, doctype_fragment) - markup = doctype + '\n

foo

' - soup = self.soup(markup) - return doctype.encode("utf8"), soup - - def test_normal_doctypes(self): - """Make sure normal, everyday HTML doctypes are handled correctly.""" - self.assertDoctypeHandled("html") - self.assertDoctypeHandled( - 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"') - - def test_empty_doctype(self): - soup = self.soup("") - doctype = soup.contents[0] - assert "" == doctype.strip() - - def test_mixed_case_doctype(self): - # A lowercase or mixed-case doctype becomes a Doctype. - for doctype_fragment in ("doctype", "DocType"): - doctype_str, soup = self._document_with_doctype( - "html", doctype_fragment - ) - - # Make sure a Doctype object was created and that the DOCTYPE - # is uppercase. - doctype = soup.contents[0] - assert doctype.__class__ == Doctype - assert doctype == "html" - assert soup.encode("utf8")[:len(doctype_str)] == b"" - - # Make sure that the doctype was correctly associated with the - # parse tree and that the rest of the document parsed. - assert soup.p.contents[0] == 'foo' - - def test_public_doctype_with_url(self): - doctype = 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"' - self.assertDoctypeHandled(doctype) - - def test_system_doctype(self): - self.assertDoctypeHandled('foo SYSTEM "http://www.example.com/"') - - def test_namespaced_system_doctype(self): - # We can handle a namespaced doctype with a system ID. - self.assertDoctypeHandled('xsl:stylesheet SYSTEM "htmlent.dtd"') - - def test_namespaced_public_doctype(self): - # Test a namespaced doctype with a public id. - self.assertDoctypeHandled('xsl:stylesheet PUBLIC "htmlent.dtd"') - - def test_real_xhtml_document(self): - """A real XHTML document should come out more or less the same as it went in.""" - markup = b""" - - -Hello. -Goodbye. -""" - with warnings.catch_warnings(record=True) as w: - soup = self.soup(markup) - assert soup.encode("utf-8").replace(b"\n", b"") == markup.replace(b"\n", b"") - - # No warning was issued about parsing an XML document as HTML, - # because XHTML is both. - assert w == [] - - - def test_namespaced_html(self): - # When a namespaced XML document is parsed as HTML it should - # be treated as HTML with weird tag names. - markup = b"""content""" - with warnings.catch_warnings(record=True) as w: - soup = self.soup(markup) - - assert 2 == len(soup.find_all("ns1:foo")) - - # n.b. no "you're parsing XML as HTML" warning was given - # because there was no XML declaration. - assert [] == w - - def test_detect_xml_parsed_as_html(self): - # A warning is issued when parsing an XML document as HTML, - # but basic stuff should still work. - markup = b"""string""" - with warnings.catch_warnings(record=True) as w: - soup = self.soup(markup) - assert soup.tag.string == 'string' - [warning] = w - assert isinstance(warning.message, XMLParsedAsHTMLWarning) - assert str(warning.message) == XMLParsedAsHTMLWarning.MESSAGE - - # NOTE: the warning is not issued if the document appears to - # be XHTML (tested with test_real_xhtml_document in the - # superclass) or if there is no XML declaration (tested with - # test_namespaced_html in the superclass). - - def test_processing_instruction(self): - # We test both Unicode and bytestring to verify that - # process_markup correctly sets processing_instruction_class - # even when the markup is already Unicode and there is no - # need to process anything. - markup = """""" - soup = self.soup(markup) - assert markup == soup.decode() - - markup = b"""""" - soup = self.soup(markup) - assert markup == soup.encode("utf8") - - def test_deepcopy(self): - """Make sure you can copy the tree builder. - - This is important because the builder is part of a - BeautifulSoup object, and we want to be able to copy that. - """ - copy.deepcopy(self.default_builder) - - def test_p_tag_is_never_empty_element(self): - """A

tag is never designated as an empty-element tag. - - Even if the markup shows it as an empty-element tag, it - shouldn't be presented that way. - """ - soup = self.soup("

") - assert not soup.p.is_empty_element - assert str(soup.p) == "

" - - def test_unclosed_tags_get_closed(self): - """A tag that's not closed by the end of the document should be closed. - - This applies to all tags except empty-element tags. - """ - self.assert_soup("

", "

") - self.assert_soup("", "") - - self.assert_soup("
", "
") - - def test_br_is_always_empty_element_tag(self): - """A
tag is designated as an empty-element tag. - - Some parsers treat

as one
tag, some parsers as - two tags, but it should always be an empty-element tag. - """ - soup = self.soup("

") - assert soup.br.is_empty_element - assert str(soup.br) == "
" - - def test_nested_formatting_elements(self): - self.assert_soup("") - - def test_double_head(self): - html = ''' - - -Ordinary HEAD element test - - - -Hello, world! - - -''' - soup = self.soup(html) - assert "text/javascript" == soup.find('script')['type'] - - def test_comment(self): - # Comments are represented as Comment objects. - markup = "

foobaz

" - self.assert_soup(markup) - - soup = self.soup(markup) - comment = soup.find(string="foobar") - assert comment.__class__ == Comment - - # The comment is properly integrated into the tree. - foo = soup.find(string="foo") - assert comment == foo.next_element - baz = soup.find(string="baz") - assert comment == baz.previous_element - - def test_preserved_whitespace_in_pre_and_textarea(self): - """Whitespace must be preserved in
 and \n"
-        self.assert_soup(pre_markup)
-        self.assert_soup(textarea_markup)
-
-        soup = self.soup(pre_markup)
-        assert soup.pre.prettify() == pre_markup
-
-        soup = self.soup(textarea_markup)
-        assert soup.textarea.prettify() == textarea_markup
-
-        soup = self.soup("")
-        assert soup.textarea.prettify() == "\n"
-
-    def test_nested_inline_elements(self):
-        """Inline elements can be nested indefinitely."""
-        b_tag = "Inside a B tag"
-        self.assert_soup(b_tag)
-
-        nested_b_tag = "

A nested tag

" - self.assert_soup(nested_b_tag) - - double_nested_b_tag = "

A doubly nested tag

" - self.assert_soup(nested_b_tag) - - def test_nested_block_level_elements(self): - """Block elements can be nested.""" - soup = self.soup('

Foo

') - blockquote = soup.blockquote - assert blockquote.p.b.string == 'Foo' - assert blockquote.b.string == 'Foo' - - def test_correctly_nested_tables(self): - """One table can go inside another one.""" - markup = ('' - '' - "') - - self.assert_soup( - markup, - '
Here's another table:" - '' - '' - '
foo
Here\'s another table:' - '
foo
' - '
') - - self.assert_soup( - "" - "" - "
Foo
Bar
Baz
") - - def test_multivalued_attribute_with_whitespace(self): - # Whitespace separating the values of a multi-valued attribute - # should be ignored. - - markup = '
' - soup = self.soup(markup) - assert ['foo', 'bar'] == soup.div['class'] - - # If you search by the literal name of the class it's like the whitespace - # wasn't there. - assert soup.div == soup.find('div', class_="foo bar") - - def test_deeply_nested_multivalued_attribute(self): - # html5lib can set the attributes of the same tag many times - # as it rearranges the tree. This has caused problems with - # multivalued attributes. - markup = '
' - soup = self.soup(markup) - assert ["css"] == soup.div.div['class'] - - def test_multivalued_attribute_on_html(self): - # html5lib uses a different API to set the attributes ot the - # tag. This has caused problems with multivalued - # attributes. - markup = '' - soup = self.soup(markup) - assert ["a", "b"] == soup.html['class'] - - def test_angle_brackets_in_attribute_values_are_escaped(self): - self.assert_soup('', '') - - def test_strings_resembling_character_entity_references(self): - # "&T" and "&p" look like incomplete character entities, but they are - # not. - self.assert_soup( - "

• AT&T is in the s&p 500

", - "

\u2022 AT&T is in the s&p 500

" - ) - - def test_apos_entity(self): - self.assert_soup( - "

Bob's Bar

", - "

Bob's Bar

", - ) - - def test_entities_in_foreign_document_encoding(self): - # “ and ” are invalid numeric entities referencing - # Windows-1252 characters. - references a character common - # to Windows-1252 and Unicode, and ☃ references a - # character only found in Unicode. - # - # All of these entities should be converted to Unicode - # characters. - markup = "

“Hello” -☃

" - soup = self.soup(markup) - assert "“Hello” -☃" == soup.p.string - - def test_entities_in_attributes_converted_to_unicode(self): - expect = '

' - self.assert_soup('

', expect) - self.assert_soup('

', expect) - self.assert_soup('

', expect) - self.assert_soup('

', expect) - - def test_entities_in_text_converted_to_unicode(self): - expect = '

pi\N{LATIN SMALL LETTER N WITH TILDE}ata

' - self.assert_soup("

piñata

", expect) - self.assert_soup("

piñata

", expect) - self.assert_soup("

piñata

", expect) - self.assert_soup("

piñata

", expect) - - def test_quot_entity_converted_to_quotation_mark(self): - self.assert_soup("

I said "good day!"

", - '

I said "good day!"

') - - def test_out_of_range_entity(self): - expect = "\N{REPLACEMENT CHARACTER}" - self.assert_soup("�", expect) - self.assert_soup("�", expect) - self.assert_soup("�", expect) - - def test_multipart_strings(self): - "Mostly to prevent a recurrence of a bug in the html5lib treebuilder." - soup = self.soup("

\nfoo

") - assert "p" == soup.h2.string.next_element.name - assert "p" == soup.p.name - self.assertConnectedness(soup) - - def test_empty_element_tags(self): - """Verify consistent handling of empty-element tags, - no matter how they come in through the markup. - """ - self.assert_soup('


', "


") - self.assert_soup('


', "


") - - def test_head_tag_between_head_and_body(self): - "Prevent recurrence of a bug in the html5lib treebuilder." - content = """ - - foo - -""" - soup = self.soup(content) - assert soup.html.body is not None - self.assertConnectedness(soup) - - def test_multiple_copies_of_a_tag(self): - "Prevent recurrence of a bug in the html5lib treebuilder." - content = """ - - - - - -""" - soup = self.soup(content) - self.assertConnectedness(soup.article) - - def test_basic_namespaces(self): - """Parsers don't need to *understand* namespaces, but at the - very least they should not choke on namespaces or lose - data.""" - - markup = b'4' - soup = self.soup(markup) - assert markup == soup.encode() - html = soup.html - assert 'http://www.w3.org/1999/xhtml' == soup.html['xmlns'] - assert 'http://www.w3.org/1998/Math/MathML' == soup.html['xmlns:mathml'] - assert 'http://www.w3.org/2000/svg' == soup.html['xmlns:svg'] - - def test_multivalued_attribute_value_becomes_list(self): - markup = b'' - soup = self.soup(markup) - assert ['foo', 'bar'] == soup.a['class'] - - # - # Generally speaking, tests below this point are more tests of - # Beautiful Soup than tests of the tree builders. But parsers are - # weird, so we run these tests separately for every tree builder - # to detect any differences between them. - # - - def test_can_parse_unicode_document(self): - # A seemingly innocuous document... but it's in Unicode! And - # it contains characters that can't be represented in the - # encoding found in the declaration! The horror! - markup = 'Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!' - soup = self.soup(markup) - assert 'Sacr\xe9 bleu!' == soup.body.string - - def test_soupstrainer(self): - """Parsers should be able to work with SoupStrainers.""" - strainer = SoupStrainer("b") - soup = self.soup("A bold statement", - parse_only=strainer) - assert soup.decode() == "bold" - - def test_single_quote_attribute_values_become_double_quotes(self): - self.assert_soup("", - '') - - def test_attribute_values_with_nested_quotes_are_left_alone(self): - text = """a""" - self.assert_soup(text) - - def test_attribute_values_with_double_nested_quotes_get_quoted(self): - text = """a""" - soup = self.soup(text) - soup.foo['attr'] = 'Brawls happen at "Bob\'s Bar"' - self.assert_soup( - soup.foo.decode(), - """a""") - - def test_ampersand_in_attribute_value_gets_escaped(self): - self.assert_soup('', - '') - - self.assert_soup( - 'foo', - 'foo') - - def test_escaped_ampersand_in_attribute_value_is_left_alone(self): - self.assert_soup('') - - def test_entities_in_strings_converted_during_parsing(self): - # Both XML and HTML entities are converted to Unicode characters - # during parsing. - text = "

<<sacré bleu!>>

" - expected = "

<<sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!>>

" - self.assert_soup(text, expected) - - def test_smart_quotes_converted_on_the_way_in(self): - # Microsoft smart quotes are converted to Unicode characters during - # parsing. - quote = b"

\x91Foo\x92

" - soup = self.soup(quote) - assert soup.p.string == "\N{LEFT SINGLE QUOTATION MARK}Foo\N{RIGHT SINGLE QUOTATION MARK}" - - def test_non_breaking_spaces_converted_on_the_way_in(self): - soup = self.soup("  ") - assert soup.a.string == "\N{NO-BREAK SPACE}" * 2 - - def test_entities_converted_on_the_way_out(self): - text = "

<<sacré bleu!>>

" - expected = "

<<sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!>>

".encode("utf-8") - soup = self.soup(text) - assert soup.p.encode("utf-8") == expected - - def test_real_iso_8859_document(self): - # Smoke test of interrelated functionality, using an - # easy-to-understand document. - - # Here it is in Unicode. Note that it claims to be in ISO-8859-1. - unicode_html = '

Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!

' - - # That's because we're going to encode it into ISO-8859-1, - # and use that to test. - iso_latin_html = unicode_html.encode("iso-8859-1") - - # Parse the ISO-8859-1 HTML. - soup = self.soup(iso_latin_html) - - # Encode it to UTF-8. - result = soup.encode("utf-8") - - # What do we expect the result to look like? Well, it would - # look like unicode_html, except that the META tag would say - # UTF-8 instead of ISO-8859-1. - expected = unicode_html.replace("ISO-8859-1", "utf-8") - - # And, of course, it would be in UTF-8, not Unicode. - expected = expected.encode("utf-8") - - # Ta-da! - assert result == expected - - def test_real_shift_jis_document(self): - # Smoke test to make sure the parser can handle a document in - # Shift-JIS encoding, without choking. - shift_jis_html = ( - b'
'
-            b'\x82\xb1\x82\xea\x82\xcdShift-JIS\x82\xc5\x83R\x81[\x83f'
-            b'\x83B\x83\x93\x83O\x82\xb3\x82\xea\x82\xbd\x93\xfa\x96{\x8c'
-            b'\xea\x82\xcc\x83t\x83@\x83C\x83\x8b\x82\xc5\x82\xb7\x81B'
-            b'
') - unicode_html = shift_jis_html.decode("shift-jis") - soup = self.soup(unicode_html) - - # Make sure the parse tree is correctly encoded to various - # encodings. - assert soup.encode("utf-8") == unicode_html.encode("utf-8") - assert soup.encode("euc_jp") == unicode_html.encode("euc_jp") - - def test_real_hebrew_document(self): - # A real-world test to make sure we can convert ISO-8859-9 (a - # Hebrew encoding) to UTF-8. - hebrew_document = b'Hebrew (ISO 8859-8) in Visual Directionality

Hebrew (ISO 8859-8) in Visual Directionality

\xed\xe5\xec\xf9' - soup = self.soup( - hebrew_document, from_encoding="iso8859-8") - # Some tree builders call it iso8859-8, others call it iso-8859-9. - # That's not a difference we really care about. - assert soup.original_encoding in ('iso8859-8', 'iso-8859-8') - assert soup.encode('utf-8') == ( - hebrew_document.decode("iso8859-8").encode("utf-8") - ) - - def test_meta_tag_reflects_current_encoding(self): - # Here's the tag saying that a document is - # encoded in Shift-JIS. - meta_tag = ('') - - # Here's a document incorporating that meta tag. - shift_jis_html = ( - '\n%s\n' - '' - 'Shift-JIS markup goes here.') % meta_tag - soup = self.soup(shift_jis_html) - - # Parse the document, and the charset is seemingly unaffected. - parsed_meta = soup.find('meta', {'http-equiv': 'Content-type'}) - content = parsed_meta['content'] - assert 'text/html; charset=x-sjis' == content - - # But that value is actually a ContentMetaAttributeValue object. - assert isinstance(content, ContentMetaAttributeValue) - - # And it will take on a value that reflects its current - # encoding. - assert 'text/html; charset=utf8' == content.encode("utf8") - - # For the rest of the story, see TestSubstitutions in - # test_tree.py. - - def test_html5_style_meta_tag_reflects_current_encoding(self): - # Here's the tag saying that a document is - # encoded in Shift-JIS. - meta_tag = ('') - - # Here's a document incorporating that meta tag. - shift_jis_html = ( - '\n%s\n' - '' - 'Shift-JIS markup goes here.') % meta_tag - soup = self.soup(shift_jis_html) - - # Parse the document, and the charset is seemingly unaffected. - parsed_meta = soup.find('meta', id="encoding") - charset = parsed_meta['charset'] - assert 'x-sjis' == charset - - # But that value is actually a CharsetMetaAttributeValue object. - assert isinstance(charset, CharsetMetaAttributeValue) - - # And it will take on a value that reflects its current - # encoding. - assert 'utf8' == charset.encode("utf8") - - def test_python_specific_encodings_not_used_in_charset(self): - # You can encode an HTML document using a Python-specific - # encoding, but that encoding won't be mentioned _inside_ the - # resulting document. Instead, the document will appear to - # have no encoding. - for markup in [ - b'' - b'' - ]: - soup = self.soup(markup) - for encoding in PYTHON_SPECIFIC_ENCODINGS: - if encoding in ( - 'idna', 'mbcs', 'oem', 'undefined', - 'string_escape', 'string-escape' - ): - # For one reason or another, these will raise an - # exception if we actually try to use them, so don't - # bother. - continue - encoded = soup.encode(encoding) - assert b'meta charset=""' in encoded - assert encoding.encode("ascii") not in encoded - - def test_tag_with_no_attributes_can_have_attributes_added(self): - data = self.soup("text") - data.a['foo'] = 'bar' - assert 'text' == data.a.decode() - - def test_closing_tag_with_no_opening_tag(self): - # Without BeautifulSoup.open_tag_counter, the tag will - # cause _popToTag to be called over and over again as we look - # for a tag that wasn't there. The result is that 'text2' - # will show up outside the body of the document. - soup = self.soup("

text1

text2
") - assert "

text1

text2
" == soup.body.decode() - - def test_worst_case(self): - """Test the worst case (currently) for linking issues.""" - - soup = self.soup(BAD_DOCUMENT) - self.linkage_validator(soup) - - -class XMLTreeBuilderSmokeTest(TreeBuilderSmokeTest): - - def test_pickle_and_unpickle_identity(self): - # Pickling a tree, then unpickling it, yields a tree identical - # to the original. - tree = self.soup("foo") - dumped = pickle.dumps(tree, 2) - loaded = pickle.loads(dumped) - assert loaded.__class__ == BeautifulSoup - assert loaded.decode() == tree.decode() - - def test_docstring_generated(self): - soup = self.soup("") - assert soup.encode() == b'\n' - - def test_xml_declaration(self): - markup = b"""\n""" - soup = self.soup(markup) - assert markup == soup.encode("utf8") - - def test_python_specific_encodings_not_used_in_xml_declaration(self): - # You can encode an XML document using a Python-specific - # encoding, but that encoding won't be mentioned _inside_ the - # resulting document. - markup = b"""\n""" - soup = self.soup(markup) - for encoding in PYTHON_SPECIFIC_ENCODINGS: - if encoding in ( - 'idna', 'mbcs', 'oem', 'undefined', - 'string_escape', 'string-escape' - ): - # For one reason or another, these will raise an - # exception if we actually try to use them, so don't - # bother. - continue - encoded = soup.encode(encoding) - assert b'' in encoded - assert encoding.encode("ascii") not in encoded - - def test_processing_instruction(self): - markup = b"""\n""" - soup = self.soup(markup) - assert markup == soup.encode("utf8") - - def test_real_xhtml_document(self): - """A real XHTML document should come out *exactly* the same as it went in.""" - markup = b""" - - -Hello. -Goodbye. -""" - soup = self.soup(markup) - assert soup.encode("utf-8") == markup - - def test_nested_namespaces(self): - doc = b""" - - - - - -""" - soup = self.soup(doc) - assert doc == soup.encode() - - def test_formatter_processes_script_tag_for_xml_documents(self): - doc = """ - -""" - soup = BeautifulSoup(doc, "lxml-xml") - # lxml would have stripped this while parsing, but we can add - # it later. - soup.script.string = 'console.log("< < hey > > ");' - encoded = soup.encode() - assert b"< < hey > >" in encoded - - def test_can_parse_unicode_document(self): - markup = 'Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!' - soup = self.soup(markup) - assert 'Sacr\xe9 bleu!' == soup.root.string - - def test_can_parse_unicode_document_begining_with_bom(self): - markup = '\N{BYTE ORDER MARK}Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!' - soup = self.soup(markup) - assert 'Sacr\xe9 bleu!' == soup.root.string - - def test_popping_namespaced_tag(self): - markup = 'b2012-07-02T20:33:42Zcd' - soup = self.soup(markup) - assert str(soup.rss) == markup - - def test_docstring_includes_correct_encoding(self): - soup = self.soup("") - assert soup.encode("latin1") == b'\n' - - def test_large_xml_document(self): - """A large XML document should come out the same as it went in.""" - markup = (b'\n' - + b'0' * (2**12) - + b'') - soup = self.soup(markup) - assert soup.encode("utf-8") == markup - - def test_tags_are_empty_element_if_and_only_if_they_are_empty(self): - self.assert_soup("

", "

") - self.assert_soup("

foo

") - - def test_namespaces_are_preserved(self): - markup = 'This tag is in the a namespaceThis tag is in the b namespace' - soup = self.soup(markup) - root = soup.root - assert "http://example.com/" == root['xmlns:a'] - assert "http://example.net/" == root['xmlns:b'] - - def test_closing_namespaced_tag(self): - markup = '

20010504

' - soup = self.soup(markup) - assert str(soup.p) == markup - - def test_namespaced_attributes(self): - markup = '' - soup = self.soup(markup) - assert str(soup.foo) == markup - - def test_namespaced_attributes_xml_namespace(self): - markup = 'bar' - soup = self.soup(markup) - assert str(soup.foo) == markup - - def test_find_by_prefixed_name(self): - doc = """ - - foo - bar - baz - -""" - soup = self.soup(doc) - - # There are three tags. - assert 3 == len(soup.find_all('tag')) - - # But two of them are ns1:tag and one of them is ns2:tag. - assert 2 == len(soup.find_all('ns1:tag')) - assert 1 == len(soup.find_all('ns2:tag')) - - assert 1, len(soup.find_all('ns2:tag', key='value')) - assert 3, len(soup.find_all(['ns1:tag', 'ns2:tag'])) - - def test_copy_tag_preserves_namespace(self): - xml = """ -""" - - soup = self.soup(xml) - tag = soup.document - duplicate = copy.copy(tag) - - # The two tags have the same namespace prefix. - assert tag.prefix == duplicate.prefix - - def test_worst_case(self): - """Test the worst case (currently) for linking issues.""" - - soup = self.soup(BAD_DOCUMENT) - self.linkage_validator(soup) - - -class HTML5TreeBuilderSmokeTest(HTMLTreeBuilderSmokeTest): - """Smoke test for a tree builder that supports HTML5.""" - - def test_real_xhtml_document(self): - # Since XHTML is not HTML5, HTML5 parsers are not tested to handle - # XHTML documents in any particular way. - pass - - def test_html_tags_have_namespace(self): - markup = "" - soup = self.soup(markup) - assert "http://www.w3.org/1999/xhtml" == soup.a.namespace - - def test_svg_tags_have_namespace(self): - markup = '' - soup = self.soup(markup) - namespace = "http://www.w3.org/2000/svg" - assert namespace == soup.svg.namespace - assert namespace == soup.circle.namespace - - - def test_mathml_tags_have_namespace(self): - markup = '5' - soup = self.soup(markup) - namespace = 'http://www.w3.org/1998/Math/MathML' - assert namespace == soup.math.namespace - assert namespace == soup.msqrt.namespace - - def test_xml_declaration_becomes_comment(self): - markup = '' - soup = self.soup(markup) - assert isinstance(soup.contents[0], Comment) - assert soup.contents[0] == '?xml version="1.0" encoding="utf-8"?' - assert "html" == soup.contents[0].next_element.name diff --git a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase b/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase deleted file mode 100644 index 4828f8a4..00000000 --- a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase +++ /dev/null @@ -1 +0,0 @@ -

\ No newline at end of file diff --git a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase b/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase deleted file mode 100644 index 8a585ce9..00000000 Binary files a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase and /dev/null differ diff --git a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase b/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase deleted file mode 100644 index 0fe66dd2..00000000 Binary files a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase and /dev/null differ diff --git a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase b/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase deleted file mode 100644 index fd411427..00000000 Binary files a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase and /dev/null differ diff --git a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase b/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase deleted file mode 100644 index 6248b2c5..00000000 --- a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase +++ /dev/null @@ -1 +0,0 @@ - >tet>< \ No newline at end of file diff --git a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase b/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase deleted file mode 100644 index 107da539..00000000 Binary files a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase and /dev/null differ diff --git a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase b/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase deleted file mode 100644 index 367106c7..00000000 --- a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase +++ /dev/null @@ -1,2 +0,0 @@ - -t \ No newline at end of file diff --git a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase b/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase deleted file mode 100644 index a823d557..00000000 Binary files a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase and /dev/null differ diff --git a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase b/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase deleted file mode 100644 index 65af44d8..00000000 Binary files a/uno/lib/python/bs4/tests/fuzz/clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase and /dev/null differ diff --git a/uno/lib/python/bs4/tests/fuzz/crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase b/uno/lib/python/bs4/tests/fuzz/crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase deleted file mode 100644 index 5559adbb..00000000 Binary files a/uno/lib/python/bs4/tests/fuzz/crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase and /dev/null differ diff --git a/uno/lib/python/bs4/tests/fuzz/crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase b/uno/lib/python/bs4/tests/fuzz/crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase deleted file mode 100644 index 88571155..00000000 Binary files a/uno/lib/python/bs4/tests/fuzz/crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase and /dev/null differ diff --git a/uno/lib/python/bs4/tests/test_builder.py b/uno/lib/python/bs4/tests/test_builder.py deleted file mode 100644 index 75370712..00000000 --- a/uno/lib/python/bs4/tests/test_builder.py +++ /dev/null @@ -1,29 +0,0 @@ -import pytest -from unittest.mock import patch -from bs4.builder import DetectsXMLParsedAsHTML - -class TestDetectsXMLParsedAsHTML(object): - - @pytest.mark.parametrize( - "markup,looks_like_xml", - [("No xml declaration", False), - ("obviously HTMLActually XHTML", False), - (" < html>Tricky XHTML", False), - ("", True), - ] - ) - def test_warn_if_markup_looks_like_xml(self, markup, looks_like_xml): - # Test of our ability to guess at whether markup looks XML-ish - # _and_ not HTML-ish. - with patch('bs4.builder.DetectsXMLParsedAsHTML._warn') as mock: - for data in markup, markup.encode('utf8'): - result = DetectsXMLParsedAsHTML.warn_if_markup_looks_like_xml( - data - ) - assert result == looks_like_xml - if looks_like_xml: - assert mock.called - else: - assert not mock.called - mock.reset_mock() diff --git a/uno/lib/python/bs4/tests/test_builder_registry.py b/uno/lib/python/bs4/tests/test_builder_registry.py deleted file mode 100644 index 9327174f..00000000 --- a/uno/lib/python/bs4/tests/test_builder_registry.py +++ /dev/null @@ -1,137 +0,0 @@ -"""Tests of the builder registry.""" - -import pytest -import warnings - -from bs4 import BeautifulSoup -from bs4.builder import ( - builder_registry as registry, - HTMLParserTreeBuilder, - TreeBuilderRegistry, -) - -from . import ( - HTML5LIB_PRESENT, - LXML_PRESENT, -) - -if HTML5LIB_PRESENT: - from bs4.builder import HTML5TreeBuilder - -if LXML_PRESENT: - from bs4.builder import ( - LXMLTreeBuilderForXML, - LXMLTreeBuilder, - ) - - -# TODO: Split out the lxml and html5lib tests into their own classes -# and gate with pytest.mark.skipIf. -class TestBuiltInRegistry(object): - """Test the built-in registry with the default builders registered.""" - - def test_combination(self): - assert registry.lookup('strict', 'html') == HTMLParserTreeBuilder - if LXML_PRESENT: - assert registry.lookup('fast', 'html') == LXMLTreeBuilder - assert registry.lookup('permissive', 'xml') == LXMLTreeBuilderForXML - if HTML5LIB_PRESENT: - assert registry.lookup('html5lib', 'html') == HTML5TreeBuilder - - def test_lookup_by_markup_type(self): - if LXML_PRESENT: - assert registry.lookup('html') == LXMLTreeBuilder - assert registry.lookup('xml') == LXMLTreeBuilderForXML - else: - assert registry.lookup('xml') == None - if HTML5LIB_PRESENT: - assert registry.lookup('html') == HTML5TreeBuilder - else: - assert registry.lookup('html') == HTMLParserTreeBuilder - - def test_named_library(self): - if LXML_PRESENT: - assert registry.lookup('lxml', 'xml') == LXMLTreeBuilderForXML - assert registry.lookup('lxml', 'html') == LXMLTreeBuilder - if HTML5LIB_PRESENT: - assert registry.lookup('html5lib') == HTML5TreeBuilder - - assert registry.lookup('html.parser') == HTMLParserTreeBuilder - - def test_beautifulsoup_constructor_does_lookup(self): - - with warnings.catch_warnings(record=True) as w: - # This will create a warning about not explicitly - # specifying a parser, but we'll ignore it. - - # You can pass in a string. - BeautifulSoup("", features="html") - # Or a list of strings. - BeautifulSoup("", features=["html", "fast"]) - pass - - # You'll get an exception if BS can't find an appropriate - # builder. - with pytest.raises(ValueError): - BeautifulSoup("", features="no-such-feature") - -class TestRegistry(object): - """Test the TreeBuilderRegistry class in general.""" - - def setup_method(self): - self.registry = TreeBuilderRegistry() - - def builder_for_features(self, *feature_list): - cls = type('Builder_' + '_'.join(feature_list), - (object,), {'features' : feature_list}) - - self.registry.register(cls) - return cls - - def test_register_with_no_features(self): - builder = self.builder_for_features() - - # Since the builder advertises no features, you can't find it - # by looking up features. - assert self.registry.lookup('foo') is None - - # But you can find it by doing a lookup with no features, if - # this happens to be the only registered builder. - assert self.registry.lookup() == builder - - def test_register_with_features_makes_lookup_succeed(self): - builder = self.builder_for_features('foo', 'bar') - assert self.registry.lookup('foo') is builder - assert self.registry.lookup('bar') is builder - - def test_lookup_fails_when_no_builder_implements_feature(self): - builder = self.builder_for_features('foo', 'bar') - assert self.registry.lookup('baz') is None - - def test_lookup_gets_most_recent_registration_when_no_feature_specified(self): - builder1 = self.builder_for_features('foo') - builder2 = self.builder_for_features('bar') - assert self.registry.lookup() == builder2 - - def test_lookup_fails_when_no_tree_builders_registered(self): - assert self.registry.lookup() is None - - def test_lookup_gets_most_recent_builder_supporting_all_features(self): - has_one = self.builder_for_features('foo') - has_the_other = self.builder_for_features('bar') - has_both_early = self.builder_for_features('foo', 'bar', 'baz') - has_both_late = self.builder_for_features('foo', 'bar', 'quux') - lacks_one = self.builder_for_features('bar') - has_the_other = self.builder_for_features('foo') - - # There are two builders featuring 'foo' and 'bar', but - # the one that also features 'quux' was registered later. - assert self.registry.lookup('foo', 'bar') == has_both_late - - # There is only one builder featuring 'foo', 'bar', and 'baz'. - assert self.registry.lookup('foo', 'bar', 'baz') == has_both_early - - def test_lookup_fails_when_cannot_reconcile_requested_features(self): - builder1 = self.builder_for_features('foo', 'bar') - builder2 = self.builder_for_features('foo', 'baz') - assert self.registry.lookup('bar', 'baz') is None diff --git a/uno/lib/python/bs4/tests/test_css.py b/uno/lib/python/bs4/tests/test_css.py deleted file mode 100644 index 359dbcd2..00000000 --- a/uno/lib/python/bs4/tests/test_css.py +++ /dev/null @@ -1,487 +0,0 @@ -import pytest -import types -from unittest.mock import MagicMock - -from bs4 import ( - CSS, - BeautifulSoup, - ResultSet, -) - -from . import ( - SoupTest, - SOUP_SIEVE_PRESENT, -) - -if SOUP_SIEVE_PRESENT: - from soupsieve import SelectorSyntaxError - - -@pytest.mark.skipif(not SOUP_SIEVE_PRESENT, reason="Soup Sieve not installed") -class TestCSSSelectors(SoupTest): - """Test basic CSS selector functionality. - - This functionality is implemented in soupsieve, which has a much - more comprehensive test suite, so this is basically an extra check - that soupsieve works as expected. - """ - - HTML = """ - - - -The title - - - -Hello there. -
-
-

An H1

-

Some text

-

Some more text

-

An H2

-

Another

-Bob -

Another H2

-me - -span1a1 -span1a2 test - -span2a1 - - - -
- -
- - - - - - - - -

English

-

English UK

-

English US

-

French

-
- - -""" - - def setup_method(self): - self.soup = BeautifulSoup(self.HTML, 'html.parser') - - def assert_selects(self, selector, expected_ids, **kwargs): - results = self.soup.select(selector, **kwargs) - assert isinstance(results, ResultSet) - el_ids = [el['id'] for el in results] - el_ids.sort() - expected_ids.sort() - assert expected_ids == el_ids, "Selector %s, expected [%s], got [%s]" % ( - selector, ', '.join(expected_ids), ', '.join(el_ids) - ) - - assertSelect = assert_selects - - def assert_select_multiple(self, *tests): - for selector, expected_ids in tests: - self.assert_selects(selector, expected_ids) - - def test_precompiled(self): - sel = self.soup.css.compile('div') - - els = self.soup.select(sel) - assert len(els) == 4 - for div in els: - assert div.name == 'div' - - el = self.soup.select_one(sel) - assert 'main' == el['id'] - - def test_one_tag_one(self): - els = self.soup.select('title') - assert len(els) == 1 - assert els[0].name == 'title' - assert els[0].contents == ['The title'] - - def test_one_tag_many(self): - els = self.soup.select('div') - assert len(els) == 4 - for div in els: - assert div.name == 'div' - - el = self.soup.select_one('div') - assert 'main' == el['id'] - - def test_select_one_returns_none_if_no_match(self): - match = self.soup.select_one('nonexistenttag') - assert None == match - - - def test_tag_in_tag_one(self): - els = self.soup.select('div div') - self.assert_selects('div div', ['inner', 'data1']) - - def test_tag_in_tag_many(self): - for selector in ('html div', 'html body div', 'body div'): - self.assert_selects(selector, ['data1', 'main', 'inner', 'footer']) - - - def test_limit(self): - self.assert_selects('html div', ['main'], limit=1) - self.assert_selects('html body div', ['inner', 'main'], limit=2) - self.assert_selects('body div', ['data1', 'main', 'inner', 'footer'], - limit=10) - - def test_tag_no_match(self): - assert len(self.soup.select('del')) == 0 - - def test_invalid_tag(self): - with pytest.raises(SelectorSyntaxError): - self.soup.select('tag%t') - - def test_select_dashed_tag_ids(self): - self.assert_selects('custom-dashed-tag', ['dash1', 'dash2']) - - def test_select_dashed_by_id(self): - dashed = self.soup.select('custom-dashed-tag[id=\"dash2\"]') - assert dashed[0].name == 'custom-dashed-tag' - assert dashed[0]['id'] == 'dash2' - - def test_dashed_tag_text(self): - assert self.soup.select('body > custom-dashed-tag')[0].text == 'Hello there.' - - def test_select_dashed_matches_find_all(self): - assert self.soup.select('custom-dashed-tag') == self.soup.find_all('custom-dashed-tag') - - def test_header_tags(self): - self.assert_select_multiple( - ('h1', ['header1']), - ('h2', ['header2', 'header3']), - ) - - def test_class_one(self): - for selector in ('.onep', 'p.onep', 'html p.onep'): - els = self.soup.select(selector) - assert len(els) == 1 - assert els[0].name == 'p' - assert els[0]['class'] == ['onep'] - - def test_class_mismatched_tag(self): - els = self.soup.select('div.onep') - assert len(els) == 0 - - def test_one_id(self): - for selector in ('div#inner', '#inner', 'div div#inner'): - self.assert_selects(selector, ['inner']) - - def test_bad_id(self): - els = self.soup.select('#doesnotexist') - assert len(els) == 0 - - def test_items_in_id(self): - els = self.soup.select('div#inner p') - assert len(els) == 3 - for el in els: - assert el.name == 'p' - assert els[1]['class'] == ['onep'] - assert not els[0].has_attr('class') - - def test_a_bunch_of_emptys(self): - for selector in ('div#main del', 'div#main div.oops', 'div div#main'): - assert len(self.soup.select(selector)) == 0 - - def test_multi_class_support(self): - for selector in ('.class1', 'p.class1', '.class2', 'p.class2', - '.class3', 'p.class3', 'html p.class2', 'div#inner .class2'): - self.assert_selects(selector, ['pmulti']) - - def test_multi_class_selection(self): - for selector in ('.class1.class3', '.class3.class2', - '.class1.class2.class3'): - self.assert_selects(selector, ['pmulti']) - - def test_child_selector(self): - self.assert_selects('.s1 > a', ['s1a1', 's1a2']) - self.assert_selects('.s1 > a span', ['s1a2s1']) - - def test_child_selector_id(self): - self.assert_selects('.s1 > a#s1a2 span', ['s1a2s1']) - - def test_attribute_equals(self): - self.assert_select_multiple( - ('p[class="onep"]', ['p1']), - ('p[id="p1"]', ['p1']), - ('[class="onep"]', ['p1']), - ('[id="p1"]', ['p1']), - ('link[rel="stylesheet"]', ['l1']), - ('link[type="text/css"]', ['l1']), - ('link[href="blah.css"]', ['l1']), - ('link[href="no-blah.css"]', []), - ('[rel="stylesheet"]', ['l1']), - ('[type="text/css"]', ['l1']), - ('[href="blah.css"]', ['l1']), - ('[href="no-blah.css"]', []), - ('p[href="no-blah.css"]', []), - ('[href="no-blah.css"]', []), - ) - - def test_attribute_tilde(self): - self.assert_select_multiple( - ('p[class~="class1"]', ['pmulti']), - ('p[class~="class2"]', ['pmulti']), - ('p[class~="class3"]', ['pmulti']), - ('[class~="class1"]', ['pmulti']), - ('[class~="class2"]', ['pmulti']), - ('[class~="class3"]', ['pmulti']), - ('a[rel~="friend"]', ['bob']), - ('a[rel~="met"]', ['bob']), - ('[rel~="friend"]', ['bob']), - ('[rel~="met"]', ['bob']), - ) - - def test_attribute_startswith(self): - self.assert_select_multiple( - ('[rel^="style"]', ['l1']), - ('link[rel^="style"]', ['l1']), - ('notlink[rel^="notstyle"]', []), - ('[rel^="notstyle"]', []), - ('link[rel^="notstyle"]', []), - ('link[href^="bla"]', ['l1']), - ('a[href^="http://"]', ['bob', 'me']), - ('[href^="http://"]', ['bob', 'me']), - ('[id^="p"]', ['pmulti', 'p1']), - ('[id^="m"]', ['me', 'main']), - ('div[id^="m"]', ['main']), - ('a[id^="m"]', ['me']), - ('div[data-tag^="dashed"]', ['data1']) - ) - - def test_attribute_endswith(self): - self.assert_select_multiple( - ('[href$=".css"]', ['l1']), - ('link[href$=".css"]', ['l1']), - ('link[id$="1"]', ['l1']), - ('[id$="1"]', ['data1', 'l1', 'p1', 'header1', 's1a1', 's2a1', 's1a2s1', 'dash1']), - ('div[id$="1"]', ['data1']), - ('[id$="noending"]', []), - ) - - def test_attribute_contains(self): - self.assert_select_multiple( - # From test_attribute_startswith - ('[rel*="style"]', ['l1']), - ('link[rel*="style"]', ['l1']), - ('notlink[rel*="notstyle"]', []), - ('[rel*="notstyle"]', []), - ('link[rel*="notstyle"]', []), - ('link[href*="bla"]', ['l1']), - ('[href*="http://"]', ['bob', 'me']), - ('[id*="p"]', ['pmulti', 'p1']), - ('div[id*="m"]', ['main']), - ('a[id*="m"]', ['me']), - # From test_attribute_endswith - ('[href*=".css"]', ['l1']), - ('link[href*=".css"]', ['l1']), - ('link[id*="1"]', ['l1']), - ('[id*="1"]', ['data1', 'l1', 'p1', 'header1', 's1a1', 's1a2', 's2a1', 's1a2s1', 'dash1']), - ('div[id*="1"]', ['data1']), - ('[id*="noending"]', []), - # New for this test - ('[href*="."]', ['bob', 'me', 'l1']), - ('a[href*="."]', ['bob', 'me']), - ('link[href*="."]', ['l1']), - ('div[id*="n"]', ['main', 'inner']), - ('div[id*="nn"]', ['inner']), - ('div[data-tag*="edval"]', ['data1']) - ) - - def test_attribute_exact_or_hypen(self): - self.assert_select_multiple( - ('p[lang|="en"]', ['lang-en', 'lang-en-gb', 'lang-en-us']), - ('[lang|="en"]', ['lang-en', 'lang-en-gb', 'lang-en-us']), - ('p[lang|="fr"]', ['lang-fr']), - ('p[lang|="gb"]', []), - ) - - def test_attribute_exists(self): - self.assert_select_multiple( - ('[rel]', ['l1', 'bob', 'me']), - ('link[rel]', ['l1']), - ('a[rel]', ['bob', 'me']), - ('[lang]', ['lang-en', 'lang-en-gb', 'lang-en-us', 'lang-fr']), - ('p[class]', ['p1', 'pmulti']), - ('[blah]', []), - ('p[blah]', []), - ('div[data-tag]', ['data1']) - ) - - def test_quoted_space_in_selector_name(self): - html = """
nope
-
yes
- """ - soup = BeautifulSoup(html, 'html.parser') - [chosen] = soup.select('div[style="display: right"]') - assert "yes" == chosen.string - - def test_unsupported_pseudoclass(self): - with pytest.raises(NotImplementedError): - self.soup.select("a:no-such-pseudoclass") - - with pytest.raises(SelectorSyntaxError): - self.soup.select("a:nth-of-type(a)") - - def test_nth_of_type(self): - # Try to select first paragraph - els = self.soup.select('div#inner p:nth-of-type(1)') - assert len(els) == 1 - assert els[0].string == 'Some text' - - # Try to select third paragraph - els = self.soup.select('div#inner p:nth-of-type(3)') - assert len(els) == 1 - assert els[0].string == 'Another' - - # Try to select (non-existent!) fourth paragraph - els = self.soup.select('div#inner p:nth-of-type(4)') - assert len(els) == 0 - - # Zero will select no tags. - els = self.soup.select('div p:nth-of-type(0)') - assert len(els) == 0 - - def test_nth_of_type_direct_descendant(self): - els = self.soup.select('div#inner > p:nth-of-type(1)') - assert len(els) == 1 - assert els[0].string == 'Some text' - - def test_id_child_selector_nth_of_type(self): - self.assert_selects('#inner > p:nth-of-type(2)', ['p1']) - - def test_select_on_element(self): - # Other tests operate on the tree; this operates on an element - # within the tree. - inner = self.soup.find("div", id="main") - selected = inner.select("div") - # The
tag was selected. The