From b36b88cb00d71e9e38dfe8413dcdb29a6676c686 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 19 Jan 2023 19:03:09 -0500 Subject: [PATCH 001/333] Initial commit --- .gitignore | 129 ++++++++++ LICENSE | 674 +++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 + 3 files changed, 805 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..b6e47617de --- /dev/null +++ b/.gitignore @@ -0,0 +1,129 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..f288702d2f --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + 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/README.md b/README.md new file mode 100644 index 0000000000..a4eed0f78e --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# starcraft-base +A base repository for From 23aa1a7f99d7a91b5d1222ab9f16d8810962f92a Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 25 Jan 2023 11:01:42 -0500 Subject: [PATCH 002/333] base: Initial specification for the base repository (#2) --- .github/PULL_RELEASE_TEMPLATE.md | 5 + .github/release-drafter.yaml | 24 + .github/renovate.json5 | 68 ++ .github/workflows/cla-check.yaml | 9 + .github/workflows/release-drafter.yaml | 16 + .github/workflows/tests.yaml | 86 +++ .gitignore | 6 + HACKING.rst | 56 ++ LICENSE | 827 +++++-------------------- README.md | 2 - README.rst | 31 + pyproject.toml | 152 +++++ starcraft/__init__.py | 25 + tests/__init__.py | 0 tests/test_init.py | 40 ++ tox.ini | 79 +++ 16 files changed, 756 insertions(+), 670 deletions(-) create mode 100644 .github/PULL_RELEASE_TEMPLATE.md create mode 100644 .github/release-drafter.yaml create mode 100644 .github/renovate.json5 create mode 100644 .github/workflows/cla-check.yaml create mode 100644 .github/workflows/release-drafter.yaml create mode 100644 .github/workflows/tests.yaml create mode 100644 HACKING.rst delete mode 100644 README.md create mode 100644 README.rst create mode 100644 pyproject.toml create mode 100644 starcraft/__init__.py create mode 100644 tests/__init__.py create mode 100644 tests/test_init.py create mode 100644 tox.ini diff --git a/.github/PULL_RELEASE_TEMPLATE.md b/.github/PULL_RELEASE_TEMPLATE.md new file mode 100644 index 0000000000..da2c9731a5 --- /dev/null +++ b/.github/PULL_RELEASE_TEMPLATE.md @@ -0,0 +1,5 @@ +- [ ] Have you followed the guidelines for contributing? +- [ ] Have you signed the [CLA](http://www.ubuntu.com/legal/contributors/)? +- [ ] Have you successfully run `tox`? + +----- diff --git a/.github/release-drafter.yaml b/.github/release-drafter.yaml new file mode 100644 index 0000000000..50f9d88e4c --- /dev/null +++ b/.github/release-drafter.yaml @@ -0,0 +1,24 @@ +categories: + - title: "New Features" + labels: + - "enhancement" + - title: "Maintenance" + labels: + - "maintenance" + - title: "Bug Fixes" + labels: + - "bug" + - title: "Specifications and Documentation" + label: + - "specification" + - "doc" + - title: "Tooling" + label: + - "tooling" +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +template: | + Special thanks to the contributors that made this release happen: $CONTRIBUTORS + + ## Full list of changes + + $CHANGES diff --git a/.github/renovate.json5 b/.github/renovate.json5 new file mode 100644 index 0000000000..c031ee570c --- /dev/null +++ b/.github/renovate.json5 @@ -0,0 +1,68 @@ + { + // Configuration file for RenovateBot: https://docs.renovatebot.com/configuration-options + extends: ["config:base"], + labels: ["dependencies"], // For convenient searching in GitHub + pip_requirements: { + fileMatch: ["pyproject.toml", "tox.ini"] + }, + packageRules: [ + { + // Automerge patches, pin changes and digest changes. + // Also groups these changes together. + groupName: "patch updates", + matchUpdateTypes: ["patch", "pin", "digest"], + prPriority: 3, // Patches should go first! + automerge: true + }, + { + // Update all internal packages in one higher-priority PR + groupName: "internal packages", + matchPackagePrefixes: ["craft-", "snap-"], + matchLanguages: ["python"], + prPriority: 2 + }, + { + // GitHub Actions are higher priority to update than most dependencies. + matchManagers: ["github-actions"], + prPriority: 1 + }, + // Everything not in one of these rules gets priority 0 and falls here. + { + // Minor changes can be grouped and automerged for dev dependencies, but are also deprioritised. + groupName: "development dependencies (minor and patch)", + groupSlug: "dev-dependencies", + matchDepTypes: ["devDependencies"], + matchUpdateTypes: ["minor", "patch", "pin", "digest"], + prPriority: -1, + automerge: true + }, + { + // Other major dependencies get deprioritised below minor dev dependencies. + matchUpdateTypes: ["major"], + prPriority: -2 + }, + { + // Major dev dependencies are stone last. + matchDepTypes: ["devDependencies"], + matchUpdateTypes: ["major"], + prPriority: -3 + } + ], + regexManagers: [ + { + // tox.ini can get updates too if we specify for each package. + fileMatch: ["tox.ini"], + matchStrings: [ + "# renovate: datasource=(?\\S+)\n\\s+(?.*?)[=><]=?(?.*?)\\n", + ] + } + ], + timezone: "Etc/UTC", + automergeSchedule: "after 1 am and before 7 am", + schedule: "every weekend", + prConcurrentLimit: 5, // No more than 5 open PRs at a time. + prCreation: "not-pending", // Wait until status checks have completed before raising the PR + prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. + prHourlyLimit: 1, // No more than 1 PR per hour. + stabilityDays: 2 // Wait 2 days from release before updating. +} diff --git a/.github/workflows/cla-check.yaml b/.github/workflows/cla-check.yaml new file mode 100644 index 0000000000..cdb271af63 --- /dev/null +++ b/.github/workflows/cla-check.yaml @@ -0,0 +1,9 @@ +name: cla-check +on: [pull_request] + +jobs: + cla-check: + runs-on: ubuntu-latest + steps: + - name: Check if CLA signed + uses: canonical/has-signed-canonical-cla@v1 diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml new file mode 100644 index 0000000000..d2e8e70ae0 --- /dev/null +++ b/.github/workflows/release-drafter.yaml @@ -0,0 +1,16 @@ +name: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - master + +jobs: + update_release_draft: + runs-on: ubuntu-latest + steps: + - name: Release Drafter + uses: release-drafter/release-drafter@v5.7.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000000..a529c5cbac --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,86 @@ +name: Tests, linting, etc. +on: + push: + branches: + - "main" + - "feature/*" + - "hotfix/*" + - "release/*" + pull_request: + +jobs: + linters: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Configure environment + run: | + echo "::group::Begin snap install" + echo "Installing snaps in the background while running apt and pip..." + sudo snap install --no-wait --classic pyright + sudo snap install --no-wait shellcheck + echo "::endgroup::" + echo "::group::pip install" + python -m pip install 'tox>=4' tox-gh + echo "::endgroup::" + echo "::group::Create virtual environments for linting processes." + tox run-parallel --parallel all --parallel-no-spinner -m lint --notest + echo "::endgroup::" + echo "::group::Wait for snap to complete" + snap watch --last=install + echo "::endgroup::" + - name: Run Linters + run: tox run -m lint + tests: + strategy: + matrix: + platform: [ubuntu-20.04, ubuntu-22.04] + runs-on: ${{ matrix.platform }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Python versions on ${{ matrix.platform }} + uses: actions/setup-python@v4 + with: + python-version: | + 3.8 + 3.9 + 3.10 + 3.11 + 3.12-dev + - name: Configure environment + run: | + echo "::group::pip install" + python -m pip install 'tox>=4' tox-gh + echo "::endgroup::" + mkdir -p results + - name: Setup Tox environments + run: > + tox run-parallel --parallel auto --parallel-no-spinner + --parallel-live -m tests --notest + - name: Test with tox + run: > + tox run-parallel --parallel all --parallel-no-spinner + --skip-pkg-install + --result-json results/tox-${{ matrix.platform }}.json + -m tests + -- --no-header --quiet -rN + - name: Upload code coverage + uses: codecov/codecov-action@v3 + with: + directory: ./results/ + files: coverage*.xml + - name: Upload test results + if: always() + uses: actions/upload-artifact@v3 + with: + name: test-results-${{ matrix.platform }} + path: results/ diff --git a/.gitignore b/.gitignore index b6e47617de..e5d55da95d 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,9 @@ dmypy.json # Pyre type checker .pyre/ + +# Caches for various tools +/.*_cache/ + +# Test results +/results/ diff --git a/HACKING.rst b/HACKING.rst new file mode 100644 index 0000000000..0a5afceb73 --- /dev/null +++ b/HACKING.rst @@ -0,0 +1,56 @@ +********* +Starcraft +********* + +Welcome to Starcraft! We hope this document helps you get started. Before contributing any code, please sign the `Canonical contributor licence agreement`_. + +Setting up a development environment +------------------------------------ +We use a forking, feature-based workflow, so you should start by forking the repository. Once you've done that, clone the project to your computer using git clone's ``--recurse-submodules`` parameter. (See more on the `git submodules`_ documentation.) + +Tooling +======= +We use a large number of tools for our project. Most of these are installed for you with tox, but you'll need to install: + +- Python 3.8 (default on Ubuntu 20.04, available on Ubuntu 22.04 through the deadsnakes_ PPA) with setuptools. +- tox_ version 4 or later. (3.8+ will automatically provision a v4 virtualenv) +- Pyright_ (it's recommended you install with ``snap install --classic pyright``) +- ShellCheck_ (also available via snap: ``snap install shellcheck``) + +Once you have all of those installed, you can install the necessary virtual environments for this repository using tox. + +Other tools +########### +Some other tools we use for code quality include: + +- Black_ for code formatting +- pytest_ for testing +- ruff_ for linting (and some additional formatting) + +A complete list is kept in our pyproject.toml_ file in dev dependencies. + +Initial Setup +############# + +After cloning the repository but before making any changes, it's worth ensuring that the tests, linting and tools all run on your machine. Running ``tox`` with no parameters will create the necessary virtual environments for linting and testing and run those:: + + tox + +If you want to install the environments but not run the tests, you can run:: + + tox --notest + +If you'd like to run the tests with a newer version of Python, you can pass a specific environment. You must have an appropriately versioned Python interpreter installed. For example, to run with Python 3.10, run:: + + tox -e test-py310 + +.. _Black: https://black.readthedocs.io +.. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ +.. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa +.. _`git submodules`: https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules +.. _pyproject.toml: ./pyproject.toml +.. _Pyright: https://github.com/microsoft/pyright +.. _pytest: https://pytest.org +.. _ruff: https://github.com/charliermarsh/ruff +.. _ShellCheck: https://www.shellcheck.net/ +.. _tox: https://tox.wiki diff --git a/LICENSE b/LICENSE index f288702d2f..0a041280bd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,674 +1,165 @@ - GNU GENERAL PUBLIC LICENSE + GNU LESSER 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 -. + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser 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 +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/README.md b/README.md deleted file mode 100644 index a4eed0f78e..0000000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# starcraft-base -A base repository for diff --git a/README.rst b/README.rst new file mode 100644 index 0000000000..c0014653aa --- /dev/null +++ b/README.rst @@ -0,0 +1,31 @@ +************** +starcraft-base +************** + +A base repository for Starcraft projects. + +Description +----------- +This project is designed to act as the basis for any future starcraft projects as well as a testbed for any tooling changes we want to make before merging them into other projects. + +Structure +--------- +TODO + +How to migrate existing projects +-------------------------------- +TODO + +How to create a new project +--------------------------- +[TODO: Make this a template repository.] + +1. [Use this template](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template) to create your repository. +2. Ensure the ``LICENSE`` file represents the current best practices from the Canonical legal team for the specific project you intend to release. (LGPL v3 for libraries, GPL v3 for applications.) +3. Rename any files or directories and ensure references are updated. +4. Replace any appropriate `starcraft` references with the appropriate name. +5. Put correct contact information into CODE_OF_CONDUCT.md +6. Write a new README! + +.. _EditorConfig: https://editorconfig.org/ +.. _pre-commit: https://pre-commit.com/ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000..b6c75275d7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,152 @@ +[project] +name = "starcraft" +version = "0.0.1" +readme = "README.rst" +dependencies = [ + +] +classifiers = [ + "Development Status :: 1 - Planning", + "License :: OSI Approved :: GNU General Public License (GPL)", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", +] +requires-python = ">=3.8" + +[project.scripts] +starcraft-hello = "starcraft:hello" + +[project.optional-dependencies] +dev = [ + "pytest==7.0.0", + "pytest-cov==4.0.0", + "pytest-mock==3.10.0", +] +types = [ +] + +[build-system] +requires = [ + "setuptools==45.2.0", # This is the version provided in apt with focal +] +build-backend = "setuptools.build_meta" + +[tool.black] +target-version = ["py38"] + +[tool.codespell] +ignore-words-list = "buildd,crate,keyserver,comandos,ro,dedent,dedented" +skip = ".tox,.git,build,.*_cache,__pycache__,*.tar,*.snap,*.png,node_modules" +quiet-level = 3 +check-filenames = true + +[tool.isort] +multi_line_output = 3 +include_trailing_comma = true +force_grid_wrap = 0 +use_parentheses = true +ensure_newline_before_comments = true +line_length = 88 + +[tool.pytest.ini_options] +minversion = "7.0" +testpaths = "tests" +xfail_strict = true +addopts = [ + "--cov", +] + +[tool.coverage.run] +branch = true +omit = ["tests/**"] + +[tool.coverage.report] +skip_empty = true +fail_under = 80 + +[tool.pyright] +strict = ["starcraft"] +pythonVersion = "3.8" +pythonPlatform = "Linux" +venvPath = ".tox" +venv = "py38" + +[tool.ruff] +line-length = 88 +target-version = "py38" +src = ["starcraft", "tests"] +extend-exclude = [ + "docs", + "__pycache__", +] +# Follow ST063 - Maintaining and updating linting specifications for updating these. +select = [ # Base linting rule selections. + # See the internal document for discussion: + # https://docs.google.com/document/d/1i1n8pDmFmWi4wTDpk-JfnWCVUThPJiggyPi2DYwBBu4/edit + # All sections here are stable in ruff and shouldn't randomly introduce + # failures with ruff updates. + "F", # The rules built into Flake8 + "E", "W", # pycodestyle errors and warnings + "D", # Implement pydocstyle checking as well. + "I", # isort checking + "PLC", "PLE", "PLR", "PLW", # Pylint + "N", # PEP8 naming + "YTT", # flake8-2020: Misuse of `sys.version` and `sys.version_info` + "BLE", # Do not catch blind exceptions + "FBT", # Disallow boolean positional arguments (make them keyword-only) + "A", # Shadowing built-ins. + "C4", # Encourage comprehensions, which tend to be faster than alternatives. + "T10", # Don't call the debugger in production code + "ISC", # Implicit string concatenation that can cause subtle issues + "ICN", # Only use common conventions for import aliases. + "Q", # Consistent quotations + "RET" # Simpler logic after return, raise, continue or break +] +extend-select = [ + # These sets are still frequently getting new rules. + # Therefore, they're getting frozen with the current rules so we can + # upgrade ruff without breaking linting. + # Pyupgrade: https://github.com/charliermarsh/ruff#pyupgrade-up + "UP00", "UP01", "UP02", "UP030", "UP032", "UP033", + # "UP034", # Very new, not yet enabled in ruff 0.0.227 + # Annotations: https://github.com/charliermarsh/ruff#flake8-annotations-ann + "ANN0", # Type annotations for arguments other than `self` and `cls` + "ANN2", # Return type annotations + # flake8-bandit: security testing. https://github.com/charliermarsh/ruff#flake8-bandit-s + # https://bandit.readthedocs.io/en/latest/plugins/index.html#complete-test-plugin-listing + "S101", "S102", # assert or exec + "S103", "S108", # File permissions and tempfiles - use #noqa to silence when appropriate. + "S104", # Network binds + "S105", "S106", "S107", # Hardcoded passwords + "S113", # Requests calls without timeouts + "S506", # Unsafe YAML load + "S508", "S509", # Insecure SNMP + "S701", # jinja2 templates without autoescape + "B0", # Common mistakes and typos. + "RUF001", "RUF002", "RUF003", # Ambiguous unicode characters + "RUF004", # Keyword arguments must come after starred arguments + "RUF005", # Encourages unpacking rather than concatenation + "RUF100", # #noqa directive that doesn't flag anything. +] +ignore = [ + #"E203", # Whitespace before ":" -- Commented because ruff doesn't currently check E203 + "E501", # Line too long (reason: black will automatically fix this for us) + "D105", # Missing docstring in magic method (reason: magic methods already have definitions) + "D107", # Missing docstring in __init__ (reason: documented in class docstring) + "D203", # 1 blank line required before class docstring (reason: pep257 default) + "D213", # Multi-line docstring summary should start at the second line (reason: pep257 default) + "D215", # Section underline is over-indented (reason: pep257 default) + "A003", # Class attribute shadowing built-in (reason: Class attributes don't often get bare references) + +] + +[tool.ruff.per-file-ignores] +"tests/**.py" = [ # Some things we want for the moin project are unnecessary in tests. + "D", # Ignore docstring rules in tests + "ANN", # Ignore type annotations in tests + "S101", # Allow assertions in tests + "S103", # Allow `os.chmod` setting a permissive mask `0o555` on file or directory + "S108", # Allow Probable insecure usage of temporary file or directory +] +# isort leaves init files alone by default, this makes ruff ignore them too. +"__init__.py" = ["I001"] diff --git a/starcraft/__init__.py b/starcraft/__init__.py new file mode 100644 index 0000000000..25ee5b9b41 --- /dev/null +++ b/starcraft/__init__.py @@ -0,0 +1,25 @@ +# This file is part of starcraft. +# +# Copyright 2023 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, 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 . +"""Starcraft package demo.""" +from typing import List, Optional, Any + + +def hello(people: Optional[List[Any]] = None) -> None: + """Says hello.""" + print("Hello *craft team!") + if people: + for person in people: + print(f"Hello {person}!") diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/test_init.py b/tests/test_init.py new file mode 100644 index 0000000000..61c5974195 --- /dev/null +++ b/tests/test_init.py @@ -0,0 +1,40 @@ +# This file is part of starcraft. +# +# Copyright 2023 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, 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 . +"""Basic Starcraft package demo tests.""" +from unittest import mock + +from starcraft import hello + + +def test_hello(mocker): + mocker.patch("builtins.print") + + hello() + + print.assert_called_once_with("Hello *craft team!") + + +def test_hello_people(mocker): + mocker.patch("builtins.print") + + hello(["people"]) + + print.assert_has_calls( + [ + mock.call("Hello *craft team!"), + mock.call("Hello people!"), + ] + ) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000000..eb7d09a453 --- /dev/null +++ b/tox.ini @@ -0,0 +1,79 @@ +[tox] +env_list = # Environments to run when called with no parameters. + lint-{black,ruff,pyright,shellcheck,codespell} + test-py38 +minversion = 4.3.5 +# Tox will use these requirements to bootstrap a venv if necessary. +# tox-igore-env-name-mismatch allows us to have one virtualenv for all linting. +# By setting requirements here, we make this INI file compatible with older +# versions of tox. Tox >= 3.8 will automatically provision the version provided +# inside of a virtual environment, so users of Ubuntu >= focal can simply +# install tox from apt. Older than that, the user gets an upgrade warning. +requires = + # renovate: datasource=pypi + tox==4.3.5 + # renovate: datasource=pypi + tox-ignore-env-name-mismatch==0.2.0 +# Allow tox to access the user's $TMPDIR environment variable if set. +# This workaround is required to avoid circular dependencies for TMPDIR, +# since tox will otherwise attempt to use the environment's TMPDIR variable. +user_tmp_dir = {env:TMPDIR} + +[testenv] # Default config for all environments. Overridable in each env. +# We have many tests that create temporary files. Unless the user has set a +# TMPDIR, this will prefer putting those temp files in $XDG_RUNTIME_DIR, +# which will speed up those tests since they'll run on a ramdisk. +env_tmp_dir = {user_tmp_dir:{env:XDG_RUNTIME_DIR:{work_dir}}}/tox_tmp/{env_name} +set_env = + TMPDIR={env_tmp_dir} + +[testenv:test-{py38,py39,py310,py311,py312}] # Configuration for all tests using pytest +description = Run tests with pytest +package = sdist +extras = dev +labels = + py38, py310, py311: tests, unit-tests +allowlist_externals = mkdir +commands_pre = mkdir -p results +commands = pytest {tty:--color=yes} --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml {posargs} + +[lint] # Standard linting configuration +skip_install = true +deps = + # renovate: datasource=pypi + black>=22.12.0 + # renovate: datasource=pypi + ruff>=0.0.226 + # renovate: datasource=pypi + codespell[tomli]>=2.2.2 +env_dir = {work_dir}/linting +runner = ignore_env_name_mismatch + +[shellcheck] +find = find {tox_root} \( -name .git -o -name .tox \) -prune -o -print +filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: + +[testenv:lint-{black,ruff,pyright,shellcheck,codespell}] +description = Lint the source code +base = testenv, lint +labels = lint +allowlist_externals = + pyright: pyright + shellcheck: bash, xargs +commands_pre = + shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' +commands = + black: black --check --diff {tty:--color} {posargs} . + ruff: ruff --diff --respect-gitignore {posargs} . + pyright: pyright --lib {posargs} + shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck + codespell: codespell --toml {tox_root}/pyproject.toml {posargs} + +[testenv:format-{black,ruff,codespell}] +description = Automatically format source code +base = testenv, lint +labels = format +commands = + black: black {tty:--color} {posargs} . + ruff: ruff --fix --respect-gitignore {posargs} . + codespell: codespell --toml {tox_root}/pyproject.toml --write-changes {posargs} From 552c132a304e4074a3a2cc3efbd1505924b21f00 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 25 Jan 2023 13:41:22 -0500 Subject: [PATCH 003/333] tools: Update tox and setuptools to fix breakages (#4) --- .github/workflows/tests.yaml | 13 +++---------- pyproject.toml | 5 ++++- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index a529c5cbac..c78c6d1783 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,7 +31,7 @@ jobs: python -m pip install 'tox>=4' tox-gh echo "::endgroup::" echo "::group::Create virtual environments for linting processes." - tox run-parallel --parallel all --parallel-no-spinner -m lint --notest + tox run -m lint --notest echo "::endgroup::" echo "::group::Wait for snap to complete" snap watch --last=install @@ -63,16 +63,9 @@ jobs: echo "::endgroup::" mkdir -p results - name: Setup Tox environments - run: > - tox run-parallel --parallel auto --parallel-no-spinner - --parallel-live -m tests --notest + run: tox run -m tests --notest - name: Test with tox - run: > - tox run-parallel --parallel all --parallel-no-spinner - --skip-pkg-install - --result-json results/tox-${{ matrix.platform }}.json - -m tests - -- --no-header --quiet -rN + run: tox run-parallel --parallel all --parallel-no-spinner --skip-pkg-install --result-json results/tox-${{ matrix.platform }}.json -m tests -- --no-header --quiet -rN - name: Upload code coverage uses: codecov/codecov-action@v3 with: diff --git a/pyproject.toml b/pyproject.toml index b6c75275d7..49d41fdce7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,10 +27,13 @@ types = [ [build-system] requires = [ - "setuptools==45.2.0", # This is the version provided in apt with focal + "setuptools==66.1.1", ] build-backend = "setuptools.build_meta" +[tool.setuptools] +packages = ["starcraft"] + [tool.black] target-version = ["py38"] From 9a0cae5aed42c33d2b06453ff1794f18a9ba9137 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 25 Jan 2023 14:36:22 -0500 Subject: [PATCH 004/333] tools: Split unit and integration tests --- pyproject.toml | 4 +--- tests/integration/__init__.py | 0 tests/integration/test_init.py | 25 +++++++++++++++++++++++++ tests/unit/__init__.py | 0 tests/{ => unit}/test_init.py | 2 +- tox.ini | 20 +++++++++++++++----- 6 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 tests/integration/__init__.py create mode 100644 tests/integration/test_init.py create mode 100644 tests/unit/__init__.py rename tests/{ => unit}/test_init.py (95%) diff --git a/pyproject.toml b/pyproject.toml index 49d41fdce7..2934a67e7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,12 +55,10 @@ line_length = 88 minversion = "7.0" testpaths = "tests" xfail_strict = true -addopts = [ - "--cov", -] [tool.coverage.run] branch = true +parallel = true omit = ["tests/**"] [tool.coverage.report] diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/integration/test_init.py b/tests/integration/test_init.py new file mode 100644 index 0000000000..2a406eb390 --- /dev/null +++ b/tests/integration/test_init.py @@ -0,0 +1,25 @@ +# This file is part of starcraft. +# +# Copyright 2023 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, 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 . +"""Basic Starcraft package demo tests.""" +import subprocess + + +def test_cli(): + expected = "Hello *craft team!\n" + + actual = subprocess.check_output(["starcraft-hello"], text=True) + + assert expected == actual diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/test_init.py b/tests/unit/test_init.py similarity index 95% rename from tests/test_init.py rename to tests/unit/test_init.py index 61c5974195..78d4114a4d 100644 --- a/tests/test_init.py +++ b/tests/unit/test_init.py @@ -13,7 +13,7 @@ # # You should have received a copy of the GNU General Public License along # with this program. If not, see . -"""Basic Starcraft package demo tests.""" +"""Basic Starcraft package demo unit tests.""" from unittest import mock from starcraft import hello diff --git a/tox.ini b/tox.ini index eb7d09a453..192ffb6e2b 100644 --- a/tox.ini +++ b/tox.ini @@ -27,15 +27,25 @@ env_tmp_dir = {user_tmp_dir:{env:XDG_RUNTIME_DIR:{work_dir}}}/tox_tmp/{env_name} set_env = TMPDIR={env_tmp_dir} -[testenv:test-{py38,py39,py310,py311,py312}] # Configuration for all tests using pytest -description = Run tests with pytest +[test] # Base configuration for unit and integration tests package = sdist extras = dev -labels = - py38, py310, py311: tests, unit-tests allowlist_externals = mkdir commands_pre = mkdir -p results -commands = pytest {tty:--color=yes} --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml {posargs} + +[testenv:test-{py38,py39,py310,py311,py312}] # Configuration for all tests using pytest +base = testenv, test +description = Run unit tests with pytest +labels = + py38, py310, py311: tests, unit-tests +commands = pytest {tty:--color=yes} --cov --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml tests/unit {posargs} + +[testenv:integration-{py38,py39,py310,py311,py312}] +base = testenv, test +description = Run integration tests with pytest +labels = + py38, py310, py311: tests, integration-tests +commands = pytest {tty:--color=yes} --junit-xml=results/test-results-{env_name}.xml tests/integration {posargs} [lint] # Standard linting configuration skip_install = true From f676cdc6e58556feb82ac49d9bcec3a5f3f5a389 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 25 Jan 2023 15:44:34 -0500 Subject: [PATCH 005/333] tools: Make renovate cleaner. (#5) --- .github/renovate.json5 | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index c031ee570c..a7261fdcfe 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -3,9 +3,12 @@ extends: ["config:base"], labels: ["dependencies"], // For convenient searching in GitHub pip_requirements: { - fileMatch: ["pyproject.toml", "tox.ini"] + fileMatch: ["^tox.ini$"] }, - packageRules: [ + pip_setup: { + fileMatch: ["^pyproject.toml$", "(^|/)setup\\.py$"] + }, + packageRules: [ { // Automerge patches, pin changes and digest changes. // Also groups these changes together. @@ -23,6 +26,7 @@ }, { // GitHub Actions are higher priority to update than most dependencies. + groupName: "GitHub Actions", matchManagers: ["github-actions"], prPriority: 1 }, @@ -52,8 +56,9 @@ { // tox.ini can get updates too if we specify for each package. fileMatch: ["tox.ini"], + depTypeTemplate: "devDependencies", matchStrings: [ - "# renovate: datasource=(?\\S+)\n\\s+(?.*?)[=><]=?(?.*?)\\n", + "# renovate: datasource=(?\S+)\n\s+(?.*?)(\[[\w]*\])*[=><]=?(?.*?)\n" ] } ], From 70a15517e40d14afc10dce7dac4cf15fcc455a60 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 25 Jan 2023 15:47:02 -0500 Subject: [PATCH 006/333] Better comment --- tests/integration/test_init.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integration/test_init.py b/tests/integration/test_init.py index 2a406eb390..879210b715 100644 --- a/tests/integration/test_init.py +++ b/tests/integration/test_init.py @@ -3,8 +3,8 @@ # Copyright 2023 Canonical Ltd. # # This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 3, as published -# by the Free Software Foundation. +# under the terms of the GNU Lesser General Public License version 3, as +# published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, @@ -13,7 +13,7 @@ # # You should have received a copy of the GNU General Public License along # with this program. If not, see . -"""Basic Starcraft package demo tests.""" +"""Basic Starcraft package demo integration tests.""" import subprocess From 229ee1136e110daf854387b078e32dccfe2b6c5f Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 25 Jan 2023 19:29:55 -0500 Subject: [PATCH 007/333] tools: Configure mypy (#6) --- pyproject.toml | 24 ++++++++++++++++++++++++ tox.ini | 7 ++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 49d41fdce7..053d757208 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,6 +74,30 @@ pythonPlatform = "Linux" venvPath = ".tox" venv = "py38" +[tool.mypy] +python_version = "3.8" +packages = ["starcraft"] +exclude = [ + "build" +] +warn_unused_configs = true +warn_redundant_casts = true +strict_equality = true +strict_concatenate = true +warn_return_any = true +disallow_subclassing_any = true +disallow_untyped_decorators = true +disallow_any_generics = true + +[[tool.mypy.overrides]] +module = ["starcraft"] +disallow_untyped_defs = true +no_implicit_optional = true + +[[tool.mypy.overrides]] +module = ["tests.*"] +strict = false + [tool.ruff] line-length = 88 target-version = "py38" diff --git a/tox.ini b/tox.ini index eb7d09a453..543c6494e8 100644 --- a/tox.ini +++ b/tox.ini @@ -46,6 +46,8 @@ deps = ruff>=0.0.226 # renovate: datasource=pypi codespell[tomli]>=2.2.2 + # renovate: datasource=pypi + mypy[reports]>=0.991 env_dir = {work_dir}/linting runner = ignore_env_name_mismatch @@ -53,14 +55,16 @@ runner = ignore_env_name_mismatch find = find {tox_root} \( -name .git -o -name .tox \) -prune -o -print filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: -[testenv:lint-{black,ruff,pyright,shellcheck,codespell}] +[testenv:lint-{black,ruff,pyright,shellcheck,codespell,mypy}] description = Lint the source code base = testenv, lint labels = lint allowlist_externals = pyright: pyright shellcheck: bash, xargs + mypy: mkdir commands_pre = + mypy: mkdir -p .mypy_cache shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' commands = black: black --check --diff {tty:--color} {posargs} . @@ -68,6 +72,7 @@ commands = pyright: pyright --lib {posargs} shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck codespell: codespell --toml {tox_root}/pyproject.toml {posargs} + mypy: mypy --install-types --non-interactive . [testenv:format-{black,ruff,codespell}] description = Automatically format source code From 63fc646670125a24e3ee57ec59852bf203b6a15c Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 25 Jan 2023 19:32:57 -0500 Subject: [PATCH 008/333] tools: Split unit and integration tests (#7) --- pyproject.toml | 4 +--- tests/integration/__init__.py | 0 tests/integration/test_init.py | 25 +++++++++++++++++++++++++ tests/unit/__init__.py | 0 tests/{ => unit}/test_init.py | 2 +- tox.ini | 20 +++++++++++++++----- 6 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 tests/integration/__init__.py create mode 100644 tests/integration/test_init.py create mode 100644 tests/unit/__init__.py rename tests/{ => unit}/test_init.py (95%) diff --git a/pyproject.toml b/pyproject.toml index 053d757208..31b4370c93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,12 +55,10 @@ line_length = 88 minversion = "7.0" testpaths = "tests" xfail_strict = true -addopts = [ - "--cov", -] [tool.coverage.run] branch = true +parallel = true omit = ["tests/**"] [tool.coverage.report] diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/integration/test_init.py b/tests/integration/test_init.py new file mode 100644 index 0000000000..879210b715 --- /dev/null +++ b/tests/integration/test_init.py @@ -0,0 +1,25 @@ +# This file is part of starcraft. +# +# Copyright 2023 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License version 3, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, 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 . +"""Basic Starcraft package demo integration tests.""" +import subprocess + + +def test_cli(): + expected = "Hello *craft team!\n" + + actual = subprocess.check_output(["starcraft-hello"], text=True) + + assert expected == actual diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/test_init.py b/tests/unit/test_init.py similarity index 95% rename from tests/test_init.py rename to tests/unit/test_init.py index 61c5974195..78d4114a4d 100644 --- a/tests/test_init.py +++ b/tests/unit/test_init.py @@ -13,7 +13,7 @@ # # You should have received a copy of the GNU General Public License along # with this program. If not, see . -"""Basic Starcraft package demo tests.""" +"""Basic Starcraft package demo unit tests.""" from unittest import mock from starcraft import hello diff --git a/tox.ini b/tox.ini index 543c6494e8..d7007ccd65 100644 --- a/tox.ini +++ b/tox.ini @@ -27,15 +27,25 @@ env_tmp_dir = {user_tmp_dir:{env:XDG_RUNTIME_DIR:{work_dir}}}/tox_tmp/{env_name} set_env = TMPDIR={env_tmp_dir} -[testenv:test-{py38,py39,py310,py311,py312}] # Configuration for all tests using pytest -description = Run tests with pytest +[test] # Base configuration for unit and integration tests package = sdist extras = dev -labels = - py38, py310, py311: tests, unit-tests allowlist_externals = mkdir commands_pre = mkdir -p results -commands = pytest {tty:--color=yes} --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml {posargs} + +[testenv:test-{py38,py39,py310,py311,py312}] # Configuration for all tests using pytest +base = testenv, test +description = Run unit tests with pytest +labels = + py38, py310, py311: tests, unit-tests +commands = pytest {tty:--color=yes} --cov --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml tests/unit {posargs} + +[testenv:integration-{py38,py39,py310,py311,py312}] +base = testenv, test +description = Run integration tests with pytest +labels = + py38, py310, py311: tests, integration-tests +commands = pytest {tty:--color=yes} --junit-xml=results/test-results-{env_name}.xml tests/integration {posargs} [lint] # Standard linting configuration skip_install = true From 605bec284de818a3f26c4e382f4d035c63b6f45a Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 25 Jan 2023 19:26:42 -0500 Subject: [PATCH 009/333] docs: Basic sphinx docs --- .readthedocs.yaml | 27 +++++++++++++++++ README.rst | 4 ++- docs/conf.py | 59 ++++++++++++++++++++++++++++++++++++++ docs/explanation/index.rst | 7 +++++ docs/howto/index.rst | 7 +++++ docs/index.rst | 52 +++++++++++++++++++++++++++++++++ docs/reference/index.rst | 13 +++++++++ docs/tutorials/index.rst | 11 +++++++ pyproject.toml | 9 ++++++ tox.ini | 20 +++++++++++++ 10 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 .readthedocs.yaml create mode 100644 docs/conf.py create mode 100644 docs/explanation/index.rst create mode 100644 docs/howto/index.rst create mode 100644 docs/index.rst create mode 100644 docs/reference/index.rst create mode 100644 docs/tutorials/index.rst diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000000..fb58117028 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,27 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/conf.py + +# Optionally build your docs in additional formats such as PDF +formats: + - pdf + - epub + +build: + os: ubuntu-22.04 + tools: + python: "3" + +python: + install: + - method: pip + path: . + extra_requirements: + - docs diff --git a/README.rst b/README.rst index c0014653aa..7e7d9e4048 100644 --- a/README.rst +++ b/README.rst @@ -25,7 +25,9 @@ How to create a new project 3. Rename any files or directories and ensure references are updated. 4. Replace any appropriate `starcraft` references with the appropriate name. 5. Put correct contact information into CODE_OF_CONDUCT.md -6. Write a new README! +6. Write a new README +7. Import your documentation to ReadTheDocs_. .. _EditorConfig: https://editorconfig.org/ .. _pre-commit: https://pre-commit.com/ +.. _ReadTheDocs: https://docs.readthedocs.io/en/stable/intro/import-guide.html diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000000..0f1b0e4fa0 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,59 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "starcraft" +copyright = "2023, Canonical" +author = "Canonical" + +# region General configuration +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.intersphinx", + "sphinx.ext.viewcode", + "sphinx.ext.coverage", + "sphinx.ext.doctest", + "sphinx_design", + "sphinx_copybutton", + "sphinx-pydantic", + "sphinx_toolbox", + "sphinx_toolbox.more_autodoc", + "sphinx.ext.autodoc", # Must be loaded after more_autodoc +] + +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +show_authors = False + +# endregion +# region Options for HTML output +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "furo" +html_static_path = ["_static"] + +# endregion +# region Options for extensions +# Intersphinx extension +# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration + +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), +} + +# Type hints configuration +set_type_checking_flag = True +typehints_fully_qualified = False +always_document_param_types = True + +# Github config +github_username = "canonical" +github_repository = "starcraft-base" + +# endregion diff --git a/docs/explanation/index.rst b/docs/explanation/index.rst new file mode 100644 index 0000000000..22c451229b --- /dev/null +++ b/docs/explanation/index.rst @@ -0,0 +1,7 @@ +.. _explanation: + +Explanation +********* + +.. toctree:: + :maxdepth: 1 diff --git a/docs/howto/index.rst b/docs/howto/index.rst new file mode 100644 index 0000000000..436a1880c1 --- /dev/null +++ b/docs/howto/index.rst @@ -0,0 +1,7 @@ +.. _howto: + +How-to guides +************* + +.. toctree:: + :maxdepth: 1 diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000000..0edd1e08eb --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,52 @@ +.. starcraft documentation root file + +StarCraft +========= + +.. toctree:: + :maxdepth: 1 + :hidden: + + tutorials/index + howto/index + reference/index + explanation/index + +.. grid:: 1 1 2 2 + + .. grid-item-card:: :ref:`Tutorial ` + + **Get started** with a hands-on introduction to Starcraft + + .. grid-item-card:: :ref:`How-to guides ` + + **Step-by-step guides** covering key operations and common tasks + +.. grid:: 1 1 2 2 + :reverse: + + .. grid-item-card:: :ref:`Reference ` + + **Technical information** about Starcraft + + .. grid-item-card:: :ref:`Explanation ` + + **Discussion and clarification** of key topics + +Project and community +===================== + +Starcraft is a member of the Canonical family. It's an open source project +that warmly welcomes community projects, contributions, suggestions, fixes +and constructive feedback. + +* `Ubuntu Code of Conduct `_. +* `Canonical contributor licenses agreement + `_. + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/reference/index.rst b/docs/reference/index.rst new file mode 100644 index 0000000000..75be505951 --- /dev/null +++ b/docs/reference/index.rst @@ -0,0 +1,13 @@ +.. _reference: + +Reference +********* + +.. toctree:: + :maxdepth: 1 + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst new file mode 100644 index 0000000000..eeb0a5cd97 --- /dev/null +++ b/docs/tutorials/index.rst @@ -0,0 +1,11 @@ +.. _tutorial: + +Tutorials +********* + +If you want to learn the basics from experience, then our tutorials will help +you acquire the necessary competencies from real-life examples with fully +reproducible steps. + +.. toctree:: + :maxdepth: 1 diff --git a/pyproject.toml b/pyproject.toml index 49d41fdce7..30021af702 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,15 @@ dev = [ ] types = [ ] +docs = [ + "sphinx==5.3.0", + "sphinx-copybutton==0.5.1", + "sphinx-design==0.3.0", + "sphinx-pydantic==0.1.1", + "sphinx-toolbox==3.4.0", + "sphinx-lint==0.6.7", + "furo==2022.12.07", +] [build-system] requires = [ diff --git a/tox.ini b/tox.ini index eb7d09a453..59683e5b4b 100644 --- a/tox.ini +++ b/tox.ini @@ -77,3 +77,23 @@ commands = black: black {tty:--color} {posargs} . ruff: ruff --fix --respect-gitignore {posargs} . codespell: codespell --toml {tox_root}/pyproject.toml --write-changes {posargs} + +[docs] # Sphinx documentation configuration +extras = docs +package = editable +no_package = true +env_dir = {work_dir}/docs +runner = ignore_env_name_mismatch + +[testenv:sphinx-build] +description = Build sphinx documentation +base = docs +allowlist_externals = bash +commands_pre = bash -c 'if [[ ! -e docs ]];then echo "No docs directory. Run `tox run -e sphinx-quickstart` to create one.;";return 1;fi' +commands = sphinx-build {posargs:-b html} {tox_root}/docs {tox_root}/docs/_build + +[testenv:lint-docs] +description = Lint the documentation with sphinx-lint +base = docs +commands = sphinx-lint {posargs} docs/ +labels = lint From 28bb9d85a83d6bec66539f8ad661b471d6da2ba6 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 25 Jan 2023 20:01:32 -0500 Subject: [PATCH 010/333] tests: coverage has per-env files --- tox.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tox.ini b/tox.ini index 192ffb6e2b..cf7149ed52 100644 --- a/tox.ini +++ b/tox.ini @@ -38,6 +38,9 @@ base = testenv, test description = Run unit tests with pytest labels = py38, py310, py311: tests, unit-tests +set_env = + TMPDIR={env_tmp_dir} + COVERAGE_FILE=.coverage_{env_name} commands = pytest {tty:--color=yes} --cov --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml tests/unit {posargs} [testenv:integration-{py38,py39,py310,py311,py312}] From a59bb4dd6c8c8e61d85981596e838156b51763ca Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 26 Jan 2023 10:43:06 -0500 Subject: [PATCH 011/333] tools: Make typing use an editable install Most static checks don't need the code to be installed at all, but type checking can require the code and its dependencies. --- tox.ini | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/tox.ini b/tox.ini index d7007ccd65..e082df2036 100644 --- a/tox.ini +++ b/tox.ini @@ -56,8 +56,6 @@ deps = ruff>=0.0.226 # renovate: datasource=pypi codespell[tomli]>=2.2.2 - # renovate: datasource=pypi - mypy[reports]>=0.991 env_dir = {work_dir}/linting runner = ignore_env_name_mismatch @@ -65,23 +63,38 @@ runner = ignore_env_name_mismatch find = find {tox_root} \( -name .git -o -name .tox \) -prune -o -print filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: -[testenv:lint-{black,ruff,pyright,shellcheck,codespell,mypy}] +[testenv:lint-{black,ruff,shellcheck,codespell}] description = Lint the source code base = testenv, lint labels = lint allowlist_externals = - pyright: pyright shellcheck: bash, xargs - mypy: mkdir commands_pre = - mypy: mkdir -p .mypy_cache shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' commands = black: black --check --diff {tty:--color} {posargs} . ruff: ruff --diff --respect-gitignore {posargs} . - pyright: pyright --lib {posargs} shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck codespell: codespell --toml {tox_root}/pyproject.toml {posargs} + +[testenv:lint-{mypy,pyright}] +description = Static type checking +base = testenv +deps = + # renovate: datasource=pypi + mypy[reports]>=0.991 +env_dir = {work_dir}/typing +runner = ignore_env_name_mismatch +package = editable +extras = [dev, types] +labels = lint, type +allowlist_externals = + pyright: pyright + mypy: mkdir +commands_pre = + mypy: mkdir -p .mypy_cache +commands = + pyright: pyright --lib {posargs} mypy: mypy --install-types --non-interactive . [testenv:format-{black,ruff,codespell}] From 77b955b5f4cf56b760734eeac3aecfbd9671f503 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 26 Jan 2023 11:03:26 -0500 Subject: [PATCH 012/333] Configure sphinx-lint Done the same way as in rockcraft Co-authored-by: Tiago Nobrega --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 59683e5b4b..b885f1f6c6 100644 --- a/tox.ini +++ b/tox.ini @@ -95,5 +95,5 @@ commands = sphinx-build {posargs:-b html} {tox_root}/docs {tox_root}/docs/_build [testenv:lint-docs] description = Lint the documentation with sphinx-lint base = docs -commands = sphinx-lint {posargs} docs/ +commands = sphinx-lint --ignore docs/_build --max-line-length 80 -e all {posargs} docs/ labels = lint From f2f804d4b19833f6c98832b0292b4a344f31e1be Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 26 Jan 2023 14:30:47 -0500 Subject: [PATCH 013/333] chore(tools): Make pyproject.toml exclude rather than include Rather than statically declaring the project to be "starcraft" all over the place, prefer excluding directories. --- pyproject.toml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 31b4370c93..4b70aaf746 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,15 +31,20 @@ requires = [ ] build-backend = "setuptools.build_meta" -[tool.setuptools] -packages = ["starcraft"] +[tool.setuptools.packages.find] +exclude = [ + "dist", + "docs", + "results", + "tests", +] [tool.black] target-version = ["py38"] [tool.codespell] ignore-words-list = "buildd,crate,keyserver,comandos,ro,dedent,dedented" -skip = ".tox,.git,build,.*_cache,__pycache__,*.tar,*.snap,*.png,node_modules" +skip = ".tox,.git,build,.*_cache,__pycache__,*.tar,*.snap,*.png,./node_modules,./docs/_build" quiet-level = 3 check-filenames = true @@ -74,9 +79,10 @@ venv = "py38" [tool.mypy] python_version = "3.8" -packages = ["starcraft"] exclude = [ - "build" + "build", + "tests", + "results", ] warn_unused_configs = true warn_redundant_casts = true From 067df32731b3cd99ade13149b2564d5fffd6866b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 06:38:08 +0000 Subject: [PATCH 014/333] chore(deps): update release-drafter/release-drafter action to v5.22.0 --- .github/workflows/release-drafter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index d2e8e70ae0..d74b8d840e 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Release Drafter - uses: release-drafter/release-drafter@v5.7.0 + uses: release-drafter/release-drafter@v5.22.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From f3e23e360bb5c20ae43142c91abd35cb64a5f611 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 09:41:07 +0000 Subject: [PATCH 015/333] chore(deps): update dependency pytest to v7.2.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 55a9f86506..2bd805c033 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ - "pytest==7.0.0", + "pytest==7.2.1", "pytest-cov==4.0.0", "pytest-mock==3.10.0", ] From bcadedb9ce51854068c0aee910a2254f9ef2da7f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 12:25:31 +0000 Subject: [PATCH 016/333] chore(deps): update dependency tox to v4.4.2 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 04af17d625..bcad7e5314 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ minversion = 4.3.5 # install tox from apt. Older than that, the user gets an upgrade warning. requires = # renovate: datasource=pypi - tox==4.3.5 + tox==4.4.2 # renovate: datasource=pypi tox-ignore-env-name-mismatch==0.2.0 # Allow tox to access the user's $TMPDIR environment variable if set. From 1a08aca9cde8aaf7c855703de0f2743ff788e715 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 16:17:11 +0000 Subject: [PATCH 017/333] chore(deps): update dependency tox-ignore-env-name-mismatch to v0.2.0.post2 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index bcad7e5314..39f5c8bec2 100644 --- a/tox.ini +++ b/tox.ini @@ -13,7 +13,7 @@ requires = # renovate: datasource=pypi tox==4.4.2 # renovate: datasource=pypi - tox-ignore-env-name-mismatch==0.2.0 + tox-ignore-env-name-mismatch==0.2.0.post2 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From 0f3d7d0bf01cbd9a3c95b67b603d84168ac613ff Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 31 Jan 2023 19:39:34 -0600 Subject: [PATCH 018/333] lint: specify a single ruff version (#21) Ensure that ruff only gets updated by renovate or explicitly in PRs. This will prevent random CI breakages until ruff is stable. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 39f5c8bec2..d54db5faca 100644 --- a/tox.ini +++ b/tox.ini @@ -56,7 +56,7 @@ deps = # renovate: datasource=pypi black>=22.12.0 # renovate: datasource=pypi - ruff>=0.0.226 + ruff==0.0.236 # renovate: datasource=pypi codespell[tomli]>=2.2.2 env_dir = {work_dir}/linting From 5a0d09f2ed7c65cc7e5c7f57b9e0c12f106228c1 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 31 Jan 2023 19:40:40 -0600 Subject: [PATCH 019/333] tools: add yamllint (#11) --- .github/release-drafter.yaml | 2 +- .yamllint.yaml | 12 ++++++++++++ tox.ini | 5 ++++- 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 .yamllint.yaml diff --git a/.github/release-drafter.yaml b/.github/release-drafter.yaml index 50f9d88e4c..5262e23c6a 100644 --- a/.github/release-drafter.yaml +++ b/.github/release-drafter.yaml @@ -18,7 +18,7 @@ categories: change-template: '- $TITLE @$AUTHOR (#$NUMBER)' template: | Special thanks to the contributors that made this release happen: $CONTRIBUTORS - + ## Full list of changes $CHANGES diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 0000000000..8f7da7486b --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,12 @@ +--- +ignore-from-file: [.gitignore] + +extends: default + +rules: + document-start: disable + float-values: enable + line-length: disable + octal-values: enable + truthy: + check-keys: false diff --git a/tox.ini b/tox.ini index d54db5faca..d2c95755db 100644 --- a/tox.ini +++ b/tox.ini @@ -59,6 +59,8 @@ deps = ruff==0.0.236 # renovate: datasource=pypi codespell[tomli]>=2.2.2 + # renovate: datasource=pypi + yamllint==1.29.0 env_dir = {work_dir}/linting runner = ignore_env_name_mismatch @@ -66,7 +68,7 @@ runner = ignore_env_name_mismatch find = find {tox_root} \( -name .git -o -name .tox \) -prune -o -print filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: -[testenv:lint-{black,ruff,shellcheck,codespell}] +[testenv:lint-{black,ruff,shellcheck,codespell,yaml}] description = Lint the source code base = testenv, lint labels = lint @@ -79,6 +81,7 @@ commands = ruff: ruff --diff --respect-gitignore {posargs} . shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck codespell: codespell --toml {tox_root}/pyproject.toml {posargs} + yaml: yamllint {posargs} . [testenv:lint-{mypy,pyright}] description = Static type checking From 9c1ea2acfad01ec5a92a993650dd64ff5730f601 Mon Sep 17 00:00:00 2001 From: Sergio Schvezov Date: Wed, 1 Feb 2023 14:24:55 -0300 Subject: [PATCH 020/333] readme: update name (#23) --- README.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 7e7d9e4048..7e615600c3 100644 --- a/README.rst +++ b/README.rst @@ -1,6 +1,6 @@ -************** -starcraft-base -************** +******** +starbase +******** A base repository for Starcraft projects. From f3d35a68e03f5ebe492866e6474dcb53760fde3c Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 1 Feb 2023 12:38:29 -0600 Subject: [PATCH 021/333] chore(lint): update ruff and config (#22) New ignore: Too many arguments on test functions * chore(lint): Ruff autofixes for new pylint --- pyproject.toml | 4 +++- tox.ini | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2bd805c033..68c9bb1d18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -140,7 +140,8 @@ select = [ # Base linting rule selections. "ISC", # Implicit string concatenation that can cause subtle issues "ICN", # Only use common conventions for import aliases. "Q", # Consistent quotations - "RET" # Simpler logic after return, raise, continue or break + "RET", # Simpler logic after return, raise, continue or break + "UP018", "C408", # Convert type calls to literals. The latest pylint enforces this, but ruff has auto-fixes. ] extend-select = [ # These sets are still frequently getting new rules. @@ -187,6 +188,7 @@ ignore = [ "S101", # Allow assertions in tests "S103", # Allow `os.chmod` setting a permissive mask `0o555` on file or directory "S108", # Allow Probable insecure usage of temporary file or directory + "PLR0913", # Allow many arguments for test functions ] # isort leaves init files alone by default, this makes ruff ignore them too. "__init__.py" = ["I001"] diff --git a/tox.ini b/tox.ini index d2c95755db..a856c331c9 100644 --- a/tox.ini +++ b/tox.ini @@ -56,7 +56,7 @@ deps = # renovate: datasource=pypi black>=22.12.0 # renovate: datasource=pypi - ruff==0.0.236 + ruff==0.0.239 # renovate: datasource=pypi codespell[tomli]>=2.2.2 # renovate: datasource=pypi From cd2832bfb83cb2239b252d94b17c796951f9566a Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Fri, 3 Feb 2023 11:46:48 -0300 Subject: [PATCH 022/333] tools: add sphinx-lint to regular linting --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index a856c331c9..f5970a1c12 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] env_list = # Environments to run when called with no parameters. - lint-{black,ruff,pyright,shellcheck,codespell} + lint-{black,ruff,pyright,shellcheck,codespell,docs} test-py38 minversion = 4.3.5 # Tox will use these requirements to bootstrap a venv if necessary. From 130845ccf2d8d622af9d4a3f69341af0fda511ff Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Fri, 3 Feb 2023 11:52:20 -0300 Subject: [PATCH 023/333] docs: use Ubuntu font --- docs/_static/css/custom.css | 28 ++++++++++++++++++++++++++++ docs/conf.py | 3 +++ 2 files changed, 31 insertions(+) create mode 100644 docs/_static/css/custom.css diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css new file mode 100644 index 0000000000..ef7e97f641 --- /dev/null +++ b/docs/_static/css/custom.css @@ -0,0 +1,28 @@ +@import url('https://fonts.googleapis.com/css2?family=Ubuntu:ital@0;1&display=swap'); + +body { + font-family: Ubuntu, "times new roman", times, roman, serif; +} + +div .toctree-wrapper { + column-count: 2; +} + +div .toctree-wrapper>ul { + margin: 0; +} + +ul .toctree-l1 { + margin: 0; + -webkit-column-break-inside: avoid; + page-break-inside: avoid; + break-inside: avoid-column; +} + +.wy-nav-content { + max-width: none; +} + +.log-snippets { + color: rgb(141, 141, 141); +} diff --git a/docs/conf.py b/docs/conf.py index 0f1b0e4fa0..eeb02572f3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -37,6 +37,9 @@ html_theme = "furo" html_static_path = ["_static"] +html_css_files = [ + "css/custom.css", +] # endregion # region Options for extensions From ec396df45355053cb08e4f69ceb9573f7b4203a2 Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Fri, 3 Feb 2023 11:53:04 -0300 Subject: [PATCH 024/333] docs: treat warnings as errors in build --- docs/explanation/index.rst | 2 +- tox.ini | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/explanation/index.rst b/docs/explanation/index.rst index 22c451229b..b9ed902fb0 100644 --- a/docs/explanation/index.rst +++ b/docs/explanation/index.rst @@ -1,7 +1,7 @@ .. _explanation: Explanation -********* +*********** .. toctree:: :maxdepth: 1 diff --git a/tox.ini b/tox.ini index f5970a1c12..dba89bdd21 100644 --- a/tox.ini +++ b/tox.ini @@ -124,7 +124,8 @@ description = Build sphinx documentation base = docs allowlist_externals = bash commands_pre = bash -c 'if [[ ! -e docs ]];then echo "No docs directory. Run `tox run -e sphinx-quickstart` to create one.;";return 1;fi' -commands = sphinx-build {posargs:-b html} {tox_root}/docs {tox_root}/docs/_build +# "-W" is to treat warnings as errors +commands = sphinx-build {posargs:-b html} -W {tox_root}/docs {tox_root}/docs/_build [testenv:lint-docs] description = Lint the documentation with sphinx-lint From 34e0222b608331b2d5e1c2411de6961b15dcc48d Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Fri, 3 Feb 2023 11:57:26 -0300 Subject: [PATCH 025/333] tools: add sphinx-autobuild --- pyproject.toml | 3 ++- tox.ini | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 68c9bb1d18..717c4aa6d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,13 +25,14 @@ dev = [ types = [ ] docs = [ + "furo==2022.12.07", "sphinx==5.3.0", + "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.1", "sphinx-design==0.3.0", "sphinx-pydantic==0.1.1", "sphinx-toolbox==3.4.0", "sphinx-lint==0.6.7", - "furo==2022.12.07", ] [build-system] diff --git a/tox.ini b/tox.ini index dba89bdd21..2eab382012 100644 --- a/tox.ini +++ b/tox.ini @@ -127,6 +127,11 @@ commands_pre = bash -c 'if [[ ! -e docs ]];then echo "No docs directory. Run `to # "-W" is to treat warnings as errors commands = sphinx-build {posargs:-b html} -W {tox_root}/docs {tox_root}/docs/_build +[testenv:rundocs] +description = Build documentation with an autoupdating server +base = docs +commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} -W --watch {tox_root}/starcraft {tox_root}/docs {tox_root}/docs/_build + [testenv:lint-docs] description = Lint the documentation with sphinx-lint base = docs From dbd1b1dfe578a193923c6b93c8fc8d957fe3ec19 Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Fri, 3 Feb 2023 12:01:12 -0300 Subject: [PATCH 026/333] tools: rename sphinx-build and rundocs Rename them to docs-build and docs-autobuild (respectively). This is to keep consistent with the other tox environments, which use the - prefix grouping. --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 2eab382012..7b67e8ae62 100644 --- a/tox.ini +++ b/tox.ini @@ -119,7 +119,7 @@ no_package = true env_dir = {work_dir}/docs runner = ignore_env_name_mismatch -[testenv:sphinx-build] +[testenv:docs-build] description = Build sphinx documentation base = docs allowlist_externals = bash @@ -127,7 +127,7 @@ commands_pre = bash -c 'if [[ ! -e docs ]];then echo "No docs directory. Run `to # "-W" is to treat warnings as errors commands = sphinx-build {posargs:-b html} -W {tox_root}/docs {tox_root}/docs/_build -[testenv:rundocs] +[testenv:docs-autobuild] description = Build documentation with an autoupdating server base = docs commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} -W --watch {tox_root}/starcraft {tox_root}/docs {tox_root}/docs/_build From 8abb2216fa34969b4236c7bce3572c3ea15fbb9f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 4 Feb 2023 20:44:46 -0500 Subject: [PATCH 027/333] chore(deps): update dependency setuptools to v67 (#26) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 717c4aa6d8..ccd10cb871 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ docs = [ [build-system] requires = [ - "setuptools==66.1.1", + "setuptools==67.1.0", ] build-backend = "setuptools.build_meta" From 4b3781bc6f291fa72a2a99eac97271b23b9e9f5f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 4 Feb 2023 23:10:09 -0600 Subject: [PATCH 028/333] chore(deps): update patch updates (#25) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 7b67e8ae62..4f7d43f6f9 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ minversion = 4.3.5 # install tox from apt. Older than that, the user gets an upgrade warning. requires = # renovate: datasource=pypi - tox==4.4.2 + tox==4.4.4 # renovate: datasource=pypi tox-ignore-env-name-mismatch==0.2.0.post2 # Allow tox to access the user's $TMPDIR environment variable if set. @@ -56,7 +56,7 @@ deps = # renovate: datasource=pypi black>=22.12.0 # renovate: datasource=pypi - ruff==0.0.239 + ruff==0.0.240 # renovate: datasource=pypi codespell[tomli]>=2.2.2 # renovate: datasource=pypi From 679c20f5ca46990b106b3613c8d35675828c97ea Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 6 Feb 2023 15:26:13 -0600 Subject: [PATCH 029/333] tools: Add editorconfig (#9) --- .editorconfig | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..6056a3e845 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,43 @@ +# Editor configuration options. +# See: https://spec.editorconfig.org/ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +max_line_length = 80 +trim_trailing_whitespace = true + +[.editorconfig] +max_line_length = off + +[Makefile] +indent_style = tab + +[{*.py,*.pyi}] +max_line_length = 88 + +[{*.bash,*.sh,*.zsh}] +indent_size = 2 +tab_width = 2 + +[{*.har,*.json,*.json5}] +indent_size = 2 +max_line_length = off + +[{*.markdown,*.md,*.rst}] +max_line_length = off +ij_visual_guides = none + +[{*.toml,Cargo.lock,Cargo.toml.orig,Gopkg.lock,Pipfile,poetry.lock}] +max_line_length = off + +[{*.ini, *.cfg}] +max_line_length = off + +[{*.yaml,*.yml}] +indent_size = 2 +max_line_length = off From 2aaed7eda34db06a17dcaa4bbf6d2d4f64790a3e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 13 Feb 2023 15:26:16 -0600 Subject: [PATCH 030/333] tools: improve coverage support in the tox test environments (#32) --- pyproject.toml | 1 + tox.ini | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ccd10cb871..77e7d6bf1b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,7 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ + "coverage[toml]==7.1.0", "pytest==7.2.1", "pytest-cov==4.0.0", "pytest-mock==3.10.0", diff --git a/tox.ini b/tox.ini index 4f7d43f6f9..9c644856ce 100644 --- a/tox.ini +++ b/tox.ini @@ -26,9 +26,10 @@ user_tmp_dir = {env:TMPDIR} env_tmp_dir = {user_tmp_dir:{env:XDG_RUNTIME_DIR:{work_dir}}}/tox_tmp/{env_name} set_env = TMPDIR={env_tmp_dir} + COVERAGE_FILE={env_tmp_dir}/.coverage_{env_name} [test] # Base configuration for unit and integration tests -package = sdist +package = editable extras = dev allowlist_externals = mkdir commands_pre = mkdir -p results @@ -38,9 +39,6 @@ base = testenv, test description = Run unit tests with pytest labels = py38, py310, py311: tests, unit-tests -set_env = - TMPDIR={env_tmp_dir} - COVERAGE_FILE=.coverage_{env_name} commands = pytest {tty:--color=yes} --cov --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml tests/unit {posargs} [testenv:integration-{py38,py39,py310,py311,py312}] From f4774ed9acfb32638a18c95ac21c734596663a99 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 13 Feb 2023 15:55:44 -0600 Subject: [PATCH 031/333] tools: fix the PR template name (#31) --- .github/{PULL_RELEASE_TEMPLATE.md => PULL_REQUEST_TEMPLATE.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{PULL_RELEASE_TEMPLATE.md => PULL_REQUEST_TEMPLATE.md} (100%) diff --git a/.github/PULL_RELEASE_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from .github/PULL_RELEASE_TEMPLATE.md rename to .github/PULL_REQUEST_TEMPLATE.md From 3ea924f96b5d72d22498e6e90a67f31aaf8ecf84 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Feb 2023 16:57:51 -0500 Subject: [PATCH 032/333] chore(deps): update dependency setuptools to v67.2.0 (#30) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 77e7d6bf1b..7adec4b9fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ docs = [ [build-system] requires = [ - "setuptools==67.1.0", + "setuptools==67.2.0", ] build-backend = "setuptools.build_meta" From 2c6d0ba3bbe523212d7ee616908903d4c077fc09 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Feb 2023 20:43:55 -0500 Subject: [PATCH 033/333] chore(deps): update patch updates (#29) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 9c644856ce..ae5b0b277b 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ minversion = 4.3.5 # install tox from apt. Older than that, the user gets an upgrade warning. requires = # renovate: datasource=pypi - tox==4.4.4 + tox==4.4.5 # renovate: datasource=pypi tox-ignore-env-name-mismatch==0.2.0.post2 # Allow tox to access the user's $TMPDIR environment variable if set. @@ -54,7 +54,7 @@ deps = # renovate: datasource=pypi black>=22.12.0 # renovate: datasource=pypi - ruff==0.0.240 + ruff==0.0.245 # renovate: datasource=pypi codespell[tomli]>=2.2.2 # renovate: datasource=pypi From a0e2622ef3c4931633e57e3bbd1078862be9c432 Mon Sep 17 00:00:00 2001 From: Callahan Date: Thu, 16 Feb 2023 18:32:22 -0600 Subject: [PATCH 034/333] lint(shellcheck): replace `find` with `git ls-files` (#33) Signed-off-by: Callahan Kovacs --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index ae5b0b277b..13da7b152d 100644 --- a/tox.ini +++ b/tox.ini @@ -63,7 +63,7 @@ env_dir = {work_dir}/linting runner = ignore_env_name_mismatch [shellcheck] -find = find {tox_root} \( -name .git -o -name .tox \) -prune -o -print +find = git ls-files filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: [testenv:lint-{black,ruff,shellcheck,codespell,yaml}] From 23902661d9ea13960cc3ff339ab2cd9ac57d6256 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 17 Feb 2023 14:27:40 -0600 Subject: [PATCH 035/333] lint: freeze the linter versions (#27) --- tox.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index 13da7b152d..50cdb23257 100644 --- a/tox.ini +++ b/tox.ini @@ -52,11 +52,11 @@ commands = pytest {tty:--color=yes} --junit-xml=results/test-results-{env_name}. skip_install = true deps = # renovate: datasource=pypi - black>=22.12.0 + black==22.12.0 # renovate: datasource=pypi ruff==0.0.245 # renovate: datasource=pypi - codespell[tomli]>=2.2.2 + codespell[tomli]==2.2.2 # renovate: datasource=pypi yamllint==1.29.0 env_dir = {work_dir}/linting @@ -86,7 +86,7 @@ description = Static type checking base = testenv deps = # renovate: datasource=pypi - mypy[reports]>=0.991 + mypy[reports]==0.991 env_dir = {work_dir}/typing runner = ignore_env_name_mismatch package = editable From ee3c053febcb3ebe240d00cda243f058e42ca34d Mon Sep 17 00:00:00 2001 From: Callahan Date: Fri, 17 Feb 2023 17:07:42 -0600 Subject: [PATCH 036/333] lint: skip more commonly ignored files and directories with codespell (#35) .direnv, .venv, venv, and .vscode are now skipped. Signed-off-by: Callahan Kovacs --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7adec4b9fd..7fd763ce02 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,7 @@ target-version = ["py38"] [tool.codespell] ignore-words-list = "buildd,crate,keyserver,comandos,ro,dedent,dedented" -skip = ".tox,.git,build,.*_cache,__pycache__,*.tar,*.snap,*.png,./node_modules,./docs/_build" +skip = ".tox,.git,build,.*_cache,__pycache__,*.tar,*.snap,*.png,./node_modules,./docs/_build,.direnv,.venv,venv,.vscode" quiet-level = 3 check-filenames = true From d9c79f0bad0253417ba6c82da64067666860373b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:53:45 -0600 Subject: [PATCH 037/333] chore(deps): update dependency mypy to v1 (#39) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 50cdb23257..ffcc9ab2ae 100644 --- a/tox.ini +++ b/tox.ini @@ -86,7 +86,7 @@ description = Static type checking base = testenv deps = # renovate: datasource=pypi - mypy[reports]==0.991 + mypy[reports]==1.0.1 env_dir = {work_dir}/typing runner = ignore_env_name_mismatch package = editable From 867bb8f454bdb45210235720a03eb44284db39b4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:55:52 -0600 Subject: [PATCH 038/333] chore(deps): update dependency ruff to v0.0.247 (#37) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index ffcc9ab2ae..d9575bd726 100644 --- a/tox.ini +++ b/tox.ini @@ -54,7 +54,7 @@ deps = # renovate: datasource=pypi black==22.12.0 # renovate: datasource=pypi - ruff==0.0.245 + ruff==0.0.247 # renovate: datasource=pypi codespell[tomli]==2.2.2 # renovate: datasource=pypi From 821339bbad7edbfca0b73afb42e695ea1627be14 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:58:11 -0600 Subject: [PATCH 039/333] chore(deps): update dependency black to v23 (#38) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index d9575bd726..b2418f00e2 100644 --- a/tox.ini +++ b/tox.ini @@ -52,7 +52,7 @@ commands = pytest {tty:--color=yes} --junit-xml=results/test-results-{env_name}. skip_install = true deps = # renovate: datasource=pypi - black==22.12.0 + black==23.1.0 # renovate: datasource=pypi ruff==0.0.247 # renovate: datasource=pypi From 6b9719a0b1da5c76cad1106067a0f249361a922b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Feb 2023 14:00:04 -0600 Subject: [PATCH 040/333] chore(deps): update dependency setuptools to v67.3.2 (#36) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7fd763ce02..cdc943ee33 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ docs = [ [build-system] requires = [ - "setuptools==67.2.0", + "setuptools==67.3.2", ] build-backend = "setuptools.build_meta" From cf1d0188c0fe18a8c901af9a13e336d5590fe757 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Sun, 19 Feb 2023 14:05:25 -0600 Subject: [PATCH 041/333] deps: group major dev dependency versions (#28) --- .github/renovate.json5 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index a7261fdcfe..7c1a6a53a7 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -46,7 +46,9 @@ prPriority: -2 }, { - // Major dev dependencies are stone last. + // Major dev dependencies are stone last, but grouped. + groupName: "development dependencies (major versions)", + groupSlug: "dev-dependencies", matchDepTypes: ["devDependencies"], matchUpdateTypes: ["major"], prPriority: -3 From c99b12beeae3d298d4822c6ebbfc6c8f9fab0ba9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 12:30:35 -0500 Subject: [PATCH 042/333] chore(deps): update patch updates (#40) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index b2418f00e2..5b80d1480b 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ minversion = 4.3.5 # install tox from apt. Older than that, the user gets an upgrade warning. requires = # renovate: datasource=pypi - tox==4.4.5 + tox==4.4.6 # renovate: datasource=pypi tox-ignore-env-name-mismatch==0.2.0.post2 # Allow tox to access the user's $TMPDIR environment variable if set. @@ -54,7 +54,7 @@ deps = # renovate: datasource=pypi black==23.1.0 # renovate: datasource=pypi - ruff==0.0.247 + ruff==0.0.252 # renovate: datasource=pypi codespell[tomli]==2.2.2 # renovate: datasource=pypi From ffa1dec7ba709132e0c083278c12209ac0015aff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 12:31:43 -0500 Subject: [PATCH 043/333] chore(deps): update dependency coverage to v7.2.1 (#42) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cdc943ee33..4c30078356 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ - "coverage[toml]==7.1.0", + "coverage[toml]==7.2.1", "pytest==7.2.1", "pytest-cov==4.0.0", "pytest-mock==3.10.0", From 6c1a196713c3fc0ece34b07b780b848c3c75ff72 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 12:32:14 -0500 Subject: [PATCH 044/333] chore(deps): update dependency setuptools to v67.4.0 (#43) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4c30078356..75f59be0c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ docs = [ [build-system] requires = [ - "setuptools==67.3.2", + "setuptools==67.4.0", ] build-backend = "setuptools.build_meta" From c0ccfdab297502192edc2675fc80696e4e612d1f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 12:33:00 -0500 Subject: [PATCH 045/333] chore(deps): update release-drafter/release-drafter action to v5.23.0 (#41) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-drafter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index d74b8d840e..8c79f119ac 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Release Drafter - uses: release-drafter/release-drafter@v5.22.0 + uses: release-drafter/release-drafter@v5.23.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 7f8ff19c884532868fffa9a22da8ab30720af52d Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 1 Mar 2023 13:07:33 -0500 Subject: [PATCH 046/333] docs: Tox environments and labels (#44) --- HACKING.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/HACKING.rst b/HACKING.rst index 0a5afceb73..1ae2e80f03 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -44,6 +44,26 @@ If you'd like to run the tests with a newer version of Python, you can pass a sp tox -e test-py310 +Tox environments and labels +########################### + +We group tox environments with the following labels: + +* ``format``: Runs all code formatters with auto-fixing +* ``type``: Runs all type checkers +* ``lint``: Runs all linters (including type checkers) +* ``unit-tests``: Runs unit tests in Python versions on supported LTS's + latest +* ``integration-tests``: Same as above but for integration tests +* ``tests``: The union of ``unit-tests`` and ``integration-tests`` + +For each of these, you can see which environments will be run with ``tox list``. For example: + + tox list -m lint + +You can also see all the environments by simply running ``tox list`` + +Running ``tox run -m format`` and ``tox run -m lint`` before committing code is recommended. + .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ .. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa From e1a7c75e9d970f692eca5b44984fda36fc99f544 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 9 Mar 2023 09:45:00 -0500 Subject: [PATCH 047/333] ci: don't upload test results when cancelling the workflow #46 Committed via https://github.com/asottile/all-repos --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index c78c6d1783..008a38d076 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -72,7 +72,7 @@ jobs: directory: ./results/ files: coverage*.xml - name: Upload test results - if: always() + if: success() || failure() uses: actions/upload-artifact@v3 with: name: test-results-${{ matrix.platform }} From 4cd5f917b7017234f8192459ad9c0af171d76526 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Mar 2023 18:50:33 -0400 Subject: [PATCH 048/333] chore(deps): update patch updates (#45) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- tox.ini | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 75f59be0c3..78d79c4e94 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,8 +18,8 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ - "coverage[toml]==7.2.1", - "pytest==7.2.1", + "coverage[toml]==7.2.2", + "pytest==7.2.2", "pytest-cov==4.0.0", "pytest-mock==3.10.0", ] diff --git a/tox.ini b/tox.ini index 5b80d1480b..9253916c32 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ minversion = 4.3.5 # install tox from apt. Older than that, the user gets an upgrade warning. requires = # renovate: datasource=pypi - tox==4.4.6 + tox==4.4.7 # renovate: datasource=pypi tox-ignore-env-name-mismatch==0.2.0.post2 # Allow tox to access the user's $TMPDIR environment variable if set. @@ -54,9 +54,9 @@ deps = # renovate: datasource=pypi black==23.1.0 # renovate: datasource=pypi - ruff==0.0.252 + ruff==0.0.256 # renovate: datasource=pypi - codespell[tomli]==2.2.2 + codespell[tomli]==2.2.4 # renovate: datasource=pypi yamllint==1.29.0 env_dir = {work_dir}/linting From a4a079ad1df2e79019a2fe044636418ac2580b5e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Mar 2023 12:59:23 -0400 Subject: [PATCH 049/333] chore(deps): update dependency setuptools to v67.6.0 (#48) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 78d79c4e94..b3445bc33f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ docs = [ [build-system] requires = [ - "setuptools==67.4.0", + "setuptools==67.6.0", ] build-backend = "setuptools.build_meta" From 2206424c46e6b05eaacda06cbe4b820e5696b946 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 19:49:35 -0400 Subject: [PATCH 050/333] chore(deps): update dependency mypy to v1.1.1 (#47) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 9253916c32..f1a4455e0c 100644 --- a/tox.ini +++ b/tox.ini @@ -86,7 +86,7 @@ description = Static type checking base = testenv deps = # renovate: datasource=pypi - mypy[reports]==1.0.1 + mypy[reports]==1.1.1 env_dir = {work_dir}/typing runner = ignore_env_name_mismatch package = editable From fe58f832311613d7c53f8c57735b69cda3d9205b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 21:12:52 -0400 Subject: [PATCH 051/333] chore(deps): update dependency black to v23.3.0 (#49) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index f1a4455e0c..20e2b650dd 100644 --- a/tox.ini +++ b/tox.ini @@ -52,7 +52,7 @@ commands = pytest {tty:--color=yes} --junit-xml=results/test-results-{env_name}. skip_install = true deps = # renovate: datasource=pypi - black==23.1.0 + black==23.3.0 # renovate: datasource=pypi ruff==0.0.256 # renovate: datasource=pypi From 3f6896cdef3c69855f48aea43f57d22dcc9c3a7e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 21:13:07 -0400 Subject: [PATCH 052/333] chore(deps): update dependency mypy to v1.2.0 (#50) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 20e2b650dd..de2f1136d0 100644 --- a/tox.ini +++ b/tox.ini @@ -86,7 +86,7 @@ description = Static type checking base = testenv deps = # renovate: datasource=pypi - mypy[reports]==1.1.1 + mypy[reports]==1.2.0 env_dir = {work_dir}/typing runner = ignore_env_name_mismatch package = editable From 263a302dca05bb58861f2b8adecc04a191914bc8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 21:13:34 -0400 Subject: [PATCH 053/333] chore(deps): update dependency furo to v2023 (#52) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b3445bc33f..cd60d1c61b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ types = [ ] docs = [ - "furo==2022.12.07", + "furo==2023.3.27", "sphinx==5.3.0", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.1", From 9de5c85b743a288d6939b669715b4d75529086fa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 21:14:14 -0400 Subject: [PATCH 054/333] chore(deps): update dependency yamllint to v1.31.0 (#51) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index de2f1136d0..eff560a3a1 100644 --- a/tox.ini +++ b/tox.ini @@ -58,7 +58,7 @@ deps = # renovate: datasource=pypi codespell[tomli]==2.2.4 # renovate: datasource=pypi - yamllint==1.29.0 + yamllint==1.31.0 env_dir = {work_dir}/linting runner = ignore_env_name_mismatch From 4adb0698b309817571a5dd8e4208629457408586 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 10 May 2023 08:20:54 -0400 Subject: [PATCH 055/333] tox: move deps from tox.ini into pyproject.toml (#53) --- pyproject.toml | 10 ++++++++-- tox.ini | 38 +++++++++++--------------------------- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cd60d1c61b..b87757686c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,15 @@ dev = [ "pytest-cov==4.0.0", "pytest-mock==3.10.0", ] +lint = [ + "black==23.3.0", + "codespell[toml]==2.2.4", + "ruff==0.0.256", + "yamllint==1.29.0" +] types = [ + "mypy[reports]==1.2.0", + "pyright==1.1.306", ] docs = [ "furo==2023.3.27", @@ -85,8 +93,6 @@ fail_under = 80 strict = ["starcraft"] pythonVersion = "3.8" pythonPlatform = "Linux" -venvPath = ".tox" -venv = "py38" [tool.mypy] python_version = "3.8" diff --git a/tox.ini b/tox.ini index eff560a3a1..bcea8ed392 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,8 @@ [tox] env_list = # Environments to run when called with no parameters. lint-{black,ruff,pyright,shellcheck,codespell,docs} - test-py38 -minversion = 4.3.5 + test-{py38,py310,py311} +minversion = 4.5 # Tox will use these requirements to bootstrap a venv if necessary. # tox-igore-env-name-mismatch allows us to have one virtualenv for all linting. # By setting requirements here, we make this INI file compatible with older @@ -11,9 +11,7 @@ minversion = 4.3.5 # install tox from apt. Older than that, the user gets an upgrade warning. requires = # renovate: datasource=pypi - tox==4.4.7 - # renovate: datasource=pypi - tox-ignore-env-name-mismatch==0.2.0.post2 + tox-ignore-env-name-mismatch>=0.2.0.post2 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. @@ -49,16 +47,8 @@ labels = commands = pytest {tty:--color=yes} --junit-xml=results/test-results-{env_name}.xml tests/integration {posargs} [lint] # Standard linting configuration -skip_install = true -deps = - # renovate: datasource=pypi - black==23.3.0 - # renovate: datasource=pypi - ruff==0.0.256 - # renovate: datasource=pypi - codespell[tomli]==2.2.4 - # renovate: datasource=pypi - yamllint==1.31.0 +package = editable +extras = lint env_dir = {work_dir}/linting runner = ignore_env_name_mismatch @@ -83,23 +73,17 @@ commands = [testenv:lint-{mypy,pyright}] description = Static type checking -base = testenv -deps = - # renovate: datasource=pypi - mypy[reports]==1.2.0 +base = testenv, lint env_dir = {work_dir}/typing -runner = ignore_env_name_mismatch -package = editable -extras = [dev, types] +extras = dev, types labels = lint, type allowlist_externals = - pyright: pyright mypy: mkdir commands_pre = mypy: mkdir -p .mypy_cache commands = - pyright: pyright --lib {posargs} - mypy: mypy --install-types --non-interactive . + pyright: pyright {posargs} + mypy: mypy --install-types --non-interactive {posargs:.} [testenv:format-{black,ruff,codespell}] description = Automatically format source code @@ -117,7 +101,7 @@ no_package = true env_dir = {work_dir}/docs runner = ignore_env_name_mismatch -[testenv:docs-build] +[testenv:build-docs] description = Build sphinx documentation base = docs allowlist_externals = bash @@ -125,7 +109,7 @@ commands_pre = bash -c 'if [[ ! -e docs ]];then echo "No docs directory. Run `to # "-W" is to treat warnings as errors commands = sphinx-build {posargs:-b html} -W {tox_root}/docs {tox_root}/docs/_build -[testenv:docs-autobuild] +[testenv:autobuild-docs] description = Build documentation with an autoupdating server base = docs commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} -W --watch {tox_root}/starcraft {tox_root}/docs {tox_root}/docs/_build From eaa6714a857c8b28ab39b21196a91607f433d649 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 9 May 2023 21:16:29 -0400 Subject: [PATCH 056/333] deps: fix renovate automerge schedule --- .github/renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 7c1a6a53a7..1ee5767afa 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -65,7 +65,7 @@ } ], timezone: "Etc/UTC", - automergeSchedule: "after 1 am and before 7 am", + automergeSchedule: "every weekend", schedule: "every weekend", prConcurrentLimit: 5, // No more than 5 open PRs at a time. prCreation: "not-pending", // Wait until status checks have completed before raising the PR From c6464d4f06a42f69e285885704c550b5e1a00f71 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 9 May 2023 23:40:59 -0400 Subject: [PATCH 057/333] tools: further improve renovate --- .github/renovate.json5 | 43 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 1ee5767afa..e54ee71b71 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,9 +1,9 @@ - { +{ // Configuration file for RenovateBot: https://docs.renovatebot.com/configuration-options extends: ["config:base"], labels: ["dependencies"], // For convenient searching in GitHub pip_requirements: { - fileMatch: ["^tox.ini$"] + fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$"] }, pip_setup: { fileMatch: ["^pyproject.toml$", "(^|/)setup\\.py$"] @@ -12,7 +12,8 @@ { // Automerge patches, pin changes and digest changes. // Also groups these changes together. - groupName: "patch updates", + groupName: "bugfixes", + excludePackageNames: ["ruff"], matchUpdateTypes: ["patch", "pin", "digest"], prPriority: 3, // Patches should go first! automerge: true @@ -35,11 +36,36 @@ // Minor changes can be grouped and automerged for dev dependencies, but are also deprioritised. groupName: "development dependencies (minor and patch)", groupSlug: "dev-dependencies", - matchDepTypes: ["devDependencies"], + matchPackageNames: [ + "black", + "codespell", + "coverage", + "isort", + "mypy", + "pydocstyle", + "pylint", + "pytest", + "tox", + ], + matchPackagePatterns: [ + ".*-mock$" + ], + matchPackagePrefixes: [ + "pytest-", + "pylint-", + "types-", + ], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: -1, automerge: true }, + { + // Documentation related updates + groupName: "documentation dependencies", + groupSlug: "doc-dependencies", + matchPackageNames: ["Sphinx"], + matchPackagePatterns: ["^[Ss]phinx.*$", "^furo$"] + }, { // Other major dependencies get deprioritised below minor dev dependencies. matchUpdateTypes: ["major"], @@ -52,6 +78,11 @@ matchDepTypes: ["devDependencies"], matchUpdateTypes: ["major"], prPriority: -3 + }, + { + // Ruff is still unstable, so update it separately. + matchPackageNames: ["ruff"], + prPriority: -3 } ], regexManagers: [ @@ -60,14 +91,14 @@ fileMatch: ["tox.ini"], depTypeTemplate: "devDependencies", matchStrings: [ - "# renovate: datasource=(?\S+)\n\s+(?.*?)(\[[\w]*\])*[=><]=?(?.*?)\n" + "# renovate: datasource=(?\\S+)\n\\s+(?.*?)(\\[[\\w]*\\])*[=><]=?(?.*?)\n" ] } ], timezone: "Etc/UTC", automergeSchedule: "every weekend", schedule: "every weekend", - prConcurrentLimit: 5, // No more than 5 open PRs at a time. + prConcurrentLimit: 2, // No more than 2 open PRs at a time. prCreation: "not-pending", // Wait until status checks have completed before raising the PR prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. prHourlyLimit: 1, // No more than 1 PR per hour. From 39c3a7fa9bd89fd0c9863e682177073e2bb1ba68 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:36:06 -0400 Subject: [PATCH 058/333] chore(deps): update dependency setuptools to v67.7.2 (#57) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b87757686c..7a2413c5a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ docs = [ [build-system] requires = [ - "setuptools==67.6.0", + "setuptools==67.7.2", ] build-backend = "setuptools.build_meta" From 22ec1ca373c3675c9105717aea22f87d827279eb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:41:38 -0400 Subject: [PATCH 059/333] chore(deps): update dependency types/mypy to v1.3.0 (#58) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7a2413c5a2..ea7c1a328e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ lint = [ "yamllint==1.29.0" ] types = [ - "mypy[reports]==1.2.0", + "mypy[reports]==1.3.0", "pyright==1.1.306", ] docs = [ From 8d2bbf781c072e6acd93adc807e46f38bcaa7b55 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:41:54 -0400 Subject: [PATCH 060/333] chore(deps): update dependency dev/pytest to v7.3.1 (#59) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ea7c1a328e..34661a6f6f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ "coverage[toml]==7.2.2", - "pytest==7.2.2", + "pytest==7.3.1", "pytest-cov==4.0.0", "pytest-mock==3.10.0", ] From eae3d8adf1bc200f1789d382c5815d25940fd602 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:42:09 -0400 Subject: [PATCH 061/333] chore(deps): update dependency docs/sphinx-design to v0.4.1 (#60) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 34661a6f6f..88a0632edb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ docs = [ "sphinx==5.3.0", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.1", - "sphinx-design==0.3.0", + "sphinx-design==0.4.1", "sphinx-pydantic==0.1.1", "sphinx-toolbox==3.4.0", "sphinx-lint==0.6.7", From dba8423462600fab6f68ee80a8e544b55cc45f95 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:42:31 -0400 Subject: [PATCH 062/333] chore(deps): update dependency lint/yamllint to v1.31.0 (#61) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 88a0632edb..8ba7f19724 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ lint = [ "black==23.3.0", "codespell[toml]==2.2.4", "ruff==0.0.256", - "yamllint==1.29.0" + "yamllint==1.31.0" ] types = [ "mypy[reports]==1.3.0", From 8cc8d441d36e51e621cb4c72bf3feee12133c115 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:57:13 -0400 Subject: [PATCH 063/333] chore(deps): update dependency sphinx-copybutton to v0.5.2 (#63) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8ba7f19724..c875c7ed7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ docs = [ "furo==2023.3.27", "sphinx==5.3.0", "sphinx-autobuild==2021.3.14", - "sphinx-copybutton==0.5.1", + "sphinx-copybutton==0.5.2", "sphinx-design==0.4.1", "sphinx-pydantic==0.1.1", "sphinx-toolbox==3.4.0", From ff2ac00ccf47dfa8b73822fdfbcc5f9c8f158d76 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:57:28 -0400 Subject: [PATCH 064/333] chore(deps): update dependency coverage to v7.2.5 (#64) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c875c7ed7c..a551eea5ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ - "coverage[toml]==7.2.2", + "coverage[toml]==7.2.5", "pytest==7.3.1", "pytest-cov==4.0.0", "pytest-mock==3.10.0", From 1949d4c590ba0def7d75f42eb9b117b555d1fe2c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:59:22 -0400 Subject: [PATCH 065/333] chore(deps): update bugfixes (#62) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a551eea5ac..0d7638fde3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,12 +26,12 @@ dev = [ lint = [ "black==23.3.0", "codespell[toml]==2.2.4", - "ruff==0.0.256", + "ruff==0.0.267", "yamllint==1.31.0" ] types = [ "mypy[reports]==1.3.0", - "pyright==1.1.306", + "pyright==1.1.308", ] docs = [ "furo==2023.3.27", From cc4c43011af4768ae241b89b4986ac76a3544e29 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 18 May 2023 20:07:36 -0400 Subject: [PATCH 066/333] ci: add documentation build (#65) --- .github/workflows/docs.yaml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/docs.yaml diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 0000000000..4026a0da67 --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,37 @@ +name: Documentation +on: + push: + branches: + - "main" + - "feature/*" + - "hotfix/*" + - "release/*" + pull_request: + paths: + - "docs/**" + - "pyproject.toml" + - ".github/workflows/docs.yaml" + +jobs: + sphinx: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + - name: Install Tox + run: pip install tox + - name: Lint documentation + run: tox run -e lint-docs + - name: Build documentation + run: tox run -e build-docs + - name: Upload documentation + uses: actions/upload-artifact@v3 + with: + name: docs + path: docs/_build/ From 189835ba6fe9785a8197a39a33dd4c4321acfbd4 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 18 May 2023 22:51:25 -0400 Subject: [PATCH 067/333] tools: fix ruff linting command in tox (#66) --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index bcea8ed392..97fc5fb34c 100644 --- a/tox.ini +++ b/tox.ini @@ -66,7 +66,7 @@ commands_pre = shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' commands = black: black --check --diff {tty:--color} {posargs} . - ruff: ruff --diff --respect-gitignore {posargs} . + ruff: ruff check --respect-gitignore {posargs} . shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck codespell: codespell --toml {tox_root}/pyproject.toml {posargs} yaml: yamllint {posargs} . From ffe98870300e34274393e06e98181656451b1cb1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 01:08:55 -0400 Subject: [PATCH 068/333] chore(deps): update dependency ruff to v0.0.269 (#69) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0d7638fde3..93eada9dae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.3.0", "codespell[toml]==2.2.4", - "ruff==0.0.267", + "ruff==0.0.269", "yamllint==1.31.0" ] types = [ From 3fd96e9d97520aa157e598940cb22e37d3e0ab99 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 01:09:58 -0400 Subject: [PATCH 069/333] chore(deps): update bugfixes (#70) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 93eada9dae..33c331c21b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]==1.3.0", - "pyright==1.1.308", + "pyright==1.1.309", ] docs = [ "furo==2023.3.27", From f4f5541ac1ea65bdd79c9d6c3038e9b4f616cb41 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 19 May 2023 00:36:46 -0400 Subject: [PATCH 070/333] docs: update sphinx to 6 Furo currently blocks us from updating to sphinx 7 https://github.com/pradyunsg/furo/pull/653 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 33c331c21b..9949215857 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ types = [ ] docs = [ "furo==2023.3.27", - "sphinx==5.3.0", + "sphinx>=6.2.1,<7.0", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", "sphinx-design==0.4.1", From 06c70ba519c8b21cf418ddad39c8d2d697045b76 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 19 May 2023 12:50:06 -0400 Subject: [PATCH 071/333] meta: dynamic version info (#67) --- pyproject.toml | 8 ++++++-- starcraft/__init__.py | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9949215857..2661dc32e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,6 @@ [project] name = "starcraft" -version = "0.0.1" -readme = "README.rst" +dynamic = ["version", "readme"] dependencies = [ ] @@ -47,9 +46,13 @@ docs = [ [build-system] requires = [ "setuptools==67.7.2", + "setuptools_scm[toml]>=7.1" ] build-backend = "setuptools.build_meta" +[tool.setuptools.dynamic] +readme = {file = "README.rst"} + [tool.setuptools.packages.find] exclude = [ "dist", @@ -58,6 +61,7 @@ exclude = [ "tests", ] + [tool.black] target-version = ["py38"] diff --git a/starcraft/__init__.py b/starcraft/__init__.py index 25ee5b9b41..3d64fc051e 100644 --- a/starcraft/__init__.py +++ b/starcraft/__init__.py @@ -14,8 +14,11 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Starcraft package demo.""" +from importlib.metadata import version from typing import List, Optional, Any +__version__ = version(__name__) + def hello(people: Optional[List[Any]] = None) -> None: """Says hello.""" From 78f12520e4b128602f5bc18ef477e1d772aa269d Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 19 May 2023 19:03:31 -0400 Subject: [PATCH 072/333] tools: improve renovate config (#72) --- .github/renovate.json5 | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index e54ee71b71..fa96068182 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -4,16 +4,13 @@ labels: ["dependencies"], // For convenient searching in GitHub pip_requirements: { fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$"] - }, - pip_setup: { - fileMatch: ["^pyproject.toml$", "(^|/)setup\\.py$"] }, packageRules: [ { // Automerge patches, pin changes and digest changes. // Also groups these changes together. groupName: "bugfixes", - excludePackageNames: ["ruff"], + excludePackagePrefixes: ["dev", "lint", "types"], matchUpdateTypes: ["patch", "pin", "digest"], prPriority: 3, // Patches should go first! automerge: true @@ -29,32 +26,20 @@ // GitHub Actions are higher priority to update than most dependencies. groupName: "GitHub Actions", matchManagers: ["github-actions"], - prPriority: 1 + prPriority: 1, + automerge: true, }, // Everything not in one of these rules gets priority 0 and falls here. { // Minor changes can be grouped and automerged for dev dependencies, but are also deprioritised. - groupName: "development dependencies (minor and patch)", + groupName: "development dependencies (non-major)", groupSlug: "dev-dependencies", - matchPackageNames: [ - "black", - "codespell", - "coverage", - "isort", - "mypy", - "pydocstyle", - "pylint", - "pytest", - "tox", - ], - matchPackagePatterns: [ - ".*-mock$" - ], matchPackagePrefixes: [ - "pytest-", - "pylint-", - "types-", + "dev", + "lint", + "types" ], + excludePackagePatterns: ["ruff"], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: -1, automerge: true @@ -64,7 +49,8 @@ groupName: "documentation dependencies", groupSlug: "doc-dependencies", matchPackageNames: ["Sphinx"], - matchPackagePatterns: ["^[Ss]phinx.*$", "^furo$"] + matchPackagePatterns: ["^[Ss]phinx.*$", "^furo$"], + matchPackagePrefixes: ["docs"], }, { // Other major dependencies get deprioritised below minor dev dependencies. @@ -81,7 +67,8 @@ }, { // Ruff is still unstable, so update it separately. - matchPackageNames: ["ruff"], + groupName: "ruff", + matchPackagePatterns: ["^(lint/)?ruff$"], prPriority: -3 } ], From 7a22e9389744c35c7d1549f2406464285c0f652e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 19 May 2023 19:10:04 -0400 Subject: [PATCH 073/333] tools: add pre-commit (#68) Co-authored-by: Callahan --- .github/renovate.json5 | 8 ++++++++ .pre-commit-config.yaml | 30 ++++++++++++++++++++++++++++++ HACKING.rst | 4 ++++ 3 files changed, 42 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.github/renovate.json5 b/.github/renovate.json5 index fa96068182..fa9af8d05d 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -80,6 +80,14 @@ matchStrings: [ "# renovate: datasource=(?\\S+)\n\\s+(?.*?)(\\[[\\w]*\\])*[=><]=?(?.*?)\n" ] + }, + { + // .pre-commit-config.yaml version updates + fileMatch: [".pre-commit-config.yaml"], + depTypeTemplate: "devDependencies", + matchStrings: [ + "# renovate: datasource=(?\\S+);\\s*depName=(?.*?)\n\s+rev: \"v?(?.*?)\"" + ] } ], timezone: "Etc/UTC", diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..5a9b3a40a1 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,30 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + - id: check-merge-conflict + - id: check-toml + - id: fix-byte-order-marker + - id: mixed-line-ending + - repo: https://github.com/charliermarsh/ruff-pre-commit + # renovate: datasource=pypi;depName=ruff + rev: "v0.0.267" + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - repo: https://github.com/psf/black + # renovate: datasource=pypi;depName=black + rev: "23.3.0" + hooks: + - id: black + - repo: https://github.com/adrienverge/yamllint.git + # renovate: datasource=pypi;depName=yamllint + rev: "v1.31.0" + hooks: + - id: yamllint diff --git a/HACKING.rst b/HACKING.rst index 1ae2e80f03..527d4c0d86 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -16,6 +16,7 @@ We use a large number of tools for our project. Most of these are installed for - tox_ version 4 or later. (3.8+ will automatically provision a v4 virtualenv) - Pyright_ (it's recommended you install with ``snap install --classic pyright``) - ShellCheck_ (also available via snap: ``snap install shellcheck``) +- pre-commit_ Once you have all of those installed, you can install the necessary virtual environments for this repository using tox. @@ -44,6 +45,8 @@ If you'd like to run the tests with a newer version of Python, you can pass a sp tox -e test-py310 +While the use of pre-commit_ is optional, it is highly encouraged, as it runs automatic fixes for files when `git commit` is called, including code formatting with ``black`` and ``ruff``. The versions available in ``apt`` from Debian 11 (bullseye), Ubuntu 22.04 (jammy) and newer are sufficient, but you can also install the latest with ``pip install pre-commit``. Once you've installed it, run ``pre-commit install`` in this git repository to install the pre-commit hooks. + Tox environments and labels ########################### @@ -68,6 +71,7 @@ Running ``tox run -m format`` and ``tox run -m lint`` before committing code is .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ .. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa .. _`git submodules`: https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules +.. _pre-commit: https://pre-commit.com/ .. _pyproject.toml: ./pyproject.toml .. _Pyright: https://github.com/microsoft/pyright .. _pytest: https://pytest.org From 01be79d8fe8c6faca82db7300c8dc5dd2e817292 Mon Sep 17 00:00:00 2001 From: Callahan Date: Fri, 19 May 2023 18:10:56 -0500 Subject: [PATCH 074/333] .gitignore: ignore direnv's .envrc file (#75) Signed-off-by: Callahan Kovacs --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index e5d55da95d..e7dc10d304 100644 --- a/.gitignore +++ b/.gitignore @@ -133,3 +133,6 @@ dmypy.json # Test results /results/ + +# direnv +.envrc From d6c7315d2ed10ff98c495fd3693d505e18766dcf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 12:22:00 -0400 Subject: [PATCH 075/333] chore(deps): update dependency docs/furo to v2023.5.20 (#76) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2661dc32e6..68ceb66e9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ types = [ "pyright==1.1.309", ] docs = [ - "furo==2023.3.27", + "furo==2023.5.20", "sphinx>=6.2.1,<7.0", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", From 44773633e0283c328672f9a972e2da525e57ae29 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 13:02:09 -0400 Subject: [PATCH 076/333] chore(deps): update dependency lint/yamllint to v1.32.0 (#77) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 68ceb66e9c..31aff7c26b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ lint = [ "black==23.3.0", "codespell[toml]==2.2.4", "ruff==0.0.269", - "yamllint==1.31.0" + "yamllint==1.32.0" ] types = [ "mypy[reports]==1.3.0", From 82c2f3f483e0fc36ab5de62062f81b35f5dc2d1e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 22 May 2023 16:13:55 -0400 Subject: [PATCH 077/333] ci: fix release-drafter config (#78) --- .github/workflows/release-drafter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index 8c79f119ac..e60ebc189b 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -4,7 +4,7 @@ on: push: # branches to consider in the event; optional, defaults to all branches: - - master + - main jobs: update_release_draft: From e64e1e06e248d6277e4f806d1742f5e328c49901 Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Tue, 23 May 2023 23:15:12 -0300 Subject: [PATCH 078/333] ci: fix name of release-drafter config file (#79) The action looks specifically for ".yml", and not ".yaml". --- .github/{release-drafter.yaml => release-drafter.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{release-drafter.yaml => release-drafter.yml} (100%) diff --git a/.github/release-drafter.yaml b/.github/release-drafter.yml similarity index 100% rename from .github/release-drafter.yaml rename to .github/release-drafter.yml From d38e78c7615c63fa77459fa92d2516691073291a Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 25 May 2023 07:26:32 -0400 Subject: [PATCH 079/333] meta: dynamic versioning (#80) Co-authored-by: Tiago Nobrega --- .gitignore | 3 +++ pyproject.toml | 5 ++++- starcraft/__init__.py | 16 ++++++++++++++-- tests/unit/test_init.py | 10 +++++++--- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index e7dc10d304..b19a46a24f 100644 --- a/.gitignore +++ b/.gitignore @@ -136,3 +136,6 @@ dmypy.json # direnv .envrc + +# Ignore version module generated by setuptools_scm +/*/_version.py diff --git a/pyproject.toml b/pyproject.toml index 31aff7c26b..66b7753aef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,6 +53,9 @@ build-backend = "setuptools.build_meta" [tool.setuptools.dynamic] readme = {file = "README.rst"} +[tool.setuptools_scm] +write_to = "starcraft/_version.py" + [tool.setuptools.packages.find] exclude = [ "dist", @@ -165,6 +168,7 @@ extend-select = [ # Annotations: https://github.com/charliermarsh/ruff#flake8-annotations-ann "ANN0", # Type annotations for arguments other than `self` and `cls` "ANN2", # Return type annotations + "B026", # Keyword arguments must come after starred arguments # flake8-bandit: security testing. https://github.com/charliermarsh/ruff#flake8-bandit-s # https://bandit.readthedocs.io/en/latest/plugins/index.html#complete-test-plugin-listing "S101", "S102", # assert or exec @@ -177,7 +181,6 @@ extend-select = [ "S701", # jinja2 templates without autoescape "B0", # Common mistakes and typos. "RUF001", "RUF002", "RUF003", # Ambiguous unicode characters - "RUF004", # Keyword arguments must come after starred arguments "RUF005", # Encourages unpacking rather than concatenation "RUF100", # #noqa directive that doesn't flag anything. ] diff --git a/starcraft/__init__.py b/starcraft/__init__.py index 3d64fc051e..4e75351052 100644 --- a/starcraft/__init__.py +++ b/starcraft/__init__.py @@ -14,10 +14,17 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Starcraft package demo.""" -from importlib.metadata import version from typing import List, Optional, Any -__version__ = version(__name__) +try: + from ._version import __version__ +except ImportError: # pragma: no cover + from importlib.metadata import version, PackageNotFoundError + + try: + __version__ = version("starcraft") + except PackageNotFoundError: + __version__ = "dev" def hello(people: Optional[List[Any]] = None) -> None: @@ -26,3 +33,8 @@ def hello(people: Optional[List[Any]] = None) -> None: if people: for person in people: print(f"Hello {person}!") + + +__all__ = [ + "__version__", +] diff --git a/tests/unit/test_init.py b/tests/unit/test_init.py index 78d4114a4d..2aeec018fd 100644 --- a/tests/unit/test_init.py +++ b/tests/unit/test_init.py @@ -16,13 +16,17 @@ """Basic Starcraft package demo unit tests.""" from unittest import mock -from starcraft import hello +import starcraft + + +def test_version(): + assert starcraft.__version__ is not None def test_hello(mocker): mocker.patch("builtins.print") - hello() + starcraft.hello() print.assert_called_once_with("Hello *craft team!") @@ -30,7 +34,7 @@ def test_hello(mocker): def test_hello_people(mocker): mocker.patch("builtins.print") - hello(["people"]) + starcraft.hello(["people"]) print.assert_has_calls( [ From ba60c11dcd216b804f2135bcba4407fc62560760 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 21:14:34 -0400 Subject: [PATCH 080/333] chore(deps): update development dependencies (non-major) (#83) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 66b7753aef..0f29769f6b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,9 +17,9 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ - "coverage[toml]==7.2.5", + "coverage[toml]==7.2.7", "pytest==7.3.1", - "pytest-cov==4.0.0", + "pytest-cov==4.1.0", "pytest-mock==3.10.0", ] lint = [ @@ -30,7 +30,7 @@ lint = [ ] types = [ "mypy[reports]==1.3.0", - "pyright==1.1.309", + "pyright==1.1.311", ] docs = [ "furo==2023.5.20", From b5cda0d0f4959e34fe077a670ec84a82212cdd95 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 5 Jun 2023 21:24:33 -0400 Subject: [PATCH 081/333] lint: stricter ruff rules (#55) --- pyproject.toml | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0f29769f6b..90810c19fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -142,26 +142,36 @@ select = [ # Base linting rule selections. # failures with ruff updates. "F", # The rules built into Flake8 "E", "W", # pycodestyle errors and warnings - "D", # Implement pydocstyle checking as well. "I", # isort checking - "PLC", "PLE", "PLR", "PLW", # Pylint "N", # PEP8 naming + "D", # Implement pydocstyle checking as well. + "UP", # Pyupgrade - note that some of are excluded below due to Python versions "YTT", # flake8-2020: Misuse of `sys.version` and `sys.version_info` + "ANN", # Type annotations. "BLE", # Do not catch blind exceptions "FBT", # Disallow boolean positional arguments (make them keyword-only) + "B0", # Common mistakes and typos. "A", # Shadowing built-ins. "C4", # Encourage comprehensions, which tend to be faster than alternatives. "T10", # Don't call the debugger in production code "ISC", # Implicit string concatenation that can cause subtle issues "ICN", # Only use common conventions for import aliases. + "INP", # Implicit namespace packages + "PYI", # Linting for type stubs. + "PT", # Pytest "Q", # Consistent quotations + "RSE", # Errors on pytest raises. "RET", # Simpler logic after return, raise, continue or break - "UP018", "C408", # Convert type calls to literals. The latest pylint enforces this, but ruff has auto-fixes. + "SIM", # Code simplification + "TCH", # Guard imports only used for type checking behind a type-checkning block. + "ARG", # Unused arguments + "PTH", # Migrate to pathlib + "ERA", # Don't check in commented out code + "PGH", # Pygrep hooks + "PL", # Pylint + "TRY", # Cleaner try/except, ] extend-select = [ - # These sets are still frequently getting new rules. - # Therefore, they're getting frozen with the current rules so we can - # upgrade ruff without breaking linting. # Pyupgrade: https://github.com/charliermarsh/ruff#pyupgrade-up "UP00", "UP01", "UP02", "UP030", "UP032", "UP033", # "UP034", # Very new, not yet enabled in ruff 0.0.227 @@ -175,16 +185,19 @@ extend-select = [ "S103", "S108", # File permissions and tempfiles - use #noqa to silence when appropriate. "S104", # Network binds "S105", "S106", "S107", # Hardcoded passwords + "S110", # try-except-pass (use contextlib.suppress instead) "S113", # Requests calls without timeouts + "S3", # Serialising, deserialising, hashing, crypto, etc. "S506", # Unsafe YAML load "S508", "S509", # Insecure SNMP "S701", # jinja2 templates without autoescape - "B0", # Common mistakes and typos. "RUF001", "RUF002", "RUF003", # Ambiguous unicode characters "RUF005", # Encourages unpacking rather than concatenation - "RUF100", # #noqa directive that doesn't flag anything. + "RUF008", # Do not use mutable default values for dataclass attributes + "RUF100", # #noqa directive that doesn't flag anything ] ignore = [ + "ANN10", # Type annotations for `self` and `cls` #"E203", # Whitespace before ":" -- Commented because ruff doesn't currently check E203 "E501", # Line too long (reason: black will automatically fix this for us) "D105", # Missing docstring in magic method (reason: magic methods already have definitions) @@ -194,6 +207,8 @@ ignore = [ "D215", # Section underline is over-indented (reason: pep257 default) "A003", # Class attribute shadowing built-in (reason: Class attributes don't often get bare references) + # Ignored due to common usage in current code + "TRY003", # Avoid specifying long messages outside the exception class ] [tool.ruff.per-file-ignores] From 43f86dab030429e8192ee59bed253cc062bed117 Mon Sep 17 00:00:00 2001 From: Callahan Date: Wed, 7 Jun 2023 16:19:37 -0500 Subject: [PATCH 082/333] tests: move starbase tests to sub-directories (#85) This allows starbase to have its own tests and allow for cleaner merges of starbase into other repositories. Signed-off-by: Callahan Kovacs --- tests/integration/starbase/__init__.py | 0 tests/integration/{ => starbase}/test_init.py | 0 tests/unit/starbase/__init__.py | 0 tests/unit/{ => starbase}/test_init.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/integration/starbase/__init__.py rename tests/integration/{ => starbase}/test_init.py (100%) create mode 100644 tests/unit/starbase/__init__.py rename tests/unit/{ => starbase}/test_init.py (100%) diff --git a/tests/integration/starbase/__init__.py b/tests/integration/starbase/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/integration/test_init.py b/tests/integration/starbase/test_init.py similarity index 100% rename from tests/integration/test_init.py rename to tests/integration/starbase/test_init.py diff --git a/tests/unit/starbase/__init__.py b/tests/unit/starbase/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/unit/test_init.py b/tests/unit/starbase/test_init.py similarity index 100% rename from tests/unit/test_init.py rename to tests/unit/starbase/test_init.py From e150fe20654c3047e29364861082404372a3e4f8 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 8 Jun 2023 16:43:26 -0400 Subject: [PATCH 083/333] ci: configure tox to disable listing dependencies (#87) --- .github/workflows/tests.yaml | 10 ++++++---- tox.ini | 4 +++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 008a38d076..2f2902efbb 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -28,7 +28,7 @@ jobs: sudo snap install --no-wait shellcheck echo "::endgroup::" echo "::group::pip install" - python -m pip install 'tox>=4' tox-gh + python -m pip install tox echo "::endgroup::" echo "::group::Create virtual environments for linting processes." tox run -m lint --notest @@ -37,7 +37,7 @@ jobs: snap watch --last=install echo "::endgroup::" - name: Run Linters - run: tox run -m lint + run: tox run --skip-pkg-install --no-list-dependencies -m lint tests: strategy: matrix: @@ -59,13 +59,15 @@ jobs: - name: Configure environment run: | echo "::group::pip install" - python -m pip install 'tox>=4' tox-gh + python -m pip install tox echo "::endgroup::" mkdir -p results - name: Setup Tox environments run: tox run -m tests --notest - name: Test with tox - run: tox run-parallel --parallel all --parallel-no-spinner --skip-pkg-install --result-json results/tox-${{ matrix.platform }}.json -m tests -- --no-header --quiet -rN + run: .tox/.tox/bin/tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m tests + env: + PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload code coverage uses: codecov/codecov-action@v3 with: diff --git a/tox.ini b/tox.ini index 97fc5fb34c..e7fc7dcb69 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ env_list = # Environments to run when called with no parameters. lint-{black,ruff,pyright,shellcheck,codespell,docs} test-{py38,py310,py311} -minversion = 4.5 +minversion = 4.6 # Tox will use these requirements to bootstrap a venv if necessary. # tox-igore-env-name-mismatch allows us to have one virtualenv for all linting. # By setting requirements here, we make this INI file compatible with older @@ -12,6 +12,8 @@ minversion = 4.5 requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 + # renovate: datasource=pypi + tox-gh==1.0.0 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From 7ab2ef4a705754968ac685753f4a6bcd74d5e78e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 9 Jun 2023 01:21:57 -0400 Subject: [PATCH 084/333] ci: cache pip packages (#88) --- .github/workflows/tests.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 2f2902efbb..f909897c74 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -20,6 +20,7 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.10' + cache: 'pip' - name: Configure environment run: | echo "::group::Begin snap install" @@ -56,6 +57,7 @@ jobs: 3.10 3.11 3.12-dev + cache: 'pip' - name: Configure environment run: | echo "::group::pip install" From 201327e7d4878e123c6a829c771a4fc8158f4fe8 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 9 Jun 2023 14:33:26 -0400 Subject: [PATCH 085/333] tox/ci: update Python versions tested (#89) --- .github/workflows/tests.yaml | 3 +-- tox.ini | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index f909897c74..715395e9f4 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -19,7 +19,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v4 with: - python-version: '3.10' + python-version: '3.11' cache: 'pip' - name: Configure environment run: | @@ -53,7 +53,6 @@ jobs: with: python-version: | 3.8 - 3.9 3.10 3.11 3.12-dev diff --git a/tox.ini b/tox.ini index e7fc7dcb69..0ae3456b82 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] env_list = # Environments to run when called with no parameters. lint-{black,ruff,pyright,shellcheck,codespell,docs} - test-{py38,py310,py311} + test-{py38,py310,py311,py312} minversion = 4.6 # Tox will use these requirements to bootstrap a venv if necessary. # tox-igore-env-name-mismatch allows us to have one virtualenv for all linting. @@ -38,14 +38,14 @@ commands_pre = mkdir -p results base = testenv, test description = Run unit tests with pytest labels = - py38, py310, py311: tests, unit-tests + py38, py310, py311, py312: tests, unit-tests commands = pytest {tty:--color=yes} --cov --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml tests/unit {posargs} [testenv:integration-{py38,py39,py310,py311,py312}] base = testenv, test description = Run integration tests with pytest labels = - py38, py310, py311: tests, integration-tests + py38, py310, py311, py312: tests, integration-tests commands = pytest {tty:--color=yes} --junit-xml=results/test-results-{env_name}.xml tests/integration {posargs} [lint] # Standard linting configuration From f3c4f888b63e76f90c52f4fa157ed2cea2f87324 Mon Sep 17 00:00:00 2001 From: Callahan Date: Fri, 9 Jun 2023 14:38:27 -0500 Subject: [PATCH 086/333] lint: ignore ruff SIM117 (#90) Signed-off-by: Callahan Kovacs --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 90810c19fe..bff87a1b90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -206,6 +206,8 @@ ignore = [ "D213", # Multi-line docstring summary should start at the second line (reason: pep257 default) "D215", # Section underline is over-indented (reason: pep257 default) "A003", # Class attribute shadowing built-in (reason: Class attributes don't often get bare references) + "SIM117", # Use a single `with` statement with multiple contexts instead of nested `with` statements + # (reason: this creates long lines that get wrapped and reduces readability) # Ignored due to common usage in current code "TRY003", # Avoid specifying long messages outside the exception class From afc42465dc31e3987f6484d0fb5e3e8b6202f387 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Jun 2023 16:40:07 -0400 Subject: [PATCH 087/333] chore(deps): update dependency tox-gh to v1.2.0 (#92) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 0ae3456b82..11381b396a 100644 --- a/tox.ini +++ b/tox.ini @@ -13,7 +13,7 @@ requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 # renovate: datasource=pypi - tox-gh==1.0.0 + tox-gh==1.2.0 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From f40aae97c4ee708dc09ea5256c860abbbe5dd830 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Jun 2023 16:40:26 -0400 Subject: [PATCH 088/333] chore(deps): update dependency lint/ruff to v0.0.272 (#91) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index bff87a1b90..b3c16b2ecc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ dev = [ lint = [ "black==23.3.0", "codespell[toml]==2.2.4", - "ruff==0.0.269", + "ruff==0.0.272", "yamllint==1.32.0" ] types = [ From 0b9e9cfe890c15d81b1624cdb1bfece53becc7f1 Mon Sep 17 00:00:00 2001 From: Callahan Date: Tue, 13 Jun 2023 10:20:45 -0500 Subject: [PATCH 089/333] meta: update versioning scheme (#86) Signed-off-by: Callahan Kovacs --- pyproject.toml | 13 +++++ tests/integration/starbase/test_version.py | 65 ++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/integration/starbase/test_version.py diff --git a/pyproject.toml b/pyproject.toml index b3c16b2ecc..98b3d43c69 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,6 +55,19 @@ readme = {file = "README.rst"} [tool.setuptools_scm] write_to = "starcraft/_version.py" +# the version comes from the latest annotated git tag formatted as 'X.Y.Z' +# standard version scheme: +# 'X.Y.Z.post+g' +# scheme when no tags exist: +# '0.0.post+g +# scheme when no tags exist and working dir is dirty: +# '0.0.post+g.d' +version_scheme = "post-release" +# deviations from the default 'git describe' command: +# - only match annotated tags +# - only match tags formatted as 'X.Y.Z' +# - exclude '+dirty' suffix +git_describe_command = "git describe --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*'" [tool.setuptools.packages.find] exclude = [ diff --git a/tests/integration/starbase/test_version.py b/tests/integration/starbase/test_version.py new file mode 100644 index 0000000000..36a48d3e8c --- /dev/null +++ b/tests/integration/starbase/test_version.py @@ -0,0 +1,65 @@ +# This file is part of starcraft. +# +# Copyright 2023 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License version 3, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, 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 . +"""Starcraft versioning tests.""" +import re +import subprocess + +import pytest +import starcraft + + +def _repo_has_version_tag() -> bool: + """Returns True if the repo has a git tag usable for versioning.""" + git_describe_command = [ + "git", + "describe", + "--always", + "--long", + "--match", + "[0-9]*.[0-9]*.[0-9]*", + "--exclude", + "*[^0-9.]*", + ] + output = subprocess.run( + git_describe_command, check=True, capture_output=True, text=True + ).stdout.rstrip("\n") + + # match on 'X.Y.Z--g' + return bool(re.fullmatch(r"\d+\.\d+\.\d+-\d+-g[0-9a-f]+", output)) + + +@pytest.mark.skipif( + _repo_has_version_tag(), reason="Skipping because project was versioned from a tag." +) +def test_version_without_tags(): + """Validate version format when no valid tag are present.""" + version = starcraft.__version__ + + # match on '0.0.post+g' + # or '0.0.post+g.d' + assert re.fullmatch(r"\d+\.\d+\.post\d+\+g[0-9a-f]+(\.d[0-9]*)?", version) + + +@pytest.mark.skipif( + not _repo_has_version_tag(), + reason="Skipping because project was not versioned from a tag.", +) +def test_version_with_tags(): + """Version should be properly formatted when a valid tag exists.""" + version = starcraft.__version__ + + # match on 'X.Y.Z.post+g' + assert re.fullmatch(r"\d+\.\d+\.\d+\.post\d+\+g[0-9a-f]+", version) From 296c5dd9333086c10bb32aa3f80fcf9539defce4 Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Wed, 14 Jun 2023 18:00:13 -0300 Subject: [PATCH 090/333] lint: fix mypy config to 'recurse' (#94) `module = ["starcraft"]` only checks checks the `starcraft` main package, and not any sub-packages and modules. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 98b3d43c69..164400840a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -131,7 +131,7 @@ disallow_untyped_decorators = true disallow_any_generics = true [[tool.mypy.overrides]] -module = ["starcraft"] +module = ["starcraft.*"] disallow_untyped_defs = true no_implicit_optional = true From 72c7781ee03c17a3bef75a38bb93e6ff0dde3402 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Jun 2023 17:58:27 -0400 Subject: [PATCH 091/333] chore(deps): update development dependencies (non-major) (#95) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 164400840a..f9aaf80349 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ "coverage[toml]==7.2.7", - "pytest==7.3.1", + "pytest==7.3.2", "pytest-cov==4.1.0", "pytest-mock==3.10.0", ] @@ -30,7 +30,7 @@ lint = [ ] types = [ "mypy[reports]==1.3.0", - "pyright==1.1.311", + "pyright==1.1.313", ] docs = [ "furo==2023.5.20", From 8c64fc4609ad41763fcbf0e2fc9c8c48b77e1cd4 Mon Sep 17 00:00:00 2001 From: Callahan Date: Fri, 16 Jun 2023 14:44:15 -0500 Subject: [PATCH 092/333] meta: add dirty flag to versioning scheme (#96) --- pyproject.toml | 17 +++++++++-------- .../integration/{starbase => }/test_version.py | 9 ++++++--- 2 files changed, 15 insertions(+), 11 deletions(-) rename tests/integration/{starbase => }/test_version.py (85%) diff --git a/pyproject.toml b/pyproject.toml index f9aaf80349..d0b93294d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,18 +56,19 @@ readme = {file = "README.rst"} [tool.setuptools_scm] write_to = "starcraft/_version.py" # the version comes from the latest annotated git tag formatted as 'X.Y.Z' -# standard version scheme: -# 'X.Y.Z.post+g' -# scheme when no tags exist: -# '0.0.post+g -# scheme when no tags exist and working dir is dirty: -# '0.0.post+g.d' +# version scheme: +# - X.Y.Z.post+g.d<%Y%m%d> +# parts of scheme: +# - X.Y.Z - most recent git tag +# - post+g - present when current commit is not tagged +# - .d<%Y%m%d> - present when working dir is dirty +# version scheme when no tags exist: +# - 0.0.post+g version_scheme = "post-release" # deviations from the default 'git describe' command: # - only match annotated tags # - only match tags formatted as 'X.Y.Z' -# - exclude '+dirty' suffix -git_describe_command = "git describe --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*'" +git_describe_command = "git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*'" [tool.setuptools.packages.find] exclude = [ diff --git a/tests/integration/starbase/test_version.py b/tests/integration/test_version.py similarity index 85% rename from tests/integration/starbase/test_version.py rename to tests/integration/test_version.py index 36a48d3e8c..68f4accfc2 100644 --- a/tests/integration/starbase/test_version.py +++ b/tests/integration/test_version.py @@ -49,7 +49,7 @@ def test_version_without_tags(): version = starcraft.__version__ # match on '0.0.post+g' - # or '0.0.post+g.d' + # or '0.0.post+g.d<%Y%m%d>' assert re.fullmatch(r"\d+\.\d+\.post\d+\+g[0-9a-f]+(\.d[0-9]*)?", version) @@ -61,5 +61,8 @@ def test_version_with_tags(): """Version should be properly formatted when a valid tag exists.""" version = starcraft.__version__ - # match on 'X.Y.Z.post+g' - assert re.fullmatch(r"\d+\.\d+\.\d+\.post\d+\+g[0-9a-f]+", version) + # match on 'X.Y.Z' + # or 'X.Y.Z.d<%Y%m%d>' + # or 'X.Y.Z.post+g' + # or 'X.Y.Z.post+g.d<%Y%m%d>' + assert re.fullmatch(r"\d+\.\d+\.\d+(\.post\d+\+g[0-9a-f]+)?(\.d[0-9]*)?", version) From 0f6657d77982007f7ced73f61dc0f08010655091 Mon Sep 17 00:00:00 2001 From: Callahan Date: Tue, 20 Jun 2023 11:27:30 -0500 Subject: [PATCH 093/333] ci: lint docs in all directories (#98) Files like README.md and HACKING.md are linted by sphinx-lint. Signed-off-by: Callahan Kovacs --- .gitignore | 3 +++ HACKING.rst | 44 +++++++++++++++++++++++++++++++++----------- README.rst | 21 +++++++++++++-------- tox.ini | 7 ++++++- 4 files changed, 55 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index b19a46a24f..4cb5044769 100644 --- a/.gitignore +++ b/.gitignore @@ -139,3 +139,6 @@ dmypy.json # Ignore version module generated by setuptools_scm /*/_version.py + +# Visual Studio Code +.vscode/ diff --git a/HACKING.rst b/HACKING.rst index 527d4c0d86..122b1d4b90 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -2,23 +2,32 @@ Starcraft ********* -Welcome to Starcraft! We hope this document helps you get started. Before contributing any code, please sign the `Canonical contributor licence agreement`_. +Welcome to Starcraft! We hope this document helps you get started. Before +contributing any code, please sign the `Canonical contributor licence +agreement`_. Setting up a development environment ------------------------------------ -We use a forking, feature-based workflow, so you should start by forking the repository. Once you've done that, clone the project to your computer using git clone's ``--recurse-submodules`` parameter. (See more on the `git submodules`_ documentation.) +We use a forking, feature-based workflow, so you should start by forking the +repository. Once you've done that, clone the project to your computer using git +clone's ``--recurse-submodules`` parameter. (See more on the `git submodules`_ +documentation.) Tooling ======= -We use a large number of tools for our project. Most of these are installed for you with tox, but you'll need to install: +We use a large number of tools for our project. Most of these are installed for +you with tox, but you'll need to install: -- Python 3.8 (default on Ubuntu 20.04, available on Ubuntu 22.04 through the deadsnakes_ PPA) with setuptools. +- Python 3.8 (default on Ubuntu 20.04, available on Ubuntu 22.04 through the + deadsnakes_ PPA) with setuptools. - tox_ version 4 or later. (3.8+ will automatically provision a v4 virtualenv) -- Pyright_ (it's recommended you install with ``snap install --classic pyright``) +- Pyright_ (it's recommended you install with ``snap install --classic + pyright``) - ShellCheck_ (also available via snap: ``snap install shellcheck``) - pre-commit_ -Once you have all of those installed, you can install the necessary virtual environments for this repository using tox. +Once you have all of those installed, you can install the necessary virtual +environments for this repository using tox. Other tools ########### @@ -33,7 +42,10 @@ A complete list is kept in our pyproject.toml_ file in dev dependencies. Initial Setup ############# -After cloning the repository but before making any changes, it's worth ensuring that the tests, linting and tools all run on your machine. Running ``tox`` with no parameters will create the necessary virtual environments for linting and testing and run those:: +After cloning the repository but before making any changes, it's worth ensuring +that the tests, linting and tools all run on your machine. Running ``tox`` with +no parameters will create the necessary virtual environments for linting and +testing and run those:: tox @@ -41,11 +53,19 @@ If you want to install the environments but not run the tests, you can run:: tox --notest -If you'd like to run the tests with a newer version of Python, you can pass a specific environment. You must have an appropriately versioned Python interpreter installed. For example, to run with Python 3.10, run:: +If you'd like to run the tests with a newer version of Python, you can pass a +specific environment. You must have an appropriately versioned Python +interpreter installed. For example, to run with Python 3.10, run:: tox -e test-py310 -While the use of pre-commit_ is optional, it is highly encouraged, as it runs automatic fixes for files when `git commit` is called, including code formatting with ``black`` and ``ruff``. The versions available in ``apt`` from Debian 11 (bullseye), Ubuntu 22.04 (jammy) and newer are sufficient, but you can also install the latest with ``pip install pre-commit``. Once you've installed it, run ``pre-commit install`` in this git repository to install the pre-commit hooks. +While the use of pre-commit_ is optional, it is highly encouraged, as it runs +automatic fixes for files when ``git commit`` is called, including code +formatting with ``black`` and ``ruff``. The versions available in ``apt`` from +Debian 11 (bullseye), Ubuntu 22.04 (jammy) and newer are sufficient, but you can +also install the latest with ``pip install pre-commit``. Once you've installed +it, run ``pre-commit install`` in this git repository to install the pre-commit +hooks. Tox environments and labels ########################### @@ -59,13 +79,15 @@ We group tox environments with the following labels: * ``integration-tests``: Same as above but for integration tests * ``tests``: The union of ``unit-tests`` and ``integration-tests`` -For each of these, you can see which environments will be run with ``tox list``. For example: +For each of these, you can see which environments will be run with ``tox list``. +For example:: tox list -m lint You can also see all the environments by simply running ``tox list`` -Running ``tox run -m format`` and ``tox run -m lint`` before committing code is recommended. +Running ``tox run -m format`` and ``tox run -m lint`` before committing code is +recommended. .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ diff --git a/README.rst b/README.rst index 7e615600c3..5c5c87e31d 100644 --- a/README.rst +++ b/README.rst @@ -6,7 +6,9 @@ A base repository for Starcraft projects. Description ----------- -This project is designed to act as the basis for any future starcraft projects as well as a testbed for any tooling changes we want to make before merging them into other projects. +This project is designed to act as the basis for any future starcraft projects +as well as a testbed for any tooling changes we want to make before merging +them into other projects. Structure --------- @@ -20,14 +22,17 @@ How to create a new project --------------------------- [TODO: Make this a template repository.] -1. [Use this template](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template) to create your repository. -2. Ensure the ``LICENSE`` file represents the current best practices from the Canonical legal team for the specific project you intend to release. (LGPL v3 for libraries, GPL v3 for applications.) -3. Rename any files or directories and ensure references are updated. -4. Replace any appropriate `starcraft` references with the appropriate name. -5. Put correct contact information into CODE_OF_CONDUCT.md -6. Write a new README -7. Import your documentation to ReadTheDocs_. +#. `Use this template`_ to create your repository. +#. Ensure the ``LICENSE`` file represents the current best practices from the + Canonical legal team for the specific project you intend to release. (LGPL v3 + for libraries, GPL v3 for applications.) +#. Rename any files or directories and ensure references are updated. +#. Replace any appropriate ``starcraft`` references with the appropriate name. +#. Put correct contact information into CODE_OF_CONDUCT.md +#. Write a new README +#. Import your documentation to ReadTheDocs_. .. _EditorConfig: https://editorconfig.org/ .. _pre-commit: https://pre-commit.com/ .. _ReadTheDocs: https://docs.readthedocs.io/en/stable/intro/import-guide.html +.. _use this template: https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template diff --git a/tox.ini b/tox.ini index 11381b396a..7e1c3dc266 100644 --- a/tox.ini +++ b/tox.ini @@ -116,8 +116,13 @@ description = Build documentation with an autoupdating server base = docs commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} -W --watch {tox_root}/starcraft {tox_root}/docs {tox_root}/docs/_build +[lint-docs] +find = git ls-files + [testenv:lint-docs] description = Lint the documentation with sphinx-lint base = docs -commands = sphinx-lint --ignore docs/_build --max-line-length 80 -e all {posargs} docs/ labels = lint +allowlist_externals = bash, xargs +commands_pre = bash -c '{[lint-docs]find} > {env_tmp_dir}/lint_docs_files' +commands = xargs --no-run-if-empty --arg-file {env_tmp_dir}/lint_docs_files sphinx-lint --max-line-length 80 --enable all {posargs} From 9985d46f34a5de6719022683caa1f91b3e379fcc Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Tue, 20 Jun 2023 14:06:07 -0300 Subject: [PATCH 094/333] tools: fix 'setuptools.package.find' directive (#97) The directive is finnicky with regards to globbing, so the tests and docs were being included in the final wheel package. --- pyproject.toml | 9 +-- tests/integration/starbase/test_setuptools.py | 55 +++++++++++++++++++ 2 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 tests/integration/starbase/test_setuptools.py diff --git a/pyproject.toml b/pyproject.toml index d0b93294d8..d67bca0b12 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ + "build", "coverage[toml]==7.2.7", "pytest==7.3.2", "pytest-cov==4.1.0", @@ -71,13 +72,7 @@ version_scheme = "post-release" git_describe_command = "git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*'" [tool.setuptools.packages.find] -exclude = [ - "dist", - "docs", - "results", - "tests", -] - +include = ["starcraft"] [tool.black] target-version = ["py38"] diff --git a/tests/integration/starbase/test_setuptools.py b/tests/integration/starbase/test_setuptools.py new file mode 100644 index 0000000000..60a3826279 --- /dev/null +++ b/tests/integration/starbase/test_setuptools.py @@ -0,0 +1,55 @@ +# This file is part of starcraft. +# +# Copyright 2023 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License version 3, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, 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 . +"""Starcraft integration tests related to building the package.""" +import re +import subprocess +from pathlib import Path +from zipfile import ZipFile + + +def test_packages(tmp_path, request): + """Check wheel generation from our pyproject.toml""" + root_dir = Path(request.config.rootdir) + out_dir = tmp_path + subprocess.check_call(["python3", "-m", "build", "--outdir", out_dir, root_dir]) + wheels = list(tmp_path.glob("*.whl")) + assert len(wheels) == 1 + wheel = wheels[0] + + starcraft_files = [] + + dist_files = [] + dist_info_re = re.compile("starcraft-.*.dist-info") + + invalid = [] + + with ZipFile(wheel) as wheel_zip: + names = [Path(p) for p in wheel_zip.namelist()] + assert len(names) > 1 + for name in names: + top = name.parts[0] + if top == "starcraft": + starcraft_files.append(name) + elif dist_info_re.match(top): + dist_files.append(top) + else: + invalid = [] + + # Only the top-level "starcraft" dir should be present, plus the + # starcraft-xyz-dist-info/ entries. + assert starcraft_files, "No 'starcraft' modules were packaged!" + assert dist_files, "The dist-info directory was not created!" + assert not invalid, f"Invalid files were packaged: {invalid}" From 25d1c1033e218d38722d9f988ce6193d829e505c Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Wed, 21 Jun 2023 08:35:44 -0300 Subject: [PATCH 095/333] tests: provide a fixture with the project's 'main' module (#99) The idea is this: since we have a few tests that are worth running in "downstream" projects (those that merge starbase periodically), instead of having to adapt every test individually in every downstream project we'll use a fixture (project_main_module) that provides the imported module object. So in starbase is returns the 'starcraft' module. The tests are then updated to use this fixture instead of importing the module directly. Downstream projects therefore only need to update the fixture's implementation and the tests will (well, should) work. --- tests/conftest.py | 36 +++++++++++++++++++ .../{starbase => }/test_setuptools.py | 22 ++++++------ tests/integration/test_version.py | 13 +++---- 3 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 tests/conftest.py rename tests/integration/{starbase => }/test_setuptools.py (74%) diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000000..8240a3868e --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,36 @@ +# Copyright 2023 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License version 3, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, 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 . +import types + +import pytest + + +@pytest.fixture() +def project_main_module() -> types.ModuleType: + """Fixture that returns the project's principal package (imported). + + This fixture should be rewritten by "downstream" projects to return the correct + module. Then, every test that uses this fixture will correctly test against the + downstream project. + """ + try: + # This should be the project's main package; downstream projects must update this. + import starcraft + + main_module = starcraft + except ImportError: + pytest.fail( + "Failed to import the project's main module: check if it needs updating" + ) + return main_module diff --git a/tests/integration/starbase/test_setuptools.py b/tests/integration/test_setuptools.py similarity index 74% rename from tests/integration/starbase/test_setuptools.py rename to tests/integration/test_setuptools.py index 60a3826279..5bd5528e52 100644 --- a/tests/integration/starbase/test_setuptools.py +++ b/tests/integration/test_setuptools.py @@ -1,5 +1,3 @@ -# This file is part of starcraft. -# # Copyright 2023 Canonical Ltd. # # This program is free software: you can redistribute it and/or modify it @@ -13,14 +11,14 @@ # # You should have received a copy of the GNU General Public License along # with this program. If not, see . -"""Starcraft integration tests related to building the package.""" +"""Integration tests related to building the package.""" import re import subprocess from pathlib import Path from zipfile import ZipFile -def test_packages(tmp_path, request): +def test_packages(project_main_module, tmp_path, request): """Check wheel generation from our pyproject.toml""" root_dir = Path(request.config.rootdir) out_dir = tmp_path @@ -29,10 +27,12 @@ def test_packages(tmp_path, request): assert len(wheels) == 1 wheel = wheels[0] - starcraft_files = [] + main_module = project_main_module.__name__ + + project_files = [] dist_files = [] - dist_info_re = re.compile("starcraft-.*.dist-info") + dist_info_re = re.compile(f"{main_module}-.*.dist-info") invalid = [] @@ -41,15 +41,15 @@ def test_packages(tmp_path, request): assert len(names) > 1 for name in names: top = name.parts[0] - if top == "starcraft": - starcraft_files.append(name) + if top == main_module: + project_files.append(name) elif dist_info_re.match(top): dist_files.append(top) else: invalid = [] - # Only the top-level "starcraft" dir should be present, plus the - # starcraft-xyz-dist-info/ entries. - assert starcraft_files, "No 'starcraft' modules were packaged!" + # Only the top-level "project_name" dir should be present, plus the + # project_name-xyz-dist-info/ entries. + assert project_files, f"No '{main_module}' modules were packaged!" assert dist_files, "The dist-info directory was not created!" assert not invalid, f"Invalid files were packaged: {invalid}" diff --git a/tests/integration/test_version.py b/tests/integration/test_version.py index 68f4accfc2..fb7cabb378 100644 --- a/tests/integration/test_version.py +++ b/tests/integration/test_version.py @@ -1,5 +1,3 @@ -# This file is part of starcraft. -# # Copyright 2023 Canonical Ltd. # # This program is free software: you can redistribute it and/or modify it @@ -13,12 +11,11 @@ # # You should have received a copy of the GNU General Public License along # with this program. If not, see . -"""Starcraft versioning tests.""" +"""Versioning tests.""" import re import subprocess import pytest -import starcraft def _repo_has_version_tag() -> bool: @@ -44,9 +41,9 @@ def _repo_has_version_tag() -> bool: @pytest.mark.skipif( _repo_has_version_tag(), reason="Skipping because project was versioned from a tag." ) -def test_version_without_tags(): +def test_version_without_tags(project_main_module): """Validate version format when no valid tag are present.""" - version = starcraft.__version__ + version = project_main_module.__version__ # match on '0.0.post+g' # or '0.0.post+g.d<%Y%m%d>' @@ -57,9 +54,9 @@ def test_version_without_tags(): not _repo_has_version_tag(), reason="Skipping because project was not versioned from a tag.", ) -def test_version_with_tags(): +def test_version_with_tags(project_main_module): """Version should be properly formatted when a valid tag exists.""" - version = starcraft.__version__ + version = project_main_module.__version__ # match on 'X.Y.Z' # or 'X.Y.Z.d<%Y%m%d>' From 61afd7e59303aa431027c32054e9fea789c93f61 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 22 Jun 2023 10:50:37 -0400 Subject: [PATCH 096/333] coverage: automatically exclude type checking blocks (#100) --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index d67bca0b12..58ff762b97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,6 +104,9 @@ omit = ["tests/**"] [tool.coverage.report] skip_empty = true fail_under = 80 +exclude_also = [ + "if (typing\\.)?TYPE_CHECKING:", +] [tool.pyright] strict = ["starcraft"] From ab5e737573ed94872534f396fb2fc04f57b0870f Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 22 Jun 2023 10:50:45 -0400 Subject: [PATCH 097/333] ruff: remove type-checking guard blocks (#101) --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 58ff762b97..265c37afda 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -175,7 +175,8 @@ select = [ # Base linting rule selections. "RSE", # Errors on pytest raises. "RET", # Simpler logic after return, raise, continue or break "SIM", # Code simplification - "TCH", # Guard imports only used for type checking behind a type-checkning block. + "TCH004", # Remove imports from type-checking guard blocks if used at runtime + "TCH005", # Delete empty type-checking blocks "ARG", # Unused arguments "PTH", # Migrate to pathlib "ERA", # Don't check in commented out code From 3f7c6fa48b57f7dd9635c4d886efa420f7672e4a Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 22 Jun 2023 12:08:10 -0400 Subject: [PATCH 098/333] tox: pass CI environment variable (#102) --- tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tox.ini b/tox.ini index 7e1c3dc266..1ed4fb0a21 100644 --- a/tox.ini +++ b/tox.ini @@ -27,6 +27,8 @@ env_tmp_dir = {user_tmp_dir:{env:XDG_RUNTIME_DIR:{work_dir}}}/tox_tmp/{env_name} set_env = TMPDIR={env_tmp_dir} COVERAGE_FILE={env_tmp_dir}/.coverage_{env_name} +pass_env = + CI [test] # Base configuration for unit and integration tests package = editable From 6363b319a83fd1566f7ad5f3a15584d38ed724d4 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 23 Jun 2023 12:08:18 -0400 Subject: [PATCH 099/333] tools: Add release GH action (#103) Co-authored-by: Tiago Nobrega --- .github/workflows/release-publish.yaml | 59 ++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/release-publish.yaml diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml new file mode 100644 index 0000000000..2b1071d8cd --- /dev/null +++ b/.github/workflows/release-publish.yaml @@ -0,0 +1,59 @@ +name: Release +on: + push: + tags: + # These tags should be protected, remember to enable the rule: + # https://github.com/canonical/starbase/settings/tag_protection + - "[0-9]+.[0-9]+.[0-9]+" + +permissions: + contents: write + +jobs: + source-wheel: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" + cache: "pip" + check-latest: true + - name: Build packages + run: | + pip install build twine + python3 -m build + twine check dist/* + - name: Upload pypi packages artifact + uses: actions/upload-artifact@v3 + with: + name: pypi-packages + path: dist/ + pypi: + needs: ["source-wheel"] + runs-on: ubuntu-latest + steps: + - name: Get packages + uses: actions/download-artifact@v3 + with: + name: pypi-packages + path: dist/ + - name: Publish to pypi + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.PYPI_API_TOKEN }} + github-release: + needs: ["source-wheel"] + runs-on: ubuntu-latest + steps: + - name: Get pypi artifacts + uses: actions/download-artifact@v3 + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: | + ** From 376982312a73adae4a58679db9a07cd09fd7c8ca Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 26 Jun 2023 10:39:20 -0400 Subject: [PATCH 100/333] pyproject: only include the actual package in wheel file (#108) Fixes #84 --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 265c37afda..3b44ba0ac9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,8 @@ version_scheme = "post-release" git_describe_command = "git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*'" [tool.setuptools.packages.find] -include = ["starcraft"] +include = ["*craft*"] +namespaces = false [tool.black] target-version = ["py38"] From 8b8fed8dc1ed22a50d3f109661f7c562cf00f5e7 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 28 Jun 2023 20:37:12 -0400 Subject: [PATCH 101/333] tox: improve UX (#106) --- HACKING.rst | 11 ++++------- pyproject.toml | 1 - tox.ini | 50 ++++++++++++++++++++++++++++++++++---------------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/HACKING.rst b/HACKING.rst index 122b1d4b90..74de28d9fa 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -20,11 +20,8 @@ you with tox, but you'll need to install: - Python 3.8 (default on Ubuntu 20.04, available on Ubuntu 22.04 through the deadsnakes_ PPA) with setuptools. -- tox_ version 4 or later. (3.8+ will automatically provision a v4 virtualenv) -- Pyright_ (it's recommended you install with ``snap install --classic - pyright``) +- tox_ version 3.8 or later - ShellCheck_ (also available via snap: ``snap install shellcheck``) -- pre-commit_ Once you have all of those installed, you can install the necessary virtual environments for this repository using tox. @@ -57,7 +54,7 @@ If you'd like to run the tests with a newer version of Python, you can pass a specific environment. You must have an appropriately versioned Python interpreter installed. For example, to run with Python 3.10, run:: - tox -e test-py310 + tox -e test-py3.10 While the use of pre-commit_ is optional, it is highly encouraged, as it runs automatic fixes for files when ``git commit`` is called, including code @@ -75,8 +72,8 @@ We group tox environments with the following labels: * ``format``: Runs all code formatters with auto-fixing * ``type``: Runs all type checkers * ``lint``: Runs all linters (including type checkers) -* ``unit-tests``: Runs unit tests in Python versions on supported LTS's + latest -* ``integration-tests``: Same as above but for integration tests +* ``unit-tests``: Runs unit tests in several supported Python versions +* ``integration-tests``: Run integration tests in several Python versions * ``tests``: The union of ``unit-tests`` and ``integration-tests`` For each of these, you can see which environments will be run with ``tox list``. diff --git a/pyproject.toml b/pyproject.toml index 3b44ba0ac9..11f0da1488 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,7 +104,6 @@ omit = ["tests/**"] [tool.coverage.report] skip_empty = true -fail_under = 80 exclude_also = [ "if (typing\\.)?TYPE_CHECKING:", ] diff --git a/tox.ini b/tox.ini index 1ed4fb0a21..22ab1bf72b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,12 @@ [tox] env_list = # Environments to run when called with no parameters. - lint-{black,ruff,pyright,shellcheck,codespell,docs} - test-{py38,py310,py311,py312} + format-{black,ruff,codespell} + pre-commit + lint-{black,ruff,mypy,pyright,shellcheck,codespell,docs,yaml} + unit-py3.{8,10,11} + integration-py3.10 +# Integration tests probably take a while, so we're only running them on Python +# 3.10, which is included in core22. minversion = 4.6 # Tox will use these requirements to bootstrap a venv if necessary. # tox-igore-env-name-mismatch allows us to have one virtualenv for all linting. @@ -29,26 +34,28 @@ set_env = COVERAGE_FILE={env_tmp_dir}/.coverage_{env_name} pass_env = CI + CRAFT_* + PYTEST_ADDOPTS [test] # Base configuration for unit and integration tests package = editable extras = dev allowlist_externals = mkdir -commands_pre = mkdir -p results +commands_pre = mkdir -p {tox_root}/results -[testenv:test-{py38,py39,py310,py311,py312}] # Configuration for all tests using pytest +[testenv:{unit,integration}-py3.{8,9,10,11,12}] # Configuration for all tests using pytest base = testenv, test -description = Run unit tests with pytest +description = + unit: Run unit tests with pytest + integration: Run integration tests with pytest labels = - py38, py310, py311, py312: tests, unit-tests -commands = pytest {tty:--color=yes} --cov --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml tests/unit {posargs} - -[testenv:integration-{py38,py39,py310,py311,py312}] -base = testenv, test -description = Run integration tests with pytest -labels = - py38, py310, py311, py312: tests, integration-tests -commands = pytest {tty:--color=yes} --junit-xml=results/test-results-{env_name}.xml tests/integration {posargs} + py3.{8,10,11}: tests + unit-py3.{8,10,11}: unit-tests + integration-py3.{8,10,11}: integration-tests +change_dir = + unit: tests/unit + integration: tests/integration +commands = pytest {tty:--color=yes} --cov={tox_root}/starcraft --cov-config={tox_root}/pyproject.toml --cov-report=xml:{tox_root}/results/coverage-{env_name}.xml --junit-xml={tox_root}/results/test-results-{env_name}.xml {posargs} [lint] # Standard linting configuration package = editable @@ -84,7 +91,7 @@ labels = lint, type allowlist_externals = mypy: mkdir commands_pre = - mypy: mkdir -p .mypy_cache + mypy: mkdir -p {tox_root}/.mypy_cache commands = pyright: pyright {posargs} mypy: mypy --install-types --non-interactive {posargs:.} @@ -98,12 +105,23 @@ commands = ruff: ruff --fix --respect-gitignore {posargs} . codespell: codespell --toml {tox_root}/pyproject.toml --write-changes {posargs} +[testenv:pre-commit] +base = +deps = pre-commit +package = skip +no_package = true +env_dir = {work_dir}/pre-commit +runner = ignore_env_name_mismatch +description = Run pre-commit on staged files or arbitrary pre-commit commands (tox run -e pre-commit -- [args]) +commands = pre-commit {posargs:run} + [docs] # Sphinx documentation configuration extras = docs package = editable no_package = true env_dir = {work_dir}/docs runner = ignore_env_name_mismatch +source_dir = {tox_root}/{project_name} [testenv:build-docs] description = Build sphinx documentation @@ -116,7 +134,7 @@ commands = sphinx-build {posargs:-b html} -W {tox_root}/docs {tox_root}/docs/_bu [testenv:autobuild-docs] description = Build documentation with an autoupdating server base = docs -commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} -W --watch {tox_root}/starcraft {tox_root}/docs {tox_root}/docs/_build +commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} -W --watch {source_dir} {tox_root}/docs {tox_root}/docs/_build [lint-docs] find = git ls-files From 3244cc2ff1abf41ed7c4b6baea0b60ca1d2364ea Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 28 Jun 2023 20:37:50 -0400 Subject: [PATCH 102/333] ci: separate unit and integration tests (#107) --- .github/workflows/tests.yaml | 48 ++++++++++++++++++++++++---- tests/integration/test_setuptools.py | 5 ++- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 715395e9f4..94f0e58cd7 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -1,4 +1,4 @@ -name: Tests, linting, etc. +name: test on: push: branches: @@ -9,7 +9,7 @@ on: pull_request: jobs: - linters: + lint: runs-on: ubuntu-latest steps: - name: Checkout @@ -39,16 +39,16 @@ jobs: echo "::endgroup::" - name: Run Linters run: tox run --skip-pkg-install --no-list-dependencies -m lint - tests: + unit: strategy: matrix: - platform: [ubuntu-20.04, ubuntu-22.04] + platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Set up Python versions on ${{ matrix.platform }} + - name: Set up Python uses: actions/setup-python@v4 with: python-version: | @@ -66,7 +66,7 @@ jobs: - name: Setup Tox environments run: tox run -m tests --notest - name: Test with tox - run: .tox/.tox/bin/tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m tests + run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m unit-tests env: PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload code coverage @@ -80,3 +80,39 @@ jobs: with: name: test-results-${{ matrix.platform }} path: results/ + integration: + strategy: + matrix: + platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] + runs-on: ${{ matrix.platform }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: | + 3.8 + 3.10 + 3.11 + 3.12-dev + cache: 'pip' + - name: Configure environment + run: | + echo "::group::pip install" + python -m pip install tox + echo "::endgroup::" + mkdir -p results + - name: Setup Tox environments + run: tox run -m tests --notest + - name: Test with tox + run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m integration-tests + env: + PYTEST_ADDOPTS: "--no-header -vv -rN" + - name: Upload test results + if: success() || failure() + uses: actions/upload-artifact@v3 + with: + name: test-results-${{ matrix.platform }} + path: results/ diff --git a/tests/integration/test_setuptools.py b/tests/integration/test_setuptools.py index 5bd5528e52..fda323fa22 100644 --- a/tests/integration/test_setuptools.py +++ b/tests/integration/test_setuptools.py @@ -14,6 +14,7 @@ """Integration tests related to building the package.""" import re import subprocess +import sys from pathlib import Path from zipfile import ZipFile @@ -22,7 +23,9 @@ def test_packages(project_main_module, tmp_path, request): """Check wheel generation from our pyproject.toml""" root_dir = Path(request.config.rootdir) out_dir = tmp_path - subprocess.check_call(["python3", "-m", "build", "--outdir", out_dir, root_dir]) + subprocess.check_call( + [sys.executable, "-m", "build", "--outdir", out_dir, root_dir] + ) wheels = list(tmp_path.glob("*.whl")) assert len(wheels) == 1 wheel = wheels[0] From 41f01241c112c3ed44665d240e2b636a0b4d178e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 3 Jul 2023 12:54:04 -0400 Subject: [PATCH 103/333] ci: make release publisher workflow fetch correct tags (#110) --- .github/workflows/release-publish.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 2b1071d8cd..4ee72f5020 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -15,13 +15,14 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 - with: - fetch-depth: 0 + - name: Fetch tag annotations + run: | + git fetch --force --tags --depth 1 + git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*' - name: Setup Python uses: actions/setup-python@v4 with: python-version: "3.11" - cache: "pip" check-latest: true - name: Build packages run: | From c6349866c91bed00a35e281a035427681a91ac51 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 6 Jul 2023 15:25:48 -0400 Subject: [PATCH 104/333] renovate: fix scheduling (#113) --- .github/renovate.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index fa9af8d05d..09d90fa2b4 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -91,8 +91,8 @@ } ], timezone: "Etc/UTC", - automergeSchedule: "every weekend", - schedule: "every weekend", + automergeSchedule: ["every weekend"], + schedule: ["every weekend"], prConcurrentLimit: 2, // No more than 2 open PRs at a time. prCreation: "not-pending", // Wait until status checks have completed before raising the PR prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. From 6a8bb7f2a49b01e23c951fdc7f0486eb05b84fa6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 20:05:02 -0400 Subject: [PATCH 105/333] chore(deps): update development dependencies (non-major) (#115) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 11f0da1488..40d701b186 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,19 +19,19 @@ starcraft-hello = "starcraft:hello" dev = [ "build", "coverage[toml]==7.2.7", - "pytest==7.3.2", + "pytest==7.4.0", "pytest-cov==4.1.0", - "pytest-mock==3.10.0", + "pytest-mock==3.11.1", ] lint = [ "black==23.3.0", - "codespell[toml]==2.2.4", + "codespell[toml]==2.2.5", "ruff==0.0.272", "yamllint==1.32.0" ] types = [ - "mypy[reports]==1.3.0", - "pyright==1.1.313", + "mypy[reports]==1.4.1", + "pyright==1.1.316", ] docs = [ "furo==2023.5.20", From 5faae7360bc1ab2b57a79c296e772a4a3323c523 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:07:09 -0400 Subject: [PATCH 106/333] chore(deps): update release-drafter/release-drafter action to v5.24.0 (#117) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-drafter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index e60ebc189b..0ee433aabf 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Release Drafter - uses: release-drafter/release-drafter@v5.23.0 + uses: release-drafter/release-drafter@v5.24.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From be3ae62f3a4fa43ac8f1eb34198d20005f038828 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:10:34 -0400 Subject: [PATCH 107/333] chore(deps): update dependency lint/ruff to v0.0.284 (#119) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 40d701b186..e78dc7f21e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.3.0", "codespell[toml]==2.2.5", - "ruff==0.0.272", + "ruff==0.0.284", "yamllint==1.32.0" ] types = [ From 366e466ff77d1962fbf7b47ef7deb15067ec9273 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:12:51 -0400 Subject: [PATCH 108/333] chore(deps): update dependency tox-gh to v1.3.1 (#121) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 22ab1bf72b..5720048314 100644 --- a/tox.ini +++ b/tox.ini @@ -18,7 +18,7 @@ requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 # renovate: datasource=pypi - tox-gh==1.2.0 + tox-gh==1.3.1 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From 2a28541133a6c30f8543fc909777cde2ae4f6e52 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:13:24 -0400 Subject: [PATCH 109/333] chore(deps): update documentation dependencies (#120) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e78dc7f21e..581d1ac1ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,14 +34,14 @@ types = [ "pyright==1.1.316", ] docs = [ - "furo==2023.5.20", + "furo==2023.7.26", "sphinx>=6.2.1,<7.0", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", - "sphinx-design==0.4.1", + "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", - "sphinx-toolbox==3.4.0", - "sphinx-lint==0.6.7", + "sphinx-toolbox==3.5.0", + "sphinx-lint==0.6.8", ] [build-system] From 3fca437590325e31c8d914ef21662427a6559596 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 23:13:37 +0000 Subject: [PATCH 110/333] chore(deps): update dependency docs/sphinx to v7 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 581d1ac1ff..9e81d159ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ types = [ ] docs = [ "furo==2023.7.26", - "sphinx>=6.2.1,<7.0", + "sphinx>=7.1.2,<7.2", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", "sphinx-design==0.5.0", From 841c322f7af48fa1cf8ca5a7ed92d143ad196bce Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 15 Aug 2023 19:14:13 -0400 Subject: [PATCH 111/333] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9e81d159ba..05fa059981 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ types = [ ] docs = [ "furo==2023.7.26", - "sphinx>=7.1.2,<7.2", + "sphinx>=7.1.2,<8", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", "sphinx-design==0.5.0", From 9d017f31d0ffedb35197c855bd3b70cbb92a1ad5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 20:13:50 -0500 Subject: [PATCH 112/333] chore(deps): update dependency docs/furo to v2023.8.19 (#122) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 05fa059981..88f7582fd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ types = [ "pyright==1.1.316", ] docs = [ - "furo==2023.7.26", + "furo==2023.8.19", "sphinx>=7.1.2,<8", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", From 25c3c1da632b8e969f6cc9eca19c6934896a0b56 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 20:14:24 -0500 Subject: [PATCH 113/333] chore(deps): update dependency lint/ruff to v0.0.285 (#123) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 88f7582fd2..c9bb1bbb7f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.3.0", "codespell[toml]==2.2.5", - "ruff==0.0.284", + "ruff==0.0.285", "yamllint==1.32.0" ] types = [ From a91362927fce694a957606c2fdca5bf9a275f9f5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 20:39:35 -0500 Subject: [PATCH 114/333] chore(deps): update development dependencies (non-major) (#124) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c9bb1bbb7f..35c03cd34e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,20 +18,20 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ "build", - "coverage[toml]==7.2.7", + "coverage[toml]==7.3.0", "pytest==7.4.0", "pytest-cov==4.1.0", "pytest-mock==3.11.1", ] lint = [ - "black==23.3.0", + "black==23.7.0", "codespell[toml]==2.2.5", "ruff==0.0.285", "yamllint==1.32.0" ] types = [ - "mypy[reports]==1.4.1", - "pyright==1.1.316", + "mypy[reports]==1.5.1", + "pyright==1.1.323", ] docs = [ "furo==2023.8.19", From 83227685d592ac6383932def727447bd0516bb4e Mon Sep 17 00:00:00 2001 From: Sergio Schvezov Date: Thu, 24 Aug 2023 20:10:52 -0300 Subject: [PATCH 115/333] docs: add conventional commits as part of the style Signed-off-by: Sergio Schvezov --- HACKING.rst | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/HACKING.rst b/HACKING.rst index 74de28d9fa..2ea5ee14f1 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -86,6 +86,33 @@ You can also see all the environments by simply running ``tox list`` Running ``tox run -m format`` and ``tox run -m lint`` before committing code is recommended. +Code Style +========== + +Commits +####### + +Format your commits following the conventional_ commit style. + +Optionally, use the parens to scope to a particular component where +applicable. + +See below for some examples of commit headings:: + + feat: inherit context from services + test: increase unit test stability + fix: check foo before running bar + feat(daemon): foo the bar correctly in the baz + test(daemon): ensure the foo bars correctly in the baz + fix(test): mock class Foo + ci(snap): upload the snap artefacts to Github + chore(deps): update go.mod dependencies + + +Recommended prefixes are: ``fix:``, ``feat:``, ``build:``, ``chore:``, ``ci:``, +``docs:``, ``style:``, ``refactor:``, ``perf:`` and ``test:`` + + .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ .. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa @@ -97,3 +124,4 @@ recommended. .. _ruff: https://github.com/charliermarsh/ruff .. _ShellCheck: https://www.shellcheck.net/ .. _tox: https://tox.wiki +.. _conventional: https://www.conventionalcommits.org/en/v1.0.0/#summary From fe1f9b0748f938d6ca3497cf3d12750b0289ed33 Mon Sep 17 00:00:00 2001 From: Sergio Schvezov Date: Thu, 24 Aug 2023 20:12:17 -0300 Subject: [PATCH 116/333] ci: check for conventional commits Signed-off-by: Sergio Schvezov --- .github/workflows/tests.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 94f0e58cd7..1e205005da 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -16,6 +16,8 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 0 + - name: conventional commits + uses: webiny/action-conventional-commits@v1.1.0 - name: Setup Python uses: actions/setup-python@v4 with: From 6577523861657c1a980eba9f3a82bfa562bdde14 Mon Sep 17 00:00:00 2001 From: Callahan Date: Mon, 11 Sep 2023 09:52:41 -0500 Subject: [PATCH 117/333] ci(renovate): allow more branches (#126) Signed-off-by: Callahan Kovacs --- .github/renovate.json5 | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 09d90fa2b4..dc37ae58f3 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -94,6 +94,7 @@ automergeSchedule: ["every weekend"], schedule: ["every weekend"], prConcurrentLimit: 2, // No more than 2 open PRs at a time. + branchConcurrentLimit: 20, // No more than 20 open branches at a time. prCreation: "not-pending", // Wait until status checks have completed before raising the PR prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. prHourlyLimit: 1, // No more than 1 PR per hour. From de65e53a9e7a5ccf9e812d633dec97f787844673 Mon Sep 17 00:00:00 2001 From: Callahan Date: Tue, 19 Sep 2023 11:56:20 -0500 Subject: [PATCH 118/333] ci(renovate): run tests on renovate branches (#127) Signed-off-by: Callahan Kovacs --- .github/workflows/tests.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 1e205005da..e549903efc 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -6,6 +6,7 @@ on: - "feature/*" - "hotfix/*" - "release/*" + - "renovate/*" pull_request: jobs: From edf7d5a7bb668fe9c279e30d8664df9e584ceb5d Mon Sep 17 00:00:00 2001 From: Callahan Date: Thu, 21 Sep 2023 12:41:06 -0500 Subject: [PATCH 119/333] chore: skip typing checkers in "_version.py" (#128) Signed-off-by: Callahan Kovacs --- pyproject.toml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 35c03cd34e..265c3bef79 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]==1.5.1", - "pyright==1.1.323", + "pyright==1.1.327", ] docs = [ "furo==2023.8.19", @@ -112,6 +112,12 @@ exclude_also = [ strict = ["starcraft"] pythonVersion = "3.8" pythonPlatform = "Linux" +exclude = [ + "**/.*", + "**/__pycache__", + # pyright might not like the annotations generated by setuptools_scm + "**/_version.py", +] [tool.mypy] python_version = "3.8" From 04f5a63ad63860d9b8e82c1027dec850acbdbe22 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:18:19 -0400 Subject: [PATCH 120/333] chore(deps): update dependency docs/furo to v2023.9.10 (#129) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 265c3bef79..fd69f45e46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ types = [ "pyright==1.1.327", ] docs = [ - "furo==2023.8.19", + "furo==2023.9.10", "sphinx>=7.1.2,<8", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", From 4e97b3f2f40ac3948f8d619c84e349828636a128 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:44:46 -0400 Subject: [PATCH 121/333] chore(deps): update dependency lint/ruff to v0.0.290 (#130) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fd69f45e46..01d653fcc6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.7.0", "codespell[toml]==2.2.5", - "ruff==0.0.285", + "ruff==0.0.290", "yamllint==1.32.0" ] types = [ From 3d0965364a6f3d26da8b8f6e5891d4c3bb9735ce Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 2 Oct 2023 16:47:24 -0400 Subject: [PATCH 122/333] style: ensure ruff picks up pydantic.validator for class methods (#134) see: https://docs.astral.sh/ruff/settings/#pep8-naming-classmethod-decorators --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 01d653fcc6..20ab919523 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -232,6 +232,10 @@ ignore = [ "TRY003", # Avoid specifying long messages outside the exception class ] +[tool.ruff.pep8-naming] +# Allow Pydantic's `@validator` decorator to trigger class method treatment. +classmethod-decorators = ["pydantic.validator"] + [tool.ruff.per-file-ignores] "tests/**.py" = [ # Some things we want for the moin project are unnecessary in tests. "D", # Ignore docstring rules in tests From aa095b1ddf21d02240810dac02dee958771ee3e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 06:49:19 -0400 Subject: [PATCH 123/333] chore(deps): update actions/checkout action to v4 (#132) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docs.yaml | 2 +- .github/workflows/release-publish.yaml | 2 +- .github/workflows/tests.yaml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 4026a0da67..cdbc402666 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Python diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 4ee72f5020..66cf8739e0 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Fetch tag annotations run: | git fetch --force --tags --depth 1 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index e549903efc..26c5ebd334 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: conventional commits @@ -48,7 +48,7 @@ jobs: platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python @@ -89,7 +89,7 @@ jobs: platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python From c3c3313364eb9ece4a2b639ba9c9e1ddae22173f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 06:54:26 -0400 Subject: [PATCH 124/333] chore(deps): update dependency lint/ruff to v0.0.291 (#131) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 20ab919523..cf4e375368 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.7.0", "codespell[toml]==2.2.5", - "ruff==0.0.290", + "ruff==0.0.291", "yamllint==1.32.0" ] types = [ From a8e334e8af5e6544aadebaeffb44b6de40f9183f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:00:32 -0400 Subject: [PATCH 125/333] chore(deps): update dependency lint/ruff to v0.1.0 (#138) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cf4e375368..00b4eeac31 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.7.0", "codespell[toml]==2.2.5", - "ruff==0.0.291", + "ruff==0.1.0", "yamllint==1.32.0" ] types = [ From e668f36c40813c26314bd52515ba2914f1b820bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Oct 2023 13:53:29 -0400 Subject: [PATCH 126/333] chore(deps): update release-drafter/release-drafter action to v5.25.0 (#140) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-drafter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index 0ee433aabf..3ae8faaa4a 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Release Drafter - uses: release-drafter/release-drafter@v5.24.0 + uses: release-drafter/release-drafter@v5.25.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 62cafdac25014ce81216697152472b47a39e01d6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Oct 2023 14:05:00 -0400 Subject: [PATCH 127/333] chore(deps): update dependency docs/sphinx-lint to v0.8.1 (#141) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 00b4eeac31..35da2da358 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ docs = [ "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", "sphinx-toolbox==3.5.0", - "sphinx-lint==0.6.8", + "sphinx-lint==0.8.1", ] [build-system] From 6f1c345b1f6f486c697de03d6c68e0c30fa3712c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Oct 2023 16:25:40 -0400 Subject: [PATCH 128/333] chore(deps): update development dependencies (non-major) (#137) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 35da2da358..c3f20370f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,20 +18,20 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ "build", - "coverage[toml]==7.3.0", - "pytest==7.4.0", + "coverage[toml]==7.3.2", + "pytest==7.4.2", "pytest-cov==4.1.0", - "pytest-mock==3.11.1", + "pytest-mock==3.12.0", ] lint = [ - "black==23.7.0", - "codespell[toml]==2.2.5", + "black==23.10.0", + "codespell[toml]==2.2.6", "ruff==0.1.0", "yamllint==1.32.0" ] types = [ - "mypy[reports]==1.5.1", - "pyright==1.1.327", + "mypy[reports]==1.6.1", + "pyright==1.1.332", ] docs = [ "furo==2023.9.10", From 6b79ebe2df5e6d0b095926c8da451fab7a3e5f29 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 22 Oct 2023 11:03:49 -0400 Subject: [PATCH 129/333] chore(deps): update dependency lint/ruff to v0.1.1 (#142) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c3f20370f7..91f3fed9fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==23.10.0", "codespell[toml]==2.2.6", - "ruff==0.1.0", + "ruff==0.1.1", "yamllint==1.32.0" ] types = [ From eae252843010193e62439b1e416b9043b3816a96 Mon Sep 17 00:00:00 2001 From: Callahan Date: Sun, 5 Nov 2023 06:20:49 -0600 Subject: [PATCH 130/333] ci: colorize tox (#145) Signed-off-by: Callahan Kovacs --- .github/workflows/docs.yaml | 4 ++-- .github/workflows/tests.yaml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index cdbc402666..80906552c2 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -27,9 +27,9 @@ jobs: - name: Install Tox run: pip install tox - name: Lint documentation - run: tox run -e lint-docs + run: tox run --colored yes -e lint-docs - name: Build documentation - run: tox run -e build-docs + run: tox run --colored yes -e build-docs - name: Upload documentation uses: actions/upload-artifact@v3 with: diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 26c5ebd334..a953f6e9e1 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -35,13 +35,13 @@ jobs: python -m pip install tox echo "::endgroup::" echo "::group::Create virtual environments for linting processes." - tox run -m lint --notest + tox run --colored yes -m lint --notest echo "::endgroup::" echo "::group::Wait for snap to complete" snap watch --last=install echo "::endgroup::" - name: Run Linters - run: tox run --skip-pkg-install --no-list-dependencies -m lint + run: tox run --skip-pkg-install --no-list-dependencies --colored yes -m lint unit: strategy: matrix: @@ -67,9 +67,9 @@ jobs: echo "::endgroup::" mkdir -p results - name: Setup Tox environments - run: tox run -m tests --notest + run: tox run --colored yes -m tests --notest - name: Test with tox - run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m unit-tests + run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json --colored yes -m unit-tests env: PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload code coverage @@ -108,9 +108,9 @@ jobs: echo "::endgroup::" mkdir -p results - name: Setup Tox environments - run: tox run -m tests --notest + run: tox run --colored yes -m tests --notest - name: Test with tox - run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json -m integration-tests + run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json --colored yes -m integration-tests env: PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload test results From f78477e6db2afb3314cb0be80cf051ce9e3ac6e8 Mon Sep 17 00:00:00 2001 From: Sheng Yu Date: Sun, 5 Nov 2023 07:21:27 -0500 Subject: [PATCH 131/333] feat(ruff): allow use Any in star args and kwargs (#144) --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 91f3fed9fb..f2a6b7ed60 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -232,6 +232,9 @@ ignore = [ "TRY003", # Avoid specifying long messages outside the exception class ] +[tool.ruff.flake8-annotations] +allow-star-arg-any = true + [tool.ruff.pep8-naming] # Allow Pydantic's `@validator` decorator to trigger class method treatment. classmethod-decorators = ["pydantic.validator"] From bd97d8309b45157be4b43d1d6817acc52474d41f Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Sun, 5 Nov 2023 16:00:18 +0200 Subject: [PATCH 132/333] chore(deps): include ruff in dev updates (#146) Now that ruff has had a 0.1 release it should be updatable with our other linters. --- .github/renovate.json5 | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index dc37ae58f3..43d5069970 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -39,7 +39,6 @@ "lint", "types" ], - excludePackagePatterns: ["ruff"], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: -1, automerge: true @@ -64,12 +63,6 @@ matchDepTypes: ["devDependencies"], matchUpdateTypes: ["major"], prPriority: -3 - }, - { - // Ruff is still unstable, so update it separately. - groupName: "ruff", - matchPackagePatterns: ["^(lint/)?ruff$"], - prPriority: -3 } ], regexManagers: [ From 406c05612f4b96c1fe2c646e85a23fa36767592c Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Sun, 5 Nov 2023 16:04:22 +0200 Subject: [PATCH 133/333] chore: update renovate config (#143) --- .github/renovate.json5 | 17 +++++++++----- .github/workflows/check-renovate.yaml | 33 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/check-renovate.yaml diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 43d5069970..abbfa12f26 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -10,7 +10,7 @@ // Automerge patches, pin changes and digest changes. // Also groups these changes together. groupName: "bugfixes", - excludePackagePrefixes: ["dev", "lint", "types"], + excludePackagePrefixes: ["lint", "types"], matchUpdateTypes: ["patch", "pin", "digest"], prPriority: 3, // Patches should go first! automerge: true @@ -23,13 +23,18 @@ prPriority: 2 }, { - // GitHub Actions are higher priority to update than most dependencies. + // GitHub Actions are higher priority to update than most dependencies since they don't tend to break things. groupName: "GitHub Actions", matchManagers: ["github-actions"], prPriority: 1, automerge: true, }, // Everything not in one of these rules gets priority 0 and falls here. + { + //Do all pydantic-related updates together + groupName: "pydantic etc.", + matchPackagePatterns: ["^pydantic"], + }, { // Minor changes can be grouped and automerged for dev dependencies, but are also deprioritised. groupName: "development dependencies (non-major)", @@ -47,8 +52,8 @@ // Documentation related updates groupName: "documentation dependencies", groupSlug: "doc-dependencies", - matchPackageNames: ["Sphinx"], - matchPackagePatterns: ["^[Ss]phinx.*$", "^furo$"], + matchPackageNames: ["Sphinx", "furo"], + matchPackagePatterns: ["[Ss]phinx.*$"], matchPackagePrefixes: ["docs"], }, { @@ -84,12 +89,12 @@ } ], timezone: "Etc/UTC", - automergeSchedule: ["every weekend"], schedule: ["every weekend"], prConcurrentLimit: 2, // No more than 2 open PRs at a time. branchConcurrentLimit: 20, // No more than 20 open branches at a time. prCreation: "not-pending", // Wait until status checks have completed before raising the PR prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. prHourlyLimit: 1, // No more than 1 PR per hour. - stabilityDays: 2 // Wait 2 days from release before updating. + stabilityDays: 2, // Wait 2 days from release before updating. + automergeStrategy: "squash" // Squash & rebase when auto-merging. } diff --git a/.github/workflows/check-renovate.yaml b/.github/workflows/check-renovate.yaml new file mode 100644 index 0000000000..84466fab1a --- /dev/null +++ b/.github/workflows/check-renovate.yaml @@ -0,0 +1,33 @@ +name: Renovate check +on: + pull_request: + paths: + - ".github/workflows/check-renovate.yaml" + - ".github/renovate.json5" + + # Allows triggering the workflow manually from the Actions tab + workflow_dispatch: + inputs: + enable_ssh_access: + type: boolean + description: 'Enable ssh access' + required: false + default: false + +jobs: + renovate: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install renovate + run: npm install --global renovate + - name: Enable ssh access + uses: mxschmitt/action-tmate@v3 + if: ${{ inputs.enable_ssh_access }} + - name: Check renovate config + run: renovate-config-validator .github/renovate.json5 + - name: Renovate dry-run + run: renovate --dry-run --autodiscover + env: + RENOVATE_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 624e393a43d3675f750e399b670c3a33f8f64344 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 9 Nov 2023 11:11:12 +0200 Subject: [PATCH 134/333] build: run Renovate immediately on craft-* patch releases (#147) --- .github/renovate.json5 | 20 ++++++++++++++++++++ .github/workflows/check-renovate.yaml | 2 ++ 2 files changed, 22 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index abbfa12f26..bb67d88955 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -6,6 +6,26 @@ fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$"] }, packageRules: [ + { + // Internal package minor patch updates get top priority, with auto-merging + groupName: "internal package patch releases", + matchPackagePatterns: ["^craft-.*"], + matchUpdateTypes: ["minor", "patch", "pin", "digest"], + prPriority: 10, + automerge: true, + minimumReleaseAge: "0 seconds", + schedule: ["at any time"], + }, + { + // Same as above, but for hotfix branches, only for patch, and without auto-merging. + groupName: "internal package patch releases (hotfix)", + matchPackagePatterns: ["^craft-.*"], + matchUpdateTypes: ["patch", "pin", "digest"], + prPriority: 10, + minimumReleaseAge: "0 seconds", + schedule: ["at any time"], + matchBaseBranches: ["/^hotfix/.*/"], // All hotfix branches + }, { // Automerge patches, pin changes and digest changes. // Also groups these changes together. diff --git a/.github/workflows/check-renovate.yaml b/.github/workflows/check-renovate.yaml index 84466fab1a..8cf7d22a2d 100644 --- a/.github/workflows/check-renovate.yaml +++ b/.github/workflows/check-renovate.yaml @@ -25,6 +25,8 @@ jobs: - name: Enable ssh access uses: mxschmitt/action-tmate@v3 if: ${{ inputs.enable_ssh_access }} + with: + limit-access-to-actor: true - name: Check renovate config run: renovate-config-validator .github/renovate.json5 - name: Renovate dry-run From 4ca930b5eac48a2a44fb0412d9eccd32b7538d52 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 10 Nov 2023 14:52:22 +0200 Subject: [PATCH 135/333] style(lint): bump max function args to 8 (#149) fixes #133 --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index f2a6b7ed60..5dfd5f783c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -235,6 +235,9 @@ ignore = [ [tool.ruff.flake8-annotations] allow-star-arg-any = true +[tool.ruf.lint.pylint] +max-args = 8 + [tool.ruff.pep8-naming] # Allow Pydantic's `@validator` decorator to trigger class method treatment. classmethod-decorators = ["pydantic.validator"] From b58ed6f3c15ecedc44a8b467d2088cb3477dfb64 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 10 Nov 2023 14:57:43 +0200 Subject: [PATCH 136/333] style(lint): private member access (#150) --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 5dfd5f783c..182d7419ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -180,6 +180,7 @@ select = [ # Base linting rule selections. "Q", # Consistent quotations "RSE", # Errors on pytest raises. "RET", # Simpler logic after return, raise, continue or break + "SLF", # Prevent accessing private class members. "SIM", # Code simplification "TCH004", # Remove imports from type-checking guard blocks if used at runtime "TCH005", # Delete empty type-checking blocks @@ -250,6 +251,7 @@ classmethod-decorators = ["pydantic.validator"] "S103", # Allow `os.chmod` setting a permissive mask `0o555` on file or directory "S108", # Allow Probable insecure usage of temporary file or directory "PLR0913", # Allow many arguments for test functions + "SLF", # Allow accessing private members in tests ] # isort leaves init files alone by default, this makes ruff ignore them too. "__init__.py" = ["I001"] From 073e45046dad5718d00365d7f5d76fc191b3ed9a Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 17 Nov 2023 17:35:41 -0500 Subject: [PATCH 137/333] style(lint): disable magic value check in tests (#151) fixes #148 --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 182d7419ef..52c5d33edc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -251,6 +251,7 @@ classmethod-decorators = ["pydantic.validator"] "S103", # Allow `os.chmod` setting a permissive mask `0o555` on file or directory "S108", # Allow Probable insecure usage of temporary file or directory "PLR0913", # Allow many arguments for test functions + "PLR2004", # Allow magic values in tests "SLF", # Allow accessing private members in tests ] # isort leaves init files alone by default, this makes ruff ignore them too. From a48d59085304269635446ecebda5eeb8178937a9 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 20 Nov 2023 12:35:54 -0500 Subject: [PATCH 138/333] style: stricter ruff linters (#139) --- pyproject.toml | 67 +++++++++++++++++----------- tests/conftest.py | 2 +- tests/integration/test_setuptools.py | 2 +- tests/integration/test_version.py | 8 +++- tests/unit/starbase/test_init.py | 2 +- tox.ini | 2 +- 6 files changed, 50 insertions(+), 33 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 52c5d33edc..4d5f893f9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -166,15 +166,36 @@ select = [ # Base linting rule selections. "UP", # Pyupgrade - note that some of are excluded below due to Python versions "YTT", # flake8-2020: Misuse of `sys.version` and `sys.version_info` "ANN", # Type annotations. + "ASYNC", # Catching blocking calls in async functions + # flake8-bandit: security testing. https://docs.astral.sh/ruff/rules/#flake8-bandit-s + # https://bandit.readthedocs.io/en/latest/plugins/index.html#complete-test-plugin-listing + "S101", "S102", # assert or exec + "S103", "S108", # File permissions and tempfiles - use #noqa to silence when appropriate. + "S104", # Network binds + "S105", "S106", "S107", # Hardcoded passwords + "S110", # try-except-pass (use contextlib.suppress instead) + "S113", # Requests calls without timeouts + "S3", # Serialising, deserialising, hashing, crypto, etc. + "S5", # Unsafe cryptography or YAML loading. + "S602", # Subprocess call with shell=true + "S701", # jinja2 templates without autoescape "BLE", # Do not catch blind exceptions "FBT", # Disallow boolean positional arguments (make them keyword-only) "B0", # Common mistakes and typos. "A", # Shadowing built-ins. + "COM", # Trailing commas "C4", # Encourage comprehensions, which tend to be faster than alternatives. "T10", # Don't call the debugger in production code "ISC", # Implicit string concatenation that can cause subtle issues "ICN", # Only use common conventions for import aliases. "INP", # Implicit namespace packages + # flake8-pie: miscellaneous linters (enabled individually because they're not really related) + "PIE790", # Unnecessary pass statement + "PIE794", # Multiple definitions of class field + "PIE796", # Duplicate value in an enum (reasonable to noqa for backwards compatibility) + "PIE804", # Don't use a dict with unnecessary kwargs + "PIE807", # prefer `list` over `lambda: []` + "PIE810", # Use a tuple rather than multiple calls. E.g. `mystr.startswith(("Hi", "Hello"))` "PYI", # Linting for type stubs. "PT", # Pytest "Q", # Consistent quotations @@ -182,39 +203,28 @@ select = [ # Base linting rule selections. "RET", # Simpler logic after return, raise, continue or break "SLF", # Prevent accessing private class members. "SIM", # Code simplification + "TID", # Tidy imports + # The team have chosen to only use type-checking blocks when necessary to prevent circular imports. + # As such, the only enabled type-checking checks are those that warn of an import that needs to be + # removed from a type-checking block. "TCH004", # Remove imports from type-checking guard blocks if used at runtime "TCH005", # Delete empty type-checking blocks "ARG", # Unused arguments "PTH", # Migrate to pathlib + "FIX", # All TODOs, FIXMEs, etc. should be turned into issues instead. "ERA", # Don't check in commented out code "PGH", # Pygrep hooks "PL", # Pylint "TRY", # Cleaner try/except, -] -extend-select = [ - # Pyupgrade: https://github.com/charliermarsh/ruff#pyupgrade-up - "UP00", "UP01", "UP02", "UP030", "UP032", "UP033", - # "UP034", # Very new, not yet enabled in ruff 0.0.227 - # Annotations: https://github.com/charliermarsh/ruff#flake8-annotations-ann - "ANN0", # Type annotations for arguments other than `self` and `cls` - "ANN2", # Return type annotations - "B026", # Keyword arguments must come after starred arguments - # flake8-bandit: security testing. https://github.com/charliermarsh/ruff#flake8-bandit-s - # https://bandit.readthedocs.io/en/latest/plugins/index.html#complete-test-plugin-listing - "S101", "S102", # assert or exec - "S103", "S108", # File permissions and tempfiles - use #noqa to silence when appropriate. - "S104", # Network binds - "S105", "S106", "S107", # Hardcoded passwords - "S110", # try-except-pass (use contextlib.suppress instead) - "S113", # Requests calls without timeouts - "S3", # Serialising, deserialising, hashing, crypto, etc. - "S506", # Unsafe YAML load - "S508", "S509", # Insecure SNMP - "S701", # jinja2 templates without autoescape + "FLY", # Detect things that would be better as f-strings. + "PERF", # Catch things that can slow down the application like unnecessary casts to list. "RUF001", "RUF002", "RUF003", # Ambiguous unicode characters "RUF005", # Encourages unpacking rather than concatenation "RUF008", # Do not use mutable default values for dataclass attributes + "RUF011", # Don't use static keys in dict comprehensions. + "RUF013", # Prohibit implicit Optionals (PEP 484) "RUF100", # #noqa directive that doesn't flag anything + "RUF200", # If ruff fails to parse pyproject.toml... ] ignore = [ "ANN10", # Type annotations for `self` and `cls` @@ -241,18 +251,21 @@ max-args = 8 [tool.ruff.pep8-naming] # Allow Pydantic's `@validator` decorator to trigger class method treatment. -classmethod-decorators = ["pydantic.validator"] +classmethod-decorators = ["pydantic.validator", "pydantic.root_validator"] [tool.ruff.per-file-ignores] "tests/**.py" = [ # Some things we want for the moin project are unnecessary in tests. "D", # Ignore docstring rules in tests - "ANN", # Ignore type annotations in tests + "ANN", # Ignore type annotations in tests + "ARG", # Allow unused arguments in tests (e.g. for fake functions/methods/classes) "S101", # Allow assertions in tests "S103", # Allow `os.chmod` setting a permissive mask `0o555` on file or directory "S108", # Allow Probable insecure usage of temporary file or directory - "PLR0913", # Allow many arguments for test functions + "PLR0913", # Allow many arguments for test functions (useful if we need many fixtures) "PLR2004", # Allow magic values in tests - "SLF", # Allow accessing private members in tests + "SLF", # Allow accessing private members from tests. +] +"__init__.py" = [ + "I001", # isort leaves init files alone by default, this makes ruff ignore them too. + "F401", # Allows unused imports in __init__ files. ] -# isort leaves init files alone by default, this makes ruff ignore them too. -"__init__.py" = ["I001"] diff --git a/tests/conftest.py b/tests/conftest.py index 8240a3868e..9bceb63b06 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -31,6 +31,6 @@ def project_main_module() -> types.ModuleType: main_module = starcraft except ImportError: pytest.fail( - "Failed to import the project's main module: check if it needs updating" + "Failed to import the project's main module: check if it needs updating", ) return main_module diff --git a/tests/integration/test_setuptools.py b/tests/integration/test_setuptools.py index fda323fa22..d40f9ac4a2 100644 --- a/tests/integration/test_setuptools.py +++ b/tests/integration/test_setuptools.py @@ -24,7 +24,7 @@ def test_packages(project_main_module, tmp_path, request): root_dir = Path(request.config.rootdir) out_dir = tmp_path subprocess.check_call( - [sys.executable, "-m", "build", "--outdir", out_dir, root_dir] + [sys.executable, "-m", "build", "--outdir", out_dir, root_dir], ) wheels = list(tmp_path.glob("*.whl")) assert len(wheels) == 1 diff --git a/tests/integration/test_version.py b/tests/integration/test_version.py index fb7cabb378..411b3118b0 100644 --- a/tests/integration/test_version.py +++ b/tests/integration/test_version.py @@ -31,7 +31,10 @@ def _repo_has_version_tag() -> bool: "*[^0-9.]*", ] output = subprocess.run( - git_describe_command, check=True, capture_output=True, text=True + git_describe_command, + check=True, + capture_output=True, + text=True, ).stdout.rstrip("\n") # match on 'X.Y.Z--g' @@ -39,7 +42,8 @@ def _repo_has_version_tag() -> bool: @pytest.mark.skipif( - _repo_has_version_tag(), reason="Skipping because project was versioned from a tag." + _repo_has_version_tag(), + reason="Skipping because project was versioned from a tag.", ) def test_version_without_tags(project_main_module): """Validate version format when no valid tag are present.""" diff --git a/tests/unit/starbase/test_init.py b/tests/unit/starbase/test_init.py index 2aeec018fd..d124894f92 100644 --- a/tests/unit/starbase/test_init.py +++ b/tests/unit/starbase/test_init.py @@ -40,5 +40,5 @@ def test_hello_people(mocker): [ mock.call("Hello *craft team!"), mock.call("Hello people!"), - ] + ], ) diff --git a/tox.ini b/tox.ini index 5720048314..a99a7ba0a5 100644 --- a/tox.ini +++ b/tox.ini @@ -77,7 +77,7 @@ commands_pre = shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' commands = black: black --check --diff {tty:--color} {posargs} . - ruff: ruff check --respect-gitignore {posargs} . + ruff: ruff check --respect-gitignore {posargs:.} shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck codespell: codespell --toml {tox_root}/pyproject.toml {posargs} yaml: yamllint {posargs} . From cc5a039f7c9f057cf66637994848194a4edb0a55 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 11:55:29 -0500 Subject: [PATCH 139/333] chore(deps): update development dependencies (non-major) (#153) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4d5f893f9c..12b2cf414f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,19 +19,19 @@ starcraft-hello = "starcraft:hello" dev = [ "build", "coverage[toml]==7.3.2", - "pytest==7.4.2", + "pytest==7.4.3", "pytest-cov==4.1.0", "pytest-mock==3.12.0", ] lint = [ - "black==23.10.0", + "black==23.11.0", "codespell[toml]==2.2.6", - "ruff==0.1.1", - "yamllint==1.32.0" + "ruff==0.1.6", + "yamllint==1.33.0" ] types = [ - "mypy[reports]==1.6.1", - "pyright==1.1.332", + "mypy[reports]==1.7.1", + "pyright==1.1.337", ] docs = [ "furo==2023.9.10", From 0eead768f55476928f89a241ecb0f857f6f176fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 17:46:05 -0300 Subject: [PATCH 140/333] chore(deps): update dependency docs/sphinx-lint to v0.9.0 (#152) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 12b2cf414f..d2c207f065 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ docs = [ "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", "sphinx-toolbox==3.5.0", - "sphinx-lint==0.8.1", + "sphinx-lint==0.9.0", ] [build-system] From 36a4cbf683d3c99cbd4f3f8fc2770b764d4b1834 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 3 Dec 2023 20:39:14 -0500 Subject: [PATCH 141/333] chore(deps): update dependency types/pyright to v1.1.338 (#155) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d2c207f065..7774417c72 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]==1.7.1", - "pyright==1.1.337", + "pyright==1.1.338", ] docs = [ "furo==2023.9.10", From 54ea9f511bd1bc4f857a27c6fc8c986df67ae9f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:06:24 -0500 Subject: [PATCH 142/333] chore(deps): update webiny/action-conventional-commits action to v1.2.0 (#154) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index a953f6e9e1..726d405d07 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -18,7 +18,7 @@ jobs: with: fetch-depth: 0 - name: conventional commits - uses: webiny/action-conventional-commits@v1.1.0 + uses: webiny/action-conventional-commits@v1.2.0 - name: Setup Python uses: actions/setup-python@v4 with: From 46e9d222a5e577d15719dae32b4cab4fc099d31b Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 5 Dec 2023 15:31:52 -0500 Subject: [PATCH 143/333] chore: make renovate update pre-commit-config (#156) --- .github/renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index bb67d88955..f94e60e79d 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -3,7 +3,7 @@ extends: ["config:base"], labels: ["dependencies"], // For convenient searching in GitHub pip_requirements: { - fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$"] + fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$", "^.pre-commit-config.yaml$"] }, packageRules: [ { From 86b756888f172cc40c90750503655efb2b25e084 Mon Sep 17 00:00:00 2001 From: Callahan Date: Thu, 7 Dec 2023 15:19:59 -0600 Subject: [PATCH 144/333] chore: use new mypy config `extra_checks` (#158) `strict_concatenate` has been deprecated in favor of `extra_checks` Signed-off-by: Callahan Kovacs --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7774417c72..d0a50ddf15 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -129,7 +129,7 @@ exclude = [ warn_unused_configs = true warn_redundant_casts = true strict_equality = true -strict_concatenate = true +extra_checks = true warn_return_any = true disallow_subclassing_any = true disallow_untyped_decorators = true From 5d460276fa84e3689c6541455acf86212f248515 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 11:58:20 -0500 Subject: [PATCH 145/333] chore(deps): update actions/setup-python action to v5 (#161) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docs.yaml | 2 +- .github/workflows/release-publish.yaml | 2 +- .github/workflows/tests.yaml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 80906552c2..0e3e3bcf66 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -21,7 +21,7 @@ jobs: with: fetch-depth: 0 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install Tox diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 66cf8739e0..55ac7a437d 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -20,7 +20,7 @@ jobs: git fetch --force --tags --depth 1 git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*' - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.11" check-latest: true diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 726d405d07..84b42a8307 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -20,7 +20,7 @@ jobs: - name: conventional commits uses: webiny/action-conventional-commits@v1.2.0 - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' @@ -52,7 +52,7 @@ jobs: with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: | 3.8 @@ -93,7 +93,7 @@ jobs: with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: | 3.8 From 0d328c440d99bde86a2a213bc679eba7d1a4954f Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 12 Dec 2023 11:52:05 -0500 Subject: [PATCH 146/333] style: ignore docstring requirements for overrides (#159) --- pyproject.toml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d0a50ddf15..64b5cc16da 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -246,7 +246,17 @@ ignore = [ [tool.ruff.flake8-annotations] allow-star-arg-any = true -[tool.ruf.lint.pylint] +[tool.ruff.lint.pydocstyle] +ignore-decorators = [ # Functions with these decorators don't have to have docstrings. + "typing.overload", # Default configuration + # The next four are all variations on override, so child classes don't have to repeat parent classes' docstrings. + "overrides.override", + "overrides.overrides", + "typing.override", + "typing_extensions.override", +] + +[tool.ruff.lint.pylint] max-args = 8 [tool.ruff.pep8-naming] From 4b2c78e23d9d3325cc0f5c8a95fea7f68d93157f Mon Sep 17 00:00:00 2001 From: Callahan Date: Fri, 15 Dec 2023 12:08:01 -0600 Subject: [PATCH 147/333] docs(HACKING): update commit message guidelines (#162) Signed-off-by: Callahan Kovacs --- .github/renovate.json5 | 3 +- .github/workflows/tests.yaml | 2 + HACKING.rst | 172 ++++++++++++++++++++++++++++++++--- 3 files changed, 165 insertions(+), 12 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index f94e60e79d..2984fef534 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -116,5 +116,6 @@ prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. prHourlyLimit: 1, // No more than 1 PR per hour. stabilityDays: 2, // Wait 2 days from release before updating. - automergeStrategy: "squash" // Squash & rebase when auto-merging. + automergeStrategy: "squash", // Squash & rebase when auto-merging. + semanticCommitType: "build" // use `build` as commit header type (i.e. `build(deps): `) } diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 84b42a8307..b22201b7aa 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -19,6 +19,8 @@ jobs: fetch-depth: 0 - name: conventional commits uses: webiny/action-conventional-commits@v1.2.0 + with: + allowed-commit-types: "build,chore,ci,docs,feat,fix,perf,refactor,style,test" - name: Setup Python uses: actions/setup-python@v5 with: diff --git a/HACKING.rst b/HACKING.rst index 2ea5ee14f1..7001e323ca 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -86,18 +86,153 @@ You can also see all the environments by simply running ``tox list`` Running ``tox run -m format`` and ``tox run -m lint`` before committing code is recommended. -Code Style -========== - Commits -####### +------- + +Commit messages are based on the `conventional commit`_ style:: + + (): + + + + + +The commit is divided into three sections: a header, body, and footer. + +Header +====== + +The header is required and consists of three subsections: a type, +optional scope, and description. The header must be 72 characters or less. + +Types +##### + +``ci`` +"""""" + +Commits that affect the CI/CD pipeline. + +``build`` +""""""""" + +Commits that affect the build of an application or library. + +This includes dependency updates, which should use the ``deps`` scope +(``build(deps):``). + +``feat`` +"""""""" + +Commits that add a new feature for the user. + +``fix`` +""""""" + +Commits that fix a bug or regression. + +``perf`` +"""""""" + +Commits that improve performance without changing the API or external behavior. + +``refactor`` +""""""""""""" + +Commits that refactor code. + +Using `Martin Fowler's definition`_, refactor means "*a change made +to the internal structure of software to make it easier to understand and +cheaper to modify without changing its observable behavior.*" + +``style`` +"""""""""" + +Commits that change the syntax, format, or aesthics of any text the codebase. +The meaning of the text should not change. + +Examples include: +* automatic changes from tools like ``black`` and ``ruff format`` +* changes to documentation that don't affect the meaning +* correcting a typo + +``test`` +"""""""" + +Commits that improve, add, or remove tests. -Format your commits following the conventional_ commit style. +``docs`` +"""""""" -Optionally, use the parens to scope to a particular component where -applicable. +Commits that affect the contents of the documentation. -See below for some examples of commit headings:: +Changes to how documentation is built should use ``build(docs)::``. + +Changes to how the documentation is built in the CI/CD pipeline should use +the ``ci(docs):``. + +``chore`` +""""""""" + +Miscellaneous commits that don't fit into any other type. + +Examples include: + +* edits to a comment or docstring +* type changes +* accommodating a developer-facing deprecation warning +* many *small* fixes for an existing PR +* merge commits (``chore(merge):``) + +Choosing the right type +""""""""""""""""""""""" + +Sometimes, multiple types may be appropriate for a PR. + +This may signal that a commit is doing more than one thing and should be +broken into multiple smaller commits. For example, a commit should not refactor +code and fix a bug. This should be two separate commits. + +In other scenarios, multiple types could be appropriate because of the nature +of the commit. This can happen with ``test`` and ``docs``, which can be used +as types or scopes. + +The types above are ordered by descending priority. The first appropriate type +should be used. + +For example, refactoring a test suite could have the header +``test(project): reorganize tests`` or +``refactor(test): reorganize project tests``. ``refactor`` has a higher +priority than ``test``, so the latter option is correct. + + +Scope +##### + +A scope is an optional part of the commit header. It adds additional context +by specifying what part of the codebase will be affected. + +It should be a tangible part of the codebase, like a directory, module, or +class name. + +If a commit affects many areas of the codebase, the scope should be omitted; +``many`` is not an accepted scope. + +Description +########### + +The description is written in the imperative mood (present tense, second +person). The description should complete the following sentence:: + + If applied, this commit will . + +The description does not begin with capital letter (unless it's a proper +noun) and does not end with puncuation mark. + +Examples +######## + +Examples of commit headings:: feat: inherit context from services test: increase unit test stability @@ -108,15 +243,31 @@ See below for some examples of commit headings:: ci(snap): upload the snap artefacts to Github chore(deps): update go.mod dependencies +Body +==== + +The body is an optional section of the commit to provide more context. +It should be succinct (no more than 3-4 sentences) and may reference relevant +bugs and issues. + +Footer +====== + +The footer is an optional section of the commit message that can mention the +signer and co-authors of the commit. + +Example footers:: -Recommended prefixes are: ``fix:``, ``feat:``, ``build:``, ``chore:``, ``ci:``, -``docs:``, ``style:``, ``refactor:``, ``perf:`` and ``test:`` + Signed-off-by: <> + Co-authored-by: <> .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ +.. _`conventional commit`: https://www.conventionalcommits.org/en/v1.0.0/#summary .. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa .. _`git submodules`: https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules +.. _`Martin Fowler's definition`: https://refactoring.com/ .. _pre-commit: https://pre-commit.com/ .. _pyproject.toml: ./pyproject.toml .. _Pyright: https://github.com/microsoft/pyright @@ -124,4 +275,3 @@ Recommended prefixes are: ``fix:``, ``feat:``, ``build:``, ``chore:``, ``ci:``, .. _ruff: https://github.com/charliermarsh/ruff .. _ShellCheck: https://www.shellcheck.net/ .. _tox: https://tox.wiki -.. _conventional: https://www.conventionalcommits.org/en/v1.0.0/#summary From ade6eba0d6be1a357cb23c56a3518171ce2c6142 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 4 Jan 2024 09:09:47 -0500 Subject: [PATCH 148/333] ci(deps): update artifact actions (#164) --- .github/workflows/docs.yaml | 2 +- .github/workflows/release-publish.yaml | 4 ++-- .github/workflows/tests.yaml | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 0e3e3bcf66..c2b688c975 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -31,7 +31,7 @@ jobs: - name: Build documentation run: tox run --colored yes -e build-docs - name: Upload documentation - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: docs path: docs/_build/ diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 55ac7a437d..27aff74a5b 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -30,7 +30,7 @@ jobs: python3 -m build twine check dist/* - name: Upload pypi packages artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: pypi-packages path: dist/ @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Get packages - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: pypi-packages path: dist/ diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b22201b7aa..11d2abc23b 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -81,9 +81,9 @@ jobs: files: coverage*.xml - name: Upload test results if: success() || failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: test-results-${{ matrix.platform }} + name: unit-test-results-${{ matrix.platform }} path: results/ integration: strategy: @@ -117,7 +117,7 @@ jobs: PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload test results if: success() || failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: test-results-${{ matrix.platform }} + name: integration-test-results-${{ matrix.platform }} path: results/ From 8931c9ab5acb27b355781339abb6c4a326e49e62 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 14:02:02 -0500 Subject: [PATCH 149/333] chore(deps): update actions/download-artifact action to v4 (#163) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-publish.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 27aff74a5b..a387c29ee6 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -52,7 +52,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Get pypi artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 - name: Release uses: softprops/action-gh-release@v1 with: From d6130fd12f9f4665b3acfb47facae4ec0bbed852 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 4 Jan 2024 16:23:53 -0500 Subject: [PATCH 150/333] ci(deps): make renovate update pyright separately. (#165) --- .github/renovate.json5 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 2984fef534..32cff51491 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -88,6 +88,12 @@ matchDepTypes: ["devDependencies"], matchUpdateTypes: ["major"], prPriority: -3 + }, + { + // Pyright makes regular breaking changes in patch releases, so we separate these + // and do them independently. + matchPackageNames: ["pyright"], + prPriority: -4 } ], regexManagers: [ From 48adeaf5b93b260c88cc3af959ed9294d076bbe6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:56:00 -0500 Subject: [PATCH 151/333] chore(deps): update dependency docs/sphinx-lint to v0.9.1 (#166) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 64b5cc16da..03eb28fda8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ docs = [ "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", "sphinx-toolbox==3.5.0", - "sphinx-lint==0.9.0", + "sphinx-lint==0.9.1", ] [build-system] From cf0b86cee65806cf387ff254d5611ec410cf557c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 14:50:54 -0500 Subject: [PATCH 152/333] chore(deps): update dependency setuptools to v67.8.0 (#167) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 03eb28fda8..0120bdbb2a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ docs = [ [build-system] requires = [ - "setuptools==67.7.2", + "setuptools==67.8.0", "setuptools_scm[toml]>=7.1" ] build-backend = "setuptools.build_meta" From a1c10a749224d9dace81e2b7262d680b102ba2a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 08:55:45 -0500 Subject: [PATCH 153/333] chore(deps): update dependency setuptools to v69 (#168) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0120bdbb2a..97f3d54ccc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ docs = [ [build-system] requires = [ - "setuptools==67.8.0", + "setuptools==69.0.3", "setuptools_scm[toml]>=7.1" ] build-backend = "setuptools.build_meta" From 621a10514d86c02d6b05371ae07822eac354ab9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 00:04:06 -0500 Subject: [PATCH 154/333] chore(deps): update dependency lint/black to v24 (#169) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 97f3d54ccc..7b20e1d416 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,7 @@ dev = [ "pytest-mock==3.12.0", ] lint = [ - "black==23.11.0", + "black==24.1.0", "codespell[toml]==2.2.6", "ruff==0.1.6", "yamllint==1.33.0" From f46054709551b9e9e9ebb89148bc566c1dd7b028 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 22:53:19 -0500 Subject: [PATCH 155/333] chore(deps): update dependency docs/furo to v2024 (#173) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7b20e1d416..997758c560 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ types = [ "pyright==1.1.338", ] docs = [ - "furo==2023.9.10", + "furo==2024.1.29", "sphinx>=7.1.2,<8", "sphinx-autobuild==2021.3.14", "sphinx-copybutton==0.5.2", From 2d56dce04ff1ca14dff28f68a5ba4f8a0df9757c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 03:53:45 +0000 Subject: [PATCH 156/333] chore(deps): update webiny/action-conventional-commits action to v1.3.0 --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 11d2abc23b..89d62b36b3 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -18,7 +18,7 @@ jobs: with: fetch-depth: 0 - name: conventional commits - uses: webiny/action-conventional-commits@v1.2.0 + uses: webiny/action-conventional-commits@v1.3.0 with: allowed-commit-types: "build,chore,ci,docs,feat,fix,perf,refactor,style,test" - name: Setup Python From 20eb12967d9eccc494506ebbd5def38d71ac2817 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 31 Jan 2024 06:17:12 -0500 Subject: [PATCH 157/333] build(deps): update pyright (#170) * Disable pyright complaints for mocks * Move `types/pyright` into renovate's pyright group --- .github/renovate.json5 | 2 +- pyproject.toml | 2 +- tests/unit/starbase/test_init.py | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 32cff51491..a51c1e6571 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -92,7 +92,7 @@ { // Pyright makes regular breaking changes in patch releases, so we separate these // and do them independently. - matchPackageNames: ["pyright"], + matchPackageNames: ["pyright", "types/pyright"], prPriority: -4 } ], diff --git a/pyproject.toml b/pyproject.toml index 997758c560..81895bdd44 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]==1.7.1", - "pyright==1.1.338", + "pyright==1.1.349", ] docs = [ "furo==2024.1.29", diff --git a/tests/unit/starbase/test_init.py b/tests/unit/starbase/test_init.py index d124894f92..ca98cfd471 100644 --- a/tests/unit/starbase/test_init.py +++ b/tests/unit/starbase/test_init.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Basic Starcraft package demo unit tests.""" +# pyright: reportFunctionMemberAccess=false from unittest import mock import starcraft From 3feb312f9d94e474b3181a2bcc37617b46e8d2f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 14:52:49 -0300 Subject: [PATCH 158/333] chore(deps): update development dependencies (non-major) (#174) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 81895bdd44..f39df121c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,19 +18,19 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ "build", - "coverage[toml]==7.3.2", - "pytest==7.4.3", + "coverage[toml]==7.4.1", + "pytest==7.4.4", "pytest-cov==4.1.0", "pytest-mock==3.12.0", ] lint = [ - "black==24.1.0", + "black==24.1.1", "codespell[toml]==2.2.6", - "ruff==0.1.6", + "ruff==0.1.14", "yamllint==1.33.0" ] types = [ - "mypy[reports]==1.7.1", + "mypy[reports]==1.8.0", "pyright==1.1.349", ] docs = [ From ceb64e2bfb97d6138ae74d625dcd33d5b043ae9b Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Wed, 31 Jan 2024 15:11:30 -0300 Subject: [PATCH 159/333] ci: fix regex for pre-commit-config.yaml (#175) --- .github/renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index a51c1e6571..02e0c28a93 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -110,7 +110,7 @@ fileMatch: [".pre-commit-config.yaml"], depTypeTemplate: "devDependencies", matchStrings: [ - "# renovate: datasource=(?\\S+);\\s*depName=(?.*?)\n\s+rev: \"v?(?.*?)\"" + "# renovate: datasource=(?\\S+);\\s*depName=(?.*?)\n\\s+rev: \"v?(?.*?)\"" ] } ], From d79b26bcfdcd476f780798b58f9e15b69bef7fad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 13:16:28 -0500 Subject: [PATCH 160/333] chore(deps): update dependency dev/pytest to v8 (#172) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f39df121c5..746b671cba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ starcraft-hello = "starcraft:hello" dev = [ "build", "coverage[toml]==7.4.1", - "pytest==7.4.4", + "pytest==8.0.0", "pytest-cov==4.1.0", "pytest-mock==3.12.0", ] From 9815d93a0767231f3245e206abb1a27bc910e665 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:02:14 -0500 Subject: [PATCH 161/333] chore(deps): update dependency black to v24 (#176) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5a9b3a40a1..8ff315785a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,7 @@ repos: args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black # renovate: datasource=pypi;depName=black - rev: "23.3.0" + rev: "24.1.1" hooks: - id: black - repo: https://github.com/adrienverge/yamllint.git From c6d29c32a697c1b5170392fc5ce224ca62edfd2a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:28:58 -0500 Subject: [PATCH 162/333] chore(deps): update dependency ruff to v0.1.15 (#177) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8ff315785a..28fa874765 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: - id: mixed-line-ending - repo: https://github.com/charliermarsh/ruff-pre-commit # renovate: datasource=pypi;depName=ruff - rev: "v0.0.267" + rev: "v0.1.15" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 0cfc30a4ef787520405cf48babeee3d5852a35a6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:29:24 -0500 Subject: [PATCH 163/333] chore(deps): update dependency yamllint to v1.33.0 (#178) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 28fa874765..f90f393485 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,6 +25,6 @@ repos: - id: black - repo: https://github.com/adrienverge/yamllint.git # renovate: datasource=pypi;depName=yamllint - rev: "v1.31.0" + rev: "v1.33.0" hooks: - id: yamllint From 5a0b0ea9ae528e9682745196e2940c4038446abd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:06:56 -0500 Subject: [PATCH 164/333] chore(deps): update dependency lint/ruff to v0.2.0 (#181) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 746b671cba..5c17f0807d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ dev = [ lint = [ "black==24.1.1", "codespell[toml]==2.2.6", - "ruff==0.1.14", + "ruff==0.2.0", "yamllint==1.33.0" ] types = [ From 4d11ec48cb2568086d011590f3a44167646e46f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:07:14 +0000 Subject: [PATCH 165/333] chore(deps): update github actions --- .github/workflows/release-drafter.yaml | 2 +- .github/workflows/tests.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index 3ae8faaa4a..4c6db3eb1f 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Release Drafter - uses: release-drafter/release-drafter@v5.25.0 + uses: release-drafter/release-drafter@v6.0.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 89d62b36b3..42dce5321e 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -75,7 +75,7 @@ jobs: env: PYTEST_ADDOPTS: "--no-header -vv -rN" - name: Upload code coverage - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: directory: ./results/ files: coverage*.xml From f6db1eb7e673e4be3404f6a6db4c8fb4e0cbdf82 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 5 Feb 2024 12:38:12 -0500 Subject: [PATCH 166/333] chore: make pre-commit linters use lint group for renovate (#183) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f90f393485..c44e4de5e1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,18 +13,18 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/charliermarsh/ruff-pre-commit - # renovate: datasource=pypi;depName=ruff + # renovate: datasource=pypi;depName=lint/ruff rev: "v0.1.15" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black - # renovate: datasource=pypi;depName=black + # renovate: datasource=pypi;depName=lint/black rev: "24.1.1" hooks: - id: black - repo: https://github.com/adrienverge/yamllint.git - # renovate: datasource=pypi;depName=yamllint + # renovate: datasource=pypi;depName=lint/yamllint rev: "v1.33.0" hooks: - id: yamllint From 234b360057791c38fdb8430afd2c405537979464 Mon Sep 17 00:00:00 2001 From: Callahan Date: Mon, 5 Feb 2024 14:49:52 -0600 Subject: [PATCH 167/333] docs(HACKING): clarify commit header for merges (#184) Signed-off-by: Callahan Kovacs --- HACKING.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/HACKING.rst b/HACKING.rst index 7001e323ca..945cf9664a 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -182,7 +182,10 @@ Examples include: * type changes * accommodating a developer-facing deprecation warning * many *small* fixes for an existing PR -* merge commits (``chore(merge):``) +* merge commits (``chore(merge): '' into ''``) + + * the remote name should not be included (i.e. use ``'main'`` + instead of ``'origin/main'``) Choosing the right type """"""""""""""""""""""" From 5b1422bc123b12f7213982fed24d9836f16bd86e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 6 Feb 2024 09:34:58 -0500 Subject: [PATCH 168/333] ci(renovate): fix pre-commit dependency manager (#185) --- .github/renovate.json5 | 5 +++-- .pre-commit-config.yaml | 7 ++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 02e0c28a93..9c4bd55507 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -108,9 +108,10 @@ { // .pre-commit-config.yaml version updates fileMatch: [".pre-commit-config.yaml"], - depTypeTemplate: "devDependencies", + datasourceTemplate: "pypi", + depTypeTemplate: "lint", matchStrings: [ - "# renovate: datasource=(?\\S+);\\s*depName=(?.*?)\n\\s+rev: \"v?(?.*?)\"" + "- repo: .*/<(?\\S+)\\s*\\n\\s*rev:\s+\"?v?(?\\S*)\"?", ] } ], diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c44e4de5e1..f84e07acdc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: "v4.4.0" hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -12,19 +12,16 @@ repos: - id: check-toml - id: fix-byte-order-marker - id: mixed-line-ending - - repo: https://github.com/charliermarsh/ruff-pre-commit - # renovate: datasource=pypi;depName=lint/ruff + - repo: https://github.com/astral-sh/ruff-pre-commit rev: "v0.1.15" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black - # renovate: datasource=pypi;depName=lint/black rev: "24.1.1" hooks: - id: black - repo: https://github.com/adrienverge/yamllint.git - # renovate: datasource=pypi;depName=lint/yamllint rev: "v1.33.0" hooks: - id: yamllint From 64dc591c581c3b43911fc21ac1f8570bfcc5931c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Feb 2024 17:06:15 -0500 Subject: [PATCH 169/333] chore(deps): update dependency docs/sphinx-autobuild to v2024 (#187) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5c17f0807d..a00fc27aa3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ types = [ docs = [ "furo==2024.1.29", "sphinx>=7.1.2,<8", - "sphinx-autobuild==2021.3.14", + "sphinx-autobuild==2024.2.4", "sphinx-copybutton==0.5.2", "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", From 455aa11710a82a74b2e55b4c9b6634daaf88e652 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Feb 2024 17:06:45 -0500 Subject: [PATCH 170/333] chore(deps): update development dependencies (non-major) (#186) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a00fc27aa3..6a269c560b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,12 +26,12 @@ dev = [ lint = [ "black==24.1.1", "codespell[toml]==2.2.6", - "ruff==0.2.0", - "yamllint==1.33.0" + "ruff==0.2.1", + "yamllint==1.34.0" ] types = [ "mypy[reports]==1.8.0", - "pyright==1.1.349", + "pyright==1.1.350", ] docs = [ "furo==2024.1.29", From 9d271a7c08bd20002a5fb273b9a9fd446f3bc335 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 16 Feb 2024 11:34:18 -0500 Subject: [PATCH 171/333] build: loosen requirements (#190) The modified dependencies are known to be sufficiently stable that the given version ranges are unlikely to cause breakages. --- pyproject.toml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6a269c560b..e49e22ec48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,35 +18,35 @@ starcraft-hello = "starcraft:hello" [project.optional-dependencies] dev = [ "build", - "coverage[toml]==7.4.1", - "pytest==8.0.0", - "pytest-cov==4.1.0", - "pytest-mock==3.12.0", + "coverage[toml]~=7.4", + "pytest~=8.0", + "pytest-cov~=4.1", + "pytest-mock~=3.12", ] lint = [ - "black==24.1.1", - "codespell[toml]==2.2.6", - "ruff==0.2.1", - "yamllint==1.34.0" + "black~=24.1", + "codespell[toml]~=2.2", + "ruff~=0.2.1", + "yamllint~=1.34" ] types = [ - "mypy[reports]==1.8.0", + "mypy[reports]~=1.8.0", "pyright==1.1.350", ] docs = [ "furo==2024.1.29", - "sphinx>=7.1.2,<8", - "sphinx-autobuild==2024.2.4", + "sphinx~=7.1", + "sphinx-autobuild~=2024.2", "sphinx-copybutton==0.5.2", "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", - "sphinx-toolbox==3.5.0", + "sphinx-toolbox~=3.5", "sphinx-lint==0.9.1", ] [build-system] requires = [ - "setuptools==69.0.3", + "setuptools>=69.0", "setuptools_scm[toml]>=7.1" ] build-backend = "setuptools.build_meta" From 826a08e26eaa745446c7eead519690d4c9bb9fa6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:14:35 -0500 Subject: [PATCH 172/333] chore(deps): update dependency types/pyright to v1.1.351 (#189) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e49e22ec48..e98240ffaf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]~=1.8.0", - "pyright==1.1.350", + "pyright==1.1.351", ] docs = [ "furo==2024.1.29", From 2130cd0b5f85324fafb7c2416a35d3471762495b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 19:54:27 -0500 Subject: [PATCH 173/333] chore(deps): update development dependencies (non-major) (#191) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e98240ffaf..a7fb1f86df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,12 +26,12 @@ dev = [ lint = [ "black~=24.1", "codespell[toml]~=2.2", - "ruff~=0.2.1", + "ruff~=0.3.0", "yamllint~=1.34" ] types = [ "mypy[reports]~=1.8.0", - "pyright==1.1.351", + "pyright==1.1.352", ] docs = [ "furo==2024.1.29", From d319ea93beca59ffbf0c5bbfe653ff956bb17c2a Mon Sep 17 00:00:00 2001 From: Callahan Date: Mon, 4 Mar 2024 20:07:26 -0600 Subject: [PATCH 174/333] chore: update ruff settings (#192) Signed-off-by: Callahan Kovacs --- pyproject.toml | 10 +++++----- tox.ini | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a7fb1f86df..181882a33c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -153,7 +153,7 @@ extend-exclude = [ "__pycache__", ] # Follow ST063 - Maintaining and updating linting specifications for updating these. -select = [ # Base linting rule selections. +lint.select = [ # Base linting rule selections. # See the internal document for discussion: # https://docs.google.com/document/d/1i1n8pDmFmWi4wTDpk-JfnWCVUThPJiggyPi2DYwBBu4/edit # All sections here are stable in ruff and shouldn't randomly introduce @@ -226,7 +226,7 @@ select = [ # Base linting rule selections. "RUF100", # #noqa directive that doesn't flag anything "RUF200", # If ruff fails to parse pyproject.toml... ] -ignore = [ +lint.ignore = [ "ANN10", # Type annotations for `self` and `cls` #"E203", # Whitespace before ":" -- Commented because ruff doesn't currently check E203 "E501", # Line too long (reason: black will automatically fix this for us) @@ -243,7 +243,7 @@ ignore = [ "TRY003", # Avoid specifying long messages outside the exception class ] -[tool.ruff.flake8-annotations] +[tool.ruff.lint.flake8-annotations] allow-star-arg-any = true [tool.ruff.lint.pydocstyle] @@ -259,11 +259,11 @@ ignore-decorators = [ # Functions with these decorators don't have to have docs [tool.ruff.lint.pylint] max-args = 8 -[tool.ruff.pep8-naming] +[tool.ruff.lint.pep8-naming] # Allow Pydantic's `@validator` decorator to trigger class method treatment. classmethod-decorators = ["pydantic.validator", "pydantic.root_validator"] -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "tests/**.py" = [ # Some things we want for the moin project are unnecessary in tests. "D", # Ignore docstring rules in tests "ANN", # Ignore type annotations in tests diff --git a/tox.ini b/tox.ini index a99a7ba0a5..e528613a59 100644 --- a/tox.ini +++ b/tox.ini @@ -102,7 +102,7 @@ base = testenv, lint labels = format commands = black: black {tty:--color} {posargs} . - ruff: ruff --fix --respect-gitignore {posargs} . + ruff: ruff check --fix --respect-gitignore {posargs} . codespell: codespell --toml {tox_root}/pyproject.toml --write-changes {posargs} [testenv:pre-commit] From c9c4de153f36647bb07fac864f08a2e7274a6ee9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 13:43:55 -0400 Subject: [PATCH 175/333] chore(deps): update development dependencies (non-major) (#193) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 181882a33c..b12ecaa9ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,8 +30,8 @@ lint = [ "yamllint~=1.34" ] types = [ - "mypy[reports]~=1.8.0", - "pyright==1.1.352", + "mypy[reports]~=1.9.0", + "pyright==1.1.355", ] docs = [ "furo==2024.1.29", From ef54940298fcda86c4dec30679695d77f65910dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 13:57:06 -0400 Subject: [PATCH 176/333] chore(deps): update softprops/action-gh-release action to v2 (#194) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-publish.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index a387c29ee6..4d30ed0fb3 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -54,7 +54,7 @@ jobs: - name: Get pypi artifacts uses: actions/download-artifact@v4 - name: Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: files: | ** From bf22cfe3e91191f8a2778a0e2afbd6180d534a0c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 08:52:16 -0300 Subject: [PATCH 177/333] chore(deps): update dependency dev/pytest-cov to v5 (#195) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b12ecaa9ea..6929eb1428 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ dev = [ "build", "coverage[toml]~=7.4", "pytest~=8.0", - "pytest-cov~=4.1", + "pytest-cov~=5.0", "pytest-mock~=3.12", ] lint = [ From 5d10b2a8c67d05994ce964a60d2b18abcd3435a9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:43:51 -0400 Subject: [PATCH 178/333] chore(deps): update dependency types/pyright to v1.1.356 (#196) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6929eb1428..5deca2b2b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]~=1.9.0", - "pyright==1.1.355", + "pyright==1.1.356", ] docs = [ "furo==2024.1.29", From 955f4455e49f169418c042c5641c24ef53a8d2bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 17:18:45 -0400 Subject: [PATCH 179/333] chore(deps): update dependency types/pyright to v1.1.357 (#198) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5deca2b2b5..c3a8927ee4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]~=1.9.0", - "pyright==1.1.356", + "pyright==1.1.357", ] docs = [ "furo==2024.1.29", From 56b1e71cab36bd54ae0b15446ca58486087dd7ce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 15:50:27 -0400 Subject: [PATCH 180/333] chore(deps): update dependency types/pyright to v1.1.358 (#202) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c3a8927ee4..9362313aff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ lint = [ ] types = [ "mypy[reports]~=1.9.0", - "pyright==1.1.357", + "pyright==1.1.358", ] docs = [ "furo==2024.1.29", From 09b91ba2f9badbb2edde5c5659e252e6d1e893d0 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 23 Apr 2024 12:44:24 -0400 Subject: [PATCH 181/333] chore: use ruff snap (#204) --- .github/workflows/tests.yaml | 2 +- HACKING.rst | 2 +- pyproject.toml | 1 - tox.ini | 5 +++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 42dce5321e..aecafab542 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,7 +31,7 @@ jobs: echo "::group::Begin snap install" echo "Installing snaps in the background while running apt and pip..." sudo snap install --no-wait --classic pyright - sudo snap install --no-wait shellcheck + sudo snap install --no-wait shellcheck ruff echo "::endgroup::" echo "::group::pip install" python -m pip install tox diff --git a/HACKING.rst b/HACKING.rst index 945cf9664a..4477e26ea8 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -22,6 +22,7 @@ you with tox, but you'll need to install: deadsnakes_ PPA) with setuptools. - tox_ version 3.8 or later - ShellCheck_ (also available via snap: ``snap install shellcheck``) +- ruff_ (also available via snap: ``snap install ruff``) Once you have all of those installed, you can install the necessary virtual environments for this repository using tox. @@ -32,7 +33,6 @@ Some other tools we use for code quality include: - Black_ for code formatting - pytest_ for testing -- ruff_ for linting (and some additional formatting) A complete list is kept in our pyproject.toml_ file in dev dependencies. diff --git a/pyproject.toml b/pyproject.toml index 9362313aff..0f6bb4beb4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,6 @@ dev = [ lint = [ "black~=24.1", "codespell[toml]~=2.2", - "ruff~=0.3.0", "yamllint~=1.34" ] types = [ diff --git a/tox.ini b/tox.ini index e528613a59..90f788092c 100644 --- a/tox.ini +++ b/tox.ini @@ -62,6 +62,9 @@ package = editable extras = lint env_dir = {work_dir}/linting runner = ignore_env_name_mismatch +allowlist_externals = + shellcheck: bash, xargs + ruff: ruff [shellcheck] find = git ls-files @@ -71,8 +74,6 @@ filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: description = Lint the source code base = testenv, lint labels = lint -allowlist_externals = - shellcheck: bash, xargs commands_pre = shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' commands = From 06f6913038c22f48545cc29d7b2b42f3c3eb6214 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:05:11 -0400 Subject: [PATCH 182/333] chore(deps): update dependency types/pyright to v1.1.359 (#206) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0f6bb4beb4..cf7d295ef3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ lint = [ ] types = [ "mypy[reports]~=1.9.0", - "pyright==1.1.358", + "pyright==1.1.359", ] docs = [ "furo==2024.1.29", From 919199006dcd367c8ea6e919f564f3660b2045dd Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 24 Apr 2024 15:59:31 -0400 Subject: [PATCH 183/333] ci: update Python versions --- .github/workflows/tests.yaml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index aecafab542..c5050638f9 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -24,7 +24,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' cache: 'pip' - name: Configure environment run: | @@ -57,10 +57,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.8 3.10 - 3.11 - 3.12-dev + 3.12 + 3.13-dev cache: 'pip' - name: Configure environment run: | @@ -98,10 +97,9 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.8 3.10 - 3.11 - 3.12-dev + 3.12 + 3.13-dev cache: 'pip' - name: Configure environment run: | From 54b8fab4981f0b878d6f49e1db91b4b7e41e396e Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 24 Apr 2024 16:02:38 -0400 Subject: [PATCH 184/333] build: update minimum Python version to 3.10 --- pyproject.toml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cf7d295ef3..77bdb733b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,9 +8,10 @@ classifiers = [ "Development Status :: 1 - Planning", "License :: OSI Approved :: GNU General Public License (GPL)", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.12", ] -requires-python = ">=3.8" +requires-python = ">=3.10" [project.scripts] starcraft-hello = "starcraft:hello" @@ -75,7 +76,7 @@ include = ["*craft*"] namespaces = false [tool.black] -target-version = ["py38"] +target-version = ["py310"] [tool.codespell] ignore-words-list = "buildd,crate,keyserver,comandos,ro,dedent,dedented" @@ -109,7 +110,7 @@ exclude_also = [ [tool.pyright] strict = ["starcraft"] -pythonVersion = "3.8" +pythonVersion = "3.10" pythonPlatform = "Linux" exclude = [ "**/.*", @@ -119,7 +120,7 @@ exclude = [ ] [tool.mypy] -python_version = "3.8" +python_version = "3.10" exclude = [ "build", "tests", @@ -145,7 +146,7 @@ strict = false [tool.ruff] line-length = 88 -target-version = "py38" +target-version = "py310" src = ["starcraft", "tests"] extend-exclude = [ "docs", From 51a7a95f963dc1484171a9f2601a0b5420f59a82 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 24 Apr 2024 16:06:24 -0400 Subject: [PATCH 185/333] style: autoformat --- starcraft/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/starcraft/__init__.py b/starcraft/__init__.py index 4e75351052..7a07a1f20b 100644 --- a/starcraft/__init__.py +++ b/starcraft/__init__.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Starcraft package demo.""" -from typing import List, Optional, Any +from typing import Any try: from ._version import __version__ @@ -27,7 +27,7 @@ __version__ = "dev" -def hello(people: Optional[List[Any]] = None) -> None: +def hello(people: list[Any] | None = None) -> None: """Says hello.""" print("Hello *craft team!") if people: From de9999bb0df912ae23ec40ea64d02f0918c1912d Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 24 Apr 2024 16:06:34 -0400 Subject: [PATCH 186/333] chore: update python versions ruff uses --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 90f788092c..a0a977578d 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ env_list = # Environments to run when called with no parameters. format-{black,ruff,codespell} pre-commit lint-{black,ruff,mypy,pyright,shellcheck,codespell,docs,yaml} - unit-py3.{8,10,11} + unit-py3.{10,12} integration-py3.10 # Integration tests probably take a while, so we're only running them on Python # 3.10, which is included in core22. From a5b35eac80c9857daf0446a2df50c97e724b2145 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 24 Apr 2024 16:09:01 -0400 Subject: [PATCH 187/333] chore: update tox python versions --- tox.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index a0a977578d..b3a1d6b748 100644 --- a/tox.ini +++ b/tox.ini @@ -49,9 +49,9 @@ description = unit: Run unit tests with pytest integration: Run integration tests with pytest labels = - py3.{8,10,11}: tests - unit-py3.{8,10,11}: unit-tests - integration-py3.{8,10,11}: integration-tests + py3.{10,12}: tests + unit-py3.{10,12}: unit-tests + integration-py3.{10,12}: integration-tests change_dir = unit: tests/unit integration: tests/integration From 439dad683a2102a6d8fe7e394cdddec405ff1e7d Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 25 Apr 2024 15:48:59 -0400 Subject: [PATCH 188/333] chore: switch to codespell snap (#205) --- .github/workflows/tests.yaml | 2 +- HACKING.rst | 2 ++ pyproject.toml | 3 +-- tox.ini | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index c5050638f9..16f6d0ae2e 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,7 +31,7 @@ jobs: echo "::group::Begin snap install" echo "Installing snaps in the background while running apt and pip..." sudo snap install --no-wait --classic pyright - sudo snap install --no-wait shellcheck ruff + sudo snap install --no-wait codespell shellcheck ruff echo "::endgroup::" echo "::group::pip install" python -m pip install tox diff --git a/HACKING.rst b/HACKING.rst index 4477e26ea8..08a6768865 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -22,6 +22,7 @@ you with tox, but you'll need to install: deadsnakes_ PPA) with setuptools. - tox_ version 3.8 or later - ShellCheck_ (also available via snap: ``snap install shellcheck``) +- Codespell_ (also available via snap: ``snap install codespell``) - ruff_ (also available via snap: ``snap install ruff``) Once you have all of those installed, you can install the necessary virtual @@ -267,6 +268,7 @@ Example footers:: .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ +.. _Codespell: https://github.com/codespell-project/codespell .. _`conventional commit`: https://www.conventionalcommits.org/en/v1.0.0/#summary .. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa .. _`git submodules`: https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules diff --git a/pyproject.toml b/pyproject.toml index 77bdb733b6..3c68f6076d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,8 +26,7 @@ dev = [ ] lint = [ "black~=24.1", - "codespell[toml]~=2.2", - "yamllint~=1.34" + "yamllint~=1.34", ] types = [ "mypy[reports]~=1.9.0", diff --git a/tox.ini b/tox.ini index b3a1d6b748..58811bfb7d 100644 --- a/tox.ini +++ b/tox.ini @@ -63,6 +63,7 @@ extras = lint env_dir = {work_dir}/linting runner = ignore_env_name_mismatch allowlist_externals = + codespell: codespell shellcheck: bash, xargs ruff: ruff From cd48e13fb1f331dfd494a9b749bfadb8f75028e6 Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Thu, 25 Apr 2024 20:44:38 -0300 Subject: [PATCH 189/333] docs: use canonical-sphinx (#209) --- docs/conf.py | 76 +++++++++++++++++++++++++++++--------------------- pyproject.toml | 5 +--- 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index eeb02572f3..d3f052d638 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,47 +1,59 @@ -# Configuration file for the Sphinx documentation builder. +# This file is part of starbase. # -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html +# Copyright 2024 Canonical Ltd. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, 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 . -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information +import datetime -project = "starcraft" -copyright = "2023, Canonical" +project = "Starbase" author = "Canonical" -# region General configuration -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration +copyright = "2023-%s, %s" % (datetime.date.today().year, author) + +# region Configuration for canonical-sphinx +ogp_site_url = "https://canonical-starbase.readthedocs-hosted.com/" +ogp_site_name = project +ogp_image = "https://assets.ubuntu.com/v1/253da317-image-document-ubuntudocs.svg" + +html_context = { + "product_page": "github.com/canonical/starbase", + "github_url": "https://github.com/canonical/starbase", +} extensions = [ - "sphinx.ext.intersphinx", - "sphinx.ext.viewcode", - "sphinx.ext.coverage", - "sphinx.ext.doctest", - "sphinx_design", - "sphinx_copybutton", - "sphinx-pydantic", - "sphinx_toolbox", - "sphinx_toolbox.more_autodoc", - "sphinx.ext.autodoc", # Must be loaded after more_autodoc + "canonical_sphinx", ] +# endregion -templates_path = ["_templates"] -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +# region General configuration +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration -show_authors = False +extensions.extend( + [ + "sphinx.ext.intersphinx", + "sphinx.ext.viewcode", + "sphinx.ext.coverage", + "sphinx.ext.doctest", + "sphinx-pydantic", + "sphinx_toolbox", + "sphinx_toolbox.more_autodoc", + "sphinx.ext.autodoc", # Must be loaded after more_autodoc + ] +) # endregion -# region Options for HTML output -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = "furo" -html_static_path = ["_static"] -html_css_files = [ - "css/custom.css", -] - -# endregion # region Options for extensions # Intersphinx extension # https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration @@ -57,6 +69,6 @@ # Github config github_username = "canonical" -github_repository = "starcraft-base" +github_repository = "starbase" # endregion diff --git a/pyproject.toml b/pyproject.toml index 3c68f6076d..449813c1ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,11 +33,8 @@ types = [ "pyright==1.1.359", ] docs = [ - "furo==2024.1.29", - "sphinx~=7.1", + "canonical-sphinx~=0.1", "sphinx-autobuild~=2024.2", - "sphinx-copybutton==0.5.2", - "sphinx-design==0.5.0", "sphinx-pydantic==0.1.1", "sphinx-toolbox~=3.5", "sphinx-lint==0.9.1", From 3b02fb67811efc1208d30214bdd8f96129a1795a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 12:57:50 -0400 Subject: [PATCH 190/333] chore(deps): update development dependencies (non-major) (#210) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 449813c1ff..bcde58044c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,8 +29,8 @@ lint = [ "yamllint~=1.34", ] types = [ - "mypy[reports]~=1.9.0", - "pyright==1.1.359", + "mypy[reports]~=1.10.0", + "pyright==1.1.363", ] docs = [ "canonical-sphinx~=0.1", From aae9d000815aba904acbf44ee9b7a83f5291b7de Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 21 May 2024 16:39:21 -0400 Subject: [PATCH 191/333] style: replace black formatter with ruff format (#212) --- pyproject.toml | 19 +++++++++++++++---- starcraft/__init__.py | 1 + tests/integration/starbase/test_init.py | 1 + tests/integration/test_setuptools.py | 1 + tests/integration/test_version.py | 1 + tests/unit/starbase/test_init.py | 1 + tox.ini | 12 ++++++------ 7 files changed, 26 insertions(+), 10 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bcde58044c..029b0ffae9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,6 @@ dev = [ "pytest-mock~=3.12", ] lint = [ - "black~=24.1", "yamllint~=1.34", ] types = [ @@ -148,8 +147,15 @@ extend-exclude = [ "docs", "__pycache__", ] + +[tool.ruff.format] +docstring-code-format = true +line-ending = "lf" +quote-style = "double" + +[tool.ruff.lint] # Follow ST063 - Maintaining and updating linting specifications for updating these. -lint.select = [ # Base linting rule selections. +select = [ # Base linting rule selections. # See the internal document for discussion: # https://docs.google.com/document/d/1i1n8pDmFmWi4wTDpk-JfnWCVUThPJiggyPi2DYwBBu4/edit # All sections here are stable in ruff and shouldn't randomly introduce @@ -217,12 +223,12 @@ lint.select = [ # Base linting rule selections. "RUF001", "RUF002", "RUF003", # Ambiguous unicode characters "RUF005", # Encourages unpacking rather than concatenation "RUF008", # Do not use mutable default values for dataclass attributes - "RUF011", # Don't use static keys in dict comprehensions. + "B035", # Don't use static keys in dict comprehensions. "RUF013", # Prohibit implicit Optionals (PEP 484) "RUF100", # #noqa directive that doesn't flag anything "RUF200", # If ruff fails to parse pyproject.toml... ] -lint.ignore = [ +ignore = [ "ANN10", # Type annotations for `self` and `cls` #"E203", # Whitespace before ":" -- Commented because ruff doesn't currently check E203 "E501", # Line too long (reason: black will automatically fix this for us) @@ -235,6 +241,11 @@ lint.ignore = [ "SIM117", # Use a single `with` statement with multiple contexts instead of nested `with` statements # (reason: this creates long lines that get wrapped and reduces readability) + # Ignored due to conflicts with ruff's formatter: + # https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules + "COM812", # Missing trailing comma - mostly the same, but marginal differences. + "ISC001", # Single-line implicit string concatenation. + # Ignored due to common usage in current code "TRY003", # Avoid specifying long messages outside the exception class ] diff --git a/starcraft/__init__.py b/starcraft/__init__.py index 7a07a1f20b..9ae32cb88f 100644 --- a/starcraft/__init__.py +++ b/starcraft/__init__.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Starcraft package demo.""" + from typing import Any try: diff --git a/tests/integration/starbase/test_init.py b/tests/integration/starbase/test_init.py index 879210b715..1c8a803ed2 100644 --- a/tests/integration/starbase/test_init.py +++ b/tests/integration/starbase/test_init.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Basic Starcraft package demo integration tests.""" + import subprocess diff --git a/tests/integration/test_setuptools.py b/tests/integration/test_setuptools.py index d40f9ac4a2..a27c9843c8 100644 --- a/tests/integration/test_setuptools.py +++ b/tests/integration/test_setuptools.py @@ -12,6 +12,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Integration tests related to building the package.""" + import re import subprocess import sys diff --git a/tests/integration/test_version.py b/tests/integration/test_version.py index 411b3118b0..b1ecda53f2 100644 --- a/tests/integration/test_version.py +++ b/tests/integration/test_version.py @@ -12,6 +12,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Versioning tests.""" + import re import subprocess diff --git a/tests/unit/starbase/test_init.py b/tests/unit/starbase/test_init.py index ca98cfd471..34e92ff9d2 100644 --- a/tests/unit/starbase/test_init.py +++ b/tests/unit/starbase/test_init.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . """Basic Starcraft package demo unit tests.""" + # pyright: reportFunctionMemberAccess=false from unittest import mock diff --git a/tox.ini b/tox.ini index 58811bfb7d..6b27f37c34 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,8 @@ [tox] env_list = # Environments to run when called with no parameters. - format-{black,ruff,codespell} + format-{ruff,codespell} pre-commit - lint-{black,ruff,mypy,pyright,shellcheck,codespell,docs,yaml} + lint-{ruff,mypy,pyright,shellcheck,codespell,docs,yaml} unit-py3.{10,12} integration-py3.10 # Integration tests probably take a while, so we're only running them on Python @@ -71,14 +71,14 @@ allowlist_externals = find = git ls-files filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: -[testenv:lint-{black,ruff,shellcheck,codespell,yaml}] +[testenv:lint-{ruff,shellcheck,codespell,yaml}] description = Lint the source code base = testenv, lint labels = lint commands_pre = shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' commands = - black: black --check --diff {tty:--color} {posargs} . + ruff: ruff format --check --diff --respect-gitignore {posargs:.} ruff: ruff check --respect-gitignore {posargs:.} shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck codespell: codespell --toml {tox_root}/pyproject.toml {posargs} @@ -98,12 +98,12 @@ commands = pyright: pyright {posargs} mypy: mypy --install-types --non-interactive {posargs:.} -[testenv:format-{black,ruff,codespell}] +[testenv:format-{ruff,codespell}] description = Automatically format source code base = testenv, lint labels = format commands = - black: black {tty:--color} {posargs} . + ruff: ruff format --respect-gitignore {posargs:.} ruff: ruff check --fix --respect-gitignore {posargs} . codespell: codespell --toml {tox_root}/pyproject.toml --write-changes {posargs} From beee3a822c23392a073c653ac9d7d0b09e8f98ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 26 May 2024 18:43:23 -0400 Subject: [PATCH 192/333] chore(deps): update dependency types/pyright to v1.1.364 (#216) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 029b0ffae9..aef1358ccf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.10.0", - "pyright==1.1.363", + "pyright==1.1.364", ] docs = [ "canonical-sphinx~=0.1", From 5b5dbef75992a65d5774de12f4777dc00a1af2dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 07:27:01 -0500 Subject: [PATCH 193/333] chore(deps): update dependency types/pyright to v1.1.365 (#217) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index aef1358ccf..b210287f30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.10.0", - "pyright==1.1.364", + "pyright==1.1.365", ] docs = [ "canonical-sphinx~=0.1", From 1acd270801ce3b204dedc61da798f897d7474f78 Mon Sep 17 00:00:00 2001 From: Callahan Date: Tue, 4 Jun 2024 11:26:43 -0500 Subject: [PATCH 194/333] docs(HACKING): document branch names and changelog (#218) Signed-off-by: Callahan Kovacs --- HACKING.rst | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/HACKING.rst b/HACKING.rst index 08a6768865..27ff1ae165 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -87,6 +87,81 @@ You can also see all the environments by simply running ``tox list`` Running ``tox run -m format`` and ``tox run -m lint`` before committing code is recommended. +Branches +-------- + +Starcraft projects follow the `OneFlow`_ git branching model. + + +Branch names +============ + +The branch name should be brief and less than 200 characters. + +Branch names are formatted as ``/``. + +This naming convention provides a few benefits: + - GitHub workflows can choose which categories they should run on + - GitHub branches rules can be configured per category + - Some IDEs and git tools display categorized branches in a neat and + nested format + +``main`` +######## + +The main branch containing the latest changes. + +``renovate/*`` +############## + +Branches created automatically by the `Renovate bot`_. + +``work/-`` +############################### + +For any work driven by a ticketing system, the ticket should be +part of the branch name. The ticketing system can be built into the repo +like GitHub issues or an external ticketing system. + +For GitHub issue #100 (a ticket to add a README file), the branch would be +called ``work/100-add-readme``. + +For an external ticketing system like Jira, a ticket labeled +``CRAFT-100`` would use a branch called ``work/CRAFT-100-add-readme``. + +``work/`` +###################### + +For any new features, bug fixes, and general work not driven by a ticketing +system. + +``hotfix/X.Y`` +############## + +For hotfixes to an existing minor release. + +For example, hotfixes for Testcraft 2.1 would go to a branch called +``hotfix/2.1``. + +As a departure from OneFlow, hotfix branches for \*craft applications can be +long-lived. This is because \*craft applications are built via Launchpad, +which uses build recipes that follow specific branches. + +After a tagged release of a hotfix branch, the branch should be merged back +to ``main``. + +``merge/`` +######################## + +For commits that merge another branch into the current branch. See the +`chore <#chore>`_ section for information on merge commit headers. + +``release/X.Y.Z`` +################# + +For commits that prepare for a release. These commits should update the +`changelog <#changelog>`_. + Commits ------- @@ -265,6 +340,21 @@ Example footers:: Signed-off-by: <> Co-authored-by: <> +Changelog +--------- + +The changelog is a reference documentation page that gives a human-readable +summary of changes to the project that are relevant to users. + +Each change should be clear in its purpose, whether it is fixing a bug, +adding a feature, or changing an existing behavior. + +Internal changes should not be included in the changelog. For example, +dev dependency updates, CI updates, and style changes should not +be included. + +The changelog should link to the project's GitHub releases page, which +contains an exhaustive list of all commits added to the release. .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ @@ -273,10 +363,12 @@ Example footers:: .. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa .. _`git submodules`: https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules .. _`Martin Fowler's definition`: https://refactoring.com/ +.. _OneFlow: https://www.endoflineblog.com/oneflow-a-git-branching-model-and-workflow .. _pre-commit: https://pre-commit.com/ .. _pyproject.toml: ./pyproject.toml .. _Pyright: https://github.com/microsoft/pyright .. _pytest: https://pytest.org +.. _`Renovate bot`: https://github.com/renovatebot/renovate .. _ruff: https://github.com/charliermarsh/ruff .. _ShellCheck: https://www.shellcheck.net/ .. _tox: https://tox.wiki From cd8da5576e5f8ecb7fe94f81558d2ffde88b20be Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 4 Jun 2024 14:25:32 -0400 Subject: [PATCH 195/333] ci: run tests on Ubuntu 24.04 (#214) https://github.com/actions/runner-images/issues/9848 --- .github/workflows/tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 16f6d0ae2e..4cf530d9ff 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -47,7 +47,7 @@ jobs: unit: strategy: matrix: - platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] + platform: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 @@ -87,7 +87,7 @@ jobs: integration: strategy: matrix: - platform: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest] + platform: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 From 77ce0886a41355b1d8e2b27b4802790320221e68 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 4 Jun 2024 14:25:54 -0400 Subject: [PATCH 196/333] ci: remove deprecated renovate config options (#215) --- .github/renovate.json5 | 14 +++++++------- .github/workflows/check-renovate.yaml | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 9c4bd55507..9dcf21417d 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -30,7 +30,7 @@ // Automerge patches, pin changes and digest changes. // Also groups these changes together. groupName: "bugfixes", - excludePackagePrefixes: ["lint", "types"], + excludeDepPatterns: ["lint/.*", "types/.*"], matchUpdateTypes: ["patch", "pin", "digest"], prPriority: 3, // Patches should go first! automerge: true @@ -38,7 +38,7 @@ { // Update all internal packages in one higher-priority PR groupName: "internal packages", - matchPackagePrefixes: ["craft-", "snap-"], + matchDepPatterns: ["craft-.*", "snap-.*"], matchLanguages: ["python"], prPriority: 2 }, @@ -59,10 +59,10 @@ // Minor changes can be grouped and automerged for dev dependencies, but are also deprioritised. groupName: "development dependencies (non-major)", groupSlug: "dev-dependencies", - matchPackagePrefixes: [ - "dev", - "lint", - "types" + matchDepPatterns: [ + "dev/.*", + "lint/.*", + "types/.*" ], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: -1, @@ -74,7 +74,7 @@ groupSlug: "doc-dependencies", matchPackageNames: ["Sphinx", "furo"], matchPackagePatterns: ["[Ss]phinx.*$"], - matchPackagePrefixes: ["docs"], + matchDepPatterns: ["docs/.*"], }, { // Other major dependencies get deprioritised below minor dev dependencies. diff --git a/.github/workflows/check-renovate.yaml b/.github/workflows/check-renovate.yaml index 8cf7d22a2d..8da9f2b938 100644 --- a/.github/workflows/check-renovate.yaml +++ b/.github/workflows/check-renovate.yaml @@ -33,3 +33,4 @@ jobs: run: renovate --dry-run --autodiscover env: RENOVATE_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RENOVATE_USE_BASE_BRANCH_CONFIG: ${{ github.ref }} From 7e0e9421ab48a2fa96d6ea2409ed23bfd4944cd0 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Thu, 6 Jun 2024 11:25:56 -0400 Subject: [PATCH 197/333] chore: add Jira sync (#219) --- .github/.jira_sync_config.yaml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/.jira_sync_config.yaml diff --git a/.github/.jira_sync_config.yaml b/.github/.jira_sync_config.yaml new file mode 100644 index 0000000000..10f6791072 --- /dev/null +++ b/.github/.jira_sync_config.yaml @@ -0,0 +1,22 @@ +settings: + components: + - Starbase + labels: + - Triaged + # Adds a comment with the JIRA ID + add_gh_comment: true + # Reflect changes on JIRA + sync_description: true + # Comments are synced from Github to JIRA + # Nothing goes from JIRA to Github + sync_comments: true + # epic_key: "MTC-296" + jira_project_key: "CRAFT" + status_mapping: + opened: Triaged + closed: done + label_mapping: + enhancement: Story + bug: Bug + spike: Spike + epic: Epic From b727837c37f1f317e2ae389bfcf1aeee30360fb0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 16:26:20 -0400 Subject: [PATCH 198/333] chore(deps): update dependency types/pyright to v1.1.366 (#220) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b210287f30..c7f30460d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.10.0", - "pyright==1.1.365", + "pyright==1.1.366", ] docs = [ "canonical-sphinx~=0.1", From 1d72f494647c57d9b30ab0301fb72faef050d6bb Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 12 Jun 2024 14:11:15 -0400 Subject: [PATCH 199/333] chore: update line length configuration (#221) --- .editorconfig | 7 +------ tox.ini | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.editorconfig b/.editorconfig index 6056a3e845..5a54b3ef2b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,7 +8,7 @@ end_of_line = lf indent_size = 4 indent_style = space insert_final_newline = true -max_line_length = 80 +max_line_length = 88 trim_trailing_whitespace = true [.editorconfig] @@ -29,15 +29,10 @@ indent_size = 2 max_line_length = off [{*.markdown,*.md,*.rst}] -max_line_length = off ij_visual_guides = none [{*.toml,Cargo.lock,Cargo.toml.orig,Gopkg.lock,Pipfile,poetry.lock}] max_line_length = off -[{*.ini, *.cfg}] -max_line_length = off - [{*.yaml,*.yml}] indent_size = 2 -max_line_length = off diff --git a/tox.ini b/tox.ini index 6b27f37c34..975273efed 100644 --- a/tox.ini +++ b/tox.ini @@ -147,4 +147,4 @@ base = docs labels = lint allowlist_externals = bash, xargs commands_pre = bash -c '{[lint-docs]find} > {env_tmp_dir}/lint_docs_files' -commands = xargs --no-run-if-empty --arg-file {env_tmp_dir}/lint_docs_files sphinx-lint --max-line-length 80 --enable all {posargs} +commands = xargs --no-run-if-empty --arg-file {env_tmp_dir}/lint_docs_files sphinx-lint --max-line-length 88 --enable all {posargs} From 3f3b5f6b1268e2365fb9746693aee88d33ea171e Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Wed, 10 Jul 2024 11:29:10 -0300 Subject: [PATCH 200/333] ci: update Release workflow (#224) This commit updates the Release workflow with the following changes: - Use self-hosted jammy machines instead of default Github runners; - Use PyPI's Trusted Publishers to publish, replacing the PYPI_API_TOKEN; - (minor) Constrain the artifacts that are attached to the Github release. --- .github/workflows/release-publish.yaml | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index 4d30ed0fb3..fc5fb390a6 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -11,18 +11,20 @@ permissions: jobs: source-wheel: - runs-on: ubuntu-latest + runs-on: [self-hosted, jammy] steps: - name: Checkout uses: actions/checkout@v4 - name: Fetch tag annotations run: | + # Note: we fetch the tags here instead of using actions/checkout's "fetch-tags" + # because of https://github.com/actions/checkout/issues/1467 git fetch --force --tags --depth 1 git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*' - name: Setup Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.10" check-latest: true - name: Build packages run: | @@ -36,7 +38,10 @@ jobs: path: dist/ pypi: needs: ["source-wheel"] - runs-on: ubuntu-latest + runs-on: [self-hosted, jammy] + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write steps: - name: Get packages uses: actions/download-artifact@v4 @@ -44,17 +49,22 @@ jobs: name: pypi-packages path: dist/ - name: Publish to pypi + # Note: this action uses PyPI's support for Trusted Publishers + # It needs a configuration on the PyPI project - see: + # https://docs.pypi.org/trusted-publishers/adding-a-publisher/#github-actions uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.PYPI_API_TOKEN }} github-release: needs: ["source-wheel"] - runs-on: ubuntu-latest + runs-on: [self-hosted, jammy] steps: - name: Get pypi artifacts uses: actions/download-artifact@v4 + with: + name: pypi-packages - name: Release uses: softprops/action-gh-release@v2 with: + # Add wheel and source tarball files: | - ** + *.whl + *.tar.gz From dacbdeba087ba777b0d9d2a02c7e7dd7870ca281 Mon Sep 17 00:00:00 2001 From: Callahan Date: Thu, 11 Jul 2024 07:44:23 -0500 Subject: [PATCH 201/333] docs(HACKING): add details on changelog convention (#225) Signed-off-by: Callahan Kovacs --- HACKING.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/HACKING.rst b/HACKING.rst index 27ff1ae165..1c3865c474 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -343,6 +343,9 @@ Example footers:: Changelog --------- +Scope +===== + The changelog is a reference documentation page that gives a human-readable summary of changes to the project that are relevant to users. @@ -353,9 +356,33 @@ Internal changes should not be included in the changelog. For example, dev dependency updates, CI updates, and style changes should not be included. +Style and format +================ + +Changes should be written in the imperative mood (present tense, second +person) similar to commit headers. + The changelog should link to the project's GitHub releases page, which contains an exhaustive list of all commits added to the release. +Release entries should be sorted by date from newest to oldest. + +Hotfixes +======== + +If an older version gets a hotfix release, subsequent releases should mention +when the hotfix is incorporated. + +For example, consider a package with a previous release ``2.9.0`` and a latest +release of ``3.0.0``. If the ``2.9.0`` receives a hotfix release ``2.9.1`` and +is merged back to ``main``, then the next ``3.x`` release should indicate that +it includes the changes from 2.9.1. + +.. note:: + + 3.0.1 includes changes from the 2.9.1 release. + + .. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ .. _Codespell: https://github.com/codespell-project/codespell From 36164586c1962db4b90fdda5f4d5c39517ec9785 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 15:43:10 -0400 Subject: [PATCH 202/333] chore(deps): update dependency types/pyright to v1.1.371 (#222) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c7f30460d3..9530a469d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.10.0", - "pyright==1.1.366", + "pyright==1.1.371", ] docs = [ "canonical-sphinx~=0.1", From 76fac3f72140923d4ccc9e88aa9cabde1d722046 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 15:46:55 -0400 Subject: [PATCH 203/333] chore(deps): update dependency tox-gh to v1.3.2 (#223) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 975273efed..be96236b66 100644 --- a/tox.ini +++ b/tox.ini @@ -18,7 +18,7 @@ requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 # renovate: datasource=pypi - tox-gh==1.3.1 + tox-gh==1.3.2 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From a90bcf78272a909f0f0dbb960c048968e05dd657 Mon Sep 17 00:00:00 2001 From: Matt Culler Date: Thu, 18 Jul 2024 10:29:03 -0400 Subject: [PATCH 204/333] docs: update hacking with explanation for exclamation point (#226) * docs: update hacking with explanation for exclamation point * Update HACKING.rst Co-authored-by: Alex Lowe --------- Co-authored-by: Alex Lowe --- HACKING.rst | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/HACKING.rst b/HACKING.rst index 1c3865c474..bc49c40233 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -167,11 +167,11 @@ Commits Commit messages are based on the `conventional commit`_ style:: - (): + [(optional scope)][!]: - + [optional body] - + [optional footer] The commit is divided into three sections: a header, body, and footer. @@ -297,6 +297,16 @@ class name. If a commit affects many areas of the codebase, the scope should be omitted; ``many`` is not an accepted scope. +Breaking changes +################ + +If an exclamation point (``!``) is inserted after the type/scope, this means +that the commit introduces a breaking change. Including one or more commits +with an exclamation point in a release will trigger a major version increment. + +Breaking changes may also be indicated by including the words ``BREAKING CHANGE`` +in the commit footer. + Description ########### From 73db57b1229d04839367640b5e7c868d0259113f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:22:22 -0400 Subject: [PATCH 205/333] chore(deps): update development dependencies (non-major) (#227) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9530a469d1..56ecc57933 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,8 +28,8 @@ lint = [ "yamllint~=1.34", ] types = [ - "mypy[reports]~=1.10.0", - "pyright==1.1.371", + "mypy[reports]~=1.11.0", + "pyright==1.1.372", ] docs = [ "canonical-sphinx~=0.1", From d88dde57927483cf6bd2adacea5860b5619642f1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 08:44:31 -0400 Subject: [PATCH 206/333] chore(deps): update dependency pyright to v1.1.375 (#234) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 56ecc57933..9b884391e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.372", + "pyright==1.1.375", ] docs = [ "canonical-sphinx~=0.1", From f97274517046856254c662c581068ee92f82da23 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 14 Aug 2024 08:44:54 -0400 Subject: [PATCH 207/333] ci: update renovate config and workflow (#232) Co-authored-by: Callahan --- .github/renovate.json5 | 51 +++++++++++++++++++++------ .github/workflows/check-renovate.yaml | 4 +++ 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 9dcf21417d..8342105f37 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,20 +1,22 @@ { // Configuration file for RenovateBot: https://docs.renovatebot.com/configuration-options - extends: ["config:base"], + extends: ["config:recommended", ":semanticCommitTypeAll(build)"], labels: ["dependencies"], // For convenient searching in GitHub + baseBranches: ["$default", "/^hotfix\\/.*/"], pip_requirements: { fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$", "^.pre-commit-config.yaml$"] }, packageRules: [ { // Internal package minor patch updates get top priority, with auto-merging - groupName: "internal package patch releases", + groupName: "internal package minor releases", matchPackagePatterns: ["^craft-.*"], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: 10, automerge: true, minimumReleaseAge: "0 seconds", schedule: ["at any time"], + matchBaseBranches: ["$default"], // Only do minor releases on main }, { // Same as above, but for hotfix branches, only for patch, and without auto-merging. @@ -24,7 +26,7 @@ prPriority: 10, minimumReleaseAge: "0 seconds", schedule: ["at any time"], - matchBaseBranches: ["/^hotfix/.*/"], // All hotfix branches + matchBaseBranches: ["/^hotfix\\/.*/"], // All hotfix branches }, { // Automerge patches, pin changes and digest changes. @@ -39,8 +41,9 @@ // Update all internal packages in one higher-priority PR groupName: "internal packages", matchDepPatterns: ["craft-.*", "snap-.*"], - matchLanguages: ["python"], - prPriority: 2 + matchCategories: ["python"], + prPriority: 2, + matchBaseBranches: ["$default"], // Not for hotfix branches }, { // GitHub Actions are higher priority to update than most dependencies since they don't tend to break things. @@ -64,6 +67,28 @@ "lint/.*", "types/.*" ], + matchPackagePatterns: [ + // Brought from charmcraft. May not be complete. + // This helps group dependencies in requirements-dev.txt files. + "^(.*/)?autoflake$", + "^(.*/)?black$", + "^(.*/)?codespell$", + "^(.*/)?coverage$", + "^(.*/)?flake8$", + "^(.*/)?hypothesis$", + "^(.*/)?mypy$", + "^(.*/)?pycodestyle$", + "^(.*/)?docstyle$", + "^(.*/)?pyfakefs$", + "^(.*/)?pyflakes$", + "^(.*/)?pylint$", + "^(.*/)?pytest", + "^(.*/)?responses$", + "^(.*/)?ruff$", + "^(.*/)?twine$", + "^(.*/)?tox$", + "^(.*/)?types-", + ], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: -1, automerge: true @@ -75,11 +100,13 @@ matchPackageNames: ["Sphinx", "furo"], matchPackagePatterns: ["[Ss]phinx.*$"], matchDepPatterns: ["docs/.*"], + matchBaseBranches: ["$default"], // Not for hotfix branches }, { // Other major dependencies get deprioritised below minor dev dependencies. matchUpdateTypes: ["major"], - prPriority: -2 + prPriority: -2, + matchBaseBranches: ["$default"], // Not for hotfix branches }, { // Major dev dependencies are stone last, but grouped. @@ -87,19 +114,22 @@ groupSlug: "dev-dependencies", matchDepTypes: ["devDependencies"], matchUpdateTypes: ["major"], - prPriority: -3 + prPriority: -3, + matchBaseBranches: ["$default"], // Not for hotfix branches }, { // Pyright makes regular breaking changes in patch releases, so we separate these // and do them independently. matchPackageNames: ["pyright", "types/pyright"], - prPriority: -4 + prPriority: -4, + matchBaseBranches: ["$default"], // Not for hotfix branches } ], - regexManagers: [ + customManagers: [ { // tox.ini can get updates too if we specify for each package. fileMatch: ["tox.ini"], + customType: "regex", depTypeTemplate: "devDependencies", matchStrings: [ "# renovate: datasource=(?\\S+)\n\\s+(?.*?)(\\[[\\w]*\\])*[=><]=?(?.*?)\n" @@ -108,6 +138,7 @@ { // .pre-commit-config.yaml version updates fileMatch: [".pre-commit-config.yaml"], + customType: "regex", datasourceTemplate: "pypi", depTypeTemplate: "lint", matchStrings: [ @@ -122,7 +153,7 @@ prCreation: "not-pending", // Wait until status checks have completed before raising the PR prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. prHourlyLimit: 1, // No more than 1 PR per hour. - stabilityDays: 2, // Wait 2 days from release before updating. + minimumReleaseAge: "2 days", automergeStrategy: "squash", // Squash & rebase when auto-merging. semanticCommitType: "build" // use `build` as commit header type (i.e. `build(deps): `) } diff --git a/.github/workflows/check-renovate.yaml b/.github/workflows/check-renovate.yaml index 8da9f2b938..7d13cfbf21 100644 --- a/.github/workflows/check-renovate.yaml +++ b/.github/workflows/check-renovate.yaml @@ -20,6 +20,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Install node + uses: actions/setup-node@v4 + with: + node-version: 22 - name: Install renovate run: npm install --global renovate - name: Enable ssh access From 6bfb9692056cec85b7aeca04348708d366ad4778 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 27 Aug 2024 11:07:29 -0400 Subject: [PATCH 208/333] style: autoformat with ruff 0.6 (#238) --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 9bceb63b06..587f0eba4b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,7 +16,7 @@ import pytest -@pytest.fixture() +@pytest.fixture def project_main_module() -> types.ModuleType: """Fixture that returns the project's principal package (imported). From 2439a13a3394492ff85d04c4afcc8bc28f7e86f2 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 30 Aug 2024 09:19:48 -0400 Subject: [PATCH 209/333] style(lint): autoformat (#239) From e2f3adfb576690f27644b3d845bef4a2c8caa1fd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 12:44:10 -0400 Subject: [PATCH 210/333] build(deps): update dependency pyright to v1.1.378 (#241) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9b884391e8..1ae184448e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.375", + "pyright==1.1.378", ] docs = [ "canonical-sphinx~=0.1", From 6b7fa704c68c6f7240cf41db6508430c24b5ca0c Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 6 Sep 2024 09:59:15 -0400 Subject: [PATCH 211/333] ci(renovate): enable pre-commit support (#242) --- .github/renovate.json5 | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 8342105f37..2a7d63671e 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,10 +1,10 @@ { // Configuration file for RenovateBot: https://docs.renovatebot.com/configuration-options - extends: ["config:recommended", ":semanticCommitTypeAll(build)"], + extends: ["config:recommended", ":semanticCommitTypeAll(build)", ":enablePreCommit"], labels: ["dependencies"], // For convenient searching in GitHub baseBranches: ["$default", "/^hotfix\\/.*/"], pip_requirements: { - fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$", "^.pre-commit-config.yaml$"] + fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$"] }, packageRules: [ { @@ -135,16 +135,6 @@ "# renovate: datasource=(?\\S+)\n\\s+(?.*?)(\\[[\\w]*\\])*[=><]=?(?.*?)\n" ] }, - { - // .pre-commit-config.yaml version updates - fileMatch: [".pre-commit-config.yaml"], - customType: "regex", - datasourceTemplate: "pypi", - depTypeTemplate: "lint", - matchStrings: [ - "- repo: .*/<(?\\S+)\\s*\\n\\s*rev:\s+\"?v?(?\\S*)\"?", - ] - } ], timezone: "Etc/UTC", schedule: ["every weekend"], From 38e8a726ec22e5206ffdaac1a1bdbfccf6ac54f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 8 Sep 2024 08:33:44 -0400 Subject: [PATCH 212/333] build(deps): update dependency pyright to v1.1.379 (#243) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1ae184448e..35fb7ed1bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.378", + "pyright==1.1.379", ] docs = [ "canonical-sphinx~=0.1", From 82d7be8ece55ca07476fb325058d8255bd933919 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 8 Sep 2024 08:37:12 -0400 Subject: [PATCH 213/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.6.4 (#245) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f84e07acdc..14a369fb67 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.15" + rev: "v0.6.4" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 96d6635ea7878db1d699bd15d493867027440973 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 8 Sep 2024 08:38:12 -0400 Subject: [PATCH 214/333] build(deps): update pre-commit hook adrienverge/yamllint to v1.35.1 (#244) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 14a369fb67..7166a7896e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,6 +22,6 @@ repos: hooks: - id: black - repo: https://github.com/adrienverge/yamllint.git - rev: "v1.33.0" + rev: "v1.35.1" hooks: - id: yamllint From 33279004921b6e3c6010222a0fe40e7f29c996a2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:39:16 -0400 Subject: [PATCH 215/333] build(deps): update pre-commit hook psf/black to v24.8.0 (#247) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7166a7896e..d728276a91 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black - rev: "24.1.1" + rev: "24.8.0" hooks: - id: black - repo: https://github.com/adrienverge/yamllint.git From 4ff207679e7401c3bb57a6de9939a3359ab7f9a0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:39:42 -0400 Subject: [PATCH 216/333] build(deps): update pre-commit hook pre-commit/pre-commit-hooks to v4.6.0 (#246) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d728276a91..3dac59daf9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: "v4.4.0" + rev: "v4.6.0" hooks: - id: trailing-whitespace - id: end-of-file-fixer From afb80d1af97fcfe485cdd6b37d098bb79dd145bb Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 13 Sep 2024 20:09:01 -0400 Subject: [PATCH 217/333] chore(renovate): fewer PRs to hotfix branches (#237) Renovate should only PR to hotfix branches for non-dev patch updates. --- .github/renovate.json5 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 2a7d63671e..a6959ddffd 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -32,7 +32,11 @@ // Automerge patches, pin changes and digest changes. // Also groups these changes together. groupName: "bugfixes", - excludeDepPatterns: ["lint/.*", "types/.*"], + excludeDepPatterns: [ + "lint/.*", + "types/.*", + "pyright", // Pyright needs to be done separately. + ], matchUpdateTypes: ["patch", "pin", "digest"], prPriority: 3, // Patches should go first! automerge: true @@ -57,6 +61,7 @@ //Do all pydantic-related updates together groupName: "pydantic etc.", matchPackagePatterns: ["^pydantic"], + matchBaseBranches: ["$default"], // Only do minor releases on main }, { // Minor changes can be grouped and automerged for dev dependencies, but are also deprioritised. @@ -91,7 +96,8 @@ ], matchUpdateTypes: ["minor", "patch", "pin", "digest"], prPriority: -1, - automerge: true + automerge: true, + matchBaseBranches: ["$default"], // Not for hotfix branches }, { // Documentation related updates From b1ac98026f6bacce34474d45a086845f4f4d473a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 08:05:31 -0400 Subject: [PATCH 218/333] build(deps): update dependency pyright to v1.1.380 (#249) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 35fb7ed1bc..4ec1a88734 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.379", + "pyright==1.1.380", ] docs = [ "canonical-sphinx~=0.1", From 197eaf7820989e32b3d831fd9e96175ce9060904 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 08:07:45 -0400 Subject: [PATCH 219/333] build(deps): update dependency sphinx-lint to v1 (#250) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4ec1a88734..7c50e13886 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ docs = [ "sphinx-autobuild~=2024.2", "sphinx-pydantic==0.1.1", "sphinx-toolbox~=3.5", - "sphinx-lint==0.9.1", + "sphinx-lint==1.0.0", ] [build-system] From ce9ccb99d7594415c293ffdf349f087469536b56 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 08:11:48 -0400 Subject: [PATCH 220/333] build(deps): update dependency tox-gh to v1.3.3 (#248) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index be96236b66..f951b6ebb7 100644 --- a/tox.ini +++ b/tox.ini @@ -18,7 +18,7 @@ requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 # renovate: datasource=pypi - tox-gh==1.3.2 + tox-gh==1.3.3 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From e4faa8c17ddaad2cabddb83fdbd1c5333d7e7a72 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 18:32:13 -0400 Subject: [PATCH 221/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.6.5 (#251) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3dac59daf9..c797584def 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.4" + rev: "v0.6.5" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 4525894020b7768615b1712e0193b2646ea2efa6 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Tue, 17 Sep 2024 11:22:37 -0400 Subject: [PATCH 222/333] build(tools): add a Makefile that uses uv (#240) --- .gitignore | 1 + Makefile | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 16 +++++++- 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 Makefile diff --git a/.gitignore b/.gitignore index 4cb5044769..289a38a0d6 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ coverage.xml *.py,cover .hypothesis/ .pytest_cache/ +.results.*.xml # Translations *.mo diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..6dcafe44b6 --- /dev/null +++ b/Makefile @@ -0,0 +1,106 @@ +PROJECT=starcraft +SOURCES=$(wildcard *.py) $(PROJECT) tests +DOCS=docs + +ifneq ($(OS),Windows_NT) + OS := $(shell uname) +endif + +.PHONY: help +help: ## Show this help. + @printf "%-30s %s\n" "Target" "Description" + @printf "%-30s %s\n" "------" "-----------" + @fgrep " ## " $(MAKEFILE_LIST) | fgrep -v grep | awk -F ': .*## ' '{$$1 = sprintf("%-30s", $$1)} 1' + +.PHONY: setup +setup: ## Set up a development environment +ifeq ($(OS),Linux) + sudo snap install codespell ruff shellcheck + sudo snap install --classic --beta astral-uv + sudo snap alias astral-uv.uv uv + sudo snap alias astral-uv.uvx uvx +else ifeq ($(OS),Windows_NT) + pipx install uv + choco install shellcheck +else ifeq ($(OS),Darwin) + brew install uv + brew install shellcheck +endif +ifneq ($(OS),Linux) + uv tool install codespell + uv tool install ruff + uv tool update-shell +endif + +.PHONY: setup-pre-commit +setup-precommit: ## Set up pre-commit hooks in this repository. +ifeq (, $(shell which pre-commit)) + uv tool install pre-commit +endif + pre-commit install + +.PHONY: autoformat +autoformat: format-ruff format-codespell ## Run all automatic formatters + +.PHONY: lint +lint: lint-ruff lint-codespell lint-mypy lint-pyright lint-shellcheck lint-yaml lint-docs ## Run all linters + +.PHONY: test +test: test-unit test-integration ## Run all tests + +.PHONY: docs +docs: ## Build documentation + uv run --extra docs sphinx-build -b html -W docs docs/_build + +.PHONY: docs-auto +docs-auto: ## Build and host docs with sphinx-autobuild + uv run --extra docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W docs docs/_build + +# Helpful in `help` to split the main targets from things that build +---------------- : ## ---------------- + +.PHONY: format-codespell +format-codespell: ## Fix spelling issues with codespell + uv run codespell --toml pyproject.toml --write-changes $(SOURCES) + +.PHONY: format-ruff +format-ruff: ## Automatically format with ruff + ruff format $(SOURCES) + ruff check --fix $(SOURCES) + +.PHONY: lint-codespell +lint-codespell: ## Check spelling with codespell + uv run codespell --toml pyproject.toml $(SOURCES) + +.PHONY: lint-docs +lint-docs: ## Lint the documentation + uv run --extra docs sphinx-lint --max-line-length 80 --enable all $(DOCS) + +.PHONY: lint-mypy +lint-mypy: ## Check types with mypy + uv run mypy $(SOURCES) + +.PHONY: lint-pyright +lint-pyright: ## Check types with pyright + uv run pyright + +.PHONY: lint-ruff +lint-ruff: ## Lint with ruff + ruff format --diff $(SOURCES) + ruff check $(SOURCES) + +.PHONY: lint-shellcheck +lint-shellcheck: + sh -c 'git ls-files | file --mime-type -Nnf- | grep shellscript | cut -f1 -d: | xargs -r shellcheck' + +.PHONY: lint-yaml +lint-yaml: ## Lint YAML files with yamllint + uv run yamllint . + +.PHONY: test-unit +test-unit: ## Run unit tests + uv run pytest --cov=$(PROJECT) --cov-config=pyproject.toml --cov-report=xml:.coverage.unit.xml --junit-xml=.results.unit.xml tests/unit + +.PHONY: test-integration +test-integration: ## Run integration tests + uv run pytest --cov=$(PROJECT) --cov-config=pyproject.toml --cov-report=xml:.coverage.integration.xml --junit-xml=.results.integration.xml tests/integration diff --git a/pyproject.toml b/pyproject.toml index 7c50e13886..0267f1fab0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,21 @@ docs = [ "sphinx-lint==1.0.0", ] +[tool.uv] +dev-dependencies = [ + "build", + "coverage[toml]~=7.4", + "pytest~=8.0", + "pytest-cov~=5.0", + "pytest-mock~=3.12", + "yamllint~=1.34", + "mypy[reports]~=1.11.0", + "pyright==1.1.375", + "types-Pygments", + "types-colorama", + "types-setuptools", +] + [build-system] requires = [ "setuptools>=69.0", @@ -118,7 +133,6 @@ exclude = [ python_version = "3.10" exclude = [ "build", - "tests", "results", ] warn_unused_configs = true From 6e8f8a94259aedacf0c769f3ddcefb3bc7a94014 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Sep 2024 09:37:10 -0400 Subject: [PATCH 223/333] build(deps): update dependency tox-gh to v1.4.1 (#255) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index f951b6ebb7..b101421e41 100644 --- a/tox.ini +++ b/tox.ini @@ -18,7 +18,7 @@ requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 # renovate: datasource=pypi - tox-gh==1.3.3 + tox-gh==1.4.1 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From b8a847ee29cffbd0bbb3c4b072589660c489fa4b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Sep 2024 09:39:53 -0400 Subject: [PATCH 224/333] build(deps): update dependency pyright to v1.1.381 (#254) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0267f1fab0..bec0dacae8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.380", + "pyright==1.1.381", ] docs = [ "canonical-sphinx~=0.1", @@ -48,7 +48,7 @@ dev-dependencies = [ "pytest-mock~=3.12", "yamllint~=1.34", "mypy[reports]~=1.11.0", - "pyright==1.1.375", + "pyright==1.1.381", "types-Pygments", "types-colorama", "types-setuptools", From 1567d4abe3793b767465f4d05e6901ece25c8cd8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:16:38 -0400 Subject: [PATCH 225/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.6.6 (#256) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c797584def..cb97a12e6d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.5" + rev: "v0.6.6" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 7d2790e71c9fc67c843e8a5dbcac38d8ec4d984a Mon Sep 17 00:00:00 2001 From: Michael DuBelko Date: Tue, 24 Sep 2024 16:19:18 -0700 Subject: [PATCH 226/333] docs: update readme and template, fix build error (#258) - Clarify the wording in the README, add more details about preparing the docs. - Disable PDF and EPUB generation. We can re-enable this later when we rebase the docs and those builds are working again. --- .readthedocs.yaml | 8 ++++---- README.rst | 31 ++++++++++++++++++------------- docs/index.rst | 2 +- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index fb58117028..190297fcae 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -10,12 +10,12 @@ sphinx: configuration: docs/conf.py # Optionally build your docs in additional formats such as PDF -formats: - - pdf - - epub +#formats: +# - pdf +# - epub build: - os: ubuntu-22.04 + os: ubuntu-24.04 tools: python: "3" diff --git a/README.rst b/README.rst index 5c5c87e31d..f76695c9fa 100644 --- a/README.rst +++ b/README.rst @@ -2,37 +2,42 @@ starbase ******** -A base repository for Starcraft projects. +The base repository for Starcraft projects. Description ----------- -This project is designed to act as the basis for any future starcraft projects -as well as a testbed for any tooling changes we want to make before merging -them into other projects. +This template code is the basis for all future starcraft projects, and acts as +the testbed for any major tooling changes that we want to make before +propagating them across all projects. Structure --------- TODO -How to migrate existing projects +Migrate existing projects -------------------------------- TODO -How to create a new project +Create a new project --------------------------- [TODO: Make this a template repository.] #. `Use this template`_ to create your repository. #. Ensure the ``LICENSE`` file represents the current best practices from the - Canonical legal team for the specific project you intend to release. (LGPL v3 - for libraries, GPL v3 for applications.) + Canonical legal team for the specific project you intend to release. We use + LGPL v3 for libraries, and GPL v3 for apps. #. Rename any files or directories and ensure references are updated. -#. Replace any appropriate ``starcraft`` references with the appropriate name. -#. Put correct contact information into CODE_OF_CONDUCT.md -#. Write a new README -#. Import your documentation to ReadTheDocs_. +#. Replace any instances of the word ``Starcraft`` with the product's name. +#. Place contact information in a code of conduct. +#. Rewrite the README. +#. If a Diataxis quadrant (tutorials, how-tos, references, explanations) + doesn't yet have content, remove its landing page from the TOC and delete + its card in ``docs/index.rst``. You can re-index it when at least one + document has been produced for it. +#. Register the product's documentation on our custom domain on `Read the + Docs for Business`_. .. _EditorConfig: https://editorconfig.org/ .. _pre-commit: https://pre-commit.com/ -.. _ReadTheDocs: https://docs.readthedocs.io/en/stable/intro/import-guide.html +.. _Read the Docs for Business: https://library.canonical.com/documentation/publish-on-read-the-docs .. _use this template: https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template diff --git a/docs/index.rst b/docs/index.rst index 0edd1e08eb..71f76626e4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,6 +1,6 @@ .. starcraft documentation root file -StarCraft +Starcraft ========= .. toctree:: From 76f2dbd0dcee5b0dfee6107b3ebf659d529e61df Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 27 Sep 2024 14:42:39 -0400 Subject: [PATCH 227/333] docs(readme): add badges (#203) Fixes #180 --- README.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.rst b/README.rst index f76695c9fa..0f173e41b8 100644 --- a/README.rst +++ b/README.rst @@ -1,3 +1,12 @@ +|Release| |Documentation| |test| + +.. |Release| image:: https://github.com/canonical/starbase/actions/workflows/release-publish.yaml/badge.svg?branch=main&event=push + :target: https://github.com/canonical/starbase/actions/workflows/release-publish.yaml +.. |Documentation| image:: https://github.com/canonical/starbase/actions/workflows/docs.yaml/badge.svg?branch=main&event=push + :target: https://github.com/canonical/starbase/actions/workflows/docs.yaml +.. |test| image:: https://github.com/canonical/starbase/actions/workflows/tests.yaml/badge.svg?branch=main&event=push + :target: https://github.com/canonical/starbase/actions/workflows/tests.yaml + ******** starbase ******** From 59e5c4b5ad72e3c5c8f3b94b63b2691961fbfcf5 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Fri, 27 Sep 2024 21:41:59 -0400 Subject: [PATCH 228/333] ci: add security scan workflow (#259) * ci: add security scan workflow * chore: update for merge --- .github/workflows/security-scan.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/security-scan.yaml diff --git a/.github/workflows/security-scan.yaml b/.github/workflows/security-scan.yaml new file mode 100644 index 0000000000..459d7e554a --- /dev/null +++ b/.github/workflows/security-scan.yaml @@ -0,0 +1,13 @@ +name: Security scan +on: + pull_request: + push: + branches: + - main + - hotfix/* + - work/secscan # For development + +jobs: + python-scans: + name: Scan Python project + uses: canonical/starflow/.github/workflows/scan-python.yaml@main From 42d6514d6389e793e6fe63b1e0fd825833d98eae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 11:00:17 -0400 Subject: [PATCH 229/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.6.8 (#263) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cb97a12e6d..990063e1ba 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.6" + rev: "v0.6.8" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 5e9c9eb5c489538a30344bf2016b47869049a739 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 11:18:34 -0400 Subject: [PATCH 230/333] build(deps): update dependency pyright to v1.1.382.post1 (#264) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bec0dacae8..1dcf7d66db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.381", + "pyright==1.1.382.post1", ] docs = [ "canonical-sphinx~=0.1", @@ -48,7 +48,7 @@ dev-dependencies = [ "pytest-mock~=3.12", "yamllint~=1.34", "mypy[reports]~=1.11.0", - "pyright==1.1.381", + "pyright==1.1.382.post1", "types-Pygments", "types-colorama", "types-setuptools", From 1327ca6ab5a474ad56dcb6128cb51e26f8641b68 Mon Sep 17 00:00:00 2001 From: Callahan Date: Fri, 4 Oct 2024 07:38:12 -0500 Subject: [PATCH 231/333] docs: update commit headers for merges (#266) Signed-off-by: Callahan Kovacs --- HACKING.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HACKING.rst b/HACKING.rst index bc49c40233..929394c7fe 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -258,10 +258,10 @@ Examples include: * type changes * accommodating a developer-facing deprecation warning * many *small* fixes for an existing PR -* merge commits (``chore(merge): '' into ''``) +* merge commits (``chore(merge): into ``) - * the remote name should not be included (i.e. use ``'main'`` - instead of ``'origin/main'``) + * the remote name should not be included (for example, use ``main`` + instead of ``origin/main``) Choosing the right type """"""""""""""""""""""" From e4b6130babe31c25ff0b2b4f060232c385740830 Mon Sep 17 00:00:00 2001 From: Matt Culler Date: Fri, 4 Oct 2024 19:18:20 -0400 Subject: [PATCH 232/333] feat: port sphinx fixes (#267) https://github.com/canonical/craft-application/commit/8b2b8f36cab1f42d2b6f8d46d109edbd18fba08d#diff-8d068e8797e88947c320f79e856c3e16a72b730124a8f9d7031e2c4680dfa534R18 Co-authored-by: Alex Lowe --- docs/index.rst | 26 +++++++++----------------- pyproject.toml | 2 +- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 71f76626e4..2a3ef9f65c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,26 +12,18 @@ Starcraft reference/index explanation/index -.. grid:: 1 1 2 2 - .. grid-item-card:: :ref:`Tutorial ` +.. list-table:: - **Get started** with a hands-on introduction to Starcraft + * - | :ref:`Tutorial ` + | **Get started** with a hands-on introduction to Starcraft + * - | :ref:`How-to guides ` + | **Step-by-step guides** covering key operations and common tasks + * - | :ref:`Reference ` + | **Technical information** about Starcraft + * - | :ref:`Explanation ` + | **Discussion and clarification** of key topics - .. grid-item-card:: :ref:`How-to guides ` - - **Step-by-step guides** covering key operations and common tasks - -.. grid:: 1 1 2 2 - :reverse: - - .. grid-item-card:: :ref:`Reference ` - - **Technical information** about Starcraft - - .. grid-item-card:: :ref:`Explanation ` - - **Discussion and clarification** of key topics Project and community ===================== diff --git a/pyproject.toml b/pyproject.toml index 1dcf7d66db..cde6ccf8d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ types = [ "pyright==1.1.382.post1", ] docs = [ - "canonical-sphinx~=0.1", + "canonical-sphinx~=0.2.0", "sphinx-autobuild~=2024.2", "sphinx-pydantic==0.1.1", "sphinx-toolbox~=3.5", From 53a7bae91f14ae801511fde512b94dbe17712781 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 5 Oct 2024 09:12:10 -0400 Subject: [PATCH 233/333] build(deps): update dependency pyright to v1.1.383 (#268) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cde6ccf8d6..d76a0c2e44 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.382.post1", + "pyright==1.1.383", ] docs = [ "canonical-sphinx~=0.2.0", @@ -48,7 +48,7 @@ dev-dependencies = [ "pytest-mock~=3.12", "yamllint~=1.34", "mypy[reports]~=1.11.0", - "pyright==1.1.382.post1", + "pyright==1.1.383", "types-Pygments", "types-colorama", "types-setuptools", From 84c2a0e490d8129ec21c8f031c2afd6ce435169c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 6 Oct 2024 18:05:48 -0400 Subject: [PATCH 234/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.6.9 (#269) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 990063e1ba..cd6d355ae0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.8" + rev: "v0.6.9" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 44ce0810d3faa75e4d7db1bfacc8606dd35d2590 Mon Sep 17 00:00:00 2001 From: Matt Culler Date: Fri, 11 Oct 2024 16:07:31 -0400 Subject: [PATCH 235/333] feat: upstream the good parts when rebasing application (#265) * feat: upstream good parts from Makefile/pyproject * feat(docs): add start of migration instructions * fix: remove unused variable * fix: need to set variable to keep uv from complaining * feat: python-apt launchpad dep in pyproject.toml * feat: more upstreaming - Compared .gitignores and added things from my application. - Removed redundant black things in hook file. - Ruff format should be after check, as sometimes check's output needs to be formatted, but format's output shouldn't need to be checked. - Updated refactor instructions. - Updated ruff excludes. - Helped pyright's type checking. * Apply suggestions from code review Co-authored-by: Alex Lowe * fix: Alex's PR review * feat(Makefile): upstream coverage target * feat(docs): update readme with integration test info * feat: upstream minor tests workflow things * fix: uv snap has added aliases and doesn't need beta * docs: finishing touches on rebase instructions * fix: the uv.lock file is supposed to be checked in * feat(docs): make targets called out per @lengau, add update note * Apply suggestions from code review * fix(Makefile): upstream npm pyright bugfix * fix: add in the ruff formatter, per @dariuszd21 * fix: don't shellcheck everything that gets sourced * Update Makefile Co-authored-by: Dariusz Duda * feat(docs): add note about merging * feat: allow installing snaps in parallel Co-authored-by: Alex Lower * Update Makefile * fix: Darius pointed out that ruff excludes via .gitignore * fix: `--respect-gitignore` is the default --------- Co-authored-by: Alex Lowe Co-authored-by: Dariusz Duda --- .github/workflows/tests.yaml | 13 +++- .gitignore | 3 + .pre-commit-config.yaml | 7 +- .shellcheckrc | 0 Makefile | 134 +++++++++++++++++++++++------------ README.rst | 59 ++++++++++++++- pyproject.toml | 9 ++- tox.ini | 4 +- 8 files changed, 169 insertions(+), 60 deletions(-) create mode 100644 .shellcheckrc diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 4cf530d9ff..0879ee0ade 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -9,11 +9,16 @@ on: - "renovate/*" pull_request: +# Cancel currently-running builds when pushing new commits to a PR or branch +# https://stackoverflow.com/a/72408109 +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true jobs: lint: runs-on: ubuntu-latest steps: - - name: Checkout + - name: Check out code uses: actions/checkout@v4 with: fetch-depth: 0 @@ -42,7 +47,7 @@ jobs: echo "::group::Wait for snap to complete" snap watch --last=install echo "::endgroup::" - - name: Run Linters + - name: Run linters run: tox run --skip-pkg-install --no-list-dependencies --colored yes -m lint unit: strategy: @@ -50,7 +55,8 @@ jobs: platform: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v4 + - name: Check out code + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python @@ -90,6 +96,7 @@ jobs: platform: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest] runs-on: ${{ matrix.platform }} steps: + - name: Check out code - uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.gitignore b/.gitignore index 289a38a0d6..0aaac198e9 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ share/python-wheels/ *.egg-info/ .installed.cfg *.egg +*.snap MANIFEST # PyInstaller @@ -71,6 +72,7 @@ instance/ # Sphinx documentation docs/_build/ +docs/spelling/ # PyBuilder target/ @@ -103,6 +105,7 @@ celerybeat.pid *.sage.py # Environments +.direnv .env .venv env/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cd6d355ae0..50e6d3df6d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,12 +15,11 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: "v0.6.9" hooks: + # Run the linter - id: ruff args: [--fix, --exit-non-zero-on-fix] - - repo: https://github.com/psf/black - rev: "24.8.0" - hooks: - - id: black + # Run the formatter + - id: ruff-format - repo: https://github.com/adrienverge/yamllint.git rev: "v1.35.1" hooks: diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Makefile b/Makefile index 6dcafe44b6..01eb849b11 100644 --- a/Makefile +++ b/Makefile @@ -6,19 +6,44 @@ ifneq ($(OS),Windows_NT) OS := $(shell uname) endif +.DEFAULT_GOAL := help + +.ONESHELL: + +.SHELLFLAGS = -ec + .PHONY: help help: ## Show this help. - @printf "%-30s %s\n" "Target" "Description" - @printf "%-30s %s\n" "------" "-----------" - @fgrep " ## " $(MAKEFILE_LIST) | fgrep -v grep | awk -F ': .*## ' '{$$1 = sprintf("%-30s", $$1)} 1' + @printf "%-41s %s\n" "Target" "Description" + @printf "%-41s %s\n" "------" "-----------" + @fgrep " ##" $(MAKEFILE_LIST) | fgrep -v grep | sed 's/:[^#]*/ /' | awk -F '[: ]*' \ + '{ + if ($$2 == "##") + { + $$1=sprintf("%-40s", $$1); + $$2=""; + print $$0; + } + else + { + $$1=sprintf(" â””%-38s", $$1); + $$2=""; + print $$0; + } + }' + +---------------- : ## ---------------- .PHONY: setup setup: ## Set up a development environment ifeq ($(OS),Linux) - sudo snap install codespell ruff shellcheck - sudo snap install --classic --beta astral-uv - sudo snap alias astral-uv.uv uv - sudo snap alias astral-uv.uvx uvx + changes="`sudo snap install --no-wait codespell`" + changes="${changes} `sudo snap install --no-wait ruff`" + changes="${changes} `sudo snap install --no-wait shellcheck`" + changes="${changes} `sudo snap install --classic --no-wait astral-uv`" + for change in ${changes}; do + snap watch ${change} + done else ifeq ($(OS),Windows_NT) pipx install uv choco install shellcheck @@ -39,68 +64,87 @@ ifeq (, $(shell which pre-commit)) endif pre-commit install +---------------- : ## ---------------- + .PHONY: autoformat autoformat: format-ruff format-codespell ## Run all automatic formatters -.PHONY: lint -lint: lint-ruff lint-codespell lint-mypy lint-pyright lint-shellcheck lint-yaml lint-docs ## Run all linters - -.PHONY: test -test: test-unit test-integration ## Run all tests - -.PHONY: docs -docs: ## Build documentation - uv run --extra docs sphinx-build -b html -W docs docs/_build +.PHONY: format-ruff +format-ruff: ##- Automatically format with ruff + ruff check --fix $(SOURCES) + success=true + ruff check --fix $(SOURCES) || success=false + ruff format $(SOURCES) + $success || exit 1 -.PHONY: docs-auto -docs-auto: ## Build and host docs with sphinx-autobuild - uv run --extra docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W docs docs/_build +.PHONY: format-codespell +format-codespell: ##- Fix spelling issues with codespell + uv run codespell --toml pyproject.toml --write-changes $(SOURCES) -# Helpful in `help` to split the main targets from things that build ---------------- : ## ---------------- -.PHONY: format-codespell -format-codespell: ## Fix spelling issues with codespell - uv run codespell --toml pyproject.toml --write-changes $(SOURCES) +.PHONY: lint +lint: lint-ruff lint-codespell lint-mypy lint-pyright lint-shellcheck lint-yaml lint-docs ## Run all linters -.PHONY: format-ruff -format-ruff: ## Automatically format with ruff - ruff format $(SOURCES) - ruff check --fix $(SOURCES) +.PHONY: lint-ruff +lint-ruff: ##- Lint with ruff + ruff check $(SOURCES) + ruff format --diff $(SOURCES) .PHONY: lint-codespell -lint-codespell: ## Check spelling with codespell +lint-codespell: ##- Check spelling with codespell uv run codespell --toml pyproject.toml $(SOURCES) -.PHONY: lint-docs -lint-docs: ## Lint the documentation - uv run --extra docs sphinx-lint --max-line-length 80 --enable all $(DOCS) - .PHONY: lint-mypy -lint-mypy: ## Check types with mypy - uv run mypy $(SOURCES) +lint-mypy: ##- Check types with mypy + uv run mypy --show-traceback --show-error-codes $(SOURCES) .PHONY: lint-pyright -lint-pyright: ## Check types with pyright +lint-pyright: ##- Check types with pyright + # Fix for a bug in npm + [ -d "/home/ubuntu/.npm/_cacache" ] && chown -R 1000:1000 "/home/ubuntu/.npm" || true uv run pyright -.PHONY: lint-ruff -lint-ruff: ## Lint with ruff - ruff format --diff $(SOURCES) - ruff check $(SOURCES) - .PHONY: lint-shellcheck -lint-shellcheck: - sh -c 'git ls-files | file --mime-type -Nnf- | grep shellscript | cut -f1 -d: | xargs -r shellcheck' +lint-shellcheck: ##- Lint shell scripts + git ls-files | file --mime-type -Nnf- | grep shellscript | cut -f1 -d: | xargs -r shellcheck .PHONY: lint-yaml -lint-yaml: ## Lint YAML files with yamllint +lint-yaml: ##- Lint YAML files with yamllint uv run yamllint . +.PHONY: lint-docs +lint-docs: ##- Lint the documentation + uv run --extra docs sphinx-lint --max-line-length 88 --enable all $(DOCS) + +---------------- : ## ---------------- + +.PHONY: test +test: test-unit test-integration ## Run all tests + .PHONY: test-unit -test-unit: ## Run unit tests +test-unit: ##- Run unit tests uv run pytest --cov=$(PROJECT) --cov-config=pyproject.toml --cov-report=xml:.coverage.unit.xml --junit-xml=.results.unit.xml tests/unit .PHONY: test-integration -test-integration: ## Run integration tests +test-integration: ##- Run integration tests uv run pytest --cov=$(PROJECT) --cov-config=pyproject.toml --cov-report=xml:.coverage.integration.xml --junit-xml=.results.integration.xml tests/integration + +---------------- : ## ---------------- + +.PHONY: coverage +coverage: ## Generate coverage report + coverage run --source starcraft -m pytest + coverage xml -o coverage.xml + coverage report -m + coverage html + +---------------- : ## ---------------- + +.PHONY: docs +docs: ## Build documentation + uv run --extra docs sphinx-build -b html -W docs docs/_build + +.PHONY: docs-auto +docs-auto: ## Build and host docs with sphinx-autobuild + uv run --extra docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W docs docs/_build diff --git a/README.rst b/README.rst index 0f173e41b8..bd323ab482 100644 --- a/README.rst +++ b/README.rst @@ -25,7 +25,64 @@ TODO Migrate existing projects -------------------------------- -TODO +#. Update this guide as you go along, if something is unclear or missing. +#. Use ruff. + #. Pull in the bare minimum ``pyproject.toml`` needed to use ruff. + #. Make your codebase pass with ruff. Commit after each step: + #. ``ruff check --fix`` + #. ``ruff check --fix --unsafe-fixes`` + #. ``ruff check --add-noqa`` + #. ``ruff format`` + #. Replace use of black, flake8, pydocstyle, isort, and pylint in Makefile/CI + with: + - ``ruff check --fix`` + - ``ruff format`` +#. Modify top-level files in your project to match what's in Starbase as closely + as possible. + #. ``Makefile`` - Ensure you use ``uv`` and at least have the same targets: + - ``setup`` + - ``lint`` + - ``test-unit`` + - ``test-integration`` (If this applies to your repo, i.e. the repo is a library + rather than an application) + - ``coverage`` + #. ``pyproject.toml`` - Expand from just the ruff things: move things into + here from your ``setup.py``, ``setup.cfg``, and ``requirements.*.txt``. + #. ``README`` - If your readme is .md, convert to .rst with pandoc: + ``pandoc -o README.rst README.md`` + Don't worry about making the contents match, Starbase's is very specific. +#. Run all the linters: ``make lint`` + #. ``mypy``: + - Mypy checks the same things as ``ruff``'s ``ANNXXX`` checks, but + ``ruff``'s ``noqa`` directives mean nothing to mypy. You'll need to fix + these by hand, mostly by adding type annotations to function definitions. + #. ``pyright``: + - For errors along the lines of "Stub file not found for $library", check + for the existence of pip package ``typing-$library`` and add it as a + dependency. + - If you have lots of errors you may need to remove the ``strict`` + directive from ``pyproject.toml``. +#. Do a side-by-side diff of the ``.gitignore`` files in your project and + Starbase, making them as close as possible and adding anything that makes + sense upstream. +#. Bring in remaining top-level files: + - .editorconfig + - .pre-commit-config.yaml + - .shellcheckrc + - tox.ini + - .yamllint.yaml +#. If you're rebasing a library, add the integrations tests structure. + Applications should use spread for integration tests. +# Finally, once all files are manually synced, actually sync the git history: + - ``git remote add starbase git@github.com:canonical/starbase.git`` + - ``git merge --allow-unrelated-histories starbase/main`` + - ``git remote remove starbase`` + - Don't forget to review all the new files and dirs that this merge adds - + you'll want to delete a lot of them. + - When you merge, DO NOT squash, otherwise the starbase history will not be + preserved. + + Create a new project --------------------------- diff --git a/pyproject.toml b/pyproject.toml index d76a0c2e44..29a4b9f8dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,6 @@ [project] name = "starcraft" +description = "The basis for Starcraft team packages" dynamic = ["version", "readme"] dependencies = [ @@ -157,10 +158,7 @@ strict = false line-length = 88 target-version = "py310" src = ["starcraft", "tests"] -extend-exclude = [ - "docs", - "__pycache__", -] +extend-exclude = ["docs"] [tool.ruff.format] docstring-code-format = true @@ -169,6 +167,7 @@ quote-style = "double" [tool.ruff.lint] # Follow ST063 - Maintaining and updating linting specifications for updating these. +# Handy link: https://docs.astral.sh/ruff/rules/ select = [ # Base linting rule selections. # See the internal document for discussion: # https://docs.google.com/document/d/1i1n8pDmFmWi4wTDpk-JfnWCVUThPJiggyPi2DYwBBu4/edit @@ -285,7 +284,7 @@ max-args = 8 classmethod-decorators = ["pydantic.validator", "pydantic.root_validator"] [tool.ruff.lint.per-file-ignores] -"tests/**.py" = [ # Some things we want for the moin project are unnecessary in tests. +"tests/**.py" = [ # Some things we want for the main project are unnecessary in tests. "D", # Ignore docstring rules in tests "ANN", # Ignore type annotations in tests "ARG", # Allow unused arguments in tests (e.g. for fake functions/methods/classes) diff --git a/tox.ini b/tox.ini index b101421e41..dd4e61956b 100644 --- a/tox.ini +++ b/tox.ini @@ -78,8 +78,8 @@ labels = lint commands_pre = shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' commands = - ruff: ruff format --check --diff --respect-gitignore {posargs:.} - ruff: ruff check --respect-gitignore {posargs:.} + ruff: ruff format --check --diff {posargs:.} + ruff: ruff check {posargs:.} shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck codespell: codespell --toml {tox_root}/pyproject.toml {posargs} yaml: yamllint {posargs} . From 9027b2cb2afd2cca1da5eb78608282322578240d Mon Sep 17 00:00:00 2001 From: Matt Culler Date: Fri, 11 Oct 2024 17:01:09 -0400 Subject: [PATCH 236/333] fix: starbase breakage from #265 (#270) * fix: broken shell escaping * fix: improper shell escaping and missed alias * Update Makefile Co-authored-by: Alex Lowe --------- Co-authored-by: Alex Lowe --- Makefile | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 01eb849b11..34e1b3f154 100644 --- a/Makefile +++ b/Makefile @@ -38,11 +38,11 @@ help: ## Show this help. setup: ## Set up a development environment ifeq ($(OS),Linux) changes="`sudo snap install --no-wait codespell`" - changes="${changes} `sudo snap install --no-wait ruff`" - changes="${changes} `sudo snap install --no-wait shellcheck`" - changes="${changes} `sudo snap install --classic --no-wait astral-uv`" - for change in ${changes}; do - snap watch ${change} + changes="$$changes `sudo snap install --no-wait ruff`" + changes="$$changes `sudo snap install --no-wait shellcheck`" + changes="$$changes `sudo snap install --classic --no-wait astral-uv`" + for change in $$changes; do + snap watch $$change done else ifeq ($(OS),Windows_NT) pipx install uv @@ -66,8 +66,8 @@ endif ---------------- : ## ---------------- -.PHONY: autoformat -autoformat: format-ruff format-codespell ## Run all automatic formatters +.PHONY: format +format: format-ruff format-codespell ## Run all automatic formatters .PHONY: format-ruff format-ruff: ##- Automatically format with ruff @@ -75,12 +75,15 @@ format-ruff: ##- Automatically format with ruff success=true ruff check --fix $(SOURCES) || success=false ruff format $(SOURCES) - $success || exit 1 + $$success || exit 1 .PHONY: format-codespell format-codespell: ##- Fix spelling issues with codespell uv run codespell --toml pyproject.toml --write-changes $(SOURCES) +.PHONY: autoformat +autoformat: format # Alias for 'format' + ---------------- : ## ---------------- .PHONY: lint From 7091ba16fd609b604353ef1efd6ef97c5aa1ba57 Mon Sep 17 00:00:00 2001 From: Tiago Nobrega Date: Mon, 21 Oct 2024 16:16:54 -0300 Subject: [PATCH 237/333] chore(ci): generate release notes when publishing --- .github/workflows/release-publish.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index fc5fb390a6..d688f3bb7b 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -64,6 +64,8 @@ jobs: - name: Release uses: softprops/action-gh-release@v2 with: + # Generate release notes on the new GH release + generate_release_notes: true # Add wheel and source tarball files: | *.whl From 07e47ee6f71f34224e3e277cf934faef4307c7f7 Mon Sep 17 00:00:00 2001 From: Imani Pelton Date: Thu, 7 Nov 2024 13:51:08 -0500 Subject: [PATCH 238/333] fix(test): removes bad "-" in test definitions (#274) --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 0879ee0ade..f6ad2c18e9 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -97,7 +97,7 @@ jobs: runs-on: ${{ matrix.platform }} steps: - name: Check out code - - uses: actions/checkout@v4 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python From f9efe7b8f82505c4b50c93d822ffd6b7b871a30d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 11:31:47 -0500 Subject: [PATCH 239/333] build(deps): update dependency pyright to v1.1.388 (#276) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 29a4b9f8dc..134408ad65 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.383", + "pyright==1.1.388", ] docs = [ "canonical-sphinx~=0.2.0", @@ -49,7 +49,7 @@ dev-dependencies = [ "pytest-mock~=3.12", "yamllint~=1.34", "mypy[reports]~=1.11.0", - "pyright==1.1.383", + "pyright==1.1.388", "types-Pygments", "types-colorama", "types-setuptools", From 5ea4251bb4a692ae1b9966ad79efe01bda956fa6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 11:34:08 -0500 Subject: [PATCH 240/333] build(deps): update dependency tox-gh to v1.4.4 (#275) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index dd4e61956b..696a22fd6f 100644 --- a/tox.ini +++ b/tox.ini @@ -18,7 +18,7 @@ requires = # renovate: datasource=pypi tox-ignore-env-name-mismatch>=0.2.0.post2 # renovate: datasource=pypi - tox-gh==1.4.1 + tox-gh==1.4.4 # Allow tox to access the user's $TMPDIR environment variable if set. # This workaround is required to avoid circular dependencies for TMPDIR, # since tox will otherwise attempt to use the environment's TMPDIR variable. From a411e24bdb71b21ffb0d76db3826e4bb18fac5cd Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Mon, 18 Nov 2024 11:53:17 -0500 Subject: [PATCH 241/333] ci: use starflow CI actions (#272) --- .github/workflows/cla-check.yaml | 9 - .github/workflows/docs.yaml | 37 - .../{security-scan.yaml => policy.yaml} | 8 +- .github/workflows/qa.yaml | 16 + .github/workflows/tests.yaml | 128 -- .readthedocs.yaml | 2 +- HACKING.rst | 84 +- Makefile | 174 +- README.rst | 16 +- common.mk | 202 ++ pyproject.toml | 27 +- tests/integration/test_setuptools.py | 4 + uv.lock | 1792 +++++++++++++++++ 13 files changed, 2100 insertions(+), 399 deletions(-) delete mode 100644 .github/workflows/cla-check.yaml delete mode 100644 .github/workflows/docs.yaml rename .github/workflows/{security-scan.yaml => policy.yaml} (50%) create mode 100644 .github/workflows/qa.yaml delete mode 100644 .github/workflows/tests.yaml create mode 100644 common.mk create mode 100644 uv.lock diff --git a/.github/workflows/cla-check.yaml b/.github/workflows/cla-check.yaml deleted file mode 100644 index cdb271af63..0000000000 --- a/.github/workflows/cla-check.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: cla-check -on: [pull_request] - -jobs: - cla-check: - runs-on: ubuntu-latest - steps: - - name: Check if CLA signed - uses: canonical/has-signed-canonical-cla@v1 diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml deleted file mode 100644 index c2b688c975..0000000000 --- a/.github/workflows/docs.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: Documentation -on: - push: - branches: - - "main" - - "feature/*" - - "hotfix/*" - - "release/*" - pull_request: - paths: - - "docs/**" - - "pyproject.toml" - - ".github/workflows/docs.yaml" - -jobs: - sphinx: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install Tox - run: pip install tox - - name: Lint documentation - run: tox run --colored yes -e lint-docs - - name: Build documentation - run: tox run --colored yes -e build-docs - - name: Upload documentation - uses: actions/upload-artifact@v4 - with: - name: docs - path: docs/_build/ diff --git a/.github/workflows/security-scan.yaml b/.github/workflows/policy.yaml similarity index 50% rename from .github/workflows/security-scan.yaml rename to .github/workflows/policy.yaml index 459d7e554a..fb8310f998 100644 --- a/.github/workflows/security-scan.yaml +++ b/.github/workflows/policy.yaml @@ -1,13 +1,15 @@ -name: Security scan +name: Check policy on: pull_request: push: branches: - main - hotfix/* - - work/secscan # For development + - work/check-policy # For development jobs: + policy: + uses: canonical/starflow/.github/workflows/policy.yaml@main python-scans: - name: Scan Python project + name: Security scan uses: canonical/starflow/.github/workflows/scan-python.yaml@main diff --git a/.github/workflows/qa.yaml b/.github/workflows/qa.yaml new file mode 100644 index 0000000000..2ac023b012 --- /dev/null +++ b/.github/workflows/qa.yaml @@ -0,0 +1,16 @@ +name: QA +on: + push: + branches: + - "main" + - "feature/*" + - "hotfix/*" + - "release/*" + - "renovate/*" + pull_request: + +jobs: + lint: + uses: canonical/starflow/.github/workflows/lint-python.yaml@main + test: + uses: canonical/starflow/.github/workflows/test-python.yaml@main diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml deleted file mode 100644 index f6ad2c18e9..0000000000 --- a/.github/workflows/tests.yaml +++ /dev/null @@ -1,128 +0,0 @@ -name: test -on: - push: - branches: - - "main" - - "feature/*" - - "hotfix/*" - - "release/*" - - "renovate/*" - pull_request: - -# Cancel currently-running builds when pushing new commits to a PR or branch -# https://stackoverflow.com/a/72408109 -concurrency: - group: ${{ github.workflow }}-${{ github.ref || github.run_id }} - cancel-in-progress: true -jobs: - lint: - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: conventional commits - uses: webiny/action-conventional-commits@v1.3.0 - with: - allowed-commit-types: "build,chore,ci,docs,feat,fix,perf,refactor,style,test" - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - cache: 'pip' - - name: Configure environment - run: | - echo "::group::Begin snap install" - echo "Installing snaps in the background while running apt and pip..." - sudo snap install --no-wait --classic pyright - sudo snap install --no-wait codespell shellcheck ruff - echo "::endgroup::" - echo "::group::pip install" - python -m pip install tox - echo "::endgroup::" - echo "::group::Create virtual environments for linting processes." - tox run --colored yes -m lint --notest - echo "::endgroup::" - echo "::group::Wait for snap to complete" - snap watch --last=install - echo "::endgroup::" - - name: Run linters - run: tox run --skip-pkg-install --no-list-dependencies --colored yes -m lint - unit: - strategy: - matrix: - platform: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest] - runs-on: ${{ matrix.platform }} - steps: - - name: Check out code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: | - 3.10 - 3.12 - 3.13-dev - cache: 'pip' - - name: Configure environment - run: | - echo "::group::pip install" - python -m pip install tox - echo "::endgroup::" - mkdir -p results - - name: Setup Tox environments - run: tox run --colored yes -m tests --notest - - name: Test with tox - run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json --colored yes -m unit-tests - env: - PYTEST_ADDOPTS: "--no-header -vv -rN" - - name: Upload code coverage - uses: codecov/codecov-action@v4 - with: - directory: ./results/ - files: coverage*.xml - - name: Upload test results - if: success() || failure() - uses: actions/upload-artifact@v4 - with: - name: unit-test-results-${{ matrix.platform }} - path: results/ - integration: - strategy: - matrix: - platform: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest] - runs-on: ${{ matrix.platform }} - steps: - - name: Check out code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: | - 3.10 - 3.12 - 3.13-dev - cache: 'pip' - - name: Configure environment - run: | - echo "::group::pip install" - python -m pip install tox - echo "::endgroup::" - mkdir -p results - - name: Setup Tox environments - run: tox run --colored yes -m tests --notest - - name: Test with tox - run: tox run --skip-pkg-install --no-list-dependencies --result-json results/tox-${{ matrix.platform }}.json --colored yes -m integration-tests - env: - PYTEST_ADDOPTS: "--no-header -vv -rN" - - name: Upload test results - if: success() || failure() - uses: actions/upload-artifact@v4 - with: - name: integration-test-results-${{ matrix.platform }} - path: results/ diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 190297fcae..071ed7918e 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -10,7 +10,7 @@ sphinx: configuration: docs/conf.py # Optionally build your docs in additional formats such as PDF -#formats: +# formats: # - pdf # - epub diff --git a/HACKING.rst b/HACKING.rst index 929394c7fe..384112f0d6 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -13,79 +13,33 @@ repository. Once you've done that, clone the project to your computer using git clone's ``--recurse-submodules`` parameter. (See more on the `git submodules`_ documentation.) -Tooling -======= -We use a large number of tools for our project. Most of these are installed for -you with tox, but you'll need to install: - -- Python 3.8 (default on Ubuntu 20.04, available on Ubuntu 22.04 through the - deadsnakes_ PPA) with setuptools. -- tox_ version 3.8 or later -- ShellCheck_ (also available via snap: ``snap install shellcheck``) -- Codespell_ (also available via snap: ``snap install codespell``) -- ruff_ (also available via snap: ``snap install ruff``) - -Once you have all of those installed, you can install the necessary virtual -environments for this repository using tox. - -Other tools -########### -Some other tools we use for code quality include: - -- Black_ for code formatting -- pytest_ for testing - -A complete list is kept in our pyproject.toml_ file in dev dependencies. - -Initial Setup -############# +To set up a development environment, run:: -After cloning the repository but before making any changes, it's worth ensuring -that the tests, linting and tools all run on your machine. Running ``tox`` with -no parameters will create the necessary virtual environments for linting and -testing and run those:: + make setup - tox +To test that the environment works, run:: -If you want to install the environments but not run the tests, you can run:: + make lint + make test - tox --notest - -If you'd like to run the tests with a newer version of Python, you can pass a -specific environment. You must have an appropriately versioned Python -interpreter installed. For example, to run with Python 3.10, run:: - - tox -e test-py3.10 - -While the use of pre-commit_ is optional, it is highly encouraged, as it runs -automatic fixes for files when ``git commit`` is called, including code -formatting with ``black`` and ``ruff``. The versions available in ``apt`` from -Debian 11 (bullseye), Ubuntu 22.04 (jammy) and newer are sufficient, but you can -also install the latest with ``pip install pre-commit``. Once you've installed -it, run ``pre-commit install`` in this git repository to install the pre-commit -hooks. - -Tox environments and labels -########################### - -We group tox environments with the following labels: +Code conventions +================ -* ``format``: Runs all code formatters with auto-fixing -* ``type``: Runs all type checkers -* ``lint``: Runs all linters (including type checkers) -* ``unit-tests``: Runs unit tests in several supported Python versions -* ``integration-tests``: Run integration tests in several Python versions -* ``tests``: The union of ``unit-tests`` and ``integration-tests`` +Several targets exist in the Makefile to help with code conventions. They are all +merged into the ``format`` target for automatic formatting and the ``lint`` target +for running all linters. These conventions apply to all files in the repository, +including documentation and metadata files. ``pre-commit`` is used for running many +hooks before committing. Run:: -For each of these, you can see which environments will be run with ``tox list``. -For example:: + make setup-precommit - tox list -m lint +to configure it for this repository. -You can also see all the environments by simply running ``tox list`` +Testing +======= -Running ``tox run -m format`` and ``tox run -m lint`` before committing code is -recommended. +Tests can be run using ``make test``, which will run all test forms. Specific types +of tests can be run with other testing targets shown in ``make help``. Branches -------- @@ -393,11 +347,9 @@ it includes the changes from 2.9.1. 3.0.1 includes changes from the 2.9.1 release. -.. _Black: https://black.readthedocs.io .. _`Canonical contributor licence agreement`: http://www.ubuntu.com/legal/contributors/ .. _Codespell: https://github.com/codespell-project/codespell .. _`conventional commit`: https://www.conventionalcommits.org/en/v1.0.0/#summary -.. _deadsnakes: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa .. _`git submodules`: https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules .. _`Martin Fowler's definition`: https://refactoring.com/ .. _OneFlow: https://www.endoflineblog.com/oneflow-a-git-branching-model-and-workflow diff --git a/Makefile b/Makefile index 34e1b3f154..909d25f71b 100644 --- a/Makefile +++ b/Makefile @@ -1,153 +1,39 @@ PROJECT=starcraft -SOURCES=$(wildcard *.py) $(PROJECT) tests -DOCS=docs -ifneq ($(OS),Windows_NT) - OS := $(shell uname) -endif - -.DEFAULT_GOAL := help - -.ONESHELL: - -.SHELLFLAGS = -ec - -.PHONY: help -help: ## Show this help. - @printf "%-41s %s\n" "Target" "Description" - @printf "%-41s %s\n" "------" "-----------" - @fgrep " ##" $(MAKEFILE_LIST) | fgrep -v grep | sed 's/:[^#]*/ /' | awk -F '[: ]*' \ - '{ - if ($$2 == "##") - { - $$1=sprintf("%-40s", $$1); - $$2=""; - print $$0; - } - else - { - $$1=sprintf(" â””%-38s", $$1); - $$2=""; - print $$0; - } - }' - ----------------- : ## ---------------- - -.PHONY: setup -setup: ## Set up a development environment -ifeq ($(OS),Linux) - changes="`sudo snap install --no-wait codespell`" - changes="$$changes `sudo snap install --no-wait ruff`" - changes="$$changes `sudo snap install --no-wait shellcheck`" - changes="$$changes `sudo snap install --classic --no-wait astral-uv`" - for change in $$changes; do - snap watch $$change - done -else ifeq ($(OS),Windows_NT) - pipx install uv - choco install shellcheck -else ifeq ($(OS),Darwin) - brew install uv - brew install shellcheck -endif -ifneq ($(OS),Linux) - uv tool install codespell - uv tool install ruff - uv tool update-shell -endif - -.PHONY: setup-pre-commit -setup-precommit: ## Set up pre-commit hooks in this repository. -ifeq (, $(shell which pre-commit)) - uv tool install pre-commit -endif - pre-commit install - ----------------- : ## ---------------- +include common.mk .PHONY: format format: format-ruff format-codespell ## Run all automatic formatters -.PHONY: format-ruff -format-ruff: ##- Automatically format with ruff - ruff check --fix $(SOURCES) - success=true - ruff check --fix $(SOURCES) || success=false - ruff format $(SOURCES) - $$success || exit 1 - -.PHONY: format-codespell -format-codespell: ##- Fix spelling issues with codespell - uv run codespell --toml pyproject.toml --write-changes $(SOURCES) - -.PHONY: autoformat -autoformat: format # Alias for 'format' - ----------------- : ## ---------------- - .PHONY: lint -lint: lint-ruff lint-codespell lint-mypy lint-pyright lint-shellcheck lint-yaml lint-docs ## Run all linters +lint: lint-ruff lint-codespell lint-mypy lint-pyright lint-shellcheck lint-yaml lint-docs lint-twine ## Run all linters -.PHONY: lint-ruff -lint-ruff: ##- Lint with ruff - ruff check $(SOURCES) - ruff format --diff $(SOURCES) +.PHONY: pack +pack: pack-pip ## Build all packages -.PHONY: lint-codespell -lint-codespell: ##- Check spelling with codespell - uv run codespell --toml pyproject.toml $(SOURCES) - -.PHONY: lint-mypy -lint-mypy: ##- Check types with mypy - uv run mypy --show-traceback --show-error-codes $(SOURCES) - -.PHONY: lint-pyright -lint-pyright: ##- Check types with pyright - # Fix for a bug in npm - [ -d "/home/ubuntu/.npm/_cacache" ] && chown -R 1000:1000 "/home/ubuntu/.npm" || true - uv run pyright - -.PHONY: lint-shellcheck -lint-shellcheck: ##- Lint shell scripts - git ls-files | file --mime-type -Nnf- | grep shellscript | cut -f1 -d: | xargs -r shellcheck - -.PHONY: lint-yaml -lint-yaml: ##- Lint YAML files with yamllint - uv run yamllint . - -.PHONY: lint-docs -lint-docs: ##- Lint the documentation - uv run --extra docs sphinx-lint --max-line-length 88 --enable all $(DOCS) - ----------------- : ## ---------------- - -.PHONY: test -test: test-unit test-integration ## Run all tests - -.PHONY: test-unit -test-unit: ##- Run unit tests - uv run pytest --cov=$(PROJECT) --cov-config=pyproject.toml --cov-report=xml:.coverage.unit.xml --junit-xml=.results.unit.xml tests/unit - -.PHONY: test-integration -test-integration: ##- Run integration tests - uv run pytest --cov=$(PROJECT) --cov-config=pyproject.toml --cov-report=xml:.coverage.integration.xml --junit-xml=.results.integration.xml tests/integration - ----------------- : ## ---------------- - -.PHONY: coverage -coverage: ## Generate coverage report - coverage run --source starcraft -m pytest - coverage xml -o coverage.xml - coverage report -m - coverage html - ----------------- : ## ---------------- - -.PHONY: docs -docs: ## Build documentation - uv run --extra docs sphinx-build -b html -W docs docs/_build - -.PHONY: docs-auto -docs-auto: ## Build and host docs with sphinx-autobuild - uv run --extra docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W docs docs/_build +.PHONY: pack-snap +pack-snap: snap/snapcraft.yaml ##- Build snap package +ifeq ($(shell which snapcraft),) + sudo snap install --classic snapcraft +endif + snapcraft pack + +.PHONY: publish +publish: publish-pypi ## Publish packages + +.PHONY: publish-pypi +publish-pypi: clean package-pip lint-twine ##- Publish Python packages to pypi + uv tool run twine upload dist/* + +# Used for installing build dependencies in CI. +.PHONY: install-build-deps +install-build-deps: +ifeq ($(shell which apt-get),) + $(warning Cannot install build dependencies without apt.) +else ifeq ($(wildcard /usr/include/libxml2/libxml/xpath.h),) + sudo $(APT) install libxml2-dev libxslt1-dev python3-venv +else ifeq ($(wildcard /usr/include/libxslt/xslt.h),) + sudo $(APT) install libxslt1-dev python3-venv +else ifeq ($(wildcard /usr/share/doc/python3-venv/copyright),) + sudo $(APT) install python3-venv +endif diff --git a/README.rst b/README.rst index bd323ab482..41260dff65 100644 --- a/README.rst +++ b/README.rst @@ -26,13 +26,16 @@ TODO Migrate existing projects -------------------------------- #. Update this guide as you go along, if something is unclear or missing. + #. Use ruff. #. Pull in the bare minimum ``pyproject.toml`` needed to use ruff. #. Make your codebase pass with ruff. Commit after each step: + #. ``ruff check --fix`` #. ``ruff check --fix --unsafe-fixes`` #. ``ruff check --add-noqa`` #. ``ruff format`` + #. Replace use of black, flake8, pydocstyle, isort, and pylint in Makefile/CI with: - ``ruff check --fix`` @@ -40,12 +43,14 @@ Migrate existing projects #. Modify top-level files in your project to match what's in Starbase as closely as possible. #. ``Makefile`` - Ensure you use ``uv`` and at least have the same targets: + - ``setup`` - ``lint`` - ``test-unit`` - ``test-integration`` (If this applies to your repo, i.e. the repo is a library rather than an application) - ``coverage`` + #. ``pyproject.toml`` - Expand from just the ruff things: move things into here from your ``setup.py``, ``setup.cfg``, and ``requirements.*.txt``. #. ``README`` - If your readme is .md, convert to .rst with pandoc: @@ -53,26 +58,33 @@ Migrate existing projects Don't worry about making the contents match, Starbase's is very specific. #. Run all the linters: ``make lint`` #. ``mypy``: + - Mypy checks the same things as ``ruff``'s ``ANNXXX`` checks, but ``ruff``'s ``noqa`` directives mean nothing to mypy. You'll need to fix these by hand, mostly by adding type annotations to function definitions. + #. ``pyright``: + - For errors along the lines of "Stub file not found for $library", check for the existence of pip package ``typing-$library`` and add it as a dependency. - If you have lots of errors you may need to remove the ``strict`` directive from ``pyproject.toml``. + #. Do a side-by-side diff of the ``.gitignore`` files in your project and Starbase, making them as close as possible and adding anything that makes sense upstream. + #. Bring in remaining top-level files: - .editorconfig - .pre-commit-config.yaml - .shellcheckrc - tox.ini - .yamllint.yaml + #. If you're rebasing a library, add the integrations tests structure. Applications should use spread for integration tests. + # Finally, once all files are manually synced, actually sync the git history: - ``git remote add starbase git@github.com:canonical/starbase.git`` - ``git merge --allow-unrelated-histories starbase/main`` @@ -83,10 +95,8 @@ Migrate existing projects preserved. - Create a new project ---------------------------- -[TODO: Make this a template repository.] +-------------------- #. `Use this template`_ to create your repository. #. Ensure the ``LICENSE`` file represents the current best practices from the diff --git a/common.mk b/common.mk new file mode 100644 index 0000000000..4e6b0a977b --- /dev/null +++ b/common.mk @@ -0,0 +1,202 @@ +# Common items for all Starcraft Makefiles. Should only be edited in the `starbase` repository: +# https://github.com/canonical/starbase + +SOURCES=$(wildcard *.py) $(PROJECT) tests +DOCS=docs + +ifneq ($(OS),Windows_NT) + OS := $(shell uname) +endif +ifdef CI + APT := apt-get --yes +else + APT := apt-get +endif + +.DEFAULT_GOAL := help + +.ONESHELL: + +.SHELLFLAGS = -ec + +.PHONY: help +help: ## Show this help. + @printf "\e[1m%-30s\e[0m | \e[1m%s\e[0m\n" "Target" "Description" + printf "\e[2m%-30s + %-41s\e[0m\n" "------------------------------" "------------------------------------------------" + egrep '^[^:]+\: [^#]*##' $$(echo $(MAKEFILE_LIST) | tac --separator=' ') | sed -e 's/^[^:]*://' -e 's/:[^#]*/ /' | sort -V| awk -F '[: ]*' \ + '{ + if ($$2 == "##") + { + $$1=sprintf(" %-28s", $$1); + $$2=" | "; + print $$0; + } + else + { + $$1=sprintf(" â”” %-25s", $$1); + $$2=" | "; + $$3=sprintf(" â”” %s", $$3); + print $$0; + } + }' + +.PHONY: setup +setup: install-uv setup-precommit ## Set up a development environment + uv sync --frozen --all-extras + +.PHONY: setup-tests +setup-tests: install-uv install-build-deps ##- Set up a testing environment without linters + uv sync --frozen + +.PHONY: setup-lint +setup-lint: install-uv install-shellcheck ##- Set up a linting-only environment + uv sync --frozen --no-dev --no-install-workspace --extra lint --extra types + +.PHONY: setup-docs +setup-docs: install-uv ##- Set up a documentation-only environment + uv sync --frozen --no-dev --no-install-workspace --extra docs + +.PHONY: setup-precommit +setup-precommit: install-uv ##- Set up pre-commit hooks in this repository. +ifeq ($(shell which pre-commit),) + uv tool install pre-commit +endif + pre-commit install + +.PHONY: clean +clean: ## Clean up the development environment + uv tool run pyclean . + rm -rf dist/ build/ docs/_build/ *.snap .coverage* + +.PHONY: autoformat +autoformat: format # Hidden alias for 'format' + +.PHONY: format-ruff +format-ruff: ##- Automatically format with ruff + success=true + ruff check --fix $(SOURCES) || success=false + ruff format $(SOURCES) + $$success || exit 1 + +.PHONY: format-codespell +format-codespell: ##- Fix spelling issues with codespell + uv run codespell --toml pyproject.toml --write-changes $(SOURCES) + +.PHONY: lint-ruff +lint-ruff: ##- Lint with ruff + ruff check $(SOURCES) + ruff format --diff $(SOURCES) + +.PHONY: lint-codespell +lint-codespell: ##- Check spelling with codespell + uv run codespell --toml pyproject.toml $(SOURCES) + +.PHONY: lint-mypy +lint-mypy: ##- Check types with mypy + uv run mypy --show-traceback --show-error-codes $(PROJECT) + +.PHONY: lint-pyright +lint-pyright: ##- Check types with pyright +ifneq ($(shell which pyright),) # Prefer the system pyright + pyright --pythonpath .venv/bin/python +else + # Fix for a bug in npm + [ -d "/home/ubuntu/.npm/_cacache" ] && chown -R 1000:1000 "/home/ubuntu/.npm" || true + uv run pyright +endif + +.PHONY: lint-shellcheck +lint-shellcheck: ##- Lint shell scripts + git ls-files | file --mime-type -Nnf- | grep shellscript | cut -f1 -d: | xargs -r shellcheck + +.PHONY: lint-yaml +lint-yaml: ##- Lint YAML files with yamllint + uv run --extra lint yamllint . + +.PHONY: lint-docs +lint-docs: ##- Lint the documentation + uv run --extra docs sphinx-lint --max-line-length 88 --enable all $(DOCS) + +.PHONY: lint-twine +lint-twine: dist/* ##- Lint Python packages with twine + uv tool run twine check dist/* + +.PHONY: test +test: ## Run all tests + uv run pytest + +.PHONY: test-fast +test-fast: ##- Run fast tests + uv run pytest -m 'not slow' + +.PHONY: test-slow +test-slow: ##- Run slow tests + uv run pytest -m 'slow' + +.PHONY: test-coverage +test-coverage: ## Generate coverage report + uv run coverage run --source $(PROJECT) -m pytest + uv run coverage xml -o coverage.xml + uv run coverage report -m + uv run coverage html + +.PHONY: docs +docs: ## Build documentation + uv run --extra docs sphinx-build -b html -W $(DOCS) $(DOCS)/_build + +.PHONY: docs-auto +docs-auto: ## Build and host docs with sphinx-autobuild + uv run --extra docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W $(DOCS) $(DOCS)/_build + +.PHONY: pack-pip +pack-pip dist/*: ##- Build packages for pip (sdist, wheel) + uv build . + +# Below are intermediate targets for setup. They are not included in help as they should +# not be used independently. + +.PHONY: install-uv +install-uv: +ifneq ($(shell which uv),) +else ifneq ($(shell which snap),) + sudo snap install --classic astral-uv +else ifneq ($(shell which brew),) + brew install uv +else ifeq ($(OS),Windows_NT) + pwsh -c "irm https://astral.sh/uv/install.ps1 | iex" +else + curl -LsSf https://astral.sh/uv/install.sh | sh +endif + +.PHONY: install-codespell +install-codespell: +ifneq ($(shell which codespell),) +else ifneq ($(shell which snap),) + sudo snap install codespell +else ifneq ($(shell which brew),) + make install-uv + uv tool install codespell +else + $(warning Codespell not installed. Please install it yourself.) +endif + +.PHONY: install-ruff +install-ruff: +ifneq ($(shell which ruff),) +else ifneq ($(shell which snap),) + sudo snap install ruff +else + make install-uv + uv tool install ruff +endif + +.PHONY: install-shellcheck +install-shellcheck: +ifneq ($(shell which shellcheck),) +else ifneq ($(shell which snap),) + sudo snap install shellcheck +else ifneq ($(shell which brew),) + brew install shellcheck +else + $(warning Codespell not installed. Please install it yourself.) +endif diff --git a/pyproject.toml b/pyproject.toml index 134408ad65..4ad8bd2b59 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,19 +18,15 @@ requires-python = ">=3.10" starcraft-hello = "starcraft:hello" [project.optional-dependencies] -dev = [ - "build", - "coverage[toml]~=7.4", - "pytest~=8.0", - "pytest-cov~=5.0", - "pytest-mock~=3.12", -] lint = [ "yamllint~=1.34", ] types = [ "mypy[reports]~=1.11.0", "pyright==1.1.388", + "types-Pygments", + "types-colorama", + "types-setuptools", ] docs = [ "canonical-sphinx~=0.2.0", @@ -41,6 +37,22 @@ docs = [ ] [tool.uv] +constraint-dependencies = [ + # Basic constraints to allow --resolution=lowest + "build>=0.7.0", + "iniconfig>=1.1.0", + "lxml>=5.0", + "pyparsing>=3.0.0", + "pyproject-hooks>=1.0.0", + "pyyaml>=5.0", + "markdown>=3.0", + "markupsafe>=2.0", + "pyyaml>5.0", + "regex>=2021.11.10", + "sphinx-basic-ng>=1.0.0b1", + "tornado>=4.0", + "webencodings>=0.4.0", +] dev-dependencies = [ "build", "coverage[toml]~=7.4", @@ -110,7 +122,6 @@ xfail_strict = true [tool.coverage.run] branch = true -parallel = true omit = ["tests/**"] [tool.coverage.report] diff --git a/tests/integration/test_setuptools.py b/tests/integration/test_setuptools.py index a27c9843c8..43f2b89d8a 100644 --- a/tests/integration/test_setuptools.py +++ b/tests/integration/test_setuptools.py @@ -19,6 +19,10 @@ from pathlib import Path from zipfile import ZipFile +import pytest + +pytestmark = [pytest.mark.slow] + def test_packages(project_main_module, tmp_path, request): """Check wheel generation from our pyproject.toml""" diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000000..c39fa9fca8 --- /dev/null +++ b/uv.lock @@ -0,0 +1,1792 @@ +version = 1 +requires-python = ">=3.10" +resolution-markers = [ + "python_full_version < '3.13'", + "python_full_version >= '3.13'", +] + +[manifest] +constraints = [ + { name = "build", specifier = ">=0.1.0" }, + { name = "iniconfig", specifier = ">=1.1.0" }, + { name = "lxml", specifier = ">=5.0" }, + { name = "markdown", specifier = ">=3.0" }, + { name = "markupsafe", specifier = ">=2.0" }, + { name = "pyparsing", specifier = ">=3.0.0" }, + { name = "pyproject-hooks", specifier = ">=1.0.0" }, + { name = "pyyaml", specifier = ">=5.0" }, + { name = "regex", specifier = ">=2021.11.10" }, + { name = "sphinx-basic-ng", specifier = ">=1.0.0b1" }, + { name = "tornado", specifier = ">=4.0" }, + { name = "webencodings", specifier = ">=0.4.0" }, +] + +[[package]] +name = "alabaster" +version = "0.7.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511 }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, +] + +[[package]] +name = "anyio" +version = "4.6.2.post1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "idna" }, + { name = "sniffio" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 }, +] + +[[package]] +name = "apeye" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "apeye-core" }, + { name = "domdf-python-tools" }, + { name = "platformdirs" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4f/6b/cc65e31843d7bfda8313a9dc0c77a21e8580b782adca53c7cb3e511fe023/apeye-1.4.1.tar.gz", hash = "sha256:14ea542fad689e3bfdbda2189a354a4908e90aee4bf84c15ab75d68453d76a36", size = 99219 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/7b/2d63664777b3e831ac1b1d8df5bbf0b7c8bee48e57115896080890527b1b/apeye-1.4.1-py3-none-any.whl", hash = "sha256:44e58a9104ec189bf42e76b3a7fe91e2b2879d96d48e9a77e5e32ff699c9204e", size = 107989 }, +] + +[[package]] +name = "apeye-core" +version = "1.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "domdf-python-tools" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e5/4c/4f108cfd06923bd897bf992a6ecb6fb122646ee7af94d7f9a64abd071d4c/apeye_core-1.1.5.tar.gz", hash = "sha256:5de72ed3d00cc9b20fea55e54b7ab8f5ef8500eb33a5368bc162a5585e238a55", size = 96511 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/9f/fa9971d2a0c6fef64c87ba362a493a4f230eff4ea8dfb9f4c7cbdf71892e/apeye_core-1.1.5-py3-none-any.whl", hash = "sha256:dc27a93f8c9e246b3b238c5ea51edf6115ab2618ef029b9f2d9a190ec8228fbf", size = 99286 }, +] + +[[package]] +name = "autodocsumm" +version = "0.2.13" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/19/2cefb1103bef41ef33393f0de37b72920a099f9a56aa5434570e7dcdf0f4/autodocsumm-0.2.13.tar.gz", hash = "sha256:ac5f0cf1adbe957acb136fe0d9e16c38fb74fcaefb45c148204aba26dbb12ee2", size = 45426 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/fb/59e528d9f5b1aadf4e4fb29e93b1d85570a0f089ebde7b43c574109f8373/autodocsumm-0.2.13-py3-none-any.whl", hash = "sha256:bf4d82ea7acb3e7d9a3ad8c135e097eca1d3f0bd00800d7804127e848e66741d", size = 14257 }, +] + +[[package]] +name = "babel" +version = "2.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, +] + +[[package]] +name = "build" +version = "1.2.2.post1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "os_name == 'nt'" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10.2'" }, + { name = "packaging" }, + { name = "pyproject-hooks" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/46/aeab111f8e06793e4f0e421fcad593d547fb8313b50990f31681ee2fb1ad/build-1.2.2.post1.tar.gz", hash = "sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7", size = 46701 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/c2/80633736cd183ee4a62107413def345f7e6e3c01563dbca1417363cf957e/build-1.2.2.post1-py3-none-any.whl", hash = "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", size = 22950 }, +] + +[[package]] +name = "cachecontrol" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "msgpack" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/55/edea9d90ee57ca54d34707607d15c20f72576b96cb9f3e7fc266cb06b426/cachecontrol-0.14.0.tar.gz", hash = "sha256:7db1195b41c81f8274a7bbd97c956f44e8348265a1bc7641c37dfebc39f0c938", size = 28899 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/a9/7d331fec593a4b2953338df33e954aac6ff79eb5a073bca2783766bc7722/cachecontrol-0.14.0-py3-none-any.whl", hash = "sha256:f5bf3f0620c38db2e5122c0726bdebb0d16869de966ea6a2befe92470b740ea0", size = 22064 }, +] + +[package.optional-dependencies] +filecache = [ + { name = "filelock" }, +] + +[[package]] +name = "canonical-sphinx" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "furo" }, + { name = "linkify-it-py" }, + { name = "myst-parser" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fe/2a/a77c673d5950d1ae1e065fddd038e547610fc9e1de41ef56b20d85fa87c2/canonical_sphinx-0.2.0.tar.gz", hash = "sha256:74d8dce67845924220d67f78bf85df379d8121e9b8e684338986dcccf9fff439", size = 56858 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/da/488d00806ddcc177c3e02049d8ab1d92aee0a334d6e2aed41a45a5c924f8/canonical_sphinx-0.2.0-py3-none-any.whl", hash = "sha256:c71ee6dbc15c084ad115f06b0f1c15f8269db3a896670e616b8945d6af089edd", size = 31067 }, +] + +[[package]] +name = "certifi" +version = "2024.8.30" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", size = 106620 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/8b/825cc84cf13a28bfbcba7c416ec22bf85a9584971be15b21dd8300c65b7f/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", size = 196363 }, + { url = "https://files.pythonhosted.org/packages/23/81/d7eef6a99e42c77f444fdd7bc894b0ceca6c3a95c51239e74a722039521c/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", size = 125639 }, + { url = "https://files.pythonhosted.org/packages/21/67/b4564d81f48042f520c948abac7079356e94b30cb8ffb22e747532cf469d/charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", size = 120451 }, + { url = "https://files.pythonhosted.org/packages/c2/72/12a7f0943dd71fb5b4e7b55c41327ac0a1663046a868ee4d0d8e9c369b85/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", size = 140041 }, + { url = "https://files.pythonhosted.org/packages/67/56/fa28c2c3e31217c4c52158537a2cf5d98a6c1e89d31faf476c89391cd16b/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", size = 150333 }, + { url = "https://files.pythonhosted.org/packages/f9/d2/466a9be1f32d89eb1554cf84073a5ed9262047acee1ab39cbaefc19635d2/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", size = 142921 }, + { url = "https://files.pythonhosted.org/packages/f8/01/344ec40cf5d85c1da3c1f57566c59e0c9b56bcc5566c08804a95a6cc8257/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", size = 144785 }, + { url = "https://files.pythonhosted.org/packages/73/8b/2102692cb6d7e9f03b9a33a710e0164cadfce312872e3efc7cfe22ed26b4/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", size = 146631 }, + { url = "https://files.pythonhosted.org/packages/d8/96/cc2c1b5d994119ce9f088a9a0c3ebd489d360a2eb058e2c8049f27092847/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", size = 140867 }, + { url = "https://files.pythonhosted.org/packages/c9/27/cde291783715b8ec30a61c810d0120411844bc4c23b50189b81188b273db/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", size = 149273 }, + { url = "https://files.pythonhosted.org/packages/3a/a4/8633b0fc1a2d1834d5393dafecce4a1cc56727bfd82b4dc18fc92f0d3cc3/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", size = 152437 }, + { url = "https://files.pythonhosted.org/packages/64/ea/69af161062166b5975ccbb0961fd2384853190c70786f288684490913bf5/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", size = 150087 }, + { url = "https://files.pythonhosted.org/packages/3b/fd/e60a9d9fd967f4ad5a92810138192f825d77b4fa2a557990fd575a47695b/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", size = 145142 }, + { url = "https://files.pythonhosted.org/packages/6d/02/8cb0988a1e49ac9ce2eed1e07b77ff118f2923e9ebd0ede41ba85f2dcb04/charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", size = 94701 }, + { url = "https://files.pythonhosted.org/packages/d6/20/f1d4670a8a723c46be695dff449d86d6092916f9e99c53051954ee33a1bc/charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", size = 102191 }, + { url = "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", size = 193339 }, + { url = "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", size = 124366 }, + { url = "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", size = 118874 }, + { url = "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", size = 138243 }, + { url = "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", size = 148676 }, + { url = "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", size = 141289 }, + { url = "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", size = 142585 }, + { url = "https://files.pythonhosted.org/packages/3b/a0/a68980ab8a1f45a36d9745d35049c1af57d27255eff8c907e3add84cf68f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", size = 144408 }, + { url = "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", size = 139076 }, + { url = "https://files.pythonhosted.org/packages/fb/9d/9c13753a5a6e0db4a0a6edb1cef7aee39859177b64e1a1e748a6e3ba62c2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", size = 146874 }, + { url = "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", size = 150871 }, + { url = "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", size = 148546 }, + { url = "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", size = 143048 }, + { url = "https://files.pythonhosted.org/packages/01/f8/38842422988b795220eb8038745d27a675ce066e2ada79516c118f291f07/charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", size = 94389 }, + { url = "https://files.pythonhosted.org/packages/0b/6e/b13bd47fa9023b3699e94abf565b5a2f0b0be6e9ddac9812182596ee62e4/charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", size = 101752 }, + { url = "https://files.pythonhosted.org/packages/d3/0b/4b7a70987abf9b8196845806198975b6aab4ce016632f817ad758a5aa056/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", size = 194445 }, + { url = "https://files.pythonhosted.org/packages/50/89/354cc56cf4dd2449715bc9a0f54f3aef3dc700d2d62d1fa5bbea53b13426/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", size = 125275 }, + { url = "https://files.pythonhosted.org/packages/fa/44/b730e2a2580110ced837ac083d8ad222343c96bb6b66e9e4e706e4d0b6df/charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", size = 119020 }, + { url = "https://files.pythonhosted.org/packages/9d/e4/9263b8240ed9472a2ae7ddc3e516e71ef46617fe40eaa51221ccd4ad9a27/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", size = 139128 }, + { url = "https://files.pythonhosted.org/packages/6b/e3/9f73e779315a54334240353eaea75854a9a690f3f580e4bd85d977cb2204/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", size = 149277 }, + { url = "https://files.pythonhosted.org/packages/1a/cf/f1f50c2f295312edb8a548d3fa56a5c923b146cd3f24114d5adb7e7be558/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", size = 142174 }, + { url = "https://files.pythonhosted.org/packages/16/92/92a76dc2ff3a12e69ba94e7e05168d37d0345fa08c87e1fe24d0c2a42223/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", size = 143838 }, + { url = "https://files.pythonhosted.org/packages/a4/01/2117ff2b1dfc61695daf2babe4a874bca328489afa85952440b59819e9d7/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", size = 146149 }, + { url = "https://files.pythonhosted.org/packages/f6/9b/93a332b8d25b347f6839ca0a61b7f0287b0930216994e8bf67a75d050255/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", size = 140043 }, + { url = "https://files.pythonhosted.org/packages/ab/f6/7ac4a01adcdecbc7a7587767c776d53d369b8b971382b91211489535acf0/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", size = 148229 }, + { url = "https://files.pythonhosted.org/packages/9d/be/5708ad18161dee7dc6a0f7e6cf3a88ea6279c3e8484844c0590e50e803ef/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", size = 151556 }, + { url = "https://files.pythonhosted.org/packages/5a/bb/3d8bc22bacb9eb89785e83e6723f9888265f3a0de3b9ce724d66bd49884e/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", size = 149772 }, + { url = "https://files.pythonhosted.org/packages/f7/fa/d3fc622de05a86f30beea5fc4e9ac46aead4731e73fd9055496732bcc0a4/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", size = 144800 }, + { url = "https://files.pythonhosted.org/packages/9a/65/bdb9bc496d7d190d725e96816e20e2ae3a6fa42a5cac99c3c3d6ff884118/charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", size = 94836 }, + { url = "https://files.pythonhosted.org/packages/3e/67/7b72b69d25b89c0b3cea583ee372c43aa24df15f0e0f8d3982c57804984b/charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", size = 102187 }, + { url = "https://files.pythonhosted.org/packages/f3/89/68a4c86f1a0002810a27f12e9a7b22feb198c59b2f05231349fbce5c06f4/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", size = 194617 }, + { url = "https://files.pythonhosted.org/packages/4f/cd/8947fe425e2ab0aa57aceb7807af13a0e4162cd21eee42ef5b053447edf5/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", size = 125310 }, + { url = "https://files.pythonhosted.org/packages/5b/f0/b5263e8668a4ee9becc2b451ed909e9c27058337fda5b8c49588183c267a/charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", size = 119126 }, + { url = "https://files.pythonhosted.org/packages/ff/6e/e445afe4f7fda27a533f3234b627b3e515a1b9429bc981c9a5e2aa5d97b6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", size = 139342 }, + { url = "https://files.pythonhosted.org/packages/a1/b2/4af9993b532d93270538ad4926c8e37dc29f2111c36f9c629840c57cd9b3/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", size = 149383 }, + { url = "https://files.pythonhosted.org/packages/fb/6f/4e78c3b97686b871db9be6f31d64e9264e889f8c9d7ab33c771f847f79b7/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", size = 142214 }, + { url = "https://files.pythonhosted.org/packages/2b/c9/1c8fe3ce05d30c87eff498592c89015b19fade13df42850aafae09e94f35/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", size = 144104 }, + { url = "https://files.pythonhosted.org/packages/ee/68/efad5dcb306bf37db7db338338e7bb8ebd8cf38ee5bbd5ceaaaa46f257e6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", size = 146255 }, + { url = "https://files.pythonhosted.org/packages/0c/75/1ed813c3ffd200b1f3e71121c95da3f79e6d2a96120163443b3ad1057505/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", size = 140251 }, + { url = "https://files.pythonhosted.org/packages/7d/0d/6f32255c1979653b448d3c709583557a4d24ff97ac4f3a5be156b2e6a210/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", size = 148474 }, + { url = "https://files.pythonhosted.org/packages/ac/a0/c1b5298de4670d997101fef95b97ac440e8c8d8b4efa5a4d1ef44af82f0d/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", size = 151849 }, + { url = "https://files.pythonhosted.org/packages/04/4f/b3961ba0c664989ba63e30595a3ed0875d6790ff26671e2aae2fdc28a399/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", size = 149781 }, + { url = "https://files.pythonhosted.org/packages/d8/90/6af4cd042066a4adad58ae25648a12c09c879efa4849c705719ba1b23d8c/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482", size = 144970 }, + { url = "https://files.pythonhosted.org/packages/cc/67/e5e7e0cbfefc4ca79025238b43cdf8a2037854195b37d6417f3d0895c4c2/charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", size = 94973 }, + { url = "https://files.pythonhosted.org/packages/65/97/fc9bbc54ee13d33dc54a7fcf17b26368b18505500fc01e228c27b5222d80/charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", size = 102308 }, + { url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 }, +] + +[[package]] +name = "click" +version = "8.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "platform_system == 'Windows'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "coverage" +version = "7.6.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/12/3669b6382792783e92046730ad3327f53b2726f0603f4c311c4da4824222/coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", size = 798716 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/93/4ad92f71e28ece5c0326e5f4a6630aa4928a8846654a65cfff69b49b95b9/coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", size = 206713 }, + { url = "https://files.pythonhosted.org/packages/01/ae/747a580b1eda3f2e431d87de48f0604bd7bc92e52a1a95185a4aa585bc47/coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", size = 207149 }, + { url = "https://files.pythonhosted.org/packages/07/1a/1f573f8a6145f6d4c9130bbc120e0024daf1b24cf2a78d7393fa6eb6aba7/coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", size = 235584 }, + { url = "https://files.pythonhosted.org/packages/40/42/c8523f2e4db34aa9389caee0d3688b6ada7a84fcc782e943a868a7f302bd/coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/8d/95/565c310fffa16ede1a042e9ea1ca3962af0d8eb5543bc72df6b91dc0c3d5/coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", size = 234649 }, + { url = "https://files.pythonhosted.org/packages/d5/81/3b550674d98968ec29c92e3e8650682be6c8b1fa7581a059e7e12e74c431/coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", size = 233744 }, + { url = "https://files.pythonhosted.org/packages/0d/70/d66c7f51b3e33aabc5ea9f9624c1c9d9655472962270eb5e7b0d32707224/coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", size = 232204 }, + { url = "https://files.pythonhosted.org/packages/23/2d/2b3a2dbed7a5f40693404c8a09e779d7c1a5fbed089d3e7224c002129ec8/coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", size = 233335 }, + { url = "https://files.pythonhosted.org/packages/5a/4f/92d1d2ad720d698a4e71c176eacf531bfb8e0721d5ad560556f2c484a513/coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", size = 209435 }, + { url = "https://files.pythonhosted.org/packages/c7/b9/cdf158e7991e2287bcf9082670928badb73d310047facac203ff8dcd5ff3/coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", size = 210243 }, + { url = "https://files.pythonhosted.org/packages/87/31/9c0cf84f0dfcbe4215b7eb95c31777cdc0483c13390e69584c8150c85175/coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", size = 206819 }, + { url = "https://files.pythonhosted.org/packages/53/ed/a38401079ad320ad6e054a01ec2b61d270511aeb3c201c80e99c841229d5/coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", size = 207263 }, + { url = "https://files.pythonhosted.org/packages/20/e7/c3ad33b179ab4213f0d70da25a9c214d52464efa11caeab438592eb1d837/coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", size = 239205 }, + { url = "https://files.pythonhosted.org/packages/36/91/fc02e8d8e694f557752120487fd982f654ba1421bbaa5560debf96ddceda/coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", size = 236612 }, + { url = "https://files.pythonhosted.org/packages/cc/57/cb08f0eda0389a9a8aaa4fc1f9fec7ac361c3e2d68efd5890d7042c18aa3/coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", size = 238479 }, + { url = "https://files.pythonhosted.org/packages/d5/c9/2c7681a9b3ca6e6f43d489c2e6653a53278ed857fd6e7010490c307b0a47/coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", size = 237405 }, + { url = "https://files.pythonhosted.org/packages/b5/4e/ebfc6944b96317df8b537ae875d2e57c27b84eb98820bc0a1055f358f056/coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", size = 236038 }, + { url = "https://files.pythonhosted.org/packages/13/f2/3a0bf1841a97c0654905e2ef531170f02c89fad2555879db8fe41a097871/coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", size = 236812 }, + { url = "https://files.pythonhosted.org/packages/b9/9c/66bf59226b52ce6ed9541b02d33e80a6e816a832558fbdc1111a7bd3abd4/coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", size = 209400 }, + { url = "https://files.pythonhosted.org/packages/2a/a0/b0790934c04dfc8d658d4a62acb8f7ca0efdf3818456fcad757b11c6479d/coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", size = 210243 }, + { url = "https://files.pythonhosted.org/packages/7d/e7/9291de916d084f41adddfd4b82246e68d61d6a75747f075f7e64628998d2/coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", size = 207013 }, + { url = "https://files.pythonhosted.org/packages/27/03/932c2c5717a7fa80cd43c6a07d3177076d97b79f12f40f882f9916db0063/coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", size = 207251 }, + { url = "https://files.pythonhosted.org/packages/d5/3f/0af47dcb9327f65a45455fbca846fe96eb57c153af46c4754a3ba678938a/coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", size = 240268 }, + { url = "https://files.pythonhosted.org/packages/8a/3c/37a9d81bbd4b23bc7d46ca820e16174c613579c66342faa390a271d2e18b/coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", size = 237298 }, + { url = "https://files.pythonhosted.org/packages/c0/70/6b0627e5bd68204ee580126ed3513140b2298995c1233bd67404b4e44d0e/coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", size = 239367 }, + { url = "https://files.pythonhosted.org/packages/3c/eb/634d7dfab24ac3b790bebaf9da0f4a5352cbc125ce6a9d5c6cf4c6cae3c7/coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", size = 238853 }, + { url = "https://files.pythonhosted.org/packages/d9/0d/8e3ed00f1266ef7472a4e33458f42e39492e01a64281084fb3043553d3f1/coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", size = 237160 }, + { url = "https://files.pythonhosted.org/packages/ce/9c/4337f468ef0ab7a2e0887a9c9da0e58e2eada6fc6cbee637a4acd5dfd8a9/coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", size = 238824 }, + { url = "https://files.pythonhosted.org/packages/5e/09/3e94912b8dd37251377bb02727a33a67ee96b84bbbe092f132b401ca5dd9/coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", size = 209639 }, + { url = "https://files.pythonhosted.org/packages/01/69/d4f3a4101171f32bc5b3caec8ff94c2c60f700107a6aaef7244b2c166793/coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", size = 210428 }, + { url = "https://files.pythonhosted.org/packages/c2/4d/2dede4f7cb5a70fb0bb40a57627fddf1dbdc6b9c1db81f7c4dcdcb19e2f4/coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", size = 207039 }, + { url = "https://files.pythonhosted.org/packages/3f/f9/d86368ae8c79e28f1fb458ebc76ae9ff3e8bd8069adc24e8f2fed03c58b7/coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", size = 207298 }, + { url = "https://files.pythonhosted.org/packages/64/c5/b4cc3c3f64622c58fbfd4d8b9a7a8ce9d355f172f91fcabbba1f026852f6/coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", size = 239813 }, + { url = "https://files.pythonhosted.org/packages/8a/86/14c42e60b70a79b26099e4d289ccdfefbc68624d096f4481163085aa614c/coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", size = 236959 }, + { url = "https://files.pythonhosted.org/packages/7f/f8/4436a643631a2fbab4b44d54f515028f6099bfb1cd95b13cfbf701e7f2f2/coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", size = 238950 }, + { url = "https://files.pythonhosted.org/packages/49/50/1571810ddd01f99a0a8be464a4ac8b147f322cd1e8e296a1528984fc560b/coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", size = 238610 }, + { url = "https://files.pythonhosted.org/packages/f3/8c/6312d241fe7cbd1f0cade34a62fea6f333d1a261255d76b9a87074d8703c/coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", size = 236697 }, + { url = "https://files.pythonhosted.org/packages/ce/5f/fef33dfd05d87ee9030f614c857deb6df6556b8f6a1c51bbbb41e24ee5ac/coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", size = 238541 }, + { url = "https://files.pythonhosted.org/packages/a9/64/6a984b6e92e1ea1353b7ffa08e27f707a5e29b044622445859200f541e8c/coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", size = 209707 }, + { url = "https://files.pythonhosted.org/packages/5c/60/ce5a9e942e9543783b3db5d942e0578b391c25cdd5e7f342d854ea83d6b7/coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", size = 210439 }, + { url = "https://files.pythonhosted.org/packages/78/53/6719677e92c308207e7f10561a1b16ab8b5c00e9328efc9af7cfd6fb703e/coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", size = 207784 }, + { url = "https://files.pythonhosted.org/packages/fa/dd/7054928930671fcb39ae6a83bb71d9ab5f0afb733172543ced4b09a115ca/coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", size = 208058 }, + { url = "https://files.pythonhosted.org/packages/b5/7d/fd656ddc2b38301927b9eb3aae3fe827e7aa82e691923ed43721fd9423c9/coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", size = 250772 }, + { url = "https://files.pythonhosted.org/packages/90/d0/eb9a3cc2100b83064bb086f18aedde3afffd7de6ead28f69736c00b7f302/coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", size = 246490 }, + { url = "https://files.pythonhosted.org/packages/45/44/3f64f38f6faab8a0cfd2c6bc6eb4c6daead246b97cf5f8fc23bf3788f841/coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", size = 248848 }, + { url = "https://files.pythonhosted.org/packages/5d/11/4c465a5f98656821e499f4b4619929bd5a34639c466021740ecdca42aa30/coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", size = 248340 }, + { url = "https://files.pythonhosted.org/packages/f1/96/ebecda2d016cce9da812f404f720ca5df83c6b29f65dc80d2000d0078741/coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", size = 246229 }, + { url = "https://files.pythonhosted.org/packages/16/d9/3d820c00066ae55d69e6d0eae11d6149a5ca7546de469ba9d597f01bf2d7/coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", size = 247510 }, + { url = "https://files.pythonhosted.org/packages/8f/c3/4fa1eb412bb288ff6bfcc163c11700ff06e02c5fad8513817186e460ed43/coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", size = 210353 }, + { url = "https://files.pythonhosted.org/packages/7e/77/03fc2979d1538884d921c2013075917fc927f41cd8526909852fe4494112/coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", size = 211502 }, + { url = "https://files.pythonhosted.org/packages/cc/56/e1d75e8981a2a92c2a777e67c26efa96c66da59d645423146eb9ff3a851b/coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", size = 198954 }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "cssutils" +version = "2.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "more-itertools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/9f/329d26121fe165be44b1dfff21aa0dc348f04633931f1d20ed6cf448a236/cssutils-2.11.1.tar.gz", hash = "sha256:0563a76513b6af6eebbe788c3bf3d01c920e46b3f90c8416738c5cfc773ff8e2", size = 711657 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/ec/bb273b7208c606890dc36540fe667d06ce840a6f62f9fae7e658fcdc90fb/cssutils-2.11.1-py3-none-any.whl", hash = "sha256:a67bfdfdff4f3867fab43698ec4897c1a828eca5973f4073321b3bccaf1199b1", size = 385747 }, +] + +[[package]] +name = "dict2css" +version = "0.3.0.post1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cssutils" }, + { name = "domdf-python-tools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/24/eb/776eef1f1aa0188c0fc165c3a60b71027539f71f2eedc43ad21b060e9c39/dict2css-0.3.0.post1.tar.gz", hash = "sha256:89c544c21c4ca7472c3fffb9d37d3d926f606329afdb751dc1de67a411b70719", size = 7845 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/47/290daabcf91628f4fc0e17c75a1690b354ba067066cd14407712600e609f/dict2css-0.3.0.post1-py3-none-any.whl", hash = "sha256:f006a6b774c3e31869015122ae82c491fd25e7de4a75607a62aa3e798f837e0d", size = 25647 }, +] + +[[package]] +name = "docutils" +version = "0.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408 }, +] + +[[package]] +name = "domdf-python-tools" +version = "3.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "natsort" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6b/78/974e10c583ba9d2302e748c9585313a7f2c7ba00e4f600324f432e38fe68/domdf_python_tools-3.9.0.tar.gz", hash = "sha256:1f8a96971178333a55e083e35610d7688cd7620ad2b99790164e1fc1a3614c18", size = 103792 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/e9/7447a88b217650a74927d3444a89507986479a69b83741900eddd34167fe/domdf_python_tools-3.9.0-py3-none-any.whl", hash = "sha256:4e1ef365cbc24627d6d1e90cf7d46d8ab8df967e1237f4a26885f6986c78872e", size = 127106 }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, +] + +[[package]] +name = "filelock" +version = "3.16.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 }, +] + +[[package]] +name = "furo" +version = "2024.8.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "pygments" }, + { name = "sphinx" }, + { name = "sphinx-basic-ng" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a0/e2/d351d69a9a9e4badb4a5be062c2d0e87bd9e6c23b5e57337fef14bef34c8/furo-2024.8.6.tar.gz", hash = "sha256:b63e4cee8abfc3136d3bc03a3d45a76a850bada4d6374d24c1716b0e01394a01", size = 1661506 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/48/e791a7ed487dbb9729ef32bb5d1af16693d8925f4366befef54119b2e576/furo-2024.8.6-py3-none-any.whl", hash = "sha256:6cd97c58b47813d3619e63e9081169880fbe331f0ca883c871ff1f3f11814f5c", size = 341333 }, +] + +[[package]] +name = "h11" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, +] + +[[package]] +name = "html5lib" +version = "1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/b6/b55c3f49042f1df3dcd422b7f224f939892ee94f22abcf503a9b7339eaf2/html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f", size = 272215 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d", size = 112173 }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769 }, +] + +[[package]] +name = "importlib-metadata" +version = "8.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", size = 55304 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/d9/a1e041c5e7caa9a05c925f4bdbdfb7f006d1f74996af53467bc394c97be7/importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", size = 26514 }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "jinja2" +version = "3.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 }, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595 }, +] + +[[package]] +name = "linkify-it-py" +version = "2.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "uc-micro-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/ae/bb56c6828e4797ba5a4821eec7c43b8bf40f69cda4d4f5f8c8a2810ec96a/linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048", size = 27946 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/1e/b832de447dee8b582cac175871d2f6c3d5077cc56d5575cadba1fd1cccfa/linkify_it_py-2.0.3-py3-none-any.whl", hash = "sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79", size = 19820 }, +] + +[[package]] +name = "lxml" +version = "5.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/6b/20c3a4b24751377aaa6307eb230b66701024012c29dd374999cc92983269/lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f", size = 3679318 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/ce/2789e39eddf2b13fac29878bfa465f0910eb6b0096e29090e5176bc8cf43/lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656", size = 8124570 }, + { url = "https://files.pythonhosted.org/packages/24/a8/f4010166a25d41715527129af2675981a50d3bbf7df09c5d9ab8ca24fbf9/lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d", size = 4413042 }, + { url = "https://files.pythonhosted.org/packages/41/a4/7e45756cecdd7577ddf67a68b69c1db0f5ddbf0c9f65021ee769165ffc5a/lxml-5.3.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:501d0d7e26b4d261fca8132854d845e4988097611ba2531408ec91cf3fd9d20a", size = 5139213 }, + { url = "https://files.pythonhosted.org/packages/02/e2/ecf845b12323c92748077e1818b64e8b4dba509a4cb12920b3762ebe7552/lxml-5.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb66442c2546446944437df74379e9cf9e9db353e61301d1a0e26482f43f0dd8", size = 4838814 }, + { url = "https://files.pythonhosted.org/packages/12/91/619f9fb72cf75e9ceb8700706f7276f23995f6ad757e6d400fbe35ca4990/lxml-5.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e41506fec7a7f9405b14aa2d5c8abbb4dbbd09d88f9496958b6d00cb4d45330", size = 5425084 }, + { url = "https://files.pythonhosted.org/packages/25/3b/162a85a8f0fd2a3032ec3f936636911c6e9523a8e263fffcfd581ce98b54/lxml-5.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f7d4a670107d75dfe5ad080bed6c341d18c4442f9378c9f58e5851e86eb79965", size = 4875993 }, + { url = "https://files.pythonhosted.org/packages/43/af/dd3f58cc7d946da6ae42909629a2b1d5dd2d1b583334d4af9396697d6863/lxml-5.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41ce1f1e2c7755abfc7e759dc34d7d05fd221723ff822947132dc934d122fe22", size = 5012462 }, + { url = "https://files.pythonhosted.org/packages/69/c1/5ea46b2d4c98f5bf5c83fffab8a0ad293c9bc74df9ecfbafef10f77f7201/lxml-5.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:44264ecae91b30e5633013fb66f6ddd05c006d3e0e884f75ce0b4755b3e3847b", size = 4815288 }, + { url = "https://files.pythonhosted.org/packages/1d/51/a0acca077ad35da458f4d3f729ef98effd2b90f003440d35fc36323f8ae6/lxml-5.3.0-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:3c174dc350d3ec52deb77f2faf05c439331d6ed5e702fc247ccb4e6b62d884b7", size = 5472435 }, + { url = "https://files.pythonhosted.org/packages/4d/6b/0989c9368986961a6b0f55b46c80404c4b758417acdb6d87bfc3bd5f4967/lxml-5.3.0-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:2dfab5fa6a28a0b60a20638dc48e6343c02ea9933e3279ccb132f555a62323d8", size = 4976354 }, + { url = "https://files.pythonhosted.org/packages/05/9e/87492d03ff604fbf656ed2bf3e2e8d28f5d58ea1f00ff27ac27b06509079/lxml-5.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b1c8c20847b9f34e98080da785bb2336ea982e7f913eed5809e5a3c872900f32", size = 5029973 }, + { url = "https://files.pythonhosted.org/packages/f9/cc/9ae1baf5472af88e19e2c454b3710c1be9ecafb20eb474eeabcd88a055d2/lxml-5.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2c86bf781b12ba417f64f3422cfc302523ac9cd1d8ae8c0f92a1c66e56ef2e86", size = 4888837 }, + { url = "https://files.pythonhosted.org/packages/d2/10/5594ffaec8c120d75b17e3ad23439b740a51549a9b5fd7484b2179adfe8f/lxml-5.3.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c162b216070f280fa7da844531169be0baf9ccb17263cf5a8bf876fcd3117fa5", size = 5530555 }, + { url = "https://files.pythonhosted.org/packages/ea/9b/de17f05377c8833343b629905571fb06cff2028f15a6f58ae2267662e341/lxml-5.3.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:36aef61a1678cb778097b4a6eeae96a69875d51d1e8f4d4b491ab3cfb54b5a03", size = 5405314 }, + { url = "https://files.pythonhosted.org/packages/8a/b4/227be0f1f3cca8255925985164c3838b8b36e441ff0cc10c1d3c6bdba031/lxml-5.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f65e5120863c2b266dbcc927b306c5b78e502c71edf3295dfcb9501ec96e5fc7", size = 5079303 }, + { url = "https://files.pythonhosted.org/packages/5c/ee/19abcebb7fc40319bb71cd6adefa1ad94d09b5660228715854d6cc420713/lxml-5.3.0-cp310-cp310-win32.whl", hash = "sha256:ef0c1fe22171dd7c7c27147f2e9c3e86f8bdf473fed75f16b0c2e84a5030ce80", size = 3475126 }, + { url = "https://files.pythonhosted.org/packages/a1/35/183d32551447e280032b2331738cd850da435a42f850b71ebeaab42c1313/lxml-5.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:052d99051e77a4f3e8482c65014cf6372e61b0a6f4fe9edb98503bb5364cfee3", size = 3805065 }, + { url = "https://files.pythonhosted.org/packages/5c/a8/449faa2a3cbe6a99f8d38dcd51a3ee8844c17862841a6f769ea7c2a9cd0f/lxml-5.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74bcb423462233bc5d6066e4e98b0264e7c1bed7541fff2f4e34fe6b21563c8b", size = 8141056 }, + { url = "https://files.pythonhosted.org/packages/ac/8a/ae6325e994e2052de92f894363b038351c50ee38749d30cc6b6d96aaf90f/lxml-5.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a3d819eb6f9b8677f57f9664265d0a10dd6551d227afb4af2b9cd7bdc2ccbf18", size = 4425238 }, + { url = "https://files.pythonhosted.org/packages/f8/fb/128dddb7f9086236bce0eeae2bfb316d138b49b159f50bc681d56c1bdd19/lxml-5.3.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b8f5db71b28b8c404956ddf79575ea77aa8b1538e8b2ef9ec877945b3f46442", size = 5095197 }, + { url = "https://files.pythonhosted.org/packages/b4/f9/a181a8ef106e41e3086629c8bdb2d21a942f14c84a0e77452c22d6b22091/lxml-5.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3406b63232fc7e9b8783ab0b765d7c59e7c59ff96759d8ef9632fca27c7ee4", size = 4809809 }, + { url = "https://files.pythonhosted.org/packages/25/2f/b20565e808f7f6868aacea48ddcdd7e9e9fb4c799287f21f1a6c7c2e8b71/lxml-5.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ecdd78ab768f844c7a1d4a03595038c166b609f6395e25af9b0f3f26ae1230f", size = 5407593 }, + { url = "https://files.pythonhosted.org/packages/23/0e/caac672ec246d3189a16c4d364ed4f7d6bf856c080215382c06764058c08/lxml-5.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168f2dfcfdedf611eb285efac1516c8454c8c99caf271dccda8943576b67552e", size = 4866657 }, + { url = "https://files.pythonhosted.org/packages/67/a4/1f5fbd3f58d4069000522196b0b776a014f3feec1796da03e495cf23532d/lxml-5.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa617107a410245b8660028a7483b68e7914304a6d4882b5ff3d2d3eb5948d8c", size = 4967017 }, + { url = "https://files.pythonhosted.org/packages/ee/73/623ecea6ca3c530dd0a4ed0d00d9702e0e85cd5624e2d5b93b005fe00abd/lxml-5.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:69959bd3167b993e6e710b99051265654133a98f20cec1d9b493b931942e9c16", size = 4810730 }, + { url = "https://files.pythonhosted.org/packages/1d/ce/fb84fb8e3c298f3a245ae3ea6221c2426f1bbaa82d10a88787412a498145/lxml-5.3.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:bd96517ef76c8654446fc3db9242d019a1bb5fe8b751ba414765d59f99210b79", size = 5455154 }, + { url = "https://files.pythonhosted.org/packages/b1/72/4d1ad363748a72c7c0411c28be2b0dc7150d91e823eadad3b91a4514cbea/lxml-5.3.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:ab6dd83b970dc97c2d10bc71aa925b84788c7c05de30241b9e96f9b6d9ea3080", size = 4969416 }, + { url = "https://files.pythonhosted.org/packages/42/07/b29571a58a3a80681722ea8ed0ba569211d9bb8531ad49b5cacf6d409185/lxml-5.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eec1bb8cdbba2925bedc887bc0609a80e599c75b12d87ae42ac23fd199445654", size = 5013672 }, + { url = "https://files.pythonhosted.org/packages/b9/93/bde740d5a58cf04cbd38e3dd93ad1e36c2f95553bbf7d57807bc6815d926/lxml-5.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a7095eeec6f89111d03dabfe5883a1fd54da319c94e0fb104ee8f23616b572d", size = 4878644 }, + { url = "https://files.pythonhosted.org/packages/56/b5/645c8c02721d49927c93181de4017164ec0e141413577687c3df8ff0800f/lxml-5.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6f651ebd0b21ec65dfca93aa629610a0dbc13dbc13554f19b0113da2e61a4763", size = 5511531 }, + { url = "https://files.pythonhosted.org/packages/85/3f/6a99a12d9438316f4fc86ef88c5d4c8fb674247b17f3173ecadd8346b671/lxml-5.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f422a209d2455c56849442ae42f25dbaaba1c6c3f501d58761c619c7836642ec", size = 5402065 }, + { url = "https://files.pythonhosted.org/packages/80/8a/df47bff6ad5ac57335bf552babfb2408f9eb680c074ec1ba412a1a6af2c5/lxml-5.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62f7fdb0d1ed2065451f086519865b4c90aa19aed51081979ecd05a21eb4d1be", size = 5069775 }, + { url = "https://files.pythonhosted.org/packages/08/ae/e7ad0f0fbe4b6368c5ee1e3ef0c3365098d806d42379c46c1ba2802a52f7/lxml-5.3.0-cp311-cp311-win32.whl", hash = "sha256:c6379f35350b655fd817cd0d6cbeef7f265f3ae5fedb1caae2eb442bbeae9ab9", size = 3474226 }, + { url = "https://files.pythonhosted.org/packages/c3/b5/91c2249bfac02ee514ab135e9304b89d55967be7e53e94a879b74eec7a5c/lxml-5.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c52100e2c2dbb0649b90467935c4b0de5528833c76a35ea1a2691ec9f1ee7a1", size = 3814971 }, + { url = "https://files.pythonhosted.org/packages/eb/6d/d1f1c5e40c64bf62afd7a3f9b34ce18a586a1cccbf71e783cd0a6d8e8971/lxml-5.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859", size = 8171753 }, + { url = "https://files.pythonhosted.org/packages/bd/83/26b1864921869784355459f374896dcf8b44d4af3b15d7697e9156cb2de9/lxml-5.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e", size = 4441955 }, + { url = "https://files.pythonhosted.org/packages/e0/d2/e9bff9fb359226c25cda3538f664f54f2804f4b37b0d7c944639e1a51f69/lxml-5.3.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f", size = 5050778 }, + { url = "https://files.pythonhosted.org/packages/88/69/6972bfafa8cd3ddc8562b126dd607011e218e17be313a8b1b9cc5a0ee876/lxml-5.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e", size = 4748628 }, + { url = "https://files.pythonhosted.org/packages/5d/ea/a6523c7c7f6dc755a6eed3d2f6d6646617cad4d3d6d8ce4ed71bfd2362c8/lxml-5.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179", size = 5322215 }, + { url = "https://files.pythonhosted.org/packages/99/37/396fbd24a70f62b31d988e4500f2068c7f3fd399d2fd45257d13eab51a6f/lxml-5.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a", size = 4813963 }, + { url = "https://files.pythonhosted.org/packages/09/91/e6136f17459a11ce1757df864b213efbeab7adcb2efa63efb1b846ab6723/lxml-5.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3", size = 4923353 }, + { url = "https://files.pythonhosted.org/packages/1d/7c/2eeecf87c9a1fca4f84f991067c693e67340f2b7127fc3eca8fa29d75ee3/lxml-5.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1", size = 4740541 }, + { url = "https://files.pythonhosted.org/packages/3b/ed/4c38ba58defca84f5f0d0ac2480fdcd99fc7ae4b28fc417c93640a6949ae/lxml-5.3.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d", size = 5346504 }, + { url = "https://files.pythonhosted.org/packages/a5/22/bbd3995437e5745cb4c2b5d89088d70ab19d4feabf8a27a24cecb9745464/lxml-5.3.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c", size = 4898077 }, + { url = "https://files.pythonhosted.org/packages/0a/6e/94537acfb5b8f18235d13186d247bca478fea5e87d224644e0fe907df976/lxml-5.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99", size = 4946543 }, + { url = "https://files.pythonhosted.org/packages/8d/e8/4b15df533fe8e8d53363b23a41df9be907330e1fa28c7ca36893fad338ee/lxml-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff", size = 4816841 }, + { url = "https://files.pythonhosted.org/packages/1a/e7/03f390ea37d1acda50bc538feb5b2bda6745b25731e4e76ab48fae7106bf/lxml-5.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a", size = 5417341 }, + { url = "https://files.pythonhosted.org/packages/ea/99/d1133ab4c250da85a883c3b60249d3d3e7c64f24faff494cf0fd23f91e80/lxml-5.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8", size = 5327539 }, + { url = "https://files.pythonhosted.org/packages/7d/ed/e6276c8d9668028213df01f598f385b05b55a4e1b4662ee12ef05dab35aa/lxml-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d", size = 5012542 }, + { url = "https://files.pythonhosted.org/packages/36/88/684d4e800f5aa28df2a991a6a622783fb73cf0e46235cfa690f9776f032e/lxml-5.3.0-cp312-cp312-win32.whl", hash = "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30", size = 3486454 }, + { url = "https://files.pythonhosted.org/packages/fc/82/ace5a5676051e60355bd8fb945df7b1ba4f4fb8447f2010fb816bfd57724/lxml-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f", size = 3816857 }, + { url = "https://files.pythonhosted.org/packages/94/6a/42141e4d373903bfea6f8e94b2f554d05506dfda522ada5343c651410dc8/lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a", size = 8156284 }, + { url = "https://files.pythonhosted.org/packages/91/5e/fa097f0f7d8b3d113fb7312c6308af702f2667f22644441715be961f2c7e/lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd", size = 4432407 }, + { url = "https://files.pythonhosted.org/packages/2d/a1/b901988aa6d4ff937f2e5cfc114e4ec561901ff00660c3e56713642728da/lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51", size = 5048331 }, + { url = "https://files.pythonhosted.org/packages/30/0f/b2a54f48e52de578b71bbe2a2f8160672a8a5e103df3a78da53907e8c7ed/lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b", size = 4744835 }, + { url = "https://files.pythonhosted.org/packages/82/9d/b000c15538b60934589e83826ecbc437a1586488d7c13f8ee5ff1f79a9b8/lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002", size = 5316649 }, + { url = "https://files.pythonhosted.org/packages/e3/ee/ffbb9eaff5e541922611d2c56b175c45893d1c0b8b11e5a497708a6a3b3b/lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4", size = 4812046 }, + { url = "https://files.pythonhosted.org/packages/15/ff/7ff89d567485c7b943cdac316087f16b2399a8b997007ed352a1248397e5/lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492", size = 4918597 }, + { url = "https://files.pythonhosted.org/packages/c6/a3/535b6ed8c048412ff51268bdf4bf1cf052a37aa7e31d2e6518038a883b29/lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3", size = 4738071 }, + { url = "https://files.pythonhosted.org/packages/7a/8f/cbbfa59cb4d4fd677fe183725a76d8c956495d7a3c7f111ab8f5e13d2e83/lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4", size = 5342213 }, + { url = "https://files.pythonhosted.org/packages/5c/fb/db4c10dd9958d4b52e34d1d1f7c1f434422aeaf6ae2bbaaff2264351d944/lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367", size = 4893749 }, + { url = "https://files.pythonhosted.org/packages/f2/38/bb4581c143957c47740de18a3281a0cab7722390a77cc6e610e8ebf2d736/lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832", size = 4945901 }, + { url = "https://files.pythonhosted.org/packages/fc/d5/18b7de4960c731e98037bd48fa9f8e6e8f2558e6fbca4303d9b14d21ef3b/lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff", size = 4815447 }, + { url = "https://files.pythonhosted.org/packages/97/a8/cd51ceaad6eb849246559a8ef60ae55065a3df550fc5fcd27014361c1bab/lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd", size = 5411186 }, + { url = "https://files.pythonhosted.org/packages/89/c3/1e3dabab519481ed7b1fdcba21dcfb8832f57000733ef0e71cf6d09a5e03/lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb", size = 5324481 }, + { url = "https://files.pythonhosted.org/packages/b6/17/71e9984cf0570cd202ac0a1c9ed5c1b8889b0fc8dc736f5ef0ffb181c284/lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b", size = 5011053 }, + { url = "https://files.pythonhosted.org/packages/69/68/9f7e6d3312a91e30829368c2b3217e750adef12a6f8eb10498249f4e8d72/lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957", size = 3485634 }, + { url = "https://files.pythonhosted.org/packages/7d/db/214290d58ad68c587bd5d6af3d34e56830438733d0d0856c0275fde43652/lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d", size = 3814417 }, + { url = "https://files.pythonhosted.org/packages/99/f7/b73a431c8500565aa500e99e60b448d305eaf7c0b4c893c7c5a8a69cc595/lxml-5.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7b1cd427cb0d5f7393c31b7496419da594fe600e6fdc4b105a54f82405e6626c", size = 3925431 }, + { url = "https://files.pythonhosted.org/packages/db/48/4a206623c0d093d0e3b15f415ffb4345b0bdf661a3d0b15a112948c033c7/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51806cfe0279e06ed8500ce19479d757db42a30fd509940b1701be9c86a5ff9a", size = 4216683 }, + { url = "https://files.pythonhosted.org/packages/54/47/577820c45dd954523ae8453b632d91e76da94ca6d9ee40d8c98dd86f916b/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee70d08fd60c9565ba8190f41a46a54096afa0eeb8f76bd66f2c25d3b1b83005", size = 4326732 }, + { url = "https://files.pythonhosted.org/packages/68/de/96cb6d3269bc994b4f5ede8ca7bf0840f5de0a278bc6e50cb317ff71cafa/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:8dc2c0395bea8254d8daebc76dcf8eb3a95ec2a46fa6fae5eaccee366bfe02ce", size = 4218377 }, + { url = "https://files.pythonhosted.org/packages/a5/43/19b1ef6cbffa4244a217f95cc5f41a6cb4720fed33510a49670b03c5f1a0/lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6ba0d3dcac281aad8a0e5b14c7ed6f9fa89c8612b47939fc94f80b16e2e9bc83", size = 4351237 }, + { url = "https://files.pythonhosted.org/packages/ba/b2/6a22fb5c0885da3b00e116aee81f0b829ec9ac8f736cd414b4a09413fc7d/lxml-5.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6e91cf736959057f7aac7adfc83481e03615a8e8dd5758aa1d95ea69e8931dba", size = 3487557 }, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357 }, + { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393 }, + { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732 }, + { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866 }, + { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964 }, + { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977 }, + { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366 }, + { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091 }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, +] + +[[package]] +name = "mdit-py-plugins" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/03/a2ecab526543b152300717cf232bb4bb8605b6edb946c845016fa9c9c9fd/mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5", size = 43542 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636", size = 55316 }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, +] + +[[package]] +name = "more-itertools" +version = "10.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/78/65922308c4248e0eb08ebcbe67c95d48615cc6f27854b6f2e57143e9178f/more-itertools-10.5.0.tar.gz", hash = "sha256:5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6", size = 121020 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/7e/3a64597054a70f7c86eb0a7d4fc315b8c1ab932f64883a297bdffeb5f967/more_itertools-10.5.0-py3-none-any.whl", hash = "sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef", size = 60952 }, +] + +[[package]] +name = "msgpack" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/d0/7555686ae7ff5731205df1012ede15dd9d927f6227ea151e901c7406af4f/msgpack-1.1.0.tar.gz", hash = "sha256:dd432ccc2c72b914e4cb77afce64aab761c1137cc698be3984eee260bcb2896e", size = 167260 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/f9/a892a6038c861fa849b11a2bb0502c07bc698ab6ea53359e5771397d883b/msgpack-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ad442d527a7e358a469faf43fda45aaf4ac3249c8310a82f0ccff9164e5dccd", size = 150428 }, + { url = "https://files.pythonhosted.org/packages/df/7a/d174cc6a3b6bb85556e6a046d3193294a92f9a8e583cdbd46dc8a1d7e7f4/msgpack-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:74bed8f63f8f14d75eec75cf3d04ad581da6b914001b474a5d3cd3372c8cc27d", size = 84131 }, + { url = "https://files.pythonhosted.org/packages/08/52/bf4fbf72f897a23a56b822997a72c16de07d8d56d7bf273242f884055682/msgpack-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:914571a2a5b4e7606997e169f64ce53a8b1e06f2cf2c3a7273aa106236d43dd5", size = 81215 }, + { url = "https://files.pythonhosted.org/packages/02/95/dc0044b439b518236aaf012da4677c1b8183ce388411ad1b1e63c32d8979/msgpack-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c921af52214dcbb75e6bdf6a661b23c3e6417f00c603dd2070bccb5c3ef499f5", size = 371229 }, + { url = "https://files.pythonhosted.org/packages/ff/75/09081792db60470bef19d9c2be89f024d366b1e1973c197bb59e6aabc647/msgpack-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8ce0b22b890be5d252de90d0e0d119f363012027cf256185fc3d474c44b1b9e", size = 378034 }, + { url = "https://files.pythonhosted.org/packages/32/d3/c152e0c55fead87dd948d4b29879b0f14feeeec92ef1fd2ec21b107c3f49/msgpack-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:73322a6cc57fcee3c0c57c4463d828e9428275fb85a27aa2aa1a92fdc42afd7b", size = 363070 }, + { url = "https://files.pythonhosted.org/packages/d9/2c/82e73506dd55f9e43ac8aa007c9dd088c6f0de2aa19e8f7330e6a65879fc/msgpack-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e1f3c3d21f7cf67bcf2da8e494d30a75e4cf60041d98b3f79875afb5b96f3a3f", size = 359863 }, + { url = "https://files.pythonhosted.org/packages/cb/a0/3d093b248837094220e1edc9ec4337de3443b1cfeeb6e0896af8ccc4cc7a/msgpack-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64fc9068d701233effd61b19efb1485587560b66fe57b3e50d29c5d78e7fef68", size = 368166 }, + { url = "https://files.pythonhosted.org/packages/e4/13/7646f14f06838b406cf5a6ddbb7e8dc78b4996d891ab3b93c33d1ccc8678/msgpack-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:42f754515e0f683f9c79210a5d1cad631ec3d06cea5172214d2176a42e67e19b", size = 370105 }, + { url = "https://files.pythonhosted.org/packages/67/fa/dbbd2443e4578e165192dabbc6a22c0812cda2649261b1264ff515f19f15/msgpack-1.1.0-cp310-cp310-win32.whl", hash = "sha256:3df7e6b05571b3814361e8464f9304c42d2196808e0119f55d0d3e62cd5ea044", size = 68513 }, + { url = "https://files.pythonhosted.org/packages/24/ce/c2c8fbf0ded750cb63cbcbb61bc1f2dfd69e16dca30a8af8ba80ec182dcd/msgpack-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:685ec345eefc757a7c8af44a3032734a739f8c45d1b0ac45efc5d8977aa4720f", size = 74687 }, + { url = "https://files.pythonhosted.org/packages/b7/5e/a4c7154ba65d93be91f2f1e55f90e76c5f91ccadc7efc4341e6f04c8647f/msgpack-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3d364a55082fb2a7416f6c63ae383fbd903adb5a6cf78c5b96cc6316dc1cedc7", size = 150803 }, + { url = "https://files.pythonhosted.org/packages/60/c2/687684164698f1d51c41778c838d854965dd284a4b9d3a44beba9265c931/msgpack-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79ec007767b9b56860e0372085f8504db5d06bd6a327a335449508bbee9648fa", size = 84343 }, + { url = "https://files.pythonhosted.org/packages/42/ae/d3adea9bb4a1342763556078b5765e666f8fdf242e00f3f6657380920972/msgpack-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6ad622bf7756d5a497d5b6836e7fc3752e2dd6f4c648e24b1803f6048596f701", size = 81408 }, + { url = "https://files.pythonhosted.org/packages/dc/17/6313325a6ff40ce9c3207293aee3ba50104aed6c2c1559d20d09e5c1ff54/msgpack-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e59bca908d9ca0de3dc8684f21ebf9a690fe47b6be93236eb40b99af28b6ea6", size = 396096 }, + { url = "https://files.pythonhosted.org/packages/a8/a1/ad7b84b91ab5a324e707f4c9761633e357820b011a01e34ce658c1dda7cc/msgpack-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e1da8f11a3dd397f0a32c76165cf0c4eb95b31013a94f6ecc0b280c05c91b59", size = 403671 }, + { url = "https://files.pythonhosted.org/packages/bb/0b/fd5b7c0b308bbf1831df0ca04ec76fe2f5bf6319833646b0a4bd5e9dc76d/msgpack-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:452aff037287acb1d70a804ffd022b21fa2bb7c46bee884dbc864cc9024128a0", size = 387414 }, + { url = "https://files.pythonhosted.org/packages/f0/03/ff8233b7c6e9929a1f5da3c7860eccd847e2523ca2de0d8ef4878d354cfa/msgpack-1.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8da4bf6d54ceed70e8861f833f83ce0814a2b72102e890cbdfe4b34764cdd66e", size = 383759 }, + { url = "https://files.pythonhosted.org/packages/1f/1b/eb82e1fed5a16dddd9bc75f0854b6e2fe86c0259c4353666d7fab37d39f4/msgpack-1.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:41c991beebf175faf352fb940bf2af9ad1fb77fd25f38d9142053914947cdbf6", size = 394405 }, + { url = "https://files.pythonhosted.org/packages/90/2e/962c6004e373d54ecf33d695fb1402f99b51832631e37c49273cc564ffc5/msgpack-1.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a52a1f3a5af7ba1c9ace055b659189f6c669cf3657095b50f9602af3a3ba0fe5", size = 396041 }, + { url = "https://files.pythonhosted.org/packages/f8/20/6e03342f629474414860c48aeffcc2f7f50ddaf351d95f20c3f1c67399a8/msgpack-1.1.0-cp311-cp311-win32.whl", hash = "sha256:58638690ebd0a06427c5fe1a227bb6b8b9fdc2bd07701bec13c2335c82131a88", size = 68538 }, + { url = "https://files.pythonhosted.org/packages/aa/c4/5a582fc9a87991a3e6f6800e9bb2f3c82972912235eb9539954f3e9997c7/msgpack-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fd2906780f25c8ed5d7b323379f6138524ba793428db5d0e9d226d3fa6aa1788", size = 74871 }, + { url = "https://files.pythonhosted.org/packages/e1/d6/716b7ca1dbde63290d2973d22bbef1b5032ca634c3ff4384a958ec3f093a/msgpack-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d46cf9e3705ea9485687aa4001a76e44748b609d260af21c4ceea7f2212a501d", size = 152421 }, + { url = "https://files.pythonhosted.org/packages/70/da/5312b067f6773429cec2f8f08b021c06af416bba340c912c2ec778539ed6/msgpack-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5dbad74103df937e1325cc4bfeaf57713be0b4f15e1c2da43ccdd836393e2ea2", size = 85277 }, + { url = "https://files.pythonhosted.org/packages/28/51/da7f3ae4462e8bb98af0d5bdf2707f1b8c65a0d4f496e46b6afb06cbc286/msgpack-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:58dfc47f8b102da61e8949708b3eafc3504509a5728f8b4ddef84bd9e16ad420", size = 82222 }, + { url = "https://files.pythonhosted.org/packages/33/af/dc95c4b2a49cff17ce47611ca9ba218198806cad7796c0b01d1e332c86bb/msgpack-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676e5be1b472909b2ee6356ff425ebedf5142427842aa06b4dfd5117d1ca8a2", size = 392971 }, + { url = "https://files.pythonhosted.org/packages/f1/54/65af8de681fa8255402c80eda2a501ba467921d5a7a028c9c22a2c2eedb5/msgpack-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17fb65dd0bec285907f68b15734a993ad3fc94332b5bb21b0435846228de1f39", size = 401403 }, + { url = "https://files.pythonhosted.org/packages/97/8c/e333690777bd33919ab7024269dc3c41c76ef5137b211d776fbb404bfead/msgpack-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a51abd48c6d8ac89e0cfd4fe177c61481aca2d5e7ba42044fd218cfd8ea9899f", size = 385356 }, + { url = "https://files.pythonhosted.org/packages/57/52/406795ba478dc1c890559dd4e89280fa86506608a28ccf3a72fbf45df9f5/msgpack-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2137773500afa5494a61b1208619e3871f75f27b03bcfca7b3a7023284140247", size = 383028 }, + { url = "https://files.pythonhosted.org/packages/e7/69/053b6549bf90a3acadcd8232eae03e2fefc87f066a5b9fbb37e2e608859f/msgpack-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:398b713459fea610861c8a7b62a6fec1882759f308ae0795b5413ff6a160cf3c", size = 391100 }, + { url = "https://files.pythonhosted.org/packages/23/f0/d4101d4da054f04274995ddc4086c2715d9b93111eb9ed49686c0f7ccc8a/msgpack-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:06f5fd2f6bb2a7914922d935d3b8bb4a7fff3a9a91cfce6d06c13bc42bec975b", size = 394254 }, + { url = "https://files.pythonhosted.org/packages/1c/12/cf07458f35d0d775ff3a2dc5559fa2e1fcd06c46f1ef510e594ebefdca01/msgpack-1.1.0-cp312-cp312-win32.whl", hash = "sha256:ad33e8400e4ec17ba782f7b9cf868977d867ed784a1f5f2ab46e7ba53b6e1e1b", size = 69085 }, + { url = "https://files.pythonhosted.org/packages/73/80/2708a4641f7d553a63bc934a3eb7214806b5b39d200133ca7f7afb0a53e8/msgpack-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:115a7af8ee9e8cddc10f87636767857e7e3717b7a2e97379dc2054712693e90f", size = 75347 }, + { url = "https://files.pythonhosted.org/packages/c8/b0/380f5f639543a4ac413e969109978feb1f3c66e931068f91ab6ab0f8be00/msgpack-1.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:071603e2f0771c45ad9bc65719291c568d4edf120b44eb36324dcb02a13bfddf", size = 151142 }, + { url = "https://files.pythonhosted.org/packages/c8/ee/be57e9702400a6cb2606883d55b05784fada898dfc7fd12608ab1fdb054e/msgpack-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0f92a83b84e7c0749e3f12821949d79485971f087604178026085f60ce109330", size = 84523 }, + { url = "https://files.pythonhosted.org/packages/7e/3a/2919f63acca3c119565449681ad08a2f84b2171ddfcff1dba6959db2cceb/msgpack-1.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1964df7b81285d00a84da4e70cb1383f2e665e0f1f2a7027e683956d04b734", size = 81556 }, + { url = "https://files.pythonhosted.org/packages/7c/43/a11113d9e5c1498c145a8925768ea2d5fce7cbab15c99cda655aa09947ed/msgpack-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59caf6a4ed0d164055ccff8fe31eddc0ebc07cf7326a2aaa0dbf7a4001cd823e", size = 392105 }, + { url = "https://files.pythonhosted.org/packages/2d/7b/2c1d74ca6c94f70a1add74a8393a0138172207dc5de6fc6269483519d048/msgpack-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0907e1a7119b337971a689153665764adc34e89175f9a34793307d9def08e6ca", size = 399979 }, + { url = "https://files.pythonhosted.org/packages/82/8c/cf64ae518c7b8efc763ca1f1348a96f0e37150061e777a8ea5430b413a74/msgpack-1.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65553c9b6da8166e819a6aa90ad15288599b340f91d18f60b2061f402b9a4915", size = 383816 }, + { url = "https://files.pythonhosted.org/packages/69/86/a847ef7a0f5ef3fa94ae20f52a4cacf596a4e4a010197fbcc27744eb9a83/msgpack-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7a946a8992941fea80ed4beae6bff74ffd7ee129a90b4dd5cf9c476a30e9708d", size = 380973 }, + { url = "https://files.pythonhosted.org/packages/aa/90/c74cf6e1126faa93185d3b830ee97246ecc4fe12cf9d2d31318ee4246994/msgpack-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4b51405e36e075193bc051315dbf29168d6141ae2500ba8cd80a522964e31434", size = 387435 }, + { url = "https://files.pythonhosted.org/packages/7a/40/631c238f1f338eb09f4acb0f34ab5862c4e9d7eda11c1b685471a4c5ea37/msgpack-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4c01941fd2ff87c2a934ee6055bda4ed353a7846b8d4f341c428109e9fcde8c", size = 399082 }, + { url = "https://files.pythonhosted.org/packages/e9/1b/fa8a952be252a1555ed39f97c06778e3aeb9123aa4cccc0fd2acd0b4e315/msgpack-1.1.0-cp313-cp313-win32.whl", hash = "sha256:7c9a35ce2c2573bada929e0b7b3576de647b0defbd25f5139dcdaba0ae35a4cc", size = 69037 }, + { url = "https://files.pythonhosted.org/packages/b6/bc/8bd826dd03e022153bfa1766dcdec4976d6c818865ed54223d71f07862b3/msgpack-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:bce7d9e614a04d0883af0b3d4d501171fbfca038f12c77fa838d9f198147a23f", size = 75140 }, +] + +[[package]] +name = "mypy" +version = "1.11.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5c/86/5d7cbc4974fd564550b80fbb8103c05501ea11aa7835edf3351d90095896/mypy-1.11.2.tar.gz", hash = "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79", size = 3078806 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/cd/815368cd83c3a31873e5e55b317551500b12f2d1d7549720632f32630333/mypy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a", size = 10939401 }, + { url = "https://files.pythonhosted.org/packages/f1/27/e18c93a195d2fad75eb96e1f1cbc431842c332e8eba2e2b77eaf7313c6b7/mypy-1.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef", size = 10111697 }, + { url = "https://files.pythonhosted.org/packages/dc/08/cdc1fc6d0d5a67d354741344cc4aa7d53f7128902ebcbe699ddd4f15a61c/mypy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383", size = 12500508 }, + { url = "https://files.pythonhosted.org/packages/64/12/aad3af008c92c2d5d0720ea3b6674ba94a98cdb86888d389acdb5f218c30/mypy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8", size = 13020712 }, + { url = "https://files.pythonhosted.org/packages/03/e6/a7d97cc124a565be5e9b7d5c2a6ebf082379ffba99646e4863ed5bbcb3c3/mypy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7", size = 9567319 }, + { url = "https://files.pythonhosted.org/packages/e2/aa/cc56fb53ebe14c64f1fe91d32d838d6f4db948b9494e200d2f61b820b85d/mypy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385", size = 10859630 }, + { url = "https://files.pythonhosted.org/packages/04/c8/b19a760fab491c22c51975cf74e3d253b8c8ce2be7afaa2490fbf95a8c59/mypy-1.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca", size = 10037973 }, + { url = "https://files.pythonhosted.org/packages/88/57/7e7e39f2619c8f74a22efb9a4c4eff32b09d3798335625a124436d121d89/mypy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104", size = 12416659 }, + { url = "https://files.pythonhosted.org/packages/fc/a6/37f7544666b63a27e46c48f49caeee388bf3ce95f9c570eb5cfba5234405/mypy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4", size = 12897010 }, + { url = "https://files.pythonhosted.org/packages/84/8b/459a513badc4d34acb31c736a0101c22d2bd0697b969796ad93294165cfb/mypy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6", size = 9562873 }, + { url = "https://files.pythonhosted.org/packages/35/3a/ed7b12ecc3f6db2f664ccf85cb2e004d3e90bec928e9d7be6aa2f16b7cdf/mypy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318", size = 10990335 }, + { url = "https://files.pythonhosted.org/packages/04/e4/1a9051e2ef10296d206519f1df13d2cc896aea39e8683302f89bf5792a59/mypy-1.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36", size = 10007119 }, + { url = "https://files.pythonhosted.org/packages/f3/3c/350a9da895f8a7e87ade0028b962be0252d152e0c2fbaafa6f0658b4d0d4/mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987", size = 12506856 }, + { url = "https://files.pythonhosted.org/packages/b6/49/ee5adf6a49ff13f4202d949544d3d08abb0ea1f3e7f2a6d5b4c10ba0360a/mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca", size = 12952066 }, + { url = "https://files.pythonhosted.org/packages/27/c0/b19d709a42b24004d720db37446a42abadf844d5c46a2c442e2a074d70d9/mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70", size = 9664000 }, + { url = "https://files.pythonhosted.org/packages/42/3a/bdf730640ac523229dd6578e8a581795720a9321399de494374afc437ec5/mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12", size = 2619625 }, +] + +[package.optional-dependencies] +reports = [ + { name = "lxml" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, +] + +[[package]] +name = "myst-parser" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "jinja2" }, + { name = "markdown-it-py" }, + { name = "mdit-py-plugins" }, + { name = "pyyaml" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/55/6d1741a1780e5e65038b74bce6689da15f620261c490c3511eb4c12bac4b/myst_parser-4.0.0.tar.gz", hash = "sha256:851c9dfb44e36e56d15d05e72f02b80da21a9e0d07cba96baf5e2d476bb91531", size = 93858 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/b4/b036f8fdb667587bb37df29dc6644681dd78b7a2a6321a34684b79412b28/myst_parser-4.0.0-py3-none-any.whl", hash = "sha256:b9317997552424448c6096c2558872fdb6f81d3ecb3a40ce84a7518798f3f28d", size = 84563 }, +] + +[[package]] +name = "natsort" +version = "8.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/a9/a0c57aee75f77794adaf35322f8b6404cbd0f89ad45c87197a937764b7d0/natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581", size = 76575 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c", size = 38268 }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + +[[package]] +name = "packaging" +version = "24.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "polib" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/10/9a/79b1067d27e38ddf84fe7da6ec516f1743f31f752c6122193e7bce38bdbf/polib-1.2.0.tar.gz", hash = "sha256:f3ef94aefed6e183e342a8a269ae1fc4742ba193186ad76f175938621dbfc26b", size = 161658 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/99/45bb1f9926efe370c6dbe324741c749658e44cb060124f28dad201202274/polib-1.2.0-py2.py3-none-any.whl", hash = "sha256:1c77ee1b81feb31df9bca258cbc58db1bbb32d10214b173882452c73af06d62d", size = 20634 }, +] + +[[package]] +name = "pydantic" +version = "2.9.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/b7/d9e3f12af310e1120c21603644a1cd86f59060e040ec5c3a80b8f05fae30/pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", size = 769917 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/e4/ba44652d562cbf0bf320e0f3810206149c8a4e99cdbf66da82e97ab53a15/pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12", size = 434928 }, +] + +[[package]] +name = "pydantic-core" +version = "2.23.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e2/aa/6b6a9b9f8537b872f552ddd46dd3da230367754b6f707b8e1e963f515ea3/pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", size = 402156 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/8b/d3ae387f66277bd8104096d6ec0a145f4baa2966ebb2cad746c0920c9526/pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b", size = 1867835 }, + { url = "https://files.pythonhosted.org/packages/46/76/f68272e4c3a7df8777798282c5e47d508274917f29992d84e1898f8908c7/pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166", size = 1776689 }, + { url = "https://files.pythonhosted.org/packages/cc/69/5f945b4416f42ea3f3bc9d2aaec66c76084a6ff4ff27555bf9415ab43189/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb", size = 1800748 }, + { url = "https://files.pythonhosted.org/packages/50/ab/891a7b0054bcc297fb02d44d05c50e68154e31788f2d9d41d0b72c89fdf7/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916", size = 1806469 }, + { url = "https://files.pythonhosted.org/packages/31/7c/6e3fa122075d78f277a8431c4c608f061881b76c2b7faca01d317ee39b5d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07", size = 2002246 }, + { url = "https://files.pythonhosted.org/packages/ad/6f/22d5692b7ab63fc4acbc74de6ff61d185804a83160adba5e6cc6068e1128/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232", size = 2659404 }, + { url = "https://files.pythonhosted.org/packages/11/ac/1e647dc1121c028b691028fa61a4e7477e6aeb5132628fde41dd34c1671f/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2", size = 2053940 }, + { url = "https://files.pythonhosted.org/packages/91/75/984740c17f12c3ce18b5a2fcc4bdceb785cce7df1511a4ce89bca17c7e2d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f", size = 1921437 }, + { url = "https://files.pythonhosted.org/packages/a0/74/13c5f606b64d93f0721e7768cd3e8b2102164866c207b8cd6f90bb15d24f/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3", size = 1966129 }, + { url = "https://files.pythonhosted.org/packages/18/03/9c4aa5919457c7b57a016c1ab513b1a926ed9b2bb7915bf8e506bf65c34b/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071", size = 2110908 }, + { url = "https://files.pythonhosted.org/packages/92/2c/053d33f029c5dc65e5cf44ff03ceeefb7cce908f8f3cca9265e7f9b540c8/pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119", size = 1735278 }, + { url = "https://files.pythonhosted.org/packages/de/81/7dfe464eca78d76d31dd661b04b5f2036ec72ea8848dd87ab7375e185c23/pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f", size = 1917453 }, + { url = "https://files.pythonhosted.org/packages/5d/30/890a583cd3f2be27ecf32b479d5d615710bb926d92da03e3f7838ff3e58b/pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8", size = 1865160 }, + { url = "https://files.pythonhosted.org/packages/1d/9a/b634442e1253bc6889c87afe8bb59447f106ee042140bd57680b3b113ec7/pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d", size = 1776777 }, + { url = "https://files.pythonhosted.org/packages/75/9a/7816295124a6b08c24c96f9ce73085032d8bcbaf7e5a781cd41aa910c891/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e", size = 1799244 }, + { url = "https://files.pythonhosted.org/packages/a9/8f/89c1405176903e567c5f99ec53387449e62f1121894aa9fc2c4fdc51a59b/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607", size = 1805307 }, + { url = "https://files.pythonhosted.org/packages/d5/a5/1a194447d0da1ef492e3470680c66048fef56fc1f1a25cafbea4bc1d1c48/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd", size = 2000663 }, + { url = "https://files.pythonhosted.org/packages/13/a5/1df8541651de4455e7d587cf556201b4f7997191e110bca3b589218745a5/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea", size = 2655941 }, + { url = "https://files.pythonhosted.org/packages/44/31/a3899b5ce02c4316865e390107f145089876dff7e1dfc770a231d836aed8/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e", size = 2052105 }, + { url = "https://files.pythonhosted.org/packages/1b/aa/98e190f8745d5ec831f6d5449344c48c0627ac5fed4e5340a44b74878f8e/pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b", size = 1919967 }, + { url = "https://files.pythonhosted.org/packages/ae/35/b6e00b6abb2acfee3e8f85558c02a0822e9a8b2f2d812ea8b9079b118ba0/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0", size = 1964291 }, + { url = "https://files.pythonhosted.org/packages/13/46/7bee6d32b69191cd649bbbd2361af79c472d72cb29bb2024f0b6e350ba06/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64", size = 2109666 }, + { url = "https://files.pythonhosted.org/packages/39/ef/7b34f1b122a81b68ed0a7d0e564da9ccdc9a2924c8d6c6b5b11fa3a56970/pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f", size = 1732940 }, + { url = "https://files.pythonhosted.org/packages/2f/76/37b7e76c645843ff46c1d73e046207311ef298d3f7b2f7d8f6ac60113071/pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3", size = 1916804 }, + { url = "https://files.pythonhosted.org/packages/74/7b/8e315f80666194b354966ec84b7d567da77ad927ed6323db4006cf915f3f/pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231", size = 1856459 }, + { url = "https://files.pythonhosted.org/packages/14/de/866bdce10ed808323d437612aca1ec9971b981e1c52e5e42ad9b8e17a6f6/pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee", size = 1770007 }, + { url = "https://files.pythonhosted.org/packages/dc/69/8edd5c3cd48bb833a3f7ef9b81d7666ccddd3c9a635225214e044b6e8281/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87", size = 1790245 }, + { url = "https://files.pythonhosted.org/packages/80/33/9c24334e3af796ce80d2274940aae38dd4e5676298b4398eff103a79e02d/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8", size = 1801260 }, + { url = "https://files.pythonhosted.org/packages/a5/6f/e9567fd90104b79b101ca9d120219644d3314962caa7948dd8b965e9f83e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327", size = 1996872 }, + { url = "https://files.pythonhosted.org/packages/2d/ad/b5f0fe9e6cfee915dd144edbd10b6e9c9c9c9d7a56b69256d124b8ac682e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2", size = 2661617 }, + { url = "https://files.pythonhosted.org/packages/06/c8/7d4b708f8d05a5cbfda3243aad468052c6e99de7d0937c9146c24d9f12e9/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36", size = 2071831 }, + { url = "https://files.pythonhosted.org/packages/89/4d/3079d00c47f22c9a9a8220db088b309ad6e600a73d7a69473e3a8e5e3ea3/pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126", size = 1917453 }, + { url = "https://files.pythonhosted.org/packages/e9/88/9df5b7ce880a4703fcc2d76c8c2d8eb9f861f79d0c56f4b8f5f2607ccec8/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e", size = 1968793 }, + { url = "https://files.pythonhosted.org/packages/e3/b9/41f7efe80f6ce2ed3ee3c2dcfe10ab7adc1172f778cc9659509a79518c43/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", size = 2116872 }, + { url = "https://files.pythonhosted.org/packages/63/08/b59b7a92e03dd25554b0436554bf23e7c29abae7cce4b1c459cd92746811/pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", size = 1738535 }, + { url = "https://files.pythonhosted.org/packages/88/8d/479293e4d39ab409747926eec4329de5b7129beaedc3786eca070605d07f/pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", size = 1917992 }, + { url = "https://files.pythonhosted.org/packages/ad/ef/16ee2df472bf0e419b6bc68c05bf0145c49247a1095e85cee1463c6a44a1/pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", size = 1856143 }, + { url = "https://files.pythonhosted.org/packages/da/fa/bc3dbb83605669a34a93308e297ab22be82dfb9dcf88c6cf4b4f264e0a42/pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", size = 1770063 }, + { url = "https://files.pythonhosted.org/packages/4e/48/e813f3bbd257a712303ebdf55c8dc46f9589ec74b384c9f652597df3288d/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", size = 1790013 }, + { url = "https://files.pythonhosted.org/packages/b4/e0/56eda3a37929a1d297fcab1966db8c339023bcca0b64c5a84896db3fcc5c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", size = 1801077 }, + { url = "https://files.pythonhosted.org/packages/04/be/5e49376769bfbf82486da6c5c1683b891809365c20d7c7e52792ce4c71f3/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", size = 1996782 }, + { url = "https://files.pythonhosted.org/packages/bc/24/e3ee6c04f1d58cc15f37bcc62f32c7478ff55142b7b3e6d42ea374ea427c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", size = 2661375 }, + { url = "https://files.pythonhosted.org/packages/c1/f8/11a9006de4e89d016b8de74ebb1db727dc100608bb1e6bbe9d56a3cbbcce/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", size = 2071635 }, + { url = "https://files.pythonhosted.org/packages/7c/45/bdce5779b59f468bdf262a5bc9eecbae87f271c51aef628d8c073b4b4b4c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", size = 1916994 }, + { url = "https://files.pythonhosted.org/packages/d8/fa/c648308fe711ee1f88192cad6026ab4f925396d1293e8356de7e55be89b5/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", size = 1968877 }, + { url = "https://files.pythonhosted.org/packages/16/16/b805c74b35607d24d37103007f899abc4880923b04929547ae68d478b7f4/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", size = 2116814 }, + { url = "https://files.pythonhosted.org/packages/d1/58/5305e723d9fcdf1c5a655e6a4cc2a07128bf644ff4b1d98daf7a9dbf57da/pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", size = 1738360 }, + { url = "https://files.pythonhosted.org/packages/a5/ae/e14b0ff8b3f48e02394d8acd911376b7b66e164535687ef7dc24ea03072f/pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", size = 1919411 }, + { url = "https://files.pythonhosted.org/packages/13/a9/5d582eb3204464284611f636b55c0a7410d748ff338756323cb1ce721b96/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", size = 1857135 }, + { url = "https://files.pythonhosted.org/packages/2c/57/faf36290933fe16717f97829eabfb1868182ac495f99cf0eda9f59687c9d/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", size = 1740583 }, + { url = "https://files.pythonhosted.org/packages/91/7c/d99e3513dc191c4fec363aef1bf4c8af9125d8fa53af7cb97e8babef4e40/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", size = 1793637 }, + { url = "https://files.pythonhosted.org/packages/29/18/812222b6d18c2d13eebbb0f7cdc170a408d9ced65794fdb86147c77e1982/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068", size = 1941963 }, + { url = "https://files.pythonhosted.org/packages/0f/36/c1f3642ac3f05e6bb4aec3ffc399fa3f84895d259cf5f0ce3054b7735c29/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801", size = 1915332 }, + { url = "https://files.pythonhosted.org/packages/f7/ca/9c0854829311fb446020ebb540ee22509731abad886d2859c855dd29b904/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728", size = 1957926 }, + { url = "https://files.pythonhosted.org/packages/c0/1c/7836b67c42d0cd4441fcd9fafbf6a027ad4b79b6559f80cf11f89fd83648/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433", size = 2100342 }, + { url = "https://files.pythonhosted.org/packages/a9/f9/b6bcaf874f410564a78908739c80861a171788ef4d4f76f5009656672dfe/pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", size = 1920344 }, +] + +[[package]] +name = "pygments" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, +] + +[[package]] +name = "pyproject-hooks" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/82/28175b2414effca1cdac8dc99f76d660e7a4fb0ceefa4b4ab8f5f6742925/pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", size = 19228 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216 }, +] + +[[package]] +name = "pyright" +version = "1.1.383" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/a9/4654d15f4125d8dca6318d7be36a3283a8b3039661291c59bbdd1e576dcf/pyright-1.1.383.tar.gz", hash = "sha256:1df7f12407f3710c9c6df938d98ec53f70053e6c6bbf71ce7bcb038d42f10070", size = 21971 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/55/40a6559cea209b551c81dcd31cb351a6ffdb5876e7865ee242e269af72d8/pyright-1.1.383-py3-none-any.whl", hash = "sha256:d864d1182a313f45aaf99e9bfc7d2668eeabc99b29a556b5344894fd73cb1959", size = 18577 }, +] + +[[package]] +name = "pytest" +version = "8.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 }, +] + +[[package]] +name = "pytest-cov" +version = "5.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/67/00efc8d11b630c56f15f4ad9c7f9223f1e5ec275aaae3fa9118c6a223ad2/pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857", size = 63042 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/3a/af5b4fa5961d9a1e6237b530eb87dd04aea6eb83da09d2a4073d81b54ccf/pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", size = 21990 }, +] + +[[package]] +name = "pytest-mock" +version = "3.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863 }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, +] + +[[package]] +name = "regex" +version = "2024.9.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/38/148df33b4dbca3bd069b963acab5e0fa1a9dbd6820f8c322d0dd6faeff96/regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd", size = 399403 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/12/497bd6599ce8a239ade68678132296aec5ee25ebea45fc8ba91aa60fceec/regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408", size = 482488 }, + { url = "https://files.pythonhosted.org/packages/c1/24/595ddb9bec2a9b151cdaf9565b0c9f3da9f0cb1dca6c158bc5175332ddf8/regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d", size = 287443 }, + { url = "https://files.pythonhosted.org/packages/69/a8/b2fb45d9715b1469383a0da7968f8cacc2f83e9fbbcd6b8713752dd980a6/regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5", size = 284561 }, + { url = "https://files.pythonhosted.org/packages/88/87/1ce4a5357216b19b7055e7d3b0efc75a6e426133bf1e7d094321df514257/regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c", size = 783177 }, + { url = "https://files.pythonhosted.org/packages/3c/65/b9f002ab32f7b68e7d1dcabb67926f3f47325b8dbc22cc50b6a043e1d07c/regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8", size = 823193 }, + { url = "https://files.pythonhosted.org/packages/22/91/8339dd3abce101204d246e31bc26cdd7ec07c9f91598472459a3a902aa41/regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35", size = 809950 }, + { url = "https://files.pythonhosted.org/packages/cb/19/556638aa11c2ec9968a1da998f07f27ec0abb9bf3c647d7c7985ca0b8eea/regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71", size = 782661 }, + { url = "https://files.pythonhosted.org/packages/d1/e9/7a5bc4c6ef8d9cd2bdd83a667888fc35320da96a4cc4da5fa084330f53db/regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8", size = 772348 }, + { url = "https://files.pythonhosted.org/packages/f1/0b/29f2105bfac3ed08e704914c38e93b07c784a6655f8a015297ee7173e95b/regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a", size = 697460 }, + { url = "https://files.pythonhosted.org/packages/71/3a/52ff61054d15a4722605f5872ad03962b319a04c1ebaebe570b8b9b7dde1/regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d", size = 769151 }, + { url = "https://files.pythonhosted.org/packages/97/07/37e460ab5ca84be8e1e197c3b526c5c86993dcc9e13cbc805c35fc2463c1/regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137", size = 777478 }, + { url = "https://files.pythonhosted.org/packages/65/7b/953075723dd5ab00780043ac2f9de667306ff9e2a85332975e9f19279174/regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6", size = 845373 }, + { url = "https://files.pythonhosted.org/packages/40/b8/3e9484c6230b8b6e8f816ab7c9a080e631124991a4ae2c27a81631777db0/regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca", size = 845369 }, + { url = "https://files.pythonhosted.org/packages/b7/99/38434984d912edbd2e1969d116257e869578f67461bd7462b894c45ed874/regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a", size = 773935 }, + { url = "https://files.pythonhosted.org/packages/ab/67/43174d2b46fa947b7b9dfe56b6c8a8a76d44223f35b1d64645a732fd1d6f/regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0", size = 261624 }, + { url = "https://files.pythonhosted.org/packages/c4/2a/4f9c47d9395b6aff24874c761d8d620c0232f97c43ef3cf668c8b355e7a7/regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623", size = 274020 }, + { url = "https://files.pythonhosted.org/packages/86/a1/d526b7b6095a0019aa360948c143aacfeb029919c898701ce7763bbe4c15/regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df", size = 482483 }, + { url = "https://files.pythonhosted.org/packages/32/d9/bfdd153179867c275719e381e1e8e84a97bd186740456a0dcb3e7125c205/regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268", size = 287442 }, + { url = "https://files.pythonhosted.org/packages/33/c4/60f3370735135e3a8d673ddcdb2507a8560d0e759e1398d366e43d000253/regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad", size = 284561 }, + { url = "https://files.pythonhosted.org/packages/b1/51/91a5ebdff17f9ec4973cb0aa9d37635efec1c6868654bbc25d1543aca4ec/regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679", size = 791779 }, + { url = "https://files.pythonhosted.org/packages/07/4a/022c5e6f0891a90cd7eb3d664d6c58ce2aba48bff107b00013f3d6167069/regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4", size = 832605 }, + { url = "https://files.pythonhosted.org/packages/ac/1c/3793990c8c83ca04e018151ddda83b83ecc41d89964f0f17749f027fc44d/regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664", size = 818556 }, + { url = "https://files.pythonhosted.org/packages/e9/5c/8b385afbfacb853730682c57be56225f9fe275c5bf02ac1fc88edbff316d/regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50", size = 792808 }, + { url = "https://files.pythonhosted.org/packages/9b/8b/a4723a838b53c771e9240951adde6af58c829fb6a6a28f554e8131f53839/regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199", size = 781115 }, + { url = "https://files.pythonhosted.org/packages/83/5f/031a04b6017033d65b261259c09043c06f4ef2d4eac841d0649d76d69541/regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4", size = 778155 }, + { url = "https://files.pythonhosted.org/packages/fd/cd/4660756070b03ce4a66663a43f6c6e7ebc2266cc6b4c586c167917185eb4/regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd", size = 784614 }, + { url = "https://files.pythonhosted.org/packages/93/8d/65b9bea7df120a7be8337c415b6d256ba786cbc9107cebba3bf8ff09da99/regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f", size = 853744 }, + { url = "https://files.pythonhosted.org/packages/96/a7/fba1eae75eb53a704475baf11bd44b3e6ccb95b316955027eb7748f24ef8/regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96", size = 855890 }, + { url = "https://files.pythonhosted.org/packages/45/14/d864b2db80a1a3358534392373e8a281d95b28c29c87d8548aed58813910/regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1", size = 781887 }, + { url = "https://files.pythonhosted.org/packages/4d/a9/bfb29b3de3eb11dc9b412603437023b8e6c02fb4e11311863d9bf62c403a/regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9", size = 261644 }, + { url = "https://files.pythonhosted.org/packages/c7/ab/1ad2511cf6a208fde57fafe49829cab8ca018128ab0d0b48973d8218634a/regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf", size = 274033 }, + { url = "https://files.pythonhosted.org/packages/6e/92/407531450762bed778eedbde04407f68cbd75d13cee96c6f8d6903d9c6c1/regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7", size = 483590 }, + { url = "https://files.pythonhosted.org/packages/8e/a2/048acbc5ae1f615adc6cba36cc45734e679b5f1e4e58c3c77f0ed611d4e2/regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231", size = 288175 }, + { url = "https://files.pythonhosted.org/packages/8a/ea/909d8620329ab710dfaf7b4adee41242ab7c9b95ea8d838e9bfe76244259/regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d", size = 284749 }, + { url = "https://files.pythonhosted.org/packages/ca/fa/521eb683b916389b4975337873e66954e0f6d8f91bd5774164a57b503185/regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64", size = 795181 }, + { url = "https://files.pythonhosted.org/packages/28/db/63047feddc3280cc242f9c74f7aeddc6ee662b1835f00046f57d5630c827/regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42", size = 835842 }, + { url = "https://files.pythonhosted.org/packages/e3/94/86adc259ff8ec26edf35fcca7e334566c1805c7493b192cb09679f9c3dee/regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766", size = 823533 }, + { url = "https://files.pythonhosted.org/packages/29/52/84662b6636061277cb857f658518aa7db6672bc6d1a3f503ccd5aefc581e/regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a", size = 797037 }, + { url = "https://files.pythonhosted.org/packages/c3/2a/cd4675dd987e4a7505f0364a958bc41f3b84942de9efaad0ef9a2646681c/regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9", size = 784106 }, + { url = "https://files.pythonhosted.org/packages/6f/75/3ea7ec29de0bbf42f21f812f48781d41e627d57a634f3f23947c9a46e303/regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d", size = 782468 }, + { url = "https://files.pythonhosted.org/packages/d3/67/15519d69b52c252b270e679cb578e22e0c02b8dd4e361f2b04efcc7f2335/regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822", size = 790324 }, + { url = "https://files.pythonhosted.org/packages/9c/71/eff77d3fe7ba08ab0672920059ec30d63fa7e41aa0fb61c562726e9bd721/regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0", size = 860214 }, + { url = "https://files.pythonhosted.org/packages/81/11/e1bdf84a72372e56f1ea4b833dd583b822a23138a616ace7ab57a0e11556/regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a", size = 859420 }, + { url = "https://files.pythonhosted.org/packages/ea/75/9753e9dcebfa7c3645563ef5c8a58f3a47e799c872165f37c55737dadd3e/regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a", size = 787333 }, + { url = "https://files.pythonhosted.org/packages/bc/4e/ba1cbca93141f7416624b3ae63573e785d4bc1834c8be44a8f0747919eca/regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776", size = 262058 }, + { url = "https://files.pythonhosted.org/packages/6e/16/efc5f194778bf43e5888209e5cec4b258005d37c613b67ae137df3b89c53/regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009", size = 273526 }, + { url = "https://files.pythonhosted.org/packages/93/0a/d1c6b9af1ff1e36832fe38d74d5c5bab913f2bdcbbd6bc0e7f3ce8b2f577/regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784", size = 483376 }, + { url = "https://files.pythonhosted.org/packages/a4/42/5910a050c105d7f750a72dcb49c30220c3ae4e2654e54aaaa0e9bc0584cb/regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36", size = 288112 }, + { url = "https://files.pythonhosted.org/packages/8d/56/0c262aff0e9224fa7ffce47b5458d373f4d3e3ff84e99b5ff0cb15e0b5b2/regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92", size = 284608 }, + { url = "https://files.pythonhosted.org/packages/b9/54/9fe8f9aec5007bbbbce28ba3d2e3eaca425f95387b7d1e84f0d137d25237/regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86", size = 795337 }, + { url = "https://files.pythonhosted.org/packages/b2/e7/6b2f642c3cded271c4f16cc4daa7231be544d30fe2b168e0223724b49a61/regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85", size = 835848 }, + { url = "https://files.pythonhosted.org/packages/cd/9e/187363bdf5d8c0e4662117b92aa32bf52f8f09620ae93abc7537d96d3311/regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963", size = 823503 }, + { url = "https://files.pythonhosted.org/packages/f8/10/601303b8ee93589f879664b0cfd3127949ff32b17f9b6c490fb201106c4d/regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6", size = 797049 }, + { url = "https://files.pythonhosted.org/packages/ef/1c/ea200f61ce9f341763f2717ab4daebe4422d83e9fd4ac5e33435fd3a148d/regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802", size = 784144 }, + { url = "https://files.pythonhosted.org/packages/d8/5c/d2429be49ef3292def7688401d3deb11702c13dcaecdc71d2b407421275b/regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29", size = 782483 }, + { url = "https://files.pythonhosted.org/packages/12/d9/cbc30f2ff7164f3b26a7760f87c54bf8b2faed286f60efd80350a51c5b99/regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8", size = 790320 }, + { url = "https://files.pythonhosted.org/packages/19/1d/43ed03a236313639da5a45e61bc553c8d41e925bcf29b0f8ecff0c2c3f25/regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84", size = 860435 }, + { url = "https://files.pythonhosted.org/packages/34/4f/5d04da61c7c56e785058a46349f7285ae3ebc0726c6ea7c5c70600a52233/regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554", size = 859571 }, + { url = "https://files.pythonhosted.org/packages/12/7f/8398c8155a3c70703a8e91c29532558186558e1aea44144b382faa2a6f7a/regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8", size = 787398 }, + { url = "https://files.pythonhosted.org/packages/58/3a/f5903977647a9a7e46d5535e9e96c194304aeeca7501240509bde2f9e17f/regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8", size = 262035 }, + { url = "https://files.pythonhosted.org/packages/ff/80/51ba3a4b7482f6011095b3a036e07374f64de180b7d870b704ed22509002/regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f", size = 273510 }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, +] + +[[package]] +name = "ruamel-yaml" +version = "0.18.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ruamel-yaml-clib", marker = "python_full_version < '3.13' and platform_python_implementation == 'CPython'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/29/81/4dfc17eb6ebb1aac314a3eb863c1325b907863a1b8b1382cdffcb6ac0ed9/ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b", size = 143362 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/67/8ece580cc363331d9a53055130f86b096bf16e38156e33b1d3014fffda6b/ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636", size = 117761 }, +] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f", size = 225315 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/57/40a958e863e299f0c74ef32a3bde9f2d1ea8d69669368c0c502a0997f57f/ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:11f891336688faf5156a36293a9c362bdc7c88f03a8a027c2c1d8e0bcde998e5", size = 131301 }, + { url = "https://files.pythonhosted.org/packages/98/a8/29a3eb437b12b95f50a6bcc3d7d7214301c6c529d8fdc227247fa84162b5/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a606ef75a60ecf3d924613892cc603b154178ee25abb3055db5062da811fd969", size = 633728 }, + { url = "https://files.pythonhosted.org/packages/35/6d/ae05a87a3ad540259c3ad88d71275cbd1c0f2d30ae04c65dcbfb6dcd4b9f/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd5415dded15c3822597455bc02bcd66e81ef8b7a48cb71a33628fc9fdde39df", size = 722230 }, + { url = "https://files.pythonhosted.org/packages/7f/b7/20c6f3c0b656fe609675d69bc135c03aac9e3865912444be6339207b6648/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76", size = 686712 }, + { url = "https://files.pythonhosted.org/packages/cd/11/d12dbf683471f888d354dac59593873c2b45feb193c5e3e0f2ebf85e68b9/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6", size = 663936 }, + { url = "https://files.pythonhosted.org/packages/72/14/4c268f5077db5c83f743ee1daeb236269fa8577133a5cfa49f8b382baf13/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd", size = 696580 }, + { url = "https://files.pythonhosted.org/packages/80/29/c0a017b704aaf3cbf704989785cd9c5d5b8ccec2dae6ac0c53833c84e677/ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da", size = 100326 }, + { url = "https://files.pythonhosted.org/packages/3a/65/fa39d74db4e2d0cd252355732d966a460a41cd01c6353b820a0952432839/ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28", size = 118079 }, + { url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6", size = 132224 }, + { url = "https://files.pythonhosted.org/packages/3c/d2/b79b7d695e2f21da020bd44c782490578f300dd44f0a4c57a92575758a76/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e", size = 641480 }, + { url = "https://files.pythonhosted.org/packages/68/6e/264c50ce2a31473a9fdbf4fa66ca9b2b17c7455b31ef585462343818bd6c/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e", size = 739068 }, + { url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52", size = 703012 }, + { url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642", size = 704352 }, + { url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2", size = 737344 }, + { url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4", size = 100205 }, + { url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb", size = 118185 }, + { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433 }, + { url = "https://files.pythonhosted.org/packages/ec/b0/b850385604334c2ce90e3ee1013bd911aedf058a934905863a6ea95e9eb4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d", size = 647362 }, + { url = "https://files.pythonhosted.org/packages/44/d0/3f68a86e006448fb6c005aee66565b9eb89014a70c491d70c08de597f8e4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c", size = 754118 }, + { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497 }, + { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042 }, + { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831 }, + { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777 }, + { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523 }, + { url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a", size = 132011 }, + { url = "https://files.pythonhosted.org/packages/7f/5e/212f473a93ae78c669ffa0cb051e3fee1139cb2d385d2ae1653d64281507/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475", size = 642488 }, + { url = "https://files.pythonhosted.org/packages/1f/8f/ecfbe2123ade605c49ef769788f79c38ddb1c8fa81e01f4dbf5cf1a44b16/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef", size = 745066 }, + { url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6", size = 701785 }, + { url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf", size = 693017 }, + { url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1", size = 741270 }, + { url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6", size = 98583 }, + { url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3", size = 115190 }, +] + +[[package]] +name = "six" +version = "1.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, +] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/7b/af302bebf22c749c56c9c3e8ae13190b5b5db37a33d9068652e8f73b7089/snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", size = 86699 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a", size = 93002 }, +] + +[[package]] +name = "soupsieve" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, +] + +[[package]] +name = "sphinx" +version = "7.4.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/be/50e50cb4f2eff47df05673d361095cafd95521d2a22521b920c67a372dcb/sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe", size = 8067911 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239", size = 3401624 }, +] + +[[package]] +name = "sphinx-autobuild" +version = "2024.10.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama" }, + { name = "sphinx" }, + { name = "starlette" }, + { name = "uvicorn" }, + { name = "watchfiles" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a5/2c/155e1de2c1ba96a72e5dba152c509a8b41e047ee5c2def9e9f0d812f8be7/sphinx_autobuild-2024.10.3.tar.gz", hash = "sha256:248150f8f333e825107b6d4b86113ab28fa51750e5f9ae63b59dc339be951fb1", size = 14023 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/c0/eba125db38c84d3c74717008fd3cb5000b68cd7e2cbafd1349c6a38c3d3b/sphinx_autobuild-2024.10.3-py3-none-any.whl", hash = "sha256:158e16c36f9d633e613c9aaf81c19b0fc458ca78b112533b20dafcda430d60fa", size = 11908 }, +] + +[[package]] +name = "sphinx-autodoc-typehints" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/cd/03e7b917230dc057922130a79ba0240df1693bfd76727ea33fae84b39138/sphinx_autodoc_typehints-2.3.0.tar.gz", hash = "sha256:535c78ed2d6a1bad393ba9f3dfa2602cf424e2631ee207263e07874c38fde084", size = 40709 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/f3/e0a4ce49da4b6f4e4ce84b3c39a0677831884cb9d8a87ccbf1e9e56e53ac/sphinx_autodoc_typehints-2.3.0-py3-none-any.whl", hash = "sha256:3098e2c6d0ba99eacd013eb06861acc9b51c6e595be86ab05c08ee5506ac0c67", size = 19836 }, +] + +[[package]] +name = "sphinx-basic-ng" +version = "1.0.0b2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/0b/a866924ded68efec7a1759587a4e478aec7559d8165fac8b2ad1c0e774d6/sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9", size = 20736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/dd/018ce05c532a22007ac58d4f45232514cd9d6dd0ee1dc374e309db830983/sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b", size = 22496 }, +] + +[[package]] +name = "sphinx-jinja2-compat" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "markupsafe" }, + { name = "standard-imghdr", marker = "python_full_version >= '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/26/df/27282da6f8c549f765beca9de1a5fc56f9651ed87711a5cac1e914137753/sphinx_jinja2_compat-0.3.0.tar.gz", hash = "sha256:f3c1590b275f42e7a654e081db5e3e5fb97f515608422bde94015ddf795dfe7c", size = 4998 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/42/2fd09d672eaaa937d6893d8b747d07943f97a6e5e30653aee6ebd339b704/sphinx_jinja2_compat-0.3.0-py3-none-any.whl", hash = "sha256:b1e4006d8e1ea31013fa9946d1b075b0c8d2a42c6e3425e63542c1e9f8be9084", size = 7883 }, +] + +[[package]] +name = "sphinx-jsonschema" +version = "1.19.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "jsonpointer" }, + { name = "pyyaml" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9c/3f/559d054f977596c5535edfeeab1f3a278f3bbb81bada2a1cb3cadbf7bb67/sphinx-jsonschema-1.19.1.tar.gz", hash = "sha256:b2385fe1c7acf2e759152aefed0cb17c920645b2a75c9934000c9c528e7d53c1", size = 18599 } + +[[package]] +name = "sphinx-lint" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "polib" }, + { name = "regex" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cf/46/f2dad36a4076e9ce88498b25b3f0de82eb7d341ea0ef715cd6c48005bcef/sphinx_lint-1.0.0.tar.gz", hash = "sha256:6eafdb44172ce526f405bf36c713eb246f1340ec2d667e7298e2487ed76decd2", size = 33574 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/31/d2/a130ffba531af7cbbb0e7ad24c7d577d3de0b797437f61d3a7234ed6d836/sphinx_lint-1.0.0-py3-none-any.whl", hash = "sha256:6117a0f340b2dc73eadfc57db7531d4477e0929f92a0c1a2f61e6edbc272f0bc", size = 20163 }, +] + +[[package]] +name = "sphinx-prompt" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "pygments" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/fb/7a07b8df1ca2418147a6b13e3f6b445071f2565198b45efa631d0d6ef0cd/sphinx_prompt-1.8.0.tar.gz", hash = "sha256:47482f86fcec29662fdfd23e7c04ef03582714195d01f5d565403320084372ed", size = 5121 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/49/f890a2668b7cbf375f5528b549c8d36dd2e801b0fbb7b2b5ef65663ecb6c/sphinx_prompt-1.8.0-py3-none-any.whl", hash = "sha256:369ecc633f0711886f9b3a078c83264245be1adf46abeeb9b88b5519e4b51007", size = 7298 }, +] + +[[package]] +name = "sphinx-pydantic" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "sphinx-jsonschema" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/58/e7a518876db551cf3bd6621eecc6675d003b9bd8413382c10298e2113f7e/sphinx-pydantic-0.1.1.tar.gz", hash = "sha256:a830e4f07fe88fbdfe3edecc2f52ef133cde2def7cb882a3f22780f34963b0fb", size = 3394 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/87/e397aba1d53aea3bccb8df07e1086e00855404afd92d118b07854d746947/sphinx_pydantic-0.1.1-py3-none-any.whl", hash = "sha256:371487ad81250d8bc5b944a2936b33c10ff88af7188d5be0ee6c4b46bb70254a", size = 2888 }, +] + +[[package]] +name = "sphinx-tabs" +version = "3.4.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "pygments" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/27/32/ab475e252dc2b704e82a91141fa404cdd8901a5cf34958fd22afacebfccd/sphinx-tabs-3.4.5.tar.gz", hash = "sha256:ba9d0c1e3e37aaadd4b5678449eb08176770e0fc227e769b6ce747df3ceea531", size = 16070 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/9f/4ac7dbb9f23a2ff5a10903a4f9e9f43e0ff051f63a313e989c962526e305/sphinx_tabs-3.4.5-py3-none-any.whl", hash = "sha256:92cc9473e2ecf1828ca3f6617d0efc0aa8acb06b08c56ba29d1413f2f0f6cf09", size = 9904 }, +] + +[[package]] +name = "sphinx-toolbox" +version = "3.8.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "apeye" }, + { name = "autodocsumm" }, + { name = "beautifulsoup4" }, + { name = "cachecontrol", extra = ["filecache"] }, + { name = "dict2css" }, + { name = "docutils" }, + { name = "domdf-python-tools" }, + { name = "filelock" }, + { name = "html5lib" }, + { name = "ruamel-yaml" }, + { name = "sphinx" }, + { name = "sphinx-autodoc-typehints" }, + { name = "sphinx-jinja2-compat" }, + { name = "sphinx-prompt" }, + { name = "sphinx-tabs" }, + { name = "tabulate" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/30/80/f837e85c8c216cdeef9b60393e4b00c9092a1e3d734106e0021abbf5930c/sphinx_toolbox-3.8.1.tar.gz", hash = "sha256:a4b39a6ea24fc8f10e24f052199bda17837a0bf4c54163a56f521552395f5e1a", size = 111977 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/d6/2a28ee4cbc158ae65afb2cfcb6895ef54d972ce1e167f8a63c135b14b080/sphinx_toolbox-3.8.1-py3-none-any.whl", hash = "sha256:53d8e77dd79e807d9ef18590c4b2960a5aa3c147415054b04c31a91afed8b88b", size = 194621 }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300 }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530 }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705 }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071 }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743 }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072 }, +] + +[[package]] +name = "standard-imghdr" +version = "3.10.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/d2/2eb5521072c9598886035c65c023f39f7384bcb73eed70794f469e34efac/standard_imghdr-3.10.14.tar.gz", hash = "sha256:2598fe2e7c540dbda34b233295e10957ab8dc8ac6f3bd9eaa8d38be167232e52", size = 5474 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/d0/9852f70eb01f814843530c053542b72d30e9fbf74da7abb0107e71938389/standard_imghdr-3.10.14-py3-none-any.whl", hash = "sha256:cdf6883163349624dee9a81d2853a20260337c4cd41c04e99c082e01833a08e2", size = 5598 }, +] + +[[package]] +name = "starcraft" +version = "0.0.post246+g316bea6.d20241022" +source = { editable = "." } + +[package.optional-dependencies] +docs = [ + { name = "canonical-sphinx" }, + { name = "sphinx-autobuild" }, + { name = "sphinx-lint" }, + { name = "sphinx-pydantic" }, + { name = "sphinx-toolbox" }, +] +lint = [ + { name = "yamllint" }, +] +types = [ + { name = "mypy", extra = ["reports"] }, + { name = "pyright" }, + { name = "types-colorama" }, + { name = "types-pygments" }, + { name = "types-setuptools" }, +] + +[package.dev-dependencies] +dev = [ + { name = "build" }, + { name = "coverage", extra = ["toml"] }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "pytest-mock" }, +] + +[package.metadata] +requires-dist = [ + { name = "canonical-sphinx", marker = "extra == 'docs'", specifier = "~=0.2.0" }, + { name = "mypy", extras = ["reports"], marker = "extra == 'types'", specifier = "~=1.11.0" }, + { name = "pyright", marker = "extra == 'types'", specifier = "==1.1.383" }, + { name = "sphinx-autobuild", marker = "extra == 'docs'", specifier = "~=2024.2" }, + { name = "sphinx-lint", marker = "extra == 'docs'", specifier = "==1.0.0" }, + { name = "sphinx-pydantic", marker = "extra == 'docs'", specifier = "==0.1.1" }, + { name = "sphinx-toolbox", marker = "extra == 'docs'", specifier = "~=3.5" }, + { name = "types-colorama", marker = "extra == 'types'" }, + { name = "types-pygments", marker = "extra == 'types'" }, + { name = "types-setuptools", marker = "extra == 'types'" }, + { name = "yamllint", marker = "extra == 'lint'", specifier = "~=1.34" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "build" }, + { name = "coverage", extras = ["toml"], specifier = "~=7.4" }, + { name = "pytest", specifier = "~=8.0" }, + { name = "pytest-cov", specifier = "~=5.0" }, + { name = "pytest-mock", specifier = "~=3.12" }, +] + +[[package]] +name = "starlette" +version = "0.41.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/53/c3a36690a923706e7ac841f649c64f5108889ab1ec44218dac45771f252a/starlette-0.41.0.tar.gz", hash = "sha256:39cbd8768b107d68bfe1ff1672b38a2c38b49777de46d2a592841d58e3bf7c2a", size = 2573755 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/c6/a4443bfabf5629129512ca0e07866c4c3c094079ba4e9b2551006927253c/starlette-0.41.0-py3-none-any.whl", hash = "sha256:a0193a3c413ebc9c78bff1c3546a45bb8c8bcb4a84cae8747d650a65bd37210a", size = 73216 }, +] + +[[package]] +name = "tabulate" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252 }, +] + +[[package]] +name = "tomli" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/b9/de2a5c0144d7d75a57ff355c0c24054f965b2dc3036456ae03a51ea6264b/tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed", size = 16096 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/db/ce8eda256fa131af12e0a76d481711abe4681b6923c27efb9a255c9e4594/tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", size = 13237 }, +] + +[[package]] +name = "types-colorama" +version = "0.4.15.20240311" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/59/73/0fb0b9fe4964b45b2a06ed41b60c352752626db46aa0fb70a49a9e283a75/types-colorama-0.4.15.20240311.tar.gz", hash = "sha256:a28e7f98d17d2b14fb9565d32388e419f4108f557a7d939a66319969b2b99c7a", size = 5608 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/83/6944b4fa01efb2e63ac62b791a8ddf0fee358f93be9f64b8f152648ad9d3/types_colorama-0.4.15.20240311-py3-none-any.whl", hash = "sha256:6391de60ddc0db3f147e31ecb230006a6823e81e380862ffca1e4695c13a0b8e", size = 5840 }, +] + +[[package]] +name = "types-docutils" +version = "0.21.0.20241005" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/23/31/6f51a6b05ad750fd7875ffd45e7a88063258782f35e5dff1f291061e394e/types-docutils-0.21.0.20241005.tar.gz", hash = "sha256:48f804a2b50da3a1b1681c4ca1b6184416a6e4129e302d15c44e9d97c59b3365", size = 20701 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/73/8ccc09357cfe9f4b8a5b31af3276dd270924bf4915a13cf816b585221b59/types_docutils-0.21.0.20241005-py3-none-any.whl", hash = "sha256:4d9021422f2f3fca8b0726fb8949395f66a06c0d951479eb3b1387d75b134430", size = 28520 }, +] + +[[package]] +name = "types-pygments" +version = "2.18.0.20240506" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "types-docutils" }, + { name = "types-setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f0/ed/0a70203637650ecaa74731faf441d128edb908ed6ca184013bfc498283ba/types-Pygments-2.18.0.20240506.tar.gz", hash = "sha256:4b4c37812c87bbde687dbf27adf5bac593745a321e57f678dbc311571ba2ac9d", size = 13516 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/52/1a740a823dcfbe7fe7c44c2ff83528df2c2b5b6e93c299e8db7bf4205c1b/types_Pygments-2.18.0.20240506-py3-none-any.whl", hash = "sha256:11c90bc1737c9af55e5569558b88df7c2233e12325cb516215f722271444e91d", size = 20775 }, +] + +[[package]] +name = "types-setuptools" +version = "75.2.0.20241019" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/cd/2e6caabafc6d01b65c212d03a177f510a00840f90d0196cf1718adafbf29/types-setuptools-75.2.0.20241019.tar.gz", hash = "sha256:86ea31b5f6df2c6b8f2dc8ae3f72b213607f62549b6fa2ed5866e5299f968694", size = 42888 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/00/a90c00f3af9f6c41788959afc440d54b9677ebc8d9e5dba0ec4914d7a997/types_setuptools-75.2.0.20241019-py3-none-any.whl", hash = "sha256:2e48ff3acd4919471e80d5e3f049cce5c177e108d5d36d2d4cee3fa4d4104258", size = 65740 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] + +[[package]] +name = "uc-micro-py" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/7a/146a99696aee0609e3712f2b44c6274566bc368dfe8375191278045186b8/uc-micro-py-1.0.3.tar.gz", hash = "sha256:d321b92cff673ec58027c04015fcaa8bb1e005478643ff4a500882eaab88c48a", size = 6043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/87/1f677586e8ac487e29672e4b17455758fce261de06a0d086167bb760361a/uc_micro_py-1.0.3-py3-none-any.whl", hash = "sha256:db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5", size = 6229 }, +] + +[[package]] +name = "urllib3" +version = "2.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, +] + +[[package]] +name = "uvicorn" +version = "0.32.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e0/fc/1d785078eefd6945f3e5bab5c076e4230698046231eb0f3747bc5c8fa992/uvicorn-0.32.0.tar.gz", hash = "sha256:f78b36b143c16f54ccdb8190d0a26b5f1901fe5a3c777e1ab29f26391af8551e", size = 77564 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/14/78bd0e95dd2444b6caacbca2b730671d4295ccb628ef58b81bee903629df/uvicorn-0.32.0-py3-none-any.whl", hash = "sha256:60b8f3a5ac027dcd31448f411ced12b5ef452c646f76f02f8cc3f25d8d26fd82", size = 63723 }, +] + +[[package]] +name = "watchfiles" +version = "0.24.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c8/27/2ba23c8cc85796e2d41976439b08d52f691655fdb9401362099502d1f0cf/watchfiles-0.24.0.tar.gz", hash = "sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1", size = 37870 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/a1/631c12626378b9f1538664aa221feb5c60dfafbd7f60b451f8d0bdbcdedd/watchfiles-0.24.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0", size = 375096 }, + { url = "https://files.pythonhosted.org/packages/f7/5c/f27c979c8a10aaa2822286c1bffdce3db731cd1aa4224b9f86623e94bbfe/watchfiles-0.24.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c", size = 367425 }, + { url = "https://files.pythonhosted.org/packages/74/0d/1889e5649885484d29f6c792ef274454d0a26b20d6ed5fdba5409335ccb6/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361", size = 437705 }, + { url = "https://files.pythonhosted.org/packages/85/8a/01d9a22e839f0d1d547af11b1fcac6ba6f889513f1b2e6f221d9d60d9585/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3", size = 433636 }, + { url = "https://files.pythonhosted.org/packages/62/32/a93db78d340c7ef86cde469deb20e36c6b2a873edee81f610e94bbba4e06/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571", size = 451069 }, + { url = "https://files.pythonhosted.org/packages/99/c2/e9e2754fae3c2721c9a7736f92dab73723f1968ed72535fff29e70776008/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd", size = 469306 }, + { url = "https://files.pythonhosted.org/packages/4c/45/f317d9e3affb06c3c27c478de99f7110143e87f0f001f0f72e18d0e1ddce/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a", size = 476187 }, + { url = "https://files.pythonhosted.org/packages/ac/d3/f1f37248abe0114916921e638f71c7d21fe77e3f2f61750e8057d0b68ef2/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e", size = 425743 }, + { url = "https://files.pythonhosted.org/packages/2b/e8/c7037ea38d838fd81a59cd25761f106ee3ef2cfd3261787bee0c68908171/watchfiles-0.24.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c", size = 612327 }, + { url = "https://files.pythonhosted.org/packages/a0/c5/0e6e228aafe01a7995fbfd2a4edb221bb11a2744803b65a5663fb85e5063/watchfiles-0.24.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188", size = 595096 }, + { url = "https://files.pythonhosted.org/packages/63/d5/4780e8bf3de3b4b46e7428a29654f7dc041cad6b19fd86d083e4b6f64bbe/watchfiles-0.24.0-cp310-none-win32.whl", hash = "sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735", size = 264149 }, + { url = "https://files.pythonhosted.org/packages/fe/1b/5148898ba55fc9c111a2a4a5fb67ad3fa7eb2b3d7f0618241ed88749313d/watchfiles-0.24.0-cp310-none-win_amd64.whl", hash = "sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04", size = 277542 }, + { url = "https://files.pythonhosted.org/packages/85/02/366ae902cd81ca5befcd1854b5c7477b378f68861597cef854bd6dc69fbe/watchfiles-0.24.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:bdcd5538e27f188dd3c804b4a8d5f52a7fc7f87e7fd6b374b8e36a4ca03db428", size = 375579 }, + { url = "https://files.pythonhosted.org/packages/bc/67/d8c9d256791fe312fea118a8a051411337c948101a24586e2df237507976/watchfiles-0.24.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2dadf8a8014fde6addfd3c379e6ed1a981c8f0a48292d662e27cabfe4239c83c", size = 367726 }, + { url = "https://files.pythonhosted.org/packages/b1/dc/a8427b21ef46386adf824a9fec4be9d16a475b850616cfd98cf09a97a2ef/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6509ed3f467b79d95fc62a98229f79b1a60d1b93f101e1c61d10c95a46a84f43", size = 437735 }, + { url = "https://files.pythonhosted.org/packages/3a/21/0b20bef581a9fbfef290a822c8be645432ceb05fb0741bf3c032e0d90d9a/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8360f7314a070c30e4c976b183d1d8d1585a4a50c5cb603f431cebcbb4f66327", size = 433644 }, + { url = "https://files.pythonhosted.org/packages/1c/e8/d5e5f71cc443c85a72e70b24269a30e529227986096abe091040d6358ea9/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:316449aefacf40147a9efaf3bd7c9bdd35aaba9ac5d708bd1eb5763c9a02bef5", size = 450928 }, + { url = "https://files.pythonhosted.org/packages/61/ee/bf17f5a370c2fcff49e1fec987a6a43fd798d8427ea754ce45b38f9e117a/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73bde715f940bea845a95247ea3e5eb17769ba1010efdc938ffcb967c634fa61", size = 469072 }, + { url = "https://files.pythonhosted.org/packages/a3/34/03b66d425986de3fc6077e74a74c78da298f8cb598887f664a4485e55543/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3770e260b18e7f4e576edca4c0a639f704088602e0bc921c5c2e721e3acb8d15", size = 475517 }, + { url = "https://files.pythonhosted.org/packages/70/eb/82f089c4f44b3171ad87a1b433abb4696f18eb67292909630d886e073abe/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa0fd7248cf533c259e59dc593a60973a73e881162b1a2f73360547132742823", size = 425480 }, + { url = "https://files.pythonhosted.org/packages/53/20/20509c8f5291e14e8a13104b1808cd7cf5c44acd5feaecb427a49d387774/watchfiles-0.24.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d7a2e3b7f5703ffbd500dabdefcbc9eafeff4b9444bbdd5d83d79eedf8428fab", size = 612322 }, + { url = "https://files.pythonhosted.org/packages/df/2b/5f65014a8cecc0a120f5587722068a975a692cadbe9fe4ea56b3d8e43f14/watchfiles-0.24.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d831ee0a50946d24a53821819b2327d5751b0c938b12c0653ea5be7dea9c82ec", size = 595094 }, + { url = "https://files.pythonhosted.org/packages/18/98/006d8043a82c0a09d282d669c88e587b3a05cabdd7f4900e402250a249ac/watchfiles-0.24.0-cp311-none-win32.whl", hash = "sha256:49d617df841a63b4445790a254013aea2120357ccacbed00253f9c2b5dc24e2d", size = 264191 }, + { url = "https://files.pythonhosted.org/packages/8a/8b/badd9247d6ec25f5f634a9b3d0d92e39c045824ec7e8afcedca8ee52c1e2/watchfiles-0.24.0-cp311-none-win_amd64.whl", hash = "sha256:d3dcb774e3568477275cc76554b5a565024b8ba3a0322f77c246bc7111c5bb9c", size = 277527 }, + { url = "https://files.pythonhosted.org/packages/af/19/35c957c84ee69d904299a38bae3614f7cede45f07f174f6d5a2f4dbd6033/watchfiles-0.24.0-cp311-none-win_arm64.whl", hash = "sha256:9301c689051a4857d5b10777da23fafb8e8e921bcf3abe6448a058d27fb67633", size = 266253 }, + { url = "https://files.pythonhosted.org/packages/35/82/92a7bb6dc82d183e304a5f84ae5437b59ee72d48cee805a9adda2488b237/watchfiles-0.24.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7211b463695d1e995ca3feb38b69227e46dbd03947172585ecb0588f19b0d87a", size = 374137 }, + { url = "https://files.pythonhosted.org/packages/87/91/49e9a497ddaf4da5e3802d51ed67ff33024597c28f652b8ab1e7c0f5718b/watchfiles-0.24.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b8693502d1967b00f2fb82fc1e744df128ba22f530e15b763c8d82baee15370", size = 367733 }, + { url = "https://files.pythonhosted.org/packages/0d/d8/90eb950ab4998effea2df4cf3a705dc594f6bc501c5a353073aa990be965/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdab9555053399318b953a1fe1f586e945bc8d635ce9d05e617fd9fe3a4687d6", size = 437322 }, + { url = "https://files.pythonhosted.org/packages/6c/a2/300b22e7bc2a222dd91fce121cefa7b49aa0d26a627b2777e7bdfcf1110b/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:34e19e56d68b0dad5cff62273107cf5d9fbaf9d75c46277aa5d803b3ef8a9e9b", size = 433409 }, + { url = "https://files.pythonhosted.org/packages/99/44/27d7708a43538ed6c26708bcccdde757da8b7efb93f4871d4cc39cffa1cc/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:41face41f036fee09eba33a5b53a73e9a43d5cb2c53dad8e61fa6c9f91b5a51e", size = 452142 }, + { url = "https://files.pythonhosted.org/packages/b0/ec/c4e04f755be003129a2c5f3520d2c47026f00da5ecb9ef1e4f9449637571/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5148c2f1ea043db13ce9b0c28456e18ecc8f14f41325aa624314095b6aa2e9ea", size = 469414 }, + { url = "https://files.pythonhosted.org/packages/c5/4e/cdd7de3e7ac6432b0abf282ec4c1a1a2ec62dfe423cf269b86861667752d/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e4bd963a935aaf40b625c2499f3f4f6bbd0c3776f6d3bc7c853d04824ff1c9f", size = 472962 }, + { url = "https://files.pythonhosted.org/packages/27/69/e1da9d34da7fc59db358424f5d89a56aaafe09f6961b64e36457a80a7194/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c79d7719d027b7a42817c5d96461a99b6a49979c143839fc37aa5748c322f234", size = 425705 }, + { url = "https://files.pythonhosted.org/packages/e8/c1/24d0f7357be89be4a43e0a656259676ea3d7a074901f47022f32e2957798/watchfiles-0.24.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:32aa53a9a63b7f01ed32e316e354e81e9da0e6267435c7243bf8ae0f10b428ef", size = 612851 }, + { url = "https://files.pythonhosted.org/packages/c7/af/175ba9b268dec56f821639c9893b506c69fd999fe6a2e2c51de420eb2f01/watchfiles-0.24.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ce72dba6a20e39a0c628258b5c308779b8697f7676c254a845715e2a1039b968", size = 594868 }, + { url = "https://files.pythonhosted.org/packages/44/81/1f701323a9f70805bc81c74c990137123344a80ea23ab9504a99492907f8/watchfiles-0.24.0-cp312-none-win32.whl", hash = "sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444", size = 264109 }, + { url = "https://files.pythonhosted.org/packages/b4/0b/32cde5bc2ebd9f351be326837c61bdeb05ad652b793f25c91cac0b48a60b/watchfiles-0.24.0-cp312-none-win_amd64.whl", hash = "sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896", size = 277055 }, + { url = "https://files.pythonhosted.org/packages/4b/81/daade76ce33d21dbec7a15afd7479de8db786e5f7b7d249263b4ea174e08/watchfiles-0.24.0-cp312-none-win_arm64.whl", hash = "sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418", size = 266169 }, + { url = "https://files.pythonhosted.org/packages/30/dc/6e9f5447ae14f645532468a84323a942996d74d5e817837a5c8ce9d16c69/watchfiles-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48", size = 373764 }, + { url = "https://files.pythonhosted.org/packages/79/c0/c3a9929c372816c7fc87d8149bd722608ea58dc0986d3ef7564c79ad7112/watchfiles-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90", size = 367873 }, + { url = "https://files.pythonhosted.org/packages/2e/11/ff9a4445a7cfc1c98caf99042df38964af12eed47d496dd5d0d90417349f/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94", size = 438381 }, + { url = "https://files.pythonhosted.org/packages/48/a3/763ba18c98211d7bb6c0f417b2d7946d346cdc359d585cc28a17b48e964b/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e", size = 432809 }, + { url = "https://files.pythonhosted.org/packages/30/4c/616c111b9d40eea2547489abaf4ffc84511e86888a166d3a4522c2ba44b5/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827", size = 451801 }, + { url = "https://files.pythonhosted.org/packages/b6/be/d7da83307863a422abbfeb12903a76e43200c90ebe5d6afd6a59d158edea/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df", size = 468886 }, + { url = "https://files.pythonhosted.org/packages/1d/d3/3dfe131ee59d5e90b932cf56aba5c996309d94dafe3d02d204364c23461c/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab", size = 472973 }, + { url = "https://files.pythonhosted.org/packages/42/6c/279288cc5653a289290d183b60a6d80e05f439d5bfdfaf2d113738d0f932/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f", size = 425282 }, + { url = "https://files.pythonhosted.org/packages/d6/d7/58afe5e85217e845edf26d8780c2d2d2ae77675eeb8d1b8b8121d799ce52/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b", size = 612540 }, + { url = "https://files.pythonhosted.org/packages/6d/d5/b96eeb9fe3fda137200dd2f31553670cbc731b1e13164fd69b49870b76ec/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18", size = 593625 }, + { url = "https://files.pythonhosted.org/packages/c1/e5/c326fe52ee0054107267608d8cea275e80be4455b6079491dfd9da29f46f/watchfiles-0.24.0-cp313-none-win32.whl", hash = "sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07", size = 263899 }, + { url = "https://files.pythonhosted.org/packages/a6/8b/8a7755c5e7221bb35fe4af2dc44db9174f90ebf0344fd5e9b1e8b42d381e/watchfiles-0.24.0-cp313-none-win_amd64.whl", hash = "sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366", size = 276622 }, + { url = "https://files.pythonhosted.org/packages/df/94/1ad200e937ec91b2a9d6b39ae1cf9c2b1a9cc88d5ceb43aa5c6962eb3c11/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f", size = 376986 }, + { url = "https://files.pythonhosted.org/packages/ee/fd/d9e020d687ccf90fe95efc513fbb39a8049cf5a3ff51f53c59fcf4c47a5d/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b", size = 369445 }, + { url = "https://files.pythonhosted.org/packages/43/cb/c0279b35053555d10ef03559c5aebfcb0c703d9c70a7b4e532df74b9b0e8/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4", size = 439383 }, + { url = "https://files.pythonhosted.org/packages/8b/c4/08b3c2cda45db5169148a981c2100c744a4a222fa7ae7644937c0c002069/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a", size = 426804 }, +] + +[[package]] +name = "webencodings" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774 }, +] + +[[package]] +name = "websockets" +version = "13.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/73/9223dbc7be3dcaf2a7bbf756c351ec8da04b1fa573edaf545b95f6b0c7fd/websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878", size = 158549 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/94/d15dbfc6a5eb636dbc754303fba18208f2e88cf97e733e1d64fb9cb5c89e/websockets-13.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee", size = 157815 }, + { url = "https://files.pythonhosted.org/packages/30/02/c04af33f4663945a26f5e8cf561eb140c35452b50af47a83c3fbcfe62ae1/websockets-13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7", size = 155466 }, + { url = "https://files.pythonhosted.org/packages/35/e8/719f08d12303ea643655e52d9e9851b2dadbb1991d4926d9ce8862efa2f5/websockets-13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6", size = 155716 }, + { url = "https://files.pythonhosted.org/packages/91/e1/14963ae0252a8925f7434065d25dcd4701d5e281a0b4b460a3b5963d2594/websockets-13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b", size = 164806 }, + { url = "https://files.pythonhosted.org/packages/ec/fa/ab28441bae5e682a0f7ddf3d03440c0c352f930da419301f4a717f675ef3/websockets-13.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa", size = 163810 }, + { url = "https://files.pythonhosted.org/packages/44/77/dea187bd9d16d4b91566a2832be31f99a40d0f5bfa55eeb638eb2c3bc33d/websockets-13.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700", size = 164125 }, + { url = "https://files.pythonhosted.org/packages/cf/d9/3af14544e83f1437eb684b399e6ba0fa769438e869bf5d83d74bc197fae8/websockets-13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c", size = 164532 }, + { url = "https://files.pythonhosted.org/packages/1c/8a/6d332eabe7d59dfefe4b8ba6f46c8c5fabb15b71c8a8bc3d2b65de19a7b6/websockets-13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0", size = 163948 }, + { url = "https://files.pythonhosted.org/packages/1a/91/a0aeadbaf3017467a1ee03f8fb67accdae233fe2d5ad4b038c0a84e357b0/websockets-13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f", size = 163898 }, + { url = "https://files.pythonhosted.org/packages/71/31/a90fb47c63e0ae605be914b0b969d7c6e6ffe2038cd744798e4b3fbce53b/websockets-13.1-cp310-cp310-win32.whl", hash = "sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe", size = 158706 }, + { url = "https://files.pythonhosted.org/packages/93/ca/9540a9ba80da04dc7f36d790c30cae4252589dbd52ccdc92e75b0be22437/websockets-13.1-cp310-cp310-win_amd64.whl", hash = "sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a", size = 159141 }, + { url = "https://files.pythonhosted.org/packages/b2/f0/cf0b8a30d86b49e267ac84addbebbc7a48a6e7bb7c19db80f62411452311/websockets-13.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19", size = 157813 }, + { url = "https://files.pythonhosted.org/packages/bf/e7/22285852502e33071a8cf0ac814f8988480ec6db4754e067b8b9d0e92498/websockets-13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5", size = 155469 }, + { url = "https://files.pythonhosted.org/packages/68/d4/c8c7c1e5b40ee03c5cc235955b0fb1ec90e7e37685a5f69229ad4708dcde/websockets-13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd", size = 155717 }, + { url = "https://files.pythonhosted.org/packages/c9/e4/c50999b9b848b1332b07c7fd8886179ac395cb766fda62725d1539e7bc6c/websockets-13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02", size = 165379 }, + { url = "https://files.pythonhosted.org/packages/bc/49/4a4ad8c072f18fd79ab127650e47b160571aacfc30b110ee305ba25fffc9/websockets-13.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7", size = 164376 }, + { url = "https://files.pythonhosted.org/packages/af/9b/8c06d425a1d5a74fd764dd793edd02be18cf6fc3b1ccd1f29244ba132dc0/websockets-13.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096", size = 164753 }, + { url = "https://files.pythonhosted.org/packages/d5/5b/0acb5815095ff800b579ffc38b13ab1b915b317915023748812d24e0c1ac/websockets-13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084", size = 165051 }, + { url = "https://files.pythonhosted.org/packages/30/93/c3891c20114eacb1af09dedfcc620c65c397f4fd80a7009cd12d9457f7f5/websockets-13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3", size = 164489 }, + { url = "https://files.pythonhosted.org/packages/28/09/af9e19885539759efa2e2cd29b8b3f9eecef7ecefea40d46612f12138b36/websockets-13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9", size = 164438 }, + { url = "https://files.pythonhosted.org/packages/b6/08/6f38b8e625b3d93de731f1d248cc1493327f16cb45b9645b3e791782cff0/websockets-13.1-cp311-cp311-win32.whl", hash = "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f", size = 158710 }, + { url = "https://files.pythonhosted.org/packages/fb/39/ec8832ecb9bb04a8d318149005ed8cee0ba4e0205835da99e0aa497a091f/websockets-13.1-cp311-cp311-win_amd64.whl", hash = "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557", size = 159137 }, + { url = "https://files.pythonhosted.org/packages/df/46/c426282f543b3c0296cf964aa5a7bb17e984f58dde23460c3d39b3148fcf/websockets-13.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc", size = 157821 }, + { url = "https://files.pythonhosted.org/packages/aa/85/22529867010baac258da7c45848f9415e6cf37fef00a43856627806ffd04/websockets-13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49", size = 155480 }, + { url = "https://files.pythonhosted.org/packages/29/2c/bdb339bfbde0119a6e84af43ebf6275278698a2241c2719afc0d8b0bdbf2/websockets-13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd", size = 155715 }, + { url = "https://files.pythonhosted.org/packages/9f/d0/8612029ea04c5c22bf7af2fd3d63876c4eaeef9b97e86c11972a43aa0e6c/websockets-13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0", size = 165647 }, + { url = "https://files.pythonhosted.org/packages/56/04/1681ed516fa19ca9083f26d3f3a302257e0911ba75009533ed60fbb7b8d1/websockets-13.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6", size = 164592 }, + { url = "https://files.pythonhosted.org/packages/38/6f/a96417a49c0ed132bb6087e8e39a37db851c70974f5c724a4b2a70066996/websockets-13.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9", size = 165012 }, + { url = "https://files.pythonhosted.org/packages/40/8b/fccf294919a1b37d190e86042e1a907b8f66cff2b61e9befdbce03783e25/websockets-13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68", size = 165311 }, + { url = "https://files.pythonhosted.org/packages/c1/61/f8615cf7ce5fe538476ab6b4defff52beb7262ff8a73d5ef386322d9761d/websockets-13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14", size = 164692 }, + { url = "https://files.pythonhosted.org/packages/5c/f1/a29dd6046d3a722d26f182b783a7997d25298873a14028c4760347974ea3/websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf", size = 164686 }, + { url = "https://files.pythonhosted.org/packages/0f/99/ab1cdb282f7e595391226f03f9b498f52109d25a2ba03832e21614967dfa/websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c", size = 158712 }, + { url = "https://files.pythonhosted.org/packages/46/93/e19160db48b5581feac8468330aa11b7292880a94a37d7030478596cc14e/websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3", size = 159145 }, + { url = "https://files.pythonhosted.org/packages/51/20/2b99ca918e1cbd33c53db2cace5f0c0cd8296fc77558e1908799c712e1cd/websockets-13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6", size = 157828 }, + { url = "https://files.pythonhosted.org/packages/b8/47/0932a71d3d9c0e9483174f60713c84cee58d62839a143f21a2bcdbd2d205/websockets-13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708", size = 155487 }, + { url = "https://files.pythonhosted.org/packages/a9/60/f1711eb59ac7a6c5e98e5637fef5302f45b6f76a2c9d64fd83bbb341377a/websockets-13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418", size = 155721 }, + { url = "https://files.pythonhosted.org/packages/6a/e6/ba9a8db7f9d9b0e5f829cf626ff32677f39824968317223605a6b419d445/websockets-13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a", size = 165609 }, + { url = "https://files.pythonhosted.org/packages/c1/22/4ec80f1b9c27a0aebd84ccd857252eda8418ab9681eb571b37ca4c5e1305/websockets-13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f", size = 164556 }, + { url = "https://files.pythonhosted.org/packages/27/ac/35f423cb6bb15600438db80755609d27eda36d4c0b3c9d745ea12766c45e/websockets-13.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5", size = 164993 }, + { url = "https://files.pythonhosted.org/packages/31/4e/98db4fd267f8be9e52e86b6ee4e9aa7c42b83452ea0ea0672f176224b977/websockets-13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135", size = 165360 }, + { url = "https://files.pythonhosted.org/packages/3f/15/3f0de7cda70ffc94b7e7024544072bc5b26e2c1eb36545291abb755d8cdb/websockets-13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2", size = 164745 }, + { url = "https://files.pythonhosted.org/packages/a1/6e/66b6b756aebbd680b934c8bdbb6dcb9ce45aad72cde5f8a7208dbb00dd36/websockets-13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6", size = 164732 }, + { url = "https://files.pythonhosted.org/packages/35/c6/12e3aab52c11aeb289e3dbbc05929e7a9d90d7a9173958477d3ef4f8ce2d/websockets-13.1-cp313-cp313-win32.whl", hash = "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d", size = 158709 }, + { url = "https://files.pythonhosted.org/packages/41/d8/63d6194aae711d7263df4498200c690a9c39fb437ede10f3e157a6343e0d/websockets-13.1-cp313-cp313-win_amd64.whl", hash = "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2", size = 159144 }, + { url = "https://files.pythonhosted.org/packages/2d/75/6da22cb3ad5b8c606963f9a5f9f88656256fecc29d420b4b2bf9e0c7d56f/websockets-13.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238", size = 155499 }, + { url = "https://files.pythonhosted.org/packages/c0/ba/22833d58629088fcb2ccccedfae725ac0bbcd713319629e97125b52ac681/websockets-13.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5", size = 155737 }, + { url = "https://files.pythonhosted.org/packages/95/54/61684fe22bdb831e9e1843d972adadf359cf04ab8613285282baea6a24bb/websockets-13.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9", size = 157095 }, + { url = "https://files.pythonhosted.org/packages/fc/f5/6652fb82440813822022a9301a30afde85e5ff3fb2aebb77f34aabe2b4e8/websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6", size = 156701 }, + { url = "https://files.pythonhosted.org/packages/67/33/ae82a7b860fa8a08aba68818bdf7ff61f04598aa5ab96df4cd5a3e418ca4/websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a", size = 156654 }, + { url = "https://files.pythonhosted.org/packages/63/0b/a1b528d36934f833e20f6da1032b995bf093d55cb416b9f2266f229fb237/websockets-13.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23", size = 159192 }, + { url = "https://files.pythonhosted.org/packages/56/27/96a5cd2626d11c8280656c6c71d8ab50fe006490ef9971ccd154e0c42cd2/websockets-13.1-py3-none-any.whl", hash = "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f", size = 152134 }, +] + +[[package]] +name = "yamllint" +version = "1.35.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pathspec" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/06/d8cee5c3dfd550cc0a466ead8b321138198485d1034130ac1393cc49d63e/yamllint-1.35.1.tar.gz", hash = "sha256:7a003809f88324fd2c877734f2d575ee7881dd9043360657cc8049c809eba6cd", size = 134583 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/28/2abf1ec14df2d584b9e7ce3b0be458838741e6aaff7a540374ba9af83916/yamllint-1.35.1-py3-none-any.whl", hash = "sha256:2e16e504bb129ff515b37823b472750b36b6de07963bd74b307341ef5ad8bdc3", size = 66738 }, +] + +[[package]] +name = "zipp" +version = "3.20.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/bf/5c0000c44ebc80123ecbdddba1f5dcd94a5ada602a9c225d84b5aaa55e86/zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29", size = 24199 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/8b/5ba542fa83c90e09eac972fc9baca7a88e7e7ca4b221a89251954019308b/zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", size = 9200 }, +] From 30d1d01024923ca4c3fbc9e92b3f4f0367b1a85b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 11:59:48 -0500 Subject: [PATCH 242/333] build(deps): update dependency pyright to v1.1.389 (#279) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- uv.lock | 27 ++++++++++++++++++++------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4ad8bd2b59..f1aacf8f67 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ lint = [ ] types = [ "mypy[reports]~=1.11.0", - "pyright==1.1.388", + "pyright==1.1.389", "types-Pygments", "types-colorama", "types-setuptools", @@ -61,7 +61,7 @@ dev-dependencies = [ "pytest-mock~=3.12", "yamllint~=1.34", "mypy[reports]~=1.11.0", - "pyright==1.1.388", + "pyright==1.1.389", "types-Pygments", "types-colorama", "types-setuptools", diff --git a/uv.lock b/uv.lock index c39fa9fca8..f9bf3248e3 100644 --- a/uv.lock +++ b/uv.lock @@ -7,13 +7,14 @@ resolution-markers = [ [manifest] constraints = [ - { name = "build", specifier = ">=0.1.0" }, + { name = "build", specifier = ">=0.7.0" }, { name = "iniconfig", specifier = ">=1.1.0" }, { name = "lxml", specifier = ">=5.0" }, { name = "markdown", specifier = ">=3.0" }, { name = "markupsafe", specifier = ">=2.0" }, { name = "pyparsing", specifier = ">=3.0.0" }, { name = "pyproject-hooks", specifier = ">=1.0.0" }, + { name = "pyyaml", specifier = ">5.0" }, { name = "pyyaml", specifier = ">=5.0" }, { name = "regex", specifier = ">=2021.11.10" }, { name = "sphinx-basic-ng", specifier = ">=1.0.0b1" }, @@ -452,7 +453,7 @@ name = "importlib-metadata" version = "8.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "zipp" }, + { name = "zipp", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", size = 55304 } wheels = [ @@ -959,15 +960,15 @@ wheels = [ [[package]] name = "pyright" -version = "1.1.383" +version = "1.1.389" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodeenv" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/a9/4654d15f4125d8dca6318d7be36a3283a8b3039661291c59bbdd1e576dcf/pyright-1.1.383.tar.gz", hash = "sha256:1df7f12407f3710c9c6df938d98ec53f70053e6c6bbf71ce7bcb038d42f10070", size = 21971 } +sdist = { url = "https://files.pythonhosted.org/packages/72/4e/9a5ab8745e7606b88c2c7ca223449ac9d82a71fd5e31df47b453f2cb39a1/pyright-1.1.389.tar.gz", hash = "sha256:716bf8cc174ab8b4dcf6828c3298cac05c5ed775dda9910106a5dcfe4c7fe220", size = 21940 } wheels = [ - { url = "https://files.pythonhosted.org/packages/1c/55/40a6559cea209b551c81dcd31cb351a6ffdb5876e7865ee242e269af72d8/pyright-1.1.383-py3-none-any.whl", hash = "sha256:d864d1182a313f45aaf99e9bfc7d2668eeabc99b29a556b5344894fd73cb1959", size = 18577 }, + { url = "https://files.pythonhosted.org/packages/1b/26/c288cabf8cfc5a27e1aa9e5029b7682c0f920b8074f45d22bf844314d66a/pyright-1.1.389-py3-none-any.whl", hash = "sha256:41e9620bba9254406dc1f621a88ceab5a88af4c826feb4f614d95691ed243a60", size = 18581 }, ] [[package]] @@ -1470,7 +1471,7 @@ wheels = [ [[package]] name = "starcraft" -version = "0.0.post246+g316bea6.d20241022" +version = "0.0.post250+ga411e24.d20241118" source = { editable = "." } [package.optional-dependencies] @@ -1496,16 +1497,22 @@ types = [ dev = [ { name = "build" }, { name = "coverage", extra = ["toml"] }, + { name = "mypy", extra = ["reports"] }, + { name = "pyright" }, { name = "pytest" }, { name = "pytest-cov" }, { name = "pytest-mock" }, + { name = "types-colorama" }, + { name = "types-pygments" }, + { name = "types-setuptools" }, + { name = "yamllint" }, ] [package.metadata] requires-dist = [ { name = "canonical-sphinx", marker = "extra == 'docs'", specifier = "~=0.2.0" }, { name = "mypy", extras = ["reports"], marker = "extra == 'types'", specifier = "~=1.11.0" }, - { name = "pyright", marker = "extra == 'types'", specifier = "==1.1.383" }, + { name = "pyright", marker = "extra == 'types'", specifier = "==1.1.389" }, { name = "sphinx-autobuild", marker = "extra == 'docs'", specifier = "~=2024.2" }, { name = "sphinx-lint", marker = "extra == 'docs'", specifier = "==1.0.0" }, { name = "sphinx-pydantic", marker = "extra == 'docs'", specifier = "==0.1.1" }, @@ -1520,9 +1527,15 @@ requires-dist = [ dev = [ { name = "build" }, { name = "coverage", extras = ["toml"], specifier = "~=7.4" }, + { name = "mypy", extras = ["reports"], specifier = "~=1.11.0" }, + { name = "pyright", specifier = "==1.1.389" }, { name = "pytest", specifier = "~=8.0" }, { name = "pytest-cov", specifier = "~=5.0" }, { name = "pytest-mock", specifier = "~=3.12" }, + { name = "types-colorama" }, + { name = "types-pygments" }, + { name = "types-setuptools" }, + { name = "yamllint", specifier = "~=1.34" }, ] [[package]] From 6aa708785640915b865a6d902eb1a0f2f17c344c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 12:04:34 -0500 Subject: [PATCH 243/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.7.4 (#278) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 50e6d3df6d..54740739df 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.9" + rev: "v0.7.4" hooks: # Run the linter - id: ruff From a235960c5b147a52cb7207cc86a147c8fb4deea4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 12:57:16 -0500 Subject: [PATCH 244/333] build(config): migrate config .github/renovate.json5 (#281) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/renovate.json5 | 291 +++++++++++++++++++++++++---------------- 1 file changed, 178 insertions(+), 113 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index a6959ddffd..f588fef4d1 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,155 +1,220 @@ { - // Configuration file for RenovateBot: https://docs.renovatebot.com/configuration-options - extends: ["config:recommended", ":semanticCommitTypeAll(build)", ":enablePreCommit"], - labels: ["dependencies"], // For convenient searching in GitHub - baseBranches: ["$default", "/^hotfix\\/.*/"], + extends: [ + 'config:recommended', + ':semanticCommitTypeAll(build)', + ':enablePreCommit', + ], + labels: [ + 'dependencies', + ], + baseBranches: [ + '$default', + '/^hotfix\\/.*/', + ], pip_requirements: { - fileMatch: ["^tox.ini$", "(^|/)requirements([\\w-]*)\\.txt$"] + fileMatch: [ + '^tox.ini$', + '(^|/)requirements([\\w-]*)\\.txt$', + ], }, - packageRules: [ + packageRules: [ { - // Internal package minor patch updates get top priority, with auto-merging - groupName: "internal package minor releases", - matchPackagePatterns: ["^craft-.*"], - matchUpdateTypes: ["minor", "patch", "pin", "digest"], + groupName: 'internal package minor releases', + matchUpdateTypes: [ + 'minor', + 'patch', + 'pin', + 'digest', + ], prPriority: 10, automerge: true, - minimumReleaseAge: "0 seconds", - schedule: ["at any time"], - matchBaseBranches: ["$default"], // Only do minor releases on main + minimumReleaseAge: '0 seconds', + schedule: [ + 'at any time', + ], + matchBaseBranches: [ + '$default', + ], + matchPackageNames: [ + '/^craft-.*/', + ], }, { - // Same as above, but for hotfix branches, only for patch, and without auto-merging. - groupName: "internal package patch releases (hotfix)", - matchPackagePatterns: ["^craft-.*"], - matchUpdateTypes: ["patch", "pin", "digest"], + groupName: 'internal package patch releases (hotfix)', + matchUpdateTypes: [ + 'patch', + 'pin', + 'digest', + ], prPriority: 10, - minimumReleaseAge: "0 seconds", - schedule: ["at any time"], - matchBaseBranches: ["/^hotfix\\/.*/"], // All hotfix branches + minimumReleaseAge: '0 seconds', + schedule: [ + 'at any time', + ], + matchBaseBranches: [ + '/^hotfix\\/.*/', + ], + matchPackageNames: [ + '/^craft-.*/', + ], }, { - // Automerge patches, pin changes and digest changes. - // Also groups these changes together. - groupName: "bugfixes", - excludeDepPatterns: [ - "lint/.*", - "types/.*", - "pyright", // Pyright needs to be done separately. - ], - matchUpdateTypes: ["patch", "pin", "digest"], - prPriority: 3, // Patches should go first! - automerge: true + groupName: 'bugfixes', + matchUpdateTypes: [ + 'patch', + 'pin', + 'digest', + ], + prPriority: 3, + automerge: true, + matchDepNames: [ + '!/lint/.*/', + '!/types/.*/', + '!/pyright/', + ], }, { - // Update all internal packages in one higher-priority PR - groupName: "internal packages", - matchDepPatterns: ["craft-.*", "snap-.*"], - matchCategories: ["python"], + groupName: 'internal packages', + matchCategories: [ + 'python', + ], prPriority: 2, - matchBaseBranches: ["$default"], // Not for hotfix branches + matchBaseBranches: [ + '$default', + ], + matchDepNames: [ + '/craft-.*/', + '/snap-.*/', + ], }, { - // GitHub Actions are higher priority to update than most dependencies since they don't tend to break things. - groupName: "GitHub Actions", - matchManagers: ["github-actions"], + groupName: 'GitHub Actions', + matchManagers: [ + 'github-actions', + ], prPriority: 1, automerge: true, }, - // Everything not in one of these rules gets priority 0 and falls here. { - //Do all pydantic-related updates together - groupName: "pydantic etc.", - matchPackagePatterns: ["^pydantic"], - matchBaseBranches: ["$default"], // Only do minor releases on main + groupName: 'pydantic etc.', + matchBaseBranches: [ + '$default', + ], + matchPackageNames: [ + '/^pydantic/', + ], }, { - // Minor changes can be grouped and automerged for dev dependencies, but are also deprioritised. - groupName: "development dependencies (non-major)", - groupSlug: "dev-dependencies", - matchDepPatterns: [ - "dev/.*", - "lint/.*", - "types/.*" - ], - matchPackagePatterns: [ - // Brought from charmcraft. May not be complete. - // This helps group dependencies in requirements-dev.txt files. - "^(.*/)?autoflake$", - "^(.*/)?black$", - "^(.*/)?codespell$", - "^(.*/)?coverage$", - "^(.*/)?flake8$", - "^(.*/)?hypothesis$", - "^(.*/)?mypy$", - "^(.*/)?pycodestyle$", - "^(.*/)?docstyle$", - "^(.*/)?pyfakefs$", - "^(.*/)?pyflakes$", - "^(.*/)?pylint$", - "^(.*/)?pytest", - "^(.*/)?responses$", - "^(.*/)?ruff$", - "^(.*/)?twine$", - "^(.*/)?tox$", - "^(.*/)?types-", - ], - matchUpdateTypes: ["minor", "patch", "pin", "digest"], + groupName: 'development dependencies (non-major)', + groupSlug: 'dev-dependencies', + matchUpdateTypes: [ + 'minor', + 'patch', + 'pin', + 'digest', + ], prPriority: -1, automerge: true, - matchBaseBranches: ["$default"], // Not for hotfix branches + matchBaseBranches: [ + '$default', + ], + matchDepNames: [ + '/dev/.*/', + '/lint/.*/', + '/types/.*/', + ], + matchPackageNames: [ + '/^(.*/)?autoflake$/', + '/^(.*/)?black$/', + '/^(.*/)?codespell$/', + '/^(.*/)?coverage$/', + '/^(.*/)?flake8$/', + '/^(.*/)?hypothesis$/', + '/^(.*/)?mypy$/', + '/^(.*/)?pycodestyle$/', + '/^(.*/)?docstyle$/', + '/^(.*/)?pyfakefs$/', + '/^(.*/)?pyflakes$/', + '/^(.*/)?pylint$/', + '/^(.*/)?pytest/', + '/^(.*/)?responses$/', + '/^(.*/)?ruff$/', + '/^(.*/)?twine$/', + '/^(.*/)?tox$/', + '/^(.*/)?types-/', + ], }, { - // Documentation related updates - groupName: "documentation dependencies", - groupSlug: "doc-dependencies", - matchPackageNames: ["Sphinx", "furo"], - matchPackagePatterns: ["[Ss]phinx.*$"], - matchDepPatterns: ["docs/.*"], - matchBaseBranches: ["$default"], // Not for hotfix branches + groupName: 'documentation dependencies', + groupSlug: 'doc-dependencies', + matchPackageNames: [ + 'Sphinx', + 'furo', + '/[Ss]phinx.*$/', + ], + matchBaseBranches: [ + '$default', + ], + matchDepNames: [ + '/docs/.*/', + ], }, { - // Other major dependencies get deprioritised below minor dev dependencies. - matchUpdateTypes: ["major"], + matchUpdateTypes: [ + 'major', + ], prPriority: -2, - matchBaseBranches: ["$default"], // Not for hotfix branches + matchBaseBranches: [ + '$default', + ], }, { - // Major dev dependencies are stone last, but grouped. - groupName: "development dependencies (major versions)", - groupSlug: "dev-dependencies", - matchDepTypes: ["devDependencies"], - matchUpdateTypes: ["major"], + groupName: 'development dependencies (major versions)', + groupSlug: 'dev-dependencies', + matchDepTypes: [ + 'devDependencies', + ], + matchUpdateTypes: [ + 'major', + ], prPriority: -3, - matchBaseBranches: ["$default"], // Not for hotfix branches + matchBaseBranches: [ + '$default', + ], }, { - // Pyright makes regular breaking changes in patch releases, so we separate these - // and do them independently. - matchPackageNames: ["pyright", "types/pyright"], + matchPackageNames: [ + 'pyright', + 'types/pyright', + ], prPriority: -4, - matchBaseBranches: ["$default"], // Not for hotfix branches - } + matchBaseBranches: [ + '$default', + ], + }, ], customManagers: [ { - // tox.ini can get updates too if we specify for each package. - fileMatch: ["tox.ini"], - customType: "regex", - depTypeTemplate: "devDependencies", + fileMatch: [ + 'tox.ini', + ], + customType: 'regex', + depTypeTemplate: 'devDependencies', matchStrings: [ - "# renovate: datasource=(?\\S+)\n\\s+(?.*?)(\\[[\\w]*\\])*[=><]=?(?.*?)\n" - ] + '# renovate: datasource=(?\\S+)\n\\s+(?.*?)(\\[[\\w]*\\])*[=><]=?(?.*?)\n', + ], }, ], - timezone: "Etc/UTC", - schedule: ["every weekend"], - prConcurrentLimit: 2, // No more than 2 open PRs at a time. - branchConcurrentLimit: 20, // No more than 20 open branches at a time. - prCreation: "not-pending", // Wait until status checks have completed before raising the PR - prNotPendingHours: 4, // ...unless the status checks have been running for 4+ hours. - prHourlyLimit: 1, // No more than 1 PR per hour. - minimumReleaseAge: "2 days", - automergeStrategy: "squash", // Squash & rebase when auto-merging. - semanticCommitType: "build" // use `build` as commit header type (i.e. `build(deps): `) + timezone: 'Etc/UTC', + schedule: [ + 'every weekend', + ], + prConcurrentLimit: 2, + branchConcurrentLimit: 20, + prCreation: 'not-pending', + prNotPendingHours: 4, + prHourlyLimit: 1, + minimumReleaseAge: '2 days', + automergeStrategy: 'squash', + semanticCommitType: 'build', } From b5c869d85018cea23b1b7378678429f4303c5ed1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 12:57:57 -0500 Subject: [PATCH 245/333] build(deps): update pre-commit hook pre-commit/pre-commit-hooks to v5 (#280) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 54740739df..ec44787ad1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: "v4.6.0" + rev: "v5.0.0" hooks: - id: trailing-whitespace - id: end-of-file-fixer From 6278c8e883fab35866e40b34521668f91b493238 Mon Sep 17 00:00:00 2001 From: Dariusz Duda Date: Thu, 28 Nov 2024 09:33:43 -0500 Subject: [PATCH 246/333] ci(rtd): pin python version to 3.12 (#284) Signed-off-by: Dariusz Duda --- .readthedocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 071ed7918e..78b2a7db59 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -17,7 +17,7 @@ sphinx: build: os: ubuntu-24.04 tools: - python: "3" + python: "3.12" python: install: From dfe2e9acbd547fe2f0e46a66f32cc50e4cdefb05 Mon Sep 17 00:00:00 2001 From: Michael DuBelko Date: Fri, 29 Nov 2024 09:53:50 -0800 Subject: [PATCH 247/333] docs: add release notes index and template (#286) Release notes occupy their own top-level section in the documentation TOC. The template for individual release notes is included as a comment at the end of the index. --- docs/explanation/index.rst | 2 +- docs/{howto => how-to-guides}/index.rst | 4 +- docs/index.rst | 12 +- docs/reference/index.rst | 4 +- docs/release-notes/index.rst | 263 ++++++++++++++++++++++++ docs/tutorials/index.rst | 4 +- 6 files changed, 277 insertions(+), 12 deletions(-) rename docs/{howto => how-to-guides}/index.rst (57%) create mode 100644 docs/release-notes/index.rst diff --git a/docs/explanation/index.rst b/docs/explanation/index.rst index b9ed902fb0..e2ad4ed003 100644 --- a/docs/explanation/index.rst +++ b/docs/explanation/index.rst @@ -1,7 +1,7 @@ .. _explanation: Explanation -*********** +=========== .. toctree:: :maxdepth: 1 diff --git a/docs/howto/index.rst b/docs/how-to-guides/index.rst similarity index 57% rename from docs/howto/index.rst rename to docs/how-to-guides/index.rst index 436a1880c1..1549165efb 100644 --- a/docs/howto/index.rst +++ b/docs/how-to-guides/index.rst @@ -1,7 +1,7 @@ -.. _howto: +.. _how-to-guides: How-to guides -************* +============= .. toctree:: :maxdepth: 1 diff --git a/docs/index.rst b/docs/index.rst index 2a3ef9f65c..dc4c41f8b2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,16 +8,17 @@ Starcraft :hidden: tutorials/index - howto/index + how-to-guides/index reference/index explanation/index + release-notes/index .. list-table:: - * - | :ref:`Tutorial ` + * - | :ref:`Tutorial ` | **Get started** with a hands-on introduction to Starcraft - * - | :ref:`How-to guides ` + * - | :ref:`How-to guides ` | **Step-by-step guides** covering key operations and common tasks * - | :ref:`Reference ` | **Technical information** about Starcraft @@ -26,7 +27,7 @@ Starcraft Project and community -===================== +--------------------- Starcraft is a member of the Canonical family. It's an open source project that warmly welcomes community projects, contributions, suggestions, fixes @@ -36,8 +37,9 @@ and constructive feedback. * `Canonical contributor licenses agreement `_. + Indices and tables -================== +------------------ * :ref:`genindex` * :ref:`modindex` diff --git a/docs/reference/index.rst b/docs/reference/index.rst index 75be505951..976c403a0c 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -1,13 +1,13 @@ .. _reference: Reference -********* +========= .. toctree:: :maxdepth: 1 Indices and tables -================== +------------------ * :ref:`genindex` * :ref:`modindex` diff --git a/docs/release-notes/index.rst b/docs/release-notes/index.rst new file mode 100644 index 0000000000..82729ed26a --- /dev/null +++ b/docs/release-notes/index.rst @@ -0,0 +1,263 @@ +.. _release-notes: + +Release notes +============= + +This page lists past release notes for Starcraft, summarising new features, bug +fixes and backwards-incompatible changes in each version. It also contains the +release and support policies for Starcraft. + + +Current releases +---------------- + + + +~~~~~~~~~~~~~~~~ + +- +- +- + + + +~~~~~~~~~~~~~~~~~~ + + + +- +- +- + + +Past releases +------------- + + + +~~~~~~~~~~~~~~ + +- +- +- + + +.. _release_policy_and_schedule: + +Release policy and schedule +--------------------------- + +Canonical is committed to supporting the <"latest major release" or "last two +major releases"> of Starcraft. + +Starcraft is released when it achieves development milestones in its product +lifecycle. It doesn't follow a predefined release cadence. + +Starcraft release naming follows the Semantic Versioning 2.0.0 scheme with +numbers for major, minor, and patch versions. + +.. list-table:: + :header-rows: 1 + + * - Version + - Example + - Significance + * - Major + - **3**.1.2 + - + + + * - Minor + - 3.\ **1**\ .2 + - A new feature within the major version. + * - Patch + - 3.1.\ **2** + - A bug fix within the major or minor version. + + +Long-term support +----------------- + +Starcraft doesn't have long-term support (LTS) releases. However, we typically +deliver a compatibility release shortly after Ubuntu LTS releases to ensure +continuity. + +Starcraft software bases are derived from Ubuntu LTS releases, and their +development keeps pace with the OS's new releases and support lifecycle. + +.. toctree:: + :maxdepth: 1 + + +.. release note template: + + Starcraft 1.0 release notes + =========================== + + 15 October 2024 + + Learn about the new features, changes, and fixes introduced in Starcraft 1.0. + For information about the Starcraft release cycle, see the + :ref:`release_policy_and_schedule`. + + + Requirements and compatibility + ------------------------------ + + Starcraft 1.0 requires Python 3.11 or higher. + + or higher".> + + For development and testing, Starcraft requires a system or VM + with a minimum of GB RAM. + + + What's new + ---------- + + Starcraft 1.0 brings the following features, integrations, and improvements. + + + + ~~~~~~~~~~~~~~~~~~ + + + + +----------------------------------------+------------------------------+-----------------------------------------+ + | Type of change | Heading format | Example | + +========================================+==============================+=========================================+ + | New feature | | Snap deltas | + +----------------------------------------+------------------------------+-----------------------------------------+ + | Support for technology, or integration | Support for | Support for signed commits | + | | integration | Gnome integration | + +----------------------------------------+------------------------------+-----------------------------------------+ + | Improvement to existing feature | | Faster buildset queries | + | | Improved | Improved language of buildset queries | + +----------------------------------------+------------------------------+-----------------------------------------+ + | Other important update | | Mitigation for Heartbleed vulnerability | + +----------------------------------------+------------------------------+-----------------------------------------+ + + + + + + + + + Minor features + -------------- + + Starcraft 1.0 brings the following minor changes. + + + + ~~~~~~~~~~~ + + + + + Backwards-incompatible changes in Starcraft 1.0 + ----------------------------------------------- + + The following changes are incompatible with previous versions of Starcraft. + + + <"Removed" or "Disabled"> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + + `_`` on the Ubuntu blog."> + + + Deprecated features in Starcraft 1.0 + ------------------------------------ + + The following features should no longer be used in Starcraft 1.0, and will be + removed in Starcraft 1.1. + + + Deprecated + ~~~~~~~~~~~~~~~~~~~~~~ + + `_`` on the Ubuntu blog."> + + + Known issues + ------------ + + The following issues are known and scheduled to be fixed in upcoming patch + releases. + + See individual issue links for any mitigations. + + - + - <Ticket ID> <Title> + + + Fixed bugs and issues + --------------------- + + The following issues have been resolved in Starcraft 1.0: + + - <Ticket ID> <Title> + - <Ticket ID> <Title> + + + Contributors + ------------ + + We would like to share a big thank you to all the people who contributed to this release. + + `@alex <>`_, `@blair <>`_, `@cam <>`_, `@devin <>`_ + diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst index eeb0a5cd97..f87110c02c 100644 --- a/docs/tutorials/index.rst +++ b/docs/tutorials/index.rst @@ -1,7 +1,7 @@ -.. _tutorial: +.. _tutorials: Tutorials -********* +========= If you want to learn the basics from experience, then our tutorials will help you acquire the necessary competencies from real-life examples with fully From 10c7eb42316f67f233571aa27614bf915bcec906 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 15:58:57 -0500 Subject: [PATCH 248/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.8.1 (#288) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ec44787ad1..da9141c759 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.7.4" + rev: "v0.8.1" hooks: # Run the linter - id: ruff From d0f4f16e29e4d7e284d4e5ae45f3fda77d4ef10a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:10:28 -0500 Subject: [PATCH 249/333] build(deps): update dependency mypy to ~=1.13.0 (#282) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- uv.lock | 49 +++++++++++++++++++++++++++---------------------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f1aacf8f67..1a3650710c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ lint = [ "yamllint~=1.34", ] types = [ - "mypy[reports]~=1.11.0", + "mypy[reports]~=1.13.0", "pyright==1.1.389", "types-Pygments", "types-colorama", @@ -60,7 +60,7 @@ dev-dependencies = [ "pytest-cov~=5.0", "pytest-mock~=3.12", "yamllint~=1.34", - "mypy[reports]~=1.11.0", + "mypy[reports]~=1.13.0", "pyright==1.1.389", "types-Pygments", "types-colorama", diff --git a/uv.lock b/uv.lock index f9bf3248e3..d64b1e918e 100644 --- a/uv.lock +++ b/uv.lock @@ -738,31 +738,36 @@ wheels = [ [[package]] name = "mypy" -version = "1.11.2" +version = "1.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5c/86/5d7cbc4974fd564550b80fbb8103c05501ea11aa7835edf3351d90095896/mypy-1.11.2.tar.gz", hash = "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79", size = 3078806 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/cd/815368cd83c3a31873e5e55b317551500b12f2d1d7549720632f32630333/mypy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a", size = 10939401 }, - { url = "https://files.pythonhosted.org/packages/f1/27/e18c93a195d2fad75eb96e1f1cbc431842c332e8eba2e2b77eaf7313c6b7/mypy-1.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef", size = 10111697 }, - { url = "https://files.pythonhosted.org/packages/dc/08/cdc1fc6d0d5a67d354741344cc4aa7d53f7128902ebcbe699ddd4f15a61c/mypy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383", size = 12500508 }, - { url = "https://files.pythonhosted.org/packages/64/12/aad3af008c92c2d5d0720ea3b6674ba94a98cdb86888d389acdb5f218c30/mypy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8", size = 13020712 }, - { url = "https://files.pythonhosted.org/packages/03/e6/a7d97cc124a565be5e9b7d5c2a6ebf082379ffba99646e4863ed5bbcb3c3/mypy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7", size = 9567319 }, - { url = "https://files.pythonhosted.org/packages/e2/aa/cc56fb53ebe14c64f1fe91d32d838d6f4db948b9494e200d2f61b820b85d/mypy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385", size = 10859630 }, - { url = "https://files.pythonhosted.org/packages/04/c8/b19a760fab491c22c51975cf74e3d253b8c8ce2be7afaa2490fbf95a8c59/mypy-1.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca", size = 10037973 }, - { url = "https://files.pythonhosted.org/packages/88/57/7e7e39f2619c8f74a22efb9a4c4eff32b09d3798335625a124436d121d89/mypy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104", size = 12416659 }, - { url = "https://files.pythonhosted.org/packages/fc/a6/37f7544666b63a27e46c48f49caeee388bf3ce95f9c570eb5cfba5234405/mypy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4", size = 12897010 }, - { url = "https://files.pythonhosted.org/packages/84/8b/459a513badc4d34acb31c736a0101c22d2bd0697b969796ad93294165cfb/mypy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6", size = 9562873 }, - { url = "https://files.pythonhosted.org/packages/35/3a/ed7b12ecc3f6db2f664ccf85cb2e004d3e90bec928e9d7be6aa2f16b7cdf/mypy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318", size = 10990335 }, - { url = "https://files.pythonhosted.org/packages/04/e4/1a9051e2ef10296d206519f1df13d2cc896aea39e8683302f89bf5792a59/mypy-1.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36", size = 10007119 }, - { url = "https://files.pythonhosted.org/packages/f3/3c/350a9da895f8a7e87ade0028b962be0252d152e0c2fbaafa6f0658b4d0d4/mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987", size = 12506856 }, - { url = "https://files.pythonhosted.org/packages/b6/49/ee5adf6a49ff13f4202d949544d3d08abb0ea1f3e7f2a6d5b4c10ba0360a/mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca", size = 12952066 }, - { url = "https://files.pythonhosted.org/packages/27/c0/b19d709a42b24004d720db37446a42abadf844d5c46a2c442e2a074d70d9/mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70", size = 9664000 }, - { url = "https://files.pythonhosted.org/packages/42/3a/bdf730640ac523229dd6578e8a581795720a9321399de494374afc437ec5/mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12", size = 2619625 }, +sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/8c/206de95a27722b5b5a8c85ba3100467bd86299d92a4f71c6b9aa448bfa2f/mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a", size = 11020731 }, + { url = "https://files.pythonhosted.org/packages/ab/bb/b31695a29eea76b1569fd28b4ab141a1adc9842edde080d1e8e1776862c7/mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80", size = 10184276 }, + { url = "https://files.pythonhosted.org/packages/a5/2d/4a23849729bb27934a0e079c9c1aad912167d875c7b070382a408d459651/mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7", size = 12587706 }, + { url = "https://files.pythonhosted.org/packages/5c/c3/d318e38ada50255e22e23353a469c791379825240e71b0ad03e76ca07ae6/mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f", size = 13105586 }, + { url = "https://files.pythonhosted.org/packages/4a/25/3918bc64952370c3dbdbd8c82c363804678127815febd2925b7273d9482c/mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372", size = 9632318 }, + { url = "https://files.pythonhosted.org/packages/d0/19/de0822609e5b93d02579075248c7aa6ceaddcea92f00bf4ea8e4c22e3598/mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", size = 10939027 }, + { url = "https://files.pythonhosted.org/packages/c8/71/6950fcc6ca84179137e4cbf7cf41e6b68b4a339a1f5d3e954f8c34e02d66/mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", size = 10108699 }, + { url = "https://files.pythonhosted.org/packages/26/50/29d3e7dd166e74dc13d46050b23f7d6d7533acf48f5217663a3719db024e/mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", size = 12506263 }, + { url = "https://files.pythonhosted.org/packages/3f/1d/676e76f07f7d5ddcd4227af3938a9c9640f293b7d8a44dd4ff41d4db25c1/mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", size = 12984688 }, + { url = "https://files.pythonhosted.org/packages/9c/03/5a85a30ae5407b1d28fab51bd3e2103e52ad0918d1e68f02a7778669a307/mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca", size = 9626811 }, + { url = "https://files.pythonhosted.org/packages/fb/31/c526a7bd2e5c710ae47717c7a5f53f616db6d9097caf48ad650581e81748/mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", size = 11077900 }, + { url = "https://files.pythonhosted.org/packages/83/67/b7419c6b503679d10bd26fc67529bc6a1f7a5f220bbb9f292dc10d33352f/mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", size = 10074818 }, + { url = "https://files.pythonhosted.org/packages/ba/07/37d67048786ae84e6612575e173d713c9a05d0ae495dde1e68d972207d98/mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", size = 12589275 }, + { url = "https://files.pythonhosted.org/packages/1f/17/b1018c6bb3e9f1ce3956722b3bf91bff86c1cefccca71cec05eae49d6d41/mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", size = 13037783 }, + { url = "https://files.pythonhosted.org/packages/cb/32/cd540755579e54a88099aee0287086d996f5a24281a673f78a0e14dba150/mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", size = 9726197 }, + { url = "https://files.pythonhosted.org/packages/11/bb/ab4cfdc562cad80418f077d8be9b4491ee4fb257440da951b85cbb0a639e/mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", size = 11069721 }, + { url = "https://files.pythonhosted.org/packages/59/3b/a393b1607cb749ea2c621def5ba8c58308ff05e30d9dbdc7c15028bca111/mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", size = 10063996 }, + { url = "https://files.pythonhosted.org/packages/d1/1f/6b76be289a5a521bb1caedc1f08e76ff17ab59061007f201a8a18cc514d1/mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8", size = 12584043 }, + { url = "https://files.pythonhosted.org/packages/a6/83/5a85c9a5976c6f96e3a5a7591aa28b4a6ca3a07e9e5ba0cec090c8b596d6/mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", size = 13036996 }, + { url = "https://files.pythonhosted.org/packages/b4/59/c39a6f752f1f893fccbcf1bdd2aca67c79c842402b5283563d006a67cf76/mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", size = 9737709 }, + { url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043 }, ] [package.optional-dependencies] @@ -1471,7 +1476,7 @@ wheels = [ [[package]] name = "starcraft" -version = "0.0.post250+ga411e24.d20241118" +version = "0.0.post252+g6aa7087.d20241118" source = { editable = "." } [package.optional-dependencies] @@ -1511,7 +1516,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "canonical-sphinx", marker = "extra == 'docs'", specifier = "~=0.2.0" }, - { name = "mypy", extras = ["reports"], marker = "extra == 'types'", specifier = "~=1.11.0" }, + { name = "mypy", extras = ["reports"], marker = "extra == 'types'", specifier = "~=1.13.0" }, { name = "pyright", marker = "extra == 'types'", specifier = "==1.1.389" }, { name = "sphinx-autobuild", marker = "extra == 'docs'", specifier = "~=2024.2" }, { name = "sphinx-lint", marker = "extra == 'docs'", specifier = "==1.0.0" }, @@ -1527,7 +1532,7 @@ requires-dist = [ dev = [ { name = "build" }, { name = "coverage", extras = ["toml"], specifier = "~=7.4" }, - { name = "mypy", extras = ["reports"], specifier = "~=1.11.0" }, + { name = "mypy", extras = ["reports"], specifier = "~=1.13.0" }, { name = "pyright", specifier = "==1.1.389" }, { name = "pytest", specifier = "~=8.0" }, { name = "pytest-cov", specifier = "~=5.0" }, From d956942b5f2c06620c0e19bc8593ecd4ce26e80c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:11:07 -0500 Subject: [PATCH 250/333] build(deps): update dependency pytest-cov to v6 (#285) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1a3650710c..1d2affc5cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,7 @@ dev-dependencies = [ "build", "coverage[toml]~=7.4", "pytest~=8.0", - "pytest-cov~=5.0", + "pytest-cov~=6.0", "pytest-mock~=3.12", "yamllint~=1.34", "mypy[reports]~=1.13.0", diff --git a/uv.lock b/uv.lock index d64b1e918e..9907513a36 100644 --- a/uv.lock +++ b/uv.lock @@ -995,15 +995,15 @@ wheels = [ [[package]] name = "pytest-cov" -version = "5.0.0" +version = "6.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage", extra = ["toml"] }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/74/67/00efc8d11b630c56f15f4ad9c7f9223f1e5ec275aaae3fa9118c6a223ad2/pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857", size = 63042 } +sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945 } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/3a/af5b4fa5961d9a1e6237b530eb87dd04aea6eb83da09d2a4073d81b54ccf/pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", size = 21990 }, + { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949 }, ] [[package]] @@ -1476,7 +1476,7 @@ wheels = [ [[package]] name = "starcraft" -version = "0.0.post252+g6aa7087.d20241118" +version = "0.0.post258+gd0f4f16.d20241205" source = { editable = "." } [package.optional-dependencies] @@ -1535,7 +1535,7 @@ dev = [ { name = "mypy", extras = ["reports"], specifier = "~=1.13.0" }, { name = "pyright", specifier = "==1.1.389" }, { name = "pytest", specifier = "~=8.0" }, - { name = "pytest-cov", specifier = "~=5.0" }, + { name = "pytest-cov", specifier = "~=6.0" }, { name = "pytest-mock", specifier = "~=3.12" }, { name = "types-colorama" }, { name = "types-pygments" }, From 0ffe5a70900a07cc8fbbd9d7b213e4413089b9c7 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Mon, 9 Dec 2024 12:32:46 -0500 Subject: [PATCH 251/333] fix: fix issues found in common.mk with charmcraft (#289) --- Makefile | 6 +++++- common.mk | 12 ++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 909d25f71b..6a8d2dd9de 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ publish-pypi: clean package-pip lint-twine ##- Publish Python packages to pypi # Used for installing build dependencies in CI. .PHONY: install-build-deps -install-build-deps: +install-build-deps: install-lint-build-deps ifeq ($(shell which apt-get),) $(warning Cannot install build dependencies without apt.) else ifeq ($(wildcard /usr/include/libxml2/libxml/xpath.h),) @@ -37,3 +37,7 @@ else ifeq ($(wildcard /usr/include/libxslt/xslt.h),) else ifeq ($(wildcard /usr/share/doc/python3-venv/copyright),) sudo $(APT) install python3-venv endif + +# If additional build dependencies need installing in order to build the linting env. +.PHONY: install-lint-build-deps +install-lint-build-deps: diff --git a/common.mk b/common.mk index 4e6b0a977b..2af6199e44 100644 --- a/common.mk +++ b/common.mk @@ -49,8 +49,8 @@ setup-tests: install-uv install-build-deps ##- Set up a testing environment with uv sync --frozen .PHONY: setup-lint -setup-lint: install-uv install-shellcheck ##- Set up a linting-only environment - uv sync --frozen --no-dev --no-install-workspace --extra lint --extra types +setup-lint: install-uv install-shellcheck install-lint-build-deps ##- Set up a linting-only environment + uv sync --frozen --no-install-workspace --extra lint --extra types .PHONY: setup-docs setup-docs: install-uv ##- Set up a documentation-only environment @@ -72,7 +72,7 @@ clean: ## Clean up the development environment autoformat: format # Hidden alias for 'format' .PHONY: format-ruff -format-ruff: ##- Automatically format with ruff +format-ruff: install-ruff ##- Automatically format with ruff success=true ruff check --fix $(SOURCES) || success=false ruff format $(SOURCES) @@ -83,7 +83,7 @@ format-codespell: ##- Fix spelling issues with codespell uv run codespell --toml pyproject.toml --write-changes $(SOURCES) .PHONY: lint-ruff -lint-ruff: ##- Lint with ruff +lint-ruff: install-ruff ##- Lint with ruff ruff check $(SOURCES) ruff format --diff $(SOURCES) @@ -102,7 +102,7 @@ ifneq ($(shell which pyright),) # Prefer the system pyright else # Fix for a bug in npm [ -d "/home/ubuntu/.npm/_cacache" ] && chown -R 1000:1000 "/home/ubuntu/.npm" || true - uv run pyright + uv run pyright --pythonpath .venv/bin/python endif .PHONY: lint-shellcheck @@ -198,5 +198,5 @@ else ifneq ($(shell which snap),) else ifneq ($(shell which brew),) brew install shellcheck else - $(warning Codespell not installed. Please install it yourself.) + $(warning Shellcheck not installed. Please install it yourself.) endif From 8095ce81185b7df2249985d424fcf0ece4707e49 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Mon, 9 Dec 2024 17:06:29 -0500 Subject: [PATCH 252/333] feat(common.mk): group linters in CI (#292) This adds ::group:: tags around linters if the CI environment variable is set, which allows the linters to be collapsed in CI. --- common.mk | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/common.mk b/common.mk index 2af6199e44..aca44e4aa2 100644 --- a/common.mk +++ b/common.mk @@ -84,19 +84,40 @@ format-codespell: ##- Fix spelling issues with codespell .PHONY: lint-ruff lint-ruff: install-ruff ##- Lint with ruff +ifneq ($(CI),) + @echo ::group::$@ +endif ruff check $(SOURCES) ruff format --diff $(SOURCES) +ifneq ($(CI),) + @echo ::endgroup:: +endif .PHONY: lint-codespell lint-codespell: ##- Check spelling with codespell +ifneq ($(CI),) + @echo ::group::$@ +endif uv run codespell --toml pyproject.toml $(SOURCES) +ifneq ($(CI),) + @echo ::endgroup:: +endif .PHONY: lint-mypy lint-mypy: ##- Check types with mypy +ifneq ($(CI),) + @echo ::group::$@ +endif uv run mypy --show-traceback --show-error-codes $(PROJECT) +ifneq ($(CI),) + @echo ::endgroup:: +endif .PHONY: lint-pyright lint-pyright: ##- Check types with pyright +ifneq ($(CI),) + @echo ::group::$@ +endif ifneq ($(shell which pyright),) # Prefer the system pyright pyright --pythonpath .venv/bin/python else @@ -104,22 +125,49 @@ else [ -d "/home/ubuntu/.npm/_cacache" ] && chown -R 1000:1000 "/home/ubuntu/.npm" || true uv run pyright --pythonpath .venv/bin/python endif +ifneq ($(CI),) + @echo ::endgroup:: +endif .PHONY: lint-shellcheck lint-shellcheck: ##- Lint shell scripts +ifneq ($(CI),) + @echo ::group::$@ +endif git ls-files | file --mime-type -Nnf- | grep shellscript | cut -f1 -d: | xargs -r shellcheck +ifneq ($(CI),) + @echo ::endgroup:: +endif .PHONY: lint-yaml lint-yaml: ##- Lint YAML files with yamllint +ifneq ($(CI),) + @echo ::group::$@ +endif uv run --extra lint yamllint . +ifneq ($(CI),) + @echo ::endgroup:: +endif .PHONY: lint-docs lint-docs: ##- Lint the documentation +ifneq ($(CI),) + @echo ::group::$@ +endif uv run --extra docs sphinx-lint --max-line-length 88 --enable all $(DOCS) +ifneq ($(CI),) + @echo ::endgroup:: +endif .PHONY: lint-twine -lint-twine: dist/* ##- Lint Python packages with twine +lint-twine: pack-pip ##- Lint Python packages with twine +ifneq ($(CI),) + @echo ::group::$@ +endif uv tool run twine check dist/* +ifneq ($(CI),) + @echo ::endgroup:: +endif .PHONY: test test: ## Run all tests @@ -149,8 +197,14 @@ docs-auto: ## Build and host docs with sphinx-autobuild uv run --extra docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W $(DOCS) $(DOCS)/_build .PHONY: pack-pip -pack-pip dist/*: ##- Build packages for pip (sdist, wheel) +pack-pip: ##- Build packages for pip (sdist, wheel) +ifneq ($(CI),) + @echo ::group::$@ +endif uv build . +ifneq ($(CI),) + @echo ::endgroup:: +endif # Below are intermediate targets for setup. They are not included in help as they should # not be used independently. From ca8814a3da13048fe9eb33e1350a35f665278cd8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:17:43 -0500 Subject: [PATCH 253/333] build(deps): update dependency pyright to v1.1.390 (#290) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- uv.lock | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1d2affc5cb..bf776e03b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ lint = [ ] types = [ "mypy[reports]~=1.13.0", - "pyright==1.1.389", + "pyright==1.1.390", "types-Pygments", "types-colorama", "types-setuptools", @@ -61,7 +61,7 @@ dev-dependencies = [ "pytest-mock~=3.12", "yamllint~=1.34", "mypy[reports]~=1.13.0", - "pyright==1.1.389", + "pyright==1.1.390", "types-Pygments", "types-colorama", "types-setuptools", diff --git a/uv.lock b/uv.lock index 9907513a36..4d80838cc6 100644 --- a/uv.lock +++ b/uv.lock @@ -965,15 +965,15 @@ wheels = [ [[package]] name = "pyright" -version = "1.1.389" +version = "1.1.390" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodeenv" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/72/4e/9a5ab8745e7606b88c2c7ca223449ac9d82a71fd5e31df47b453f2cb39a1/pyright-1.1.389.tar.gz", hash = "sha256:716bf8cc174ab8b4dcf6828c3298cac05c5ed775dda9910106a5dcfe4c7fe220", size = 21940 } +sdist = { url = "https://files.pythonhosted.org/packages/ba/42/1e0392f35dd275f9f775baf7c86407cef7f6a0d9b8e099a93e5422a7e571/pyright-1.1.390.tar.gz", hash = "sha256:aad7f160c49e0fbf8209507a15e17b781f63a86a1facb69ca877c71ef2e9538d", size = 21950 } wheels = [ - { url = "https://files.pythonhosted.org/packages/1b/26/c288cabf8cfc5a27e1aa9e5029b7682c0f920b8074f45d22bf844314d66a/pyright-1.1.389-py3-none-any.whl", hash = "sha256:41e9620bba9254406dc1f621a88ceab5a88af4c826feb4f614d95691ed243a60", size = 18581 }, + { url = "https://files.pythonhosted.org/packages/43/20/3f492ca789fb17962ad23619959c7fa642082621751514296c58de3bb801/pyright-1.1.390-py3-none-any.whl", hash = "sha256:ecebfba5b6b50af7c1a44c2ba144ba2ab542c227eb49bc1f16984ff714e0e110", size = 18579 }, ] [[package]] @@ -1476,7 +1476,7 @@ wheels = [ [[package]] name = "starcraft" -version = "0.0.post258+gd0f4f16.d20241205" +version = "0.0.post259+gd956942.d20241207" source = { editable = "." } [package.optional-dependencies] @@ -1517,7 +1517,7 @@ dev = [ requires-dist = [ { name = "canonical-sphinx", marker = "extra == 'docs'", specifier = "~=0.2.0" }, { name = "mypy", extras = ["reports"], marker = "extra == 'types'", specifier = "~=1.13.0" }, - { name = "pyright", marker = "extra == 'types'", specifier = "==1.1.389" }, + { name = "pyright", marker = "extra == 'types'", specifier = "==1.1.390" }, { name = "sphinx-autobuild", marker = "extra == 'docs'", specifier = "~=2024.2" }, { name = "sphinx-lint", marker = "extra == 'docs'", specifier = "==1.0.0" }, { name = "sphinx-pydantic", marker = "extra == 'docs'", specifier = "==0.1.1" }, @@ -1533,7 +1533,7 @@ dev = [ { name = "build" }, { name = "coverage", extras = ["toml"], specifier = "~=7.4" }, { name = "mypy", extras = ["reports"], specifier = "~=1.13.0" }, - { name = "pyright", specifier = "==1.1.389" }, + { name = "pyright", specifier = "==1.1.390" }, { name = "pytest", specifier = "~=8.0" }, { name = "pytest-cov", specifier = "~=6.0" }, { name = "pytest-mock", specifier = "~=3.12" }, From 533a5464fabc966a669c31bcf7046cdb3535232c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:18:36 -0500 Subject: [PATCH 254/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.8.2 (#291) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index da9141c759..47fb7affe9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.8.1" + rev: "v0.8.2" hooks: # Run the linter - id: ruff From 2a0a5243f1500996e9432c1e64a3c6a7e897ed4e Mon Sep 17 00:00:00 2001 From: Upils <5464641+upils@users.noreply.github.com> Date: Mon, 9 Dec 2024 23:20:22 +0100 Subject: [PATCH 255/333] fix: Typos in doc and make files (#287) Signed-off-by: Paul Mars <paul.mars@canonical.com> Co-authored-by: Alex Lowe <alex.lowe@canonical.com> --- README.rst | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 41260dff65..2acce3c79d 100644 --- a/README.rst +++ b/README.rst @@ -85,7 +85,8 @@ Migrate existing projects #. If you're rebasing a library, add the integrations tests structure. Applications should use spread for integration tests. -# Finally, once all files are manually synced, actually sync the git history: +#. Finally, once all files are manually synced, actually sync the git history: + - ``git remote add starbase git@github.com:canonical/starbase.git`` - ``git merge --allow-unrelated-histories starbase/main`` - ``git remote remove starbase`` @@ -99,11 +100,18 @@ Create a new project -------------------- #. `Use this template`_ to create your repository. +#. Sync the git history with starbase to ease future merging: + - ``git clone <your-repo>`` + - ``git remote add starbase git@github.com:canonical/starbase.git`` + - ``git merge --allow-unrelated-histories starbase/main`` + - ``git push -f origin main`` + - ``git remote remove starbase`` #. Ensure the ``LICENSE`` file represents the current best practices from the Canonical legal team for the specific project you intend to release. We use LGPL v3 for libraries, and GPL v3 for apps. #. Rename any files or directories and ensure references are updated. -#. Replace any instances of the word ``Starcraft`` with the product's name. +#. Replace any instances of the words ``Starcraft`` and ``starbase`` with the product's + name. #. Place contact information in a code of conduct. #. Rewrite the README. #. If a Diataxis quadrant (tutorials, how-tos, references, explanations) From b3a71bf1916de6ed20a9938290bd8ea1418e9e9c Mon Sep 17 00:00:00 2001 From: Upils <5464641+upils@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:02:03 +0100 Subject: [PATCH 256/333] feat: register the 'slow' mark to pytest (#293) Signed-off-by: Paul Mars <paul.mars@canonical.com> --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index bf776e03b5..0395c30559 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -119,6 +119,7 @@ line_length = 88 minversion = "7.0" testpaths = "tests" xfail_strict = true +markers = ["slow: slow tests"] [tool.coverage.run] branch = true From 512434d9a8c332a7a1dfbafad09b34c1954179a9 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Thu, 12 Dec 2024 09:48:24 -0500 Subject: [PATCH 257/333] ci: use starflow renovate config (#260) * ci: use starflow renovate config * ci: print renovate config in renovate job * ci: iterate * fix: better renovate dry-run --- .github/renovate.json5 | 219 +------------------------- .github/workflows/check-renovate.yaml | 4 +- 2 files changed, 3 insertions(+), 220 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index f588fef4d1..205663fdfd 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,220 +1,3 @@ { - extends: [ - 'config:recommended', - ':semanticCommitTypeAll(build)', - ':enablePreCommit', - ], - labels: [ - 'dependencies', - ], - baseBranches: [ - '$default', - '/^hotfix\\/.*/', - ], - pip_requirements: { - fileMatch: [ - '^tox.ini$', - '(^|/)requirements([\\w-]*)\\.txt$', - ], - }, - packageRules: [ - { - groupName: 'internal package minor releases', - matchUpdateTypes: [ - 'minor', - 'patch', - 'pin', - 'digest', - ], - prPriority: 10, - automerge: true, - minimumReleaseAge: '0 seconds', - schedule: [ - 'at any time', - ], - matchBaseBranches: [ - '$default', - ], - matchPackageNames: [ - '/^craft-.*/', - ], - }, - { - groupName: 'internal package patch releases (hotfix)', - matchUpdateTypes: [ - 'patch', - 'pin', - 'digest', - ], - prPriority: 10, - minimumReleaseAge: '0 seconds', - schedule: [ - 'at any time', - ], - matchBaseBranches: [ - '/^hotfix\\/.*/', - ], - matchPackageNames: [ - '/^craft-.*/', - ], - }, - { - groupName: 'bugfixes', - matchUpdateTypes: [ - 'patch', - 'pin', - 'digest', - ], - prPriority: 3, - automerge: true, - matchDepNames: [ - '!/lint/.*/', - '!/types/.*/', - '!/pyright/', - ], - }, - { - groupName: 'internal packages', - matchCategories: [ - 'python', - ], - prPriority: 2, - matchBaseBranches: [ - '$default', - ], - matchDepNames: [ - '/craft-.*/', - '/snap-.*/', - ], - }, - { - groupName: 'GitHub Actions', - matchManagers: [ - 'github-actions', - ], - prPriority: 1, - automerge: true, - }, - { - groupName: 'pydantic etc.', - matchBaseBranches: [ - '$default', - ], - matchPackageNames: [ - '/^pydantic/', - ], - }, - { - groupName: 'development dependencies (non-major)', - groupSlug: 'dev-dependencies', - matchUpdateTypes: [ - 'minor', - 'patch', - 'pin', - 'digest', - ], - prPriority: -1, - automerge: true, - matchBaseBranches: [ - '$default', - ], - matchDepNames: [ - '/dev/.*/', - '/lint/.*/', - '/types/.*/', - ], - matchPackageNames: [ - '/^(.*/)?autoflake$/', - '/^(.*/)?black$/', - '/^(.*/)?codespell$/', - '/^(.*/)?coverage$/', - '/^(.*/)?flake8$/', - '/^(.*/)?hypothesis$/', - '/^(.*/)?mypy$/', - '/^(.*/)?pycodestyle$/', - '/^(.*/)?docstyle$/', - '/^(.*/)?pyfakefs$/', - '/^(.*/)?pyflakes$/', - '/^(.*/)?pylint$/', - '/^(.*/)?pytest/', - '/^(.*/)?responses$/', - '/^(.*/)?ruff$/', - '/^(.*/)?twine$/', - '/^(.*/)?tox$/', - '/^(.*/)?types-/', - ], - }, - { - groupName: 'documentation dependencies', - groupSlug: 'doc-dependencies', - matchPackageNames: [ - 'Sphinx', - 'furo', - '/[Ss]phinx.*$/', - ], - matchBaseBranches: [ - '$default', - ], - matchDepNames: [ - '/docs/.*/', - ], - }, - { - matchUpdateTypes: [ - 'major', - ], - prPriority: -2, - matchBaseBranches: [ - '$default', - ], - }, - { - groupName: 'development dependencies (major versions)', - groupSlug: 'dev-dependencies', - matchDepTypes: [ - 'devDependencies', - ], - matchUpdateTypes: [ - 'major', - ], - prPriority: -3, - matchBaseBranches: [ - '$default', - ], - }, - { - matchPackageNames: [ - 'pyright', - 'types/pyright', - ], - prPriority: -4, - matchBaseBranches: [ - '$default', - ], - }, - ], - customManagers: [ - { - fileMatch: [ - 'tox.ini', - ], - customType: 'regex', - depTypeTemplate: 'devDependencies', - matchStrings: [ - '# renovate: datasource=(?<datasource>\\S+)\n\\s+(?<depName>.*?)(\\[[\\w]*\\])*[=><]=?(?<currentValue>.*?)\n', - ], - }, - ], - timezone: 'Etc/UTC', - schedule: [ - 'every weekend', - ], - prConcurrentLimit: 2, - branchConcurrentLimit: 20, - prCreation: 'not-pending', - prNotPendingHours: 4, - prHourlyLimit: 1, - minimumReleaseAge: '2 days', - automergeStrategy: 'squash', - semanticCommitType: 'build', + extends: ["github>canonical/starflow:renovate-base.json5"], } diff --git a/.github/workflows/check-renovate.yaml b/.github/workflows/check-renovate.yaml index 7d13cfbf21..efbe384818 100644 --- a/.github/workflows/check-renovate.yaml +++ b/.github/workflows/check-renovate.yaml @@ -25,7 +25,7 @@ jobs: with: node-version: 22 - name: Install renovate - run: npm install --global renovate + run: npm install --global re2 renovate - name: Enable ssh access uses: mxschmitt/action-tmate@v3 if: ${{ inputs.enable_ssh_access }} @@ -34,7 +34,7 @@ jobs: - name: Check renovate config run: renovate-config-validator .github/renovate.json5 - name: Renovate dry-run - run: renovate --dry-run --autodiscover + run: renovate --dry-run=full --autodiscover --print-config env: RENOVATE_TOKEN: ${{ secrets.GITHUB_TOKEN }} RENOVATE_USE_BASE_BRANCH_CONFIG: ${{ github.ref }} From d23661717dca939b00b58033c9cc13209b3bacd0 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Thu, 12 Dec 2024 14:59:46 -0500 Subject: [PATCH 258/333] ci: use starflow renovate config (#260) From e9f2f6b4115f422ac942e3038909ec3791b35832 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Thu, 12 Dec 2024 16:24:16 -0500 Subject: [PATCH 259/333] fix: update renovate config (#296) We've moved to using a default config location for renovate in starflow. --- .github/renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 205663fdfd..32ac7a083a 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,3 +1,3 @@ { - extends: ["github>canonical/starflow:renovate-base.json5"], + extends: ["github>canonical/starflow"], } From 49181688d727fa9efc08dfa6dc12616d3ede7b7a Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Thu, 12 Dec 2024 17:03:43 -0500 Subject: [PATCH 260/333] fix: update renovate config (#298) Renovate is way too picky! --- .github/renovate.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 32ac7a083a..66cb2f6bd6 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,3 +1,3 @@ { - extends: ["github>canonical/starflow"], + extends: ["github>canonical/starflow:renovate.json5"], } From 0b70cf1b791313c26273cf06653dc719daf7b0ef Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Fri, 13 Dec 2024 15:52:23 -0500 Subject: [PATCH 261/333] feat: use existing, then snap, then uv pyright (#299) This changes the way we get pyright, preferring the snap and no longer having it frozen to a specific version. --- common.mk | 17 +++++++++++++---- pyproject.toml | 1 - 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/common.mk b/common.mk index aca44e4aa2..ab4c874a0c 100644 --- a/common.mk +++ b/common.mk @@ -49,7 +49,7 @@ setup-tests: install-uv install-build-deps ##- Set up a testing environment with uv sync --frozen .PHONY: setup-lint -setup-lint: install-uv install-shellcheck install-lint-build-deps ##- Set up a linting-only environment +setup-lint: install-uv install-shellcheck install-pyright install-lint-build-deps ##- Set up a linting-only environment uv sync --frozen --no-install-workspace --extra lint --extra types .PHONY: setup-docs @@ -121,9 +121,7 @@ endif ifneq ($(shell which pyright),) # Prefer the system pyright pyright --pythonpath .venv/bin/python else - # Fix for a bug in npm - [ -d "/home/ubuntu/.npm/_cacache" ] && chown -R 1000:1000 "/home/ubuntu/.npm" || true - uv run pyright --pythonpath .venv/bin/python + uv tool run pyright --pythonpath .venv/bin/python endif ifneq ($(CI),) @echo ::endgroup:: @@ -234,6 +232,17 @@ else $(warning Codespell not installed. Please install it yourself.) endif +.PHONY: install-pyright +install-pyright: install-uv +ifneq ($(shell which pyright),) +else ifneq ($(shell which snap),) + sudo snap install --classic pyright +else + # Workaround for a bug in npm + [ -d "$(HOME)/.npm/_cacache" ] && chown -R `id -u`:`id -g` "$(HOME)/.npm" || true + uv tool install pyright +endif + .PHONY: install-ruff install-ruff: ifneq ($(shell which ruff),) diff --git a/pyproject.toml b/pyproject.toml index 0395c30559..fb605fa545 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,6 @@ lint = [ ] types = [ "mypy[reports]~=1.13.0", - "pyright==1.1.390", "types-Pygments", "types-colorama", "types-setuptools", From b6842c0315796a8a07e6c779bcba564aecf59229 Mon Sep 17 00:00:00 2001 From: Tiago Nobrega <tiago.nobrega@canonical.com> Date: Fri, 13 Dec 2024 17:19:08 -0300 Subject: [PATCH 262/333] ci: restrict pypi job to amd64 The `gh-action-pypi-publish` pulls in a docker image to do the actual publishing, and said image is apparently always amd64 --- .github/workflows/release-publish.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-publish.yaml b/.github/workflows/release-publish.yaml index d688f3bb7b..780bf803e5 100644 --- a/.github/workflows/release-publish.yaml +++ b/.github/workflows/release-publish.yaml @@ -38,7 +38,7 @@ jobs: path: dist/ pypi: needs: ["source-wheel"] - runs-on: [self-hosted, jammy] + runs-on: [self-hosted, jammy, amd64] permissions: # IMPORTANT: this permission is mandatory for trusted publishing id-token: write From bddd6ac83969c44994aeb170897fb8a79b598b7c Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Fri, 13 Dec 2024 16:05:41 -0500 Subject: [PATCH 263/333] chore: add constraints needed by craft-store and craft-archives (#294) --- pyproject.toml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fb605fa545..ff7b00d348 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,18 +39,27 @@ docs = [ constraint-dependencies = [ # Basic constraints to allow --resolution=lowest "build>=0.7.0", + "cffi>=1.15", "iniconfig>=1.1.0", + "httplib2>=0.20.0", + "libnacl>=2.0", "lxml>=5.0", + "markdown>=3.0", + "markupsafe>=2.0", + "oauthlib>=3.0.0", + "protobuf>=5.0", + "pynacl>=1.5", "pyparsing>=3.0.0", "pyproject-hooks>=1.0.0", + "pytz>=2020", "pyyaml>=5.0", - "markdown>=3.0", - "markupsafe>=2.0", - "pyyaml>5.0", "regex>=2021.11.10", + "setuptools>=50", "sphinx-basic-ng>=1.0.0b1", "tornado>=4.0", + "urllib3>=2.0", "webencodings>=0.4.0", + "wheel>=0.38", ] dev-dependencies = [ "build", From 2375a1c91bb23a17b5f5a001d5e5a00d89b7882a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:41:17 -0500 Subject: [PATCH 264/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.8.3 (#302) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 47fb7affe9..8eb7e57683 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.8.2" + rev: "v0.8.3" hooks: # Run the linter - id: ruff From b4a1f7a3bfd036329204218356a32b8963728fba Mon Sep 17 00:00:00 2001 From: Michael DuBelko <michael.dubelko@canonical.com> Date: Mon, 16 Dec 2024 10:14:24 -0800 Subject: [PATCH 265/333] docs: add app cadence, update deprecation notice in release notes index --- docs/release-notes/index.rst | 114 ++++++++++++++++++++++------------- 1 file changed, 72 insertions(+), 42 deletions(-) diff --git a/docs/release-notes/index.rst b/docs/release-notes/index.rst index 82729ed26a..d720c9d9c1 100644 --- a/docs/release-notes/index.rst +++ b/docs/release-notes/index.rst @@ -49,12 +49,19 @@ Past releases Release policy and schedule --------------------------- -Canonical is committed to supporting the <"latest major release" or "last two -major releases"> of Starcraft. <Optional: "We forward-port changes in older -releases to the latest release, if they're compatible."> - -Starcraft is released when it achieves development milestones in its product -lifecycle. It doesn't follow a predefined release cadence. +<Apps: Canonical is committed to releasing Starcraft on a regular monthly +cadence. Our goal is to have new features and fixes available as soon as +possible. On the first Monday of the month, we publish a major or minor +version of Starcraft to the candidate channel, where it undergoes testing and +feedback. If we determine the candidate is ready for mainstream use by the +Monday of the week after, we release it as a stable version. During testing +and feedback of a candidate, we prioritise fixes for critical issues.> + +<Libraries: Canonical is committed to supporting the <"latest major release" or +"last two major releases"> of Starcraft. [Optional: We forward-port changes in +older releases to the latest release, if they're compatible.] Starcraft is +released when it achieves development milestones in its lifecycle. It doesn't +follow a predefined release cadence.> Starcraft release naming follows the Semantic Versioning 2.0.0 scheme with numbers for major, minor, and patch versions. @@ -86,8 +93,8 @@ Starcraft doesn't have long-term support (LTS) releases. However, we typically deliver a compatibility release shortly after Ubuntu LTS releases to ensure continuity. -Starcraft software bases are derived from Ubuntu LTS releases, and their -development keeps pace with the OS's new releases and support lifecycle. +<Apps: Starcraft software bases are derived from Ubuntu LTS releases, and their +development keeps pace with the OS's new releases and support lifecycle.> .. toctree:: :maxdepth: 1 @@ -95,12 +102,12 @@ development keeps pace with the OS's new releases and support lifecycle. .. release note template: - Starcraft 1.0 release notes + Starcraft 2.0 release notes =========================== 15 October 2024 - Learn about the new features, changes, and fixes introduced in Starcraft 1.0. + Learn about the new features, changes, and fixes introduced in Starcraft 2.0. For information about the Starcraft release cycle, see the :ref:`release_policy_and_schedule`. @@ -108,7 +115,7 @@ development keeps pace with the OS's new releases and support lifecycle. Requirements and compatibility ------------------------------ - Starcraft 1.0 requires Python 3.11 or higher. + Starcraft 2.0 requires Python 3.11 or higher. <If there are multiple requirements, remove "Python 3.11 or higher" in the previous paragraph and add a separate list here, with the same format of @@ -121,7 +128,7 @@ development keeps pace with the OS's new releases and support lifecycle. What's new ---------- - Starcraft 1.0 brings the following features, integrations, and improvements. + Starcraft 2.0 brings the following features, integrations, and improvements. <Important change> @@ -171,10 +178,10 @@ development keeps pace with the OS's new releases and support lifecycle. Minor features -------------- - Starcraft 1.0 brings the following minor changes. + Starcraft 2.0 brings the following minor changes. - <Feature x> + <Feature A> ~~~~~~~~~~~ <Add a short list of changes to the feature. Keep each item brief and for the @@ -183,13 +190,13 @@ development keeps pace with the OS's new releases and support lifecycle. ``method()`` more descriptive and recommend a likely remedy."> - Backwards-incompatible changes in Starcraft 1.0 - ----------------------------------------------- + Backwards-incompatible changes + ------------------------------ The following changes are incompatible with previous versions of Starcraft. - <"Removed" or "Disabled"> <feature y> + <"Removed" or "Disabled"> <feature B> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Paragraph 1, optional: Briefly cover the sequence of events that led to this @@ -201,43 +208,66 @@ development keeps pace with the OS's new releases and support lifecycle. alternative solution, or state if no alternative exists. If necessary, describe the consequences of the reader's inaction. Link to relevant documentation, standards, or public discussion. For example, "In accordance - with the report, Starcraft 1.0 no longer supports encryption algorithm X. As + with the report, Starcraft 2.0 no longer supports encryption algorithm X. As of this release, if you haven't already we highly recommend you immediately switch to encryption algorithm Y to ensure your data stays protected. For more details about this decision and our policy, see ```Security notice on encryption X <>`_`` on the Ubuntu blog."> - Deprecated features in Starcraft 1.0 - ------------------------------------ - - The following features should no longer be used in Starcraft 1.0, and will be - removed in Starcraft 1.1. + Feature deprecations + -------------------- + The following features are deprecated in Starcraft 2.0: - Deprecated <feature z> + Deprecated <feature C> ~~~~~~~~~~~~~~~~~~~~~~ - <Use the same format as backwards-incompatible changes, but use future tense - to describe what we *intend* and *plan* to do in subsequent releases. Think - of this as a promise or commitment to the reader, and be mindful of the trust - we want them to place in us. Don't write conjecture or make promises about - details that haven't been decided. Include only the decisions that we have - set in stone and information we're allowed to disclose at of the release day. - Use phrases like "we plan to", or "we are working on", or "we have scheduled - development of". End by linking to relevant documentation, standards, or - public discussion. For example, "In October 2024, the NIST published SP - ABC-123, urging software publishers to cease the use of encryption algorithm - X. We are deprecating its usage in this release, and plan to remove it in - Starcraft 1.1. For more details about this decision and our policy, see - ```Security notice on encryption X <>`_`` on the Ubuntu blog."> + <Use the same format as backwards-incompatible changes, but use present tense + to describe what is deprecated in this release, and how. Advise on an + alternative replacement, if it exists. This item is a statement of fact, not + a promise. If the implementation or schedule for the deprecation changed from + what we originally planned, don't make a point of it -- simply describe what + *is*. End by linking to relevant documentation, standards, or public + discussion. For example, "In October 2024, the NIST published SP ABC-123, + urging software publishers to cease the use of encryption algorithm X. We are + deprecating its usage in this release, and advise you to adopt algorithm Z as + a replacement. For more details about this decision and our policy, see + `Security notice on encryption X <>`_ on the Ubuntu blog."> + + + Scheduled feature deprecations + ------------------------------ + + <Iterate on the following paragraph+items if you're covering multiple + versions in this section.> + + The following features will be deprecated in Starcraft <planned version>: + + + <Feature D> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + <Future deprecation: Use the same format as backwards-incompatible changes, + but use future tense to describe what we *intend* and *plan* to do in + subsequent releases. Think of this as a promise or commitment to the reader, + and be mindful of the trust we want them to place in us. Don't write + conjecture or make promises about details that haven't been decided. Include + only the decisions that we have set in stone and information we're allowed to + disclose at of the release day. Use phrases like "we plan to", "we are + working on", or "we have scheduled development of". End by linking to + relevant documentation, standards, or public discussion. For example, "In + October 2024, the NIST published SP ABC-123, urging software publishers to + cease the use of encryption algorithm X. We plan to deprecate it in Starcraft + 1.2. For more details about this decision and our policy, see `Security + notice on encryption X <>`_ on the Ubuntu blog."> Known issues ------------ - The following issues are known and scheduled to be fixed in upcoming patch - releases. + The following issues were reported and are scheduled to be fixed in upcoming + patch releases. See individual issue links for any mitigations. @@ -248,7 +278,7 @@ development keeps pace with the OS's new releases and support lifecycle. Fixed bugs and issues --------------------- - The following issues have been resolved in Starcraft 1.0: + The following issues have been resolved in Starcraft 2.0: - <Ticket ID> <Title> - <Ticket ID> <Title> @@ -257,7 +287,7 @@ development keeps pace with the OS's new releases and support lifecycle. Contributors ------------ - We would like to share a big thank you to all the people who contributed to this release. + We would like to express a big thank you to all the people who contributed to + this release. `@alex <>`_, `@blair <>`_, `@cam <>`_, `@devin <>`_ - From 913e47542790a1d21e84135524cd3c22f342a46b Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Tue, 17 Dec 2024 16:35:21 -0500 Subject: [PATCH 266/333] chore: add CODEOWNERS file (#295) --- .github/CODEOWNERS | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..127df20a16 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,9 @@ +# GitHub CODEOWNERS. See: +# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners +# Remember, the last match takes precedence. + +# Documentation owners +/docs/ @medubelko @canonical/starcraft + +# Finally, all CODEOWNERS changes need to be approved by The Man, Himself. +/.github/CODEOWNERS @sergiusens From c5c71673c8957fe8bd914f04b15e200403f58902 Mon Sep 17 00:00:00 2001 From: Michael DuBelko <michael.dubelko@canonical.com> Date: Thu, 19 Dec 2024 07:44:11 -0800 Subject: [PATCH 267/333] docs: remove release policy from rn index (#306) --- docs/release-notes/index.rst | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/docs/release-notes/index.rst b/docs/release-notes/index.rst index d720c9d9c1..54ecf5dc81 100644 --- a/docs/release-notes/index.rst +++ b/docs/release-notes/index.rst @@ -44,26 +44,12 @@ Past releases - <link to past release, initial, such as 6.0.0> -.. _release_policy_and_schedule: - -Release policy and schedule ---------------------------- - -<Apps: Canonical is committed to releasing Starcraft on a regular monthly -cadence. Our goal is to have new features and fixes available as soon as -possible. On the first Monday of the month, we publish a major or minor -version of Starcraft to the candidate channel, where it undergoes testing and -feedback. If we determine the candidate is ready for mainstream use by the -Monday of the week after, we release it as a stable version. During testing -and feedback of a candidate, we prioritise fixes for critical issues.> - -<Libraries: Canonical is committed to supporting the <"latest major release" or -"last two major releases"> of Starcraft. [Optional: We forward-port changes in -older releases to the latest release, if they're compatible.] Starcraft is -released when it achieves development milestones in its lifecycle. It doesn't -follow a predefined release cadence.> - -Starcraft release naming follows the Semantic Versioning 2.0.0 scheme with +.. _release-versioning: + +Release versioning +------------------ + +Starcraft version naming follows the Semantic Versioning 2.0.0 scheme with numbers for major, minor, and patch versions. .. list-table:: @@ -108,8 +94,6 @@ development keeps pace with the OS's new releases and support lifecycle.> 15 October 2024 Learn about the new features, changes, and fixes introduced in Starcraft 2.0. - For information about the Starcraft release cycle, see the - :ref:`release_policy_and_schedule`. Requirements and compatibility From 45b62434585c80e82307f74f777f910ab5d4c93e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 20:30:38 -0500 Subject: [PATCH 268/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.8.4 (#312) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8eb7e57683..a573ef0506 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.8.3" + rev: "v0.8.4" hooks: # Run the linter - id: ruff From 427083481678d2c0a19654b89b3a4aecae50aede Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 20:31:51 -0500 Subject: [PATCH 269/333] build(deps): update dependency pyright to v1.1.391 (#311) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 29 ++++++++++++++++++++--------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ff7b00d348..f228749789 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,7 +69,7 @@ dev-dependencies = [ "pytest-mock~=3.12", "yamllint~=1.34", "mypy[reports]~=1.13.0", - "pyright==1.1.390", + "pyright==1.1.391", "types-Pygments", "types-colorama", "types-setuptools", diff --git a/uv.lock b/uv.lock index 4d80838cc6..ab95a0c9bf 100644 --- a/uv.lock +++ b/uv.lock @@ -8,18 +8,27 @@ resolution-markers = [ [manifest] constraints = [ { name = "build", specifier = ">=0.7.0" }, + { name = "cffi", specifier = ">=1.15" }, + { name = "httplib2", specifier = ">=0.20.0" }, { name = "iniconfig", specifier = ">=1.1.0" }, + { name = "libnacl", specifier = ">=2.0" }, { name = "lxml", specifier = ">=5.0" }, { name = "markdown", specifier = ">=3.0" }, { name = "markupsafe", specifier = ">=2.0" }, + { name = "oauthlib", specifier = ">=3.0.0" }, + { name = "protobuf", specifier = ">=5.0" }, + { name = "pynacl", specifier = ">=1.5" }, { name = "pyparsing", specifier = ">=3.0.0" }, { name = "pyproject-hooks", specifier = ">=1.0.0" }, - { name = "pyyaml", specifier = ">5.0" }, + { name = "pytz", specifier = ">=2020" }, { name = "pyyaml", specifier = ">=5.0" }, { name = "regex", specifier = ">=2021.11.10" }, + { name = "setuptools", specifier = ">=50" }, { name = "sphinx-basic-ng", specifier = ">=1.0.0b1" }, { name = "tornado", specifier = ">=4.0" }, + { name = "urllib3", specifier = ">=2.0" }, { name = "webencodings", specifier = ">=0.4.0" }, + { name = "wheel", specifier = ">=0.38" }, ] [[package]] @@ -248,7 +257,7 @@ name = "click" version = "8.1.7" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } wheels = [ @@ -965,15 +974,15 @@ wheels = [ [[package]] name = "pyright" -version = "1.1.390" +version = "1.1.391" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodeenv" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/42/1e0392f35dd275f9f775baf7c86407cef7f6a0d9b8e099a93e5422a7e571/pyright-1.1.390.tar.gz", hash = "sha256:aad7f160c49e0fbf8209507a15e17b781f63a86a1facb69ca877c71ef2e9538d", size = 21950 } +sdist = { url = "https://files.pythonhosted.org/packages/11/05/4ea52a8a45cc28897edb485b4102d37cbfd5fce8445d679cdeb62bfad221/pyright-1.1.391.tar.gz", hash = "sha256:66b2d42cdf5c3cbab05f2f4b76e8bec8aa78e679bfa0b6ad7b923d9e027cadb2", size = 21965 } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/20/3f492ca789fb17962ad23619959c7fa642082621751514296c58de3bb801/pyright-1.1.390-py3-none-any.whl", hash = "sha256:ecebfba5b6b50af7c1a44c2ba144ba2ab542c227eb49bc1f16984ff714e0e110", size = 18579 }, + { url = "https://files.pythonhosted.org/packages/ad/89/66f49552fbeb21944c8077d11834b2201514a56fd1b7747ffff9630f1bd9/pyright-1.1.391-py3-none-any.whl", hash = "sha256:54fa186f8b3e8a55a44ebfa842636635688670c6896dcf6cf4a7fc75062f4d15", size = 18579 }, ] [[package]] @@ -1170,6 +1179,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/b7/20c6f3c0b656fe609675d69bc135c03aac9e3865912444be6339207b6648/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76", size = 686712 }, { url = "https://files.pythonhosted.org/packages/cd/11/d12dbf683471f888d354dac59593873c2b45feb193c5e3e0f2ebf85e68b9/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6", size = 663936 }, { url = "https://files.pythonhosted.org/packages/72/14/4c268f5077db5c83f743ee1daeb236269fa8577133a5cfa49f8b382baf13/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd", size = 696580 }, + { url = "https://files.pythonhosted.org/packages/30/fc/8cd12f189c6405a4c1cf37bd633aa740a9538c8e40497c231072d0fef5cf/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a", size = 663393 }, { url = "https://files.pythonhosted.org/packages/80/29/c0a017b704aaf3cbf704989785cd9c5d5b8ccec2dae6ac0c53833c84e677/ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da", size = 100326 }, { url = "https://files.pythonhosted.org/packages/3a/65/fa39d74db4e2d0cd252355732d966a460a41cd01c6353b820a0952432839/ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28", size = 118079 }, { url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6", size = 132224 }, @@ -1178,6 +1188,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52", size = 703012 }, { url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642", size = 704352 }, { url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2", size = 737344 }, + { url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3", size = 714498 }, { url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4", size = 100205 }, { url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb", size = 118185 }, { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433 }, @@ -1186,6 +1197,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497 }, { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042 }, { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831 }, + { url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d", size = 715692 }, { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777 }, { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523 }, { url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a", size = 132011 }, @@ -1194,6 +1206,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6", size = 701785 }, { url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf", size = 693017 }, { url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1", size = 741270 }, + { url = "https://files.pythonhosted.org/packages/87/b8/01c29b924dcbbed75cc45b30c30d565d763b9c4d540545a0eeecffb8f09c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01", size = 709059 }, { url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6", size = 98583 }, { url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3", size = 115190 }, ] @@ -1476,7 +1489,7 @@ wheels = [ [[package]] name = "starcraft" -version = "0.0.post259+gd956942.d20241207" +version = "0.0.post276+gc5c7167.d20241221" source = { editable = "." } [package.optional-dependencies] @@ -1492,7 +1505,6 @@ lint = [ ] types = [ { name = "mypy", extra = ["reports"] }, - { name = "pyright" }, { name = "types-colorama" }, { name = "types-pygments" }, { name = "types-setuptools" }, @@ -1517,7 +1529,6 @@ dev = [ requires-dist = [ { name = "canonical-sphinx", marker = "extra == 'docs'", specifier = "~=0.2.0" }, { name = "mypy", extras = ["reports"], marker = "extra == 'types'", specifier = "~=1.13.0" }, - { name = "pyright", marker = "extra == 'types'", specifier = "==1.1.390" }, { name = "sphinx-autobuild", marker = "extra == 'docs'", specifier = "~=2024.2" }, { name = "sphinx-lint", marker = "extra == 'docs'", specifier = "==1.0.0" }, { name = "sphinx-pydantic", marker = "extra == 'docs'", specifier = "==0.1.1" }, @@ -1533,7 +1544,7 @@ dev = [ { name = "build" }, { name = "coverage", extras = ["toml"], specifier = "~=7.4" }, { name = "mypy", extras = ["reports"], specifier = "~=1.13.0" }, - { name = "pyright", specifier = "==1.1.390" }, + { name = "pyright", specifier = "==1.1.391" }, { name = "pytest", specifier = "~=8.0" }, { name = "pytest-cov", specifier = "~=6.0" }, { name = "pytest-mock", specifier = "~=3.12" }, From a102dbaa3e33f6966c2f6b8601e94b2b43d1304a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 12:59:36 -0500 Subject: [PATCH 270/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.8.6 (#314) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a573ef0506..c2ff402f00 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.8.4" + rev: "v0.8.6" hooks: # Run the linter - id: ruff From 4083b5ceb5f0f3111e1eb89ba2ffc03f282c6ae1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:00:02 -0500 Subject: [PATCH 271/333] build(deps): update dependency mypy to ~=1.14.1 (#313) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- uv.lock | 58 +++++++++++++++++++++++++++----------------------- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f228749789..8a97ad1528 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ lint = [ "yamllint~=1.34", ] types = [ - "mypy[reports]~=1.13.0", + "mypy[reports]~=1.14.1", "types-Pygments", "types-colorama", "types-setuptools", @@ -68,7 +68,7 @@ dev-dependencies = [ "pytest-cov~=6.0", "pytest-mock~=3.12", "yamllint~=1.34", - "mypy[reports]~=1.13.0", + "mypy[reports]~=1.14.1", "pyright==1.1.391", "types-Pygments", "types-colorama", diff --git a/uv.lock b/uv.lock index ab95a0c9bf..8d07e1fe1b 100644 --- a/uv.lock +++ b/uv.lock @@ -747,36 +747,40 @@ wheels = [ [[package]] name = "mypy" -version = "1.13.0" +version = "1.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/8c/206de95a27722b5b5a8c85ba3100467bd86299d92a4f71c6b9aa448bfa2f/mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a", size = 11020731 }, - { url = "https://files.pythonhosted.org/packages/ab/bb/b31695a29eea76b1569fd28b4ab141a1adc9842edde080d1e8e1776862c7/mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80", size = 10184276 }, - { url = "https://files.pythonhosted.org/packages/a5/2d/4a23849729bb27934a0e079c9c1aad912167d875c7b070382a408d459651/mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7", size = 12587706 }, - { url = "https://files.pythonhosted.org/packages/5c/c3/d318e38ada50255e22e23353a469c791379825240e71b0ad03e76ca07ae6/mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f", size = 13105586 }, - { url = "https://files.pythonhosted.org/packages/4a/25/3918bc64952370c3dbdbd8c82c363804678127815febd2925b7273d9482c/mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372", size = 9632318 }, - { url = "https://files.pythonhosted.org/packages/d0/19/de0822609e5b93d02579075248c7aa6ceaddcea92f00bf4ea8e4c22e3598/mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", size = 10939027 }, - { url = "https://files.pythonhosted.org/packages/c8/71/6950fcc6ca84179137e4cbf7cf41e6b68b4a339a1f5d3e954f8c34e02d66/mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", size = 10108699 }, - { url = "https://files.pythonhosted.org/packages/26/50/29d3e7dd166e74dc13d46050b23f7d6d7533acf48f5217663a3719db024e/mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", size = 12506263 }, - { url = "https://files.pythonhosted.org/packages/3f/1d/676e76f07f7d5ddcd4227af3938a9c9640f293b7d8a44dd4ff41d4db25c1/mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", size = 12984688 }, - { url = "https://files.pythonhosted.org/packages/9c/03/5a85a30ae5407b1d28fab51bd3e2103e52ad0918d1e68f02a7778669a307/mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca", size = 9626811 }, - { url = "https://files.pythonhosted.org/packages/fb/31/c526a7bd2e5c710ae47717c7a5f53f616db6d9097caf48ad650581e81748/mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", size = 11077900 }, - { url = "https://files.pythonhosted.org/packages/83/67/b7419c6b503679d10bd26fc67529bc6a1f7a5f220bbb9f292dc10d33352f/mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", size = 10074818 }, - { url = "https://files.pythonhosted.org/packages/ba/07/37d67048786ae84e6612575e173d713c9a05d0ae495dde1e68d972207d98/mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", size = 12589275 }, - { url = "https://files.pythonhosted.org/packages/1f/17/b1018c6bb3e9f1ce3956722b3bf91bff86c1cefccca71cec05eae49d6d41/mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", size = 13037783 }, - { url = "https://files.pythonhosted.org/packages/cb/32/cd540755579e54a88099aee0287086d996f5a24281a673f78a0e14dba150/mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", size = 9726197 }, - { url = "https://files.pythonhosted.org/packages/11/bb/ab4cfdc562cad80418f077d8be9b4491ee4fb257440da951b85cbb0a639e/mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", size = 11069721 }, - { url = "https://files.pythonhosted.org/packages/59/3b/a393b1607cb749ea2c621def5ba8c58308ff05e30d9dbdc7c15028bca111/mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", size = 10063996 }, - { url = "https://files.pythonhosted.org/packages/d1/1f/6b76be289a5a521bb1caedc1f08e76ff17ab59061007f201a8a18cc514d1/mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8", size = 12584043 }, - { url = "https://files.pythonhosted.org/packages/a6/83/5a85c9a5976c6f96e3a5a7591aa28b4a6ca3a07e9e5ba0cec090c8b596d6/mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", size = 13036996 }, - { url = "https://files.pythonhosted.org/packages/b4/59/c39a6f752f1f893fccbcf1bdd2aca67c79c842402b5283563d006a67cf76/mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", size = 9737709 }, - { url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043 }, +sdist = { url = "https://files.pythonhosted.org/packages/b9/eb/2c92d8ea1e684440f54fa49ac5d9a5f19967b7b472a281f419e69a8d228e/mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", size = 3216051 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/7a/87ae2adb31d68402da6da1e5f30c07ea6063e9f09b5e7cfc9dfa44075e74/mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb", size = 11211002 }, + { url = "https://files.pythonhosted.org/packages/e1/23/eada4c38608b444618a132be0d199b280049ded278b24cbb9d3fc59658e4/mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0", size = 10358400 }, + { url = "https://files.pythonhosted.org/packages/43/c9/d6785c6f66241c62fd2992b05057f404237deaad1566545e9f144ced07f5/mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d", size = 12095172 }, + { url = "https://files.pythonhosted.org/packages/c3/62/daa7e787770c83c52ce2aaf1a111eae5893de9e004743f51bfcad9e487ec/mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b", size = 12828732 }, + { url = "https://files.pythonhosted.org/packages/1b/a2/5fb18318a3637f29f16f4e41340b795da14f4751ef4f51c99ff39ab62e52/mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427", size = 13012197 }, + { url = "https://files.pythonhosted.org/packages/28/99/e153ce39105d164b5f02c06c35c7ba958aaff50a2babba7d080988b03fe7/mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f", size = 9780836 }, + { url = "https://files.pythonhosted.org/packages/da/11/a9422850fd506edbcdc7f6090682ecceaf1f87b9dd847f9df79942da8506/mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c", size = 11120432 }, + { url = "https://files.pythonhosted.org/packages/b6/9e/47e450fd39078d9c02d620545b2cb37993a8a8bdf7db3652ace2f80521ca/mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1", size = 10279515 }, + { url = "https://files.pythonhosted.org/packages/01/b5/6c8d33bd0f851a7692a8bfe4ee75eb82b6983a3cf39e5e32a5d2a723f0c1/mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8", size = 12025791 }, + { url = "https://files.pythonhosted.org/packages/f0/4c/e10e2c46ea37cab5c471d0ddaaa9a434dc1d28650078ac1b56c2d7b9b2e4/mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f", size = 12749203 }, + { url = "https://files.pythonhosted.org/packages/88/55/beacb0c69beab2153a0f57671ec07861d27d735a0faff135a494cd4f5020/mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1", size = 12885900 }, + { url = "https://files.pythonhosted.org/packages/a2/75/8c93ff7f315c4d086a2dfcde02f713004357d70a163eddb6c56a6a5eff40/mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae", size = 9777869 }, + { url = "https://files.pythonhosted.org/packages/43/1b/b38c079609bb4627905b74fc6a49849835acf68547ac33d8ceb707de5f52/mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", size = 11266668 }, + { url = "https://files.pythonhosted.org/packages/6b/75/2ed0d2964c1ffc9971c729f7a544e9cd34b2cdabbe2d11afd148d7838aa2/mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", size = 10254060 }, + { url = "https://files.pythonhosted.org/packages/a1/5f/7b8051552d4da3c51bbe8fcafffd76a6823779101a2b198d80886cd8f08e/mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", size = 11933167 }, + { url = "https://files.pythonhosted.org/packages/04/90/f53971d3ac39d8b68bbaab9a4c6c58c8caa4d5fd3d587d16f5927eeeabe1/mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", size = 12864341 }, + { url = "https://files.pythonhosted.org/packages/03/d2/8bc0aeaaf2e88c977db41583559319f1821c069e943ada2701e86d0430b7/mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89", size = 12972991 }, + { url = "https://files.pythonhosted.org/packages/6f/17/07815114b903b49b0f2cf7499f1c130e5aa459411596668267535fe9243c/mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", size = 9879016 }, + { url = "https://files.pythonhosted.org/packages/9e/15/bb6a686901f59222275ab228453de741185f9d54fecbaacec041679496c6/mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", size = 11252097 }, + { url = "https://files.pythonhosted.org/packages/f8/b3/8b0f74dfd072c802b7fa368829defdf3ee1566ba74c32a2cb2403f68024c/mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", size = 10239728 }, + { url = "https://files.pythonhosted.org/packages/c5/9b/4fd95ab20c52bb5b8c03cc49169be5905d931de17edfe4d9d2986800b52e/mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", size = 11924965 }, + { url = "https://files.pythonhosted.org/packages/56/9d/4a236b9c57f5d8f08ed346914b3f091a62dd7e19336b2b2a0d85485f82ff/mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", size = 12867660 }, + { url = "https://files.pythonhosted.org/packages/40/88/a61a5497e2f68d9027de2bb139c7bb9abaeb1be1584649fa9d807f80a338/mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", size = 12969198 }, + { url = "https://files.pythonhosted.org/packages/54/da/3d6fc5d92d324701b0c23fb413c853892bfe0e1dbe06c9138037d459756b/mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", size = 9885276 }, + { url = "https://files.pythonhosted.org/packages/a0/b5/32dd67b69a16d088e533962e5044e51004176a9952419de0370cdaead0f8/mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", size = 2752905 }, ] [package.optional-dependencies] @@ -1489,7 +1493,7 @@ wheels = [ [[package]] name = "starcraft" -version = "0.0.post276+gc5c7167.d20241221" +version = "0.0.post278+g4270834.d20250101" source = { editable = "." } [package.optional-dependencies] @@ -1528,7 +1532,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "canonical-sphinx", marker = "extra == 'docs'", specifier = "~=0.2.0" }, - { name = "mypy", extras = ["reports"], marker = "extra == 'types'", specifier = "~=1.13.0" }, + { name = "mypy", extras = ["reports"], marker = "extra == 'types'", specifier = "~=1.14.1" }, { name = "sphinx-autobuild", marker = "extra == 'docs'", specifier = "~=2024.2" }, { name = "sphinx-lint", marker = "extra == 'docs'", specifier = "==1.0.0" }, { name = "sphinx-pydantic", marker = "extra == 'docs'", specifier = "==0.1.1" }, @@ -1543,7 +1547,7 @@ requires-dist = [ dev = [ { name = "build" }, { name = "coverage", extras = ["toml"], specifier = "~=7.4" }, - { name = "mypy", extras = ["reports"], specifier = "~=1.13.0" }, + { name = "mypy", extras = ["reports"], specifier = "~=1.14.1" }, { name = "pyright", specifier = "==1.1.391" }, { name = "pytest", specifier = "~=8.0" }, { name = "pytest-cov", specifier = "~=6.0" }, From 68d8d79db38568309d44895bce74d2a5b9fa4128 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Tue, 7 Jan 2025 15:42:36 -0500 Subject: [PATCH 272/333] style: replace yamllint with prettier (#305) * style: replace yamllint with prettier Lints and formats YAML, JSON, JSON5, Markdown and CSS files with prettier. Cannot do TOML right now due to: https://github.com/prettier/prettier/issues/15141 Fixes #273 CRAFT-3626 --- .editorconfig | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/release-drafter.yml | 2 +- .github/workflows/check-renovate.yaml | 2 +- .github/workflows/policy.yaml | 2 +- .pre-commit-config.yaml | 10 ++++++---- .yamllint.yaml | 12 ------------ Makefile | 4 ++-- common.mk | 28 ++++++++++++++++++++++----- docs/_static/css/custom.css | 4 ++-- pyproject.toml | 1 - tox.ini | 5 ++--- uv.lock | 2 -- 13 files changed, 40 insertions(+), 36 deletions(-) delete mode 100644 .yamllint.yaml diff --git a/.editorconfig b/.editorconfig index 5a54b3ef2b..adea89a830 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,7 +14,7 @@ trim_trailing_whitespace = true [.editorconfig] max_line_length = off -[Makefile] +[{Makefile,*.mk}] indent_style = tab [{*.py,*.pyi}] diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index da2c9731a5..ca01e6b66e 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,4 +2,4 @@ - [ ] Have you signed the [CLA](http://www.ubuntu.com/legal/contributors/)? - [ ] Have you successfully run `tox`? ------ +--- diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 5262e23c6a..e78bce4016 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -15,7 +15,7 @@ categories: - title: "Tooling" label: - "tooling" -change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +change-template: "- $TITLE @$AUTHOR (#$NUMBER)" template: | Special thanks to the contributors that made this release happen: $CONTRIBUTORS diff --git a/.github/workflows/check-renovate.yaml b/.github/workflows/check-renovate.yaml index efbe384818..de31e3ee76 100644 --- a/.github/workflows/check-renovate.yaml +++ b/.github/workflows/check-renovate.yaml @@ -10,7 +10,7 @@ on: inputs: enable_ssh_access: type: boolean - description: 'Enable ssh access' + description: "Enable ssh access" required: false default: false diff --git a/.github/workflows/policy.yaml b/.github/workflows/policy.yaml index fb8310f998..9c59dc18be 100644 --- a/.github/workflows/policy.yaml +++ b/.github/workflows/policy.yaml @@ -5,7 +5,7 @@ on: branches: - main - hotfix/* - - work/check-policy # For development + - work/check-policy # For development jobs: policy: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c2ff402f00..6d11bd4e32 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,14 +13,16 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.8.6" + rev: "v0.8.4" hooks: # Run the linter - id: ruff args: [--fix, --exit-non-zero-on-fix] # Run the formatter - id: ruff-format - - repo: https://github.com/adrienverge/yamllint.git - rev: "v1.35.1" + - repo: https://github.com/pre-commit/mirrors-prettier + rev: "" # Intentionally blank, despite the warning. hooks: - - id: yamllint + - id: prettier + additional_dependencies: + - prettier@3.4.2 diff --git a/.yamllint.yaml b/.yamllint.yaml deleted file mode 100644 index 8f7da7486b..0000000000 --- a/.yamllint.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -ignore-from-file: [.gitignore] - -extends: default - -rules: - document-start: disable - float-values: enable - line-length: disable - octal-values: enable - truthy: - check-keys: false diff --git a/Makefile b/Makefile index 6a8d2dd9de..7743d1ea0b 100644 --- a/Makefile +++ b/Makefile @@ -3,10 +3,10 @@ PROJECT=starcraft include common.mk .PHONY: format -format: format-ruff format-codespell ## Run all automatic formatters +format: format-ruff format-codespell format-prettier ## Run all automatic formatters .PHONY: lint -lint: lint-ruff lint-codespell lint-mypy lint-pyright lint-shellcheck lint-yaml lint-docs lint-twine ## Run all linters +lint: lint-ruff lint-codespell lint-mypy lint-prettier lint-pyright lint-shellcheck lint-docs lint-twine ## Run all linters .PHONY: pack pack: pack-pip ## Build all packages diff --git a/common.mk b/common.mk index ab4c874a0c..1483ce6c21 100644 --- a/common.mk +++ b/common.mk @@ -8,11 +8,14 @@ ifneq ($(OS),Windows_NT) OS := $(shell uname) endif ifdef CI - APT := apt-get --yes + APT := apt-get --yes else APT := apt-get endif +PRETTIER=npm exec --package=prettier -- prettier +PRETTIER_FILES=**.yaml **.yml **.json **.json5 **.css **.md + .DEFAULT_GOAL := help .ONESHELL: @@ -82,6 +85,10 @@ format-ruff: install-ruff ##- Automatically format with ruff format-codespell: ##- Fix spelling issues with codespell uv run codespell --toml pyproject.toml --write-changes $(SOURCES) +.PHONY: format-prettier +format-prettier: install-npm ##- Format files with prettier + $(PRETTIER) --write $(PRETTIER_FILES) + .PHONY: lint-ruff lint-ruff: install-ruff ##- Lint with ruff ifneq ($(CI),) @@ -137,12 +144,12 @@ ifneq ($(CI),) @echo ::endgroup:: endif -.PHONY: lint-yaml -lint-yaml: ##- Lint YAML files with yamllint +.PHONY: lint-prettier +lint-prettier: install-npm ##- Lint files with prettier ifneq ($(CI),) @echo ::group::$@ endif - uv run --extra lint yamllint . + $(PRETTIER) --check $(PRETTIER_FILES) ifneq ($(CI),) @echo ::endgroup:: endif @@ -238,7 +245,7 @@ ifneq ($(shell which pyright),) else ifneq ($(shell which snap),) sudo snap install --classic pyright else - # Workaround for a bug in npm + # Workaround for a bug in npm [ -d "$(HOME)/.npm/_cacache" ] && chown -R `id -u`:`id -g` "$(HOME)/.npm" || true uv tool install pyright endif @@ -263,3 +270,14 @@ else ifneq ($(shell which brew),) else $(warning Shellcheck not installed. Please install it yourself.) endif + +.PHONY: install-npm +install-npm: +ifneq ($(shell which npm),) +else ifneq ($(shell which snap),) + sudo snap install --classic node +else ifneq ($(shell which brew),) + brew install node +else + $(error npm not installed. Please install it yourself.) +endif diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css index ef7e97f641..83174e022b 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -1,4 +1,4 @@ -@import url('https://fonts.googleapis.com/css2?family=Ubuntu:ital@0;1&display=swap'); +@import url("https://fonts.googleapis.com/css2?family=Ubuntu:ital@0;1&display=swap"); body { font-family: Ubuntu, "times new roman", times, roman, serif; @@ -8,7 +8,7 @@ div .toctree-wrapper { column-count: 2; } -div .toctree-wrapper>ul { +div .toctree-wrapper > ul { margin: 0; } diff --git a/pyproject.toml b/pyproject.toml index 8a97ad1528..b74e3616e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,7 +67,6 @@ dev-dependencies = [ "pytest~=8.0", "pytest-cov~=6.0", "pytest-mock~=3.12", - "yamllint~=1.34", "mypy[reports]~=1.14.1", "pyright==1.1.391", "types-Pygments", diff --git a/tox.ini b/tox.ini index 696a22fd6f..17afaf5153 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ env_list = # Environments to run when called with no parameters. format-{ruff,codespell} pre-commit - lint-{ruff,mypy,pyright,shellcheck,codespell,docs,yaml} + lint-{ruff,mypy,pyright,shellcheck,codespell,docs} unit-py3.{10,12} integration-py3.10 # Integration tests probably take a while, so we're only running them on Python @@ -71,7 +71,7 @@ allowlist_externals = find = git ls-files filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: -[testenv:lint-{ruff,shellcheck,codespell,yaml}] +[testenv:lint-{ruff,shellcheck,codespell}] description = Lint the source code base = testenv, lint labels = lint @@ -82,7 +82,6 @@ commands = ruff: ruff check {posargs:.} shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck codespell: codespell --toml {tox_root}/pyproject.toml {posargs} - yaml: yamllint {posargs} . [testenv:lint-{mypy,pyright}] description = Static type checking diff --git a/uv.lock b/uv.lock index 8d07e1fe1b..5184eec64a 100644 --- a/uv.lock +++ b/uv.lock @@ -1526,7 +1526,6 @@ dev = [ { name = "types-colorama" }, { name = "types-pygments" }, { name = "types-setuptools" }, - { name = "yamllint" }, ] [package.metadata] @@ -1555,7 +1554,6 @@ dev = [ { name = "types-colorama" }, { name = "types-pygments" }, { name = "types-setuptools" }, - { name = "yamllint", specifier = "~=1.34" }, ] [[package]] From 68ad84a836c611dce46ce2f995458b1f7ac86b45 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 14:13:48 -0500 Subject: [PATCH 273/333] build(deps): update dependency canonical-sphinx to ~=0.3.0 (#317) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b74e3616e8..9b085a7897 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ types = [ "types-setuptools", ] docs = [ - "canonical-sphinx~=0.2.0", + "canonical-sphinx~=0.3.0", "sphinx-autobuild~=2024.2", "sphinx-pydantic==0.1.1", "sphinx-toolbox~=3.5", diff --git a/uv.lock b/uv.lock index 5184eec64a..96c5bbc9db 100644 --- a/uv.lock +++ b/uv.lock @@ -161,7 +161,7 @@ filecache = [ [[package]] name = "canonical-sphinx" -version = "0.2.0" +version = "0.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "furo" }, @@ -169,9 +169,9 @@ dependencies = [ { name = "myst-parser" }, { name = "sphinx" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/2a/a77c673d5950d1ae1e065fddd038e547610fc9e1de41ef56b20d85fa87c2/canonical_sphinx-0.2.0.tar.gz", hash = "sha256:74d8dce67845924220d67f78bf85df379d8121e9b8e684338986dcccf9fff439", size = 56858 } +sdist = { url = "https://files.pythonhosted.org/packages/54/19/b2101265969ba6bfacbb9b3355a32a22abdcccceba61542813f07fe0e965/canonical_sphinx-0.3.0.tar.gz", hash = "sha256:7914a1281e7520a032058e7a511d019fee25a152c032499a7bf9e15852f9d9e7", size = 1051001 } wheels = [ - { url = "https://files.pythonhosted.org/packages/99/da/488d00806ddcc177c3e02049d8ab1d92aee0a334d6e2aed41a45a5c924f8/canonical_sphinx-0.2.0-py3-none-any.whl", hash = "sha256:c71ee6dbc15c084ad115f06b0f1c15f8269db3a896670e616b8945d6af089edd", size = 31067 }, + { url = "https://files.pythonhosted.org/packages/30/ba/ab2e2113841f88a9725c6c55f4918a3031ef3efad6afd154d9444cd40c8e/canonical_sphinx-0.3.0-py3-none-any.whl", hash = "sha256:55dc07c54038ea7016a5a6a12fafa1bde8558a00009237f5224db1c65e919b0f", size = 1027670 }, ] [[package]] @@ -1493,7 +1493,7 @@ wheels = [ [[package]] name = "starcraft" -version = "0.0.post278+g4270834.d20250101" +version = "0.0.post281+g68d8d79.d20250111" source = { editable = "." } [package.optional-dependencies] @@ -1530,7 +1530,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "canonical-sphinx", marker = "extra == 'docs'", specifier = "~=0.2.0" }, + { name = "canonical-sphinx", marker = "extra == 'docs'", specifier = "~=0.3.0" }, { name = "mypy", extras = ["reports"], marker = "extra == 'types'", specifier = "~=1.14.1" }, { name = "sphinx-autobuild", marker = "extra == 'docs'", specifier = "~=2024.2" }, { name = "sphinx-lint", marker = "extra == 'docs'", specifier = "==1.0.0" }, From c1f03c6fbe5d3133253e3ecaed112178f4f7827a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 14:14:45 -0500 Subject: [PATCH 274/333] build(deps): lock file maintenance (#320) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- uv.lock | 874 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 452 insertions(+), 422 deletions(-) diff --git a/uv.lock b/uv.lock index 96c5bbc9db..9ed93cf6be 100644 --- a/uv.lock +++ b/uv.lock @@ -1,8 +1,8 @@ version = 1 requires-python = ">=3.10" resolution-markers = [ - "python_full_version < '3.13'", "python_full_version >= '3.13'", + "python_full_version < '3.13'", ] [manifest] @@ -51,17 +51,17 @@ wheels = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.8.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "idna" }, { name = "sniffio" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 } +sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 }, + { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 }, ] [[package]] @@ -94,14 +94,14 @@ wheels = [ [[package]] name = "autodocsumm" -version = "0.2.13" +version = "0.2.14" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/98/19/2cefb1103bef41ef33393f0de37b72920a099f9a56aa5434570e7dcdf0f4/autodocsumm-0.2.13.tar.gz", hash = "sha256:ac5f0cf1adbe957acb136fe0d9e16c38fb74fcaefb45c148204aba26dbb12ee2", size = 45426 } +sdist = { url = "https://files.pythonhosted.org/packages/03/96/92afe8a7912b327c01f0a8b6408c9556ee13b1aba5b98d587ac7327ff32d/autodocsumm-0.2.14.tar.gz", hash = "sha256:2839a9d4facc3c4eccd306c08695540911042b46eeafcdc3203e6d0bab40bc77", size = 46357 } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/fb/59e528d9f5b1aadf4e4fb29e93b1d85570a0f089ebde7b43c574109f8373/autodocsumm-0.2.13-py3-none-any.whl", hash = "sha256:bf4d82ea7acb3e7d9a3ad8c135e097eca1d3f0bd00800d7804127e848e66741d", size = 14257 }, + { url = "https://files.pythonhosted.org/packages/87/bc/3f66af9beb683728e06ca08797e4e9d3e44f432f339718cae3ba856a9cad/autodocsumm-0.2.14-py3-none-any.whl", hash = "sha256:3bad8717fc5190802c60392a7ab04b9f3c97aa9efa8b3780b3d81d615bfe5dc0", size = 14640 }, ] [[package]] @@ -143,15 +143,15 @@ wheels = [ [[package]] name = "cachecontrol" -version = "0.14.0" +version = "0.14.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "msgpack" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/55/edea9d90ee57ca54d34707607d15c20f72576b96cb9f3e7fc266cb06b426/cachecontrol-0.14.0.tar.gz", hash = "sha256:7db1195b41c81f8274a7bbd97c956f44e8348265a1bc7641c37dfebc39f0c938", size = 28899 } +sdist = { url = "https://files.pythonhosted.org/packages/b7/a4/3390ac4dfa1773f661c8780368018230e8207ec4fd3800d2c0c3adee4456/cachecontrol-0.14.2.tar.gz", hash = "sha256:7d47d19f866409b98ff6025b6a0fca8e4c791fb31abbd95f622093894ce903a2", size = 28832 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/a9/7d331fec593a4b2953338df33e954aac6ff79eb5a073bca2783766bc7722/cachecontrol-0.14.0-py3-none-any.whl", hash = "sha256:f5bf3f0620c38db2e5122c0726bdebb0d16869de966ea6a2befe92470b740ea0", size = 22064 }, + { url = "https://files.pythonhosted.org/packages/c8/63/baffb44ca6876e7b5fc8fe17b24a7c07bf479d604a592182db9af26ea366/cachecontrol-0.14.2-py3-none-any.whl", hash = "sha256:ebad2091bf12d0d200dfc2464330db638c5deb41d546f6d7aca079e87290f3b0", size = 21780 }, ] [package.optional-dependencies] @@ -176,92 +176,84 @@ wheels = [ [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 } +sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, + { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, ] [[package]] name = "charset-normalizer" -version = "3.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", size = 106620 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/69/8b/825cc84cf13a28bfbcba7c416ec22bf85a9584971be15b21dd8300c65b7f/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", size = 196363 }, - { url = "https://files.pythonhosted.org/packages/23/81/d7eef6a99e42c77f444fdd7bc894b0ceca6c3a95c51239e74a722039521c/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", size = 125639 }, - { url = "https://files.pythonhosted.org/packages/21/67/b4564d81f48042f520c948abac7079356e94b30cb8ffb22e747532cf469d/charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", size = 120451 }, - { url = "https://files.pythonhosted.org/packages/c2/72/12a7f0943dd71fb5b4e7b55c41327ac0a1663046a868ee4d0d8e9c369b85/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", size = 140041 }, - { url = "https://files.pythonhosted.org/packages/67/56/fa28c2c3e31217c4c52158537a2cf5d98a6c1e89d31faf476c89391cd16b/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", size = 150333 }, - { url = "https://files.pythonhosted.org/packages/f9/d2/466a9be1f32d89eb1554cf84073a5ed9262047acee1ab39cbaefc19635d2/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", size = 142921 }, - { url = "https://files.pythonhosted.org/packages/f8/01/344ec40cf5d85c1da3c1f57566c59e0c9b56bcc5566c08804a95a6cc8257/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", size = 144785 }, - { url = "https://files.pythonhosted.org/packages/73/8b/2102692cb6d7e9f03b9a33a710e0164cadfce312872e3efc7cfe22ed26b4/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", size = 146631 }, - { url = "https://files.pythonhosted.org/packages/d8/96/cc2c1b5d994119ce9f088a9a0c3ebd489d360a2eb058e2c8049f27092847/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", size = 140867 }, - { url = "https://files.pythonhosted.org/packages/c9/27/cde291783715b8ec30a61c810d0120411844bc4c23b50189b81188b273db/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", size = 149273 }, - { url = "https://files.pythonhosted.org/packages/3a/a4/8633b0fc1a2d1834d5393dafecce4a1cc56727bfd82b4dc18fc92f0d3cc3/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", size = 152437 }, - { url = "https://files.pythonhosted.org/packages/64/ea/69af161062166b5975ccbb0961fd2384853190c70786f288684490913bf5/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", size = 150087 }, - { url = "https://files.pythonhosted.org/packages/3b/fd/e60a9d9fd967f4ad5a92810138192f825d77b4fa2a557990fd575a47695b/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", size = 145142 }, - { url = "https://files.pythonhosted.org/packages/6d/02/8cb0988a1e49ac9ce2eed1e07b77ff118f2923e9ebd0ede41ba85f2dcb04/charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", size = 94701 }, - { url = "https://files.pythonhosted.org/packages/d6/20/f1d4670a8a723c46be695dff449d86d6092916f9e99c53051954ee33a1bc/charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", size = 102191 }, - { url = "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", size = 193339 }, - { url = "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", size = 124366 }, - { url = "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", size = 118874 }, - { url = "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", size = 138243 }, - { url = "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", size = 148676 }, - { url = "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", size = 141289 }, - { url = "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", size = 142585 }, - { url = "https://files.pythonhosted.org/packages/3b/a0/a68980ab8a1f45a36d9745d35049c1af57d27255eff8c907e3add84cf68f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", size = 144408 }, - { url = "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", size = 139076 }, - { url = "https://files.pythonhosted.org/packages/fb/9d/9c13753a5a6e0db4a0a6edb1cef7aee39859177b64e1a1e748a6e3ba62c2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", size = 146874 }, - { url = "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", size = 150871 }, - { url = "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", size = 148546 }, - { url = "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", size = 143048 }, - { url = "https://files.pythonhosted.org/packages/01/f8/38842422988b795220eb8038745d27a675ce066e2ada79516c118f291f07/charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", size = 94389 }, - { url = "https://files.pythonhosted.org/packages/0b/6e/b13bd47fa9023b3699e94abf565b5a2f0b0be6e9ddac9812182596ee62e4/charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", size = 101752 }, - { url = "https://files.pythonhosted.org/packages/d3/0b/4b7a70987abf9b8196845806198975b6aab4ce016632f817ad758a5aa056/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", size = 194445 }, - { url = "https://files.pythonhosted.org/packages/50/89/354cc56cf4dd2449715bc9a0f54f3aef3dc700d2d62d1fa5bbea53b13426/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", size = 125275 }, - { url = "https://files.pythonhosted.org/packages/fa/44/b730e2a2580110ced837ac083d8ad222343c96bb6b66e9e4e706e4d0b6df/charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", size = 119020 }, - { url = "https://files.pythonhosted.org/packages/9d/e4/9263b8240ed9472a2ae7ddc3e516e71ef46617fe40eaa51221ccd4ad9a27/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", size = 139128 }, - { url = "https://files.pythonhosted.org/packages/6b/e3/9f73e779315a54334240353eaea75854a9a690f3f580e4bd85d977cb2204/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", size = 149277 }, - { url = "https://files.pythonhosted.org/packages/1a/cf/f1f50c2f295312edb8a548d3fa56a5c923b146cd3f24114d5adb7e7be558/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", size = 142174 }, - { url = "https://files.pythonhosted.org/packages/16/92/92a76dc2ff3a12e69ba94e7e05168d37d0345fa08c87e1fe24d0c2a42223/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", size = 143838 }, - { url = "https://files.pythonhosted.org/packages/a4/01/2117ff2b1dfc61695daf2babe4a874bca328489afa85952440b59819e9d7/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", size = 146149 }, - { url = "https://files.pythonhosted.org/packages/f6/9b/93a332b8d25b347f6839ca0a61b7f0287b0930216994e8bf67a75d050255/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", size = 140043 }, - { url = "https://files.pythonhosted.org/packages/ab/f6/7ac4a01adcdecbc7a7587767c776d53d369b8b971382b91211489535acf0/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", size = 148229 }, - { url = "https://files.pythonhosted.org/packages/9d/be/5708ad18161dee7dc6a0f7e6cf3a88ea6279c3e8484844c0590e50e803ef/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", size = 151556 }, - { url = "https://files.pythonhosted.org/packages/5a/bb/3d8bc22bacb9eb89785e83e6723f9888265f3a0de3b9ce724d66bd49884e/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", size = 149772 }, - { url = "https://files.pythonhosted.org/packages/f7/fa/d3fc622de05a86f30beea5fc4e9ac46aead4731e73fd9055496732bcc0a4/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", size = 144800 }, - { url = "https://files.pythonhosted.org/packages/9a/65/bdb9bc496d7d190d725e96816e20e2ae3a6fa42a5cac99c3c3d6ff884118/charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", size = 94836 }, - { url = "https://files.pythonhosted.org/packages/3e/67/7b72b69d25b89c0b3cea583ee372c43aa24df15f0e0f8d3982c57804984b/charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", size = 102187 }, - { url = "https://files.pythonhosted.org/packages/f3/89/68a4c86f1a0002810a27f12e9a7b22feb198c59b2f05231349fbce5c06f4/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", size = 194617 }, - { url = "https://files.pythonhosted.org/packages/4f/cd/8947fe425e2ab0aa57aceb7807af13a0e4162cd21eee42ef5b053447edf5/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", size = 125310 }, - { url = "https://files.pythonhosted.org/packages/5b/f0/b5263e8668a4ee9becc2b451ed909e9c27058337fda5b8c49588183c267a/charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", size = 119126 }, - { url = "https://files.pythonhosted.org/packages/ff/6e/e445afe4f7fda27a533f3234b627b3e515a1b9429bc981c9a5e2aa5d97b6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", size = 139342 }, - { url = "https://files.pythonhosted.org/packages/a1/b2/4af9993b532d93270538ad4926c8e37dc29f2111c36f9c629840c57cd9b3/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", size = 149383 }, - { url = "https://files.pythonhosted.org/packages/fb/6f/4e78c3b97686b871db9be6f31d64e9264e889f8c9d7ab33c771f847f79b7/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", size = 142214 }, - { url = "https://files.pythonhosted.org/packages/2b/c9/1c8fe3ce05d30c87eff498592c89015b19fade13df42850aafae09e94f35/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", size = 144104 }, - { url = "https://files.pythonhosted.org/packages/ee/68/efad5dcb306bf37db7db338338e7bb8ebd8cf38ee5bbd5ceaaaa46f257e6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", size = 146255 }, - { url = "https://files.pythonhosted.org/packages/0c/75/1ed813c3ffd200b1f3e71121c95da3f79e6d2a96120163443b3ad1057505/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", size = 140251 }, - { url = "https://files.pythonhosted.org/packages/7d/0d/6f32255c1979653b448d3c709583557a4d24ff97ac4f3a5be156b2e6a210/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", size = 148474 }, - { url = "https://files.pythonhosted.org/packages/ac/a0/c1b5298de4670d997101fef95b97ac440e8c8d8b4efa5a4d1ef44af82f0d/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", size = 151849 }, - { url = "https://files.pythonhosted.org/packages/04/4f/b3961ba0c664989ba63e30595a3ed0875d6790ff26671e2aae2fdc28a399/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", size = 149781 }, - { url = "https://files.pythonhosted.org/packages/d8/90/6af4cd042066a4adad58ae25648a12c09c879efa4849c705719ba1b23d8c/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482", size = 144970 }, - { url = "https://files.pythonhosted.org/packages/cc/67/e5e7e0cbfefc4ca79025238b43cdf8a2037854195b37d6417f3d0895c4c2/charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", size = 94973 }, - { url = "https://files.pythonhosted.org/packages/65/97/fc9bbc54ee13d33dc54a7fcf17b26368b18505500fc01e228c27b5222d80/charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", size = 102308 }, - { url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 }, +version = "3.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", size = 198013 }, + { url = "https://files.pythonhosted.org/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", size = 141285 }, + { url = "https://files.pythonhosted.org/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", size = 151449 }, + { url = "https://files.pythonhosted.org/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", size = 143892 }, + { url = "https://files.pythonhosted.org/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", size = 146123 }, + { url = "https://files.pythonhosted.org/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", size = 147943 }, + { url = "https://files.pythonhosted.org/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", size = 142063 }, + { url = "https://files.pythonhosted.org/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", size = 150578 }, + { url = "https://files.pythonhosted.org/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", size = 153629 }, + { url = "https://files.pythonhosted.org/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", size = 150778 }, + { url = "https://files.pythonhosted.org/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", size = 146453 }, + { url = "https://files.pythonhosted.org/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", size = 95479 }, + { url = "https://files.pythonhosted.org/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", size = 102790 }, + { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995 }, + { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471 }, + { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831 }, + { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335 }, + { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862 }, + { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673 }, + { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211 }, + { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039 }, + { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939 }, + { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075 }, + { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340 }, + { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205 }, + { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441 }, + { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, + { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, + { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, + { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, + { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, + { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, + { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, + { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, + { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, + { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, + { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, + { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, + { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, + { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, + { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, + { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, + { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, + { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, + { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, + { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, + { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, + { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, + { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, + { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, + { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, + { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, ] [[package]] @@ -275,61 +267,61 @@ wheels = [ [[package]] name = "coverage" -version = "7.6.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/12/3669b6382792783e92046730ad3327f53b2726f0603f4c311c4da4824222/coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", size = 798716 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/93/4ad92f71e28ece5c0326e5f4a6630aa4928a8846654a65cfff69b49b95b9/coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", size = 206713 }, - { url = "https://files.pythonhosted.org/packages/01/ae/747a580b1eda3f2e431d87de48f0604bd7bc92e52a1a95185a4aa585bc47/coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", size = 207149 }, - { url = "https://files.pythonhosted.org/packages/07/1a/1f573f8a6145f6d4c9130bbc120e0024daf1b24cf2a78d7393fa6eb6aba7/coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", size = 235584 }, - { url = "https://files.pythonhosted.org/packages/40/42/c8523f2e4db34aa9389caee0d3688b6ada7a84fcc782e943a868a7f302bd/coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", size = 233486 }, - { url = "https://files.pythonhosted.org/packages/8d/95/565c310fffa16ede1a042e9ea1ca3962af0d8eb5543bc72df6b91dc0c3d5/coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", size = 234649 }, - { url = "https://files.pythonhosted.org/packages/d5/81/3b550674d98968ec29c92e3e8650682be6c8b1fa7581a059e7e12e74c431/coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", size = 233744 }, - { url = "https://files.pythonhosted.org/packages/0d/70/d66c7f51b3e33aabc5ea9f9624c1c9d9655472962270eb5e7b0d32707224/coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", size = 232204 }, - { url = "https://files.pythonhosted.org/packages/23/2d/2b3a2dbed7a5f40693404c8a09e779d7c1a5fbed089d3e7224c002129ec8/coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", size = 233335 }, - { url = "https://files.pythonhosted.org/packages/5a/4f/92d1d2ad720d698a4e71c176eacf531bfb8e0721d5ad560556f2c484a513/coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", size = 209435 }, - { url = "https://files.pythonhosted.org/packages/c7/b9/cdf158e7991e2287bcf9082670928badb73d310047facac203ff8dcd5ff3/coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", size = 210243 }, - { url = "https://files.pythonhosted.org/packages/87/31/9c0cf84f0dfcbe4215b7eb95c31777cdc0483c13390e69584c8150c85175/coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", size = 206819 }, - { url = "https://files.pythonhosted.org/packages/53/ed/a38401079ad320ad6e054a01ec2b61d270511aeb3c201c80e99c841229d5/coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", size = 207263 }, - { url = "https://files.pythonhosted.org/packages/20/e7/c3ad33b179ab4213f0d70da25a9c214d52464efa11caeab438592eb1d837/coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", size = 239205 }, - { url = "https://files.pythonhosted.org/packages/36/91/fc02e8d8e694f557752120487fd982f654ba1421bbaa5560debf96ddceda/coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", size = 236612 }, - { url = "https://files.pythonhosted.org/packages/cc/57/cb08f0eda0389a9a8aaa4fc1f9fec7ac361c3e2d68efd5890d7042c18aa3/coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", size = 238479 }, - { url = "https://files.pythonhosted.org/packages/d5/c9/2c7681a9b3ca6e6f43d489c2e6653a53278ed857fd6e7010490c307b0a47/coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", size = 237405 }, - { url = "https://files.pythonhosted.org/packages/b5/4e/ebfc6944b96317df8b537ae875d2e57c27b84eb98820bc0a1055f358f056/coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", size = 236038 }, - { url = "https://files.pythonhosted.org/packages/13/f2/3a0bf1841a97c0654905e2ef531170f02c89fad2555879db8fe41a097871/coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", size = 236812 }, - { url = "https://files.pythonhosted.org/packages/b9/9c/66bf59226b52ce6ed9541b02d33e80a6e816a832558fbdc1111a7bd3abd4/coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", size = 209400 }, - { url = "https://files.pythonhosted.org/packages/2a/a0/b0790934c04dfc8d658d4a62acb8f7ca0efdf3818456fcad757b11c6479d/coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", size = 210243 }, - { url = "https://files.pythonhosted.org/packages/7d/e7/9291de916d084f41adddfd4b82246e68d61d6a75747f075f7e64628998d2/coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", size = 207013 }, - { url = "https://files.pythonhosted.org/packages/27/03/932c2c5717a7fa80cd43c6a07d3177076d97b79f12f40f882f9916db0063/coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", size = 207251 }, - { url = "https://files.pythonhosted.org/packages/d5/3f/0af47dcb9327f65a45455fbca846fe96eb57c153af46c4754a3ba678938a/coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", size = 240268 }, - { url = "https://files.pythonhosted.org/packages/8a/3c/37a9d81bbd4b23bc7d46ca820e16174c613579c66342faa390a271d2e18b/coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", size = 237298 }, - { url = "https://files.pythonhosted.org/packages/c0/70/6b0627e5bd68204ee580126ed3513140b2298995c1233bd67404b4e44d0e/coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", size = 239367 }, - { url = "https://files.pythonhosted.org/packages/3c/eb/634d7dfab24ac3b790bebaf9da0f4a5352cbc125ce6a9d5c6cf4c6cae3c7/coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", size = 238853 }, - { url = "https://files.pythonhosted.org/packages/d9/0d/8e3ed00f1266ef7472a4e33458f42e39492e01a64281084fb3043553d3f1/coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", size = 237160 }, - { url = "https://files.pythonhosted.org/packages/ce/9c/4337f468ef0ab7a2e0887a9c9da0e58e2eada6fc6cbee637a4acd5dfd8a9/coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", size = 238824 }, - { url = "https://files.pythonhosted.org/packages/5e/09/3e94912b8dd37251377bb02727a33a67ee96b84bbbe092f132b401ca5dd9/coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", size = 209639 }, - { url = "https://files.pythonhosted.org/packages/01/69/d4f3a4101171f32bc5b3caec8ff94c2c60f700107a6aaef7244b2c166793/coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", size = 210428 }, - { url = "https://files.pythonhosted.org/packages/c2/4d/2dede4f7cb5a70fb0bb40a57627fddf1dbdc6b9c1db81f7c4dcdcb19e2f4/coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", size = 207039 }, - { url = "https://files.pythonhosted.org/packages/3f/f9/d86368ae8c79e28f1fb458ebc76ae9ff3e8bd8069adc24e8f2fed03c58b7/coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", size = 207298 }, - { url = "https://files.pythonhosted.org/packages/64/c5/b4cc3c3f64622c58fbfd4d8b9a7a8ce9d355f172f91fcabbba1f026852f6/coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", size = 239813 }, - { url = "https://files.pythonhosted.org/packages/8a/86/14c42e60b70a79b26099e4d289ccdfefbc68624d096f4481163085aa614c/coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", size = 236959 }, - { url = "https://files.pythonhosted.org/packages/7f/f8/4436a643631a2fbab4b44d54f515028f6099bfb1cd95b13cfbf701e7f2f2/coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", size = 238950 }, - { url = "https://files.pythonhosted.org/packages/49/50/1571810ddd01f99a0a8be464a4ac8b147f322cd1e8e296a1528984fc560b/coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", size = 238610 }, - { url = "https://files.pythonhosted.org/packages/f3/8c/6312d241fe7cbd1f0cade34a62fea6f333d1a261255d76b9a87074d8703c/coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", size = 236697 }, - { url = "https://files.pythonhosted.org/packages/ce/5f/fef33dfd05d87ee9030f614c857deb6df6556b8f6a1c51bbbb41e24ee5ac/coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", size = 238541 }, - { url = "https://files.pythonhosted.org/packages/a9/64/6a984b6e92e1ea1353b7ffa08e27f707a5e29b044622445859200f541e8c/coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", size = 209707 }, - { url = "https://files.pythonhosted.org/packages/5c/60/ce5a9e942e9543783b3db5d942e0578b391c25cdd5e7f342d854ea83d6b7/coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", size = 210439 }, - { url = "https://files.pythonhosted.org/packages/78/53/6719677e92c308207e7f10561a1b16ab8b5c00e9328efc9af7cfd6fb703e/coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", size = 207784 }, - { url = "https://files.pythonhosted.org/packages/fa/dd/7054928930671fcb39ae6a83bb71d9ab5f0afb733172543ced4b09a115ca/coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", size = 208058 }, - { url = "https://files.pythonhosted.org/packages/b5/7d/fd656ddc2b38301927b9eb3aae3fe827e7aa82e691923ed43721fd9423c9/coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", size = 250772 }, - { url = "https://files.pythonhosted.org/packages/90/d0/eb9a3cc2100b83064bb086f18aedde3afffd7de6ead28f69736c00b7f302/coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", size = 246490 }, - { url = "https://files.pythonhosted.org/packages/45/44/3f64f38f6faab8a0cfd2c6bc6eb4c6daead246b97cf5f8fc23bf3788f841/coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", size = 248848 }, - { url = "https://files.pythonhosted.org/packages/5d/11/4c465a5f98656821e499f4b4619929bd5a34639c466021740ecdca42aa30/coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", size = 248340 }, - { url = "https://files.pythonhosted.org/packages/f1/96/ebecda2d016cce9da812f404f720ca5df83c6b29f65dc80d2000d0078741/coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", size = 246229 }, - { url = "https://files.pythonhosted.org/packages/16/d9/3d820c00066ae55d69e6d0eae11d6149a5ca7546de469ba9d597f01bf2d7/coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", size = 247510 }, - { url = "https://files.pythonhosted.org/packages/8f/c3/4fa1eb412bb288ff6bfcc163c11700ff06e02c5fad8513817186e460ed43/coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", size = 210353 }, - { url = "https://files.pythonhosted.org/packages/7e/77/03fc2979d1538884d921c2013075917fc927f41cd8526909852fe4494112/coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", size = 211502 }, - { url = "https://files.pythonhosted.org/packages/cc/56/e1d75e8981a2a92c2a777e67c26efa96c66da59d645423146eb9ff3a851b/coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", size = 198954 }, +version = "7.6.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/ba/ac14d281f80aab516275012e8875991bb06203957aa1e19950139238d658/coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23", size = 803868 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/12/2a2a923edf4ddabdffed7ad6da50d96a5c126dae7b80a33df7310e329a1e/coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78", size = 207982 }, + { url = "https://files.pythonhosted.org/packages/ca/49/6985dbca9c7be3f3cb62a2e6e492a0c88b65bf40579e16c71ae9c33c6b23/coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c", size = 208414 }, + { url = "https://files.pythonhosted.org/packages/35/93/287e8f1d1ed2646f4e0b2605d14616c9a8a2697d0d1b453815eb5c6cebdb/coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a", size = 236860 }, + { url = "https://files.pythonhosted.org/packages/de/e1/cfdb5627a03567a10031acc629b75d45a4ca1616e54f7133ca1fa366050a/coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165", size = 234758 }, + { url = "https://files.pythonhosted.org/packages/6d/85/fc0de2bcda3f97c2ee9fe8568f7d48f7279e91068958e5b2cc19e0e5f600/coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988", size = 235920 }, + { url = "https://files.pythonhosted.org/packages/79/73/ef4ea0105531506a6f4cf4ba571a214b14a884630b567ed65b3d9c1975e1/coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5", size = 234986 }, + { url = "https://files.pythonhosted.org/packages/c6/4d/75afcfe4432e2ad0405c6f27adeb109ff8976c5e636af8604f94f29fa3fc/coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3", size = 233446 }, + { url = "https://files.pythonhosted.org/packages/86/5b/efee56a89c16171288cafff022e8af44f8f94075c2d8da563c3935212871/coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5", size = 234566 }, + { url = "https://files.pythonhosted.org/packages/f2/db/67770cceb4a64d3198bf2aa49946f411b85ec6b0a9b489e61c8467a4253b/coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244", size = 210675 }, + { url = "https://files.pythonhosted.org/packages/8d/27/e8bfc43f5345ec2c27bc8a1fa77cdc5ce9dcf954445e11f14bb70b889d14/coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e", size = 211518 }, + { url = "https://files.pythonhosted.org/packages/85/d2/5e175fcf6766cf7501a8541d81778fd2f52f4870100e791f5327fd23270b/coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3", size = 208088 }, + { url = "https://files.pythonhosted.org/packages/4b/6f/06db4dc8fca33c13b673986e20e466fd936235a6ec1f0045c3853ac1b593/coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43", size = 208536 }, + { url = "https://files.pythonhosted.org/packages/0d/62/c6a0cf80318c1c1af376d52df444da3608eafc913b82c84a4600d8349472/coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132", size = 240474 }, + { url = "https://files.pythonhosted.org/packages/a3/59/750adafc2e57786d2e8739a46b680d4fb0fbc2d57fbcb161290a9f1ecf23/coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f", size = 237880 }, + { url = "https://files.pythonhosted.org/packages/2c/f8/ef009b3b98e9f7033c19deb40d629354aab1d8b2d7f9cfec284dbedf5096/coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994", size = 239750 }, + { url = "https://files.pythonhosted.org/packages/a6/e2/6622f3b70f5f5b59f705e680dae6db64421af05a5d1e389afd24dae62e5b/coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99", size = 238642 }, + { url = "https://files.pythonhosted.org/packages/2d/10/57ac3f191a3c95c67844099514ff44e6e19b2915cd1c22269fb27f9b17b6/coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd", size = 237266 }, + { url = "https://files.pythonhosted.org/packages/ee/2d/7016f4ad9d553cabcb7333ed78ff9d27248ec4eba8dd21fa488254dff894/coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377", size = 238045 }, + { url = "https://files.pythonhosted.org/packages/a7/fe/45af5c82389a71e0cae4546413266d2195c3744849669b0bab4b5f2c75da/coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8", size = 210647 }, + { url = "https://files.pythonhosted.org/packages/db/11/3f8e803a43b79bc534c6a506674da9d614e990e37118b4506faf70d46ed6/coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609", size = 211508 }, + { url = "https://files.pythonhosted.org/packages/86/77/19d09ea06f92fdf0487499283b1b7af06bc422ea94534c8fe3a4cd023641/coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853", size = 208281 }, + { url = "https://files.pythonhosted.org/packages/b6/67/5479b9f2f99fcfb49c0d5cf61912a5255ef80b6e80a3cddba39c38146cf4/coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078", size = 208514 }, + { url = "https://files.pythonhosted.org/packages/15/d1/febf59030ce1c83b7331c3546d7317e5120c5966471727aa7ac157729c4b/coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0", size = 241537 }, + { url = "https://files.pythonhosted.org/packages/4b/7e/5ac4c90192130e7cf8b63153fe620c8bfd9068f89a6d9b5f26f1550f7a26/coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50", size = 238572 }, + { url = "https://files.pythonhosted.org/packages/dc/03/0334a79b26ecf59958f2fe9dd1f5ab3e2f88db876f5071933de39af09647/coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022", size = 240639 }, + { url = "https://files.pythonhosted.org/packages/d7/45/8a707f23c202208d7b286d78ad6233f50dcf929319b664b6cc18a03c1aae/coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b", size = 240072 }, + { url = "https://files.pythonhosted.org/packages/66/02/603ce0ac2d02bc7b393279ef618940b4a0535b0868ee791140bda9ecfa40/coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0", size = 238386 }, + { url = "https://files.pythonhosted.org/packages/04/62/4e6887e9be060f5d18f1dd58c2838b2d9646faf353232dec4e2d4b1c8644/coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852", size = 240054 }, + { url = "https://files.pythonhosted.org/packages/5c/74/83ae4151c170d8bd071924f212add22a0e62a7fe2b149edf016aeecad17c/coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359", size = 210904 }, + { url = "https://files.pythonhosted.org/packages/c3/54/de0893186a221478f5880283119fc40483bc460b27c4c71d1b8bba3474b9/coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247", size = 211692 }, + { url = "https://files.pythonhosted.org/packages/25/6d/31883d78865529257bf847df5789e2ae80e99de8a460c3453dbfbe0db069/coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9", size = 208308 }, + { url = "https://files.pythonhosted.org/packages/70/22/3f2b129cc08de00c83b0ad6252e034320946abfc3e4235c009e57cfeee05/coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b", size = 208565 }, + { url = "https://files.pythonhosted.org/packages/97/0a/d89bc2d1cc61d3a8dfe9e9d75217b2be85f6c73ebf1b9e3c2f4e797f4531/coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690", size = 241083 }, + { url = "https://files.pythonhosted.org/packages/4c/81/6d64b88a00c7a7aaed3a657b8eaa0931f37a6395fcef61e53ff742b49c97/coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18", size = 238235 }, + { url = "https://files.pythonhosted.org/packages/9a/0b/7797d4193f5adb4b837207ed87fecf5fc38f7cc612b369a8e8e12d9fa114/coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c", size = 240220 }, + { url = "https://files.pythonhosted.org/packages/65/4d/6f83ca1bddcf8e51bf8ff71572f39a1c73c34cf50e752a952c34f24d0a60/coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd", size = 239847 }, + { url = "https://files.pythonhosted.org/packages/30/9d/2470df6aa146aff4c65fee0f87f58d2164a67533c771c9cc12ffcdb865d5/coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e", size = 237922 }, + { url = "https://files.pythonhosted.org/packages/08/dd/723fef5d901e6a89f2507094db66c091449c8ba03272861eaefa773ad95c/coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694", size = 239783 }, + { url = "https://files.pythonhosted.org/packages/3d/f7/64d3298b2baf261cb35466000628706ce20a82d42faf9b771af447cd2b76/coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6", size = 210965 }, + { url = "https://files.pythonhosted.org/packages/d5/58/ec43499a7fc681212fe7742fe90b2bc361cdb72e3181ace1604247a5b24d/coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e", size = 211719 }, + { url = "https://files.pythonhosted.org/packages/ab/c9/f2857a135bcff4330c1e90e7d03446b036b2363d4ad37eb5e3a47bbac8a6/coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe", size = 209050 }, + { url = "https://files.pythonhosted.org/packages/aa/b3/f840e5bd777d8433caa9e4a1eb20503495709f697341ac1a8ee6a3c906ad/coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273", size = 209321 }, + { url = "https://files.pythonhosted.org/packages/85/7d/125a5362180fcc1c03d91850fc020f3831d5cda09319522bcfa6b2b70be7/coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8", size = 252039 }, + { url = "https://files.pythonhosted.org/packages/a9/9c/4358bf3c74baf1f9bddd2baf3756b54c07f2cfd2535f0a47f1e7757e54b3/coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098", size = 247758 }, + { url = "https://files.pythonhosted.org/packages/cf/c7/de3eb6fc5263b26fab5cda3de7a0f80e317597a4bad4781859f72885f300/coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb", size = 250119 }, + { url = "https://files.pythonhosted.org/packages/3e/e6/43de91f8ba2ec9140c6a4af1102141712949903dc732cf739167cfa7a3bc/coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0", size = 249597 }, + { url = "https://files.pythonhosted.org/packages/08/40/61158b5499aa2adf9e37bc6d0117e8f6788625b283d51e7e0c53cf340530/coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf", size = 247473 }, + { url = "https://files.pythonhosted.org/packages/50/69/b3f2416725621e9f112e74e8470793d5b5995f146f596f133678a633b77e/coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2", size = 248737 }, + { url = "https://files.pythonhosted.org/packages/3c/6e/fe899fb937657db6df31cc3e61c6968cb56d36d7326361847440a430152e/coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312", size = 211611 }, + { url = "https://files.pythonhosted.org/packages/1c/55/52f5e66142a9d7bc93a15192eba7a78513d2abf6b3558d77b4ca32f5f424/coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d", size = 212781 }, + { url = "https://files.pythonhosted.org/packages/a1/70/de81bfec9ed38a64fc44a77c7665e20ca507fc3265597c28b0d989e4082e/coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f", size = 200223 }, ] [package.optional-dependencies] @@ -462,7 +454,7 @@ name = "importlib-metadata" version = "8.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "zipp", marker = "python_full_version < '3.13'" }, + { name = "zipp" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", size = 55304 } wheels = [ @@ -480,14 +472,14 @@ wheels = [ [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245 } +sdist = { url = "https://files.pythonhosted.org/packages/af/92/b3130cbbf5591acf9ade8708c365f3238046ac7cb8ccba6e81abccb0ccff/jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", size = 244674 } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 }, + { url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 }, ] [[package]] @@ -834,11 +826,11 @@ wheels = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788 } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 }, + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, ] [[package]] @@ -879,92 +871,100 @@ wheels = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, { name = "pydantic-core" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a9/b7/d9e3f12af310e1120c21603644a1cd86f59060e040ec5c3a80b8f05fae30/pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", size = 769917 } +sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/ca334c2ef6f2e046b1144fe4bb2a5da8a4c574e7f2ebf7e16b34a6a2fa92/pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff", size = 761287 } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/e4/ba44652d562cbf0bf320e0f3810206149c8a4e99cdbf66da82e97ab53a15/pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12", size = 434928 }, + { url = "https://files.pythonhosted.org/packages/58/26/82663c79010b28eddf29dcdd0ea723439535fa917fce5905885c0e9ba562/pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53", size = 431426 }, ] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e2/aa/6b6a9b9f8537b872f552ddd46dd3da230367754b6f707b8e1e963f515ea3/pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", size = 402156 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/8b/d3ae387f66277bd8104096d6ec0a145f4baa2966ebb2cad746c0920c9526/pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b", size = 1867835 }, - { url = "https://files.pythonhosted.org/packages/46/76/f68272e4c3a7df8777798282c5e47d508274917f29992d84e1898f8908c7/pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166", size = 1776689 }, - { url = "https://files.pythonhosted.org/packages/cc/69/5f945b4416f42ea3f3bc9d2aaec66c76084a6ff4ff27555bf9415ab43189/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb", size = 1800748 }, - { url = "https://files.pythonhosted.org/packages/50/ab/891a7b0054bcc297fb02d44d05c50e68154e31788f2d9d41d0b72c89fdf7/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916", size = 1806469 }, - { url = "https://files.pythonhosted.org/packages/31/7c/6e3fa122075d78f277a8431c4c608f061881b76c2b7faca01d317ee39b5d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07", size = 2002246 }, - { url = "https://files.pythonhosted.org/packages/ad/6f/22d5692b7ab63fc4acbc74de6ff61d185804a83160adba5e6cc6068e1128/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232", size = 2659404 }, - { url = "https://files.pythonhosted.org/packages/11/ac/1e647dc1121c028b691028fa61a4e7477e6aeb5132628fde41dd34c1671f/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2", size = 2053940 }, - { url = "https://files.pythonhosted.org/packages/91/75/984740c17f12c3ce18b5a2fcc4bdceb785cce7df1511a4ce89bca17c7e2d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f", size = 1921437 }, - { url = "https://files.pythonhosted.org/packages/a0/74/13c5f606b64d93f0721e7768cd3e8b2102164866c207b8cd6f90bb15d24f/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3", size = 1966129 }, - { url = "https://files.pythonhosted.org/packages/18/03/9c4aa5919457c7b57a016c1ab513b1a926ed9b2bb7915bf8e506bf65c34b/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071", size = 2110908 }, - { url = "https://files.pythonhosted.org/packages/92/2c/053d33f029c5dc65e5cf44ff03ceeefb7cce908f8f3cca9265e7f9b540c8/pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119", size = 1735278 }, - { url = "https://files.pythonhosted.org/packages/de/81/7dfe464eca78d76d31dd661b04b5f2036ec72ea8848dd87ab7375e185c23/pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f", size = 1917453 }, - { url = "https://files.pythonhosted.org/packages/5d/30/890a583cd3f2be27ecf32b479d5d615710bb926d92da03e3f7838ff3e58b/pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8", size = 1865160 }, - { url = "https://files.pythonhosted.org/packages/1d/9a/b634442e1253bc6889c87afe8bb59447f106ee042140bd57680b3b113ec7/pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d", size = 1776777 }, - { url = "https://files.pythonhosted.org/packages/75/9a/7816295124a6b08c24c96f9ce73085032d8bcbaf7e5a781cd41aa910c891/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e", size = 1799244 }, - { url = "https://files.pythonhosted.org/packages/a9/8f/89c1405176903e567c5f99ec53387449e62f1121894aa9fc2c4fdc51a59b/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607", size = 1805307 }, - { url = "https://files.pythonhosted.org/packages/d5/a5/1a194447d0da1ef492e3470680c66048fef56fc1f1a25cafbea4bc1d1c48/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd", size = 2000663 }, - { url = "https://files.pythonhosted.org/packages/13/a5/1df8541651de4455e7d587cf556201b4f7997191e110bca3b589218745a5/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea", size = 2655941 }, - { url = "https://files.pythonhosted.org/packages/44/31/a3899b5ce02c4316865e390107f145089876dff7e1dfc770a231d836aed8/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e", size = 2052105 }, - { url = "https://files.pythonhosted.org/packages/1b/aa/98e190f8745d5ec831f6d5449344c48c0627ac5fed4e5340a44b74878f8e/pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b", size = 1919967 }, - { url = "https://files.pythonhosted.org/packages/ae/35/b6e00b6abb2acfee3e8f85558c02a0822e9a8b2f2d812ea8b9079b118ba0/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0", size = 1964291 }, - { url = "https://files.pythonhosted.org/packages/13/46/7bee6d32b69191cd649bbbd2361af79c472d72cb29bb2024f0b6e350ba06/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64", size = 2109666 }, - { url = "https://files.pythonhosted.org/packages/39/ef/7b34f1b122a81b68ed0a7d0e564da9ccdc9a2924c8d6c6b5b11fa3a56970/pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f", size = 1732940 }, - { url = "https://files.pythonhosted.org/packages/2f/76/37b7e76c645843ff46c1d73e046207311ef298d3f7b2f7d8f6ac60113071/pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3", size = 1916804 }, - { url = "https://files.pythonhosted.org/packages/74/7b/8e315f80666194b354966ec84b7d567da77ad927ed6323db4006cf915f3f/pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231", size = 1856459 }, - { url = "https://files.pythonhosted.org/packages/14/de/866bdce10ed808323d437612aca1ec9971b981e1c52e5e42ad9b8e17a6f6/pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee", size = 1770007 }, - { url = "https://files.pythonhosted.org/packages/dc/69/8edd5c3cd48bb833a3f7ef9b81d7666ccddd3c9a635225214e044b6e8281/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87", size = 1790245 }, - { url = "https://files.pythonhosted.org/packages/80/33/9c24334e3af796ce80d2274940aae38dd4e5676298b4398eff103a79e02d/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8", size = 1801260 }, - { url = "https://files.pythonhosted.org/packages/a5/6f/e9567fd90104b79b101ca9d120219644d3314962caa7948dd8b965e9f83e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327", size = 1996872 }, - { url = "https://files.pythonhosted.org/packages/2d/ad/b5f0fe9e6cfee915dd144edbd10b6e9c9c9c9d7a56b69256d124b8ac682e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2", size = 2661617 }, - { url = "https://files.pythonhosted.org/packages/06/c8/7d4b708f8d05a5cbfda3243aad468052c6e99de7d0937c9146c24d9f12e9/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36", size = 2071831 }, - { url = "https://files.pythonhosted.org/packages/89/4d/3079d00c47f22c9a9a8220db088b309ad6e600a73d7a69473e3a8e5e3ea3/pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126", size = 1917453 }, - { url = "https://files.pythonhosted.org/packages/e9/88/9df5b7ce880a4703fcc2d76c8c2d8eb9f861f79d0c56f4b8f5f2607ccec8/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e", size = 1968793 }, - { url = "https://files.pythonhosted.org/packages/e3/b9/41f7efe80f6ce2ed3ee3c2dcfe10ab7adc1172f778cc9659509a79518c43/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", size = 2116872 }, - { url = "https://files.pythonhosted.org/packages/63/08/b59b7a92e03dd25554b0436554bf23e7c29abae7cce4b1c459cd92746811/pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", size = 1738535 }, - { url = "https://files.pythonhosted.org/packages/88/8d/479293e4d39ab409747926eec4329de5b7129beaedc3786eca070605d07f/pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", size = 1917992 }, - { url = "https://files.pythonhosted.org/packages/ad/ef/16ee2df472bf0e419b6bc68c05bf0145c49247a1095e85cee1463c6a44a1/pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", size = 1856143 }, - { url = "https://files.pythonhosted.org/packages/da/fa/bc3dbb83605669a34a93308e297ab22be82dfb9dcf88c6cf4b4f264e0a42/pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", size = 1770063 }, - { url = "https://files.pythonhosted.org/packages/4e/48/e813f3bbd257a712303ebdf55c8dc46f9589ec74b384c9f652597df3288d/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", size = 1790013 }, - { url = "https://files.pythonhosted.org/packages/b4/e0/56eda3a37929a1d297fcab1966db8c339023bcca0b64c5a84896db3fcc5c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", size = 1801077 }, - { url = "https://files.pythonhosted.org/packages/04/be/5e49376769bfbf82486da6c5c1683b891809365c20d7c7e52792ce4c71f3/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", size = 1996782 }, - { url = "https://files.pythonhosted.org/packages/bc/24/e3ee6c04f1d58cc15f37bcc62f32c7478ff55142b7b3e6d42ea374ea427c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", size = 2661375 }, - { url = "https://files.pythonhosted.org/packages/c1/f8/11a9006de4e89d016b8de74ebb1db727dc100608bb1e6bbe9d56a3cbbcce/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", size = 2071635 }, - { url = "https://files.pythonhosted.org/packages/7c/45/bdce5779b59f468bdf262a5bc9eecbae87f271c51aef628d8c073b4b4b4c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", size = 1916994 }, - { url = "https://files.pythonhosted.org/packages/d8/fa/c648308fe711ee1f88192cad6026ab4f925396d1293e8356de7e55be89b5/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", size = 1968877 }, - { url = "https://files.pythonhosted.org/packages/16/16/b805c74b35607d24d37103007f899abc4880923b04929547ae68d478b7f4/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", size = 2116814 }, - { url = "https://files.pythonhosted.org/packages/d1/58/5305e723d9fcdf1c5a655e6a4cc2a07128bf644ff4b1d98daf7a9dbf57da/pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", size = 1738360 }, - { url = "https://files.pythonhosted.org/packages/a5/ae/e14b0ff8b3f48e02394d8acd911376b7b66e164535687ef7dc24ea03072f/pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", size = 1919411 }, - { url = "https://files.pythonhosted.org/packages/13/a9/5d582eb3204464284611f636b55c0a7410d748ff338756323cb1ce721b96/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", size = 1857135 }, - { url = "https://files.pythonhosted.org/packages/2c/57/faf36290933fe16717f97829eabfb1868182ac495f99cf0eda9f59687c9d/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", size = 1740583 }, - { url = "https://files.pythonhosted.org/packages/91/7c/d99e3513dc191c4fec363aef1bf4c8af9125d8fa53af7cb97e8babef4e40/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", size = 1793637 }, - { url = "https://files.pythonhosted.org/packages/29/18/812222b6d18c2d13eebbb0f7cdc170a408d9ced65794fdb86147c77e1982/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068", size = 1941963 }, - { url = "https://files.pythonhosted.org/packages/0f/36/c1f3642ac3f05e6bb4aec3ffc399fa3f84895d259cf5f0ce3054b7735c29/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801", size = 1915332 }, - { url = "https://files.pythonhosted.org/packages/f7/ca/9c0854829311fb446020ebb540ee22509731abad886d2859c855dd29b904/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728", size = 1957926 }, - { url = "https://files.pythonhosted.org/packages/c0/1c/7836b67c42d0cd4441fcd9fafbf6a027ad4b79b6559f80cf11f89fd83648/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433", size = 2100342 }, - { url = "https://files.pythonhosted.org/packages/a9/f9/b6bcaf874f410564a78908739c80861a171788ef4d4f76f5009656672dfe/pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", size = 1920344 }, +sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938 }, + { url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684 }, + { url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169 }, + { url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227 }, + { url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695 }, + { url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662 }, + { url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370 }, + { url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813 }, + { url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287 }, + { url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414 }, + { url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301 }, + { url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685 }, + { url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876 }, + { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421 }, + { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998 }, + { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167 }, + { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071 }, + { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244 }, + { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470 }, + { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291 }, + { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613 }, + { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355 }, + { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661 }, + { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261 }, + { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361 }, + { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484 }, + { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102 }, + { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, + { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, + { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, + { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, + { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, + { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, + { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, + { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, + { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, + { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, + { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, + { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, + { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, + { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, + { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, + { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, + { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, + { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, + { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, + { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, + { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, + { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, + { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, + { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, + { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, + { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, + { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, + { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, + { url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159 }, + { url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331 }, + { url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467 }, + { url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797 }, + { url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839 }, + { url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861 }, + { url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582 }, + { url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985 }, + { url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715 }, ] [[package]] name = "pygments" -version = "2.18.0" +version = "2.19.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, ] [[package]] @@ -991,7 +991,7 @@ wheels = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1001,9 +1001,9 @@ dependencies = [ { name = "pluggy" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 } +sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 }, + { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, ] [[package]] @@ -1077,71 +1077,71 @@ wheels = [ [[package]] name = "regex" -version = "2024.9.11" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/38/148df33b4dbca3bd069b963acab5e0fa1a9dbd6820f8c322d0dd6faeff96/regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd", size = 399403 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/63/12/497bd6599ce8a239ade68678132296aec5ee25ebea45fc8ba91aa60fceec/regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408", size = 482488 }, - { url = "https://files.pythonhosted.org/packages/c1/24/595ddb9bec2a9b151cdaf9565b0c9f3da9f0cb1dca6c158bc5175332ddf8/regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d", size = 287443 }, - { url = "https://files.pythonhosted.org/packages/69/a8/b2fb45d9715b1469383a0da7968f8cacc2f83e9fbbcd6b8713752dd980a6/regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5", size = 284561 }, - { url = "https://files.pythonhosted.org/packages/88/87/1ce4a5357216b19b7055e7d3b0efc75a6e426133bf1e7d094321df514257/regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c", size = 783177 }, - { url = "https://files.pythonhosted.org/packages/3c/65/b9f002ab32f7b68e7d1dcabb67926f3f47325b8dbc22cc50b6a043e1d07c/regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8", size = 823193 }, - { url = "https://files.pythonhosted.org/packages/22/91/8339dd3abce101204d246e31bc26cdd7ec07c9f91598472459a3a902aa41/regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35", size = 809950 }, - { url = "https://files.pythonhosted.org/packages/cb/19/556638aa11c2ec9968a1da998f07f27ec0abb9bf3c647d7c7985ca0b8eea/regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71", size = 782661 }, - { url = "https://files.pythonhosted.org/packages/d1/e9/7a5bc4c6ef8d9cd2bdd83a667888fc35320da96a4cc4da5fa084330f53db/regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8", size = 772348 }, - { url = "https://files.pythonhosted.org/packages/f1/0b/29f2105bfac3ed08e704914c38e93b07c784a6655f8a015297ee7173e95b/regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a", size = 697460 }, - { url = "https://files.pythonhosted.org/packages/71/3a/52ff61054d15a4722605f5872ad03962b319a04c1ebaebe570b8b9b7dde1/regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d", size = 769151 }, - { url = "https://files.pythonhosted.org/packages/97/07/37e460ab5ca84be8e1e197c3b526c5c86993dcc9e13cbc805c35fc2463c1/regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137", size = 777478 }, - { url = "https://files.pythonhosted.org/packages/65/7b/953075723dd5ab00780043ac2f9de667306ff9e2a85332975e9f19279174/regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6", size = 845373 }, - { url = "https://files.pythonhosted.org/packages/40/b8/3e9484c6230b8b6e8f816ab7c9a080e631124991a4ae2c27a81631777db0/regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca", size = 845369 }, - { url = "https://files.pythonhosted.org/packages/b7/99/38434984d912edbd2e1969d116257e869578f67461bd7462b894c45ed874/regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a", size = 773935 }, - { url = "https://files.pythonhosted.org/packages/ab/67/43174d2b46fa947b7b9dfe56b6c8a8a76d44223f35b1d64645a732fd1d6f/regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0", size = 261624 }, - { url = "https://files.pythonhosted.org/packages/c4/2a/4f9c47d9395b6aff24874c761d8d620c0232f97c43ef3cf668c8b355e7a7/regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623", size = 274020 }, - { url = "https://files.pythonhosted.org/packages/86/a1/d526b7b6095a0019aa360948c143aacfeb029919c898701ce7763bbe4c15/regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df", size = 482483 }, - { url = "https://files.pythonhosted.org/packages/32/d9/bfdd153179867c275719e381e1e8e84a97bd186740456a0dcb3e7125c205/regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268", size = 287442 }, - { url = "https://files.pythonhosted.org/packages/33/c4/60f3370735135e3a8d673ddcdb2507a8560d0e759e1398d366e43d000253/regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad", size = 284561 }, - { url = "https://files.pythonhosted.org/packages/b1/51/91a5ebdff17f9ec4973cb0aa9d37635efec1c6868654bbc25d1543aca4ec/regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679", size = 791779 }, - { url = "https://files.pythonhosted.org/packages/07/4a/022c5e6f0891a90cd7eb3d664d6c58ce2aba48bff107b00013f3d6167069/regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4", size = 832605 }, - { url = "https://files.pythonhosted.org/packages/ac/1c/3793990c8c83ca04e018151ddda83b83ecc41d89964f0f17749f027fc44d/regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664", size = 818556 }, - { url = "https://files.pythonhosted.org/packages/e9/5c/8b385afbfacb853730682c57be56225f9fe275c5bf02ac1fc88edbff316d/regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50", size = 792808 }, - { url = "https://files.pythonhosted.org/packages/9b/8b/a4723a838b53c771e9240951adde6af58c829fb6a6a28f554e8131f53839/regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199", size = 781115 }, - { url = "https://files.pythonhosted.org/packages/83/5f/031a04b6017033d65b261259c09043c06f4ef2d4eac841d0649d76d69541/regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4", size = 778155 }, - { url = "https://files.pythonhosted.org/packages/fd/cd/4660756070b03ce4a66663a43f6c6e7ebc2266cc6b4c586c167917185eb4/regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd", size = 784614 }, - { url = "https://files.pythonhosted.org/packages/93/8d/65b9bea7df120a7be8337c415b6d256ba786cbc9107cebba3bf8ff09da99/regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f", size = 853744 }, - { url = "https://files.pythonhosted.org/packages/96/a7/fba1eae75eb53a704475baf11bd44b3e6ccb95b316955027eb7748f24ef8/regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96", size = 855890 }, - { url = "https://files.pythonhosted.org/packages/45/14/d864b2db80a1a3358534392373e8a281d95b28c29c87d8548aed58813910/regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1", size = 781887 }, - { url = "https://files.pythonhosted.org/packages/4d/a9/bfb29b3de3eb11dc9b412603437023b8e6c02fb4e11311863d9bf62c403a/regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9", size = 261644 }, - { url = "https://files.pythonhosted.org/packages/c7/ab/1ad2511cf6a208fde57fafe49829cab8ca018128ab0d0b48973d8218634a/regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf", size = 274033 }, - { url = "https://files.pythonhosted.org/packages/6e/92/407531450762bed778eedbde04407f68cbd75d13cee96c6f8d6903d9c6c1/regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7", size = 483590 }, - { url = "https://files.pythonhosted.org/packages/8e/a2/048acbc5ae1f615adc6cba36cc45734e679b5f1e4e58c3c77f0ed611d4e2/regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231", size = 288175 }, - { url = "https://files.pythonhosted.org/packages/8a/ea/909d8620329ab710dfaf7b4adee41242ab7c9b95ea8d838e9bfe76244259/regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d", size = 284749 }, - { url = "https://files.pythonhosted.org/packages/ca/fa/521eb683b916389b4975337873e66954e0f6d8f91bd5774164a57b503185/regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64", size = 795181 }, - { url = "https://files.pythonhosted.org/packages/28/db/63047feddc3280cc242f9c74f7aeddc6ee662b1835f00046f57d5630c827/regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42", size = 835842 }, - { url = "https://files.pythonhosted.org/packages/e3/94/86adc259ff8ec26edf35fcca7e334566c1805c7493b192cb09679f9c3dee/regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766", size = 823533 }, - { url = "https://files.pythonhosted.org/packages/29/52/84662b6636061277cb857f658518aa7db6672bc6d1a3f503ccd5aefc581e/regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a", size = 797037 }, - { url = "https://files.pythonhosted.org/packages/c3/2a/cd4675dd987e4a7505f0364a958bc41f3b84942de9efaad0ef9a2646681c/regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9", size = 784106 }, - { url = "https://files.pythonhosted.org/packages/6f/75/3ea7ec29de0bbf42f21f812f48781d41e627d57a634f3f23947c9a46e303/regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d", size = 782468 }, - { url = "https://files.pythonhosted.org/packages/d3/67/15519d69b52c252b270e679cb578e22e0c02b8dd4e361f2b04efcc7f2335/regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822", size = 790324 }, - { url = "https://files.pythonhosted.org/packages/9c/71/eff77d3fe7ba08ab0672920059ec30d63fa7e41aa0fb61c562726e9bd721/regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0", size = 860214 }, - { url = "https://files.pythonhosted.org/packages/81/11/e1bdf84a72372e56f1ea4b833dd583b822a23138a616ace7ab57a0e11556/regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a", size = 859420 }, - { url = "https://files.pythonhosted.org/packages/ea/75/9753e9dcebfa7c3645563ef5c8a58f3a47e799c872165f37c55737dadd3e/regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a", size = 787333 }, - { url = "https://files.pythonhosted.org/packages/bc/4e/ba1cbca93141f7416624b3ae63573e785d4bc1834c8be44a8f0747919eca/regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776", size = 262058 }, - { url = "https://files.pythonhosted.org/packages/6e/16/efc5f194778bf43e5888209e5cec4b258005d37c613b67ae137df3b89c53/regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009", size = 273526 }, - { url = "https://files.pythonhosted.org/packages/93/0a/d1c6b9af1ff1e36832fe38d74d5c5bab913f2bdcbbd6bc0e7f3ce8b2f577/regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784", size = 483376 }, - { url = "https://files.pythonhosted.org/packages/a4/42/5910a050c105d7f750a72dcb49c30220c3ae4e2654e54aaaa0e9bc0584cb/regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36", size = 288112 }, - { url = "https://files.pythonhosted.org/packages/8d/56/0c262aff0e9224fa7ffce47b5458d373f4d3e3ff84e99b5ff0cb15e0b5b2/regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92", size = 284608 }, - { url = "https://files.pythonhosted.org/packages/b9/54/9fe8f9aec5007bbbbce28ba3d2e3eaca425f95387b7d1e84f0d137d25237/regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86", size = 795337 }, - { url = "https://files.pythonhosted.org/packages/b2/e7/6b2f642c3cded271c4f16cc4daa7231be544d30fe2b168e0223724b49a61/regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85", size = 835848 }, - { url = "https://files.pythonhosted.org/packages/cd/9e/187363bdf5d8c0e4662117b92aa32bf52f8f09620ae93abc7537d96d3311/regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963", size = 823503 }, - { url = "https://files.pythonhosted.org/packages/f8/10/601303b8ee93589f879664b0cfd3127949ff32b17f9b6c490fb201106c4d/regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6", size = 797049 }, - { url = "https://files.pythonhosted.org/packages/ef/1c/ea200f61ce9f341763f2717ab4daebe4422d83e9fd4ac5e33435fd3a148d/regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802", size = 784144 }, - { url = "https://files.pythonhosted.org/packages/d8/5c/d2429be49ef3292def7688401d3deb11702c13dcaecdc71d2b407421275b/regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29", size = 782483 }, - { url = "https://files.pythonhosted.org/packages/12/d9/cbc30f2ff7164f3b26a7760f87c54bf8b2faed286f60efd80350a51c5b99/regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8", size = 790320 }, - { url = "https://files.pythonhosted.org/packages/19/1d/43ed03a236313639da5a45e61bc553c8d41e925bcf29b0f8ecff0c2c3f25/regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84", size = 860435 }, - { url = "https://files.pythonhosted.org/packages/34/4f/5d04da61c7c56e785058a46349f7285ae3ebc0726c6ea7c5c70600a52233/regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554", size = 859571 }, - { url = "https://files.pythonhosted.org/packages/12/7f/8398c8155a3c70703a8e91c29532558186558e1aea44144b382faa2a6f7a/regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8", size = 787398 }, - { url = "https://files.pythonhosted.org/packages/58/3a/f5903977647a9a7e46d5535e9e96c194304aeeca7501240509bde2f9e17f/regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8", size = 262035 }, - { url = "https://files.pythonhosted.org/packages/ff/80/51ba3a4b7482f6011095b3a036e07374f64de180b7d870b704ed22509002/regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f", size = 273510 }, +version = "2024.11.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/3c/4651f6b130c6842a8f3df82461a8950f923925db8b6961063e82744bddcc/regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91", size = 482674 }, + { url = "https://files.pythonhosted.org/packages/15/51/9f35d12da8434b489c7b7bffc205c474a0a9432a889457026e9bc06a297a/regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0", size = 287684 }, + { url = "https://files.pythonhosted.org/packages/bd/18/b731f5510d1b8fb63c6b6d3484bfa9a59b84cc578ac8b5172970e05ae07c/regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e", size = 284589 }, + { url = "https://files.pythonhosted.org/packages/78/a2/6dd36e16341ab95e4c6073426561b9bfdeb1a9c9b63ab1b579c2e96cb105/regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde", size = 782511 }, + { url = "https://files.pythonhosted.org/packages/1b/2b/323e72d5d2fd8de0d9baa443e1ed70363ed7e7b2fb526f5950c5cb99c364/regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e", size = 821149 }, + { url = "https://files.pythonhosted.org/packages/90/30/63373b9ea468fbef8a907fd273e5c329b8c9535fee36fc8dba5fecac475d/regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2", size = 809707 }, + { url = "https://files.pythonhosted.org/packages/f2/98/26d3830875b53071f1f0ae6d547f1d98e964dd29ad35cbf94439120bb67a/regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf", size = 781702 }, + { url = "https://files.pythonhosted.org/packages/87/55/eb2a068334274db86208ab9d5599ffa63631b9f0f67ed70ea7c82a69bbc8/regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c", size = 771976 }, + { url = "https://files.pythonhosted.org/packages/74/c0/be707bcfe98254d8f9d2cff55d216e946f4ea48ad2fd8cf1428f8c5332ba/regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86", size = 697397 }, + { url = "https://files.pythonhosted.org/packages/49/dc/bb45572ceb49e0f6509f7596e4ba7031f6819ecb26bc7610979af5a77f45/regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67", size = 768726 }, + { url = "https://files.pythonhosted.org/packages/5a/db/f43fd75dc4c0c2d96d0881967897926942e935d700863666f3c844a72ce6/regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d", size = 775098 }, + { url = "https://files.pythonhosted.org/packages/99/d7/f94154db29ab5a89d69ff893159b19ada89e76b915c1293e98603d39838c/regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2", size = 839325 }, + { url = "https://files.pythonhosted.org/packages/f7/17/3cbfab1f23356fbbf07708220ab438a7efa1e0f34195bf857433f79f1788/regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008", size = 843277 }, + { url = "https://files.pythonhosted.org/packages/7e/f2/48b393b51900456155de3ad001900f94298965e1cad1c772b87f9cfea011/regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62", size = 773197 }, + { url = "https://files.pythonhosted.org/packages/45/3f/ef9589aba93e084cd3f8471fded352826dcae8489b650d0b9b27bc5bba8a/regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e", size = 261714 }, + { url = "https://files.pythonhosted.org/packages/42/7e/5f1b92c8468290c465fd50c5318da64319133231415a8aa6ea5ab995a815/regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519", size = 274042 }, + { url = "https://files.pythonhosted.org/packages/58/58/7e4d9493a66c88a7da6d205768119f51af0f684fe7be7bac8328e217a52c/regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638", size = 482669 }, + { url = "https://files.pythonhosted.org/packages/34/4c/8f8e631fcdc2ff978609eaeef1d6994bf2f028b59d9ac67640ed051f1218/regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7", size = 287684 }, + { url = "https://files.pythonhosted.org/packages/c5/1b/f0e4d13e6adf866ce9b069e191f303a30ab1277e037037a365c3aad5cc9c/regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20", size = 284589 }, + { url = "https://files.pythonhosted.org/packages/25/4d/ab21047f446693887f25510887e6820b93f791992994f6498b0318904d4a/regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114", size = 792121 }, + { url = "https://files.pythonhosted.org/packages/45/ee/c867e15cd894985cb32b731d89576c41a4642a57850c162490ea34b78c3b/regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3", size = 831275 }, + { url = "https://files.pythonhosted.org/packages/b3/12/b0f480726cf1c60f6536fa5e1c95275a77624f3ac8fdccf79e6727499e28/regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f", size = 818257 }, + { url = "https://files.pythonhosted.org/packages/bf/ce/0d0e61429f603bac433910d99ef1a02ce45a8967ffbe3cbee48599e62d88/regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0", size = 792727 }, + { url = "https://files.pythonhosted.org/packages/e4/c1/243c83c53d4a419c1556f43777ccb552bccdf79d08fda3980e4e77dd9137/regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55", size = 780667 }, + { url = "https://files.pythonhosted.org/packages/c5/f4/75eb0dd4ce4b37f04928987f1d22547ddaf6c4bae697623c1b05da67a8aa/regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89", size = 776963 }, + { url = "https://files.pythonhosted.org/packages/16/5d/95c568574e630e141a69ff8a254c2f188b4398e813c40d49228c9bbd9875/regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d", size = 784700 }, + { url = "https://files.pythonhosted.org/packages/8e/b5/f8495c7917f15cc6fee1e7f395e324ec3e00ab3c665a7dc9d27562fd5290/regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34", size = 848592 }, + { url = "https://files.pythonhosted.org/packages/1c/80/6dd7118e8cb212c3c60b191b932dc57db93fb2e36fb9e0e92f72a5909af9/regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d", size = 852929 }, + { url = "https://files.pythonhosted.org/packages/11/9b/5a05d2040297d2d254baf95eeeb6df83554e5e1df03bc1a6687fc4ba1f66/regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45", size = 781213 }, + { url = "https://files.pythonhosted.org/packages/26/b7/b14e2440156ab39e0177506c08c18accaf2b8932e39fb092074de733d868/regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9", size = 261734 }, + { url = "https://files.pythonhosted.org/packages/80/32/763a6cc01d21fb3819227a1cc3f60fd251c13c37c27a73b8ff4315433a8e/regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60", size = 274052 }, + { url = "https://files.pythonhosted.org/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", size = 483781 }, + { url = "https://files.pythonhosted.org/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", size = 288455 }, + { url = "https://files.pythonhosted.org/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", size = 284759 }, + { url = "https://files.pythonhosted.org/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", size = 794976 }, + { url = "https://files.pythonhosted.org/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", size = 833077 }, + { url = "https://files.pythonhosted.org/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", size = 823160 }, + { url = "https://files.pythonhosted.org/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", size = 796896 }, + { url = "https://files.pythonhosted.org/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", size = 783997 }, + { url = "https://files.pythonhosted.org/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", size = 781725 }, + { url = "https://files.pythonhosted.org/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", size = 789481 }, + { url = "https://files.pythonhosted.org/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", size = 852896 }, + { url = "https://files.pythonhosted.org/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", size = 860138 }, + { url = "https://files.pythonhosted.org/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", size = 787692 }, + { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135 }, + { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567 }, + { url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525 }, + { url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324 }, + { url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617 }, + { url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023 }, + { url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072 }, + { url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130 }, + { url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857 }, + { url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006 }, + { url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650 }, + { url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545 }, + { url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045 }, + { url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182 }, + { url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733 }, + { url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122 }, + { url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545 }, ] [[package]] @@ -1161,14 +1161,14 @@ wheels = [ [[package]] name = "ruamel-yaml" -version = "0.18.6" +version = "0.18.10" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ruamel-yaml-clib", marker = "python_full_version < '3.13' and platform_python_implementation == 'CPython'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/29/81/4dfc17eb6ebb1aac314a3eb863c1325b907863a1b8b1382cdffcb6ac0ed9/ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b", size = 143362 } +sdist = { url = "https://files.pythonhosted.org/packages/ea/46/f44d8be06b85bc7c4d8c95d658be2b68f27711f279bf9dd0612a5e4794f5/ruamel.yaml-0.18.10.tar.gz", hash = "sha256:20c86ab29ac2153f80a428e1254a8adf686d3383df04490514ca3b79a362db58", size = 143447 } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/67/8ece580cc363331d9a53055130f86b096bf16e38156e33b1d3014fffda6b/ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636", size = 117761 }, + { url = "https://files.pythonhosted.org/packages/c2/36/dfc1ebc0081e6d39924a2cc53654497f967a084a436bb64402dfce4254d9/ruamel.yaml-0.18.10-py3-none-any.whl", hash = "sha256:30f22513ab2301b3d2b577adc121c6471f28734d3d9728581245f1e76468b4f1", size = 117729 }, ] [[package]] @@ -1217,11 +1217,11 @@ wheels = [ [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, ] [[package]] @@ -1493,7 +1493,7 @@ wheels = [ [[package]] name = "starcraft" -version = "0.0.post281+g68d8d79.d20250111" +version = "0.0.post282+g68ad84a" source = { editable = "." } [package.optional-dependencies] @@ -1558,14 +1558,14 @@ dev = [ [[package]] name = "starlette" -version = "0.41.0" +version = "0.45.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/53/c3a36690a923706e7ac841f649c64f5108889ab1ec44218dac45771f252a/starlette-0.41.0.tar.gz", hash = "sha256:39cbd8768b107d68bfe1ff1672b38a2c38b49777de46d2a592841d58e3bf7c2a", size = 2573755 } +sdist = { url = "https://files.pythonhosted.org/packages/90/4f/e1c9f4ec3dae67a94c9285ed275355d5f7cf0f3a5c34538c8ae5412af550/starlette-0.45.2.tar.gz", hash = "sha256:bba1831d15ae5212b22feab2f218bab6ed3cd0fc2dc1d4442443bb1ee52260e0", size = 2574026 } wheels = [ - { url = "https://files.pythonhosted.org/packages/35/c6/a4443bfabf5629129512ca0e07866c4c3c094079ba4e9b2551006927253c/starlette-0.41.0-py3-none-any.whl", hash = "sha256:a0193a3c413ebc9c78bff1c3546a45bb8c8bcb4a84cae8747d650a65bd37210a", size = 73216 }, + { url = "https://files.pythonhosted.org/packages/aa/ab/fe4f57c83620b39dfc9e7687ebad59129ff05170b99422105019d9a65eec/starlette-0.45.2-py3-none-any.whl", hash = "sha256:4daec3356fb0cb1e723a5235e5beaf375d2259af27532958e2d79df549dad9da", size = 71505 }, ] [[package]] @@ -1579,11 +1579,41 @@ wheels = [ [[package]] name = "tomli" -version = "2.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/b9/de2a5c0144d7d75a57ff355c0c24054f965b2dc3036456ae03a51ea6264b/tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed", size = 16096 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/db/ce8eda256fa131af12e0a76d481711abe4681b6923c27efb9a255c9e4594/tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", size = 13237 }, +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, ] [[package]] @@ -1597,33 +1627,33 @@ wheels = [ [[package]] name = "types-docutils" -version = "0.21.0.20241005" +version = "0.21.0.20241128" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/23/31/6f51a6b05ad750fd7875ffd45e7a88063258782f35e5dff1f291061e394e/types-docutils-0.21.0.20241005.tar.gz", hash = "sha256:48f804a2b50da3a1b1681c4ca1b6184416a6e4129e302d15c44e9d97c59b3365", size = 20701 } +sdist = { url = "https://files.pythonhosted.org/packages/dd/df/64e7ab01a4fc5ce46895dc94e31cffc8b8087c8d91ee54c45ac2d8d82445/types_docutils-0.21.0.20241128.tar.gz", hash = "sha256:4dd059805b83ac6ec5a223699195c4e9eeb0446a4f7f2aeff1759a4a7cc17473", size = 26739 } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/73/8ccc09357cfe9f4b8a5b31af3276dd270924bf4915a13cf816b585221b59/types_docutils-0.21.0.20241005-py3-none-any.whl", hash = "sha256:4d9021422f2f3fca8b0726fb8949395f66a06c0d951479eb3b1387d75b134430", size = 28520 }, + { url = "https://files.pythonhosted.org/packages/59/b6/10ba95739f2cbb9c5bd2f6568148d62b468afe01a94c633e8892a2936d8a/types_docutils-0.21.0.20241128-py3-none-any.whl", hash = "sha256:e0409204009639e9b0bf4521eeabe58b5e574ce9c0db08421c2ac26c32be0039", size = 34677 }, ] [[package]] name = "types-pygments" -version = "2.18.0.20240506" +version = "2.19.0.20250107" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "types-docutils" }, { name = "types-setuptools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f0/ed/0a70203637650ecaa74731faf441d128edb908ed6ca184013bfc498283ba/types-Pygments-2.18.0.20240506.tar.gz", hash = "sha256:4b4c37812c87bbde687dbf27adf5bac593745a321e57f678dbc311571ba2ac9d", size = 13516 } +sdist = { url = "https://files.pythonhosted.org/packages/3c/d8/9e0ed97a3ca6143c74347bc32a2499809bc83039b115d0138e502679f4e8/types_pygments-2.19.0.20250107.tar.gz", hash = "sha256:94de72c7f09b956c518f566e056812c698272a7a03a9cd81f0065576c6bd3219", size = 18309 } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/52/1a740a823dcfbe7fe7c44c2ff83528df2c2b5b6e93c299e8db7bf4205c1b/types_Pygments-2.18.0.20240506-py3-none-any.whl", hash = "sha256:11c90bc1737c9af55e5569558b88df7c2233e12325cb516215f722271444e91d", size = 20775 }, + { url = "https://files.pythonhosted.org/packages/ec/e2/0777eed72b5cec191168b37522fbbe831c8353fe6655c3f29a0454f73498/types_Pygments-2.19.0.20250107-py3-none-any.whl", hash = "sha256:34a555ed327f249daed18c6309e6e62770cdb8b9c321029ba7fd852d10b16f10", size = 25548 }, ] [[package]] name = "types-setuptools" -version = "75.2.0.20241019" +version = "75.8.0.20250110" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5e/cd/2e6caabafc6d01b65c212d03a177f510a00840f90d0196cf1718adafbf29/types-setuptools-75.2.0.20241019.tar.gz", hash = "sha256:86ea31b5f6df2c6b8f2dc8ae3f72b213607f62549b6fa2ed5866e5299f968694", size = 42888 } +sdist = { url = "https://files.pythonhosted.org/packages/f7/42/5713e90d4f9683f2301d900f33e4fc2405ad8ac224dda30f6cb7f4cd215b/types_setuptools-75.8.0.20250110.tar.gz", hash = "sha256:96f7ec8bbd6e0a54ea180d66ad68ad7a1d7954e7281a710ea2de75e355545271", size = 48185 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ad/00/a90c00f3af9f6c41788959afc440d54b9677ebc8d9e5dba0ec4914d7a997/types_setuptools-75.2.0.20241019-py3-none-any.whl", hash = "sha256:2e48ff3acd4919471e80d5e3f049cce5c177e108d5d36d2d4cee3fa4d4104258", size = 65740 }, + { url = "https://files.pythonhosted.org/packages/cf/a3/dbfd106751b11c728cec21cc62cbfe7ff7391b935c4b6e8f0bdc2e6fd541/types_setuptools-75.8.0.20250110-py3-none-any.whl", hash = "sha256:a9f12980bbf9bcdc23ecd80755789085bad6bfce4060c2275bc2b4ca9f2bc480", size = 71521 }, ] [[package]] @@ -1646,90 +1676,90 @@ wheels = [ [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } +sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, + { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, ] [[package]] name = "uvicorn" -version = "0.32.0" +version = "0.34.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "h11" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e0/fc/1d785078eefd6945f3e5bab5c076e4230698046231eb0f3747bc5c8fa992/uvicorn-0.32.0.tar.gz", hash = "sha256:f78b36b143c16f54ccdb8190d0a26b5f1901fe5a3c777e1ab29f26391af8551e", size = 77564 } +sdist = { url = "https://files.pythonhosted.org/packages/4b/4d/938bd85e5bf2edeec766267a5015ad969730bb91e31b44021dfe8b22df6c/uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9", size = 76568 } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/14/78bd0e95dd2444b6caacbca2b730671d4295ccb628ef58b81bee903629df/uvicorn-0.32.0-py3-none-any.whl", hash = "sha256:60b8f3a5ac027dcd31448f411ced12b5ef452c646f76f02f8cc3f25d8d26fd82", size = 63723 }, + { url = "https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", size = 62315 }, ] [[package]] name = "watchfiles" -version = "0.24.0" +version = "1.0.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c8/27/2ba23c8cc85796e2d41976439b08d52f691655fdb9401362099502d1f0cf/watchfiles-0.24.0.tar.gz", hash = "sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1", size = 37870 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/a1/631c12626378b9f1538664aa221feb5c60dfafbd7f60b451f8d0bdbcdedd/watchfiles-0.24.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0", size = 375096 }, - { url = "https://files.pythonhosted.org/packages/f7/5c/f27c979c8a10aaa2822286c1bffdce3db731cd1aa4224b9f86623e94bbfe/watchfiles-0.24.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c", size = 367425 }, - { url = "https://files.pythonhosted.org/packages/74/0d/1889e5649885484d29f6c792ef274454d0a26b20d6ed5fdba5409335ccb6/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361", size = 437705 }, - { url = "https://files.pythonhosted.org/packages/85/8a/01d9a22e839f0d1d547af11b1fcac6ba6f889513f1b2e6f221d9d60d9585/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3", size = 433636 }, - { url = "https://files.pythonhosted.org/packages/62/32/a93db78d340c7ef86cde469deb20e36c6b2a873edee81f610e94bbba4e06/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571", size = 451069 }, - { url = "https://files.pythonhosted.org/packages/99/c2/e9e2754fae3c2721c9a7736f92dab73723f1968ed72535fff29e70776008/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd", size = 469306 }, - { url = "https://files.pythonhosted.org/packages/4c/45/f317d9e3affb06c3c27c478de99f7110143e87f0f001f0f72e18d0e1ddce/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a", size = 476187 }, - { url = "https://files.pythonhosted.org/packages/ac/d3/f1f37248abe0114916921e638f71c7d21fe77e3f2f61750e8057d0b68ef2/watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e", size = 425743 }, - { url = "https://files.pythonhosted.org/packages/2b/e8/c7037ea38d838fd81a59cd25761f106ee3ef2cfd3261787bee0c68908171/watchfiles-0.24.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c", size = 612327 }, - { url = "https://files.pythonhosted.org/packages/a0/c5/0e6e228aafe01a7995fbfd2a4edb221bb11a2744803b65a5663fb85e5063/watchfiles-0.24.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188", size = 595096 }, - { url = "https://files.pythonhosted.org/packages/63/d5/4780e8bf3de3b4b46e7428a29654f7dc041cad6b19fd86d083e4b6f64bbe/watchfiles-0.24.0-cp310-none-win32.whl", hash = "sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735", size = 264149 }, - { url = "https://files.pythonhosted.org/packages/fe/1b/5148898ba55fc9c111a2a4a5fb67ad3fa7eb2b3d7f0618241ed88749313d/watchfiles-0.24.0-cp310-none-win_amd64.whl", hash = "sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04", size = 277542 }, - { url = "https://files.pythonhosted.org/packages/85/02/366ae902cd81ca5befcd1854b5c7477b378f68861597cef854bd6dc69fbe/watchfiles-0.24.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:bdcd5538e27f188dd3c804b4a8d5f52a7fc7f87e7fd6b374b8e36a4ca03db428", size = 375579 }, - { url = "https://files.pythonhosted.org/packages/bc/67/d8c9d256791fe312fea118a8a051411337c948101a24586e2df237507976/watchfiles-0.24.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2dadf8a8014fde6addfd3c379e6ed1a981c8f0a48292d662e27cabfe4239c83c", size = 367726 }, - { url = "https://files.pythonhosted.org/packages/b1/dc/a8427b21ef46386adf824a9fec4be9d16a475b850616cfd98cf09a97a2ef/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6509ed3f467b79d95fc62a98229f79b1a60d1b93f101e1c61d10c95a46a84f43", size = 437735 }, - { url = "https://files.pythonhosted.org/packages/3a/21/0b20bef581a9fbfef290a822c8be645432ceb05fb0741bf3c032e0d90d9a/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8360f7314a070c30e4c976b183d1d8d1585a4a50c5cb603f431cebcbb4f66327", size = 433644 }, - { url = "https://files.pythonhosted.org/packages/1c/e8/d5e5f71cc443c85a72e70b24269a30e529227986096abe091040d6358ea9/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:316449aefacf40147a9efaf3bd7c9bdd35aaba9ac5d708bd1eb5763c9a02bef5", size = 450928 }, - { url = "https://files.pythonhosted.org/packages/61/ee/bf17f5a370c2fcff49e1fec987a6a43fd798d8427ea754ce45b38f9e117a/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73bde715f940bea845a95247ea3e5eb17769ba1010efdc938ffcb967c634fa61", size = 469072 }, - { url = "https://files.pythonhosted.org/packages/a3/34/03b66d425986de3fc6077e74a74c78da298f8cb598887f664a4485e55543/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3770e260b18e7f4e576edca4c0a639f704088602e0bc921c5c2e721e3acb8d15", size = 475517 }, - { url = "https://files.pythonhosted.org/packages/70/eb/82f089c4f44b3171ad87a1b433abb4696f18eb67292909630d886e073abe/watchfiles-0.24.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa0fd7248cf533c259e59dc593a60973a73e881162b1a2f73360547132742823", size = 425480 }, - { url = "https://files.pythonhosted.org/packages/53/20/20509c8f5291e14e8a13104b1808cd7cf5c44acd5feaecb427a49d387774/watchfiles-0.24.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d7a2e3b7f5703ffbd500dabdefcbc9eafeff4b9444bbdd5d83d79eedf8428fab", size = 612322 }, - { url = "https://files.pythonhosted.org/packages/df/2b/5f65014a8cecc0a120f5587722068a975a692cadbe9fe4ea56b3d8e43f14/watchfiles-0.24.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d831ee0a50946d24a53821819b2327d5751b0c938b12c0653ea5be7dea9c82ec", size = 595094 }, - { url = "https://files.pythonhosted.org/packages/18/98/006d8043a82c0a09d282d669c88e587b3a05cabdd7f4900e402250a249ac/watchfiles-0.24.0-cp311-none-win32.whl", hash = "sha256:49d617df841a63b4445790a254013aea2120357ccacbed00253f9c2b5dc24e2d", size = 264191 }, - { url = "https://files.pythonhosted.org/packages/8a/8b/badd9247d6ec25f5f634a9b3d0d92e39c045824ec7e8afcedca8ee52c1e2/watchfiles-0.24.0-cp311-none-win_amd64.whl", hash = "sha256:d3dcb774e3568477275cc76554b5a565024b8ba3a0322f77c246bc7111c5bb9c", size = 277527 }, - { url = "https://files.pythonhosted.org/packages/af/19/35c957c84ee69d904299a38bae3614f7cede45f07f174f6d5a2f4dbd6033/watchfiles-0.24.0-cp311-none-win_arm64.whl", hash = "sha256:9301c689051a4857d5b10777da23fafb8e8e921bcf3abe6448a058d27fb67633", size = 266253 }, - { url = "https://files.pythonhosted.org/packages/35/82/92a7bb6dc82d183e304a5f84ae5437b59ee72d48cee805a9adda2488b237/watchfiles-0.24.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7211b463695d1e995ca3feb38b69227e46dbd03947172585ecb0588f19b0d87a", size = 374137 }, - { url = "https://files.pythonhosted.org/packages/87/91/49e9a497ddaf4da5e3802d51ed67ff33024597c28f652b8ab1e7c0f5718b/watchfiles-0.24.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b8693502d1967b00f2fb82fc1e744df128ba22f530e15b763c8d82baee15370", size = 367733 }, - { url = "https://files.pythonhosted.org/packages/0d/d8/90eb950ab4998effea2df4cf3a705dc594f6bc501c5a353073aa990be965/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdab9555053399318b953a1fe1f586e945bc8d635ce9d05e617fd9fe3a4687d6", size = 437322 }, - { url = "https://files.pythonhosted.org/packages/6c/a2/300b22e7bc2a222dd91fce121cefa7b49aa0d26a627b2777e7bdfcf1110b/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:34e19e56d68b0dad5cff62273107cf5d9fbaf9d75c46277aa5d803b3ef8a9e9b", size = 433409 }, - { url = "https://files.pythonhosted.org/packages/99/44/27d7708a43538ed6c26708bcccdde757da8b7efb93f4871d4cc39cffa1cc/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:41face41f036fee09eba33a5b53a73e9a43d5cb2c53dad8e61fa6c9f91b5a51e", size = 452142 }, - { url = "https://files.pythonhosted.org/packages/b0/ec/c4e04f755be003129a2c5f3520d2c47026f00da5ecb9ef1e4f9449637571/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5148c2f1ea043db13ce9b0c28456e18ecc8f14f41325aa624314095b6aa2e9ea", size = 469414 }, - { url = "https://files.pythonhosted.org/packages/c5/4e/cdd7de3e7ac6432b0abf282ec4c1a1a2ec62dfe423cf269b86861667752d/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e4bd963a935aaf40b625c2499f3f4f6bbd0c3776f6d3bc7c853d04824ff1c9f", size = 472962 }, - { url = "https://files.pythonhosted.org/packages/27/69/e1da9d34da7fc59db358424f5d89a56aaafe09f6961b64e36457a80a7194/watchfiles-0.24.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c79d7719d027b7a42817c5d96461a99b6a49979c143839fc37aa5748c322f234", size = 425705 }, - { url = "https://files.pythonhosted.org/packages/e8/c1/24d0f7357be89be4a43e0a656259676ea3d7a074901f47022f32e2957798/watchfiles-0.24.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:32aa53a9a63b7f01ed32e316e354e81e9da0e6267435c7243bf8ae0f10b428ef", size = 612851 }, - { url = "https://files.pythonhosted.org/packages/c7/af/175ba9b268dec56f821639c9893b506c69fd999fe6a2e2c51de420eb2f01/watchfiles-0.24.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ce72dba6a20e39a0c628258b5c308779b8697f7676c254a845715e2a1039b968", size = 594868 }, - { url = "https://files.pythonhosted.org/packages/44/81/1f701323a9f70805bc81c74c990137123344a80ea23ab9504a99492907f8/watchfiles-0.24.0-cp312-none-win32.whl", hash = "sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444", size = 264109 }, - { url = "https://files.pythonhosted.org/packages/b4/0b/32cde5bc2ebd9f351be326837c61bdeb05ad652b793f25c91cac0b48a60b/watchfiles-0.24.0-cp312-none-win_amd64.whl", hash = "sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896", size = 277055 }, - { url = "https://files.pythonhosted.org/packages/4b/81/daade76ce33d21dbec7a15afd7479de8db786e5f7b7d249263b4ea174e08/watchfiles-0.24.0-cp312-none-win_arm64.whl", hash = "sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418", size = 266169 }, - { url = "https://files.pythonhosted.org/packages/30/dc/6e9f5447ae14f645532468a84323a942996d74d5e817837a5c8ce9d16c69/watchfiles-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48", size = 373764 }, - { url = "https://files.pythonhosted.org/packages/79/c0/c3a9929c372816c7fc87d8149bd722608ea58dc0986d3ef7564c79ad7112/watchfiles-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90", size = 367873 }, - { url = "https://files.pythonhosted.org/packages/2e/11/ff9a4445a7cfc1c98caf99042df38964af12eed47d496dd5d0d90417349f/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94", size = 438381 }, - { url = "https://files.pythonhosted.org/packages/48/a3/763ba18c98211d7bb6c0f417b2d7946d346cdc359d585cc28a17b48e964b/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e", size = 432809 }, - { url = "https://files.pythonhosted.org/packages/30/4c/616c111b9d40eea2547489abaf4ffc84511e86888a166d3a4522c2ba44b5/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827", size = 451801 }, - { url = "https://files.pythonhosted.org/packages/b6/be/d7da83307863a422abbfeb12903a76e43200c90ebe5d6afd6a59d158edea/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df", size = 468886 }, - { url = "https://files.pythonhosted.org/packages/1d/d3/3dfe131ee59d5e90b932cf56aba5c996309d94dafe3d02d204364c23461c/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab", size = 472973 }, - { url = "https://files.pythonhosted.org/packages/42/6c/279288cc5653a289290d183b60a6d80e05f439d5bfdfaf2d113738d0f932/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f", size = 425282 }, - { url = "https://files.pythonhosted.org/packages/d6/d7/58afe5e85217e845edf26d8780c2d2d2ae77675eeb8d1b8b8121d799ce52/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b", size = 612540 }, - { url = "https://files.pythonhosted.org/packages/6d/d5/b96eeb9fe3fda137200dd2f31553670cbc731b1e13164fd69b49870b76ec/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18", size = 593625 }, - { url = "https://files.pythonhosted.org/packages/c1/e5/c326fe52ee0054107267608d8cea275e80be4455b6079491dfd9da29f46f/watchfiles-0.24.0-cp313-none-win32.whl", hash = "sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07", size = 263899 }, - { url = "https://files.pythonhosted.org/packages/a6/8b/8a7755c5e7221bb35fe4af2dc44db9174f90ebf0344fd5e9b1e8b42d381e/watchfiles-0.24.0-cp313-none-win_amd64.whl", hash = "sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366", size = 276622 }, - { url = "https://files.pythonhosted.org/packages/df/94/1ad200e937ec91b2a9d6b39ae1cf9c2b1a9cc88d5ceb43aa5c6962eb3c11/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f", size = 376986 }, - { url = "https://files.pythonhosted.org/packages/ee/fd/d9e020d687ccf90fe95efc513fbb39a8049cf5a3ff51f53c59fcf4c47a5d/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b", size = 369445 }, - { url = "https://files.pythonhosted.org/packages/43/cb/c0279b35053555d10ef03559c5aebfcb0c703d9c70a7b4e532df74b9b0e8/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4", size = 439383 }, - { url = "https://files.pythonhosted.org/packages/8b/c4/08b3c2cda45db5169148a981c2100c744a4a222fa7ae7644937c0c002069/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a", size = 426804 }, +sdist = { url = "https://files.pythonhosted.org/packages/f5/26/c705fc77d0a9ecdb9b66f1e2976d95b81df3cae518967431e7dbf9b5e219/watchfiles-1.0.4.tar.gz", hash = "sha256:6ba473efd11062d73e4f00c2b730255f9c1bdd73cd5f9fe5b5da8dbd4a717205", size = 94625 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/02/22fcaed0396730b0d362bc8d1ffb3be2658fd473eecbb2ba84243e157f11/watchfiles-1.0.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ba5bb3073d9db37c64520681dd2650f8bd40902d991e7b4cfaeece3e32561d08", size = 395212 }, + { url = "https://files.pythonhosted.org/packages/e9/3d/ec5a2369a46edf3ebe092c39d9ae48e8cb6dacbde51c4b4f98936c524269/watchfiles-1.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f25d0ba0fe2b6d2c921cf587b2bf4c451860086534f40c384329fb96e2044d1", size = 384815 }, + { url = "https://files.pythonhosted.org/packages/df/b4/898991cececbe171e67142c31905510203649569d9817848f47c4177ee42/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47eb32ef8c729dbc4f4273baece89398a4d4b5d21a1493efea77a17059f4df8a", size = 450680 }, + { url = "https://files.pythonhosted.org/packages/58/f7/d4aa3000e812cfb5e5c2c6c0a3ec9d0a46a42489a8727edd160631c4e210/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:076f293100db3b0b634514aa0d294b941daa85fc777f9c698adb1009e5aca0b1", size = 455923 }, + { url = "https://files.pythonhosted.org/packages/dd/95/7e2e4c6aba1b02fb5c76d2f6a450b85215921ec5f8f7ad5efd075369563f/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1eacd91daeb5158c598fe22d7ce66d60878b6294a86477a4715154990394c9b3", size = 482339 }, + { url = "https://files.pythonhosted.org/packages/bb/67/4265b0fabcc2ef2c9e3e8802ba7908cf718a357ebfb49c72e53787156a48/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:13c2ce7b72026cfbca120d652f02c7750f33b4c9395d79c9790b27f014c8a5a2", size = 519908 }, + { url = "https://files.pythonhosted.org/packages/0d/96/b57802d5f8164bdf070befb4fd3dec4edba5a364ec0670965a97eb8098ce/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:90192cdc15ab7254caa7765a98132a5a41471cf739513cc9bcf7d2ffcc0ec7b2", size = 501410 }, + { url = "https://files.pythonhosted.org/packages/8b/18/6db0de4e8911ba14e31853201b40c0fa9fea5ecf3feb86b0ad58f006dfc3/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:278aaa395f405972e9f523bd786ed59dfb61e4b827856be46a42130605fd0899", size = 452876 }, + { url = "https://files.pythonhosted.org/packages/df/df/092a961815edf723a38ba2638c49491365943919c3526cc9cf82c42786a6/watchfiles-1.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a462490e75e466edbb9fc4cd679b62187153b3ba804868452ef0577ec958f5ff", size = 615353 }, + { url = "https://files.pythonhosted.org/packages/f3/cf/b85fe645de4ff82f3f436c5e9032379fce37c303f6396a18f9726cc34519/watchfiles-1.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8d0d0630930f5cd5af929040e0778cf676a46775753e442a3f60511f2409f48f", size = 613187 }, + { url = "https://files.pythonhosted.org/packages/f6/d4/a9fea27aef4dd69689bc3556718c1157a7accb72aa035ece87c1fa8483b5/watchfiles-1.0.4-cp310-cp310-win32.whl", hash = "sha256:cc27a65069bcabac4552f34fd2dce923ce3fcde0721a16e4fb1b466d63ec831f", size = 270799 }, + { url = "https://files.pythonhosted.org/packages/df/02/dbe9d4439f15dd4ad0720b6e039bde9d66d1f830331f34c18eb70fa6608e/watchfiles-1.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:8b1f135238e75d075359cf506b27bf3f4ca12029c47d3e769d8593a2024ce161", size = 284145 }, + { url = "https://files.pythonhosted.org/packages/0f/bb/8461adc4b1fed009546fb797fc0d5698dcfe5e289cb37e1b8f16a93cdc30/watchfiles-1.0.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:2a9f93f8439639dc244c4d2902abe35b0279102bca7bbcf119af964f51d53c19", size = 394869 }, + { url = "https://files.pythonhosted.org/packages/55/88/9ebf36b3547176d1709c320de78c1fa3263a46be31b5b1267571d9102686/watchfiles-1.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9eea33ad8c418847dd296e61eb683cae1c63329b6d854aefcd412e12d94ee235", size = 384905 }, + { url = "https://files.pythonhosted.org/packages/03/8a/04335ce23ef78d8c69f0913e8b20cf7d9233e3986543aeef95ef2d6e43d2/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31f1a379c9dcbb3f09cf6be1b7e83b67c0e9faabed0471556d9438a4a4e14202", size = 449944 }, + { url = "https://files.pythonhosted.org/packages/17/4e/c8d5dcd14fe637f4633616dabea8a4af0a10142dccf3b43e0f081ba81ab4/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab594e75644421ae0a2484554832ca5895f8cab5ab62de30a1a57db460ce06c6", size = 456020 }, + { url = "https://files.pythonhosted.org/packages/5e/74/3e91e09e1861dd7fbb1190ce7bd786700dc0fbc2ccd33bb9fff5de039229/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc2eb5d14a8e0d5df7b36288979176fbb39672d45184fc4b1c004d7c3ce29317", size = 482983 }, + { url = "https://files.pythonhosted.org/packages/a1/3d/e64de2d1ce4eb6a574fd78ce3a28c279da263be9ef3cfcab6f708df192f2/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f68d8e9d5a321163ddacebe97091000955a1b74cd43724e346056030b0bacee", size = 520320 }, + { url = "https://files.pythonhosted.org/packages/2c/bd/52235f7063b57240c66a991696ed27e2a18bd6fcec8a1ea5a040b70d0611/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9ce064e81fe79faa925ff03b9f4c1a98b0bbb4a1b8c1b015afa93030cb21a49", size = 500988 }, + { url = "https://files.pythonhosted.org/packages/3a/b0/ff04194141a5fe650c150400dd9e42667916bc0f52426e2e174d779b8a74/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b77d5622ac5cc91d21ae9c2b284b5d5c51085a0bdb7b518dba263d0af006132c", size = 452573 }, + { url = "https://files.pythonhosted.org/packages/3d/9d/966164332c5a178444ae6d165082d4f351bd56afd9c3ec828eecbf190e6a/watchfiles-1.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1941b4e39de9b38b868a69b911df5e89dc43767feeda667b40ae032522b9b5f1", size = 615114 }, + { url = "https://files.pythonhosted.org/packages/94/df/f569ae4c1877f96ad4086c153a8eee5a19a3b519487bf5c9454a3438c341/watchfiles-1.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4f8c4998506241dedf59613082d1c18b836e26ef2a4caecad0ec41e2a15e4226", size = 613076 }, + { url = "https://files.pythonhosted.org/packages/15/ae/8ce5f29e65d5fa5790e3c80c289819c55e12be2e1b9f5b6a0e55e169b97d/watchfiles-1.0.4-cp311-cp311-win32.whl", hash = "sha256:4ebbeca9360c830766b9f0df3640b791be569d988f4be6c06d6fae41f187f105", size = 271013 }, + { url = "https://files.pythonhosted.org/packages/a4/c6/79dc4a7c598a978e5fafa135090aaf7bbb03b8dec7bada437dfbe578e7ed/watchfiles-1.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:05d341c71f3d7098920f8551d4df47f7b57ac5b8dad56558064c3431bdfc0b74", size = 284229 }, + { url = "https://files.pythonhosted.org/packages/37/3d/928633723211753f3500bfb138434f080363b87a1b08ca188b1ce54d1e05/watchfiles-1.0.4-cp311-cp311-win_arm64.whl", hash = "sha256:32b026a6ab64245b584acf4931fe21842374da82372d5c039cba6bf99ef722f3", size = 276824 }, + { url = "https://files.pythonhosted.org/packages/5b/1a/8f4d9a1461709756ace48c98f07772bc6d4519b1e48b5fa24a4061216256/watchfiles-1.0.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:229e6ec880eca20e0ba2f7e2249c85bae1999d330161f45c78d160832e026ee2", size = 391345 }, + { url = "https://files.pythonhosted.org/packages/bc/d2/6750b7b3527b1cdaa33731438432e7238a6c6c40a9924049e4cebfa40805/watchfiles-1.0.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5717021b199e8353782dce03bd8a8f64438832b84e2885c4a645f9723bf656d9", size = 381515 }, + { url = "https://files.pythonhosted.org/packages/4e/17/80500e42363deef1e4b4818729ed939aaddc56f82f4e72b2508729dd3c6b/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0799ae68dfa95136dde7c472525700bd48777875a4abb2ee454e3ab18e9fc712", size = 449767 }, + { url = "https://files.pythonhosted.org/packages/10/37/1427fa4cfa09adbe04b1e97bced19a29a3462cc64c78630787b613a23f18/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:43b168bba889886b62edb0397cab5b6490ffb656ee2fcb22dec8bfeb371a9e12", size = 455677 }, + { url = "https://files.pythonhosted.org/packages/c5/7a/39e9397f3a19cb549a7d380412fd9e507d4854eddc0700bfad10ef6d4dba/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb2c46e275fbb9f0c92e7654b231543c7bbfa1df07cdc4b99fa73bedfde5c844", size = 482219 }, + { url = "https://files.pythonhosted.org/packages/45/2d/7113931a77e2ea4436cad0c1690c09a40a7f31d366f79c6f0a5bc7a4f6d5/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:857f5fc3aa027ff5e57047da93f96e908a35fe602d24f5e5d8ce64bf1f2fc733", size = 518830 }, + { url = "https://files.pythonhosted.org/packages/f9/1b/50733b1980fa81ef3c70388a546481ae5fa4c2080040100cd7bf3bf7b321/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55ccfd27c497b228581e2838d4386301227fc0cb47f5a12923ec2fe4f97b95af", size = 497997 }, + { url = "https://files.pythonhosted.org/packages/2b/b4/9396cc61b948ef18943e7c85ecfa64cf940c88977d882da57147f62b34b1/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c11ea22304d17d4385067588123658e9f23159225a27b983f343fcffc3e796a", size = 452249 }, + { url = "https://files.pythonhosted.org/packages/fb/69/0c65a5a29e057ad0dc691c2fa6c23b2983c7dabaa190ba553b29ac84c3cc/watchfiles-1.0.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:74cb3ca19a740be4caa18f238298b9d472c850f7b2ed89f396c00a4c97e2d9ff", size = 614412 }, + { url = "https://files.pythonhosted.org/packages/7f/b9/319fcba6eba5fad34327d7ce16a6b163b39741016b1996f4a3c96b8dd0e1/watchfiles-1.0.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7cce76c138a91e720d1df54014a047e680b652336e1b73b8e3ff3158e05061e", size = 611982 }, + { url = "https://files.pythonhosted.org/packages/f1/47/143c92418e30cb9348a4387bfa149c8e0e404a7c5b0585d46d2f7031b4b9/watchfiles-1.0.4-cp312-cp312-win32.whl", hash = "sha256:b045c800d55bc7e2cadd47f45a97c7b29f70f08a7c2fa13241905010a5493f94", size = 271822 }, + { url = "https://files.pythonhosted.org/packages/ea/94/b0165481bff99a64b29e46e07ac2e0df9f7a957ef13bec4ceab8515f44e3/watchfiles-1.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:c2acfa49dd0ad0bf2a9c0bb9a985af02e89345a7189be1efc6baa085e0f72d7c", size = 285441 }, + { url = "https://files.pythonhosted.org/packages/11/de/09fe56317d582742d7ca8c2ca7b52a85927ebb50678d9b0fa8194658f536/watchfiles-1.0.4-cp312-cp312-win_arm64.whl", hash = "sha256:22bb55a7c9e564e763ea06c7acea24fc5d2ee5dfc5dafc5cfbedfe58505e9f90", size = 277141 }, + { url = "https://files.pythonhosted.org/packages/08/98/f03efabec64b5b1fa58c0daab25c68ef815b0f320e54adcacd0d6847c339/watchfiles-1.0.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:8012bd820c380c3d3db8435e8cf7592260257b378b649154a7948a663b5f84e9", size = 390954 }, + { url = "https://files.pythonhosted.org/packages/16/09/4dd49ba0a32a45813debe5fb3897955541351ee8142f586303b271a02b40/watchfiles-1.0.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa216f87594f951c17511efe5912808dfcc4befa464ab17c98d387830ce07b60", size = 381133 }, + { url = "https://files.pythonhosted.org/packages/76/59/5aa6fc93553cd8d8ee75c6247763d77c02631aed21551a97d94998bf1dae/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62c9953cf85529c05b24705639ffa390f78c26449e15ec34d5339e8108c7c407", size = 449516 }, + { url = "https://files.pythonhosted.org/packages/4c/aa/df4b6fe14b6317290b91335b23c96b488d365d65549587434817e06895ea/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7cf684aa9bba4cd95ecb62c822a56de54e3ae0598c1a7f2065d51e24637a3c5d", size = 454820 }, + { url = "https://files.pythonhosted.org/packages/5e/71/185f8672f1094ce48af33252c73e39b48be93b761273872d9312087245f6/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f44a39aee3cbb9b825285ff979ab887a25c5d336e5ec3574f1506a4671556a8d", size = 481550 }, + { url = "https://files.pythonhosted.org/packages/85/d7/50ebba2c426ef1a5cb17f02158222911a2e005d401caf5d911bfca58f4c4/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38320582736922be8c865d46520c043bff350956dfc9fbaee3b2df4e1740a4b", size = 518647 }, + { url = "https://files.pythonhosted.org/packages/f0/7a/4c009342e393c545d68987e8010b937f72f47937731225b2b29b7231428f/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39f4914548b818540ef21fd22447a63e7be6e24b43a70f7642d21f1e73371590", size = 497547 }, + { url = "https://files.pythonhosted.org/packages/0f/7c/1cf50b35412d5c72d63b2bf9a4fffee2e1549a245924960dd087eb6a6de4/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f12969a3765909cf5dc1e50b2436eb2c0e676a3c75773ab8cc3aa6175c16e902", size = 452179 }, + { url = "https://files.pythonhosted.org/packages/d6/a9/3db1410e1c1413735a9a472380e4f431ad9a9e81711cda2aaf02b7f62693/watchfiles-1.0.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:0986902677a1a5e6212d0c49b319aad9cc48da4bd967f86a11bde96ad9676ca1", size = 614125 }, + { url = "https://files.pythonhosted.org/packages/f2/e1/0025d365cf6248c4d1ee4c3d2e3d373bdd3f6aff78ba4298f97b4fad2740/watchfiles-1.0.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:308ac265c56f936636e3b0e3f59e059a40003c655228c131e1ad439957592303", size = 611911 }, + { url = "https://files.pythonhosted.org/packages/55/55/035838277d8c98fc8c917ac9beeb0cd6c59d675dc2421df5f9fcf44a0070/watchfiles-1.0.4-cp313-cp313-win32.whl", hash = "sha256:aee397456a29b492c20fda2d8961e1ffb266223625346ace14e4b6d861ba9c80", size = 271152 }, + { url = "https://files.pythonhosted.org/packages/f0/e5/96b8e55271685ddbadc50ce8bc53aa2dff278fb7ac4c2e473df890def2dc/watchfiles-1.0.4-cp313-cp313-win_amd64.whl", hash = "sha256:d6097538b0ae5c1b88c3b55afa245a66793a8fec7ada6755322e465fb1a0e8cc", size = 285216 }, + { url = "https://files.pythonhosted.org/packages/6f/06/175d5ac6b838fb319008c0cd981d7bf289317c510154d411d3584ca2b67b/watchfiles-1.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cdcc92daeae268de1acf5b7befcd6cfffd9a047098199056c72e4623f531de18", size = 396269 }, + { url = "https://files.pythonhosted.org/packages/86/ee/5db93b0b57dc0587abdbac4149296ee73275f615d790a82cb5598af0557f/watchfiles-1.0.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d8d3d9203705b5797f0af7e7e5baa17c8588030aaadb7f6a86107b7247303817", size = 386010 }, + { url = "https://files.pythonhosted.org/packages/75/61/fe0dc5fedf152bfc085a53711f740701f6bdb8ab6b5c950402b681d4858b/watchfiles-1.0.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdef5a1be32d0b07dcea3318a0be95d42c98ece24177820226b56276e06b63b0", size = 450913 }, + { url = "https://files.pythonhosted.org/packages/9f/dd/3c7731af3baf1a9957afc643d176f94480921a690ec3237c9f9d11301c08/watchfiles-1.0.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:342622287b5604ddf0ed2d085f3a589099c9ae8b7331df3ae9845571586c4f3d", size = 453474 }, ] [[package]] @@ -1743,61 +1773,61 @@ wheels = [ [[package]] name = "websockets" -version = "13.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e2/73/9223dbc7be3dcaf2a7bbf756c351ec8da04b1fa573edaf545b95f6b0c7fd/websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878", size = 158549 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/94/d15dbfc6a5eb636dbc754303fba18208f2e88cf97e733e1d64fb9cb5c89e/websockets-13.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee", size = 157815 }, - { url = "https://files.pythonhosted.org/packages/30/02/c04af33f4663945a26f5e8cf561eb140c35452b50af47a83c3fbcfe62ae1/websockets-13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7", size = 155466 }, - { url = "https://files.pythonhosted.org/packages/35/e8/719f08d12303ea643655e52d9e9851b2dadbb1991d4926d9ce8862efa2f5/websockets-13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6", size = 155716 }, - { url = "https://files.pythonhosted.org/packages/91/e1/14963ae0252a8925f7434065d25dcd4701d5e281a0b4b460a3b5963d2594/websockets-13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b", size = 164806 }, - { url = "https://files.pythonhosted.org/packages/ec/fa/ab28441bae5e682a0f7ddf3d03440c0c352f930da419301f4a717f675ef3/websockets-13.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa", size = 163810 }, - { url = "https://files.pythonhosted.org/packages/44/77/dea187bd9d16d4b91566a2832be31f99a40d0f5bfa55eeb638eb2c3bc33d/websockets-13.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700", size = 164125 }, - { url = "https://files.pythonhosted.org/packages/cf/d9/3af14544e83f1437eb684b399e6ba0fa769438e869bf5d83d74bc197fae8/websockets-13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c", size = 164532 }, - { url = "https://files.pythonhosted.org/packages/1c/8a/6d332eabe7d59dfefe4b8ba6f46c8c5fabb15b71c8a8bc3d2b65de19a7b6/websockets-13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0", size = 163948 }, - { url = "https://files.pythonhosted.org/packages/1a/91/a0aeadbaf3017467a1ee03f8fb67accdae233fe2d5ad4b038c0a84e357b0/websockets-13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f", size = 163898 }, - { url = "https://files.pythonhosted.org/packages/71/31/a90fb47c63e0ae605be914b0b969d7c6e6ffe2038cd744798e4b3fbce53b/websockets-13.1-cp310-cp310-win32.whl", hash = "sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe", size = 158706 }, - { url = "https://files.pythonhosted.org/packages/93/ca/9540a9ba80da04dc7f36d790c30cae4252589dbd52ccdc92e75b0be22437/websockets-13.1-cp310-cp310-win_amd64.whl", hash = "sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a", size = 159141 }, - { url = "https://files.pythonhosted.org/packages/b2/f0/cf0b8a30d86b49e267ac84addbebbc7a48a6e7bb7c19db80f62411452311/websockets-13.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19", size = 157813 }, - { url = "https://files.pythonhosted.org/packages/bf/e7/22285852502e33071a8cf0ac814f8988480ec6db4754e067b8b9d0e92498/websockets-13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5", size = 155469 }, - { url = "https://files.pythonhosted.org/packages/68/d4/c8c7c1e5b40ee03c5cc235955b0fb1ec90e7e37685a5f69229ad4708dcde/websockets-13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd", size = 155717 }, - { url = "https://files.pythonhosted.org/packages/c9/e4/c50999b9b848b1332b07c7fd8886179ac395cb766fda62725d1539e7bc6c/websockets-13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02", size = 165379 }, - { url = "https://files.pythonhosted.org/packages/bc/49/4a4ad8c072f18fd79ab127650e47b160571aacfc30b110ee305ba25fffc9/websockets-13.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7", size = 164376 }, - { url = "https://files.pythonhosted.org/packages/af/9b/8c06d425a1d5a74fd764dd793edd02be18cf6fc3b1ccd1f29244ba132dc0/websockets-13.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096", size = 164753 }, - { url = "https://files.pythonhosted.org/packages/d5/5b/0acb5815095ff800b579ffc38b13ab1b915b317915023748812d24e0c1ac/websockets-13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084", size = 165051 }, - { url = "https://files.pythonhosted.org/packages/30/93/c3891c20114eacb1af09dedfcc620c65c397f4fd80a7009cd12d9457f7f5/websockets-13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3", size = 164489 }, - { url = "https://files.pythonhosted.org/packages/28/09/af9e19885539759efa2e2cd29b8b3f9eecef7ecefea40d46612f12138b36/websockets-13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9", size = 164438 }, - { url = "https://files.pythonhosted.org/packages/b6/08/6f38b8e625b3d93de731f1d248cc1493327f16cb45b9645b3e791782cff0/websockets-13.1-cp311-cp311-win32.whl", hash = "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f", size = 158710 }, - { url = "https://files.pythonhosted.org/packages/fb/39/ec8832ecb9bb04a8d318149005ed8cee0ba4e0205835da99e0aa497a091f/websockets-13.1-cp311-cp311-win_amd64.whl", hash = "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557", size = 159137 }, - { url = "https://files.pythonhosted.org/packages/df/46/c426282f543b3c0296cf964aa5a7bb17e984f58dde23460c3d39b3148fcf/websockets-13.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc", size = 157821 }, - { url = "https://files.pythonhosted.org/packages/aa/85/22529867010baac258da7c45848f9415e6cf37fef00a43856627806ffd04/websockets-13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49", size = 155480 }, - { url = "https://files.pythonhosted.org/packages/29/2c/bdb339bfbde0119a6e84af43ebf6275278698a2241c2719afc0d8b0bdbf2/websockets-13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd", size = 155715 }, - { url = "https://files.pythonhosted.org/packages/9f/d0/8612029ea04c5c22bf7af2fd3d63876c4eaeef9b97e86c11972a43aa0e6c/websockets-13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0", size = 165647 }, - { url = "https://files.pythonhosted.org/packages/56/04/1681ed516fa19ca9083f26d3f3a302257e0911ba75009533ed60fbb7b8d1/websockets-13.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6", size = 164592 }, - { url = "https://files.pythonhosted.org/packages/38/6f/a96417a49c0ed132bb6087e8e39a37db851c70974f5c724a4b2a70066996/websockets-13.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9", size = 165012 }, - { url = "https://files.pythonhosted.org/packages/40/8b/fccf294919a1b37d190e86042e1a907b8f66cff2b61e9befdbce03783e25/websockets-13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68", size = 165311 }, - { url = "https://files.pythonhosted.org/packages/c1/61/f8615cf7ce5fe538476ab6b4defff52beb7262ff8a73d5ef386322d9761d/websockets-13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14", size = 164692 }, - { url = "https://files.pythonhosted.org/packages/5c/f1/a29dd6046d3a722d26f182b783a7997d25298873a14028c4760347974ea3/websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf", size = 164686 }, - { url = "https://files.pythonhosted.org/packages/0f/99/ab1cdb282f7e595391226f03f9b498f52109d25a2ba03832e21614967dfa/websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c", size = 158712 }, - { url = "https://files.pythonhosted.org/packages/46/93/e19160db48b5581feac8468330aa11b7292880a94a37d7030478596cc14e/websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3", size = 159145 }, - { url = "https://files.pythonhosted.org/packages/51/20/2b99ca918e1cbd33c53db2cace5f0c0cd8296fc77558e1908799c712e1cd/websockets-13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6", size = 157828 }, - { url = "https://files.pythonhosted.org/packages/b8/47/0932a71d3d9c0e9483174f60713c84cee58d62839a143f21a2bcdbd2d205/websockets-13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708", size = 155487 }, - { url = "https://files.pythonhosted.org/packages/a9/60/f1711eb59ac7a6c5e98e5637fef5302f45b6f76a2c9d64fd83bbb341377a/websockets-13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418", size = 155721 }, - { url = "https://files.pythonhosted.org/packages/6a/e6/ba9a8db7f9d9b0e5f829cf626ff32677f39824968317223605a6b419d445/websockets-13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a", size = 165609 }, - { url = "https://files.pythonhosted.org/packages/c1/22/4ec80f1b9c27a0aebd84ccd857252eda8418ab9681eb571b37ca4c5e1305/websockets-13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f", size = 164556 }, - { url = "https://files.pythonhosted.org/packages/27/ac/35f423cb6bb15600438db80755609d27eda36d4c0b3c9d745ea12766c45e/websockets-13.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5", size = 164993 }, - { url = "https://files.pythonhosted.org/packages/31/4e/98db4fd267f8be9e52e86b6ee4e9aa7c42b83452ea0ea0672f176224b977/websockets-13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135", size = 165360 }, - { url = "https://files.pythonhosted.org/packages/3f/15/3f0de7cda70ffc94b7e7024544072bc5b26e2c1eb36545291abb755d8cdb/websockets-13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2", size = 164745 }, - { url = "https://files.pythonhosted.org/packages/a1/6e/66b6b756aebbd680b934c8bdbb6dcb9ce45aad72cde5f8a7208dbb00dd36/websockets-13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6", size = 164732 }, - { url = "https://files.pythonhosted.org/packages/35/c6/12e3aab52c11aeb289e3dbbc05929e7a9d90d7a9173958477d3ef4f8ce2d/websockets-13.1-cp313-cp313-win32.whl", hash = "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d", size = 158709 }, - { url = "https://files.pythonhosted.org/packages/41/d8/63d6194aae711d7263df4498200c690a9c39fb437ede10f3e157a6343e0d/websockets-13.1-cp313-cp313-win_amd64.whl", hash = "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2", size = 159144 }, - { url = "https://files.pythonhosted.org/packages/2d/75/6da22cb3ad5b8c606963f9a5f9f88656256fecc29d420b4b2bf9e0c7d56f/websockets-13.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238", size = 155499 }, - { url = "https://files.pythonhosted.org/packages/c0/ba/22833d58629088fcb2ccccedfae725ac0bbcd713319629e97125b52ac681/websockets-13.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5", size = 155737 }, - { url = "https://files.pythonhosted.org/packages/95/54/61684fe22bdb831e9e1843d972adadf359cf04ab8613285282baea6a24bb/websockets-13.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9", size = 157095 }, - { url = "https://files.pythonhosted.org/packages/fc/f5/6652fb82440813822022a9301a30afde85e5ff3fb2aebb77f34aabe2b4e8/websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6", size = 156701 }, - { url = "https://files.pythonhosted.org/packages/67/33/ae82a7b860fa8a08aba68818bdf7ff61f04598aa5ab96df4cd5a3e418ca4/websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a", size = 156654 }, - { url = "https://files.pythonhosted.org/packages/63/0b/a1b528d36934f833e20f6da1032b995bf093d55cb416b9f2266f229fb237/websockets-13.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23", size = 159192 }, - { url = "https://files.pythonhosted.org/packages/56/27/96a5cd2626d11c8280656c6c71d8ab50fe006490ef9971ccd154e0c42cd2/websockets-13.1-py3-none-any.whl", hash = "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f", size = 152134 }, +version = "14.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f4/1b/380b883ce05bb5f45a905b61790319a28958a9ab1e4b6b95ff5464b60ca1/websockets-14.1.tar.gz", hash = "sha256:398b10c77d471c0aab20a845e7a60076b6390bfdaac7a6d2edb0d2c59d75e8d8", size = 162840 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/91/b1b375dbd856fd5fff3f117de0e520542343ecaf4e8fc60f1ac1e9f5822c/websockets-14.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a0adf84bc2e7c86e8a202537b4fd50e6f7f0e4a6b6bf64d7ccb96c4cd3330b29", size = 161950 }, + { url = "https://files.pythonhosted.org/packages/61/8f/4d52f272d3ebcd35e1325c646e98936099a348374d4a6b83b524bded8116/websockets-14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90b5d9dfbb6d07a84ed3e696012610b6da074d97453bd01e0e30744b472c8179", size = 159601 }, + { url = "https://files.pythonhosted.org/packages/c4/b1/29e87b53eb1937992cdee094a0988aadc94f25cf0b37e90c75eed7123d75/websockets-14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2177ee3901075167f01c5e335a6685e71b162a54a89a56001f1c3e9e3d2ad250", size = 159854 }, + { url = "https://files.pythonhosted.org/packages/3f/e6/752a2f5e8321ae2a613062676c08ff2fccfb37dc837a2ee919178a372e8a/websockets-14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f14a96a0034a27f9d47fd9788913924c89612225878f8078bb9d55f859272b0", size = 168835 }, + { url = "https://files.pythonhosted.org/packages/60/27/ca62de7877596926321b99071639275e94bb2401397130b7cf33dbf2106a/websockets-14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f874ba705deea77bcf64a9da42c1f5fc2466d8f14daf410bc7d4ceae0a9fcb0", size = 167844 }, + { url = "https://files.pythonhosted.org/packages/7e/db/f556a1d06635c680ef376be626c632e3f2bbdb1a0189d1d1bffb061c3b70/websockets-14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9607b9a442392e690a57909c362811184ea429585a71061cd5d3c2b98065c199", size = 168157 }, + { url = "https://files.pythonhosted.org/packages/b3/bc/99e5f511838c365ac6ecae19674eb5e94201aa4235bd1af3e6fa92c12905/websockets-14.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bea45f19b7ca000380fbd4e02552be86343080120d074b87f25593ce1700ad58", size = 168561 }, + { url = "https://files.pythonhosted.org/packages/c6/e7/251491585bad61c79e525ac60927d96e4e17b18447cc9c3cfab47b2eb1b8/websockets-14.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:219c8187b3ceeadbf2afcf0f25a4918d02da7b944d703b97d12fb01510869078", size = 167979 }, + { url = "https://files.pythonhosted.org/packages/ac/98/7ac2e4eeada19bdbc7a3a66a58e3ebdf33648b9e1c5b3f08c3224df168cf/websockets-14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ad2ab2547761d79926effe63de21479dfaf29834c50f98c4bf5b5480b5838434", size = 167925 }, + { url = "https://files.pythonhosted.org/packages/ab/3d/09e65c47ee2396b7482968068f6e9b516221e1032b12dcf843b9412a5dfb/websockets-14.1-cp310-cp310-win32.whl", hash = "sha256:1288369a6a84e81b90da5dbed48610cd7e5d60af62df9851ed1d1d23a9069f10", size = 162831 }, + { url = "https://files.pythonhosted.org/packages/8a/67/59828a3d09740e6a485acccfbb66600632f2178b6ed1b61388ee96f17d5a/websockets-14.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0744623852f1497d825a49a99bfbec9bea4f3f946df6eb9d8a2f0c37a2fec2e", size = 163266 }, + { url = "https://files.pythonhosted.org/packages/97/ed/c0d03cb607b7fe1f7ff45e2cd4bb5cd0f9e3299ced79c2c303a6fff44524/websockets-14.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:449d77d636f8d9c17952628cc7e3b8faf6e92a17ec581ec0c0256300717e1512", size = 161949 }, + { url = "https://files.pythonhosted.org/packages/06/91/bf0a44e238660d37a2dda1b4896235d20c29a2d0450f3a46cd688f43b239/websockets-14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a35f704be14768cea9790d921c2c1cc4fc52700410b1c10948511039be824aac", size = 159606 }, + { url = "https://files.pythonhosted.org/packages/ff/b8/7185212adad274c2b42b6a24e1ee6b916b7809ed611cbebc33b227e5c215/websockets-14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b1f3628a0510bd58968c0f60447e7a692933589b791a6b572fcef374053ca280", size = 159854 }, + { url = "https://files.pythonhosted.org/packages/5a/8a/0849968d83474be89c183d8ae8dcb7f7ada1a3c24f4d2a0d7333c231a2c3/websockets-14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c3deac3748ec73ef24fc7be0b68220d14d47d6647d2f85b2771cb35ea847aa1", size = 169402 }, + { url = "https://files.pythonhosted.org/packages/bd/4f/ef886e37245ff6b4a736a09b8468dae05d5d5c99de1357f840d54c6f297d/websockets-14.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7048eb4415d46368ef29d32133134c513f507fff7d953c18c91104738a68c3b3", size = 168406 }, + { url = "https://files.pythonhosted.org/packages/11/43/e2dbd4401a63e409cebddedc1b63b9834de42f51b3c84db885469e9bdcef/websockets-14.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cf0ad281c979306a6a34242b371e90e891bce504509fb6bb5246bbbf31e7b6", size = 168776 }, + { url = "https://files.pythonhosted.org/packages/6d/d6/7063e3f5c1b612e9f70faae20ebaeb2e684ffa36cb959eb0862ee2809b32/websockets-14.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cc1fc87428c1d18b643479caa7b15db7d544652e5bf610513d4a3478dbe823d0", size = 169083 }, + { url = "https://files.pythonhosted.org/packages/49/69/e6f3d953f2fa0f8a723cf18cd011d52733bd7f6e045122b24e0e7f49f9b0/websockets-14.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f95ba34d71e2fa0c5d225bde3b3bdb152e957150100e75c86bc7f3964c450d89", size = 168529 }, + { url = "https://files.pythonhosted.org/packages/70/ff/f31fa14561fc1d7b8663b0ed719996cf1f581abee32c8fb2f295a472f268/websockets-14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9481a6de29105d73cf4515f2bef8eb71e17ac184c19d0b9918a3701c6c9c4f23", size = 168475 }, + { url = "https://files.pythonhosted.org/packages/f1/15/b72be0e4bf32ff373aa5baef46a4c7521b8ea93ad8b49ca8c6e8e764c083/websockets-14.1-cp311-cp311-win32.whl", hash = "sha256:368a05465f49c5949e27afd6fbe0a77ce53082185bbb2ac096a3a8afaf4de52e", size = 162833 }, + { url = "https://files.pythonhosted.org/packages/bc/ef/2d81679acbe7057ffe2308d422f744497b52009ea8bab34b6d74a2657d1d/websockets-14.1-cp311-cp311-win_amd64.whl", hash = "sha256:6d24fc337fc055c9e83414c94e1ee0dee902a486d19d2a7f0929e49d7d604b09", size = 163263 }, + { url = "https://files.pythonhosted.org/packages/55/64/55698544ce29e877c9188f1aee9093712411a8fc9732cca14985e49a8e9c/websockets-14.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ed907449fe5e021933e46a3e65d651f641975a768d0649fee59f10c2985529ed", size = 161957 }, + { url = "https://files.pythonhosted.org/packages/a2/b1/b088f67c2b365f2c86c7b48edb8848ac27e508caf910a9d9d831b2f343cb/websockets-14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:87e31011b5c14a33b29f17eb48932e63e1dcd3fa31d72209848652310d3d1f0d", size = 159620 }, + { url = "https://files.pythonhosted.org/packages/c1/89/2a09db1bbb40ba967a1b8225b07b7df89fea44f06de9365f17f684d0f7e6/websockets-14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bc6ccf7d54c02ae47a48ddf9414c54d48af9c01076a2e1023e3b486b6e72c707", size = 159852 }, + { url = "https://files.pythonhosted.org/packages/ca/c1/f983138cd56e7d3079f1966e81f77ce6643f230cd309f73aa156bb181749/websockets-14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9777564c0a72a1d457f0848977a1cbe15cfa75fa2f67ce267441e465717dcf1a", size = 169675 }, + { url = "https://files.pythonhosted.org/packages/c1/c8/84191455d8660e2a0bdb33878d4ee5dfa4a2cedbcdc88bbd097303b65bfa/websockets-14.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a655bde548ca98f55b43711b0ceefd2a88a71af6350b0c168aa77562104f3f45", size = 168619 }, + { url = "https://files.pythonhosted.org/packages/8d/a7/62e551fdcd7d44ea74a006dc193aba370505278ad76efd938664531ce9d6/websockets-14.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3dfff83ca578cada2d19e665e9c8368e1598d4e787422a460ec70e531dbdd58", size = 169042 }, + { url = "https://files.pythonhosted.org/packages/ad/ed/1532786f55922c1e9c4d329608e36a15fdab186def3ca9eb10d7465bc1cc/websockets-14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6a6c9bcf7cdc0fd41cc7b7944447982e8acfd9f0d560ea6d6845428ed0562058", size = 169345 }, + { url = "https://files.pythonhosted.org/packages/ea/fb/160f66960d495df3de63d9bcff78e1b42545b2a123cc611950ffe6468016/websockets-14.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4b6caec8576e760f2c7dd878ba817653144d5f369200b6ddf9771d64385b84d4", size = 168725 }, + { url = "https://files.pythonhosted.org/packages/cf/53/1bf0c06618b5ac35f1d7906444b9958f8485682ab0ea40dee7b17a32da1e/websockets-14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eb6d38971c800ff02e4a6afd791bbe3b923a9a57ca9aeab7314c21c84bf9ff05", size = 168712 }, + { url = "https://files.pythonhosted.org/packages/e5/22/5ec2f39fff75f44aa626f86fa7f20594524a447d9c3be94d8482cd5572ef/websockets-14.1-cp312-cp312-win32.whl", hash = "sha256:1d045cbe1358d76b24d5e20e7b1878efe578d9897a25c24e6006eef788c0fdf0", size = 162838 }, + { url = "https://files.pythonhosted.org/packages/74/27/28f07df09f2983178db7bf6c9cccc847205d2b92ced986cd79565d68af4f/websockets-14.1-cp312-cp312-win_amd64.whl", hash = "sha256:90f4c7a069c733d95c308380aae314f2cb45bd8a904fb03eb36d1a4983a4993f", size = 163277 }, + { url = "https://files.pythonhosted.org/packages/34/77/812b3ba5110ed8726eddf9257ab55ce9e85d97d4aa016805fdbecc5e5d48/websockets-14.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:3630b670d5057cd9e08b9c4dab6493670e8e762a24c2c94ef312783870736ab9", size = 161966 }, + { url = "https://files.pythonhosted.org/packages/8d/24/4fcb7aa6986ae7d9f6d083d9d53d580af1483c5ec24bdec0978307a0f6ac/websockets-14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36ebd71db3b89e1f7b1a5deaa341a654852c3518ea7a8ddfdf69cc66acc2db1b", size = 159625 }, + { url = "https://files.pythonhosted.org/packages/f8/47/2a0a3a2fc4965ff5b9ce9324d63220156bd8bedf7f90824ab92a822e65fd/websockets-14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5b918d288958dc3fa1c5a0b9aa3256cb2b2b84c54407f4813c45d52267600cd3", size = 159857 }, + { url = "https://files.pythonhosted.org/packages/dd/c8/d7b425011a15e35e17757e4df75b25e1d0df64c0c315a44550454eaf88fc/websockets-14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00fe5da3f037041da1ee0cf8e308374e236883f9842c7c465aa65098b1c9af59", size = 169635 }, + { url = "https://files.pythonhosted.org/packages/93/39/6e3b5cffa11036c40bd2f13aba2e8e691ab2e01595532c46437b56575678/websockets-14.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8149a0f5a72ca36720981418eeffeb5c2729ea55fa179091c81a0910a114a5d2", size = 168578 }, + { url = "https://files.pythonhosted.org/packages/cf/03/8faa5c9576299b2adf34dcccf278fc6bbbcda8a3efcc4d817369026be421/websockets-14.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77569d19a13015e840b81550922056acabc25e3f52782625bc6843cfa034e1da", size = 169018 }, + { url = "https://files.pythonhosted.org/packages/8c/05/ea1fec05cc3a60defcdf0bb9f760c3c6bd2dd2710eff7ac7f891864a22ba/websockets-14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cf5201a04550136ef870aa60ad3d29d2a59e452a7f96b94193bee6d73b8ad9a9", size = 169383 }, + { url = "https://files.pythonhosted.org/packages/21/1d/eac1d9ed787f80754e51228e78855f879ede1172c8b6185aca8cef494911/websockets-14.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:88cf9163ef674b5be5736a584c999e98daf3aabac6e536e43286eb74c126b9c7", size = 168773 }, + { url = "https://files.pythonhosted.org/packages/0e/1b/e808685530185915299740d82b3a4af3f2b44e56ccf4389397c7a5d95d39/websockets-14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:836bef7ae338a072e9d1863502026f01b14027250a4545672673057997d5c05a", size = 168757 }, + { url = "https://files.pythonhosted.org/packages/b6/19/6ab716d02a3b068fbbeb6face8a7423156e12c446975312f1c7c0f4badab/websockets-14.1-cp313-cp313-win32.whl", hash = "sha256:0d4290d559d68288da9f444089fd82490c8d2744309113fc26e2da6e48b65da6", size = 162834 }, + { url = "https://files.pythonhosted.org/packages/6c/fd/ab6b7676ba712f2fc89d1347a4b5bdc6aa130de10404071f2b2606450209/websockets-14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8621a07991add373c3c5c2cf89e1d277e49dc82ed72c75e3afc74bd0acc446f0", size = 163277 }, + { url = "https://files.pythonhosted.org/packages/fb/cd/382a05a1ba2a93bd9fb807716a660751295df72e77204fb130a102fcdd36/websockets-14.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5dc25a9dbd1a7f61eca4b7cb04e74ae4b963d658f9e4f9aad9cd00b688692c8", size = 159633 }, + { url = "https://files.pythonhosted.org/packages/b7/a0/fa7c62e2952ef028b422fbf420f9353d9dd4dfaa425de3deae36e98c0784/websockets-14.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:04a97aca96ca2acedf0d1f332c861c5a4486fdcba7bcef35873820f940c4231e", size = 159867 }, + { url = "https://files.pythonhosted.org/packages/c1/94/954b4924f868db31d5f0935893c7a8446515ee4b36bb8ad75a929469e453/websockets-14.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df174ece723b228d3e8734a6f2a6febbd413ddec39b3dc592f5a4aa0aff28098", size = 161121 }, + { url = "https://files.pythonhosted.org/packages/7a/2e/f12bbb41a8f2abb76428ba4fdcd9e67b5b364a3e7fa97c88f4d6950aa2d4/websockets-14.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:034feb9f4286476f273b9a245fb15f02c34d9586a5bc936aff108c3ba1b21beb", size = 160731 }, + { url = "https://files.pythonhosted.org/packages/13/97/b76979401f2373af1fe3e08f960b265cecab112e7dac803446fb98351a52/websockets-14.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c308dabd2b380807ab64b62985eaccf923a78ebc572bd485375b9ca2b7dc7", size = 160681 }, + { url = "https://files.pythonhosted.org/packages/39/9c/16916d9a436c109a1d7ba78817e8fee357b78968be3f6e6f517f43afa43d/websockets-14.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5a42d3ecbb2db5080fc578314439b1d79eef71d323dc661aa616fb492436af5d", size = 163316 }, + { url = "https://files.pythonhosted.org/packages/b0/0b/c7e5d11020242984d9d37990310520ed663b942333b83a033c2f20191113/websockets-14.1-py3-none-any.whl", hash = "sha256:4d4fc827a20abe6d544a119896f6b78ee13fe81cbfef416f3f2ddf09a03f0e2e", size = 156277 }, ] [[package]] @@ -1815,9 +1845,9 @@ wheels = [ [[package]] name = "zipp" -version = "3.20.2" +version = "3.21.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/bf/5c0000c44ebc80123ecbdddba1f5dcd94a5ada602a9c225d84b5aaa55e86/zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29", size = 24199 } +sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545 } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/8b/5ba542fa83c90e09eac972fc9baca7a88e7e7ca4b221a89251954019308b/zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", size = 9200 }, + { url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630 }, ] From 45ab05b2523b6be141435d89e7e2b4f52181d959 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Mon, 13 Jan 2025 14:21:53 -0500 Subject: [PATCH 275/333] style: update linting configuration for ruff 0.9 (#319) --- .pre-commit-config.yaml | 2 +- pyproject.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6d11bd4e32..7a08dbbff2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.8.4" + rev: "v0.9.1" hooks: # Run the linter - id: ruff diff --git a/pyproject.toml b/pyproject.toml index 9b085a7897..1443b99e2b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -241,8 +241,8 @@ select = [ # Base linting rule selections. # The team have chosen to only use type-checking blocks when necessary to prevent circular imports. # As such, the only enabled type-checking checks are those that warn of an import that needs to be # removed from a type-checking block. - "TCH004", # Remove imports from type-checking guard blocks if used at runtime - "TCH005", # Delete empty type-checking blocks + "TC004", # Remove imports from type-checking guard blocks if used at runtime + "TC005", # Delete empty type-checking blocks "ARG", # Unused arguments "PTH", # Migrate to pathlib "FIX", # All TODOs, FIXMEs, etc. should be turned into issues instead. From 55bf1effbffd2c23ff7b5c62d0f90eb46ed27609 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Mon, 13 Jan 2025 14:24:14 -0500 Subject: [PATCH 276/333] fix: use uv tool run for pre-commit if not global (#300) Issue found here: https://github.com/canonical/craft-store/pull/241#pullrequestreview-2502863941 --- common.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common.mk b/common.mk index 1483ce6c21..3c3a146b28 100644 --- a/common.mk +++ b/common.mk @@ -62,9 +62,10 @@ setup-docs: install-uv ##- Set up a documentation-only environment .PHONY: setup-precommit setup-precommit: install-uv ##- Set up pre-commit hooks in this repository. ifeq ($(shell which pre-commit),) - uv tool install pre-commit -endif + uv tool run pre-commit install +else pre-commit install +endif .PHONY: clean clean: ## Clean up the development environment From 170dd5ea3a23b1068034f4bd409c70db8b7cb2b1 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Mon, 13 Jan 2025 15:36:08 -0500 Subject: [PATCH 277/333] fix(common.mk): freeze UV by default. (#322) --- common.mk | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/common.mk b/common.mk index 3c3a146b28..6407b00c14 100644 --- a/common.mk +++ b/common.mk @@ -16,6 +16,9 @@ endif PRETTIER=npm exec --package=prettier -- prettier PRETTIER_FILES=**.yaml **.yml **.json **.json5 **.css **.md +# By default we should not update the uv lock file here. +export UV_FROZEN := true + .DEFAULT_GOAL := help .ONESHELL: @@ -45,19 +48,19 @@ help: ## Show this help. .PHONY: setup setup: install-uv setup-precommit ## Set up a development environment - uv sync --frozen --all-extras + uv sync --all-extras .PHONY: setup-tests setup-tests: install-uv install-build-deps ##- Set up a testing environment without linters - uv sync --frozen + uv sync .PHONY: setup-lint setup-lint: install-uv install-shellcheck install-pyright install-lint-build-deps ##- Set up a linting-only environment - uv sync --frozen --no-install-workspace --extra lint --extra types + uv sync --no-install-workspace --extra lint --extra types .PHONY: setup-docs setup-docs: install-uv ##- Set up a documentation-only environment - uv sync --frozen --no-dev --no-install-workspace --extra docs + uv sync --no-dev --no-install-workspace --extra docs .PHONY: setup-precommit setup-precommit: install-uv ##- Set up pre-commit hooks in this repository. From 66815218aa8f57b98cd129e48635accda0388ca0 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Mon, 13 Jan 2025 15:36:39 -0500 Subject: [PATCH 278/333] style(pyproject): make git_describe_command an array (#321) While setuptools_scm accepts a string, the schema only notes an array, so toml schema linters will complain about this. https://json.schemastore.org/partial-setuptools-scm.json Co-authored-by: Imani Pelton <imani.pelton@canonical.com> --- pyproject.toml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1443b99e2b..e4a7df29b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -99,7 +99,16 @@ version_scheme = "post-release" # deviations from the default 'git describe' command: # - only match annotated tags # - only match tags formatted as 'X.Y.Z' -git_describe_command = "git describe --dirty --long --match '[0-9]*.[0-9]*.[0-9]*' --exclude '*[^0-9.]*'" +git_describe_command = [ + "git", + "describe", + "--dirty", + "--long", + "--match", + "[0-9]*.[0-9]*.[0-9]*", + "--exclude", + "*[^0-9.]*", +] [tool.setuptools.packages.find] include = ["*craft*"] From 6f78e1a8efa8f2d937828b21552d6b0eac365e1a Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Mon, 13 Jan 2025 16:46:58 -0500 Subject: [PATCH 279/333] feat: remove tox.ini (#310) --- tox.ini | 149 -------------------------------------------------------- 1 file changed, 149 deletions(-) delete mode 100644 tox.ini diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 17afaf5153..0000000000 --- a/tox.ini +++ /dev/null @@ -1,149 +0,0 @@ -[tox] -env_list = # Environments to run when called with no parameters. - format-{ruff,codespell} - pre-commit - lint-{ruff,mypy,pyright,shellcheck,codespell,docs} - unit-py3.{10,12} - integration-py3.10 -# Integration tests probably take a while, so we're only running them on Python -# 3.10, which is included in core22. -minversion = 4.6 -# Tox will use these requirements to bootstrap a venv if necessary. -# tox-igore-env-name-mismatch allows us to have one virtualenv for all linting. -# By setting requirements here, we make this INI file compatible with older -# versions of tox. Tox >= 3.8 will automatically provision the version provided -# inside of a virtual environment, so users of Ubuntu >= focal can simply -# install tox from apt. Older than that, the user gets an upgrade warning. -requires = - # renovate: datasource=pypi - tox-ignore-env-name-mismatch>=0.2.0.post2 - # renovate: datasource=pypi - tox-gh==1.4.4 -# Allow tox to access the user's $TMPDIR environment variable if set. -# This workaround is required to avoid circular dependencies for TMPDIR, -# since tox will otherwise attempt to use the environment's TMPDIR variable. -user_tmp_dir = {env:TMPDIR} - -[testenv] # Default config for all environments. Overridable in each env. -# We have many tests that create temporary files. Unless the user has set a -# TMPDIR, this will prefer putting those temp files in $XDG_RUNTIME_DIR, -# which will speed up those tests since they'll run on a ramdisk. -env_tmp_dir = {user_tmp_dir:{env:XDG_RUNTIME_DIR:{work_dir}}}/tox_tmp/{env_name} -set_env = - TMPDIR={env_tmp_dir} - COVERAGE_FILE={env_tmp_dir}/.coverage_{env_name} -pass_env = - CI - CRAFT_* - PYTEST_ADDOPTS - -[test] # Base configuration for unit and integration tests -package = editable -extras = dev -allowlist_externals = mkdir -commands_pre = mkdir -p {tox_root}/results - -[testenv:{unit,integration}-py3.{8,9,10,11,12}] # Configuration for all tests using pytest -base = testenv, test -description = - unit: Run unit tests with pytest - integration: Run integration tests with pytest -labels = - py3.{10,12}: tests - unit-py3.{10,12}: unit-tests - integration-py3.{10,12}: integration-tests -change_dir = - unit: tests/unit - integration: tests/integration -commands = pytest {tty:--color=yes} --cov={tox_root}/starcraft --cov-config={tox_root}/pyproject.toml --cov-report=xml:{tox_root}/results/coverage-{env_name}.xml --junit-xml={tox_root}/results/test-results-{env_name}.xml {posargs} - -[lint] # Standard linting configuration -package = editable -extras = lint -env_dir = {work_dir}/linting -runner = ignore_env_name_mismatch -allowlist_externals = - codespell: codespell - shellcheck: bash, xargs - ruff: ruff - -[shellcheck] -find = git ls-files -filter = file --mime-type -Nnf- | grep shellscript | cut -f1 -d: - -[testenv:lint-{ruff,shellcheck,codespell}] -description = Lint the source code -base = testenv, lint -labels = lint -commands_pre = - shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' -commands = - ruff: ruff format --check --diff {posargs:.} - ruff: ruff check {posargs:.} - shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck - codespell: codespell --toml {tox_root}/pyproject.toml {posargs} - -[testenv:lint-{mypy,pyright}] -description = Static type checking -base = testenv, lint -env_dir = {work_dir}/typing -extras = dev, types -labels = lint, type -allowlist_externals = - mypy: mkdir -commands_pre = - mypy: mkdir -p {tox_root}/.mypy_cache -commands = - pyright: pyright {posargs} - mypy: mypy --install-types --non-interactive {posargs:.} - -[testenv:format-{ruff,codespell}] -description = Automatically format source code -base = testenv, lint -labels = format -commands = - ruff: ruff format --respect-gitignore {posargs:.} - ruff: ruff check --fix --respect-gitignore {posargs} . - codespell: codespell --toml {tox_root}/pyproject.toml --write-changes {posargs} - -[testenv:pre-commit] -base = -deps = pre-commit -package = skip -no_package = true -env_dir = {work_dir}/pre-commit -runner = ignore_env_name_mismatch -description = Run pre-commit on staged files or arbitrary pre-commit commands (tox run -e pre-commit -- [args]) -commands = pre-commit {posargs:run} - -[docs] # Sphinx documentation configuration -extras = docs -package = editable -no_package = true -env_dir = {work_dir}/docs -runner = ignore_env_name_mismatch -source_dir = {tox_root}/{project_name} - -[testenv:build-docs] -description = Build sphinx documentation -base = docs -allowlist_externals = bash -commands_pre = bash -c 'if [[ ! -e docs ]];then echo "No docs directory. Run `tox run -e sphinx-quickstart` to create one.;";return 1;fi' -# "-W" is to treat warnings as errors -commands = sphinx-build {posargs:-b html} -W {tox_root}/docs {tox_root}/docs/_build - -[testenv:autobuild-docs] -description = Build documentation with an autoupdating server -base = docs -commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} -W --watch {source_dir} {tox_root}/docs {tox_root}/docs/_build - -[lint-docs] -find = git ls-files - -[testenv:lint-docs] -description = Lint the documentation with sphinx-lint -base = docs -labels = lint -allowlist_externals = bash, xargs -commands_pre = bash -c '{[lint-docs]find} > {env_tmp_dir}/lint_docs_files' -commands = xargs --no-run-if-empty --arg-file {env_tmp_dir}/lint_docs_files sphinx-lint --max-line-length 88 --enable all {posargs} From f84c2dfbfbf0894840c127a12bb67aef7f45c077 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 22:06:46 -0500 Subject: [PATCH 280/333] build(deps): lock file maintenance (#326) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- uv.lock | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/uv.lock b/uv.lock index 9ed93cf6be..617c370115 100644 --- a/uv.lock +++ b/uv.lock @@ -678,11 +678,11 @@ wheels = [ [[package]] name = "more-itertools" -version = "10.5.0" +version = "10.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/78/65922308c4248e0eb08ebcbe67c95d48615cc6f27854b6f2e57143e9178f/more-itertools-10.5.0.tar.gz", hash = "sha256:5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6", size = 121020 } +sdist = { url = "https://files.pythonhosted.org/packages/88/3b/7fa1fe835e2e93fd6d7b52b2f95ae810cf5ba133e1845f726f5a992d62c2/more-itertools-10.6.0.tar.gz", hash = "sha256:2cd7fad1009c31cc9fb6a035108509e6547547a7a738374f10bd49a09eb3ee3b", size = 125009 } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/7e/3a64597054a70f7c86eb0a7d4fc315b8c1ab932f64883a297bdffeb5f967/more_itertools-10.5.0-py3-none-any.whl", hash = "sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef", size = 60952 }, + { url = "https://files.pythonhosted.org/packages/23/62/0fe302c6d1be1c777cab0616e6302478251dfbf9055ad426f5d0def75c89/more_itertools-10.6.0-py3-none-any.whl", hash = "sha256:6eb054cb4b6db1473f6e15fcc676a08e4732548acd47c708f0e179c2c7c01e89", size = 63038 }, ] [[package]] @@ -1493,7 +1493,6 @@ wheels = [ [[package]] name = "starcraft" -version = "0.0.post282+g68ad84a" source = { editable = "." } [package.optional-dependencies] From 7fbfea184149dbd8296d4e40e00c1e74f24c5bd1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 22:07:25 -0500 Subject: [PATCH 281/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.2 (#316) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7a08dbbff2..9d58fe3166 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.9.1" + rev: "v0.9.2" hooks: # Run the linter - id: ruff From 4c45c0ed1da474bb34dcafb7156a2e0ca9b57d3e Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Mon, 20 Jan 2025 17:19:23 -0500 Subject: [PATCH 282/333] build(deps): remove pyright (#327) We install it separately (either from snap from uv) anyway. --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e4a7df29b8..4f137cb5b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,7 +68,6 @@ dev-dependencies = [ "pytest-cov~=6.0", "pytest-mock~=3.12", "mypy[reports]~=1.14.1", - "pyright==1.1.391", "types-Pygments", "types-colorama", "types-setuptools", From 9b08557dae27ea25539f99e184ecd7abb3fbcae3 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Wed, 22 Jan 2025 10:54:28 -0500 Subject: [PATCH 283/333] fix(common.mk): docs ignores (#324) See: https://github.com/canonical/charmcraft/pull/2096 --- common.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.mk b/common.mk index 6407b00c14..9117213ad9 100644 --- a/common.mk +++ b/common.mk @@ -163,7 +163,7 @@ lint-docs: ##- Lint the documentation ifneq ($(CI),) @echo ::group::$@ endif - uv run --extra docs sphinx-lint --max-line-length 88 --enable all $(DOCS) + uv run --extra docs sphinx-lint --max-line-length 88 --ignore docs/reference/commands --ignore docs/_build --enable all $(DOCS) ifneq ($(CI),) @echo ::endgroup:: endif From fbd7c43534acdea4421e12831686faeed54a3fe1 Mon Sep 17 00:00:00 2001 From: Michael DuBelko <michael.dubelko@canonical.com> Date: Wed, 22 Jan 2025 18:59:38 -0800 Subject: [PATCH 284/333] docs: make minor improvements to release note template (#328) - For notes, add text describing how present tense with "now" is permissible, and add examples that demonstrate it. - Make it clearer that the items in the fixed issue list should be links. --- docs/release-notes/index.rst | 49 ++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/docs/release-notes/index.rst b/docs/release-notes/index.rst index 54ecf5dc81..c9ded895fc 100644 --- a/docs/release-notes/index.rst +++ b/docs/release-notes/index.rst @@ -3,8 +3,8 @@ Release notes ============= -This page lists past release notes for Starcraft, summarising new features, bug -fixes and backwards-incompatible changes in each version. It also contains the +This page lists the notes for past releases of Starcraft, which summarise new features, +bug fixes and backwards-incompatible changes in each version. It also contains the release and support policies for Starcraft. @@ -141,15 +141,17 @@ development keeps pace with the OS's new releases and support lifecycle.> them to provide users and authors an avenue for discoverability and feedback."> - <Paragraph 2: Present the new behaviour or feature. In words, *show* what the - feature is and make a case for how the reader could benefit from it. Centre - the user whenever possible ("you"), and speak on behalf of Canonical ("we"). - Prefer general, simple usage over complex applications. Use past tense. For - example, "We understand that some authors may not want to have their snaps - publicly ranked. If you prefer to disable ranking for your snap, we added the - ``feedback`` key in Snapcraft recipes, which contains child keys for - controlling many of the rating and feedback features in the store. You can - declare ``voting: false`` to disable voting".> + <Paragraph 2: Present the new behaviour or feature. In words, *show* what the feature + is and make a case for how the reader could benefit from it. Centre the user whenever + possible ("you"), and speak on behalf of Canonical ("we"). Prefer general, simple + usage over complex applications. Use past tense, or the form "is now [x]" or "now + [does x]". For example, "We understand that some authors may not want to have their + snaps publicly ranked. If you prefer to disable ranking for your snap, we added the + ``feedback`` key in Snapcraft recipes, which contains child keys for controlling many + of the rating and feedback features in the store. You can declare ``voting: false`` to + disable voting." Another example: "The Maven and Ant plugins now generate the more + standard path to the Java runtime executable instead of an unconventional one, making + their locations more predictable."> <Paragraph 3, optional: Provide a call to action. This could take several forms, such as a call to immediately perform a relevant action in Starcraft, @@ -168,10 +170,12 @@ development keeps pace with the OS's new releases and support lifecycle.> <Feature A> ~~~~~~~~~~~ - <Add a short list of changes to the feature. Keep each item brief and for the - most part descriptive. There's little need to sell the change or give a - detailed reason. Use past tense. For example, "- Made the error message for - ``method()`` more descriptive and recommend a likely remedy."> + <Add a short list of changes to the feature. Keep each item brief and for the most + part descriptive. There's little need to sell the change or give a detailed reason. + Use past tense, or the form "is now [x]" or "now [does x]". For example, "- Made the + error message for ``method()`` more descriptive and recommend a likely remedy." + Another example: "- The GET method on the profiles API now returns the user creation + date."> Backwards-incompatible changes @@ -230,7 +234,7 @@ development keeps pace with the OS's new releases and support lifecycle.> <Feature D> - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~ <Future deprecation: Use the same format as backwards-incompatible changes, but use future tense to describe what we *intend* and *plan* to do in @@ -255,8 +259,8 @@ development keeps pace with the OS's new releases and support lifecycle.> See individual issue links for any mitigations. - - <Ticket ID> <Title> - - <Ticket ID> <Title> + - `ID <link>`_ <Title> + - `ID <link>`_ <Title> Fixed bugs and issues @@ -264,8 +268,8 @@ development keeps pace with the OS's new releases and support lifecycle.> The following issues have been resolved in Starcraft 2.0: - - <Ticket ID> <Title> - - <Ticket ID> <Title> + - `ID <link>`_ <Title> + - `ID <link>`_ <Title> Contributors @@ -274,4 +278,7 @@ development keeps pace with the OS's new releases and support lifecycle.> We would like to express a big thank you to all the people who contributed to this release. - `@alex <>`_, `@blair <>`_, `@cam <>`_, `@devin <>`_ + :literalref:`@alex<https://example.com/alex>`, + :literalref:`@blair<https://example.com/blair>`, + :literalref:`@cam<https://example.com/cam>`, + and :literalref:`@devin<https://example.com/devin>` From de0d3082b0a3e898755f595ab67c740f2ff485ba Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani.pelton@canonical.com> Date: Thu, 23 Jan 2025 22:12:11 -0500 Subject: [PATCH 285/333] docs: fix spacing errors in README (#331) --- README.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.rst b/README.rst index 2acce3c79d..d417a10497 100644 --- a/README.rst +++ b/README.rst @@ -28,6 +28,7 @@ Migrate existing projects #. Update this guide as you go along, if something is unclear or missing. #. Use ruff. + #. Pull in the bare minimum ``pyproject.toml`` needed to use ruff. #. Make your codebase pass with ruff. Commit after each step: @@ -40,8 +41,10 @@ Migrate existing projects with: - ``ruff check --fix`` - ``ruff format`` + #. Modify top-level files in your project to match what's in Starbase as closely as possible. + #. ``Makefile`` - Ensure you use ``uv`` and at least have the same targets: - ``setup`` @@ -56,7 +59,9 @@ Migrate existing projects #. ``README`` - If your readme is .md, convert to .rst with pandoc: ``pandoc -o README.rst README.md`` Don't worry about making the contents match, Starbase's is very specific. + #. Run all the linters: ``make lint`` + #. ``mypy``: - Mypy checks the same things as ``ruff``'s ``ANNXXX`` checks, but From 3b7289b68bbed1452eac3318e8f3c45dfafc2d0b Mon Sep 17 00:00:00 2001 From: Tiago Nobrega <tiago.nobrega@canonical.com> Date: Sat, 25 Jan 2025 19:40:45 -0300 Subject: [PATCH 286/333] fix(common.mk): fix glob of prettier files (#332) --- common.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.mk b/common.mk index 9117213ad9..dfdb1dd30e 100644 --- a/common.mk +++ b/common.mk @@ -14,7 +14,7 @@ else endif PRETTIER=npm exec --package=prettier -- prettier -PRETTIER_FILES=**.yaml **.yml **.json **.json5 **.css **.md +PRETTIER_FILES="**/*.{yaml,yml,json,json5,css,md}" # By default we should not update the uv lock file here. export UV_FROZEN := true From d3d4189c84430bb8cbc1690d698ca13b39c7e388 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani.pelton@canonical.com> Date: Tue, 28 Jan 2025 09:32:03 -0500 Subject: [PATCH 287/333] docs: fix some formatting errors in README (#336) --- README.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.rst b/README.rst index d417a10497..3ca5ac90d4 100644 --- a/README.rst +++ b/README.rst @@ -39,6 +39,7 @@ Migrate existing projects #. Replace use of black, flake8, pydocstyle, isort, and pylint in Makefile/CI with: + - ``ruff check --fix`` - ``ruff format`` @@ -57,7 +58,9 @@ Migrate existing projects #. ``pyproject.toml`` - Expand from just the ruff things: move things into here from your ``setup.py``, ``setup.cfg``, and ``requirements.*.txt``. #. ``README`` - If your readme is .md, convert to .rst with pandoc: + ``pandoc -o README.rst README.md`` + Don't worry about making the contents match, Starbase's is very specific. #. Run all the linters: ``make lint`` @@ -81,6 +84,7 @@ Migrate existing projects sense upstream. #. Bring in remaining top-level files: + - .editorconfig - .pre-commit-config.yaml - .shellcheckrc @@ -106,6 +110,7 @@ Create a new project #. `Use this template`_ to create your repository. #. Sync the git history with starbase to ease future merging: + - ``git clone <your-repo>`` - ``git remote add starbase git@github.com:canonical/starbase.git`` - ``git merge --allow-unrelated-histories starbase/main`` From 0bb01068ebed8b7674ba91f376cf6900852fc873 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Tue, 28 Jan 2025 09:33:18 -0500 Subject: [PATCH 288/333] build!: switch from using extras to dependency groups (#330) * build: switch from using extras to dependency groups Now that PEP 735 is finalised and we have a standard for dependency groups, we should move away from using extras to using those. https://packaging.python.org/en/latest/specifications/dependency-groups/ * build(docs): use uv in readthedocs This adjusts the readthedocs to use uv, which speeds up the RTD build time fairly significantly. The old RTD configuration also would not work now that we've moved from extras to dependency groups. * ci: fix the pull request template to use make --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .readthedocs.yaml | 16 ++++--- common.mk | 14 +++--- pyproject.toml | 26 +++++----- uv.lock | 82 +++++++++++--------------------- 5 files changed, 59 insertions(+), 81 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ca01e6b66e..2ad1a1da3d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,5 @@ - [ ] Have you followed the guidelines for contributing? - [ ] Have you signed the [CLA](http://www.ubuntu.com/legal/contributors/)? -- [ ] Have you successfully run `tox`? +- [ ] Have you successfully run `make lint && make test`? --- diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 78b2a7db59..2d4b82d202 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -18,10 +18,12 @@ build: os: ubuntu-24.04 tools: python: "3.12" - -python: - install: - - method: pip - path: . - extra_requirements: - - docs + jobs: + post_system_dependencies: + - asdf plugin add uv + - asdf install uv latest + - asdf global uv latest + create_environment: + - uv venv "${READTHEDOCS_VIRTUALENV_PATH}" + install: + - UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv sync --frozen --group docs diff --git a/common.mk b/common.mk index dfdb1dd30e..03e0fc1ade 100644 --- a/common.mk +++ b/common.mk @@ -48,7 +48,7 @@ help: ## Show this help. .PHONY: setup setup: install-uv setup-precommit ## Set up a development environment - uv sync --all-extras + uv sync --all-groups .PHONY: setup-tests setup-tests: install-uv install-build-deps ##- Set up a testing environment without linters @@ -56,11 +56,11 @@ setup-tests: install-uv install-build-deps ##- Set up a testing environment with .PHONY: setup-lint setup-lint: install-uv install-shellcheck install-pyright install-lint-build-deps ##- Set up a linting-only environment - uv sync --no-install-workspace --extra lint --extra types + uv sync --no-install-workspace --group lint --group types .PHONY: setup-docs setup-docs: install-uv ##- Set up a documentation-only environment - uv sync --no-dev --no-install-workspace --extra docs + uv sync --no-dev --group docs .PHONY: setup-precommit setup-precommit: install-uv ##- Set up pre-commit hooks in this repository. @@ -105,7 +105,7 @@ ifneq ($(CI),) endif .PHONY: lint-codespell -lint-codespell: ##- Check spelling with codespell +lint-codespell: install-codespell ##- Check spelling with codespell ifneq ($(CI),) @echo ::group::$@ endif @@ -163,7 +163,7 @@ lint-docs: ##- Lint the documentation ifneq ($(CI),) @echo ::group::$@ endif - uv run --extra docs sphinx-lint --max-line-length 88 --ignore docs/reference/commands --ignore docs/_build --enable all $(DOCS) + uv run --group docs sphinx-lint --max-line-length 88 --ignore docs/reference/commands --ignore docs/_build --enable all $(DOCS) ifneq ($(CI),) @echo ::endgroup:: endif @@ -199,11 +199,11 @@ test-coverage: ## Generate coverage report .PHONY: docs docs: ## Build documentation - uv run --extra docs sphinx-build -b html -W $(DOCS) $(DOCS)/_build + uv run --group docs sphinx-build -b html -W $(DOCS) $(DOCS)/_build .PHONY: docs-auto docs-auto: ## Build and host docs with sphinx-autobuild - uv run --extra docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W $(DOCS) $(DOCS)/_build + uv run --group docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W $(DOCS) $(DOCS)/_build .PHONY: pack-pip pack-pip: ##- Build packages for pip (sdist, wheel) diff --git a/pyproject.toml b/pyproject.toml index 4f137cb5b5..c74aad7250 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ requires-python = ">=3.10" [project.scripts] starcraft-hello = "starcraft:hello" -[project.optional-dependencies] +[dependency-groups] lint = [ "yamllint~=1.34", ] @@ -34,11 +34,21 @@ docs = [ "sphinx-toolbox~=3.5", "sphinx-lint==1.0.0", ] +dev = [ + "build>=0.7.0", + "coverage[toml]~=7.4", + "pytest~=8.0", + "pytest-cov~=6.0", + "pytest-mock~=3.12", + "mypy[reports]~=1.14.1", + "types-Pygments", + "types-colorama", + "types-setuptools", +] [tool.uv] constraint-dependencies = [ # Basic constraints to allow --resolution=lowest - "build>=0.7.0", "cffi>=1.15", "iniconfig>=1.1.0", "httplib2>=0.20.0", @@ -61,17 +71,7 @@ constraint-dependencies = [ "webencodings>=0.4.0", "wheel>=0.38", ] -dev-dependencies = [ - "build", - "coverage[toml]~=7.4", - "pytest~=8.0", - "pytest-cov~=6.0", - "pytest-mock~=3.12", - "mypy[reports]~=1.14.1", - "types-Pygments", - "types-colorama", - "types-setuptools", -] + [build-system] requires = [ diff --git a/uv.lock b/uv.lock index 617c370115..0e7396ad13 100644 --- a/uv.lock +++ b/uv.lock @@ -7,7 +7,6 @@ resolution-markers = [ [manifest] constraints = [ - { name = "build", specifier = ">=0.7.0" }, { name = "cffi", specifier = ">=1.15" }, { name = "httplib2", specifier = ">=0.20.0" }, { name = "iniconfig", specifier = ">=1.1.0" }, @@ -454,7 +453,7 @@ name = "importlib-metadata" version = "8.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "zipp" }, + { name = "zipp", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", size = 55304 } wheels = [ @@ -815,15 +814,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c", size = 38268 }, ] -[[package]] -name = "nodeenv" -version = "1.9.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, -] - [[package]] name = "packaging" version = "24.2" @@ -976,19 +966,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216 }, ] -[[package]] -name = "pyright" -version = "1.1.391" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "nodeenv" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/11/05/4ea52a8a45cc28897edb485b4102d37cbfd5fce8445d679cdeb62bfad221/pyright-1.1.391.tar.gz", hash = "sha256:66b2d42cdf5c3cbab05f2f4b76e8bec8aa78e679bfa0b6ad7b923d9e027cadb2", size = 21965 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ad/89/66f49552fbeb21944c8077d11834b2201514a56fd1b7747ffff9630f1bd9/pyright-1.1.391-py3-none-any.whl", hash = "sha256:54fa186f8b3e8a55a44ebfa842636635688670c6896dcf6cf4a7fc75062f4d15", size = 18579 }, -] - [[package]] name = "pytest" version = "8.3.4" @@ -1493,9 +1470,21 @@ wheels = [ [[package]] name = "starcraft" +version = "0.0.post293+g096e54a.d20250123" source = { editable = "." } -[package.optional-dependencies] +[package.dev-dependencies] +dev = [ + { name = "build" }, + { name = "coverage", extra = ["toml"] }, + { name = "mypy", extra = ["reports"] }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "pytest-mock" }, + { name = "types-colorama" }, + { name = "types-pygments" }, + { name = "types-setuptools" }, +] docs = [ { name = "canonical-sphinx" }, { name = "sphinx-autobuild" }, @@ -1513,40 +1502,13 @@ types = [ { name = "types-setuptools" }, ] -[package.dev-dependencies] -dev = [ - { name = "build" }, - { name = "coverage", extra = ["toml"] }, - { name = "mypy", extra = ["reports"] }, - { name = "pyright" }, - { name = "pytest" }, - { name = "pytest-cov" }, - { name = "pytest-mock" }, - { name = "types-colorama" }, - { name = "types-pygments" }, - { name = "types-setuptools" }, -] - [package.metadata] -requires-dist = [ - { name = "canonical-sphinx", marker = "extra == 'docs'", specifier = "~=0.3.0" }, - { name = "mypy", extras = ["reports"], marker = "extra == 'types'", specifier = "~=1.14.1" }, - { name = "sphinx-autobuild", marker = "extra == 'docs'", specifier = "~=2024.2" }, - { name = "sphinx-lint", marker = "extra == 'docs'", specifier = "==1.0.0" }, - { name = "sphinx-pydantic", marker = "extra == 'docs'", specifier = "==0.1.1" }, - { name = "sphinx-toolbox", marker = "extra == 'docs'", specifier = "~=3.5" }, - { name = "types-colorama", marker = "extra == 'types'" }, - { name = "types-pygments", marker = "extra == 'types'" }, - { name = "types-setuptools", marker = "extra == 'types'" }, - { name = "yamllint", marker = "extra == 'lint'", specifier = "~=1.34" }, -] [package.metadata.requires-dev] dev = [ - { name = "build" }, + { name = "build", specifier = ">=0.7.0" }, { name = "coverage", extras = ["toml"], specifier = "~=7.4" }, { name = "mypy", extras = ["reports"], specifier = "~=1.14.1" }, - { name = "pyright", specifier = "==1.1.391" }, { name = "pytest", specifier = "~=8.0" }, { name = "pytest-cov", specifier = "~=6.0" }, { name = "pytest-mock", specifier = "~=3.12" }, @@ -1554,6 +1516,20 @@ dev = [ { name = "types-pygments" }, { name = "types-setuptools" }, ] +docs = [ + { name = "canonical-sphinx", specifier = "~=0.3.0" }, + { name = "sphinx-autobuild", specifier = "~=2024.2" }, + { name = "sphinx-lint", specifier = "==1.0.0" }, + { name = "sphinx-pydantic", specifier = "==0.1.1" }, + { name = "sphinx-toolbox", specifier = "~=3.5" }, +] +lint = [{ name = "yamllint", specifier = "~=1.34" }] +types = [ + { name = "mypy", extras = ["reports"], specifier = "~=1.14.1" }, + { name = "types-colorama" }, + { name = "types-pygments" }, + { name = "types-setuptools" }, +] [[package]] name = "starlette" From 764de6f6085554da5c93bc2ead692bea6496c4b3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 09:58:03 -0500 Subject: [PATCH 289/333] build(deps): update release-drafter/release-drafter action to v6.1.0 (#334) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-drafter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index 4c6db3eb1f..273701240d 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -11,6 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Release Drafter - uses: release-drafter/release-drafter@v6.0.0 + uses: release-drafter/release-drafter@v6.1.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From b4cf8dde9a68b26891a0c771137373f58ba779a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 10:32:15 -0500 Subject: [PATCH 290/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.3 (#335) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9d58fe3166..7fed7d6cb4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.9.2" + rev: "v0.9.3" hooks: # Run the linter - id: ruff From 97abd69f11848b99fa9b3d3346e62e7c1c22bbee Mon Sep 17 00:00:00 2001 From: Michael DuBelko <michael.dubelko@canonical.com> Date: Wed, 29 Jan 2025 12:25:27 -0800 Subject: [PATCH 291/333] fix(common.mk): skip frivolous link checks in lint-docs (#333) Resolve erroneous link warnings affecting literalref directives. Sphinx-lint will no longer check for spaces before angle brackets (` <>`) or underscores after graves (`_). The root cause is a bug in our implementation of literalref: https://github.com/canonical/canonical-sphinx-extensions/issues/47 --- common.mk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common.mk b/common.mk index 03e0fc1ade..8f6fdf894d 100644 --- a/common.mk +++ b/common.mk @@ -163,7 +163,10 @@ lint-docs: ##- Lint the documentation ifneq ($(CI),) @echo ::group::$@ endif - uv run --group docs sphinx-lint --max-line-length 88 --ignore docs/reference/commands --ignore docs/_build --enable all $(DOCS) + uv run --extra docs sphinx-lint --max-line-length 88 \ + --ignore docs/reference/commands --ignore docs/_build \ + --enable all $(DOCS) \ + -d missing-underscore-after-hyperlink,missing-space-in-hyperlink ifneq ($(CI),) @echo ::endgroup:: endif From 05c018a1a74d32a2a76522a5afced321a1fbf7ce Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Thu, 30 Jan 2025 13:40:55 -0500 Subject: [PATCH 292/333] feat(make): Make groups configurable by version codename (#338) --- Makefile | 13 +++++++++++++ common.mk | 15 ++++++--------- pyproject.toml | 2 +- uv.lock | 1 - 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 7743d1ea0b..ebfc6cff4a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,17 @@ PROJECT=starcraft +UV_TEST_GROUPS := "--group=dev" +UV_DOCS_GROUPS := "--group=docs" +UV_LINT_GROUPS := "--group=lint" "--group=types" + +# If you have dev dependencies that depend on your distro version, uncomment these: +# ifneq ($(wildcard /etc/os-release),) +# include /etc/os-release +# endif +# ifdef VERSION_CODENAME +# UV_TEST_GROUPS += "--group=dev-$(VERSION_CODENAME)" +# UV_DOCS_GROUPS += "--group=dev-$(VERSION_CODENAME)" +# UV_LINT_GROUPS += "--group=dev-$(VERSION_CODENAME)" +# endif include common.mk diff --git a/common.mk b/common.mk index 8f6fdf894d..48ee3c9b74 100644 --- a/common.mk +++ b/common.mk @@ -48,19 +48,19 @@ help: ## Show this help. .PHONY: setup setup: install-uv setup-precommit ## Set up a development environment - uv sync --all-groups + uv sync $(UV_TEST_GROUPS) $(UV_LINT_GROUPS) $(UV_DOCS_GROUPS) .PHONY: setup-tests setup-tests: install-uv install-build-deps ##- Set up a testing environment without linters - uv sync + uv sync $(UV_TEST_GROUPS) .PHONY: setup-lint setup-lint: install-uv install-shellcheck install-pyright install-lint-build-deps ##- Set up a linting-only environment - uv sync --no-install-workspace --group lint --group types + uv sync $(UV_LINT_GROUPS) .PHONY: setup-docs setup-docs: install-uv ##- Set up a documentation-only environment - uv sync --no-dev --group docs + uv sync --no-dev $(UV_DOCS_GROUPS) .PHONY: setup-precommit setup-precommit: install-uv ##- Set up pre-commit hooks in this repository. @@ -163,10 +163,7 @@ lint-docs: ##- Lint the documentation ifneq ($(CI),) @echo ::group::$@ endif - uv run --extra docs sphinx-lint --max-line-length 88 \ - --ignore docs/reference/commands --ignore docs/_build \ - --enable all $(DOCS) \ - -d missing-underscore-after-hyperlink,missing-space-in-hyperlink + uv run $(UV_DOCS_GROUPS) sphinx-lint --max-line-length 88 --ignore docs/reference/commands --ignore docs/_build --enable all $(DOCS) -d missing-underscore-after-hyperlink,missing-space-in-hyperlink ifneq ($(CI),) @echo ::endgroup:: endif @@ -202,7 +199,7 @@ test-coverage: ## Generate coverage report .PHONY: docs docs: ## Build documentation - uv run --group docs sphinx-build -b html -W $(DOCS) $(DOCS)/_build + uv run $(UV_DOCS_GROUPS) sphinx-build -b html -W $(DOCS) $(DOCS)/_build .PHONY: docs-auto docs-auto: ## Build and host docs with sphinx-autobuild diff --git a/pyproject.toml b/pyproject.toml index c74aad7250..572b0b91ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ docs = [ "sphinx-autobuild~=2024.2", "sphinx-pydantic==0.1.1", "sphinx-toolbox~=3.5", - "sphinx-lint==1.0.0", + "sphinx-lint~=1.0", ] dev = [ "build>=0.7.0", diff --git a/uv.lock b/uv.lock index 0e7396ad13..3385aaa57e 100644 --- a/uv.lock +++ b/uv.lock @@ -1470,7 +1470,6 @@ wheels = [ [[package]] name = "starcraft" -version = "0.0.post293+g096e54a.d20250123" source = { editable = "." } [package.dev-dependencies] From c0465a48d3403b069b7c72c63d569edf4ce504b3 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Thu, 30 Jan 2025 13:53:50 -0500 Subject: [PATCH 293/333] fix(make): generate a list of build dependencies and run one command (#339) --- Makefile | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index ebfc6cff4a..6eb618c111 100644 --- a/Makefile +++ b/Makefile @@ -38,17 +38,27 @@ publish: publish-pypi ## Publish packages publish-pypi: clean package-pip lint-twine ##- Publish Python packages to pypi uv tool run twine upload dist/* +# Find dependencies that need installing +APT_PACKAGES := +ifeq ($(wildcard /usr/include/libxml2/libxml/xpath.h),) +APT_PACKAGES += libxml2-dev +endif +ifeq ($(wildcard /usr/include/libxslt/xslt.h),) +APT_PACKAGES += libxslt1-dev +endif +ifeq ($(wildcard /usr/share/doc/python3-venv/copyright),) +APT_PACKAGES += python3-venv +endif + # Used for installing build dependencies in CI. .PHONY: install-build-deps install-build-deps: install-lint-build-deps -ifeq ($(shell which apt-get),) +ifeq ($(APT_PACKAGES),) +else ifeq ($(shell which apt-get),) $(warning Cannot install build dependencies without apt.) -else ifeq ($(wildcard /usr/include/libxml2/libxml/xpath.h),) - sudo $(APT) install libxml2-dev libxslt1-dev python3-venv -else ifeq ($(wildcard /usr/include/libxslt/xslt.h),) - sudo $(APT) install libxslt1-dev python3-venv -else ifeq ($(wildcard /usr/share/doc/python3-venv/copyright),) - sudo $(APT) install python3-venv + $(warning Please ensure the equivalents to these packages are installed: $(APT_PACKAGES)) +else + sudo $(APT) install $(APT_PACKAGES) endif # If additional build dependencies need installing in order to build the linting env. From 5cf407731fb68cad10eb38a194b7d199abf71468 Mon Sep 17 00:00:00 2001 From: Tiago Nobrega <tiago.nobrega@canonical.com> Date: Thu, 30 Jan 2025 19:35:41 -0300 Subject: [PATCH 294/333] ci: fetch tags on readthedocs (#342) This is sometimes needs in cases where readthedocs' default clone doesn't include the tags. --- .readthedocs.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 2d4b82d202..82b873cf2b 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -19,6 +19,8 @@ build: tools: python: "3.12" jobs: + post_checkout: + - git fetch --tags --unshallow # Also fetch tags post_system_dependencies: - asdf plugin add uv - asdf install uv latest From 61931c24ff31e062529f095f8277a8169d88b301 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani.pelton@canonical.com> Date: Thu, 30 Jan 2025 17:42:08 -0500 Subject: [PATCH 295/333] fix(make): depend on build deps during setup (#341) --- common.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.mk b/common.mk index 48ee3c9b74..f8035b1aa9 100644 --- a/common.mk +++ b/common.mk @@ -47,7 +47,7 @@ help: ## Show this help. }' .PHONY: setup -setup: install-uv setup-precommit ## Set up a development environment +setup: install-uv setup-precommit install-build-deps ## Set up a development environment uv sync $(UV_TEST_GROUPS) $(UV_LINT_GROUPS) $(UV_DOCS_GROUPS) .PHONY: setup-tests From 067feab40936fbacb4680e5b781d0a0114c24d2b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 31 Jan 2025 11:19:12 -0500 Subject: [PATCH 296/333] build(deps): lock file maintenance (#343) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- uv.lock | 110 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/uv.lock b/uv.lock index 3385aaa57e..f6084d270d 100644 --- a/uv.lock +++ b/uv.lock @@ -1747,61 +1747,61 @@ wheels = [ [[package]] name = "websockets" -version = "14.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f4/1b/380b883ce05bb5f45a905b61790319a28958a9ab1e4b6b95ff5464b60ca1/websockets-14.1.tar.gz", hash = "sha256:398b10c77d471c0aab20a845e7a60076b6390bfdaac7a6d2edb0d2c59d75e8d8", size = 162840 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/91/b1b375dbd856fd5fff3f117de0e520542343ecaf4e8fc60f1ac1e9f5822c/websockets-14.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a0adf84bc2e7c86e8a202537b4fd50e6f7f0e4a6b6bf64d7ccb96c4cd3330b29", size = 161950 }, - { url = "https://files.pythonhosted.org/packages/61/8f/4d52f272d3ebcd35e1325c646e98936099a348374d4a6b83b524bded8116/websockets-14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90b5d9dfbb6d07a84ed3e696012610b6da074d97453bd01e0e30744b472c8179", size = 159601 }, - { url = "https://files.pythonhosted.org/packages/c4/b1/29e87b53eb1937992cdee094a0988aadc94f25cf0b37e90c75eed7123d75/websockets-14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2177ee3901075167f01c5e335a6685e71b162a54a89a56001f1c3e9e3d2ad250", size = 159854 }, - { url = "https://files.pythonhosted.org/packages/3f/e6/752a2f5e8321ae2a613062676c08ff2fccfb37dc837a2ee919178a372e8a/websockets-14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f14a96a0034a27f9d47fd9788913924c89612225878f8078bb9d55f859272b0", size = 168835 }, - { url = "https://files.pythonhosted.org/packages/60/27/ca62de7877596926321b99071639275e94bb2401397130b7cf33dbf2106a/websockets-14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f874ba705deea77bcf64a9da42c1f5fc2466d8f14daf410bc7d4ceae0a9fcb0", size = 167844 }, - { url = "https://files.pythonhosted.org/packages/7e/db/f556a1d06635c680ef376be626c632e3f2bbdb1a0189d1d1bffb061c3b70/websockets-14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9607b9a442392e690a57909c362811184ea429585a71061cd5d3c2b98065c199", size = 168157 }, - { url = "https://files.pythonhosted.org/packages/b3/bc/99e5f511838c365ac6ecae19674eb5e94201aa4235bd1af3e6fa92c12905/websockets-14.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bea45f19b7ca000380fbd4e02552be86343080120d074b87f25593ce1700ad58", size = 168561 }, - { url = "https://files.pythonhosted.org/packages/c6/e7/251491585bad61c79e525ac60927d96e4e17b18447cc9c3cfab47b2eb1b8/websockets-14.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:219c8187b3ceeadbf2afcf0f25a4918d02da7b944d703b97d12fb01510869078", size = 167979 }, - { url = "https://files.pythonhosted.org/packages/ac/98/7ac2e4eeada19bdbc7a3a66a58e3ebdf33648b9e1c5b3f08c3224df168cf/websockets-14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ad2ab2547761d79926effe63de21479dfaf29834c50f98c4bf5b5480b5838434", size = 167925 }, - { url = "https://files.pythonhosted.org/packages/ab/3d/09e65c47ee2396b7482968068f6e9b516221e1032b12dcf843b9412a5dfb/websockets-14.1-cp310-cp310-win32.whl", hash = "sha256:1288369a6a84e81b90da5dbed48610cd7e5d60af62df9851ed1d1d23a9069f10", size = 162831 }, - { url = "https://files.pythonhosted.org/packages/8a/67/59828a3d09740e6a485acccfbb66600632f2178b6ed1b61388ee96f17d5a/websockets-14.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0744623852f1497d825a49a99bfbec9bea4f3f946df6eb9d8a2f0c37a2fec2e", size = 163266 }, - { url = "https://files.pythonhosted.org/packages/97/ed/c0d03cb607b7fe1f7ff45e2cd4bb5cd0f9e3299ced79c2c303a6fff44524/websockets-14.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:449d77d636f8d9c17952628cc7e3b8faf6e92a17ec581ec0c0256300717e1512", size = 161949 }, - { url = "https://files.pythonhosted.org/packages/06/91/bf0a44e238660d37a2dda1b4896235d20c29a2d0450f3a46cd688f43b239/websockets-14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a35f704be14768cea9790d921c2c1cc4fc52700410b1c10948511039be824aac", size = 159606 }, - { url = "https://files.pythonhosted.org/packages/ff/b8/7185212adad274c2b42b6a24e1ee6b916b7809ed611cbebc33b227e5c215/websockets-14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b1f3628a0510bd58968c0f60447e7a692933589b791a6b572fcef374053ca280", size = 159854 }, - { url = "https://files.pythonhosted.org/packages/5a/8a/0849968d83474be89c183d8ae8dcb7f7ada1a3c24f4d2a0d7333c231a2c3/websockets-14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c3deac3748ec73ef24fc7be0b68220d14d47d6647d2f85b2771cb35ea847aa1", size = 169402 }, - { url = "https://files.pythonhosted.org/packages/bd/4f/ef886e37245ff6b4a736a09b8468dae05d5d5c99de1357f840d54c6f297d/websockets-14.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7048eb4415d46368ef29d32133134c513f507fff7d953c18c91104738a68c3b3", size = 168406 }, - { url = "https://files.pythonhosted.org/packages/11/43/e2dbd4401a63e409cebddedc1b63b9834de42f51b3c84db885469e9bdcef/websockets-14.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cf0ad281c979306a6a34242b371e90e891bce504509fb6bb5246bbbf31e7b6", size = 168776 }, - { url = "https://files.pythonhosted.org/packages/6d/d6/7063e3f5c1b612e9f70faae20ebaeb2e684ffa36cb959eb0862ee2809b32/websockets-14.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cc1fc87428c1d18b643479caa7b15db7d544652e5bf610513d4a3478dbe823d0", size = 169083 }, - { url = "https://files.pythonhosted.org/packages/49/69/e6f3d953f2fa0f8a723cf18cd011d52733bd7f6e045122b24e0e7f49f9b0/websockets-14.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f95ba34d71e2fa0c5d225bde3b3bdb152e957150100e75c86bc7f3964c450d89", size = 168529 }, - { url = "https://files.pythonhosted.org/packages/70/ff/f31fa14561fc1d7b8663b0ed719996cf1f581abee32c8fb2f295a472f268/websockets-14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9481a6de29105d73cf4515f2bef8eb71e17ac184c19d0b9918a3701c6c9c4f23", size = 168475 }, - { url = "https://files.pythonhosted.org/packages/f1/15/b72be0e4bf32ff373aa5baef46a4c7521b8ea93ad8b49ca8c6e8e764c083/websockets-14.1-cp311-cp311-win32.whl", hash = "sha256:368a05465f49c5949e27afd6fbe0a77ce53082185bbb2ac096a3a8afaf4de52e", size = 162833 }, - { url = "https://files.pythonhosted.org/packages/bc/ef/2d81679acbe7057ffe2308d422f744497b52009ea8bab34b6d74a2657d1d/websockets-14.1-cp311-cp311-win_amd64.whl", hash = "sha256:6d24fc337fc055c9e83414c94e1ee0dee902a486d19d2a7f0929e49d7d604b09", size = 163263 }, - { url = "https://files.pythonhosted.org/packages/55/64/55698544ce29e877c9188f1aee9093712411a8fc9732cca14985e49a8e9c/websockets-14.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ed907449fe5e021933e46a3e65d651f641975a768d0649fee59f10c2985529ed", size = 161957 }, - { url = "https://files.pythonhosted.org/packages/a2/b1/b088f67c2b365f2c86c7b48edb8848ac27e508caf910a9d9d831b2f343cb/websockets-14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:87e31011b5c14a33b29f17eb48932e63e1dcd3fa31d72209848652310d3d1f0d", size = 159620 }, - { url = "https://files.pythonhosted.org/packages/c1/89/2a09db1bbb40ba967a1b8225b07b7df89fea44f06de9365f17f684d0f7e6/websockets-14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bc6ccf7d54c02ae47a48ddf9414c54d48af9c01076a2e1023e3b486b6e72c707", size = 159852 }, - { url = "https://files.pythonhosted.org/packages/ca/c1/f983138cd56e7d3079f1966e81f77ce6643f230cd309f73aa156bb181749/websockets-14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9777564c0a72a1d457f0848977a1cbe15cfa75fa2f67ce267441e465717dcf1a", size = 169675 }, - { url = "https://files.pythonhosted.org/packages/c1/c8/84191455d8660e2a0bdb33878d4ee5dfa4a2cedbcdc88bbd097303b65bfa/websockets-14.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a655bde548ca98f55b43711b0ceefd2a88a71af6350b0c168aa77562104f3f45", size = 168619 }, - { url = "https://files.pythonhosted.org/packages/8d/a7/62e551fdcd7d44ea74a006dc193aba370505278ad76efd938664531ce9d6/websockets-14.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3dfff83ca578cada2d19e665e9c8368e1598d4e787422a460ec70e531dbdd58", size = 169042 }, - { url = "https://files.pythonhosted.org/packages/ad/ed/1532786f55922c1e9c4d329608e36a15fdab186def3ca9eb10d7465bc1cc/websockets-14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6a6c9bcf7cdc0fd41cc7b7944447982e8acfd9f0d560ea6d6845428ed0562058", size = 169345 }, - { url = "https://files.pythonhosted.org/packages/ea/fb/160f66960d495df3de63d9bcff78e1b42545b2a123cc611950ffe6468016/websockets-14.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4b6caec8576e760f2c7dd878ba817653144d5f369200b6ddf9771d64385b84d4", size = 168725 }, - { url = "https://files.pythonhosted.org/packages/cf/53/1bf0c06618b5ac35f1d7906444b9958f8485682ab0ea40dee7b17a32da1e/websockets-14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eb6d38971c800ff02e4a6afd791bbe3b923a9a57ca9aeab7314c21c84bf9ff05", size = 168712 }, - { url = "https://files.pythonhosted.org/packages/e5/22/5ec2f39fff75f44aa626f86fa7f20594524a447d9c3be94d8482cd5572ef/websockets-14.1-cp312-cp312-win32.whl", hash = "sha256:1d045cbe1358d76b24d5e20e7b1878efe578d9897a25c24e6006eef788c0fdf0", size = 162838 }, - { url = "https://files.pythonhosted.org/packages/74/27/28f07df09f2983178db7bf6c9cccc847205d2b92ced986cd79565d68af4f/websockets-14.1-cp312-cp312-win_amd64.whl", hash = "sha256:90f4c7a069c733d95c308380aae314f2cb45bd8a904fb03eb36d1a4983a4993f", size = 163277 }, - { url = "https://files.pythonhosted.org/packages/34/77/812b3ba5110ed8726eddf9257ab55ce9e85d97d4aa016805fdbecc5e5d48/websockets-14.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:3630b670d5057cd9e08b9c4dab6493670e8e762a24c2c94ef312783870736ab9", size = 161966 }, - { url = "https://files.pythonhosted.org/packages/8d/24/4fcb7aa6986ae7d9f6d083d9d53d580af1483c5ec24bdec0978307a0f6ac/websockets-14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36ebd71db3b89e1f7b1a5deaa341a654852c3518ea7a8ddfdf69cc66acc2db1b", size = 159625 }, - { url = "https://files.pythonhosted.org/packages/f8/47/2a0a3a2fc4965ff5b9ce9324d63220156bd8bedf7f90824ab92a822e65fd/websockets-14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5b918d288958dc3fa1c5a0b9aa3256cb2b2b84c54407f4813c45d52267600cd3", size = 159857 }, - { url = "https://files.pythonhosted.org/packages/dd/c8/d7b425011a15e35e17757e4df75b25e1d0df64c0c315a44550454eaf88fc/websockets-14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00fe5da3f037041da1ee0cf8e308374e236883f9842c7c465aa65098b1c9af59", size = 169635 }, - { url = "https://files.pythonhosted.org/packages/93/39/6e3b5cffa11036c40bd2f13aba2e8e691ab2e01595532c46437b56575678/websockets-14.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8149a0f5a72ca36720981418eeffeb5c2729ea55fa179091c81a0910a114a5d2", size = 168578 }, - { url = "https://files.pythonhosted.org/packages/cf/03/8faa5c9576299b2adf34dcccf278fc6bbbcda8a3efcc4d817369026be421/websockets-14.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77569d19a13015e840b81550922056acabc25e3f52782625bc6843cfa034e1da", size = 169018 }, - { url = "https://files.pythonhosted.org/packages/8c/05/ea1fec05cc3a60defcdf0bb9f760c3c6bd2dd2710eff7ac7f891864a22ba/websockets-14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cf5201a04550136ef870aa60ad3d29d2a59e452a7f96b94193bee6d73b8ad9a9", size = 169383 }, - { url = "https://files.pythonhosted.org/packages/21/1d/eac1d9ed787f80754e51228e78855f879ede1172c8b6185aca8cef494911/websockets-14.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:88cf9163ef674b5be5736a584c999e98daf3aabac6e536e43286eb74c126b9c7", size = 168773 }, - { url = "https://files.pythonhosted.org/packages/0e/1b/e808685530185915299740d82b3a4af3f2b44e56ccf4389397c7a5d95d39/websockets-14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:836bef7ae338a072e9d1863502026f01b14027250a4545672673057997d5c05a", size = 168757 }, - { url = "https://files.pythonhosted.org/packages/b6/19/6ab716d02a3b068fbbeb6face8a7423156e12c446975312f1c7c0f4badab/websockets-14.1-cp313-cp313-win32.whl", hash = "sha256:0d4290d559d68288da9f444089fd82490c8d2744309113fc26e2da6e48b65da6", size = 162834 }, - { url = "https://files.pythonhosted.org/packages/6c/fd/ab6b7676ba712f2fc89d1347a4b5bdc6aa130de10404071f2b2606450209/websockets-14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8621a07991add373c3c5c2cf89e1d277e49dc82ed72c75e3afc74bd0acc446f0", size = 163277 }, - { url = "https://files.pythonhosted.org/packages/fb/cd/382a05a1ba2a93bd9fb807716a660751295df72e77204fb130a102fcdd36/websockets-14.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5dc25a9dbd1a7f61eca4b7cb04e74ae4b963d658f9e4f9aad9cd00b688692c8", size = 159633 }, - { url = "https://files.pythonhosted.org/packages/b7/a0/fa7c62e2952ef028b422fbf420f9353d9dd4dfaa425de3deae36e98c0784/websockets-14.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:04a97aca96ca2acedf0d1f332c861c5a4486fdcba7bcef35873820f940c4231e", size = 159867 }, - { url = "https://files.pythonhosted.org/packages/c1/94/954b4924f868db31d5f0935893c7a8446515ee4b36bb8ad75a929469e453/websockets-14.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df174ece723b228d3e8734a6f2a6febbd413ddec39b3dc592f5a4aa0aff28098", size = 161121 }, - { url = "https://files.pythonhosted.org/packages/7a/2e/f12bbb41a8f2abb76428ba4fdcd9e67b5b364a3e7fa97c88f4d6950aa2d4/websockets-14.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:034feb9f4286476f273b9a245fb15f02c34d9586a5bc936aff108c3ba1b21beb", size = 160731 }, - { url = "https://files.pythonhosted.org/packages/13/97/b76979401f2373af1fe3e08f960b265cecab112e7dac803446fb98351a52/websockets-14.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c308dabd2b380807ab64b62985eaccf923a78ebc572bd485375b9ca2b7dc7", size = 160681 }, - { url = "https://files.pythonhosted.org/packages/39/9c/16916d9a436c109a1d7ba78817e8fee357b78968be3f6e6f517f43afa43d/websockets-14.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5a42d3ecbb2db5080fc578314439b1d79eef71d323dc661aa616fb492436af5d", size = 163316 }, - { url = "https://files.pythonhosted.org/packages/b0/0b/c7e5d11020242984d9d37990310520ed663b942333b83a033c2f20191113/websockets-14.1-py3-none-any.whl", hash = "sha256:4d4fc827a20abe6d544a119896f6b78ee13fe81cbfef416f3f2ddf09a03f0e2e", size = 156277 }, +version = "14.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/54/8359678c726243d19fae38ca14a334e740782336c9f19700858c4eb64a1e/websockets-14.2.tar.gz", hash = "sha256:5059ed9c54945efb321f097084b4c7e52c246f2c869815876a69d1efc4ad6eb5", size = 164394 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/fa/76607eb7dcec27b2d18d63f60a32e60e2b8629780f343bb83a4dbb9f4350/websockets-14.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e8179f95323b9ab1c11723e5d91a89403903f7b001828161b480a7810b334885", size = 163089 }, + { url = "https://files.pythonhosted.org/packages/9e/00/ad2246b5030575b79e7af0721810fdaecaf94c4b2625842ef7a756fa06dd/websockets-14.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d8c3e2cdb38f31d8bd7d9d28908005f6fa9def3324edb9bf336d7e4266fd397", size = 160741 }, + { url = "https://files.pythonhosted.org/packages/72/f7/60f10924d333a28a1ff3fcdec85acf226281331bdabe9ad74947e1b7fc0a/websockets-14.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:714a9b682deb4339d39ffa674f7b674230227d981a37d5d174a4a83e3978a610", size = 160996 }, + { url = "https://files.pythonhosted.org/packages/63/7c/c655789cf78648c01ac6ecbe2d6c18f91b75bdc263ffee4d08ce628d12f0/websockets-14.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2e53c72052f2596fb792a7acd9704cbc549bf70fcde8a99e899311455974ca3", size = 169974 }, + { url = "https://files.pythonhosted.org/packages/fb/5b/013ed8b4611857ac92ac631079c08d9715b388bd1d88ec62e245f87a39df/websockets-14.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3fbd68850c837e57373d95c8fe352203a512b6e49eaae4c2f4088ef8cf21980", size = 168985 }, + { url = "https://files.pythonhosted.org/packages/cd/33/aa3e32fd0df213a5a442310754fe3f89dd87a0b8e5b4e11e0991dd3bcc50/websockets-14.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b27ece32f63150c268593d5fdb82819584831a83a3f5809b7521df0685cd5d8", size = 169297 }, + { url = "https://files.pythonhosted.org/packages/93/17/dae0174883d6399f57853ac44abf5f228eaba86d98d160f390ffabc19b6e/websockets-14.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4daa0faea5424d8713142b33825fff03c736f781690d90652d2c8b053345b0e7", size = 169677 }, + { url = "https://files.pythonhosted.org/packages/42/e2/0375af7ac00169b98647c804651c515054b34977b6c1354f1458e4116c1e/websockets-14.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:bc63cee8596a6ec84d9753fd0fcfa0452ee12f317afe4beae6b157f0070c6c7f", size = 169089 }, + { url = "https://files.pythonhosted.org/packages/73/8d/80f71d2a351a44b602859af65261d3dde3a0ce4e76cf9383738a949e0cc3/websockets-14.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a570862c325af2111343cc9b0257b7119b904823c675b22d4ac547163088d0d", size = 169026 }, + { url = "https://files.pythonhosted.org/packages/48/97/173b1fa6052223e52bb4054a141433ad74931d94c575e04b654200b98ca4/websockets-14.2-cp310-cp310-win32.whl", hash = "sha256:75862126b3d2d505e895893e3deac0a9339ce750bd27b4ba515f008b5acf832d", size = 163967 }, + { url = "https://files.pythonhosted.org/packages/c0/5b/2fcf60f38252a4562b28b66077e0d2b48f91fef645d5f78874cd1dec807b/websockets-14.2-cp310-cp310-win_amd64.whl", hash = "sha256:cc45afb9c9b2dc0852d5c8b5321759cf825f82a31bfaf506b65bf4668c96f8b2", size = 164413 }, + { url = "https://files.pythonhosted.org/packages/15/b6/504695fb9a33df0ca56d157f5985660b5fc5b4bf8c78f121578d2d653392/websockets-14.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3bdc8c692c866ce5fefcaf07d2b55c91d6922ac397e031ef9b774e5b9ea42166", size = 163088 }, + { url = "https://files.pythonhosted.org/packages/81/26/ebfb8f6abe963c795122439c6433c4ae1e061aaedfc7eff32d09394afbae/websockets-14.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c93215fac5dadc63e51bcc6dceca72e72267c11def401d6668622b47675b097f", size = 160745 }, + { url = "https://files.pythonhosted.org/packages/a1/c6/1435ad6f6dcbff80bb95e8986704c3174da8866ddb751184046f5c139ef6/websockets-14.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c9b6535c0e2cf8a6bf938064fb754aaceb1e6a4a51a80d884cd5db569886910", size = 160995 }, + { url = "https://files.pythonhosted.org/packages/96/63/900c27cfe8be1a1f2433fc77cd46771cf26ba57e6bdc7cf9e63644a61863/websockets-14.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a52a6d7cf6938e04e9dceb949d35fbdf58ac14deea26e685ab6368e73744e4c", size = 170543 }, + { url = "https://files.pythonhosted.org/packages/00/8b/bec2bdba92af0762d42d4410593c1d7d28e9bfd952c97a3729df603dc6ea/websockets-14.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9f05702e93203a6ff5226e21d9b40c037761b2cfb637187c9802c10f58e40473", size = 169546 }, + { url = "https://files.pythonhosted.org/packages/6b/a9/37531cb5b994f12a57dec3da2200ef7aadffef82d888a4c29a0d781568e4/websockets-14.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22441c81a6748a53bfcb98951d58d1af0661ab47a536af08920d129b4d1c3473", size = 169911 }, + { url = "https://files.pythonhosted.org/packages/60/d5/a6eadba2ed9f7e65d677fec539ab14a9b83de2b484ab5fe15d3d6d208c28/websockets-14.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd9b868d78b194790e6236d9cbc46d68aba4b75b22497eb4ab64fa640c3af56", size = 170183 }, + { url = "https://files.pythonhosted.org/packages/76/57/a338ccb00d1df881c1d1ee1f2a20c9c1b5b29b51e9e0191ee515d254fea6/websockets-14.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1a5a20d5843886d34ff8c57424cc65a1deda4375729cbca4cb6b3353f3ce4142", size = 169623 }, + { url = "https://files.pythonhosted.org/packages/64/22/e5f7c33db0cb2c1d03b79fd60d189a1da044e2661f5fd01d629451e1db89/websockets-14.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:34277a29f5303d54ec6468fb525d99c99938607bc96b8d72d675dee2b9f5bf1d", size = 169583 }, + { url = "https://files.pythonhosted.org/packages/aa/2e/2b4662237060063a22e5fc40d46300a07142afe30302b634b4eebd717c07/websockets-14.2-cp311-cp311-win32.whl", hash = "sha256:02687db35dbc7d25fd541a602b5f8e451a238ffa033030b172ff86a93cb5dc2a", size = 163969 }, + { url = "https://files.pythonhosted.org/packages/94/a5/0cda64e1851e73fc1ecdae6f42487babb06e55cb2f0dc8904b81d8ef6857/websockets-14.2-cp311-cp311-win_amd64.whl", hash = "sha256:862e9967b46c07d4dcd2532e9e8e3c2825e004ffbf91a5ef9dde519ee2effb0b", size = 164408 }, + { url = "https://files.pythonhosted.org/packages/c1/81/04f7a397653dc8bec94ddc071f34833e8b99b13ef1a3804c149d59f92c18/websockets-14.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1f20522e624d7ffbdbe259c6b6a65d73c895045f76a93719aa10cd93b3de100c", size = 163096 }, + { url = "https://files.pythonhosted.org/packages/ec/c5/de30e88557e4d70988ed4d2eabd73fd3e1e52456b9f3a4e9564d86353b6d/websockets-14.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:647b573f7d3ada919fd60e64d533409a79dcf1ea21daeb4542d1d996519ca967", size = 160758 }, + { url = "https://files.pythonhosted.org/packages/e5/8c/d130d668781f2c77d106c007b6c6c1d9db68239107c41ba109f09e6c218a/websockets-14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6af99a38e49f66be5a64b1e890208ad026cda49355661549c507152113049990", size = 160995 }, + { url = "https://files.pythonhosted.org/packages/a6/bc/f6678a0ff17246df4f06765e22fc9d98d1b11a258cc50c5968b33d6742a1/websockets-14.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:091ab63dfc8cea748cc22c1db2814eadb77ccbf82829bac6b2fbe3401d548eda", size = 170815 }, + { url = "https://files.pythonhosted.org/packages/d8/b2/8070cb970c2e4122a6ef38bc5b203415fd46460e025652e1ee3f2f43a9a3/websockets-14.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b374e8953ad477d17e4851cdc66d83fdc2db88d9e73abf755c94510ebddceb95", size = 169759 }, + { url = "https://files.pythonhosted.org/packages/81/da/72f7caabd94652e6eb7e92ed2d3da818626e70b4f2b15a854ef60bf501ec/websockets-14.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a39d7eceeea35db85b85e1169011bb4321c32e673920ae9c1b6e0978590012a3", size = 170178 }, + { url = "https://files.pythonhosted.org/packages/31/e0/812725b6deca8afd3a08a2e81b3c4c120c17f68c9b84522a520b816cda58/websockets-14.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0a6f3efd47ffd0d12080594f434faf1cd2549b31e54870b8470b28cc1d3817d9", size = 170453 }, + { url = "https://files.pythonhosted.org/packages/66/d3/8275dbc231e5ba9bb0c4f93144394b4194402a7a0c8ffaca5307a58ab5e3/websockets-14.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:065ce275e7c4ffb42cb738dd6b20726ac26ac9ad0a2a48e33ca632351a737267", size = 169830 }, + { url = "https://files.pythonhosted.org/packages/a3/ae/e7d1a56755ae15ad5a94e80dd490ad09e345365199600b2629b18ee37bc7/websockets-14.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e9d0e53530ba7b8b5e389c02282f9d2aa47581514bd6049d3a7cffe1385cf5fe", size = 169824 }, + { url = "https://files.pythonhosted.org/packages/b6/32/88ccdd63cb261e77b882e706108d072e4f1c839ed723bf91a3e1f216bf60/websockets-14.2-cp312-cp312-win32.whl", hash = "sha256:20e6dd0984d7ca3037afcb4494e48c74ffb51e8013cac71cf607fffe11df7205", size = 163981 }, + { url = "https://files.pythonhosted.org/packages/b3/7d/32cdb77990b3bdc34a306e0a0f73a1275221e9a66d869f6ff833c95b56ef/websockets-14.2-cp312-cp312-win_amd64.whl", hash = "sha256:44bba1a956c2c9d268bdcdf234d5e5ff4c9b6dc3e300545cbe99af59dda9dcce", size = 164421 }, + { url = "https://files.pythonhosted.org/packages/82/94/4f9b55099a4603ac53c2912e1f043d6c49d23e94dd82a9ce1eb554a90215/websockets-14.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6f1372e511c7409a542291bce92d6c83320e02c9cf392223272287ce55bc224e", size = 163102 }, + { url = "https://files.pythonhosted.org/packages/8e/b7/7484905215627909d9a79ae07070057afe477433fdacb59bf608ce86365a/websockets-14.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4da98b72009836179bb596a92297b1a61bb5a830c0e483a7d0766d45070a08ad", size = 160766 }, + { url = "https://files.pythonhosted.org/packages/a3/a4/edb62efc84adb61883c7d2c6ad65181cb087c64252138e12d655989eec05/websockets-14.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8a86a269759026d2bde227652b87be79f8a734e582debf64c9d302faa1e9f03", size = 160998 }, + { url = "https://files.pythonhosted.org/packages/f5/79/036d320dc894b96af14eac2529967a6fc8b74f03b83c487e7a0e9043d842/websockets-14.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86cf1aaeca909bf6815ea714d5c5736c8d6dd3a13770e885aafe062ecbd04f1f", size = 170780 }, + { url = "https://files.pythonhosted.org/packages/63/75/5737d21ee4dd7e4b9d487ee044af24a935e36a9ff1e1419d684feedcba71/websockets-14.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b0f6c3ba3b1240f602ebb3971d45b02cc12bd1845466dd783496b3b05783a5", size = 169717 }, + { url = "https://files.pythonhosted.org/packages/2c/3c/bf9b2c396ed86a0b4a92ff4cdaee09753d3ee389be738e92b9bbd0330b64/websockets-14.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:669c3e101c246aa85bc8534e495952e2ca208bd87994650b90a23d745902db9a", size = 170155 }, + { url = "https://files.pythonhosted.org/packages/75/2d/83a5aca7247a655b1da5eb0ee73413abd5c3a57fc8b92915805e6033359d/websockets-14.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eabdb28b972f3729348e632ab08f2a7b616c7e53d5414c12108c29972e655b20", size = 170495 }, + { url = "https://files.pythonhosted.org/packages/79/dd/699238a92761e2f943885e091486378813ac8f43e3c84990bc394c2be93e/websockets-14.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2066dc4cbcc19f32c12a5a0e8cc1b7ac734e5b64ac0a325ff8353451c4b15ef2", size = 169880 }, + { url = "https://files.pythonhosted.org/packages/c8/c9/67a8f08923cf55ce61aadda72089e3ed4353a95a3a4bc8bf42082810e580/websockets-14.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ab95d357cd471df61873dadf66dd05dd4709cae001dd6342edafc8dc6382f307", size = 169856 }, + { url = "https://files.pythonhosted.org/packages/17/b1/1ffdb2680c64e9c3921d99db460546194c40d4acbef999a18c37aa4d58a3/websockets-14.2-cp313-cp313-win32.whl", hash = "sha256:a9e72fb63e5f3feacdcf5b4ff53199ec8c18d66e325c34ee4c551ca748623bbc", size = 163974 }, + { url = "https://files.pythonhosted.org/packages/14/13/8b7fc4cb551b9cfd9890f0fd66e53c18a06240319915533b033a56a3d520/websockets-14.2-cp313-cp313-win_amd64.whl", hash = "sha256:b439ea828c4ba99bb3176dc8d9b933392a2413c0f6b149fdcba48393f573377f", size = 164420 }, + { url = "https://files.pythonhosted.org/packages/10/3d/91d3d2bb1325cd83e8e2c02d0262c7d4426dc8fa0831ef1aa4d6bf2041af/websockets-14.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d7d9cafbccba46e768be8a8ad4635fa3eae1ffac4c6e7cb4eb276ba41297ed29", size = 160773 }, + { url = "https://files.pythonhosted.org/packages/33/7c/cdedadfef7381939577858b1b5718a4ab073adbb584e429dd9d9dc9bfe16/websockets-14.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c76193c1c044bd1e9b3316dcc34b174bbf9664598791e6fb606d8d29000e070c", size = 161007 }, + { url = "https://files.pythonhosted.org/packages/ca/35/7a20a3c450b27c04e50fbbfc3dfb161ed8e827b2a26ae31c4b59b018b8c6/websockets-14.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd475a974d5352390baf865309fe37dec6831aafc3014ffac1eea99e84e83fc2", size = 162264 }, + { url = "https://files.pythonhosted.org/packages/e8/9c/e3f9600564b0c813f2448375cf28b47dc42c514344faed3a05d71fb527f9/websockets-14.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c6c0097a41968b2e2b54ed3424739aab0b762ca92af2379f152c1aef0187e1c", size = 161873 }, + { url = "https://files.pythonhosted.org/packages/3f/37/260f189b16b2b8290d6ae80c9f96d8b34692cf1bb3475df54c38d3deb57d/websockets-14.2-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d7ff794c8b36bc402f2e07c0b2ceb4a2424147ed4785ff03e2a7af03711d60a", size = 161818 }, + { url = "https://files.pythonhosted.org/packages/ff/1e/e47dedac8bf7140e59aa6a679e850c4df9610ae844d71b6015263ddea37b/websockets-14.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dec254fcabc7bd488dab64846f588fc5b6fe0d78f641180030f8ea27b76d72c3", size = 164465 }, + { url = "https://files.pythonhosted.org/packages/7b/c8/d529f8a32ce40d98309f4470780631e971a5a842b60aec864833b3615786/websockets-14.2-py3-none-any.whl", hash = "sha256:7a6ceec4ea84469f15cf15807a747e9efe57e369c384fa86e022b3bea679b79b", size = 157416 }, ] [[package]] From 8ba2f0a6d7ee60c7d48217e3fa4b61ab819124be Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 11:29:50 -0500 Subject: [PATCH 297/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.4 (#344) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7fed7d6cb4..82a133c4da 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.9.3" + rev: "v0.9.4" hooks: # Run the linter - id: ruff From c9e090ab011049119b628ebc00915928914dc994 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani.pelton@canonical.com> Date: Fri, 7 Feb 2025 10:23:40 -0500 Subject: [PATCH 298/333] chore: hush some of the linter output (#345) --- common.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common.mk b/common.mk index f8035b1aa9..9c1f3f0b2e 100644 --- a/common.mk +++ b/common.mk @@ -13,7 +13,7 @@ else APT := apt-get endif -PRETTIER=npm exec --package=prettier -- prettier +PRETTIER=npm exec --package=prettier -- prettier --log-level warn PRETTIER_FILES="**/*.{yaml,yml,json,json5,css,md}" # By default we should not update the uv lock file here. @@ -210,7 +210,7 @@ pack-pip: ##- Build packages for pip (sdist, wheel) ifneq ($(CI),) @echo ::group::$@ endif - uv build . + uv build --quiet . ifneq ($(CI),) @echo ::endgroup:: endif From 7db121ee0f1cd747d2115dbb265b1e3b44a37be1 Mon Sep 17 00:00:00 2001 From: Callahan <callahan.kovacs@canonical.com> Date: Fri, 7 Feb 2025 14:06:41 -0600 Subject: [PATCH 299/333] docs(HACKING): add note about revert commits (#346) Signed-off-by: Callahan Kovacs <callahankovacs@gmail.com> --- HACKING.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/HACKING.rst b/HACKING.rst index 384112f0d6..07784179cf 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -212,6 +212,7 @@ Examples include: * type changes * accommodating a developer-facing deprecation warning * many *small* fixes for an existing PR +* reverts (``chore(revert): <header of reverted commit>``) * merge commits (``chore(merge): <branch or tag> into <branch>``) * the remote name should not be included (for example, use ``main`` From b09d0903ebc48ebf183c42bf96e001a734eca06c Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Mon, 27 Jan 2025 10:40:22 -0500 Subject: [PATCH 300/333] style: fix ruff warning --- snapcraft/parts/grammar.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/snapcraft/parts/grammar.py b/snapcraft/parts/grammar.py index b7390f9748..9425a57a38 100644 --- a/snapcraft/parts/grammar.py +++ b/snapcraft/parts/grammar.py @@ -71,9 +71,9 @@ def self_check(value: Any) -> bool: # TODO: make checker optional in craft-grammar. processor = GrammarProcessor(arch=arch, target_arch=target_arch, checker=self_check) - for part_name in parts_yaml_data: - parts_yaml_data[part_name] = process_part( - part_yaml_data=parts_yaml_data[part_name], processor=processor + for part in parts_yaml_data.values(): + part = process_part( + part_yaml_data=part, processor=processor ) return parts_yaml_data From 8eca0b600e11f2dcc0c9436d4b497930190bebb9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 17:18:05 -0500 Subject: [PATCH 301/333] build(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.9.5 (#348) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 82a133c4da..6a01d39b77 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.9.4" + rev: "v0.9.5" hooks: # Run the linter - id: ruff From ab3b82a5c25bccddea59662f42170ca0616658a5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 17:18:33 -0500 Subject: [PATCH 302/333] build(deps): update dependency mypy to ~=1.15.0 (#347) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 4 ++-- uv.lock | 62 +++++++++++++++++++++++++------------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 572b0b91ff..f57e1dbe0b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ lint = [ "yamllint~=1.34", ] types = [ - "mypy[reports]~=1.14.1", + "mypy[reports]~=1.15.0", "types-Pygments", "types-colorama", "types-setuptools", @@ -40,7 +40,7 @@ dev = [ "pytest~=8.0", "pytest-cov~=6.0", "pytest-mock~=3.12", - "mypy[reports]~=1.14.1", + "mypy[reports]~=1.15.0", "types-Pygments", "types-colorama", "types-setuptools", diff --git a/uv.lock b/uv.lock index f6084d270d..64c9a9b0e5 100644 --- a/uv.lock +++ b/uv.lock @@ -738,40 +738,40 @@ wheels = [ [[package]] name = "mypy" -version = "1.14.1" +version = "1.15.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/eb/2c92d8ea1e684440f54fa49ac5d9a5f19967b7b472a281f419e69a8d228e/mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", size = 3216051 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/7a/87ae2adb31d68402da6da1e5f30c07ea6063e9f09b5e7cfc9dfa44075e74/mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb", size = 11211002 }, - { url = "https://files.pythonhosted.org/packages/e1/23/eada4c38608b444618a132be0d199b280049ded278b24cbb9d3fc59658e4/mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0", size = 10358400 }, - { url = "https://files.pythonhosted.org/packages/43/c9/d6785c6f66241c62fd2992b05057f404237deaad1566545e9f144ced07f5/mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d", size = 12095172 }, - { url = "https://files.pythonhosted.org/packages/c3/62/daa7e787770c83c52ce2aaf1a111eae5893de9e004743f51bfcad9e487ec/mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b", size = 12828732 }, - { url = "https://files.pythonhosted.org/packages/1b/a2/5fb18318a3637f29f16f4e41340b795da14f4751ef4f51c99ff39ab62e52/mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427", size = 13012197 }, - { url = "https://files.pythonhosted.org/packages/28/99/e153ce39105d164b5f02c06c35c7ba958aaff50a2babba7d080988b03fe7/mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f", size = 9780836 }, - { url = "https://files.pythonhosted.org/packages/da/11/a9422850fd506edbcdc7f6090682ecceaf1f87b9dd847f9df79942da8506/mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c", size = 11120432 }, - { url = "https://files.pythonhosted.org/packages/b6/9e/47e450fd39078d9c02d620545b2cb37993a8a8bdf7db3652ace2f80521ca/mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1", size = 10279515 }, - { url = "https://files.pythonhosted.org/packages/01/b5/6c8d33bd0f851a7692a8bfe4ee75eb82b6983a3cf39e5e32a5d2a723f0c1/mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8", size = 12025791 }, - { url = "https://files.pythonhosted.org/packages/f0/4c/e10e2c46ea37cab5c471d0ddaaa9a434dc1d28650078ac1b56c2d7b9b2e4/mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f", size = 12749203 }, - { url = "https://files.pythonhosted.org/packages/88/55/beacb0c69beab2153a0f57671ec07861d27d735a0faff135a494cd4f5020/mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1", size = 12885900 }, - { url = "https://files.pythonhosted.org/packages/a2/75/8c93ff7f315c4d086a2dfcde02f713004357d70a163eddb6c56a6a5eff40/mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae", size = 9777869 }, - { url = "https://files.pythonhosted.org/packages/43/1b/b38c079609bb4627905b74fc6a49849835acf68547ac33d8ceb707de5f52/mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", size = 11266668 }, - { url = "https://files.pythonhosted.org/packages/6b/75/2ed0d2964c1ffc9971c729f7a544e9cd34b2cdabbe2d11afd148d7838aa2/mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", size = 10254060 }, - { url = "https://files.pythonhosted.org/packages/a1/5f/7b8051552d4da3c51bbe8fcafffd76a6823779101a2b198d80886cd8f08e/mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", size = 11933167 }, - { url = "https://files.pythonhosted.org/packages/04/90/f53971d3ac39d8b68bbaab9a4c6c58c8caa4d5fd3d587d16f5927eeeabe1/mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", size = 12864341 }, - { url = "https://files.pythonhosted.org/packages/03/d2/8bc0aeaaf2e88c977db41583559319f1821c069e943ada2701e86d0430b7/mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89", size = 12972991 }, - { url = "https://files.pythonhosted.org/packages/6f/17/07815114b903b49b0f2cf7499f1c130e5aa459411596668267535fe9243c/mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", size = 9879016 }, - { url = "https://files.pythonhosted.org/packages/9e/15/bb6a686901f59222275ab228453de741185f9d54fecbaacec041679496c6/mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", size = 11252097 }, - { url = "https://files.pythonhosted.org/packages/f8/b3/8b0f74dfd072c802b7fa368829defdf3ee1566ba74c32a2cb2403f68024c/mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", size = 10239728 }, - { url = "https://files.pythonhosted.org/packages/c5/9b/4fd95ab20c52bb5b8c03cc49169be5905d931de17edfe4d9d2986800b52e/mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", size = 11924965 }, - { url = "https://files.pythonhosted.org/packages/56/9d/4a236b9c57f5d8f08ed346914b3f091a62dd7e19336b2b2a0d85485f82ff/mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", size = 12867660 }, - { url = "https://files.pythonhosted.org/packages/40/88/a61a5497e2f68d9027de2bb139c7bb9abaeb1be1584649fa9d807f80a338/mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", size = 12969198 }, - { url = "https://files.pythonhosted.org/packages/54/da/3d6fc5d92d324701b0c23fb413c853892bfe0e1dbe06c9138037d459756b/mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", size = 9885276 }, - { url = "https://files.pythonhosted.org/packages/a0/b5/32dd67b69a16d088e533962e5044e51004176a9952419de0370cdaead0f8/mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", size = 2752905 }, +sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433 }, + { url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472 }, + { url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424 }, + { url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450 }, + { url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765 }, + { url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701 }, + { url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338 }, + { url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540 }, + { url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051 }, + { url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751 }, + { url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783 }, + { url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618 }, + { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981 }, + { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175 }, + { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675 }, + { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020 }, + { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582 }, + { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614 }, + { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592 }, + { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611 }, + { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443 }, + { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541 }, + { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348 }, + { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648 }, + { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777 }, ] [package.optional-dependencies] @@ -1507,7 +1507,7 @@ types = [ dev = [ { name = "build", specifier = ">=0.7.0" }, { name = "coverage", extras = ["toml"], specifier = "~=7.4" }, - { name = "mypy", extras = ["reports"], specifier = "~=1.14.1" }, + { name = "mypy", extras = ["reports"], specifier = "~=1.15.0" }, { name = "pytest", specifier = "~=8.0" }, { name = "pytest-cov", specifier = "~=6.0" }, { name = "pytest-mock", specifier = "~=3.12" }, @@ -1518,13 +1518,13 @@ dev = [ docs = [ { name = "canonical-sphinx", specifier = "~=0.3.0" }, { name = "sphinx-autobuild", specifier = "~=2024.2" }, - { name = "sphinx-lint", specifier = "==1.0.0" }, + { name = "sphinx-lint", specifier = "~=1.0" }, { name = "sphinx-pydantic", specifier = "==0.1.1" }, { name = "sphinx-toolbox", specifier = "~=3.5" }, ] lint = [{ name = "yamllint", specifier = "~=1.34" }] types = [ - { name = "mypy", extras = ["reports"], specifier = "~=1.14.1" }, + { name = "mypy", extras = ["reports"], specifier = "~=1.15.0" }, { name = "types-colorama" }, { name = "types-pygments" }, { name = "types-setuptools" }, From 8c6820eed2bdc1e708989ccfcab9bf16d010b9c7 Mon Sep 17 00:00:00 2001 From: Michael DuBelko <michael.dubelko@canonical.com> Date: Mon, 10 Feb 2025 16:47:03 -0800 Subject: [PATCH 303/333] feat(docs): add redirects --- docs/conf.py | 4 ++++ docs/redirects.txt | 5 +++++ pyproject.toml | 1 + uv.lock | 14 ++++++++++++++ 4 files changed, 24 insertions(+) create mode 100644 docs/redirects.txt diff --git a/docs/conf.py b/docs/conf.py index d3f052d638..9a162200bd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -49,6 +49,7 @@ "sphinx_toolbox", "sphinx_toolbox.more_autodoc", "sphinx.ext.autodoc", # Must be loaded after more_autodoc + "sphinxext.rediraffe", ] ) @@ -72,3 +73,6 @@ github_repository = "starbase" # endregion + +# Client-side page redirects. +rediraffe_redirects = "redirects.txt" diff --git a/docs/redirects.txt b/docs/redirects.txt new file mode 100644 index 0000000000..4e32bd57e7 --- /dev/null +++ b/docs/redirects.txt @@ -0,0 +1,5 @@ +# Client-side page redirects. Each mapping takes the format: +# "<old path>" "<current path>" +# Paths must be represented as source files relative to the root of the `docs` dir. +# The old path must be a file that _doesn't exist_ in the source. The current path +# must be a file that _does exist_ in the source. diff --git a/pyproject.toml b/pyproject.toml index f57e1dbe0b..9159ec82b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,6 +33,7 @@ docs = [ "sphinx-pydantic==0.1.1", "sphinx-toolbox~=3.5", "sphinx-lint~=1.0", + "sphinxext-rediraffe==0.2.7", ] dev = [ "build>=0.7.0", diff --git a/uv.lock b/uv.lock index 64c9a9b0e5..092b4d1758 100644 --- a/uv.lock +++ b/uv.lock @@ -1459,6 +1459,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072 }, ] +[[package]] +name = "sphinxext-rediraffe" +version = "0.2.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/b4/e5fbb493f796430230189a1ce5f9beff1ac1b98619fc71ed35deca6059a5/sphinxext-rediraffe-0.2.7.tar.gz", hash = "sha256:651dcbfae5ffda9ffd534dfb8025f36120e5efb6ea1a33f5420023862b9f725d", size = 8735 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/4f/c8797e796199e55cf6c8979ecdf5f4b09b81e93f87b3193c759faea63263/sphinxext_rediraffe-0.2.7-py3-none-any.whl", hash = "sha256:9e430a52d4403847f4ffb3a8dd6dfc34a9fe43525305131f52ed899743a5fd8c", size = 8267 }, +] + [[package]] name = "standard-imghdr" version = "3.10.14" @@ -1490,6 +1502,7 @@ docs = [ { name = "sphinx-lint" }, { name = "sphinx-pydantic" }, { name = "sphinx-toolbox" }, + { name = "sphinxext-rediraffe" }, ] lint = [ { name = "yamllint" }, @@ -1521,6 +1534,7 @@ docs = [ { name = "sphinx-lint", specifier = "~=1.0" }, { name = "sphinx-pydantic", specifier = "==0.1.1" }, { name = "sphinx-toolbox", specifier = "~=3.5" }, + { name = "sphinxext-rediraffe", specifier = "==0.2.7" }, ] lint = [{ name = "yamllint", specifier = "~=1.34" }] types = [ From daba40ff59fe5069b5989e5812d5f1c28ac7d044 Mon Sep 17 00:00:00 2001 From: Alex Lowe <alex.lowe@canonical.com> Date: Tue, 11 Feb 2025 11:41:31 -0500 Subject: [PATCH 304/333] style(HACKING): fix typo (#349) --- HACKING.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACKING.rst b/HACKING.rst index 07784179cf..a5cecd43d0 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -178,7 +178,7 @@ cheaper to modify without changing its observable behavior.*" ``style`` """""""""" -Commits that change the syntax, format, or aesthics of any text the codebase. +Commits that change the syntax, format, or aesthetics of any text in the codebase. The meaning of the text should not change. Examples include: From b3e809a6bb284e02d50e49442f34790100e0a334 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Mon, 27 Jan 2025 11:24:08 -0500 Subject: [PATCH 305/333] build: migrate to pyproject for building with uv --- .gitignore | 1 + pyproject.toml | 110 ++ snap/snapcraft.yaml | 2 +- snapcraft/__init__.py | 19 +- uv.lock | 2938 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 3057 insertions(+), 13 deletions(-) create mode 100644 uv.lock diff --git a/.gitignore b/.gitignore index bdfd02fc87..ca39ce615c 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ __pycache__ *.comp *.snap snap/.snapcraft/ +/snapcraft/_version.py .spread_multipass .spread-reuse.* /stage diff --git a/pyproject.toml b/pyproject.toml index 62b20ec258..6e9f961d2a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,113 @@ +[project] +name = "snapcraft" +description = "Create snaps" +readme = "README.md" +dynamic = ["version"] +dependencies = [ + "attrs==24.2.0", + "catkin-pkg==1.0.0 ; sys_platform == 'linux'", + "click==8.1.7", + "craft-application~=4.4", + "craft-archives~=2.0", + "craft-cli~=2.9", + "craft-grammar>=2.0.1,<3.0.0", + "craft-parts==2.3.0", + "craft-platforms~=0.4", + "craft-store>=3.0.2,<4.0.0", + "cryptography==43.0.3", # Pinned due to https://github.com/canonical/snapcraft/issues/5217 + "docutils<0.20", # Frozen until we can update sphinx dependencies. + "gnupg", + "jsonschema==2.5.1", + "launchpadlib", + "lazr.restfulclient", + "lxml", + "macaroonbakery", + "mypy-extensions", + "overrides", + "packaging", + "progressbar", + "pydantic~=2.8", + "pyelftools", + # Pygit2 and libgit2 need to match versions. + # Further info: https://www.pygit2.org/install.html#version-numbers + "pygit2~=1.13.0", + "pylxd ; sys_platform == 'linux'", + "pymacaroons", + "python-apt @ https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz ; sys_platform == 'linux'", + "python-debian ; sys_platform == 'linux'", + "pyxdg", + "pyyaml", + "raven", + "requests-toolbelt", + "requests-unixsocket2", + "requests", + "simplejson", + "snap-helpers", + "tabulate", + "toml", + "tinydb", + "typing-extensions", + "validators>=0.28.3", +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Operating System :: POSIX :: Linux", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "Natural Language :: English", + "Topic :: Software Development :: Build Tools", + "Topic :: System :: Software Distribution", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.12", +] +requires-python = ">=3.12" + +[project.scripts] +snapcraft = "snapcraft.application:main" +snapcraft_legacy = "snapcraft_legacy.cli.__main__:run" + +[build-system] +requires = [ + "setuptools>=69.0", + "setuptools_scm[toml]>=7.1", +] +build-backend = "setuptools.build_meta" + +[tool.setuptools_scm] +write_to = "snapcraft/_version.py" +# the version comes from the latest annotated git tag formatted as 'X.Y.Z' +# version scheme: +# - X.Y.Z.post<commits since tag>+g<hash>.d<%Y%m%d> +# parts of scheme: +# - X.Y.Z - most recent git tag +# - post<commits since tag>+g<hash> - present when current commit is not tagged +# - +dirty - present when working dir is dirty +# version scheme when no tags exist: +# - 0.0.post<total commits>+g<hash> +version_scheme = "post-release" +# deviations from the default 'git describe' command: +# - only match annotated tags +# - only match tags formatted as 'X.Y.Z' +git_describe_command = [ + "git", + "describe", + "--dirty", + "--long", + "--match", + "[0-9]*.[0-9]*.[0-9]*", + "--exclude", + "*[^0-9.]*", +] +# Appends "+dirty" to the version when working dir is dirty +# Necessary to avoid version numbers being too long +local_scheme = "dirty-tag" + +[tool.setuptools.packages.find] +include = ["*craft*"] +namespaces = false + [tool.black] extend-exclude = ''' /( diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 347655002a..d90d0eed7c 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -194,7 +194,7 @@ parts: override-build: | ${SNAP}/libexec/snapcraft/craftctl default - version="$(python3 setup.py --version)" + version=$(PYTHONPATH=$CRAFT_PART_INSTALL/lib/python3.12/site-packages python3 -c "import snapcraft;print(snapcraft.__version__)") ${SNAP}/libexec/snapcraft/craftctl set version="$version" [ -n "$(echo $version | grep "+git")" ] && grade=devel || grade=stable diff --git a/snapcraft/__init__.py b/snapcraft/__init__.py index 569d755bc7..2f5c327469 100644 --- a/snapcraft/__init__.py +++ b/snapcraft/__init__.py @@ -16,20 +16,15 @@ """Publish your app for Linux users for desktop, cloud, and IoT.""" -import os -from importlib import metadata - # For legacy compatibility import snapcraft.sources # noqa: F401 +try: + from ._version import __version__ +except ImportError: + from importlib.metadata import PackageNotFoundError, version -def _get_version(): - if os.environ.get("SNAP_NAME") == "snapcraft": - return os.environ["SNAP_VERSION"] try: - return metadata.version("snapcraft") - except metadata.PackageNotFoundError: - return "0.0.0+devel" - - -__version__ = _get_version() + __version__ = version("snapcraft") + except PackageNotFoundError: + __version__ = "dev" diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000000..6576ed4853 --- /dev/null +++ b/uv.lock @@ -0,0 +1,2938 @@ +version = 1 +requires-python = ">=3.12" +resolution-markers = [ + "python_full_version >= '3.13'", + "python_full_version < '3.13'", +] + +[[package]] +name = "alabaster" +version = "0.7.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511 }, +] + +[[package]] +name = "altgraph" +version = "0.17.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/de/a8/7145824cf0b9e3c28046520480f207df47e927df83aa9555fb47f8505922/altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406", size = 48418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/3f/3bc3f1d83f6e4a7fcb834d3720544ca597590425be5ba9db032b2bf322a2/altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff", size = 21212 }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, +] + +[[package]] +name = "anyio" +version = "4.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 }, +] + +[[package]] +name = "apeye" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "apeye-core" }, + { name = "domdf-python-tools" }, + { name = "platformdirs" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4f/6b/cc65e31843d7bfda8313a9dc0c77a21e8580b782adca53c7cb3e511fe023/apeye-1.4.1.tar.gz", hash = "sha256:14ea542fad689e3bfdbda2189a354a4908e90aee4bf84c15ab75d68453d76a36", size = 99219 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/7b/2d63664777b3e831ac1b1d8df5bbf0b7c8bee48e57115896080890527b1b/apeye-1.4.1-py3-none-any.whl", hash = "sha256:44e58a9104ec189bf42e76b3a7fe91e2b2879d96d48e9a77e5e32ff699c9204e", size = 107989 }, +] + +[[package]] +name = "apeye-core" +version = "1.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "domdf-python-tools" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e5/4c/4f108cfd06923bd897bf992a6ecb6fb122646ee7af94d7f9a64abd071d4c/apeye_core-1.1.5.tar.gz", hash = "sha256:5de72ed3d00cc9b20fea55e54b7ab8f5ef8500eb33a5368bc162a5585e238a55", size = 96511 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/9f/fa9971d2a0c6fef64c87ba362a493a4f230eff4ea8dfb9f4c7cbdf71892e/apeye_core-1.1.5-py3-none-any.whl", hash = "sha256:dc27a93f8c9e246b3b238c5ea51edf6115ab2618ef029b9f2d9a190ec8228fbf", size = 99286 }, +] + +[[package]] +name = "astroid" +version = "3.3.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/c5/5c83c48bbf547f3dd8b587529db7cf5a265a3368b33e85e76af8ff6061d3/astroid-3.3.8.tar.gz", hash = "sha256:a88c7994f914a4ea8572fac479459f4955eeccc877be3f2d959a33273b0cf40b", size = 398196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/28/0bc8a17d6cd4cc3c79ae41b7105a2b9a327c110e5ddd37a8a27b29a5c8a2/astroid-3.3.8-py3-none-any.whl", hash = "sha256:187ccc0c248bfbba564826c26f070494f7bc964fd286b6d9fff4420e55de828c", size = 275153 }, +] + +[[package]] +name = "attrs" +version = "24.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", size = 792678 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", size = 63001 }, +] + +[[package]] +name = "autodocsumm" +version = "0.2.14" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/03/96/92afe8a7912b327c01f0a8b6408c9556ee13b1aba5b98d587ac7327ff32d/autodocsumm-0.2.14.tar.gz", hash = "sha256:2839a9d4facc3c4eccd306c08695540911042b46eeafcdc3203e6d0bab40bc77", size = 46357 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/bc/3f66af9beb683728e06ca08797e4e9d3e44f432f339718cae3ba856a9cad/autodocsumm-0.2.14-py3-none-any.whl", hash = "sha256:3bad8717fc5190802c60392a7ab04b9f3c97aa9efa8b3780b3d81d615bfe5dc0", size = 14640 }, +] + +[[package]] +name = "babel" +version = "2.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, +] + +[[package]] +name = "boolean-py" +version = "4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/d9/b6e56a303d221fc0bdff2c775e4eef7fedd58194aa5a96fa89fb71634cc9/boolean.py-4.0.tar.gz", hash = "sha256:17b9a181630e43dde1851d42bef546d616d5d9b4480357514597e78b203d06e4", size = 34504 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/02/6389ef0529af6da0b913374dedb9bbde8eabfe45767ceec38cc37801b0bd/boolean.py-4.0-py3-none-any.whl", hash = "sha256:2876f2051d7d6394a531d82dc6eb407faa0b01a0a0b3083817ccd7323b8d96bd", size = 25909 }, +] + +[[package]] +name = "bracex" +version = "2.5.post1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/6c/57418c4404cd22fe6275b8301ca2b46a8cdaa8157938017a9ae0b3edf363/bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6", size = 26641 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/02/8db98cdc1a58e0abd6716d5e63244658e6e63513c65f469f34b6f1053fd0/bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6", size = 11558 }, +] + +[[package]] +name = "cachecontrol" +version = "0.14.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "msgpack" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b7/a4/3390ac4dfa1773f661c8780368018230e8207ec4fd3800d2c0c3adee4456/cachecontrol-0.14.2.tar.gz", hash = "sha256:7d47d19f866409b98ff6025b6a0fca8e4c791fb31abbd95f622093894ce903a2", size = 28832 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/63/baffb44ca6876e7b5fc8fe17b24a7c07bf479d604a592182db9af26ea366/cachecontrol-0.14.2-py3-none-any.whl", hash = "sha256:ebad2091bf12d0d200dfc2464330db638c5deb41d546f6d7aca079e87290f3b0", size = 21780 }, +] + +[package.optional-dependencies] +filecache = [ + { name = "filelock" }, +] + +[[package]] +name = "canonical-sphinx" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "furo" }, + { name = "linkify-it-py" }, + { name = "myst-parser" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/19/b2101265969ba6bfacbb9b3355a32a22abdcccceba61542813f07fe0e965/canonical_sphinx-0.3.0.tar.gz", hash = "sha256:7914a1281e7520a032058e7a511d019fee25a152c032499a7bf9e15852f9d9e7", size = 1051001 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/ba/ab2e2113841f88a9725c6c55f4918a3031ef3efad6afd154d9444cd40c8e/canonical_sphinx-0.3.0-py3-none-any.whl", hash = "sha256:55dc07c54038ea7016a5a6a12fafa1bde8558a00009237f5224db1c65e919b0f", size = 1027670 }, +] + +[package.optional-dependencies] +full = [ + { name = "canonical-sphinx-extensions" }, + { name = "pyspelling" }, + { name = "sphinx-copybutton" }, + { name = "sphinx-design" }, + { name = "sphinx-notfound-page" }, + { name = "sphinx-reredirects" }, + { name = "sphinx-tabs" }, + { name = "sphinxcontrib-jquery" }, + { name = "sphinxext-opengraph" }, +] + +[[package]] +name = "canonical-sphinx-extensions" +version = "0.0.23" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "docutils" }, + { name = "gitpython" }, + { name = "requests" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b6/49/2e64462241adfe97615dd646ad3042e1a3e7bb77f14ed15e1aa0e543c3ff/canonical_sphinx_extensions-0.0.23.tar.gz", hash = "sha256:5178c97e8c515dcff42b1976a81a68e74e70ca77a8fb0b68af3dc097705a49eb", size = 20653 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/dd/e9079ddd7fee8f34bece4e69d9a33338f1f88630757a6a963ca0aac0e01f/canonical_sphinx_extensions-0.0.23-py3-none-any.whl", hash = "sha256:05113c93e37fe9c9be1a5f1ba6491c1dbb7492cdecd9b5202ed165e671973c31", size = 38023 }, +] + +[[package]] +name = "catkin-pkg" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/a2/88f8ba42a0119833887b8afe159f6e3ae96e2700720baf461eeabcc6acd8/catkin_pkg-1.0.0.tar.gz", hash = "sha256:476e9f52917282f464739241b4bcaf5ebbfba9a7a68d9af8f875225feac0e1b5", size = 64861 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/f7/86d933ec31f00450f513ef110fa9c0e5da4c6e2c992933a35c8d8fe7d01f/catkin_pkg-1.0.0-py3-none-any.whl", hash = "sha256:10a6589e9edf3cd5bd18e35e094d20b516e6351bcf0da891c28a0ff526fdb7cc", size = 75996 }, +] + +[[package]] +name = "certifi" +version = "2024.12.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, +] + +[[package]] +name = "cffi" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, +] + +[[package]] +name = "chardet" +version = "5.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/f7b6ab21ec75897ed80c17d79b15951a719226b9fababf1e40ea74d69079/chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", size = 2069618 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970", size = 199385 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, + { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, + { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, + { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, + { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, + { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, + { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, + { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, + { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, + { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, + { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, + { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, + { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, + { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, + { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, + { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, + { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, + { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, + { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, + { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, + { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, + { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, + { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, + { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, + { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, + { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, +] + +[[package]] +name = "click" +version = "8.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, +] + +[[package]] +name = "codespell" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/15/e0/709453393c0ea77d007d907dd436b3ee262e28b30995ea1aa36c6ffbccaf/codespell-2.4.1.tar.gz", hash = "sha256:299fcdcb09d23e81e35a671bbe746d5ad7e8385972e65dbb833a2eaac33c01e5", size = 344740 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/01/b394922252051e97aab231d416c86da3d8a6d781eeadcdca1082867de64e/codespell-2.4.1-py3-none-any.whl", hash = "sha256:3dadafa67df7e4a3dbf51e0d7315061b80d265f9552ebd699b3dd6834b47e425", size = 344501 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "coverage" +version = "7.6.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/ba/ac14d281f80aab516275012e8875991bb06203957aa1e19950139238d658/coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23", size = 803868 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/77/19d09ea06f92fdf0487499283b1b7af06bc422ea94534c8fe3a4cd023641/coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853", size = 208281 }, + { url = "https://files.pythonhosted.org/packages/b6/67/5479b9f2f99fcfb49c0d5cf61912a5255ef80b6e80a3cddba39c38146cf4/coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078", size = 208514 }, + { url = "https://files.pythonhosted.org/packages/15/d1/febf59030ce1c83b7331c3546d7317e5120c5966471727aa7ac157729c4b/coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0", size = 241537 }, + { url = "https://files.pythonhosted.org/packages/4b/7e/5ac4c90192130e7cf8b63153fe620c8bfd9068f89a6d9b5f26f1550f7a26/coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50", size = 238572 }, + { url = "https://files.pythonhosted.org/packages/dc/03/0334a79b26ecf59958f2fe9dd1f5ab3e2f88db876f5071933de39af09647/coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022", size = 240639 }, + { url = "https://files.pythonhosted.org/packages/d7/45/8a707f23c202208d7b286d78ad6233f50dcf929319b664b6cc18a03c1aae/coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b", size = 240072 }, + { url = "https://files.pythonhosted.org/packages/66/02/603ce0ac2d02bc7b393279ef618940b4a0535b0868ee791140bda9ecfa40/coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0", size = 238386 }, + { url = "https://files.pythonhosted.org/packages/04/62/4e6887e9be060f5d18f1dd58c2838b2d9646faf353232dec4e2d4b1c8644/coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852", size = 240054 }, + { url = "https://files.pythonhosted.org/packages/5c/74/83ae4151c170d8bd071924f212add22a0e62a7fe2b149edf016aeecad17c/coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359", size = 210904 }, + { url = "https://files.pythonhosted.org/packages/c3/54/de0893186a221478f5880283119fc40483bc460b27c4c71d1b8bba3474b9/coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247", size = 211692 }, + { url = "https://files.pythonhosted.org/packages/25/6d/31883d78865529257bf847df5789e2ae80e99de8a460c3453dbfbe0db069/coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9", size = 208308 }, + { url = "https://files.pythonhosted.org/packages/70/22/3f2b129cc08de00c83b0ad6252e034320946abfc3e4235c009e57cfeee05/coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b", size = 208565 }, + { url = "https://files.pythonhosted.org/packages/97/0a/d89bc2d1cc61d3a8dfe9e9d75217b2be85f6c73ebf1b9e3c2f4e797f4531/coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690", size = 241083 }, + { url = "https://files.pythonhosted.org/packages/4c/81/6d64b88a00c7a7aaed3a657b8eaa0931f37a6395fcef61e53ff742b49c97/coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18", size = 238235 }, + { url = "https://files.pythonhosted.org/packages/9a/0b/7797d4193f5adb4b837207ed87fecf5fc38f7cc612b369a8e8e12d9fa114/coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c", size = 240220 }, + { url = "https://files.pythonhosted.org/packages/65/4d/6f83ca1bddcf8e51bf8ff71572f39a1c73c34cf50e752a952c34f24d0a60/coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd", size = 239847 }, + { url = "https://files.pythonhosted.org/packages/30/9d/2470df6aa146aff4c65fee0f87f58d2164a67533c771c9cc12ffcdb865d5/coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e", size = 237922 }, + { url = "https://files.pythonhosted.org/packages/08/dd/723fef5d901e6a89f2507094db66c091449c8ba03272861eaefa773ad95c/coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694", size = 239783 }, + { url = "https://files.pythonhosted.org/packages/3d/f7/64d3298b2baf261cb35466000628706ce20a82d42faf9b771af447cd2b76/coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6", size = 210965 }, + { url = "https://files.pythonhosted.org/packages/d5/58/ec43499a7fc681212fe7742fe90b2bc361cdb72e3181ace1604247a5b24d/coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e", size = 211719 }, + { url = "https://files.pythonhosted.org/packages/ab/c9/f2857a135bcff4330c1e90e7d03446b036b2363d4ad37eb5e3a47bbac8a6/coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe", size = 209050 }, + { url = "https://files.pythonhosted.org/packages/aa/b3/f840e5bd777d8433caa9e4a1eb20503495709f697341ac1a8ee6a3c906ad/coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273", size = 209321 }, + { url = "https://files.pythonhosted.org/packages/85/7d/125a5362180fcc1c03d91850fc020f3831d5cda09319522bcfa6b2b70be7/coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8", size = 252039 }, + { url = "https://files.pythonhosted.org/packages/a9/9c/4358bf3c74baf1f9bddd2baf3756b54c07f2cfd2535f0a47f1e7757e54b3/coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098", size = 247758 }, + { url = "https://files.pythonhosted.org/packages/cf/c7/de3eb6fc5263b26fab5cda3de7a0f80e317597a4bad4781859f72885f300/coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb", size = 250119 }, + { url = "https://files.pythonhosted.org/packages/3e/e6/43de91f8ba2ec9140c6a4af1102141712949903dc732cf739167cfa7a3bc/coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0", size = 249597 }, + { url = "https://files.pythonhosted.org/packages/08/40/61158b5499aa2adf9e37bc6d0117e8f6788625b283d51e7e0c53cf340530/coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf", size = 247473 }, + { url = "https://files.pythonhosted.org/packages/50/69/b3f2416725621e9f112e74e8470793d5b5995f146f596f133678a633b77e/coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2", size = 248737 }, + { url = "https://files.pythonhosted.org/packages/3c/6e/fe899fb937657db6df31cc3e61c6968cb56d36d7326361847440a430152e/coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312", size = 211611 }, + { url = "https://files.pythonhosted.org/packages/1c/55/52f5e66142a9d7bc93a15192eba7a78513d2abf6b3558d77b4ca32f5f424/coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d", size = 212781 }, +] + +[[package]] +name = "craft-application" +version = "4.8.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "craft-archives" }, + { name = "craft-cli" }, + { name = "craft-grammar" }, + { name = "craft-parts" }, + { name = "craft-platforms" }, + { name = "craft-providers" }, + { name = "jinja2" }, + { name = "license-expression" }, + { name = "platformdirs" }, + { name = "pydantic" }, + { name = "pygit2" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "snap-helpers" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/09/a4/03f588d549e60067f3093cd3541b283400a61e5893f0d740d47b9fdedb6e/craft_application-4.8.2.tar.gz", hash = "sha256:4070a035952bc3fa8aa16cc1b488814e92375dc6d27905c250e23cf42849bae7", size = 228126 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/5a/385cdacac2ad5b41e5b481d9c25b71dc1c34188d183a376ba3e331653c88/craft_application-4.8.2-py3-none-any.whl", hash = "sha256:77ef9217211cf6d6d164288f65879f94f15c282ddf8f1ab58a324b645a7e88bf", size = 146039 }, +] + +[[package]] +name = "craft-archives" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distro" }, + { name = "launchpadlib" }, + { name = "lazr-restfulclient" }, + { name = "lazr-uri" }, + { name = "overrides" }, + { name = "pydantic" }, + { name = "python-debian" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8b/8e/efd531838ceb591d4aaa4d032807131082bf20e39112472be33346cc9267/craft-archives-2.0.2.tar.gz", hash = "sha256:8dfc0a78ba0bf1e63891975463e2a15c0028b9697b2282d6e9fe05bd6477960d", size = 74887 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/6f/930785e102111ded8acbbcb399de25fc74799ada41b56526d9aa8e980db5/craft_archives-2.0.2-py3-none-any.whl", hash = "sha256:8598e70b1228ce6cd2d73cab3c7bae5947ef329434d1ef865999c0a2a2c629b1", size = 32160 }, +] + +[[package]] +name = "craft-cli" +version = "2.15.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "overrides" }, + { name = "platformdirs" }, + { name = "pywin32", marker = "sys_platform == 'win32'" }, + { name = "pyyaml" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/a7/32b8170deaefb28a8ec4cbccbaa0fbc4fac019cf3edf3682079af271ffa9/craft_cli-2.15.0.tar.gz", hash = "sha256:83c94e521c597c0836eb4a649c68105827006731d2032ca925cf1aea27d9fc9c", size = 116960 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/1c/9786bc93f1d210eadf6513868d27b75996ab6c3a40013782a4be86f5a98e/craft_cli-2.15.0-py3-none-any.whl", hash = "sha256:4ed2f7e409acce8f66a60d7038645431b38b2320d2eb88e133b7b9af1ce9843a", size = 46437 }, +] + +[[package]] +name = "craft-grammar" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "overrides" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/d6/073514a6dd3f79fd82f73b0532df0f5dfc39c5ba548795a8c1406851e914/craft_grammar-2.0.1.tar.gz", hash = "sha256:fd6d90b49f3dc1705d9a745192d61192f2eeb42ecb316d7a2b921083d7601c5a", size = 48405 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/46/dc5c80ac98a005aebdad33ac1ade4e84b3967b7d0280f56dc41046ee0daa/craft_grammar-2.0.1-py3-none-any.whl", hash = "sha256:f72ee5d2a4f73bc75190111b1728b1da9968831fdaf0f4ded35122fb5ba39e3c", size = 23877 }, +] + +[[package]] +name = "craft-parts" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "overrides" }, + { name = "pydantic" }, + { name = "pyxdg" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "requests-unixsocket2" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/2f/299694e04ea30f21ab1638ab54342f38a711b198f5fbf0bb9f5a085053d0/craft_parts-2.3.0.tar.gz", hash = "sha256:96516a8a4314659f53f6f2999a38250f8bc5308bb41ac74df9b23e330aaa34ae", size = 639970 } + +[[package]] +name = "craft-platforms" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "distro" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/30/cb/898d65cfdde700565dc6339e09d919a6e0ac65e27486427ba4d7eb7f6434/craft_platforms-0.5.0.tar.gz", hash = "sha256:f41226163ca111517abd30fd3d1e8c16f08819eb3623b36e5a58d1db3ea8da21", size = 150900 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/d5/a1231182a3012239940ca84bc3b289d54eba7b5841a140439b03226bbd7a/craft_platforms-0.5.0-py3-none-any.whl", hash = "sha256:f80e0eee22174ddc888a938206716dcb7abf66d1161479206e47127091fdfec1", size = 22332 }, +] + +[[package]] +name = "craft-providers" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "requests-unixsocket2" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/29/1f/4c0eb72331e11ec8fec5cd24e993fe1e34ca04331251b90b8b6c7b1b72c7/craft_providers-2.1.0.tar.gz", hash = "sha256:9494a70cd0f86c13a746157bc1a54520e867656690f60d07d4ffdce39f60a99a", size = 180276 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/53/81f948ad5cd368bd7774b716e9afcae383ac8a389b7b462b214cd8981ade/craft_providers-2.1.0-py2.py3-none-any.whl", hash = "sha256:502e6fbb92435fac0db3bee0fcdaa84f0826880176b4635d896c5e4d429e3c5e", size = 97031 }, +] + +[[package]] +name = "craft-store" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "httpx" }, + { name = "jaraco-classes" }, + { name = "keyring" }, + { name = "macaroonbakery" }, + { name = "overrides" }, + { name = "pydantic" }, + { name = "pyxdg" }, + { name = "requests" }, + { name = "requests-toolbelt" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/51/8135945f2e2bad6a30c70fcfb6009194821818a730d306ee28c11e6a0273/craft_store-3.2.0.tar.gz", hash = "sha256:60bbe6b1e65b0b2691d0fe42df88ce0853df312507d2b853d2b508d7e5f80910", size = 200904 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/d7/39d43ec8a7df9082bce03f3fc82980501a5152c8a8f057a0caa97743cc36/craft_store-3.2.0-py3-none-any.whl", hash = "sha256:fb2feff7d4bebd0eba9f6b01916d6cad7c6cc69c10da5be3f2238856fd61294a", size = 53112 }, +] + +[[package]] +name = "cryptography" +version = "43.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0d/05/07b55d1fa21ac18c3a8c79f764e2514e6f6a9698f1be44994f5adf0d29db/cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", size = 686989 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/f3/01fdf26701a26f4b4dbc337a26883ad5bccaa6f1bbbdd29cd89e22f18a1c/cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e", size = 6225303 }, + { url = "https://files.pythonhosted.org/packages/a3/01/4896f3d1b392025d4fcbecf40fdea92d3df8662123f6835d0af828d148fd/cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e", size = 3760905 }, + { url = "https://files.pythonhosted.org/packages/0a/be/f9a1f673f0ed4b7f6c643164e513dbad28dd4f2dcdf5715004f172ef24b6/cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f", size = 3977271 }, + { url = "https://files.pythonhosted.org/packages/4e/49/80c3a7b5514d1b416d7350830e8c422a4d667b6d9b16a9392ebfd4a5388a/cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6", size = 3746606 }, + { url = "https://files.pythonhosted.org/packages/0e/16/a28ddf78ac6e7e3f25ebcef69ab15c2c6be5ff9743dd0709a69a4f968472/cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18", size = 3986484 }, + { url = "https://files.pythonhosted.org/packages/01/f5/69ae8da70c19864a32b0315049866c4d411cce423ec169993d0434218762/cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd", size = 3852131 }, + { url = "https://files.pythonhosted.org/packages/fd/db/e74911d95c040f9afd3612b1f732e52b3e517cb80de8bf183be0b7d413c6/cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73", size = 4075647 }, + { url = "https://files.pythonhosted.org/packages/56/48/7b6b190f1462818b324e674fa20d1d5ef3e24f2328675b9b16189cbf0b3c/cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2", size = 2623873 }, + { url = "https://files.pythonhosted.org/packages/eb/b1/0ebff61a004f7f89e7b65ca95f2f2375679d43d0290672f7713ee3162aff/cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd", size = 3068039 }, + { url = "https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984", size = 6222984 }, + { url = "https://files.pythonhosted.org/packages/2f/78/55356eb9075d0be6e81b59f45c7b48df87f76a20e73893872170471f3ee8/cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5", size = 3762968 }, + { url = "https://files.pythonhosted.org/packages/2a/2c/488776a3dc843f95f86d2f957ca0fc3407d0242b50bede7fad1e339be03f/cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4", size = 3977754 }, + { url = "https://files.pythonhosted.org/packages/7c/04/2345ca92f7a22f601a9c62961741ef7dd0127c39f7310dffa0041c80f16f/cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7", size = 3749458 }, + { url = "https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405", size = 3988220 }, + { url = "https://files.pythonhosted.org/packages/21/ce/b9c9ff56c7164d8e2edfb6c9305045fbc0df4508ccfdb13ee66eb8c95b0e/cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16", size = 3853898 }, + { url = "https://files.pythonhosted.org/packages/2a/33/b3682992ab2e9476b9c81fff22f02c8b0a1e6e1d49ee1750a67d85fd7ed2/cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73", size = 4076592 }, + { url = "https://files.pythonhosted.org/packages/81/1e/ffcc41b3cebd64ca90b28fd58141c5f68c83d48563c88333ab660e002cd3/cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995", size = 2623145 }, + { url = "https://files.pythonhosted.org/packages/87/5c/3dab83cc4aba1f4b0e733e3f0c3e7d4386440d660ba5b1e3ff995feb734d/cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362", size = 3068026 }, +] + +[[package]] +name = "cssutils" +version = "2.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "more-itertools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/9f/329d26121fe165be44b1dfff21aa0dc348f04633931f1d20ed6cf448a236/cssutils-2.11.1.tar.gz", hash = "sha256:0563a76513b6af6eebbe788c3bf3d01c920e46b3f90c8416738c5cfc773ff8e2", size = 711657 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/ec/bb273b7208c606890dc36540fe667d06ce840a6f62f9fae7e658fcdc90fb/cssutils-2.11.1-py3-none-any.whl", hash = "sha256:a67bfdfdff4f3867fab43698ec4897c1a828eca5973f4073321b3bccaf1199b1", size = 385747 }, +] + +[[package]] +name = "dict2css" +version = "0.3.0.post1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cssutils" }, + { name = "domdf-python-tools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/24/eb/776eef1f1aa0188c0fc165c3a60b71027539f71f2eedc43ad21b060e9c39/dict2css-0.3.0.post1.tar.gz", hash = "sha256:89c544c21c4ca7472c3fffb9d37d3d926f606329afdb751dc1de67a411b70719", size = 7845 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/47/290daabcf91628f4fc0e17c75a1690b354ba067066cd14407712600e609f/dict2css-0.3.0.post1-py3-none-any.whl", hash = "sha256:f006a6b774c3e31869015122ae82c491fd25e7de4a75607a62aa3e798f837e0d", size = 25647 }, +] + +[[package]] +name = "dill" +version = "0.3.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/43/86fe3f9e130c4137b0f1b50784dd70a5087b911fe07fa81e53e0c4c47fea/dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c", size = 187000 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a", size = 119418 }, +] + +[[package]] +name = "distro" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277 }, +] + +[[package]] +name = "docutils" +version = "0.19" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/330ea8d383eb2ce973df34d1239b3b21e91cd8c865d21ff82902d952f91f/docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6", size = 2056383 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/69/e391bd51bc08ed9141ecd899a0ddb61ab6465309f1eb470905c0c8868081/docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc", size = 570472 }, +] + +[[package]] +name = "domdf-python-tools" +version = "3.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "natsort" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6b/78/974e10c583ba9d2302e748c9585313a7f2c7ba00e4f600324f432e38fe68/domdf_python_tools-3.9.0.tar.gz", hash = "sha256:1f8a96971178333a55e083e35610d7688cd7620ad2b99790164e1fc1a3614c18", size = 103792 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/e9/7447a88b217650a74927d3444a89507986479a69b83741900eddd34167fe/domdf_python_tools-3.9.0-py3-none-any.whl", hash = "sha256:4e1ef365cbc24627d6d1e90cf7d46d8ab8df967e1237f4a26885f6986c78872e", size = 127106 }, +] + +[[package]] +name = "filelock" +version = "3.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/9c/0b15fb47b464e1b663b1acd1253a062aa5feecb07d4e597daea542ebd2b5/filelock-3.17.0.tar.gz", hash = "sha256:ee4e77401ef576ebb38cd7f13b9b28893194acc20a8e68e18730ba9c0e54660e", size = 18027 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/ec/00d68c4ddfedfe64159999e5f8a98fb8442729a63e2077eb9dcd89623d27/filelock-3.17.0-py3-none-any.whl", hash = "sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338", size = 16164 }, +] + +[[package]] +name = "fixtures" +version = "4.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pbr" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/21/79/a63e71f7663b380e0fe74c1673bca12e114884dc7c1a61408e9fcde3db28/fixtures-4.2.2.tar.gz", hash = "sha256:af9368737fad6fd501638ca99c78000c3f3fb03fa40a60f9e9d39aa64f342bc1", size = 59199 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/9e/ab77b2e316b2960b64277d8927ded0dc6f95c9cf8b4dba29fabd7680832f/fixtures-4.2.2-py3-none-any.whl", hash = "sha256:5cf7668cb1c0152c2cddeae32e898e83b93d07be78e481a2e786db87354fd0f0", size = 64537 }, +] + +[[package]] +name = "flake8" +version = "7.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mccabe" }, + { name = "pycodestyle" }, + { name = "pyflakes" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/72/e8d66150c4fcace3c0a450466aa3480506ba2cae7b61e100a2613afc3907/flake8-7.1.1.tar.gz", hash = "sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38", size = 48054 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/42/65004373ac4617464f35ed15931b30d764f53cdd30cc78d5aea349c8c050/flake8-7.1.1-py2.py3-none-any.whl", hash = "sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213", size = 57731 }, +] + +[[package]] +name = "furo" +version = "2024.8.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "pygments" }, + { name = "sphinx" }, + { name = "sphinx-basic-ng" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a0/e2/d351d69a9a9e4badb4a5be062c2d0e87bd9e6c23b5e57337fef14bef34c8/furo-2024.8.6.tar.gz", hash = "sha256:b63e4cee8abfc3136d3bc03a3d45a76a850bada4d6374d24c1716b0e01394a01", size = 1661506 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/48/e791a7ed487dbb9729ef32bb5d1af16693d8925f4366befef54119b2e576/furo-2024.8.6-py3-none-any.whl", hash = "sha256:6cd97c58b47813d3619e63e9081169880fbe331f0ca883c871ff1f3f11814f5c", size = 341333 }, +] + +[[package]] +name = "gitdb" +version = "4.0.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "smmap" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794 }, +] + +[[package]] +name = "gitpython" +version = "3.1.44" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gitdb" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/89/37df0b71473153574a5cdef8f242de422a0f5d26d7a9e231e6f169b4ad14/gitpython-3.1.44.tar.gz", hash = "sha256:c87e30b26253bf5418b01b0660f818967f3c503193838337fe5e573331249269", size = 214196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/9a/4114a9057db2f1462d5c8f8390ab7383925fe1ac012eaa42402ad65c2963/GitPython-3.1.44-py3-none-any.whl", hash = "sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110", size = 207599 }, +] + +[[package]] +name = "gnupg" +version = "2.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "psutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/6c/21f99b450d2f0821ff35343b9a7843b71e98de35192454606435c72991a8/gnupg-2.3.1.tar.gz", hash = "sha256:8db5a05c369dbc231dab4c98515ce828f2dffdc14f1534441a6c59b71c6d2031", size = 100437 } + +[[package]] +name = "h11" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, +] + +[[package]] +name = "html5lib" +version = "1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/b6/b55c3f49042f1df3dcd422b7f224f939892ee94f22abcf503a9b7339eaf2/html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f", size = 272215 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d", size = 112173 }, +] + +[[package]] +name = "httpcore" +version = "1.0.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 }, +] + +[[package]] +name = "httplib2" +version = "0.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/ad/2371116b22d616c194aa25ec410c9c6c37f23599dcd590502b74db197584/httplib2-0.22.0.tar.gz", hash = "sha256:d7a10bc5ef5ab08322488bde8c726eeee5c8618723fdb399597ec58f3d82df81", size = 351116 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/6c/d2fbdaaa5959339d53ba38e94c123e4e84b8fbc4b84beb0e70d7c1608486/httplib2-0.22.0-py3-none-any.whl", hash = "sha256:14ae0a53c1ba8f3d37e9e27cf37eabb0fb9980f435ba405d546948b009dd64dc", size = 96854 }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, +] + +[[package]] +name = "hupper" +version = "1.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/e6/bb064537288eee2be97f3e0fcad8e7242bc5bbe9664ae57c7d29b3fa18c2/hupper-1.12.1.tar.gz", hash = "sha256:06bf54170ff4ecf4c84ad5f188dee3901173ab449c2608ad05b9bfd6b13e32eb", size = 43231 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/7d/3888833e4f5ea56af4a9935066ec09a83228e533d7b8877f65889d706ee4/hupper-1.12.1-py3-none-any.whl", hash = "sha256:e872b959f09d90be5fb615bd2e62de89a0b57efc037bdf9637fb09cdf8552b19", size = 22830 }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769 }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "isort" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/28/b382d1656ac0ee4cef4bf579b13f9c6c813bff8a5cb5996669592c8c75fa/isort-6.0.0.tar.gz", hash = "sha256:75d9d8a1438a9432a7d7b54f2d3b45cad9a4a0fdba43617d9873379704a8bdf1", size = 828356 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c7/d6017f09ae5b1206fbe531f7af3b6dac1f67aedcbd2e79f3b386c27955d6/isort-6.0.0-py3-none-any.whl", hash = "sha256:567954102bb47bb12e0fae62606570faacddd441e45683968c8d1734fb1af892", size = 94053 }, +] + +[[package]] +name = "jaraco-classes" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "more-itertools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/c0/ed4a27bc5571b99e3cff68f8a9fa5b56ff7df1c2251cc715a652ddd26402/jaraco.classes-3.4.0.tar.gz", hash = "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", size = 11780 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl", hash = "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790", size = 6777 }, +] + +[[package]] +name = "jaraco-context" +version = "6.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/ad/f3777b81bf0b6e7bc7514a1656d3e637b2e8e15fab2ce3235730b3e7a4e6/jaraco_context-6.0.1.tar.gz", hash = "sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3", size = 13912 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/db/0c52c4cf5e4bd9f5d7135ec7669a3a767af21b3a308e1ed3674881e52b62/jaraco.context-6.0.1-py3-none-any.whl", hash = "sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4", size = 6825 }, +] + +[[package]] +name = "jaraco-functools" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "more-itertools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/23/9894b3df5d0a6eb44611c36aec777823fc2e07740dabbd0b810e19594013/jaraco_functools-4.1.0.tar.gz", hash = "sha256:70f7e0e2ae076498e212562325e805204fc092d7b4c17e0e86c959e249701a9d", size = 19159 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/4f/24b319316142c44283d7540e76c7b5a6dbd5db623abd86bb7b3491c21018/jaraco.functools-4.1.0-py3-none-any.whl", hash = "sha256:ad159f13428bc4acbf5541ad6dec511f91573b90fba04df61dafa2a1231cf649", size = 10187 }, +] + +[[package]] +name = "jeepney" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/f4/154cf374c2daf2020e05c3c6a03c91348d59b23c5366e968feb198306fdf/jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806", size = 106005 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/72/2a1e2290f1ab1e06f71f3d0f1646c9e4634e70e1d37491535e19266e8dc9/jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755", size = 48435 }, +] + +[[package]] +name = "jinja2" +version = "3.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/92/b3130cbbf5591acf9ade8708c365f3238046ac7cb8ccba6e81abccb0ccff/jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", size = 244674 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 }, +] + +[[package]] +name = "jsonschema" +version = "2.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/0d/c816f5ea5adaf1293a1d81d32e4cdfdaf8496973aa5049786d7fdb14e7e7/jsonschema-2.5.1.tar.gz", hash = "sha256:36673ac378feed3daa5956276a829699056523d7961027911f064b52255ead41", size = 50855 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/cc/5388547ea3504bd8cbf99ba2ae7a3231598f54038e9b228cbd174f8ec6a1/jsonschema-2.5.1-py2.py3-none-any.whl", hash = "sha256:71e7b3bcf9fca408bcb65bb60892f375d3abdd2e4f296eeeb8fe0bbbfcde598e", size = 38953 }, +] + +[[package]] +name = "keyring" +version = "25.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jaraco-classes" }, + { name = "jaraco-context" }, + { name = "jaraco-functools" }, + { name = "jeepney", marker = "sys_platform == 'linux'" }, + { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, + { name = "secretstorage", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/70/09/d904a6e96f76ff214be59e7aa6ef7190008f52a0ab6689760a98de0bf37d/keyring-25.6.0.tar.gz", hash = "sha256:0b39998aa941431eb3d9b0d4b2460bc773b9df6fed7621c2dfb291a7e0187a66", size = 62750 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/32/da7f44bcb1105d3e88a0b74ebdca50c59121d2ddf71c9e34ba47df7f3a56/keyring-25.6.0-py3-none-any.whl", hash = "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd", size = 39085 }, +] + +[[package]] +name = "launchpadlib" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httplib2" }, + { name = "lazr-restfulclient" }, + { name = "lazr-uri" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/30/ec/e659321733decaafe95d4cf964ce360b153de48c5725d5f27cefe97bf5f8/launchpadlib-2.1.0.tar.gz", hash = "sha256:b4c25890bb75050d54c08123d2733156b78a59a2555f5461f69b0e44cd91242f", size = 209860 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/a2/2fbbee98e88322446edc71a9ea662c8bf288e5199777545b4480d09bf3d1/launchpadlib-2.1.0-py3-none-any.whl", hash = "sha256:28ae51a8f09deb6506c7f72e47e21d37b28edba2a0d4a1bc7ebecca35168e2ac", size = 217563 }, +] + +[[package]] +name = "lazr-restfulclient" +version = "0.14.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distro" }, + { name = "httplib2" }, + { name = "oauthlib" }, + { name = "setuptools" }, + { name = "six" }, + { name = "wadllib" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ea/a3/45d80620a048c6f5d1acecbc244f00e65989914bca370a9179e3612aeec8/lazr.restfulclient-0.14.6.tar.gz", hash = "sha256:43f12a1d3948463b1462038c47b429dcb5e42e0ba7f2e16511b02ba5d2adffdb", size = 58590 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/de/0588cc50519e5b7ec75742d3e7cb7234298c95ef580b97f0ed3ac8fbc891/lazr.restfulclient-0.14.6-py2.py3-none-any.whl", hash = "sha256:97e95b1d8f0ec7fed998b48aea773baf8dcab06cf78a4deb9a046af5cca0cea2", size = 67413 }, +] + +[[package]] +name = "lazr-uri" +version = "1.0.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/53/de9135d731a077b1b4a30672720870abdb62577f18b1f323c87e6e61b96c/lazr_uri-1.0.7.tar.gz", hash = "sha256:ed0cf6f333e450114752afb1ce0c299c36ac4b109063eb50354c4f87f825a3ee", size = 20125 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/86/e9ebca51e6da2715d3dbd46fffc016df0613feff6c4a4ae025a0b18b1935/lazr.uri-1.0.7-py3-none-any.whl", hash = "sha256:a11441f9a1b5f1788d186b31dabd55d6a968fbc2bb434256c45a2cd2f5404825", size = 21487 }, +] + +[[package]] +name = "legacy-cgi" +version = "2.6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ad/2e/e1860989bc6cfdecba66db37f2f783636b97a1248ac25fbe864b6e931c22/legacy_cgi-2.6.2.tar.gz", hash = "sha256:9952471ceb304043b104c22d00b4f333cac27a6abe446d8a528fc437cf13c85f", size = 24794 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/cd/54d1fd92d7f6aca9523d8583052e00b273bdfe28aa7fd54a3a5759dab05e/legacy_cgi-2.6.2-py3-none-any.whl", hash = "sha256:a7b83afb1baf6ebeb56522537c5943ef9813cf933f6715e88a803f7edbce0bff", size = 19572 }, +] + +[[package]] +name = "license-expression" +version = "30.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "boolean-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/6f/8709031ea6e0573e6075d24ea34507b0eb32f83f10e1420f2e34606bf0da/license_expression-30.4.1.tar.gz", hash = "sha256:9f02105f9e0fcecba6a85dfbbed7d94ea1c3a70cf23ddbfb5adf3438a6f6fce0", size = 177184 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/84/8a89614b2e7eeeaf0a68a4046d6cfaea4544c8619ea02595ebeec9b2bae3/license_expression-30.4.1-py3-none-any.whl", hash = "sha256:679646bc3261a17690494a3e1cada446e5ee342dbd87dcfa4a0c24cc5dce13ee", size = 111457 }, +] + +[[package]] +name = "linkify-it-py" +version = "2.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "uc-micro-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/ae/bb56c6828e4797ba5a4821eec7c43b8bf40f69cda4d4f5f8c8a2810ec96a/linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048", size = 27946 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/1e/b832de447dee8b582cac175871d2f6c3d5077cc56d5575cadba1fd1cccfa/linkify_it_py-2.0.3-py3-none-any.whl", hash = "sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79", size = 19820 }, +] + +[[package]] +name = "lxml" +version = "5.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/6b/20c3a4b24751377aaa6307eb230b66701024012c29dd374999cc92983269/lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f", size = 3679318 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/6d/d1f1c5e40c64bf62afd7a3f9b34ce18a586a1cccbf71e783cd0a6d8e8971/lxml-5.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859", size = 8171753 }, + { url = "https://files.pythonhosted.org/packages/bd/83/26b1864921869784355459f374896dcf8b44d4af3b15d7697e9156cb2de9/lxml-5.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e", size = 4441955 }, + { url = "https://files.pythonhosted.org/packages/e0/d2/e9bff9fb359226c25cda3538f664f54f2804f4b37b0d7c944639e1a51f69/lxml-5.3.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f", size = 5050778 }, + { url = "https://files.pythonhosted.org/packages/88/69/6972bfafa8cd3ddc8562b126dd607011e218e17be313a8b1b9cc5a0ee876/lxml-5.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e", size = 4748628 }, + { url = "https://files.pythonhosted.org/packages/5d/ea/a6523c7c7f6dc755a6eed3d2f6d6646617cad4d3d6d8ce4ed71bfd2362c8/lxml-5.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179", size = 5322215 }, + { url = "https://files.pythonhosted.org/packages/99/37/396fbd24a70f62b31d988e4500f2068c7f3fd399d2fd45257d13eab51a6f/lxml-5.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a", size = 4813963 }, + { url = "https://files.pythonhosted.org/packages/09/91/e6136f17459a11ce1757df864b213efbeab7adcb2efa63efb1b846ab6723/lxml-5.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3", size = 4923353 }, + { url = "https://files.pythonhosted.org/packages/1d/7c/2eeecf87c9a1fca4f84f991067c693e67340f2b7127fc3eca8fa29d75ee3/lxml-5.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1", size = 4740541 }, + { url = "https://files.pythonhosted.org/packages/3b/ed/4c38ba58defca84f5f0d0ac2480fdcd99fc7ae4b28fc417c93640a6949ae/lxml-5.3.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d", size = 5346504 }, + { url = "https://files.pythonhosted.org/packages/a5/22/bbd3995437e5745cb4c2b5d89088d70ab19d4feabf8a27a24cecb9745464/lxml-5.3.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c", size = 4898077 }, + { url = "https://files.pythonhosted.org/packages/0a/6e/94537acfb5b8f18235d13186d247bca478fea5e87d224644e0fe907df976/lxml-5.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99", size = 4946543 }, + { url = "https://files.pythonhosted.org/packages/8d/e8/4b15df533fe8e8d53363b23a41df9be907330e1fa28c7ca36893fad338ee/lxml-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff", size = 4816841 }, + { url = "https://files.pythonhosted.org/packages/1a/e7/03f390ea37d1acda50bc538feb5b2bda6745b25731e4e76ab48fae7106bf/lxml-5.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a", size = 5417341 }, + { url = "https://files.pythonhosted.org/packages/ea/99/d1133ab4c250da85a883c3b60249d3d3e7c64f24faff494cf0fd23f91e80/lxml-5.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8", size = 5327539 }, + { url = "https://files.pythonhosted.org/packages/7d/ed/e6276c8d9668028213df01f598f385b05b55a4e1b4662ee12ef05dab35aa/lxml-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d", size = 5012542 }, + { url = "https://files.pythonhosted.org/packages/36/88/684d4e800f5aa28df2a991a6a622783fb73cf0e46235cfa690f9776f032e/lxml-5.3.0-cp312-cp312-win32.whl", hash = "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30", size = 3486454 }, + { url = "https://files.pythonhosted.org/packages/fc/82/ace5a5676051e60355bd8fb945df7b1ba4f4fb8447f2010fb816bfd57724/lxml-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f", size = 3816857 }, + { url = "https://files.pythonhosted.org/packages/94/6a/42141e4d373903bfea6f8e94b2f554d05506dfda522ada5343c651410dc8/lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a", size = 8156284 }, + { url = "https://files.pythonhosted.org/packages/91/5e/fa097f0f7d8b3d113fb7312c6308af702f2667f22644441715be961f2c7e/lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd", size = 4432407 }, + { url = "https://files.pythonhosted.org/packages/2d/a1/b901988aa6d4ff937f2e5cfc114e4ec561901ff00660c3e56713642728da/lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51", size = 5048331 }, + { url = "https://files.pythonhosted.org/packages/30/0f/b2a54f48e52de578b71bbe2a2f8160672a8a5e103df3a78da53907e8c7ed/lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b", size = 4744835 }, + { url = "https://files.pythonhosted.org/packages/82/9d/b000c15538b60934589e83826ecbc437a1586488d7c13f8ee5ff1f79a9b8/lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002", size = 5316649 }, + { url = "https://files.pythonhosted.org/packages/e3/ee/ffbb9eaff5e541922611d2c56b175c45893d1c0b8b11e5a497708a6a3b3b/lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4", size = 4812046 }, + { url = "https://files.pythonhosted.org/packages/15/ff/7ff89d567485c7b943cdac316087f16b2399a8b997007ed352a1248397e5/lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492", size = 4918597 }, + { url = "https://files.pythonhosted.org/packages/c6/a3/535b6ed8c048412ff51268bdf4bf1cf052a37aa7e31d2e6518038a883b29/lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3", size = 4738071 }, + { url = "https://files.pythonhosted.org/packages/7a/8f/cbbfa59cb4d4fd677fe183725a76d8c956495d7a3c7f111ab8f5e13d2e83/lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4", size = 5342213 }, + { url = "https://files.pythonhosted.org/packages/5c/fb/db4c10dd9958d4b52e34d1d1f7c1f434422aeaf6ae2bbaaff2264351d944/lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367", size = 4893749 }, + { url = "https://files.pythonhosted.org/packages/f2/38/bb4581c143957c47740de18a3281a0cab7722390a77cc6e610e8ebf2d736/lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832", size = 4945901 }, + { url = "https://files.pythonhosted.org/packages/fc/d5/18b7de4960c731e98037bd48fa9f8e6e8f2558e6fbca4303d9b14d21ef3b/lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff", size = 4815447 }, + { url = "https://files.pythonhosted.org/packages/97/a8/cd51ceaad6eb849246559a8ef60ae55065a3df550fc5fcd27014361c1bab/lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd", size = 5411186 }, + { url = "https://files.pythonhosted.org/packages/89/c3/1e3dabab519481ed7b1fdcba21dcfb8832f57000733ef0e71cf6d09a5e03/lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb", size = 5324481 }, + { url = "https://files.pythonhosted.org/packages/b6/17/71e9984cf0570cd202ac0a1c9ed5c1b8889b0fc8dc736f5ef0ffb181c284/lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b", size = 5011053 }, + { url = "https://files.pythonhosted.org/packages/69/68/9f7e6d3312a91e30829368c2b3217e750adef12a6f8eb10498249f4e8d72/lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957", size = 3485634 }, + { url = "https://files.pythonhosted.org/packages/7d/db/214290d58ad68c587bd5d6af3d34e56830438733d0d0856c0275fde43652/lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d", size = 3814417 }, +] + +[[package]] +name = "macaroonbakery" +version = "1.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, + { name = "pymacaroons" }, + { name = "pynacl" }, + { name = "pyrfc3339" }, + { name = "requests" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4b/ae/59f5ab870640bd43673b708e5f24aed592dc2673cc72caa49b0053b4af37/macaroonbakery-1.3.4.tar.gz", hash = "sha256:41ca993a23e4f8ef2fe7723b5cd4a30c759735f1d5021e990770c8a0e0f33970", size = 82143 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/42/227f748dc222b7a1c5cb40c7c74ab4162c7fc146b88980776b490ab673a1/macaroonbakery-1.3.4-py2.py3-none-any.whl", hash = "sha256:1e952a189f5c1e96ef82b081b2852c770d7daa20987e2088e762dd5689fb253b", size = 103184 }, +] + +[[package]] +name = "markdown" +version = "3.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/28/3af612670f82f4c056911fbbbb42760255801b3068c48de792d354ff4472/markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2", size = 357086 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/08/83871f3c50fc983b88547c196d11cf8c3340e37c32d2e9d6152abe2c61f7/Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803", size = 106349 }, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350 }, +] + +[[package]] +name = "mdit-py-plugins" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/03/a2ecab526543b152300717cf232bb4bb8605b6edb946c845016fa9c9c9fd/mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5", size = 43542 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636", size = 55316 }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, +] + +[[package]] +name = "more-itertools" +version = "10.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/88/3b/7fa1fe835e2e93fd6d7b52b2f95ae810cf5ba133e1845f726f5a992d62c2/more-itertools-10.6.0.tar.gz", hash = "sha256:2cd7fad1009c31cc9fb6a035108509e6547547a7a738374f10bd49a09eb3ee3b", size = 125009 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/62/0fe302c6d1be1c777cab0616e6302478251dfbf9055ad426f5d0def75c89/more_itertools-10.6.0-py3-none-any.whl", hash = "sha256:6eb054cb4b6db1473f6e15fcc676a08e4732548acd47c708f0e179c2c7c01e89", size = 63038 }, +] + +[[package]] +name = "msgpack" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/d0/7555686ae7ff5731205df1012ede15dd9d927f6227ea151e901c7406af4f/msgpack-1.1.0.tar.gz", hash = "sha256:dd432ccc2c72b914e4cb77afce64aab761c1137cc698be3984eee260bcb2896e", size = 167260 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/d6/716b7ca1dbde63290d2973d22bbef1b5032ca634c3ff4384a958ec3f093a/msgpack-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d46cf9e3705ea9485687aa4001a76e44748b609d260af21c4ceea7f2212a501d", size = 152421 }, + { url = "https://files.pythonhosted.org/packages/70/da/5312b067f6773429cec2f8f08b021c06af416bba340c912c2ec778539ed6/msgpack-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5dbad74103df937e1325cc4bfeaf57713be0b4f15e1c2da43ccdd836393e2ea2", size = 85277 }, + { url = "https://files.pythonhosted.org/packages/28/51/da7f3ae4462e8bb98af0d5bdf2707f1b8c65a0d4f496e46b6afb06cbc286/msgpack-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:58dfc47f8b102da61e8949708b3eafc3504509a5728f8b4ddef84bd9e16ad420", size = 82222 }, + { url = "https://files.pythonhosted.org/packages/33/af/dc95c4b2a49cff17ce47611ca9ba218198806cad7796c0b01d1e332c86bb/msgpack-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676e5be1b472909b2ee6356ff425ebedf5142427842aa06b4dfd5117d1ca8a2", size = 392971 }, + { url = "https://files.pythonhosted.org/packages/f1/54/65af8de681fa8255402c80eda2a501ba467921d5a7a028c9c22a2c2eedb5/msgpack-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17fb65dd0bec285907f68b15734a993ad3fc94332b5bb21b0435846228de1f39", size = 401403 }, + { url = "https://files.pythonhosted.org/packages/97/8c/e333690777bd33919ab7024269dc3c41c76ef5137b211d776fbb404bfead/msgpack-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a51abd48c6d8ac89e0cfd4fe177c61481aca2d5e7ba42044fd218cfd8ea9899f", size = 385356 }, + { url = "https://files.pythonhosted.org/packages/57/52/406795ba478dc1c890559dd4e89280fa86506608a28ccf3a72fbf45df9f5/msgpack-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2137773500afa5494a61b1208619e3871f75f27b03bcfca7b3a7023284140247", size = 383028 }, + { url = "https://files.pythonhosted.org/packages/e7/69/053b6549bf90a3acadcd8232eae03e2fefc87f066a5b9fbb37e2e608859f/msgpack-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:398b713459fea610861c8a7b62a6fec1882759f308ae0795b5413ff6a160cf3c", size = 391100 }, + { url = "https://files.pythonhosted.org/packages/23/f0/d4101d4da054f04274995ddc4086c2715d9b93111eb9ed49686c0f7ccc8a/msgpack-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:06f5fd2f6bb2a7914922d935d3b8bb4a7fff3a9a91cfce6d06c13bc42bec975b", size = 394254 }, + { url = "https://files.pythonhosted.org/packages/1c/12/cf07458f35d0d775ff3a2dc5559fa2e1fcd06c46f1ef510e594ebefdca01/msgpack-1.1.0-cp312-cp312-win32.whl", hash = "sha256:ad33e8400e4ec17ba782f7b9cf868977d867ed784a1f5f2ab46e7ba53b6e1e1b", size = 69085 }, + { url = "https://files.pythonhosted.org/packages/73/80/2708a4641f7d553a63bc934a3eb7214806b5b39d200133ca7f7afb0a53e8/msgpack-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:115a7af8ee9e8cddc10f87636767857e7e3717b7a2e97379dc2054712693e90f", size = 75347 }, + { url = "https://files.pythonhosted.org/packages/c8/b0/380f5f639543a4ac413e969109978feb1f3c66e931068f91ab6ab0f8be00/msgpack-1.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:071603e2f0771c45ad9bc65719291c568d4edf120b44eb36324dcb02a13bfddf", size = 151142 }, + { url = "https://files.pythonhosted.org/packages/c8/ee/be57e9702400a6cb2606883d55b05784fada898dfc7fd12608ab1fdb054e/msgpack-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0f92a83b84e7c0749e3f12821949d79485971f087604178026085f60ce109330", size = 84523 }, + { url = "https://files.pythonhosted.org/packages/7e/3a/2919f63acca3c119565449681ad08a2f84b2171ddfcff1dba6959db2cceb/msgpack-1.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1964df7b81285d00a84da4e70cb1383f2e665e0f1f2a7027e683956d04b734", size = 81556 }, + { url = "https://files.pythonhosted.org/packages/7c/43/a11113d9e5c1498c145a8925768ea2d5fce7cbab15c99cda655aa09947ed/msgpack-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59caf6a4ed0d164055ccff8fe31eddc0ebc07cf7326a2aaa0dbf7a4001cd823e", size = 392105 }, + { url = "https://files.pythonhosted.org/packages/2d/7b/2c1d74ca6c94f70a1add74a8393a0138172207dc5de6fc6269483519d048/msgpack-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0907e1a7119b337971a689153665764adc34e89175f9a34793307d9def08e6ca", size = 399979 }, + { url = "https://files.pythonhosted.org/packages/82/8c/cf64ae518c7b8efc763ca1f1348a96f0e37150061e777a8ea5430b413a74/msgpack-1.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65553c9b6da8166e819a6aa90ad15288599b340f91d18f60b2061f402b9a4915", size = 383816 }, + { url = "https://files.pythonhosted.org/packages/69/86/a847ef7a0f5ef3fa94ae20f52a4cacf596a4e4a010197fbcc27744eb9a83/msgpack-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7a946a8992941fea80ed4beae6bff74ffd7ee129a90b4dd5cf9c476a30e9708d", size = 380973 }, + { url = "https://files.pythonhosted.org/packages/aa/90/c74cf6e1126faa93185d3b830ee97246ecc4fe12cf9d2d31318ee4246994/msgpack-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4b51405e36e075193bc051315dbf29168d6141ae2500ba8cd80a522964e31434", size = 387435 }, + { url = "https://files.pythonhosted.org/packages/7a/40/631c238f1f338eb09f4acb0f34ab5862c4e9d7eda11c1b685471a4c5ea37/msgpack-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4c01941fd2ff87c2a934ee6055bda4ed353a7846b8d4f341c428109e9fcde8c", size = 399082 }, + { url = "https://files.pythonhosted.org/packages/e9/1b/fa8a952be252a1555ed39f97c06778e3aeb9123aa4cccc0fd2acd0b4e315/msgpack-1.1.0-cp313-cp313-win32.whl", hash = "sha256:7c9a35ce2c2573bada929e0b7b3576de647b0defbd25f5139dcdaba0ae35a4cc", size = 69037 }, + { url = "https://files.pythonhosted.org/packages/b6/bc/8bd826dd03e022153bfa1766dcdec4976d6c818865ed54223d71f07862b3/msgpack-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:bce7d9e614a04d0883af0b3d4d501171fbfca038f12c77fa838d9f198147a23f", size = 75140 }, +] + +[[package]] +name = "mypy" +version = "1.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/eb/2c92d8ea1e684440f54fa49ac5d9a5f19967b7b472a281f419e69a8d228e/mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", size = 3216051 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/1b/b38c079609bb4627905b74fc6a49849835acf68547ac33d8ceb707de5f52/mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", size = 11266668 }, + { url = "https://files.pythonhosted.org/packages/6b/75/2ed0d2964c1ffc9971c729f7a544e9cd34b2cdabbe2d11afd148d7838aa2/mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", size = 10254060 }, + { url = "https://files.pythonhosted.org/packages/a1/5f/7b8051552d4da3c51bbe8fcafffd76a6823779101a2b198d80886cd8f08e/mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", size = 11933167 }, + { url = "https://files.pythonhosted.org/packages/04/90/f53971d3ac39d8b68bbaab9a4c6c58c8caa4d5fd3d587d16f5927eeeabe1/mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", size = 12864341 }, + { url = "https://files.pythonhosted.org/packages/03/d2/8bc0aeaaf2e88c977db41583559319f1821c069e943ada2701e86d0430b7/mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89", size = 12972991 }, + { url = "https://files.pythonhosted.org/packages/6f/17/07815114b903b49b0f2cf7499f1c130e5aa459411596668267535fe9243c/mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", size = 9879016 }, + { url = "https://files.pythonhosted.org/packages/9e/15/bb6a686901f59222275ab228453de741185f9d54fecbaacec041679496c6/mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", size = 11252097 }, + { url = "https://files.pythonhosted.org/packages/f8/b3/8b0f74dfd072c802b7fa368829defdf3ee1566ba74c32a2cb2403f68024c/mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", size = 10239728 }, + { url = "https://files.pythonhosted.org/packages/c5/9b/4fd95ab20c52bb5b8c03cc49169be5905d931de17edfe4d9d2986800b52e/mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", size = 11924965 }, + { url = "https://files.pythonhosted.org/packages/56/9d/4a236b9c57f5d8f08ed346914b3f091a62dd7e19336b2b2a0d85485f82ff/mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", size = 12867660 }, + { url = "https://files.pythonhosted.org/packages/40/88/a61a5497e2f68d9027de2bb139c7bb9abaeb1be1584649fa9d807f80a338/mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", size = 12969198 }, + { url = "https://files.pythonhosted.org/packages/54/da/3d6fc5d92d324701b0c23fb413c853892bfe0e1dbe06c9138037d459756b/mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", size = 9885276 }, + { url = "https://files.pythonhosted.org/packages/a0/b5/32dd67b69a16d088e533962e5044e51004176a9952419de0370cdaead0f8/mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", size = 2752905 }, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, +] + +[[package]] +name = "myst-parser" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "jinja2" }, + { name = "markdown-it-py" }, + { name = "mdit-py-plugins" }, + { name = "pyyaml" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/55/6d1741a1780e5e65038b74bce6689da15f620261c490c3511eb4c12bac4b/myst_parser-4.0.0.tar.gz", hash = "sha256:851c9dfb44e36e56d15d05e72f02b80da21a9e0d07cba96baf5e2d476bb91531", size = 93858 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/b4/b036f8fdb667587bb37df29dc6644681dd78b7a2a6321a34684b79412b28/myst_parser-4.0.0-py3-none-any.whl", hash = "sha256:b9317997552424448c6096c2558872fdb6f81d3ecb3a40ce84a7518798f3f28d", size = 84563 }, +] + +[[package]] +name = "natsort" +version = "8.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/a9/a0c57aee75f77794adaf35322f8b6404cbd0f89ad45c87197a937764b7d0/natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581", size = 76575 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c", size = 38268 }, +] + +[[package]] +name = "oauthlib" +version = "3.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/fa/fbf4001037904031639e6bfbfc02badfc7e12f137a8afa254df6c4c8a670/oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918", size = 177352 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/80/cab10959dc1faead58dc8384a781dfbf93cb4d33d50988f7a69f1b7c9bbe/oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", size = 151688 }, +] + +[[package]] +name = "overrides" +version = "7.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "pastedeploy" +version = "3.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/97/0c4a613ec96a54d21daa7e089178263915554320402e89b4e319436a63cb/PasteDeploy-3.1.0.tar.gz", hash = "sha256:9ddbaf152f8095438a9fe81f82c78a6714b92ae8e066bed418b6a7ff6a095a95", size = 37841 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/30/cdddd9a88969683a59222a6d61cd6dce923977f2e9f9ffba38e1324149cd/PasteDeploy-3.1.0-py3-none-any.whl", hash = "sha256:76388ad53a661448d436df28c798063108f70e994ddc749540d733cdbd1b38cf", size = 16943 }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, +] + +[[package]] +name = "pbr" +version = "6.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/35/80cf8f6a4f34017a7fe28242dc45161a1baa55c41563c354d8147e8358b2/pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24", size = 124032 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/44/6a65ecd630393d47ad3e7d5354768cb7f9a10b3a0eb2cd8c6f52b28211ee/pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a", size = 108529 }, +] + +[[package]] +name = "pefile" +version = "2023.2.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/78/c5/3b3c62223f72e2360737fd2a57c30e5b2adecd85e70276879609a7403334/pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc", size = 74854 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/26/d0ad8b448476d0a1e8d3ea5622dc77b916db84c6aa3cb1e1c0965af948fc/pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6", size = 71791 }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772 }, +] + +[[package]] +name = "pip" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/47/3e/68beeeeb306ea20ffd30b3ed993f531d16cd884ec4f60c9b1e238f69f2af/pip-25.0.tar.gz", hash = "sha256:8e0a97f7b4c47ae4a494560da84775e9e2f671d415d8d828e052efefb206b30b", size = 1950328 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/8a/1ddf40be20103bcc605db840e9ade09c8e8c9f920a03e9cfe88eae97a058/pip-25.0-py3-none-any.whl", hash = "sha256:b6eb97a803356a52b2dd4bb73ba9e65b2ba16caa6bcb25a7497350a4e5859b65", size = 1841506 }, +] + +[[package]] +name = "plaster" +version = "1.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/93/66df0f87f1442d8afea8531ae8a4a9eca656006a54eac2b4489427e92c10/plaster-1.1.2.tar.gz", hash = "sha256:f8befc54bf8c1147c10ab40297ec84c2676fa2d4ea5d6f524d9436a80074ef98", size = 33232 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/8b/3f98db1448e3b4d2d142716874a7e02f6101685fdaa0f55a8668e9ffa048/plaster-1.1.2-py2.py3-none-any.whl", hash = "sha256:42992ab1f4865f1278e2ad740e8ad145683bb4022e03534265528f0c23c0df2d", size = 11554 }, +] + +[[package]] +name = "plaster-pastedeploy" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pastedeploy" }, + { name = "plaster" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c7/af/01a22f73ce97c6375c88d7ceaf6f5f4f345e940da93c94f98833d898a449/plaster_pastedeploy-1.0.1.tar.gz", hash = "sha256:be262e6d2e41a7264875daa2fe2850cbb0615728bcdc92828fdc72736e381412", size = 20915 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/30/2d4cf89035c22a89bf0e34dbc50fdc07c42c9bdc90fd972d495257ad2b6e/plaster_pastedeploy-1.0.1-py2.py3-none-any.whl", hash = "sha256:ad3550cc744648969ed3b810f33c9344f515ee8d8a8cec18e8f2c4a643c2181f", size = 7823 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "polib" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/10/9a/79b1067d27e38ddf84fe7da6ec516f1743f31f752c6122193e7bce38bdbf/polib-1.2.0.tar.gz", hash = "sha256:f3ef94aefed6e183e342a8a269ae1fc4742ba193186ad76f175938621dbfc26b", size = 161658 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/99/45bb1f9926efe370c6dbe324741c749658e44cb060124f28dad201202274/polib-1.2.0-py2.py3-none-any.whl", hash = "sha256:1c77ee1b81feb31df9bca258cbc58db1bbb32d10214b173882452c73af06d62d", size = 20634 }, +] + +[[package]] +name = "progressbar" +version = "2.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/a6/b8e451f6cff1c99b4747a2f7235aa904d2d49e8e1464e0b798272aa84358/progressbar-2.5.tar.gz", hash = "sha256:5d81cb529da2e223b53962afd6c8ca0f05c6670e40309a7219eacc36af9b6c63", size = 10046 } + +[[package]] +name = "protobuf" +version = "5.29.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/d1/e0a911544ca9993e0f17ce6d3cc0932752356c1b0a834397f28e63479344/protobuf-5.29.3.tar.gz", hash = "sha256:5da0f41edaf117bde316404bad1a486cb4ededf8e4a54891296f648e8e076620", size = 424945 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/7a/1e38f3cafa022f477ca0f57a1f49962f21ad25850c3ca0acd3b9d0091518/protobuf-5.29.3-cp310-abi3-win32.whl", hash = "sha256:3ea51771449e1035f26069c4c7fd51fba990d07bc55ba80701c78f886bf9c888", size = 422708 }, + { url = "https://files.pythonhosted.org/packages/61/fa/aae8e10512b83de633f2646506a6d835b151edf4b30d18d73afd01447253/protobuf-5.29.3-cp310-abi3-win_amd64.whl", hash = "sha256:a4fa6f80816a9a0678429e84973f2f98cbc218cca434abe8db2ad0bffc98503a", size = 434508 }, + { url = "https://files.pythonhosted.org/packages/dd/04/3eaedc2ba17a088961d0e3bd396eac764450f431621b58a04ce898acd126/protobuf-5.29.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a8434404bbf139aa9e1300dbf989667a83d42ddda9153d8ab76e0d5dcaca484e", size = 417825 }, + { url = "https://files.pythonhosted.org/packages/4f/06/7c467744d23c3979ce250397e26d8ad8eeb2bea7b18ca12ad58313c1b8d5/protobuf-5.29.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:daaf63f70f25e8689c072cfad4334ca0ac1d1e05a92fc15c54eb9cf23c3efd84", size = 319573 }, + { url = "https://files.pythonhosted.org/packages/a8/45/2ebbde52ad2be18d3675b6bee50e68cd73c9e0654de77d595540b5129df8/protobuf-5.29.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:c027e08a08be10b67c06bf2370b99c811c466398c357e615ca88c91c07f0910f", size = 319672 }, + { url = "https://files.pythonhosted.org/packages/fd/b2/ab07b09e0f6d143dfb839693aa05765257bceaa13d03bf1a696b78323e7a/protobuf-5.29.3-py3-none-any.whl", hash = "sha256:0a18ed4a24198528f2333802eb075e59dea9d679ab7a6c5efb017a59004d849f", size = 172550 }, +] + +[[package]] +name = "psutil" +version = "6.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/5a/07871137bb752428aa4b659f910b399ba6f291156bdea939be3e96cae7cb/psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5", size = 508502 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/99/ca79d302be46f7bdd8321089762dd4476ee725fce16fc2b2e1dbba8cac17/psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8", size = 247511 }, + { url = "https://files.pythonhosted.org/packages/0b/6b/73dbde0dd38f3782905d4587049b9be64d76671042fdcaf60e2430c6796d/psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377", size = 248985 }, + { url = "https://files.pythonhosted.org/packages/17/38/c319d31a1d3f88c5b79c68b3116c129e5133f1822157dd6da34043e32ed6/psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003", size = 284488 }, + { url = "https://files.pythonhosted.org/packages/9c/39/0f88a830a1c8a3aba27fededc642da37613c57cbff143412e3536f89784f/psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160", size = 287477 }, + { url = "https://files.pythonhosted.org/packages/47/da/99f4345d4ddf2845cb5b5bd0d93d554e84542d116934fde07a0c50bd4e9f/psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3", size = 289017 }, + { url = "https://files.pythonhosted.org/packages/38/53/bd755c2896f4461fd4f36fa6a6dcb66a88a9e4b9fd4e5b66a77cf9d4a584/psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53", size = 250602 }, + { url = "https://files.pythonhosted.org/packages/7b/d7/7831438e6c3ebbfa6e01a927127a6cb42ad3ab844247f3c5b96bea25d73d/psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649", size = 254444 }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993 }, +] + +[[package]] +name = "pyasynchat" +version = "1.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyasyncore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/fd/aacc6309abcc5a388c66915829cd8175daccac583828fde40a1eea5768e4/pyasynchat-1.0.4.tar.gz", hash = "sha256:3f5333df649e46c56d48c57e6a4b7163fd07f626bfd884e22ef373ab3c3a4670", size = 9747 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/4f/b4a7aa2a35858d40f970bdb63ab3e9deda35d0d2116b9175f929f37d764d/pyasynchat-1.0.4-py3-none-any.whl", hash = "sha256:167feb25d635a01b61338e17e9ab1e3372cd9274005af4083dcda52d51f64a76", size = 7753 }, +] + +[[package]] +name = "pyasyncore" +version = "1.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/6e/956e2bc9b47e3310cd524036f506b779a77788c2a1eb732e544240ad346f/pyasyncore-1.0.4.tar.gz", hash = "sha256:2c7a8b9b750ba6260f1e5a061456d61320a80579c6a43d42183417da89c7d5d6", size = 15339 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/46/aaa0999302d7a584a033ec23b6ca21a452cf9c7f6d8dce8d174ac407eb3f/pyasyncore-1.0.4-py3-none-any.whl", hash = "sha256:9e5f6dc9dc057c56370b7a5cdb4c4670fd4b0556de2913ed1f428cd6a5366895", size = 10032 }, +] + +[[package]] +name = "pycodestyle" +version = "2.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/aa/210b2c9aedd8c1cbeea31a50e42050ad56187754b34eb214c46709445801/pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521", size = 39232 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/d8/a211b3f85e99a0daa2ddec96c949cac6824bd305b040571b82a03dd62636/pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", size = 31284 }, +] + +[[package]] +name = "pycparser" +version = "2.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, +] + +[[package]] +name = "pydantic" +version = "2.10.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 }, +] + +[[package]] +name = "pydantic-core" +version = "2.27.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, + { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, + { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, + { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, + { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, + { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, + { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, + { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, + { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, + { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, + { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, + { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, + { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, + { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, + { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, + { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, + { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, + { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, + { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, + { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, + { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, + { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, + { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, + { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, + { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, + { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, + { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, + { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, +] + +[[package]] +name = "pyelftools" +version = "0.31" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/88/56/0f2d69ed9a0060da009f672ddec8a71c041d098a66f6b1d80264bf6bbdc0/pyelftools-0.31.tar.gz", hash = "sha256:c774416b10310156879443b81187d182d8d9ee499660380e645918b50bc88f99", size = 14108889 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/64/711030d9fe9ccaf6ee3ab1bcf4801c6bb3d0e585af18824a50b016b4f39c/pyelftools-0.31-py3-none-any.whl", hash = "sha256:f52de7b3c7e8c64c8abc04a79a1cf37ac5fb0b8a49809827130b858944840607", size = 180473 }, +] + +[[package]] +name = "pyflakes" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/f9/669d8c9c86613c9d568757c7f5824bd3197d7b1c6c27553bc5618a27cce2/pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", size = 63788 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/d7/f1b7db88d8e4417c5d47adad627a93547f44bdc9028372dbd2313f34a855/pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a", size = 62725 }, +] + +[[package]] +name = "pyftpdlib" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyasynchat" }, + { name = "pyasyncore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b4/0c/32bf0a7c88efe147bc3bc6586216d92269d196c59f149b05efa973834946/pyftpdlib-2.0.1.tar.gz", hash = "sha256:ef0d172a82bfae10e2dec222e87533514609d41bf4b0fd0f07e29d4380fb96bf", size = 202285 } + +[[package]] +name = "pygit2" +version = "1.13.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/09/50/f0795db653ceda94f4388d2b40598c188aa4990715909fabcf16b381b843/pygit2-1.13.3.tar.gz", hash = "sha256:0257c626011e4afb99bdb20875443f706f84201d4c92637f02215b98eac13ded", size = 752098 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/af/e874991f3513e5d56020bed5fbd278dcb1824aaf881d01c7a6436e089ecd/pygit2-1.13.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:07b17f766c88ce1d05d264b5819e75ad261f3b60e33e4105a71f02467d0f6d39", size = 5793582 }, + { url = "https://files.pythonhosted.org/packages/69/df/a391d29563431e9e107d26b871aebc7adc7a421f801747d4ffac0a29f86e/pygit2-1.13.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81bfe9ca394cdc896b632f18cd5f9c656a5f6c03c61deb1570b9081f2406776b", size = 4759604 }, + { url = "https://files.pythonhosted.org/packages/cb/f4/927fbb9b1bf35047c410fdcdf83867468248ebef8f45b2418fab540c45aa/pygit2-1.13.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c83e6e5ac357a9e87698c1eb25f430846f208bce12362d2209e7c9ac214e00c", size = 5055898 }, + { url = "https://files.pythonhosted.org/packages/6b/f2/fcf58c2b237d426e6f45b7d65fe14ee4e5f45aab5f674af1d82217086fb0/pygit2-1.13.3-cp312-cp312-win32.whl", hash = "sha256:de481a2cee7ef98143109bd9d2b30690022aeb8ba849feeba082a3b48a53c214", size = 1150594 }, + { url = "https://files.pythonhosted.org/packages/e3/53/69d648828082c2a1cf0c5204d2fcae22c80fdc8569d4421e0e48566f9009/pygit2-1.13.3-cp312-cp312-win_amd64.whl", hash = "sha256:0353b55f8bed1742dab15083ee9ee508ed91feb5c2563e2a612af277317030c6", size = 1232240 }, +] + +[[package]] +name = "pygments" +version = "2.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, +] + +[[package]] +name = "pyinstaller" +version = "6.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "altgraph" }, + { name = "packaging" }, + { name = "pefile", marker = "sys_platform == 'win32'" }, + { name = "pyinstaller-hooks-contrib" }, + { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/d4/54f5f5c73b803e6256ea97ffc6ba8a305d9a5f57f85f9b00b282512bf18a/pyinstaller-6.11.1.tar.gz", hash = "sha256:491dfb4d9d5d1d9650d9507daec1ff6829527a254d8e396badd60a0affcb72ef", size = 4249772 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/f0/98c9138f5f0ff17462f1ad6d712dcfa643b9a283d6238d464d8145bc139d/pyinstaller-6.11.1-py3-none-win32.whl", hash = "sha256:2e8365276c5131c9bef98e358fbc305e4022db8bedc9df479629d6414021956a", size = 1280261 }, + { url = "https://files.pythonhosted.org/packages/7d/08/f43080614b3e8bce481d4dfd580e579497c7dcdaf87656d9d2ad912e5796/pyinstaller-6.11.1-py3-none-win_amd64.whl", hash = "sha256:7ac83c0dc0e04357dab98c487e74ad2adb30e7eb186b58157a8faf46f1fa796f", size = 1340482 }, + { url = "https://files.pythonhosted.org/packages/ed/56/953c6594cb66e249563854c9cc04ac5a055c6c99d1614298feeaeaa9b87e/pyinstaller-6.11.1-py3-none-win_arm64.whl", hash = "sha256:35e6b8077d240600bb309ed68bb0b1453fd2b7ab740b66d000db7abae6244423", size = 1267519 }, +] + +[[package]] +name = "pyinstaller-hooks-contrib" +version = "2025.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/92/2e/eb876675aa5338f6ebb2d86dd91cc530542e054e9b6bce1ee938c14fdc07/pyinstaller_hooks_contrib-2025.0.tar.gz", hash = "sha256:6dc0b55a1acaab2ffee36ed4a05b073aa0a22e46f25fb5c66a31e217454135ed", size = 146002 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/46/f0654c01d3e16ee652e62dd59c8e80b67842d83d9c103d69d0654507954a/pyinstaller_hooks_contrib-2025.0-py3-none-any.whl", hash = "sha256:3c0623799c3f81a37293127f485d65894c20fd718f722cb588785a3e52581ad1", size = 344671 }, +] + +[[package]] +name = "pylint" +version = "3.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astroid" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "dill" }, + { name = "isort" }, + { name = "mccabe" }, + { name = "platformdirs" }, + { name = "tomlkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/b9/50be49afc91469f832c4bf12318ab4abe56ee9aa3700a89aad5359ad195f/pylint-3.3.4.tar.gz", hash = "sha256:74ae7a38b177e69a9b525d0794bd8183820bfa7eb68cc1bee6e8ed22a42be4ce", size = 1518905 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/8b/eef15df5f4e7aa393de31feb96ca9a3d6639669bd59d589d0685d5ef4e62/pylint-3.3.4-py3-none-any.whl", hash = "sha256:289e6a1eb27b453b08436478391a48cd53bb0efb824873f949e709350f3de018", size = 522280 }, +] + +[[package]] +name = "pylxd" +version = "2.3.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "python-dateutil" }, + { name = "requests" }, + { name = "requests-toolbelt" }, + { name = "ws4py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9b/8e/6a31a694560adaba20df521c3102bdecec06a0fea9c73ff1466834e2df30/pylxd-2.3.5.tar.gz", hash = "sha256:d67973dd2dc1728e3e1b41cc973e11e6cbceae87878d193ac04cc2b65a7158ef", size = 71781 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/44/ea48223c7fd42376cc9c6cdff3a8bf3cd19045a3c3722a2fcc9655cfd8a3/pylxd-2.3.5-py3-none-any.whl", hash = "sha256:f74affdb8a852c6241593c6bc022be1d6e2e700d9bc5efb180aeb7e7697a268d", size = 98084 }, +] + +[[package]] +name = "pymacaroons" +version = "0.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pynacl" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/37/b4/52ff00b59e91c4817ca60210c33caf11e85a7f68f7b361748ca2eb50923e/pymacaroons-0.13.0.tar.gz", hash = "sha256:1e6bba42a5f66c245adf38a5a4006a99dcc06a0703786ea636098667d42903b8", size = 21083 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/87/fd9b54258216e3f19671f6e9dd76da1ebc49e93ea0107c986b1071dd3068/pymacaroons-0.13.0-py2.py3-none-any.whl", hash = "sha256:3e14dff6a262fdbf1a15e769ce635a8aea72e6f8f91e408f9a97166c53b91907", size = 19463 }, +] + +[[package]] +name = "pynacl" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/22/27582568be639dfe22ddb3902225f91f2f17ceff88ce80e4db396c8986da/PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba", size = 3392854 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/75/0b8ede18506041c0bf23ac4d8e2971b4161cd6ce630b177d0a08eb0d8857/PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1", size = 349920 }, + { url = "https://files.pythonhosted.org/packages/59/bb/fddf10acd09637327a97ef89d2a9d621328850a72f1fdc8c08bdf72e385f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92", size = 601722 }, + { url = "https://files.pythonhosted.org/packages/5d/70/87a065c37cca41a75f2ce113a5a2c2aa7533be648b184ade58971b5f7ccc/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394", size = 680087 }, + { url = "https://files.pythonhosted.org/packages/ee/87/f1bb6a595f14a327e8285b9eb54d41fef76c585a0edef0a45f6fc95de125/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d", size = 856678 }, + { url = "https://files.pythonhosted.org/packages/66/28/ca86676b69bf9f90e710571b67450508484388bfce09acf8a46f0b8c785f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858", size = 1133660 }, + { url = "https://files.pythonhosted.org/packages/3d/85/c262db650e86812585e2bc59e497a8f59948a005325a11bbbc9ecd3fe26b/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b", size = 663824 }, + { url = "https://files.pythonhosted.org/packages/fd/1a/cc308a884bd299b651f1633acb978e8596c71c33ca85e9dc9fa33a5399b9/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff", size = 1117912 }, + { url = "https://files.pythonhosted.org/packages/25/2d/b7df6ddb0c2a33afdb358f8af6ea3b8c4d1196ca45497dd37a56f0c122be/PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543", size = 204624 }, + { url = "https://files.pythonhosted.org/packages/5e/22/d3db169895faaf3e2eda892f005f433a62db2decbcfbc2f61e6517adfa87/PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93", size = 212141 }, +] + +[[package]] +name = "pyparsing" +version = "3.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/1a/3544f4f299a47911c2ab3710f534e52fea62a633c96806995da5d25be4b2/pyparsing-3.2.1.tar.gz", hash = "sha256:61980854fd66de3a90028d679a954d5f2623e83144b5afe5ee86f43d762e5f0a", size = 1067694 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/a7/c8a2d361bf89c0d9577c934ebb7421b25dc84bf3a8e3ac0a40aed9acc547/pyparsing-3.2.1-py3-none-any.whl", hash = "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1", size = 107716 }, +] + +[[package]] +name = "pyramid" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "hupper" }, + { name = "plaster" }, + { name = "plaster-pastedeploy" }, + { name = "setuptools" }, + { name = "translationstring" }, + { name = "venusian" }, + { name = "webob" }, + { name = "zope-deprecation" }, + { name = "zope-interface" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/47/c3/5d5736e692fc7ff052577f03136b5edfdf1e2e177eff2f4b91206acae11d/pyramid-2.0.2.tar.gz", hash = "sha256:372138a738e4216535cc76dcce6eddd5a1aaca95130f2354fb834264c06f18de", size = 2637533 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/41/a2114b8dd2187ae007e022a2baabdc7937cc78211cefc0c01fc5452193af/pyramid-2.0.2-py3-none-any.whl", hash = "sha256:2e6585ac55c147f0a51bc00dadf72075b3bdd9a871b332ff9e5e04117ccd76fa", size = 247277 }, +] + +[[package]] +name = "pyrfc3339" +version = "1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytz" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/52/75ea0ae249ba885c9429e421b4f94bc154df68484847f1ac164287d978d7/pyRFC3339-1.1.tar.gz", hash = "sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a", size = 5290 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/7a/725f5c16756ec6211b1e7eeac09f469084595513917ea069bc023c40a5e2/pyRFC3339-1.1-py2.py3-none-any.whl", hash = "sha256:67196cb83b470709c580bb4738b83165e67c6cc60e1f2e4f286cfcb402a926f4", size = 5669 }, +] + +[[package]] +name = "pyspelling" +version = "2.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "html5lib" }, + { name = "lxml" }, + { name = "markdown" }, + { name = "pyyaml" }, + { name = "soupsieve" }, + { name = "wcmatch" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/12/07/168a857755a29b7e41550a28cd8f527025bc62fcb36a951d8f3f2eedcdf7/pyspelling-2.10.tar.gz", hash = "sha256:acd67133c1b7cecd410e3d4489e61f2e4b1f0b6acf1ae6c48c240fbb21729c37", size = 148239 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/16/242558b5c5cb73efd52490f1e6bfb03eae63b2585770b9cae78bd491ef0b/pyspelling-2.10-py3-none-any.whl", hash = "sha256:9b079dd238bd0616a49f9ac5df32799beb851dddc5ed7634f551e7df1aeee943", size = 45035 }, +] + +[[package]] +name = "pytest" +version = "8.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, +] + +[[package]] +name = "pytest-check" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/15/d3/178a723f0420cf4e06fb6ddf43fc1ec68c1d0d4ea3db1ecf8f6df21b345f/pytest_check-2.4.1.tar.gz", hash = "sha256:5224efcef059bf7f0cda253f8d0f62704b4819ff48c93f51c675aea6a014f650", size = 28933 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/25/465756acbb66db47ad40e0be6b457d8644c7b9f882b2ff7f5e92dde07915/pytest_check-2.4.1-py3-none-any.whl", hash = "sha256:74f38938183880d9921aeb85662437d2b13e1e053e1bed7d186d54613d3068c7", size = 13789 }, +] + +[[package]] +name = "pytest-cov" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949 }, +] + +[[package]] +name = "pytest-mock" +version = "3.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863 }, +] + +[[package]] +name = "pytest-subprocess" +version = "1.5.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/32/ae/3ad5c609a5088936608af12f42ad72567a877d3c64303500ebc3b7df0297/pytest_subprocess-1.5.3.tar.gz", hash = "sha256:c00b1140fb0211b3153e09500d770db10770baccbe6e05ee9c140036d1d811d5", size = 42282 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/82/a038e8fdb86d5494a39b8730547ec79767731d02ecb556121e40c0892803/pytest_subprocess-1.5.3-py3-none-any.whl", hash = "sha256:b62580f5a84335fb9f2ec65d49e56a3c93f4722c148fe1771a002835d310a75b", size = 21759 }, +] + +[[package]] +name = "python-apt" +version = "0.0.0" +source = { url = "https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz" } +sdist = { hash = "sha256:a895e4d38d04e86f89251d264760837887ddb420fe195e0b576d8a382fb5999e" } + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, +] + +[[package]] +name = "python-debian" +version = "0.1.49" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "chardet" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/8d/2ebc549adf1f623d4044b108b30ff5cdac5756b0384cd9dddac63fe53eae/python-debian-0.1.49.tar.gz", hash = "sha256:8cf677a30dbcb4be7a99536c17e11308a827a4d22028dc59a67f6c6dd3f0f58c", size = 121690 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/37/6e38e7aafa55c1257f63ca9f575e8e3cf2560c896c5202a16c9f33ee7657/python_debian-0.1.49-py3-none-any.whl", hash = "sha256:880f3bc52e31599f2a9b432bd7691844286825087fccdcf2f6ffd5cd79a26f9f", size = 132460 }, +] + +[[package]] +name = "pytz" +version = "2024.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, +] + +[[package]] +name = "pywin32" +version = "308" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/7c/d00d6bdd96de4344e06c4afbf218bc86b54436a94c01c71a8701f613aa56/pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897", size = 5939729 }, + { url = "https://files.pythonhosted.org/packages/21/27/0c8811fbc3ca188f93b5354e7c286eb91f80a53afa4e11007ef661afa746/pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47", size = 6543015 }, + { url = "https://files.pythonhosted.org/packages/9d/0f/d40f8373608caed2255781a3ad9a51d03a594a1248cd632d6a298daca693/pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091", size = 7976033 }, + { url = "https://files.pythonhosted.org/packages/a9/a4/aa562d8935e3df5e49c161b427a3a2efad2ed4e9cf81c3de636f1fdddfd0/pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed", size = 5938579 }, + { url = "https://files.pythonhosted.org/packages/c7/50/b0efb8bb66210da67a53ab95fd7a98826a97ee21f1d22949863e6d588b22/pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4", size = 6542056 }, + { url = "https://files.pythonhosted.org/packages/26/df/2b63e3e4f2df0224f8aaf6d131f54fe4e8c96400eb9df563e2aae2e1a1f9/pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd", size = 7974986 }, +] + +[[package]] +name = "pywin32-ctypes" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", size = 29471 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8", size = 30756 }, +] + +[[package]] +name = "pyxdg" +version = "0.28" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/25/7998cd2dec731acbd438fbf91bc619603fc5188de0a9a17699a781840452/pyxdg-0.28.tar.gz", hash = "sha256:3267bb3074e934df202af2ee0868575484108581e6f3cb006af1da35395e88b4", size = 77776 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/8d/cf41b66a8110670e3ad03dab9b759704eeed07fa96e90fdc0357b2ba70e2/pyxdg-0.28-py2.py3-none-any.whl", hash = "sha256:bdaf595999a0178ecea4052b7f4195569c1ff4d344567bccdc12dfdf02d545ab", size = 49520 }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, +] + +[[package]] +name = "raven" +version = "6.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/57/b74a86d74f96b224a477316d418389af9738ba7a63c829477e7a86dd6f47/raven-6.10.0.tar.gz", hash = "sha256:3fa6de6efa2493a7c827472e984ce9b020797d0da16f1db67197bcc23c8fae54", size = 288902 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/8e/62e26a88c0a1bbae677200baf0767c1022321a6555634f8129e6d55c5ddc/raven-6.10.0-py2.py3-none-any.whl", hash = "sha256:44a13f87670836e153951af9a3c80405d36b43097db869a36e92809673692ce4", size = 284314 }, +] + +[[package]] +name = "regex" +version = "2024.11.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", size = 483781 }, + { url = "https://files.pythonhosted.org/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", size = 288455 }, + { url = "https://files.pythonhosted.org/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", size = 284759 }, + { url = "https://files.pythonhosted.org/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", size = 794976 }, + { url = "https://files.pythonhosted.org/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", size = 833077 }, + { url = "https://files.pythonhosted.org/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", size = 823160 }, + { url = "https://files.pythonhosted.org/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", size = 796896 }, + { url = "https://files.pythonhosted.org/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", size = 783997 }, + { url = "https://files.pythonhosted.org/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", size = 781725 }, + { url = "https://files.pythonhosted.org/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", size = 789481 }, + { url = "https://files.pythonhosted.org/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", size = 852896 }, + { url = "https://files.pythonhosted.org/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", size = 860138 }, + { url = "https://files.pythonhosted.org/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", size = 787692 }, + { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135 }, + { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567 }, + { url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525 }, + { url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324 }, + { url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617 }, + { url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023 }, + { url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072 }, + { url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130 }, + { url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857 }, + { url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006 }, + { url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650 }, + { url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545 }, + { url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045 }, + { url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182 }, + { url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733 }, + { url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122 }, + { url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545 }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, +] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481 }, +] + +[[package]] +name = "requests-unixsocket2" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/14/66/88737c8720685f44e6a1c04cb2185301a6ec4538ac82324f0f33c9dc5fd5/requests_unixsocket2-0.4.2.tar.gz", hash = "sha256:929c58ecc5981f3d127661ceb9ec8c76e0f08d31c52e44ab1462ac0dcd55b5f5", size = 6367 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/34/b1072b2b1310572d8b801adcf3b148197eea2f8207f3750f73fcd2a6db5d/requests_unixsocket2-0.4.2-py3-none-any.whl", hash = "sha256:701fcd49d74bc0f759bbe45c4dfda0045fd89652948c2b473b1a312214c3770b", size = 7786 }, +] + +[[package]] +name = "ruamel-yaml" +version = "0.18.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ruamel-yaml-clib", marker = "python_full_version < '3.13' and platform_python_implementation == 'CPython'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ea/46/f44d8be06b85bc7c4d8c95d658be2b68f27711f279bf9dd0612a5e4794f5/ruamel.yaml-0.18.10.tar.gz", hash = "sha256:20c86ab29ac2153f80a428e1254a8adf686d3383df04490514ca3b79a362db58", size = 143447 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/36/dfc1ebc0081e6d39924a2cc53654497f967a084a436bb64402dfce4254d9/ruamel.yaml-0.18.10-py3-none-any.whl", hash = "sha256:30f22513ab2301b3d2b577adc121c6471f28734d3d9728581245f1e76468b4f1", size = 117729 }, +] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f", size = 225315 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433 }, + { url = "https://files.pythonhosted.org/packages/ec/b0/b850385604334c2ce90e3ee1013bd911aedf058a934905863a6ea95e9eb4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d", size = 647362 }, + { url = "https://files.pythonhosted.org/packages/44/d0/3f68a86e006448fb6c005aee66565b9eb89014a70c491d70c08de597f8e4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c", size = 754118 }, + { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497 }, + { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042 }, + { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831 }, + { url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d", size = 715692 }, + { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777 }, + { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523 }, + { url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a", size = 132011 }, + { url = "https://files.pythonhosted.org/packages/7f/5e/212f473a93ae78c669ffa0cb051e3fee1139cb2d385d2ae1653d64281507/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475", size = 642488 }, + { url = "https://files.pythonhosted.org/packages/1f/8f/ecfbe2123ade605c49ef769788f79c38ddb1c8fa81e01f4dbf5cf1a44b16/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef", size = 745066 }, + { url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6", size = 701785 }, + { url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf", size = 693017 }, + { url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1", size = 741270 }, + { url = "https://files.pythonhosted.org/packages/87/b8/01c29b924dcbbed75cc45b30c30d565d763b9c4d540545a0eeecffb8f09c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01", size = 709059 }, + { url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6", size = 98583 }, + { url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3", size = 115190 }, +] + +[[package]] +name = "secretstorage" +version = "3.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "jeepney" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/53/a4/f48c9d79cb507ed1373477dbceaba7401fd8a23af63b837fa61f1dcd3691/SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77", size = 19739 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/24/b4293291fa1dd830f353d2cb163295742fa87f179fcc8a20a306a81978b7/SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99", size = 15221 }, +] + +[[package]] +name = "setuptools" +version = "75.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/92/ec/089608b791d210aec4e7f97488e67ab0d33add3efccb83a056cbafe3a2a6/setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6", size = 1343222 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/8a/b9dc7678803429e4a3bc9ba462fa3dd9066824d3c607490235c6a796be5a/setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3", size = 1228782 }, +] + +[[package]] +name = "simplejson" +version = "3.19.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/29/085111f19717f865eceaf0d4397bf3e76b08d60428b076b64e2a1903706d/simplejson-3.19.3.tar.gz", hash = "sha256:8e086896c36210ab6050f2f9f095a5f1e03c83fa0e7f296d6cba425411364680", size = 85237 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/15/513fea93fafbdd4993eacfcb762965b2ff3d29e618c029e2956174d68c4b/simplejson-3.19.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:66a0399e21c2112acacfebf3d832ebe2884f823b1c7e6d1363f2944f1db31a99", size = 92921 }, + { url = "https://files.pythonhosted.org/packages/a4/4f/998a907ae1a6c104dc0ee48aa248c2478490152808d34d8e07af57f396c3/simplejson-3.19.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6ef9383c5e05f445be60f1735c1816163c874c0b1ede8bb4390aff2ced34f333", size = 75311 }, + { url = "https://files.pythonhosted.org/packages/db/44/acd6122201e927451869d45952b9ab1d3025cdb5e61548d286d08fbccc08/simplejson-3.19.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:42e5acf80d4d971238d4df97811286a044d720693092b20a56d5e56b7dcc5d09", size = 74964 }, + { url = "https://files.pythonhosted.org/packages/27/ca/d0a1e8f16e1bbdc0b8c6d88166f45f565ed7285f53928cfef3b6ce78f14d/simplejson-3.19.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0b0efc7279d768db7c74d3d07f0b5c81280d16ae3fb14e9081dc903e8360771", size = 150106 }, + { url = "https://files.pythonhosted.org/packages/63/59/0554b78cf26c98e2b9cae3f44723bd72c2394e2afec1a14eedc6211f7187/simplejson-3.19.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0552eb06e7234da892e1d02365cd2b7b2b1f8233aa5aabdb2981587b7cc92ea0", size = 158347 }, + { url = "https://files.pythonhosted.org/packages/b2/fe/9f30890352e431e8508cc569912d3322147d3e7e4f321e48c0adfcb4c97d/simplejson-3.19.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf6a3b9a7d7191471b464fe38f684df10eb491ec9ea454003edb45a011ab187", size = 148456 }, + { url = "https://files.pythonhosted.org/packages/37/e3/663a09542ee021d4131162f7a164cb2e7f04ef48433a67591738afbf12ea/simplejson-3.19.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7017329ca8d4dca94ad5e59f496e5fc77630aecfc39df381ffc1d37fb6b25832", size = 152190 }, + { url = "https://files.pythonhosted.org/packages/31/20/4e0c4d35e10ff6465003bec304316d822a559a1c38c66ef6892ca199c207/simplejson-3.19.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:67a20641afebf4cfbcff50061f07daad1eace6e7b31d7622b6fa2c40d43900ba", size = 149846 }, + { url = "https://files.pythonhosted.org/packages/08/7a/46e2e072cac3987cbb05946f25167f0ad2fe536748e7405953fd6661a486/simplejson-3.19.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:dd6a7dabcc4c32daf601bc45e01b79175dde4b52548becea4f9545b0a4428169", size = 151714 }, + { url = "https://files.pythonhosted.org/packages/7f/7d/dbeeac10eb61d5d8858d0bb51121a21050d281dc83af4c557f86da28746c/simplejson-3.19.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:08f9b443a94e72dd02c87098c96886d35790e79e46b24e67accafbf13b73d43b", size = 158777 }, + { url = "https://files.pythonhosted.org/packages/fc/8f/a98bdbb799c6a4a884b5823db31785a96ba895b4b0f4d8ac345d6fe98bbf/simplejson-3.19.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fa97278ae6614346b5ca41a45a911f37a3261b57dbe4a00602048652c862c28b", size = 154230 }, + { url = "https://files.pythonhosted.org/packages/b1/db/852eebceb85f969ae40e06babed1a93d3bacb536f187d7a80ff5823a5979/simplejson-3.19.3-cp312-cp312-win32.whl", hash = "sha256:ef28c3b328d29b5e2756903aed888960bc5df39b4c2eab157ae212f70ed5bf74", size = 74002 }, + { url = "https://files.pythonhosted.org/packages/fe/68/9f0e5df0651cb79ef83cba1378765a00ee8038e6201cc82b8e7178a7778e/simplejson-3.19.3-cp312-cp312-win_amd64.whl", hash = "sha256:1e662336db50ad665777e6548b5076329a94a0c3d4a0472971c588b3ef27de3a", size = 75596 }, + { url = "https://files.pythonhosted.org/packages/93/3a/5896821ed543899fcb9c4256c7e71bb110048047349a00f42bc8b8fb379f/simplejson-3.19.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0959e6cb62e3994b5a40e31047ff97ef5c4138875fae31659bead691bed55896", size = 92931 }, + { url = "https://files.pythonhosted.org/packages/39/15/5d33d269440912ee40d856db0c8be2b91aba7a219690ab01f86cb0edd590/simplejson-3.19.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a7bfad839c624e139a4863007233a3f194e7c51551081f9789cba52e4da5167", size = 75318 }, + { url = "https://files.pythonhosted.org/packages/2a/8d/2e7483a2bf7ec53acf7e012bafbda79d7b34f90471dda8e424544a59d484/simplejson-3.19.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afab2f7f2486a866ff04d6d905e9386ca6a231379181a3838abce1f32fbdcc37", size = 74971 }, + { url = "https://files.pythonhosted.org/packages/4d/9d/9bdf34437c8834a7cf7246f85e9d5122e30579f512c10a0c2560e994294f/simplejson-3.19.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d00313681015ac498e1736b304446ee6d1c72c5b287cd196996dad84369998f7", size = 150112 }, + { url = "https://files.pythonhosted.org/packages/a7/e2/1f2ae2d89eaf85f6163c82150180aae5eaa18085cfaf892f8a57d4c51cbd/simplejson-3.19.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d936ae682d5b878af9d9eb4d8bb1fdd5e41275c8eb59ceddb0aeed857bb264a2", size = 158354 }, + { url = "https://files.pythonhosted.org/packages/60/83/26f610adf234c8492b3f30501e12f2271e67790f946c6898fe0c58aefe99/simplejson-3.19.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c6657485393f2e9b8177c77a7634f13ebe70d5e6de150aae1677d91516ce6b", size = 148455 }, + { url = "https://files.pythonhosted.org/packages/b5/4b/109af50006af77133653c55b5b91b4bd2d579ff8254ce11216c0b75f911b/simplejson-3.19.3-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a6a750d3c7461b1c47cfc6bba8d9e57a455e7c5f80057d2a82f738040dd1129", size = 152191 }, + { url = "https://files.pythonhosted.org/packages/75/dc/108872a8825cbd99ae6f4334e0490ff1580367baf12198bcaf988f6820ba/simplejson-3.19.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ea7a4a998c87c5674a27089e022110a1a08a7753f21af3baf09efe9915c23c3c", size = 149954 }, + { url = "https://files.pythonhosted.org/packages/eb/be/deec1d947a5d0472276ab4a4d1a9378dc5ee27f3dc9e54d4f62ffbad7a08/simplejson-3.19.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6300680d83a399be2b8f3b0ef7ef90b35d2a29fe6e9c21438097e0938bbc1564", size = 151812 }, + { url = "https://files.pythonhosted.org/packages/e9/58/4ee130702d36b1551ef66e7587eefe56651f3669255bf748cd71691e2434/simplejson-3.19.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ab69f811a660c362651ae395eba8ce84f84c944cea0df5718ea0ba9d1e4e7252", size = 158880 }, + { url = "https://files.pythonhosted.org/packages/0f/e1/59cc6a371b60f89e3498d9f4c8109f6b7359094d453f5fe80b2677b777b0/simplejson-3.19.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:256e09d0f94d9c3d177d9e95fd27a68c875a4baa2046633df387b86b652f5747", size = 154344 }, + { url = "https://files.pythonhosted.org/packages/79/45/1b36044670016f5cb25ebd92497427d2d1711ecb454d00f71eb9a00b77cc/simplejson-3.19.3-cp313-cp313-win32.whl", hash = "sha256:2c78293470313aefa9cfc5e3f75ca0635721fb016fb1121c1c5b0cb8cc74712a", size = 74002 }, + { url = "https://files.pythonhosted.org/packages/e2/58/b06226e6b0612f2b1fa13d5273551da259f894566b1eef32249ddfdcce44/simplejson-3.19.3-cp313-cp313-win_amd64.whl", hash = "sha256:3bbcdc438dc1683b35f7a8dc100960c721f922f9ede8127f63bed7dfded4c64c", size = 75599 }, + { url = "https://files.pythonhosted.org/packages/0d/e7/f9fafbd4f39793a20cc52e77bbd766f7384312526d402c382928dc7667f6/simplejson-3.19.3-py3-none-any.whl", hash = "sha256:49cc4c7b940d43bd12bf87ec63f28cbc4964fc4e12c031cc8cd01650f43eb94e", size = 57004 }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, +] + +[[package]] +name = "smmap" +version = "5.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303 }, +] + +[[package]] +name = "snap-helpers" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/2a/221ab0a9c0200065bdd8a5d2b131997e3e19ce81832fdf8138a7f5247216/snap-helpers-0.4.2.tar.gz", hash = "sha256:ef3b8621e331bb71afe27e54ef742a7dd2edd9e8026afac285beb42109c8b9a9", size = 20100 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/2c/c1304eb8787bbed23cfc0b07cee6b21e1310ceb6a6f7a4193dab02525c91/snap_helpers-0.4.2-py3-none-any.whl", hash = "sha256:04d0ebd167c943849c99ec68b87829fef4a915cbe9b02d8afc3891d889327327", size = 22805 }, +] + +[[package]] +name = "snapcraft" +source = { editable = "." } +dependencies = [ + { name = "attrs" }, + { name = "catkin-pkg", marker = "sys_platform == 'linux'" }, + { name = "click" }, + { name = "craft-application" }, + { name = "craft-archives" }, + { name = "craft-cli" }, + { name = "craft-grammar" }, + { name = "craft-parts" }, + { name = "craft-platforms" }, + { name = "craft-store" }, + { name = "cryptography" }, + { name = "docutils" }, + { name = "gnupg" }, + { name = "jsonschema" }, + { name = "launchpadlib" }, + { name = "lazr-restfulclient" }, + { name = "lxml" }, + { name = "macaroonbakery" }, + { name = "mypy-extensions" }, + { name = "overrides" }, + { name = "packaging" }, + { name = "progressbar" }, + { name = "pydantic" }, + { name = "pyelftools" }, + { name = "pygit2" }, + { name = "pylxd", marker = "sys_platform == 'linux'" }, + { name = "pymacaroons" }, + { name = "python-apt", marker = "sys_platform == 'linux'" }, + { name = "python-debian", marker = "sys_platform == 'linux'" }, + { name = "pyxdg" }, + { name = "pyyaml" }, + { name = "raven" }, + { name = "requests" }, + { name = "requests-toolbelt" }, + { name = "requests-unixsocket2" }, + { name = "simplejson" }, + { name = "snap-helpers" }, + { name = "tabulate" }, + { name = "tinydb" }, + { name = "toml" }, + { name = "typing-extensions" }, + { name = "validators" }, +] + +[package.dev-dependencies] +dev = [ + { name = "coverage" }, + { name = "fixtures" }, + { name = "flake8" }, + { name = "mccabe" }, + { name = "pexpect" }, + { name = "pip" }, + { name = "pycodestyle" }, + { name = "pyflakes" }, + { name = "pyftpdlib" }, + { name = "pyinstaller", marker = "sys_platform == 'win32'" }, + { name = "pylint" }, + { name = "pyramid" }, + { name = "pytest" }, + { name = "pytest-check" }, + { name = "pytest-cov" }, + { name = "pytest-mock" }, + { name = "pytest-subprocess" }, + { name = "testscenarios" }, +] +docs = [ + { name = "canonical-sphinx", extra = ["full"] }, + { name = "pyspelling" }, + { name = "sphinx-autobuild" }, + { name = "sphinx-autodoc-typehints" }, + { name = "sphinx-lint" }, + { name = "sphinx-toolbox" }, + { name = "sphinxcontrib-details-directive" }, +] +lint = [ + { name = "codespell" }, + { name = "yamllint" }, +] +types = [ + { name = "mypy" }, + { name = "types-pyyaml" }, + { name = "types-requests" }, + { name = "types-setuptools" }, + { name = "types-simplejson" }, + { name = "types-tabulate" }, + { name = "types-toml" }, +] + +[package.metadata] +requires-dist = [ + { name = "attrs", specifier = "==24.2.0" }, + { name = "catkin-pkg", marker = "sys_platform == 'linux'", specifier = "==1.0.0" }, + { name = "click", specifier = "==8.1.7" }, + { name = "craft-application", specifier = "~=4.4" }, + { name = "craft-archives", specifier = "~=2.0" }, + { name = "craft-cli", specifier = "~=2.9" }, + { name = "craft-grammar", specifier = ">=2.0.1,<3.0.0" }, + { name = "craft-parts", specifier = "==2.3.0" }, + { name = "craft-platforms", specifier = "~=0.4" }, + { name = "craft-store", specifier = ">=3.0.2,<4.0.0" }, + { name = "cryptography", specifier = "==43.0.3" }, + { name = "docutils", specifier = "<0.20" }, + { name = "gnupg" }, + { name = "jsonschema", specifier = "==2.5.1" }, + { name = "launchpadlib" }, + { name = "lazr-restfulclient" }, + { name = "lxml" }, + { name = "macaroonbakery" }, + { name = "mypy-extensions" }, + { name = "overrides" }, + { name = "packaging" }, + { name = "progressbar" }, + { name = "pydantic", specifier = "~=2.8" }, + { name = "pyelftools" }, + { name = "pygit2", specifier = "~=1.13.0" }, + { name = "pylxd", marker = "sys_platform == 'linux'" }, + { name = "pymacaroons" }, + { name = "python-apt", marker = "sys_platform == 'linux'", url = "https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz" }, + { name = "python-debian", marker = "sys_platform == 'linux'" }, + { name = "pyxdg" }, + { name = "pyyaml" }, + { name = "raven" }, + { name = "requests" }, + { name = "requests-toolbelt" }, + { name = "requests-unixsocket2" }, + { name = "simplejson" }, + { name = "snap-helpers" }, + { name = "tabulate" }, + { name = "tinydb" }, + { name = "toml" }, + { name = "typing-extensions" }, + { name = "validators", specifier = ">=0.28.3" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "coverage", extras = ["toml"] }, + { name = "fixtures" }, + { name = "flake8" }, + { name = "mccabe" }, + { name = "pexpect" }, + { name = "pip" }, + { name = "pycodestyle" }, + { name = "pyflakes" }, + { name = "pyftpdlib" }, + { name = "pyinstaller", marker = "sys_platform == 'win32'" }, + { name = "pylint" }, + { name = "pyramid" }, + { name = "pytest" }, + { name = "pytest-check" }, + { name = "pytest-cov" }, + { name = "pytest-mock" }, + { name = "pytest-subprocess" }, + { name = "testscenarios" }, +] +docs = [ + { name = "canonical-sphinx", extras = ["full"], specifier = ">=0.2.0" }, + { name = "pyspelling" }, + { name = "sphinx-autobuild" }, + { name = "sphinx-autodoc-typehints" }, + { name = "sphinx-lint" }, + { name = "sphinx-toolbox" }, + { name = "sphinxcontrib-details-directive" }, +] +lint = [ + { name = "codespell", extras = ["toml"] }, + { name = "yamllint", specifier = "~=1.34" }, +] +types = [ + { name = "mypy" }, + { name = "types-pyyaml" }, + { name = "types-requests", specifier = "==2.31.0.6" }, + { name = "types-setuptools" }, + { name = "types-simplejson" }, + { name = "types-tabulate" }, + { name = "types-toml" }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, +] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/7b/af302bebf22c749c56c9c3e8ae13190b5b5db37a33d9068652e8f73b7089/snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", size = 86699 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a", size = 93002 }, +] + +[[package]] +name = "soupsieve" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, +] + +[[package]] +name = "sphinx" +version = "7.3.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b7/0a/b88033900b1582f5ed8f880263363daef968d1cd064175e32abfd9714410/sphinx-7.3.7.tar.gz", hash = "sha256:a4a7db75ed37531c05002d56ed6948d4c42f473a36f46e1382b0bd76ca9627bc", size = 7094808 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/fa/130c32ed94cf270e3d0b9ded16fb7b2c8fea86fa7263c29a696a30c1dde7/sphinx-7.3.7-py3-none-any.whl", hash = "sha256:413f75440be4cacf328f580b4274ada4565fb2187d696a84970c23f77b64d8c3", size = 3335650 }, +] + +[[package]] +name = "sphinx-autobuild" +version = "2024.10.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama" }, + { name = "sphinx" }, + { name = "starlette" }, + { name = "uvicorn" }, + { name = "watchfiles" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a5/2c/155e1de2c1ba96a72e5dba152c509a8b41e047ee5c2def9e9f0d812f8be7/sphinx_autobuild-2024.10.3.tar.gz", hash = "sha256:248150f8f333e825107b6d4b86113ab28fa51750e5f9ae63b59dc339be951fb1", size = 14023 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/c0/eba125db38c84d3c74717008fd3cb5000b68cd7e2cbafd1349c6a38c3d3b/sphinx_autobuild-2024.10.3-py3-none-any.whl", hash = "sha256:158e16c36f9d633e613c9aaf81c19b0fc458ca78b112533b20dafcda430d60fa", size = 11908 }, +] + +[[package]] +name = "sphinx-autodoc-typehints" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/cd/03e7b917230dc057922130a79ba0240df1693bfd76727ea33fae84b39138/sphinx_autodoc_typehints-2.3.0.tar.gz", hash = "sha256:535c78ed2d6a1bad393ba9f3dfa2602cf424e2631ee207263e07874c38fde084", size = 40709 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/f3/e0a4ce49da4b6f4e4ce84b3c39a0677831884cb9d8a87ccbf1e9e56e53ac/sphinx_autodoc_typehints-2.3.0-py3-none-any.whl", hash = "sha256:3098e2c6d0ba99eacd013eb06861acc9b51c6e595be86ab05c08ee5506ac0c67", size = 19836 }, +] + +[[package]] +name = "sphinx-basic-ng" +version = "1.0.0b2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/0b/a866924ded68efec7a1759587a4e478aec7559d8165fac8b2ad1c0e774d6/sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9", size = 20736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/dd/018ce05c532a22007ac58d4f45232514cd9d6dd0ee1dc374e309db830983/sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b", size = 22496 }, +] + +[[package]] +name = "sphinx-copybutton" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e", size = 13343 }, +] + +[[package]] +name = "sphinx-design" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2b/69/b34e0cb5336f09c6866d53b4a19d76c227cdec1bbc7ac4de63ca7d58c9c7/sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632", size = 2193689 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/43/65c0acbd8cc6f50195a3a1fc195c404988b15c67090e73c7a41a9f57d6bd/sphinx_design-0.6.1-py3-none-any.whl", hash = "sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c", size = 2215338 }, +] + +[[package]] +name = "sphinx-jinja2-compat" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "markupsafe" }, + { name = "standard-imghdr", marker = "python_full_version >= '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/26/df/27282da6f8c549f765beca9de1a5fc56f9651ed87711a5cac1e914137753/sphinx_jinja2_compat-0.3.0.tar.gz", hash = "sha256:f3c1590b275f42e7a654e081db5e3e5fb97f515608422bde94015ddf795dfe7c", size = 4998 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/42/2fd09d672eaaa937d6893d8b747d07943f97a6e5e30653aee6ebd339b704/sphinx_jinja2_compat-0.3.0-py3-none-any.whl", hash = "sha256:b1e4006d8e1ea31013fa9946d1b075b0c8d2a42c6e3425e63542c1e9f8be9084", size = 7883 }, +] + +[[package]] +name = "sphinx-lint" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "polib" }, + { name = "regex" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cf/46/f2dad36a4076e9ce88498b25b3f0de82eb7d341ea0ef715cd6c48005bcef/sphinx_lint-1.0.0.tar.gz", hash = "sha256:6eafdb44172ce526f405bf36c713eb246f1340ec2d667e7298e2487ed76decd2", size = 33574 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/31/d2/a130ffba531af7cbbb0e7ad24c7d577d3de0b797437f61d3a7234ed6d836/sphinx_lint-1.0.0-py3-none-any.whl", hash = "sha256:6117a0f340b2dc73eadfc57db7531d4477e0929f92a0c1a2f61e6edbc272f0bc", size = 20163 }, +] + +[[package]] +name = "sphinx-notfound-page" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6a/b2/67603444a8ee97b4a8ea71b0a9d6bab1727ed65e362c87e02f818ee57b8a/sphinx_notfound_page-1.1.0.tar.gz", hash = "sha256:913e1754370bb3db201d9300d458a8b8b5fb22e9246a816643a819a9ea2b8067", size = 7392 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/d4/019fe439c840a7966012bbb95ccbdd81c5c10271749706793b43beb05145/sphinx_notfound_page-1.1.0-py3-none-any.whl", hash = "sha256:835dc76ff7914577a1f58d80a2c8418fb6138c0932c8da8adce4d9096fbcd389", size = 8167 }, +] + +[[package]] +name = "sphinx-prompt" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "pygments" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/fb/7a07b8df1ca2418147a6b13e3f6b445071f2565198b45efa631d0d6ef0cd/sphinx_prompt-1.8.0.tar.gz", hash = "sha256:47482f86fcec29662fdfd23e7c04ef03582714195d01f5d565403320084372ed", size = 5121 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/49/f890a2668b7cbf375f5528b549c8d36dd2e801b0fbb7b2b5ef65663ecb6c/sphinx_prompt-1.8.0-py3-none-any.whl", hash = "sha256:369ecc633f0711886f9b3a078c83264245be1adf46abeeb9b88b5519e4b51007", size = 7298 }, +] + +[[package]] +name = "sphinx-reredirects" +version = "0.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/1d/b1229d825a418738ce1a03930629a7b873cd6a0ff05953493604de35a3d5/sphinx_reredirects-0.1.5.tar.gz", hash = "sha256:cfa753b441020a22708ce8eb17d4fd553a28fc87a609330092917ada2a6da0d8", size = 7095 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/97/1f8143f87330f4c9ccc2c08ae9cd3cb1ce2944c51e98dd7ff141154fbcc7/sphinx_reredirects-0.1.5-py3-none-any.whl", hash = "sha256:444ae1438fba4418242ca76d6a6de3eaee82aaf0d8f2b0cac71a15d32ce6eba2", size = 5673 }, +] + +[[package]] +name = "sphinx-tabs" +version = "3.4.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "pygments" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/27/32/ab475e252dc2b704e82a91141fa404cdd8901a5cf34958fd22afacebfccd/sphinx-tabs-3.4.5.tar.gz", hash = "sha256:ba9d0c1e3e37aaadd4b5678449eb08176770e0fc227e769b6ce747df3ceea531", size = 16070 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/9f/4ac7dbb9f23a2ff5a10903a4f9e9f43e0ff051f63a313e989c962526e305/sphinx_tabs-3.4.5-py3-none-any.whl", hash = "sha256:92cc9473e2ecf1828ca3f6617d0efc0aa8acb06b08c56ba29d1413f2f0f6cf09", size = 9904 }, +] + +[[package]] +name = "sphinx-toolbox" +version = "3.8.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "apeye" }, + { name = "autodocsumm" }, + { name = "beautifulsoup4" }, + { name = "cachecontrol", extra = ["filecache"] }, + { name = "dict2css" }, + { name = "docutils" }, + { name = "domdf-python-tools" }, + { name = "filelock" }, + { name = "html5lib" }, + { name = "ruamel-yaml" }, + { name = "sphinx" }, + { name = "sphinx-autodoc-typehints" }, + { name = "sphinx-jinja2-compat" }, + { name = "sphinx-prompt" }, + { name = "sphinx-tabs" }, + { name = "tabulate" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/30/80/f837e85c8c216cdeef9b60393e4b00c9092a1e3d734106e0021abbf5930c/sphinx_toolbox-3.8.1.tar.gz", hash = "sha256:a4b39a6ea24fc8f10e24f052199bda17837a0bf4c54163a56f521552395f5e1a", size = 111977 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/d6/2a28ee4cbc158ae65afb2cfcb6895ef54d972ce1e167f8a63c135b14b080/sphinx_toolbox-3.8.1-py3-none-any.whl", hash = "sha256:53d8e77dd79e807d9ef18590c4b2960a5aa3c147415054b04c31a91afed8b88b", size = 194621 }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300 }, +] + +[[package]] +name = "sphinxcontrib-details-directive" +version = "0.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/62/0a/2de87a4f6e0e33415692ed4b03e0b7dfde7d91a691d1486c1577191f875c/sphinxcontrib-details-directive-0.1.0.tar.gz", hash = "sha256:78bd6a67f786a21868abf0e6a5973340d7e7a6fd71b1890de9c856f92877b38b", size = 7969 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/9e/9cb96fbdca829ba3eb094d966d0f48bb018215e73f96c8750088e73f2f19/sphinxcontrib_details_directive-0.1.0-py2.py3-none-any.whl", hash = "sha256:ed4d4f47b36e3e905601d425945cbe9d50d4cbcf9964bbf9c863d5a983fb7bf6", size = 10724 }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530 }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705 }, +] + +[[package]] +name = "sphinxcontrib-jquery" +version = "4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/f3/aa67467e051df70a6330fe7770894b3e4f09436dea6881ae0b4f3d87cad8/sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a", size = 122331 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/85/749bd22d1a68db7291c89e2ebca53f4306c3f205853cf31e9de279034c3c/sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae", size = 121104 }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071 }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743 }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072 }, +] + +[[package]] +name = "sphinxext-opengraph" +version = "0.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/5b/4302fe33c88dbfb572e2c1cad26735164c23f16fb8dba94ddb1867d0ef06/sphinxext-opengraph-0.9.1.tar.gz", hash = "sha256:dd2868a1e7c9497977fbbf44cc0844a42af39ca65fe1bb0272518af225d06fc5", size = 1034511 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/0a/970b80b4fa1feeb6deb6f2e22d4cb14e388b27b315a1afdb9db930ff91a4/sphinxext_opengraph-0.9.1-py3-none-any.whl", hash = "sha256:b3b230cc6a5b5189139df937f0d9c7b23c7c204493b22646273687969dcb760e", size = 1005241 }, +] + +[[package]] +name = "standard-imghdr" +version = "3.10.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/d2/2eb5521072c9598886035c65c023f39f7384bcb73eed70794f469e34efac/standard_imghdr-3.10.14.tar.gz", hash = "sha256:2598fe2e7c540dbda34b233295e10957ab8dc8ac6f3bd9eaa8d38be167232e52", size = 5474 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/d0/9852f70eb01f814843530c053542b72d30e9fbf74da7abb0107e71938389/standard_imghdr-3.10.14-py3-none-any.whl", hash = "sha256:cdf6883163349624dee9a81d2853a20260337c4cd41c04e99c082e01833a08e2", size = 5598 }, +] + +[[package]] +name = "starlette" +version = "0.45.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ff/fb/2984a686808b89a6781526129a4b51266f678b2d2b97ab2d325e56116df8/starlette-0.45.3.tar.gz", hash = "sha256:2cbcba2a75806f8a41c722141486f37c28e30a0921c5f6fe4346cb0dcee1302f", size = 2574076 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/61/f2b52e107b1fc8944b33ef56bf6ac4ebbe16d91b94d2b87ce013bf63fb84/starlette-0.45.3-py3-none-any.whl", hash = "sha256:dfb6d332576f136ec740296c7e8bb8c8a7125044e7c6da30744718880cdd059d", size = 71507 }, +] + +[[package]] +name = "tabulate" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252 }, +] + +[[package]] +name = "testscenarios" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pbr" }, + { name = "testtools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f0/de/b0b5b98c0f38fd7086d082c47fcb455eedd39a044abe7c595f5f40cd6eed/testscenarios-0.5.0.tar.gz", hash = "sha256:c257cb6b90ea7e6f8fef3158121d430543412c9a87df30b5dde6ec8b9b57a2b6", size = 20951 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/25/2f10da0d5427989fefa5ab51e697bc02625bbb7de2be3bc8452462efac78/testscenarios-0.5.0-py2.py3-none-any.whl", hash = "sha256:480263fa5d6e618125bdf092aab129a3aeed5996b1e668428f12cc56d6d01d28", size = 21002 }, +] + +[[package]] +name = "testtools" +version = "2.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6a/05/a543317ac62cf72e98dc40de5ab117ef14508f36352ed715cb3cd3fe1bbb/testtools-2.7.2.tar.gz", hash = "sha256:5be5bbc1f0fa0f8b60aca6ceec07845d41d0c475cf445bfadb4d2c45ec397ea3", size = 201430 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/76/17eb3cfd467e7a53f2727e7a879a77c514970a12e23e3ac12e40ad3e0ac4/testtools-2.7.2-py3-none-any.whl", hash = "sha256:11712e29cebbe92187c3ad47ace5c32f91e1bb7a9f1ac5e8684c2b01eaa6fd2d", size = 179922 }, +] + +[[package]] +name = "tinydb" +version = "4.8.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a0/79/4af51e2bb214b6ea58f857c51183d92beba85b23f7ba61c983ab3de56c33/tinydb-4.8.2.tar.gz", hash = "sha256:f7dfc39b8d7fda7a1ca62a8dbb449ffd340a117c1206b68c50b1a481fb95181d", size = 32566 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/17/853354204e1ca022d6b7d011ca7f3206c4f8faa3cc743e92609b49c1d83f/tinydb-4.8.2-py3-none-any.whl", hash = "sha256:f97030ee5cbc91eeadd1d7af07ab0e48ceb04aa63d4a983adbaca4cba16e86c3", size = 24888 }, +] + +[[package]] +name = "toml" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588 }, +] + +[[package]] +name = "tomlkit" +version = "0.13.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/09/a439bec5888f00a54b8b9f05fa94d7f901d6735ef4e55dcec9bc37b5d8fa/tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79", size = 192885 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/b6/a447b5e4ec71e13871be01ba81f5dfc9d0af7e473da256ff46bc0e24026f/tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", size = 37955 }, +] + +[[package]] +name = "translationstring" +version = "1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/14/39/32325add93da9439775d7fe4b4887eb7986dbc1d5675b0431f4531f560e5/translationstring-1.4.tar.gz", hash = "sha256:bf947538d76e69ba12ab17283b10355a9ecfbc078e6123443f43f2107f6376f3", size = 24199 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/98/36187601a15e3d37e9bfcf0e0e1055532b39d044353b06861c3a519737a9/translationstring-1.4-py2.py3-none-any.whl", hash = "sha256:5f4dc4d939573db851c8d840551e1a0fb27b946afe3b95aafc22577eed2d6262", size = 15028 }, +] + +[[package]] +name = "types-pyyaml" +version = "6.0.12.20241230" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/f9/4d566925bcf9396136c0a2e5dc7e230ff08d86fa011a69888dd184469d80/types_pyyaml-6.0.12.20241230.tar.gz", hash = "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c", size = 17078 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/c1/48474fbead512b70ccdb4f81ba5eb4a58f69d100ba19f17c92c0c4f50ae6/types_PyYAML-6.0.12.20241230-py3-none-any.whl", hash = "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6", size = 20029 }, +] + +[[package]] +name = "types-requests" +version = "2.31.0.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "types-urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/b8/c1e8d39996b4929b918aba10dba5de07a8b3f4c8487bb61bb79882544e69/types-requests-2.31.0.6.tar.gz", hash = "sha256:cd74ce3b53c461f1228a9b783929ac73a666658f223e28ed29753771477b3bd0", size = 15535 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/a1/6f8dc74d9069e790d604ddae70cb46dcbac668f1bb08136e7b0f2f5cd3bf/types_requests-2.31.0.6-py3-none-any.whl", hash = "sha256:a2db9cb228a81da8348b49ad6db3f5519452dd20a9c1e1a868c83c5fe88fd1a9", size = 14516 }, +] + +[[package]] +name = "types-setuptools" +version = "75.8.0.20250110" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/42/5713e90d4f9683f2301d900f33e4fc2405ad8ac224dda30f6cb7f4cd215b/types_setuptools-75.8.0.20250110.tar.gz", hash = "sha256:96f7ec8bbd6e0a54ea180d66ad68ad7a1d7954e7281a710ea2de75e355545271", size = 48185 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/a3/dbfd106751b11c728cec21cc62cbfe7ff7391b935c4b6e8f0bdc2e6fd541/types_setuptools-75.8.0.20250110-py3-none-any.whl", hash = "sha256:a9f12980bbf9bcdc23ecd80755789085bad6bfce4060c2275bc2b4ca9f2bc480", size = 71521 }, +] + +[[package]] +name = "types-simplejson" +version = "3.19.0.20241221" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/f0/3d4dd216dc527a52ab564cbecd2fd8b3c8b96722348745f8f5cb9ab59801/types_simplejson-3.19.0.20241221.tar.gz", hash = "sha256:114af9db0f49ad15755d2b6ad8e6fd04b5a493815e2fc1e011729d4650defc70", size = 9688 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/2f/4a5fcab9225bec1d075d543d00f005fe83685ddc1bd395ab1b382b9553db/types_simplejson-3.19.0.20241221-py3-none-any.whl", hash = "sha256:179dfaef8c357156c781fa47cfdfcd953a7953fc375dfe9ab19a20054a828980", size = 10285 }, +] + +[[package]] +name = "types-tabulate" +version = "0.9.0.20241207" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/43/16030404a327e4ff8c692f2273854019ed36718667b2993609dc37d14dd4/types_tabulate-0.9.0.20241207.tar.gz", hash = "sha256:ac1ac174750c0a385dfd248edc6279fa328aaf4ea317915ab879a2ec47833230", size = 8195 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/86/a9ebfd509cbe74471106dffed320e208c72537f9aeb0a55eaa6b1b5e4d17/types_tabulate-0.9.0.20241207-py3-none-any.whl", hash = "sha256:b8dad1343c2a8ba5861c5441370c3e35908edd234ff036d4298708a1d4cf8a85", size = 8307 }, +] + +[[package]] +name = "types-toml" +version = "0.10.8.20240310" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/86/47/3e4c75042792bff8e90d7991aa5c51812cc668828cc6cce711e97f63a607/types-toml-0.10.8.20240310.tar.gz", hash = "sha256:3d41501302972436a6b8b239c850b26689657e25281b48ff0ec06345b8830331", size = 4392 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/a2/d32ab58c0b216912638b140ab2170ee4b8644067c293b170e19fba340ccc/types_toml-0.10.8.20240310-py3-none-any.whl", hash = "sha256:627b47775d25fa29977d9c70dc0cbab3f314f32c8d8d0c012f2ef5de7aaec05d", size = 4777 }, +] + +[[package]] +name = "types-urllib3" +version = "1.26.25.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/73/de/b9d7a68ad39092368fb21dd6194b362b98a1daeea5dcfef5e1adb5031c7e/types-urllib3-1.26.25.14.tar.gz", hash = "sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f", size = 11239 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/7b/3fc711b2efea5e85a7a0bbfe269ea944aa767bbba5ec52f9ee45d362ccf3/types_urllib3-1.26.25.14-py3-none-any.whl", hash = "sha256:9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e", size = 15377 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] + +[[package]] +name = "uc-micro-py" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/7a/146a99696aee0609e3712f2b44c6274566bc368dfe8375191278045186b8/uc-micro-py-1.0.3.tar.gz", hash = "sha256:d321b92cff673ec58027c04015fcaa8bb1e005478643ff4a500882eaab88c48a", size = 6043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/87/1f677586e8ac487e29672e4b17455758fce261de06a0d086167bb760361a/uc_micro_py-1.0.3-py3-none-any.whl", hash = "sha256:db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5", size = 6229 }, +] + +[[package]] +name = "urllib3" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, +] + +[[package]] +name = "uvicorn" +version = "0.34.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4b/4d/938bd85e5bf2edeec766267a5015ad969730bb91e31b44021dfe8b22df6c/uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9", size = 76568 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", size = 62315 }, +] + +[[package]] +name = "validators" +version = "0.34.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/64/07/91582d69320f6f6daaf2d8072608a4ad8884683d4840e7e4f3a9dbdcc639/validators-0.34.0.tar.gz", hash = "sha256:647fe407b45af9a74d245b943b18e6a816acf4926974278f6dd617778e1e781f", size = 70955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/78/36828a4d857b25896f9774c875714ba4e9b3bc8a92d2debe3f4df3a83d4f/validators-0.34.0-py3-none-any.whl", hash = "sha256:c804b476e3e6d3786fa07a30073a4ef694e617805eb1946ceee3fe5a9b8b1321", size = 43536 }, +] + +[[package]] +name = "venusian" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/4c/eefa68085c555dc11e6744b9c6fbe5966b1c9378c47267776a448923e9a5/venusian-3.1.1.tar.gz", hash = "sha256:534fb3b355669283eb3954581931e5d1d071fce61d029d58f3219a5e3a6f0c41", size = 39269 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/4b/34d926eba40db81b204066a60b4efdc5d8867a8efcbfe44d69b634b1c907/venusian-3.1.1-py3-none-any.whl", hash = "sha256:0845808a985976acbceaa1fbb871c7fac4fb28ae75453232970e9c2c2866dbf4", size = 14026 }, +] + +[[package]] +name = "wadllib" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lazr-uri" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/54/82866d8c2bf602ed9df52c8f8b7a45e94f8c2441b3d1e9e46d34f0e3270f/wadllib-2.0.0.tar.gz", hash = "sha256:1edbaf23e4fa34fea70c9b380baa2a139b1086ae489ebcccc4b3b65fc9737427", size = 65960 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/a1/3789e82241db565f25e2c6a69c6ebe79f3db84431e93760a4abb451822bd/wadllib-2.0.0-py3-none-any.whl", hash = "sha256:f8e0fc4f19c2c96b3ca8a091f04c86ca196ec9590d44c4d864320aa9533473ea", size = 61733 }, +] + +[[package]] +name = "watchfiles" +version = "1.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/26/c705fc77d0a9ecdb9b66f1e2976d95b81df3cae518967431e7dbf9b5e219/watchfiles-1.0.4.tar.gz", hash = "sha256:6ba473efd11062d73e4f00c2b730255f9c1bdd73cd5f9fe5b5da8dbd4a717205", size = 94625 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/1a/8f4d9a1461709756ace48c98f07772bc6d4519b1e48b5fa24a4061216256/watchfiles-1.0.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:229e6ec880eca20e0ba2f7e2249c85bae1999d330161f45c78d160832e026ee2", size = 391345 }, + { url = "https://files.pythonhosted.org/packages/bc/d2/6750b7b3527b1cdaa33731438432e7238a6c6c40a9924049e4cebfa40805/watchfiles-1.0.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5717021b199e8353782dce03bd8a8f64438832b84e2885c4a645f9723bf656d9", size = 381515 }, + { url = "https://files.pythonhosted.org/packages/4e/17/80500e42363deef1e4b4818729ed939aaddc56f82f4e72b2508729dd3c6b/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0799ae68dfa95136dde7c472525700bd48777875a4abb2ee454e3ab18e9fc712", size = 449767 }, + { url = "https://files.pythonhosted.org/packages/10/37/1427fa4cfa09adbe04b1e97bced19a29a3462cc64c78630787b613a23f18/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:43b168bba889886b62edb0397cab5b6490ffb656ee2fcb22dec8bfeb371a9e12", size = 455677 }, + { url = "https://files.pythonhosted.org/packages/c5/7a/39e9397f3a19cb549a7d380412fd9e507d4854eddc0700bfad10ef6d4dba/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb2c46e275fbb9f0c92e7654b231543c7bbfa1df07cdc4b99fa73bedfde5c844", size = 482219 }, + { url = "https://files.pythonhosted.org/packages/45/2d/7113931a77e2ea4436cad0c1690c09a40a7f31d366f79c6f0a5bc7a4f6d5/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:857f5fc3aa027ff5e57047da93f96e908a35fe602d24f5e5d8ce64bf1f2fc733", size = 518830 }, + { url = "https://files.pythonhosted.org/packages/f9/1b/50733b1980fa81ef3c70388a546481ae5fa4c2080040100cd7bf3bf7b321/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55ccfd27c497b228581e2838d4386301227fc0cb47f5a12923ec2fe4f97b95af", size = 497997 }, + { url = "https://files.pythonhosted.org/packages/2b/b4/9396cc61b948ef18943e7c85ecfa64cf940c88977d882da57147f62b34b1/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c11ea22304d17d4385067588123658e9f23159225a27b983f343fcffc3e796a", size = 452249 }, + { url = "https://files.pythonhosted.org/packages/fb/69/0c65a5a29e057ad0dc691c2fa6c23b2983c7dabaa190ba553b29ac84c3cc/watchfiles-1.0.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:74cb3ca19a740be4caa18f238298b9d472c850f7b2ed89f396c00a4c97e2d9ff", size = 614412 }, + { url = "https://files.pythonhosted.org/packages/7f/b9/319fcba6eba5fad34327d7ce16a6b163b39741016b1996f4a3c96b8dd0e1/watchfiles-1.0.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7cce76c138a91e720d1df54014a047e680b652336e1b73b8e3ff3158e05061e", size = 611982 }, + { url = "https://files.pythonhosted.org/packages/f1/47/143c92418e30cb9348a4387bfa149c8e0e404a7c5b0585d46d2f7031b4b9/watchfiles-1.0.4-cp312-cp312-win32.whl", hash = "sha256:b045c800d55bc7e2cadd47f45a97c7b29f70f08a7c2fa13241905010a5493f94", size = 271822 }, + { url = "https://files.pythonhosted.org/packages/ea/94/b0165481bff99a64b29e46e07ac2e0df9f7a957ef13bec4ceab8515f44e3/watchfiles-1.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:c2acfa49dd0ad0bf2a9c0bb9a985af02e89345a7189be1efc6baa085e0f72d7c", size = 285441 }, + { url = "https://files.pythonhosted.org/packages/11/de/09fe56317d582742d7ca8c2ca7b52a85927ebb50678d9b0fa8194658f536/watchfiles-1.0.4-cp312-cp312-win_arm64.whl", hash = "sha256:22bb55a7c9e564e763ea06c7acea24fc5d2ee5dfc5dafc5cfbedfe58505e9f90", size = 277141 }, + { url = "https://files.pythonhosted.org/packages/08/98/f03efabec64b5b1fa58c0daab25c68ef815b0f320e54adcacd0d6847c339/watchfiles-1.0.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:8012bd820c380c3d3db8435e8cf7592260257b378b649154a7948a663b5f84e9", size = 390954 }, + { url = "https://files.pythonhosted.org/packages/16/09/4dd49ba0a32a45813debe5fb3897955541351ee8142f586303b271a02b40/watchfiles-1.0.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa216f87594f951c17511efe5912808dfcc4befa464ab17c98d387830ce07b60", size = 381133 }, + { url = "https://files.pythonhosted.org/packages/76/59/5aa6fc93553cd8d8ee75c6247763d77c02631aed21551a97d94998bf1dae/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62c9953cf85529c05b24705639ffa390f78c26449e15ec34d5339e8108c7c407", size = 449516 }, + { url = "https://files.pythonhosted.org/packages/4c/aa/df4b6fe14b6317290b91335b23c96b488d365d65549587434817e06895ea/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7cf684aa9bba4cd95ecb62c822a56de54e3ae0598c1a7f2065d51e24637a3c5d", size = 454820 }, + { url = "https://files.pythonhosted.org/packages/5e/71/185f8672f1094ce48af33252c73e39b48be93b761273872d9312087245f6/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f44a39aee3cbb9b825285ff979ab887a25c5d336e5ec3574f1506a4671556a8d", size = 481550 }, + { url = "https://files.pythonhosted.org/packages/85/d7/50ebba2c426ef1a5cb17f02158222911a2e005d401caf5d911bfca58f4c4/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38320582736922be8c865d46520c043bff350956dfc9fbaee3b2df4e1740a4b", size = 518647 }, + { url = "https://files.pythonhosted.org/packages/f0/7a/4c009342e393c545d68987e8010b937f72f47937731225b2b29b7231428f/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39f4914548b818540ef21fd22447a63e7be6e24b43a70f7642d21f1e73371590", size = 497547 }, + { url = "https://files.pythonhosted.org/packages/0f/7c/1cf50b35412d5c72d63b2bf9a4fffee2e1549a245924960dd087eb6a6de4/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f12969a3765909cf5dc1e50b2436eb2c0e676a3c75773ab8cc3aa6175c16e902", size = 452179 }, + { url = "https://files.pythonhosted.org/packages/d6/a9/3db1410e1c1413735a9a472380e4f431ad9a9e81711cda2aaf02b7f62693/watchfiles-1.0.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:0986902677a1a5e6212d0c49b319aad9cc48da4bd967f86a11bde96ad9676ca1", size = 614125 }, + { url = "https://files.pythonhosted.org/packages/f2/e1/0025d365cf6248c4d1ee4c3d2e3d373bdd3f6aff78ba4298f97b4fad2740/watchfiles-1.0.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:308ac265c56f936636e3b0e3f59e059a40003c655228c131e1ad439957592303", size = 611911 }, + { url = "https://files.pythonhosted.org/packages/55/55/035838277d8c98fc8c917ac9beeb0cd6c59d675dc2421df5f9fcf44a0070/watchfiles-1.0.4-cp313-cp313-win32.whl", hash = "sha256:aee397456a29b492c20fda2d8961e1ffb266223625346ace14e4b6d861ba9c80", size = 271152 }, + { url = "https://files.pythonhosted.org/packages/f0/e5/96b8e55271685ddbadc50ce8bc53aa2dff278fb7ac4c2e473df890def2dc/watchfiles-1.0.4-cp313-cp313-win_amd64.whl", hash = "sha256:d6097538b0ae5c1b88c3b55afa245a66793a8fec7ada6755322e465fb1a0e8cc", size = 285216 }, +] + +[[package]] +name = "wcmatch" +version = "10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "bracex" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/41/ab/b3a52228538ccb983653c446c1656eddf1d5303b9cb8b9aef6a91299f862/wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a", size = 115578 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/df/4ee467ab39cc1de4b852c212c1ed3becfec2e486a51ac1ce0091f85f38d7/wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a", size = 39347 }, +] + +[[package]] +name = "webencodings" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774 }, +] + +[[package]] +name = "webob" +version = "1.8.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "legacy-cgi", marker = "python_full_version >= '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/0b/1732085540b01f65e4e7999e15864fe14cd18b12a95731a43fd6fd11b26a/webob-1.8.9.tar.gz", hash = "sha256:ad6078e2edb6766d1334ec3dee072ac6a7f95b1e32ce10def8ff7f0f02d56589", size = 279775 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/bd/c336448be43d40be28e71f2e0f3caf7ccb28e2755c58f4c02c065bfe3e8e/WebOb-1.8.9-py2.py3-none-any.whl", hash = "sha256:45e34c58ed0c7e2ecd238ffd34432487ff13d9ad459ddfd77895e67abba7c1f9", size = 115364 }, +] + +[[package]] +name = "websockets" +version = "14.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/54/8359678c726243d19fae38ca14a334e740782336c9f19700858c4eb64a1e/websockets-14.2.tar.gz", hash = "sha256:5059ed9c54945efb321f097084b4c7e52c246f2c869815876a69d1efc4ad6eb5", size = 164394 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/81/04f7a397653dc8bec94ddc071f34833e8b99b13ef1a3804c149d59f92c18/websockets-14.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1f20522e624d7ffbdbe259c6b6a65d73c895045f76a93719aa10cd93b3de100c", size = 163096 }, + { url = "https://files.pythonhosted.org/packages/ec/c5/de30e88557e4d70988ed4d2eabd73fd3e1e52456b9f3a4e9564d86353b6d/websockets-14.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:647b573f7d3ada919fd60e64d533409a79dcf1ea21daeb4542d1d996519ca967", size = 160758 }, + { url = "https://files.pythonhosted.org/packages/e5/8c/d130d668781f2c77d106c007b6c6c1d9db68239107c41ba109f09e6c218a/websockets-14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6af99a38e49f66be5a64b1e890208ad026cda49355661549c507152113049990", size = 160995 }, + { url = "https://files.pythonhosted.org/packages/a6/bc/f6678a0ff17246df4f06765e22fc9d98d1b11a258cc50c5968b33d6742a1/websockets-14.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:091ab63dfc8cea748cc22c1db2814eadb77ccbf82829bac6b2fbe3401d548eda", size = 170815 }, + { url = "https://files.pythonhosted.org/packages/d8/b2/8070cb970c2e4122a6ef38bc5b203415fd46460e025652e1ee3f2f43a9a3/websockets-14.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b374e8953ad477d17e4851cdc66d83fdc2db88d9e73abf755c94510ebddceb95", size = 169759 }, + { url = "https://files.pythonhosted.org/packages/81/da/72f7caabd94652e6eb7e92ed2d3da818626e70b4f2b15a854ef60bf501ec/websockets-14.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a39d7eceeea35db85b85e1169011bb4321c32e673920ae9c1b6e0978590012a3", size = 170178 }, + { url = "https://files.pythonhosted.org/packages/31/e0/812725b6deca8afd3a08a2e81b3c4c120c17f68c9b84522a520b816cda58/websockets-14.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0a6f3efd47ffd0d12080594f434faf1cd2549b31e54870b8470b28cc1d3817d9", size = 170453 }, + { url = "https://files.pythonhosted.org/packages/66/d3/8275dbc231e5ba9bb0c4f93144394b4194402a7a0c8ffaca5307a58ab5e3/websockets-14.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:065ce275e7c4ffb42cb738dd6b20726ac26ac9ad0a2a48e33ca632351a737267", size = 169830 }, + { url = "https://files.pythonhosted.org/packages/a3/ae/e7d1a56755ae15ad5a94e80dd490ad09e345365199600b2629b18ee37bc7/websockets-14.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e9d0e53530ba7b8b5e389c02282f9d2aa47581514bd6049d3a7cffe1385cf5fe", size = 169824 }, + { url = "https://files.pythonhosted.org/packages/b6/32/88ccdd63cb261e77b882e706108d072e4f1c839ed723bf91a3e1f216bf60/websockets-14.2-cp312-cp312-win32.whl", hash = "sha256:20e6dd0984d7ca3037afcb4494e48c74ffb51e8013cac71cf607fffe11df7205", size = 163981 }, + { url = "https://files.pythonhosted.org/packages/b3/7d/32cdb77990b3bdc34a306e0a0f73a1275221e9a66d869f6ff833c95b56ef/websockets-14.2-cp312-cp312-win_amd64.whl", hash = "sha256:44bba1a956c2c9d268bdcdf234d5e5ff4c9b6dc3e300545cbe99af59dda9dcce", size = 164421 }, + { url = "https://files.pythonhosted.org/packages/82/94/4f9b55099a4603ac53c2912e1f043d6c49d23e94dd82a9ce1eb554a90215/websockets-14.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6f1372e511c7409a542291bce92d6c83320e02c9cf392223272287ce55bc224e", size = 163102 }, + { url = "https://files.pythonhosted.org/packages/8e/b7/7484905215627909d9a79ae07070057afe477433fdacb59bf608ce86365a/websockets-14.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4da98b72009836179bb596a92297b1a61bb5a830c0e483a7d0766d45070a08ad", size = 160766 }, + { url = "https://files.pythonhosted.org/packages/a3/a4/edb62efc84adb61883c7d2c6ad65181cb087c64252138e12d655989eec05/websockets-14.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8a86a269759026d2bde227652b87be79f8a734e582debf64c9d302faa1e9f03", size = 160998 }, + { url = "https://files.pythonhosted.org/packages/f5/79/036d320dc894b96af14eac2529967a6fc8b74f03b83c487e7a0e9043d842/websockets-14.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86cf1aaeca909bf6815ea714d5c5736c8d6dd3a13770e885aafe062ecbd04f1f", size = 170780 }, + { url = "https://files.pythonhosted.org/packages/63/75/5737d21ee4dd7e4b9d487ee044af24a935e36a9ff1e1419d684feedcba71/websockets-14.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b0f6c3ba3b1240f602ebb3971d45b02cc12bd1845466dd783496b3b05783a5", size = 169717 }, + { url = "https://files.pythonhosted.org/packages/2c/3c/bf9b2c396ed86a0b4a92ff4cdaee09753d3ee389be738e92b9bbd0330b64/websockets-14.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:669c3e101c246aa85bc8534e495952e2ca208bd87994650b90a23d745902db9a", size = 170155 }, + { url = "https://files.pythonhosted.org/packages/75/2d/83a5aca7247a655b1da5eb0ee73413abd5c3a57fc8b92915805e6033359d/websockets-14.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eabdb28b972f3729348e632ab08f2a7b616c7e53d5414c12108c29972e655b20", size = 170495 }, + { url = "https://files.pythonhosted.org/packages/79/dd/699238a92761e2f943885e091486378813ac8f43e3c84990bc394c2be93e/websockets-14.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2066dc4cbcc19f32c12a5a0e8cc1b7ac734e5b64ac0a325ff8353451c4b15ef2", size = 169880 }, + { url = "https://files.pythonhosted.org/packages/c8/c9/67a8f08923cf55ce61aadda72089e3ed4353a95a3a4bc8bf42082810e580/websockets-14.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ab95d357cd471df61873dadf66dd05dd4709cae001dd6342edafc8dc6382f307", size = 169856 }, + { url = "https://files.pythonhosted.org/packages/17/b1/1ffdb2680c64e9c3921d99db460546194c40d4acbef999a18c37aa4d58a3/websockets-14.2-cp313-cp313-win32.whl", hash = "sha256:a9e72fb63e5f3feacdcf5b4ff53199ec8c18d66e325c34ee4c551ca748623bbc", size = 163974 }, + { url = "https://files.pythonhosted.org/packages/14/13/8b7fc4cb551b9cfd9890f0fd66e53c18a06240319915533b033a56a3d520/websockets-14.2-cp313-cp313-win_amd64.whl", hash = "sha256:b439ea828c4ba99bb3176dc8d9b933392a2413c0f6b149fdcba48393f573377f", size = 164420 }, + { url = "https://files.pythonhosted.org/packages/7b/c8/d529f8a32ce40d98309f4470780631e971a5a842b60aec864833b3615786/websockets-14.2-py3-none-any.whl", hash = "sha256:7a6ceec4ea84469f15cf15807a747e9efe57e369c384fa86e022b3bea679b79b", size = 157416 }, +] + +[[package]] +name = "ws4py" +version = "0.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/55/dd8a5e1f975d1549494fe8692fc272602f17e475fe70de910cdd53aec902/ws4py-0.6.0.tar.gz", hash = "sha256:9f87b19b773f0a0744a38f3afa36a803286dd3197f0bb35d9b75293ec7002d19", size = 53288 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/62/dad08725f855f9695d1c2b34466cf0d1482d1168bb54d73d22b6b0124ba3/ws4py-0.6.0-py3-none-any.whl", hash = "sha256:1499c3fc103a65eb12d7b1ead7566f88487f6f678ab10ee4e53cf2411c068752", size = 45806 }, +] + +[[package]] +name = "yamllint" +version = "1.35.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pathspec" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/06/d8cee5c3dfd550cc0a466ead8b321138198485d1034130ac1393cc49d63e/yamllint-1.35.1.tar.gz", hash = "sha256:7a003809f88324fd2c877734f2d575ee7881dd9043360657cc8049c809eba6cd", size = 134583 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/28/2abf1ec14df2d584b9e7ce3b0be458838741e6aaff7a540374ba9af83916/yamllint-1.35.1-py3-none-any.whl", hash = "sha256:2e16e504bb129ff515b37823b472750b36b6de07963bd74b307341ef5ad8bdc3", size = 66738 }, +] + +[[package]] +name = "zope-deprecation" +version = "5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/22/0e621e31b5826b2ff121fea5b1ea91173c88f86e182181f012abcc84a51f/zope_deprecation-5.1.tar.gz", hash = "sha256:46bed4611fb53edc731aadeb64b28308bcb848f4cc150c60c948d078f7108721", size = 24453 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/88/5fc32633682a452260f50417da3d4be26137dd220ef617bbd8ed52f0cfa9/zope.deprecation-5.1-py3-none-any.whl", hash = "sha256:60f957b964d8f947a4a592c647d51ce0f4f844d1f041657956ddde0d9fa9a76a", size = 10020 }, +] + +[[package]] +name = "zope-interface" +version = "7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/30/93/9210e7606be57a2dfc6277ac97dcc864fd8d39f142ca194fdc186d596fda/zope.interface-7.2.tar.gz", hash = "sha256:8b49f1a3d1ee4cdaf5b32d2e738362c7f5e40ac8b46dd7d1a65e82a4872728fe", size = 252960 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/0b/c7516bc3bad144c2496f355e35bd699443b82e9437aa02d9867653203b4a/zope.interface-7.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:086ee2f51eaef1e4a52bd7d3111a0404081dadae87f84c0ad4ce2649d4f708b7", size = 208959 }, + { url = "https://files.pythonhosted.org/packages/a2/e9/1463036df1f78ff8c45a02642a7bf6931ae4a38a4acd6a8e07c128e387a7/zope.interface-7.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:21328fcc9d5b80768bf051faa35ab98fb979080c18e6f84ab3f27ce703bce465", size = 209357 }, + { url = "https://files.pythonhosted.org/packages/07/a8/106ca4c2add440728e382f1b16c7d886563602487bdd90004788d45eb310/zope.interface-7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6dd02ec01f4468da0f234da9d9c8545c5412fef80bc590cc51d8dd084138a89", size = 264235 }, + { url = "https://files.pythonhosted.org/packages/fc/ca/57286866285f4b8a4634c12ca1957c24bdac06eae28fd4a3a578e30cf906/zope.interface-7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e7da17f53e25d1a3bde5da4601e026adc9e8071f9f6f936d0fe3fe84ace6d54", size = 259253 }, + { url = "https://files.pythonhosted.org/packages/96/08/2103587ebc989b455cf05e858e7fbdfeedfc3373358320e9c513428290b1/zope.interface-7.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cab15ff4832580aa440dc9790b8a6128abd0b88b7ee4dd56abacbc52f212209d", size = 264702 }, + { url = "https://files.pythonhosted.org/packages/5f/c7/3c67562e03b3752ba4ab6b23355f15a58ac2d023a6ef763caaca430f91f2/zope.interface-7.2-cp312-cp312-win_amd64.whl", hash = "sha256:29caad142a2355ce7cfea48725aa8bcf0067e2b5cc63fcf5cd9f97ad12d6afb5", size = 212466 }, + { url = "https://files.pythonhosted.org/packages/c6/3b/e309d731712c1a1866d61b5356a069dd44e5b01e394b6cb49848fa2efbff/zope.interface-7.2-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:3e0350b51e88658d5ad126c6a57502b19d5f559f6cb0a628e3dc90442b53dd98", size = 208961 }, + { url = "https://files.pythonhosted.org/packages/49/65/78e7cebca6be07c8fc4032bfbb123e500d60efdf7b86727bb8a071992108/zope.interface-7.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15398c000c094b8855d7d74f4fdc9e73aa02d4d0d5c775acdef98cdb1119768d", size = 209356 }, + { url = "https://files.pythonhosted.org/packages/11/b1/627384b745310d082d29e3695db5f5a9188186676912c14b61a78bbc6afe/zope.interface-7.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:802176a9f99bd8cc276dcd3b8512808716492f6f557c11196d42e26c01a69a4c", size = 264196 }, + { url = "https://files.pythonhosted.org/packages/b8/f6/54548df6dc73e30ac6c8a7ff1da73ac9007ba38f866397091d5a82237bd3/zope.interface-7.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb23f58a446a7f09db85eda09521a498e109f137b85fb278edb2e34841055398", size = 259237 }, + { url = "https://files.pythonhosted.org/packages/b6/66/ac05b741c2129fdf668b85631d2268421c5cd1a9ff99be1674371139d665/zope.interface-7.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a71a5b541078d0ebe373a81a3b7e71432c61d12e660f1d67896ca62d9628045b", size = 264696 }, + { url = "https://files.pythonhosted.org/packages/0a/2f/1bccc6f4cc882662162a1158cda1a7f616add2ffe322b28c99cb031b4ffc/zope.interface-7.2-cp313-cp313-win_amd64.whl", hash = "sha256:4893395d5dd2ba655c38ceb13014fd65667740f09fa5bb01caa1e6284e48c0cd", size = 212472 }, +] From c8651d49bd1a87e055ba470bcc22c2d6cd1887a6 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Mon, 27 Jan 2025 14:01:15 -0500 Subject: [PATCH 306/333] chore: replace black with ruff formatter --- CODE_STYLE.md | 6 +++--- README.md | 2 +- pyproject.toml | 12 ------------ tools/environment-setup-local.sh | 3 --- 4 files changed, 4 insertions(+), 19 deletions(-) diff --git a/CODE_STYLE.md b/CODE_STYLE.md index 7d9a1b6105..b163e6f353 100644 --- a/CODE_STYLE.md +++ b/CODE_STYLE.md @@ -13,8 +13,8 @@ tests. Some other rules are only socially enforced during code reviews. ## Code Formatting -This code base adheres to black[2]. -You can `snap install black --beta --devmode` to install the linter and formatter onto your host. +This code base adheres to [Ruff][2]. +You can `snap install ruff` to install the linter and formatter onto your host. ## Conditionals @@ -76,4 +76,4 @@ fix it. Generally speaking, all comments should end with some punctuation. [1]: TESTING.md -[2]: https://github.com/ambv/black +[2]: https://docs.astral.sh/ruff/ diff --git a/README.md b/README.md index e8b6707df8..f8189640a1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Documentation Status](https://readthedocs.com/projects/canonical-snapcraft/badge/?version=latest)](https://canonical-snapcraft.readthedocs-hosted.com/en/latest/?badge=latest) [![Scheduled spread tests](https://github.com/canonical/snapcraft/actions/workflows/spread-scheduled.yaml/badge.svg?branch=main)](https://github.com/canonical/snapcraft/actions/workflows/spread-scheduled.yaml) [![Coverage Status][codecov-image]][codecov-url] -[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) +[![Code style: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) # Snapcraft diff --git a/pyproject.toml b/pyproject.toml index 6e9f961d2a..120f1e1a07 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -108,18 +108,6 @@ local_scheme = "dirty-tag" include = ["*craft*"] namespaces = false -[tool.black] -extend-exclude = ''' -/( - | snapcraft_legacy - | tools - | docs/sphinx-resources -)/ -''' -# Targeting future versions as well so we don't have black reformatting code -# en masse later. -target-version = ["py312"] - [tool.mypy] python_version = "3.12" ignore_missing_imports = true diff --git a/tools/environment-setup-local.sh b/tools/environment-setup-local.sh index 881346a128..8d717293a2 100755 --- a/tools/environment-setup-local.sh +++ b/tools/environment-setup-local.sh @@ -41,9 +41,6 @@ pip install -r "${SNAPCRAFT_DIR}/requirements.txt" # Install the project for quick tests pip install --editable "${SNAPCRAFT_DIR}" -# Install black to run static tests. -sudo snap install black --beta - # Install shellcheck for static tests. sudo snap install shellcheck From 928ab77325e456d5c71dc19a347cfadc6e8ef5fe Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Tue, 28 Jan 2025 12:09:55 -0500 Subject: [PATCH 307/333] build: bring in starbase makefile --- Makefile | 135 +++++++++++++++-------- common.mk | 287 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 78 ++++++++++++++ uv.lock | 63 +++++++---- 4 files changed, 500 insertions(+), 63 deletions(-) create mode 100644 common.mk diff --git a/Makefile b/Makefile index 2f9f7f40b4..6e9fee48c5 100644 --- a/Makefile +++ b/Makefile @@ -1,55 +1,104 @@ -SOURCES=setup.py snapcraft tests/*.py tests/unit -SOURCES_LEGACY=snapcraft_legacy tests/legacy +PROJECT=snapcraft +UV_TEST_GROUPS := "--group=dev" +UV_DOCS_GROUPS := "--group=docs" +UV_LINT_GROUPS := "--group=lint" "--group=types" -.PHONY: autoformat-black -autoformat-black: - tox run -e format-black +ifneq ($(wildcard /etc/os-release),) +include /etc/os-release +endif +ifdef VERSION_CODENAME +UV_TEST_GROUPS += "--group=dev-$(VERSION_CODENAME)" +UV_DOCS_GROUPS += "--group=dev-$(VERSION_CODENAME)" +UV_LINT_GROUPS += "--group=dev-$(VERSION_CODENAME)" +endif -.PHONY: freeze-requirements -freeze-requirements: - tools/freeze-requirements.sh +include common.mk -.PHONY: test-black -test-black: - tox run -e lint-black +.PHONY: format +format: format-ruff format-codespell format-prettier ## Run all automatic formatters -.PHONY: test-codespell -test-codespell: - tox run -e lint-codespell +# Override the common.mk lint-docs target until https://github.com/canonical/snapcraft/issues/5229 is resolved +.PHONY: lint-docs +lint-docs: ##- Lint the documentation +ifneq ($(CI),) + @echo ::group::$@ +endif + uv run $(UV_DOCS_GROUPS) sphinx-lint --ignore docs/reference/commands --ignore docs/_build --enable all $(DOCS) -d missing-underscore-after-hyperlink,missing-space-in-hyperlink +ifneq ($(CI),) + @echo ::endgroup:: +endif -.PHONY: test-mypy -test-mypy: - tox run -e lint-mypy - -.PHONY: test-pydocstyle -test-pydocstyle: - tox run -e lint-docstyle - -.PHONY: test-pyright -test-pyright: - tox run -e lint-pyright +.PHONY: lint +lint: lint-ruff lint-codespell lint-mypy lint-prettier lint-pyright lint-shellcheck lint-docs lint-twine ## Run all linters -.PHONY: test-ruff -test-ruff: - ruff check +.PHONY: pack +pack: pack-pip ## Build all packages -.PHONY: test-shellcheck -test-shellcheck: - tox run -e lint-shellcheck +.PHONY: pack-snap +pack-snap: snap/snapcraft.yaml ##- Build snap package +ifeq ($(shell which snapcraft),) + sudo snap install --classic snapcraft +endif + snapcraft pack -.PHONY: test-legacy-units -test-legacy-units: - tox run -e test-legacy-py312 +.PHONY: publish +publish: publish-pypi ## Publish packages -.PHONY: test-units -test-units: test-legacy-units - tox run -e test-py312 +.PHONY: publish-pypi +publish-pypi: clean package-pip lint-twine ##- Publish Python packages to pypi + uv tool run twine upload dist/* -.PHONY: tests -tests: tests-static test-units +# Find dependencies that need installing +APT_PACKAGES := +ifeq ($(wildcard /usr/include/libxml2/libxml/xpath.h),) +APT_PACKAGES += libxml2-dev +endif +ifeq ($(wildcard /usr/include/libxslt/xslt.h),) +APT_PACKAGES += libxslt1-dev +endif +ifeq ($(wildcard /usr/share/doc/python3-venv/copyright),) +APT_PACKAGES += python3-venv +endif +ifeq ($(wildcard /usr/share/doc/libapt-pkg-dev/copyright),) +APT_PACKAGES += libapt-pkg-dev +endif +ifeq ($(wildcard /usr/share/doc/libgit2-dev/copyright),) +APT_PACKAGES += libgit2-dev +endif +ifeq ($(shell which cargo),) +APT_PACKAGES += cargo +endif +ifeq ($(wildcard /usr/share/doc/python3-dev),) +APT_PACKAGES += python3-dev +endif +ifeq ($(wildcard /usr/share/doc/libffi8),) +APT_PACKAGES += libffi-dev +endif +ifeq ($(wildcard /usr/share/doc/pkg-config/copyright),) +APT_PACKAGES += pkg-config +endif +ifeq ($(wildcard /usr/share/doc/libssl-dev/copyright),) +APT_PACKAGES += libssl-dev +endif +ifeq ($(wildcard /usr/share/doc/libyaml-dev/copyright),) +APT_PACKAGES += libyaml-dev +endif +# Needed for xdelta3 tests +ifeq ($(wildcard /usr/share/doc/xdelta3/copyright),) +APT_PACKAGES += xdelta3 +endif -.PHONY: tests-static -tests-static: test-black test-codespell test-ruff test-mypy test-pydocstyle test-pyright test-shellcheck +# Used for installing build dependencies in CI. +.PHONY: install-build-deps +install-build-deps: install-lint-build-deps +ifeq ($(APT_PACKAGES),) +else ifeq ($(shell which apt-get),) + $(warning Cannot install build dependencies without apt.) + $(warning Please ensure the equivalents to these packages are installed: $(APT_PACKAGES)) +else + sudo $(APT) install $(APT_PACKAGES) +endif -.PHONY: lint -lint: tests-static +# If additional build dependencies need installing in order to build the linting env. +.PHONY: install-lint-build-deps +install-lint-build-deps: diff --git a/common.mk b/common.mk new file mode 100644 index 0000000000..9b8a7be761 --- /dev/null +++ b/common.mk @@ -0,0 +1,287 @@ +# Common items for all Starcraft Makefiles. Should only be edited in the `starbase` repository: +# https://github.com/canonical/starbase + +SOURCES=$(wildcard *.py) $(PROJECT) tests +DOCS=docs + +ifneq ($(OS),Windows_NT) + OS := $(shell uname) +endif +ifdef CI + APT := apt-get --yes +else + APT := apt-get +endif + +PRETTIER=npm exec --package=prettier -- prettier --log-level warn +PRETTIER_FILES="**/*.{yaml,yml,json,json5,css,md}" + +# By default we should not update the uv lock file here. +export UV_FROZEN := true + +.DEFAULT_GOAL := help + +.ONESHELL: + +.SHELLFLAGS = -ec + +.PHONY: help +help: ## Show this help. + @printf "\e[1m%-30s\e[0m | \e[1m%s\e[0m\n" "Target" "Description" + printf "\e[2m%-30s + %-41s\e[0m\n" "------------------------------" "------------------------------------------------" + egrep '^[^:]+\: [^#]*##' $$(echo $(MAKEFILE_LIST) | tac --separator=' ') | sed -e 's/^[^:]*://' -e 's/:[^#]*/ /' | sort -V| awk -F '[: ]*' \ + '{ + if ($$2 == "##") + { + $$1=sprintf(" %-28s", $$1); + $$2=" | "; + print $$0; + } + else + { + $$1=sprintf(" â”” %-25s", $$1); + $$2=" | "; + $$3=sprintf(" â”” %s", $$3); + print $$0; + } + }' + +.PHONY: setup +setup: install-uv setup-precommit install-build-deps ## Set up a development environment + uv sync $(UV_TEST_GROUPS) $(UV_LINT_GROUPS) $(UV_DOCS_GROUPS) + +.PHONY: setup-tests +setup-tests: install-uv install-build-deps ##- Set up a testing environment without linters + uv sync $(UV_TEST_GROUPS) + +.PHONY: setup-lint +setup-lint: install-uv install-shellcheck install-pyright install-lint-build-deps ##- Set up a linting-only environment + uv sync $(UV_LINT_GROUPS) + +.PHONY: setup-docs +setup-docs: install-uv ##- Set up a documentation-only environment + uv sync --no-dev $(UV_DOCS_GROUPS) + +.PHONY: setup-precommit +setup-precommit: install-uv ##- Set up pre-commit hooks in this repository. +ifeq ($(shell which pre-commit),) + uv tool run pre-commit install +else + pre-commit install +endif + +.PHONY: clean +clean: ## Clean up the development environment + uv tool run pyclean . + rm -rf dist/ build/ docs/_build/ *.snap .coverage* + +.PHONY: autoformat +autoformat: format # Hidden alias for 'format' + +.PHONY: format-ruff +format-ruff: install-ruff ##- Automatically format with ruff + success=true + ruff check --fix $(SOURCES) || success=false + ruff format $(SOURCES) + $$success || exit 1 + +.PHONY: format-codespell +format-codespell: ##- Fix spelling issues with codespell + uv run codespell --toml pyproject.toml --write-changes $(SOURCES) + +.PHONY: format-prettier +format-prettier: install-npm ##- Format files with prettier + $(PRETTIER) --write $(PRETTIER_FILES) + +.PHONY: lint-ruff +lint-ruff: install-ruff ##- Lint with ruff +ifneq ($(CI),) + @echo ::group::$@ +endif + ruff check $(SOURCES) + ruff format --diff $(SOURCES) +ifneq ($(CI),) + @echo ::endgroup:: +endif + +.PHONY: lint-codespell +lint-codespell: install-codespell ##- Check spelling with codespell +ifneq ($(CI),) + @echo ::group::$@ +endif + uv run codespell --toml pyproject.toml $(SOURCES) +ifneq ($(CI),) + @echo ::endgroup:: +endif + +.PHONY: lint-mypy +lint-mypy: ##- Check types with mypy +ifneq ($(CI),) + @echo ::group::$@ +endif + uv run mypy --show-traceback --show-error-codes $(PROJECT) +ifneq ($(CI),) + @echo ::endgroup:: +endif + +.PHONY: lint-pyright +lint-pyright: ##- Check types with pyright +ifneq ($(CI),) + @echo ::group::$@ +endif +ifneq ($(shell which pyright),) # Prefer the system pyright + pyright --pythonpath .venv/bin/python +else + uv tool run pyright --pythonpath .venv/bin/python +endif +ifneq ($(CI),) + @echo ::endgroup:: +endif + +.PHONY: lint-shellcheck +lint-shellcheck: ##- Lint shell scripts +ifneq ($(CI),) + @echo ::group::$@ +endif + git ls-files | file --mime-type -Nnf- | grep shellscript | cut -f1 -d: | xargs -r shellcheck +ifneq ($(CI),) + @echo ::endgroup:: +endif + +.PHONY: lint-prettier +lint-prettier: install-npm ##- Lint files with prettier +ifneq ($(CI),) + @echo ::group::$@ +endif + $(PRETTIER) --check $(PRETTIER_FILES) +ifneq ($(CI),) + @echo ::endgroup:: +endif + +.PHONY: lint-docs +lint-docs: ##- Lint the documentation +ifneq ($(CI),) + @echo ::group::$@ +endif + uv run $(UV_DOCS_GROUPS) sphinx-lint --max-line-length 88 --ignore docs/reference/commands --ignore docs/_build --enable all $(DOCS) -d missing-underscore-after-hyperlink,missing-space-in-hyperlink +ifneq ($(CI),) + @echo ::endgroup:: +endif + +.PHONY: lint-twine +lint-twine: pack-pip ##- Lint Python packages with twine +ifneq ($(CI),) + @echo ::group::$@ +endif + uv tool run twine check dist/* +ifneq ($(CI),) + @echo ::endgroup:: +endif + +.PHONY: test +test: ## Run all tests + uv run pytest + +.PHONY: test-fast +test-fast: ##- Run fast tests + uv run pytest -m 'not slow' + +.PHONY: test-slow +test-slow: ##- Run slow tests + uv run pytest -m 'slow' + +.PHONY: test-coverage +test-coverage: ## Generate coverage report + uv run coverage run --source $(PROJECT) -m pytest + uv run coverage xml -o coverage.xml + uv run coverage report -m + uv run coverage html + +.PHONY: docs +docs: ## Build documentation + uv run --group docs sphinx-build -b html -W $(DOCS) $(DOCS)/_build + +.PHONY: docs-auto +docs-auto: ## Build and host docs with sphinx-autobuild + uv run --group docs sphinx-autobuild -b html --open-browser --port=8080 --watch $(PROJECT) -W $(DOCS) $(DOCS)/_build + +.PHONY: pack-pip +pack-pip: ##- Build packages for pip (sdist, wheel) +ifneq ($(CI),) + @echo ::group::$@ +endif + uv build --quiet . +ifneq ($(CI),) + @echo ::endgroup:: +endif + +# Below are intermediate targets for setup. They are not included in help as they should +# not be used independently. + +.PHONY: install-uv +install-uv: +ifneq ($(shell which uv),) +else ifneq ($(shell which snap),) + sudo snap install --classic astral-uv +else ifneq ($(shell which brew),) + brew install uv +else ifeq ($(OS),Windows_NT) + pwsh -c "irm https://astral.sh/uv/install.ps1 | iex" +else + curl -LsSf https://astral.sh/uv/install.sh | sh +endif + +.PHONY: install-codespell +install-codespell: +ifneq ($(shell which codespell),) +else ifneq ($(shell which snap),) + sudo snap install codespell +else ifneq ($(shell which brew),) + make install-uv + uv tool install codespell +else + $(warning Codespell not installed. Please install it yourself.) +endif + +.PHONY: install-pyright +install-pyright: install-uv +ifneq ($(shell which pyright),) +else ifneq ($(shell which snap),) + sudo snap install --classic pyright +else + # Workaround for a bug in npm + [ -d "$(HOME)/.npm/_cacache" ] && chown -R `id -u`:`id -g` "$(HOME)/.npm" || true + uv tool install pyright +endif + +.PHONY: install-ruff +install-ruff: +ifneq ($(shell which ruff),) +else ifneq ($(shell which snap),) + sudo snap install ruff +else + make install-uv + uv tool install ruff +endif + +.PHONY: install-shellcheck +install-shellcheck: +ifneq ($(shell which shellcheck),) +else ifneq ($(shell which snap),) + sudo snap install shellcheck +else ifneq ($(shell which brew),) + brew install shellcheck +else + $(warning Shellcheck not installed. Please install it yourself.) +endif + +.PHONY: install-npm +install-npm: +ifneq ($(shell which npm),) +else ifneq ($(shell which snap),) + sudo snap install --classic node +else ifneq ($(shell which brew),) + brew install node +else + $(error npm not installed. Please install it yourself.) +endif diff --git a/pyproject.toml b/pyproject.toml index 120f1e1a07..f71dbbb49b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,84 @@ classifiers = [ ] requires-python = ">=3.12" +[dependency-groups] +dev = [ + "coverage[toml]", + "pyflakes", + "fixtures", + # For Tiobe TiCS + "flake8", + "mccabe", + "testscenarios", + "pexpect", + "pip", + "pycodestyle", + "pyftpdlib", + "pyinstaller ; sys_platform == 'win32'", + # For Tiobe TiCS + "pylint", + "pyramid", + "pytest", + "pytest-cov", + "pytest-check", + "pytest-mock", + "pytest-subprocess", +] +docs = [ + "canonical-sphinx[full]>=0.2.0", + "sphinx-autobuild", + "sphinx-autodoc-typehints", + "sphinxcontrib-details-directive", + "sphinx-lint", + "sphinx-toolbox", + "pyspelling", +] +lint = [ + "yamllint~=1.34", + "codespell[toml]", + { include-group = "types" }, +] +types = [ + "mypy", + "types-PyYAML", + # Pinned because any higher requires urllib3>=2 + "types-requests==2.31.0.6", + "types-setuptools", + "types-simplejson", + "types-tabulate", + "types-toml", +] +dev-jammy = [ + # Stay on 2.4 for Jammy + "python-apt~=2.4.0;sys_platform=='linux'", +] +dev-noble = [ + # 2.7 for Noble + "python-apt~=2.7.0;sys_platform=='linux'", +] +dev-oracular = [ + # 2.9 for Oracular+ + "python-apt>=2.9.0;sys_platform=='linux'", +] +dev-plucky = [ + # 2.9 for Oracular+ + "python-apt>=2.9.0;sys_platform=='linux'", +] + +[tool.uv] +conflicts = [ + [ + { group = "dev-jammy" }, + { group = "dev-noble" }, + { group = "dev-oracular" }, + { group = "dev-plucky" }, + ] +] + +[[tool.uv.index]] +name = "python-apt-wheels" +url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" # workaround to get python-apt to install across multiple platforms + [project.scripts] snapcraft = "snapcraft.application:main" snapcraft_legacy = "snapcraft_legacy.cli.__main__:run" diff --git a/uv.lock b/uv.lock index 6576ed4853..fc32866060 100644 --- a/uv.lock +++ b/uv.lock @@ -4,6 +4,12 @@ resolution-markers = [ "python_full_version >= '3.13'", "python_full_version < '3.13'", ] +conflicts = [[ + { package = "snapcraft", group = "dev-jammy" }, + { package = "snapcraft", group = "dev-noble" }, + { package = "snapcraft", group = "dev-oracular" }, + { package = "snapcraft", group = "dev-plucky" }, +]] [[package]] name = "alabaster" @@ -39,7 +45,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "sniffio" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126 } wheels = [ @@ -311,7 +317,7 @@ name = "click" version = "8.1.7" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } wheels = [ @@ -427,7 +433,7 @@ dependencies = [ { name = "jinja2" }, { name = "overrides" }, { name = "platformdirs" }, - { name = "pywin32", marker = "sys_platform == 'win32'" }, + { name = "pywin32", marker = "sys_platform == 'win32' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, { name = "pyyaml" }, { name = "typing-extensions" }, ] @@ -520,7 +526,7 @@ name = "cryptography" version = "43.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, + { name = "cffi", marker = "platform_python_implementation != 'PyPy' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0d/05/07b55d1fa21ac18c3a8c79f764e2514e6f6a9698f1be44994f5adf0d29db/cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", size = 686989 } wheels = [ @@ -870,9 +876,9 @@ dependencies = [ { name = "jaraco-classes" }, { name = "jaraco-context" }, { name = "jaraco-functools" }, - { name = "jeepney", marker = "sys_platform == 'linux'" }, - { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, - { name = "secretstorage", marker = "sys_platform == 'linux'" }, + { name = "jeepney", marker = "sys_platform == 'linux' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, + { name = "pywin32-ctypes", marker = "sys_platform == 'win32' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, + { name = "secretstorage", marker = "sys_platform == 'linux' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/70/09/d904a6e96f76ff214be59e7aa6ef7190008f52a0ab6689760a98de0bf37d/keyring-25.6.0.tar.gz", hash = "sha256:0b39998aa941431eb3d9b0d4b2460bc773b9df6fed7621c2dfb291a7e0187a66", size = 62750 } wheels = [ @@ -1531,10 +1537,11 @@ version = "6.11.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "altgraph" }, + { name = "macholib", marker = "sys_platform == 'darwin' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, { name = "packaging" }, - { name = "pefile", marker = "sys_platform == 'win32'" }, + { name = "pefile", marker = "sys_platform == 'win32' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, { name = "pyinstaller-hooks-contrib" }, - { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, + { name = "pywin32-ctypes", marker = "sys_platform == 'win32' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, { name = "setuptools" }, ] sdist = { url = "https://files.pythonhosted.org/packages/55/d4/54f5f5c73b803e6256ea97ffc6ba8a305d9a5f57f85f9b00b282512bf18a/pyinstaller-6.11.1.tar.gz", hash = "sha256:491dfb4d9d5d1d9650d9507daec1ff6829527a254d8e396badd60a0affcb72ef", size = 4249772 } @@ -1563,7 +1570,7 @@ version = "3.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "astroid" }, - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, { name = "dill" }, { name = "isort" }, { name = "mccabe" }, @@ -1688,7 +1695,7 @@ name = "pytest" version = "8.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, @@ -1935,7 +1942,7 @@ name = "ruamel-yaml" version = "0.18.10" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ruamel-yaml-clib", marker = "python_full_version < '3.13' and platform_python_implementation == 'CPython'" }, + { name = "ruamel-yaml-clib", marker = "(python_full_version < '3.13' and platform_python_implementation == 'CPython') or (python_full_version >= '3.13' and extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (python_full_version >= '3.13' and extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (python_full_version >= '3.13' and extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (python_full_version >= '3.13' and extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (python_full_version >= '3.13' and extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (python_full_version >= '3.13' and extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky') or (platform_python_implementation != 'CPython' and extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (platform_python_implementation != 'CPython' and extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (platform_python_implementation != 'CPython' and extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (platform_python_implementation != 'CPython' and extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (platform_python_implementation != 'CPython' and extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (platform_python_implementation != 'CPython' and extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ea/46/f44d8be06b85bc7c4d8c95d658be2b68f27711f279bf9dd0612a5e4794f5/ruamel.yaml-0.18.10.tar.gz", hash = "sha256:20c86ab29ac2153f80a428e1254a8adf686d3383df04490514ca3b79a362db58", size = 143447 } wheels = [ @@ -2057,10 +2064,11 @@ wheels = [ [[package]] name = "snapcraft" +version = "8.5.1.post87+dirty" source = { editable = "." } dependencies = [ { name = "attrs" }, - { name = "catkin-pkg", marker = "sys_platform == 'linux'" }, + { name = "catkin-pkg", marker = "sys_platform == 'linux' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, { name = "click" }, { name = "craft-application" }, { name = "craft-archives" }, @@ -2084,10 +2092,9 @@ dependencies = [ { name = "pydantic" }, { name = "pyelftools" }, { name = "pygit2" }, - { name = "pylxd", marker = "sys_platform == 'linux'" }, + { name = "pylxd", marker = "sys_platform == 'linux' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, { name = "pymacaroons" }, - { name = "python-apt", marker = "sys_platform == 'linux'" }, - { name = "python-debian", marker = "sys_platform == 'linux'" }, + { name = "python-debian", marker = "sys_platform == 'linux' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, { name = "pyxdg" }, { name = "pyyaml" }, { name = "raven" }, @@ -2114,7 +2121,7 @@ dev = [ { name = "pycodestyle" }, { name = "pyflakes" }, { name = "pyftpdlib" }, - { name = "pyinstaller", marker = "sys_platform == 'win32'" }, + { name = "pyinstaller", marker = "sys_platform == 'win32' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, { name = "pylint" }, { name = "pyramid" }, { name = "pytest" }, @@ -2124,6 +2131,18 @@ dev = [ { name = "pytest-subprocess" }, { name = "testscenarios" }, ] +dev-jammy = [ + { name = "python-apt", version = "2.4.0+ubuntu4", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, +] +dev-noble = [ + { name = "python-apt", version = "2.7.7+ubuntu3", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, +] +dev-oracular = [ + { name = "python-apt", version = "2.9.0+ubuntu1", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, +] +dev-plucky = [ + { name = "python-apt", version = "2.9.0+ubuntu1", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, +] docs = [ { name = "canonical-sphinx", extra = ["full"] }, { name = "pyspelling" }, @@ -2214,6 +2233,10 @@ dev = [ { name = "pytest-subprocess" }, { name = "testscenarios" }, ] +dev-jammy = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = "~=2.4.0" }] +dev-noble = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = "~=2.7.0" }] +dev-oracular = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = ">=2.9.0" }] +dev-plucky = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = ">=2.9.0" }] docs = [ { name = "canonical-sphinx", extras = ["full"], specifier = ">=0.2.0" }, { name = "pyspelling" }, @@ -2271,7 +2294,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "alabaster" }, { name = "babel" }, - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, { name = "docutils" }, { name = "imagesize" }, { name = "jinja2" }, @@ -2363,7 +2386,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jinja2" }, { name = "markupsafe" }, - { name = "standard-imghdr", marker = "python_full_version >= '3.13'" }, + { name = "standard-imghdr", marker = "python_full_version >= '3.13' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/26/df/27282da6f8c549f765beca9de1a5fc56f9651ed87711a5cac1e914137753/sphinx_jinja2_compat-0.3.0.tar.gz", hash = "sha256:f3c1590b275f42e7a654e081db5e3e5fb97f515608422bde94015ddf795dfe7c", size = 4998 } wheels = [ @@ -2842,7 +2865,7 @@ name = "webob" version = "1.8.9" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "legacy-cgi", marker = "python_full_version >= '3.13'" }, + { name = "legacy-cgi", marker = "python_full_version >= '3.13' or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-noble') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-jammy' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-oracular') or (extra == 'group-9-snapcraft-dev-noble' and extra == 'group-9-snapcraft-dev-plucky') or (extra == 'group-9-snapcraft-dev-oracular' and extra == 'group-9-snapcraft-dev-plucky')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/85/0b/1732085540b01f65e4e7999e15864fe14cd18b12a95731a43fd6fd11b26a/webob-1.8.9.tar.gz", hash = "sha256:ad6078e2edb6766d1334ec3dee072ac6a7f95b1e32ce10def8ff7f0f02d56589", size = 279775 } wheels = [ From d26f18524eebe0c377778d5b9dc0f27f49f2e2c6 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 09:14:07 -0500 Subject: [PATCH 308/333] chore: move data_files and scripts from setup.py into pyproject.toml data_files is deprecated, so changes to common.py compensate for the change needed to remove its use --- pyproject.toml | 13 ++++++++----- snap/snapcraft.yaml | 4 ++++ snapcraft_legacy/internal/common.py | 9 ++++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f71dbbb49b..0e71fc9daf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,14 +4,14 @@ description = "Create snaps" readme = "README.md" dynamic = ["version"] dependencies = [ - "attrs==24.2.0", + "attrs", "catkin-pkg==1.0.0 ; sys_platform == 'linux'", "click==8.1.7", "craft-application~=4.4", "craft-archives~=2.0", - "craft-cli~=2.9", + "craft-cli~=2.15.0", "craft-grammar>=2.0.1,<3.0.0", - "craft-parts==2.3.0", + "craft-parts==2.4.1", "craft-platforms~=0.4", "craft-store>=3.0.2,<4.0.0", "cryptography==43.0.3", # Pinned due to https://github.com/canonical/snapcraft/issues/5217 @@ -153,6 +153,9 @@ requires = [ ] build-backend = "setuptools.build_meta" +[tool.setuptools] +script-files = ["bin/snapcraftctl", "bin/snapcraftctl-compat"] + [tool.setuptools_scm] write_to = "snapcraft/_version.py" # the version comes from the latest annotated git tag formatted as 'X.Y.Z' @@ -183,8 +186,8 @@ git_describe_command = [ local_scheme = "dirty-tag" [tool.setuptools.packages.find] -include = ["*craft*"] -namespaces = false +include = ["snapcraft", "extensions", "keyrings", "schema", "snapcraft_legacy"] +namespaces = true [tool.mypy] python_version = "3.12" diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index d90d0eed7c..382bf8cbac 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -182,6 +182,10 @@ parts: bin/snapcraftctl: bin/scriptlet-bin/snapcraftctl # Also install the compatibility wrapper for core22+. bin/snapcraftctl-compat: libexec/snapcraft/snapcraftctl + # Include general data in the share directory + "**/site-packages/extensions": share/snapcraft/extensions + "**/site-packages/keyrings": share/snapcraft/keyrings + "**/site-packages/schema": share/snapcraft/schema build-attributes: - enable-patchelf build-environment: diff --git a/snapcraft_legacy/internal/common.py b/snapcraft_legacy/internal/common.py index 6017b40505..33f7f26e37 100644 --- a/snapcraft_legacy/internal/common.py +++ b/snapcraft_legacy/internal/common.py @@ -35,13 +35,16 @@ from snapcraft_legacy.internal import errors SNAPCRAFT_FILES = ["parts", "stage", "prime"] + _DEFAULT_PLUGINDIR = os.path.join(sys.prefix, "share", "snapcraft", "plugins") _plugindir = _DEFAULT_PLUGINDIR -_DEFAULT_SCHEMADIR = os.path.join(sys.prefix, "share", "snapcraft", "schema") + +_BASE_DIR = Path(__file__).parents[2] +_DEFAULT_SCHEMADIR = _BASE_DIR / "schema" _schemadir = _DEFAULT_SCHEMADIR -_DEFAULT_EXTENSIONSDIR = os.path.join(sys.prefix, "share", "snapcraft", "extensions") +_DEFAULT_EXTENSIONSDIR = _BASE_DIR / "extensions" _extensionsdir = _DEFAULT_EXTENSIONSDIR -_DEFAULT_KEYRINGSDIR = os.path.join(sys.prefix, "share", "snapcraft", "keyrings") +_DEFAULT_KEYRINGSDIR = _BASE_DIR / "keyrings" _keyringsdir = _DEFAULT_KEYRINGSDIR _DOCKERENV_FILE = "/.dockerenv" From 081a66d062e9a9d7bd46479ba9c231a9b0cc5277 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 09:56:16 -0500 Subject: [PATCH 309/333] build: remove all requirements files and generate requirements with uv --- appveyor.yml | 13 +- pyproject.toml | 2 +- requirements-devel.txt | 431 ----------------------------------- requirements-docs.txt | 495 ----------------------------------------- requirements.txt | 272 ---------------------- snap/snapcraft.yaml | 5 +- 6 files changed, 11 insertions(+), 1207 deletions(-) delete mode 100644 requirements-devel.txt delete mode 100644 requirements-docs.txt delete mode 100644 requirements.txt diff --git a/appveyor.yml b/appveyor.yml index 7f4a447663..09c3389a43 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,13 +15,12 @@ cache: build: off install: -- cmd: | - %PYTHON%\python.exe -m venv venv - venv\Scripts\activate.bat - python -c "import sys; print(sys.executable)" - python -m pip install -r requirements-devel.txt - python -m pip install --prefix %VIRTUAL_ENV% -e . - venv\Scripts\deactivate.bat + - cmd: | + %PYTHON%\python.exe -m venv venv + venv\Scripts\activate.bat + python -c "import sys; print(sys.executable)" + python -m pip install --prefix %VIRTUAL_ENV% -e . + venv\Scripts\deactivate.bat build_script: - cmd: | diff --git a/pyproject.toml b/pyproject.toml index 0e71fc9daf..e3f6a2f215 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ dependencies = [ "attrs", "catkin-pkg==1.0.0 ; sys_platform == 'linux'", "click==8.1.7", - "craft-application~=4.4", + "craft-application>=4.4.1,<5.0.0", "craft-archives~=2.0", "craft-cli~=2.15.0", "craft-grammar>=2.0.1,<3.0.0", diff --git a/requirements-devel.txt b/requirements-devel.txt deleted file mode 100644 index 572eeb3a11..0000000000 --- a/requirements-devel.txt +++ /dev/null @@ -1,431 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile --extra=dev --output-file=requirements-devel.txt -# -annotated-types==0.7.0 - # via - # craft-platforms - # pydantic -astroid==3.3.5 - # via pylint -attrs==24.2.0 - # via snapcraft (setup.py) -black==24.10.0 - # via snapcraft (setup.py) -boolean-py==4.0 - # via license-expression -cachetools==5.5.0 - # via tox -catkin-pkg==1.0.0 ; sys_platform == "linux" - # via snapcraft (setup.py) -certifi==2024.8.30 - # via requests -cffi==1.17.1 - # via - # cryptography - # pygit2 - # pynacl -chardet==5.2.0 - # via - # python-debian - # tox -charset-normalizer==3.4.0 - # via requests -click==8.1.7 - # via - # black - # snapcraft (setup.py) -codespell[toml]==2.3.0 - # via snapcraft (setup.py) -colorama==0.4.6 - # via tox -coverage[toml]==7.6.4 - # via - # pytest-cov - # snapcraft (setup.py) -craft-application==4.4.1 - # via snapcraft (setup.py) -craft-archives==2.0.1 - # via - # craft-application - # snapcraft (setup.py) -craft-cli==2.15.0 - # via - # craft-application - # snapcraft (setup.py) -craft-grammar==2.0.1 - # via - # craft-application - # snapcraft (setup.py) -craft-parts==2.4.1 - # via - # craft-application - # snapcraft (setup.py) -craft-platforms==0.4.0 - # via - # craft-application - # snapcraft (setup.py) -craft-providers==2.0.4 - # via - # craft-application - # snapcraft (setup.py) -craft-store==3.0.2 - # via snapcraft (setup.py) -cryptography==43.0.3 - # via - # pylxd - # secretstorage -dill==0.3.9 - # via pylint -distlib==0.3.9 - # via virtualenv -distro==1.9.0 - # via - # craft-archives - # craft-platforms - # lazr-restfulclient -docutils==0.19 - # via - # catkin-pkg - # snapcraft (setup.py) -filelock==3.16.1 - # via - # tox - # virtualenv -fixtures==4.1.0 - # via snapcraft (setup.py) -flake8==7.1.1 - # via snapcraft (setup.py) -gnupg==2.3.1 - # via snapcraft (setup.py) -httplib2==0.22.0 - # via - # launchpadlib - # lazr-restfulclient -hupper==1.12.1 - # via pyramid -idna==3.10 - # via requests -iniconfig==2.0.0 - # via pytest -isort==5.13.2 - # via pylint -jaraco-classes==3.4.0 - # via - # craft-store - # keyring -jaraco-context==6.0.1 - # via keyring -jaraco-functools==4.1.0 - # via keyring -jeepney==0.8.0 - # via - # keyring - # secretstorage -jinja2==3.1.5 - # via craft-application -jsonschema==2.5.1 - # via snapcraft (setup.py) -keyring==25.5.0 - # via craft-store -launchpadlib==2.0.0 - # via - # craft-archives - # snapcraft (setup.py) -lazr-restfulclient==0.14.6 - # via - # craft-archives - # launchpadlib - # snapcraft (setup.py) -lazr-uri==1.0.6 - # via - # craft-archives - # launchpadlib - # wadllib -license-expression==30.4.0 - # via craft-application -lxml==5.3.0 - # via snapcraft (setup.py) -macaroonbakery==1.3.4 - # via - # craft-store - # snapcraft (setup.py) -markupsafe==3.0.2 - # via jinja2 -mccabe==0.7.0 - # via - # flake8 - # pylint - # snapcraft (setup.py) -more-itertools==10.5.0 - # via - # jaraco-classes - # jaraco-functools -mypy==1.13.0 - # via snapcraft (setup.py) -mypy-extensions==1.0.0 - # via - # black - # mypy - # snapcraft (setup.py) -oauthlib==3.2.2 - # via lazr-restfulclient -overrides==7.7.0 - # via - # craft-archives - # craft-grammar - # craft-parts - # craft-store - # snapcraft (setup.py) -packaging==24.2 - # via - # black - # craft-providers - # pyproject-api - # pytest - # snapcraft (setup.py) - # tox -pastedeploy==3.1.0 - # via plaster-pastedeploy -pathspec==0.12.1 - # via - # black - # yamllint -pbr==6.1.0 - # via - # fixtures - # testscenarios -pexpect==4.9.0 - # via snapcraft (setup.py) -plaster==1.1.2 - # via - # plaster-pastedeploy - # pyramid -plaster-pastedeploy==1.0.1 - # via pyramid -platformdirs==4.3.6 - # via - # black - # craft-application - # craft-cli - # pylint - # tox - # virtualenv -pluggy==1.5.0 - # via - # pytest - # tox -progressbar==2.5 - # via snapcraft (setup.py) -protobuf==5.28.3 - # via macaroonbakery -psutil==6.1.0 - # via gnupg -ptyprocess==0.7.0 - # via pexpect -pyasynchat==1.0.4 - # via pyftpdlib -pyasyncore==1.0.4 - # via - # pyasynchat - # pyftpdlib -pycodestyle==2.12.1 - # via - # flake8 - # snapcraft (setup.py) -pycparser==2.22 - # via cffi -pydantic==2.10.3 - # via - # craft-application - # craft-archives - # craft-grammar - # craft-parts - # craft-providers - # craft-store - # snapcraft (setup.py) -pydantic-core==2.27.1 - # via pydantic -pydocstyle==6.3.0 - # via snapcraft (setup.py) -pyelftools==0.31 - # via snapcraft (setup.py) -pyflakes==3.2.0 - # via - # flake8 - # snapcraft (setup.py) -pyftpdlib==2.0.1 - # via snapcraft (setup.py) -pygit2==1.13.3 - # via - # craft-application - # snapcraft (setup.py) -pylint==3.3.1 - # via snapcraft (setup.py) -pylxd==2.3.5 ; sys_platform == "linux" - # via snapcraft (setup.py) -pymacaroons==0.13.0 - # via - # macaroonbakery - # snapcraft (setup.py) -pynacl==1.5.0 - # via - # macaroonbakery - # pymacaroons -pyparsing==3.2.0 - # via - # catkin-pkg - # httplib2 -pyproject-api==1.8.0 - # via tox -pyramid==2.0.2 - # via snapcraft (setup.py) -pyrfc3339==1.1 - # via macaroonbakery -pytest==8.3.3 - # via - # pytest-check - # pytest-cov - # pytest-mock - # pytest-subprocess - # snapcraft (setup.py) -pytest-check==2.4.1 - # via snapcraft (setup.py) -pytest-cov==6.0.0 - # via snapcraft (setup.py) -pytest-mock==3.14.0 - # via snapcraft (setup.py) -pytest-subprocess==1.5.2 - # via snapcraft (setup.py) - # via snapcraft (setup.py) -python-dateutil==2.9.0.post0 - # via - # catkin-pkg - # pylxd -python-debian==0.1.49 ; sys_platform == "linux" - # via - # craft-archives - # snapcraft (setup.py) -pytz==2024.2 - # via pyrfc3339 -pyxdg==0.28 - # via - # craft-parts - # craft-store - # snapcraft (setup.py) -pyyaml==6.0.2 - # via - # craft-application - # craft-cli - # craft-parts - # craft-providers - # snap-helpers - # snapcraft (setup.py) - # yamllint -raven==6.10.0 - # via snapcraft (setup.py) -requests==2.32.3 - # via - # craft-application - # craft-parts - # craft-providers - # craft-store - # macaroonbakery - # pylxd - # requests-toolbelt - # requests-unixsocket2 - # snapcraft (setup.py) -requests-toolbelt==1.0.0 - # via - # craft-store - # pylxd - # snapcraft (setup.py) -requests-unixsocket2==0.4.2 - # via - # craft-parts - # craft-providers - # snapcraft (setup.py) -secretstorage==3.3.3 - # via keyring -simplejson==3.19.3 - # via snapcraft (setup.py) -six==1.16.0 - # via - # lazr-restfulclient - # macaroonbakery - # pymacaroons - # python-dateutil -snap-helpers==0.4.2 - # via - # craft-application - # snapcraft (setup.py) -snowballstemmer==2.2.0 - # via pydocstyle -tabulate==0.9.0 - # via snapcraft (setup.py) -testscenarios==0.5.0 - # via snapcraft (setup.py) -testtools==2.7.2 - # via testscenarios -tinydb==4.8.2 - # via snapcraft (setup.py) -toml==0.10.2 - # via snapcraft (setup.py) -tomlkit==0.13.2 - # via pylint -tox==4.23.2 - # via snapcraft (setup.py) -translationstring==1.4 - # via pyramid -types-pyyaml==6.0.12.20240917 - # via snapcraft (setup.py) -types-requests==2.31.0.6 - # via snapcraft (setup.py) -types-setuptools==75.3.0.20241112 - # via snapcraft (setup.py) -types-simplejson==3.19.0.20240801 - # via snapcraft (setup.py) -types-tabulate==0.9.0.20240106 - # via snapcraft (setup.py) -types-toml==0.10.8.20240310 - # via snapcraft (setup.py) -types-urllib3==1.26.25.14 - # via types-requests -typing-extensions==4.12.2 - # via - # craft-application - # craft-platforms - # mypy - # pydantic - # pydantic-core - # snapcraft (setup.py) -urllib3==2.2.3 - # via - # requests - # requests-unixsocket2 -validators==0.34.0 - # via snapcraft (setup.py) -venusian==3.1.0 - # via pyramid -virtualenv==20.27.1 - # via tox -wadllib==2.0.0 - # via lazr-restfulclient -webob==1.8.9 - # via pyramid -ws4py==0.5.1 - # via pylxd -yamllint==1.35.1 - # via snapcraft (setup.py) -zope-deprecation==5.0 - # via pyramid -zope-interface==7.1.1 - # via pyramid - -# The following packages are considered to be unsafe in a requirements file: -# pip -# setuptools -python-apt @ https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz ; sys.platform == "linux" -pyinstaller==5.13.1 ; sys.platform == "win32" diff --git a/requirements-docs.txt b/requirements-docs.txt deleted file mode 100644 index bf0c316e6c..0000000000 --- a/requirements-docs.txt +++ /dev/null @@ -1,495 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile --extra=docs --output-file=requirements-docs.txt -# -alabaster==0.7.16 - # via sphinx -annotated-types==0.7.0 - # via - # craft-platforms - # pydantic -anyio==4.6.2.post1 - # via - # starlette - # watchfiles -apeye==1.4.1 - # via sphinx-toolbox -apeye-core==1.1.5 - # via apeye -attrs==24.2.0 - # via snapcraft (setup.py) -autodocsumm==0.2.14 - # via sphinx-toolbox -babel==2.16.0 - # via sphinx -beautifulsoup4==4.12.3 - # via - # canonical-sphinx-extensions - # furo - # pyspelling - # sphinx-toolbox -boolean-py==4.0 - # via license-expression -bracex==2.5.post1 - # via wcmatch -cachecontrol[filecache]==0.14.1 - # via sphinx-toolbox -canonical-sphinx[full]==0.2.0 - # via snapcraft (setup.py) -canonical-sphinx-extensions==0.0.23 - # via canonical-sphinx -catkin-pkg==1.0.0 ; sys_platform == "linux" - # via snapcraft (setup.py) -certifi==2024.8.30 - # via requests -cffi==1.17.1 - # via - # cryptography - # pygit2 - # pynacl -chardet==5.2.0 - # via python-debian -charset-normalizer==3.4.0 - # via requests -click==8.1.7 - # via - # snapcraft (setup.py) - # uvicorn -colorama==0.4.6 - # via sphinx-autobuild -craft-application==4.4.1 - # via snapcraft (setup.py) -craft-archives==2.0.1 - # via - # craft-application - # snapcraft (setup.py) -craft-cli==2.15.0 - # via - # craft-application - # snapcraft (setup.py) -craft-grammar==2.0.1 - # via - # craft-application - # snapcraft (setup.py) -craft-parts==2.4.1 - # via - # craft-application - # snapcraft (setup.py) -craft-platforms==0.4.0 - # via - # craft-application - # snapcraft (setup.py) -craft-providers==2.0.4 - # via - # craft-application - # snapcraft (setup.py) -craft-store==3.0.2 - # via snapcraft (setup.py) -cryptography==43.0.3 - # via - # pylxd - # secretstorage -cssutils==2.11.1 - # via dict2css -dict2css==0.3.0.post1 - # via sphinx-toolbox -distro==1.9.0 - # via - # craft-archives - # craft-platforms - # lazr-restfulclient -docutils==0.19 - # via - # canonical-sphinx-extensions - # catkin-pkg - # myst-parser - # snapcraft (setup.py) - # sphinx - # sphinx-prompt - # sphinx-tabs - # sphinx-toolbox -domdf-python-tools==3.9.0 - # via - # apeye - # apeye-core - # dict2css - # sphinx-toolbox -filelock==3.16.1 - # via - # cachecontrol - # sphinx-toolbox -furo==2024.8.6 - # via canonical-sphinx -gitdb==4.0.11 - # via gitpython -gitpython==3.1.43 - # via canonical-sphinx-extensions -gnupg==2.3.1 - # via snapcraft (setup.py) -h11==0.14.0 - # via uvicorn -html5lib==1.1 - # via - # pyspelling - # sphinx-toolbox -httplib2==0.22.0 - # via - # launchpadlib - # lazr-restfulclient -idna==3.10 - # via - # anyio - # apeye-core - # requests -imagesize==1.4.1 - # via sphinx -jaraco-classes==3.4.0 - # via - # craft-store - # keyring -jaraco-context==6.0.1 - # via keyring -jaraco-functools==4.1.0 - # via keyring -jeepney==0.8.0 - # via - # keyring - # secretstorage -jinja2==3.1.5 - # via - # craft-application - # craft-cli - # myst-parser - # sphinx - # sphinx-jinja2-compat -jsonschema==2.5.1 - # via snapcraft (setup.py) -keyring==25.5.0 - # via craft-store -launchpadlib==2.0.0 - # via - # craft-archives - # snapcraft (setup.py) -lazr-restfulclient==0.14.6 - # via - # craft-archives - # launchpadlib - # snapcraft (setup.py) -lazr-uri==1.0.6 - # via - # craft-archives - # launchpadlib - # wadllib -license-expression==30.4.0 - # via craft-application -linkify-it-py==2.0.3 - # via canonical-sphinx -lxml==5.3.0 - # via - # pyspelling - # snapcraft (setup.py) -macaroonbakery==1.3.4 - # via - # craft-store - # snapcraft (setup.py) -markdown==3.7 - # via pyspelling -markdown-it-py==3.0.0 - # via - # mdit-py-plugins - # myst-parser -markupsafe==3.0.2 - # via - # jinja2 - # sphinx-jinja2-compat -mdit-py-plugins==0.4.2 - # via myst-parser -mdurl==0.1.2 - # via markdown-it-py -more-itertools==10.5.0 - # via - # cssutils - # jaraco-classes - # jaraco-functools -msgpack==1.1.0 - # via cachecontrol -mypy-extensions==1.0.0 - # via snapcraft (setup.py) -myst-parser==4.0.0 - # via canonical-sphinx -natsort==8.4.0 - # via domdf-python-tools -oauthlib==3.2.2 - # via lazr-restfulclient -overrides==7.7.0 - # via - # craft-archives - # craft-cli - # craft-grammar - # craft-parts - # craft-store - # snapcraft (setup.py) -packaging==24.2 - # via - # craft-providers - # snapcraft (setup.py) - # sphinx -platformdirs==4.3.6 - # via - # apeye - # craft-application - # craft-cli -polib==1.2.0 - # via sphinx-lint -progressbar==2.5 - # via snapcraft (setup.py) -protobuf==5.28.3 - # via macaroonbakery -psutil==6.1.0 - # via gnupg -pycparser==2.22 - # via cffi -pydantic==2.10.3 - # via - # craft-application - # craft-archives - # craft-grammar - # craft-parts - # craft-providers - # craft-store - # snapcraft (setup.py) -pydantic-core==2.27.1 - # via pydantic -pyelftools==0.31 - # via snapcraft (setup.py) -pygit2==1.13.3 - # via - # craft-application - # snapcraft (setup.py) -pygments==2.18.0 - # via - # furo - # sphinx - # sphinx-prompt - # sphinx-tabs -pylxd==2.3.5 ; sys_platform == "linux" - # via snapcraft (setup.py) -pymacaroons==0.13.0 - # via - # macaroonbakery - # snapcraft (setup.py) -pynacl==1.5.0 - # via - # macaroonbakery - # pymacaroons -pyparsing==3.2.0 - # via - # catkin-pkg - # httplib2 -pyrfc3339==1.1 - # via macaroonbakery -pyspelling==2.10 - # via - # canonical-sphinx - # snapcraft (setup.py) -python-apt @ https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz ; sys_platform == "linux" - # via snapcraft (setup.py) -python-dateutil==2.9.0.post0 - # via - # catkin-pkg - # pylxd -python-debian==0.1.49 ; sys_platform == "linux" - # via - # craft-archives - # snapcraft (setup.py) -pytz==2024.2 - # via pyrfc3339 -pyxdg==0.28 - # via - # craft-parts - # craft-store - # snapcraft (setup.py) -pyyaml==6.0.2 - # via - # craft-application - # craft-cli - # craft-parts - # craft-providers - # myst-parser - # pyspelling - # snap-helpers - # snapcraft (setup.py) -raven==6.10.0 - # via snapcraft (setup.py) -regex==2024.11.6 - # via sphinx-lint -requests==2.32.3 - # via - # apeye - # cachecontrol - # canonical-sphinx-extensions - # craft-application - # craft-parts - # craft-providers - # craft-store - # macaroonbakery - # pylxd - # requests-toolbelt - # requests-unixsocket2 - # snapcraft (setup.py) - # sphinx -requests-toolbelt==1.0.0 - # via - # craft-store - # pylxd - # snapcraft (setup.py) -requests-unixsocket2==0.4.2 - # via - # craft-parts - # craft-providers - # snapcraft (setup.py) -ruamel-yaml==0.18.6 - # via sphinx-toolbox -ruamel-yaml-clib==0.2.12 - # via ruamel-yaml -secretstorage==3.3.3 - # via keyring -simplejson==3.19.3 - # via snapcraft (setup.py) -six==1.16.0 - # via - # html5lib - # lazr-restfulclient - # macaroonbakery - # pymacaroons - # python-dateutil -smmap==5.0.1 - # via gitdb -snap-helpers==0.4.2 - # via - # craft-application - # snapcraft (setup.py) -sniffio==1.3.1 - # via anyio -snowballstemmer==2.2.0 - # via sphinx -soupsieve==2.6 - # via - # beautifulsoup4 - # pyspelling -sphinx==7.3.7 - # via - # autodocsumm - # canonical-sphinx - # canonical-sphinx-extensions - # furo - # myst-parser - # sphinx-autobuild - # sphinx-autodoc-typehints - # sphinx-basic-ng - # sphinx-copybutton - # sphinx-design - # sphinx-notfound-page - # sphinx-prompt - # sphinx-reredirects - # sphinx-tabs - # sphinx-toolbox - # sphinxcontrib-details-directive - # sphinxcontrib-jquery - # sphinxext-opengraph - # sphinxext-rediraffe -sphinx-autobuild==2024.10.3 - # via snapcraft (setup.py) -sphinx-autodoc-typehints==2.3.0 - # via - # snapcraft (setup.py) - # sphinx-toolbox -sphinx-basic-ng==1.0.0b2 - # via furo -sphinx-copybutton==0.5.2 - # via canonical-sphinx -sphinx-design==0.6.1 - # via canonical-sphinx -sphinx-jinja2-compat==0.3.0 - # via sphinx-toolbox -sphinx-lint==1.0.0 - # via snapcraft (setup.py) -sphinx-notfound-page==1.0.4 - # via canonical-sphinx -sphinx-prompt==1.8.0 - # via sphinx-toolbox -sphinx-reredirects==0.1.5 - # via canonical-sphinx -sphinx-tabs==3.4.5 - # via - # canonical-sphinx - # sphinx-toolbox -sphinx-toolbox==3.8.1 - # via snapcraft (setup.py) -sphinxcontrib-applehelp==2.0.0 - # via sphinx -sphinxcontrib-details-directive==0.1.0 - # via snapcraft (setup.py) -sphinxcontrib-devhelp==2.0.0 - # via sphinx -sphinxcontrib-htmlhelp==2.1.0 - # via sphinx -sphinxcontrib-jquery==4.1 - # via canonical-sphinx -sphinxcontrib-jsmath==1.0.1 - # via sphinx -sphinxcontrib-qthelp==2.0.0 - # via sphinx -sphinxcontrib-serializinghtml==2.0.0 - # via sphinx -sphinxext-opengraph==0.9.1 - # via canonical-sphinx -sphinxext-rediraffe==0.2.7 - # via snapcraft (setup.py) -starlette==0.41.2 - # via sphinx-autobuild -tabulate==0.9.0 - # via - # snapcraft (setup.py) - # sphinx-toolbox -tinydb==4.8.2 - # via snapcraft (setup.py) -toml==0.10.2 - # via snapcraft (setup.py) -typing-extensions==4.12.2 - # via - # craft-application - # craft-cli - # craft-platforms - # domdf-python-tools - # pydantic - # pydantic-core - # snapcraft (setup.py) - # sphinx-toolbox -uc-micro-py==1.0.3 - # via linkify-it-py -urllib3==2.2.3 - # via - # requests - # requests-unixsocket2 -uvicorn==0.32.0 - # via sphinx-autobuild -validators==0.34.0 - # via snapcraft (setup.py) -wadllib==2.0.0 - # via lazr-restfulclient -watchfiles==0.24.0 - # via sphinx-autobuild -wcmatch==10.0 - # via pyspelling -webencodings==0.5.1 - # via html5lib -websockets==14.1 - # via sphinx-autobuild -ws4py==0.5.1 - # via pylxd - -# The following packages are considered to be unsafe in a requirements file: -# setuptools diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 39d1766a25..0000000000 --- a/requirements.txt +++ /dev/null @@ -1,272 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile --output-file=requirements.txt -# -annotated-types==0.7.0 - # via - # craft-platforms - # pydantic -attrs==24.2.0 - # via snapcraft (setup.py) -boolean-py==4.0 - # via license-expression -catkin-pkg==1.0.0 ; sys_platform == "linux" - # via snapcraft (setup.py) -certifi==2024.8.30 - # via requests -cffi==1.17.1 - # via - # cryptography - # pygit2 - # pynacl -chardet==5.2.0 - # via python-debian -charset-normalizer==3.4.0 - # via requests -click==8.1.7 - # via snapcraft (setup.py) -craft-application==4.4.1 - # via snapcraft (setup.py) -craft-archives==2.0.1 - # via - # craft-application - # snapcraft (setup.py) -craft-cli==2.15.0 - # via - # craft-application - # snapcraft (setup.py) -craft-grammar==2.0.1 - # via - # craft-application - # snapcraft (setup.py) -craft-parts==2.4.1 - # via - # craft-application - # snapcraft (setup.py) -craft-platforms==0.4.0 - # via - # craft-application - # snapcraft (setup.py) -craft-providers==2.0.4 - # via - # craft-application - # snapcraft (setup.py) -craft-store==3.0.2 - # via snapcraft (setup.py) -cryptography==43.0.3 - # via - # pylxd - # secretstorage -distro==1.9.0 - # via - # craft-archives - # craft-platforms - # lazr-restfulclient -docutils==0.19 - # via - # catkin-pkg - # snapcraft (setup.py) -gnupg==2.3.1 - # via snapcraft (setup.py) -httplib2==0.22.0 - # via - # launchpadlib - # lazr-restfulclient -idna==3.10 - # via requests -jaraco-classes==3.4.0 - # via - # craft-store - # keyring -jaraco-context==6.0.1 - # via keyring -jaraco-functools==4.1.0 - # via keyring -jeepney==0.8.0 - # via - # keyring - # secretstorage -jinja2==3.1.5 - # via craft-application -jsonschema==2.5.1 - # via snapcraft (setup.py) -keyring==25.5.0 - # via craft-store -launchpadlib==2.0.0 - # via - # craft-archives - # snapcraft (setup.py) -lazr-restfulclient==0.14.6 - # via - # craft-archives - # launchpadlib - # snapcraft (setup.py) -lazr-uri==1.0.6 - # via - # craft-archives - # launchpadlib - # wadllib -license-expression==30.4.0 - # via craft-application -lxml==5.3.0 - # via snapcraft (setup.py) -macaroonbakery==1.3.4 - # via - # craft-store - # snapcraft (setup.py) -markupsafe==3.0.2 - # via jinja2 -more-itertools==10.5.0 - # via - # jaraco-classes - # jaraco-functools -mypy-extensions==1.0.0 - # via snapcraft (setup.py) -oauthlib==3.2.2 - # via lazr-restfulclient -overrides==7.7.0 - # via - # craft-archives - # craft-grammar - # craft-parts - # craft-store - # snapcraft (setup.py) -packaging==24.2 - # via - # craft-providers - # snapcraft (setup.py) -platformdirs==4.3.6 - # via - # craft-application - # craft-cli -progressbar==2.5 - # via snapcraft (setup.py) -protobuf==5.28.3 - # via macaroonbakery -psutil==6.1.0 - # via gnupg -pycparser==2.22 - # via cffi -pydantic==2.10.3 - # via - # craft-application - # craft-archives - # craft-grammar - # craft-parts - # craft-providers - # craft-store - # snapcraft (setup.py) -pydantic-core==2.27.1 - # via pydantic -pyelftools==0.31 - # via snapcraft (setup.py) -pygit2==1.13.3 - # via - # craft-application - # snapcraft (setup.py) -pylxd==2.3.5 ; sys_platform == "linux" - # via snapcraft (setup.py) -pymacaroons==0.13.0 - # via - # macaroonbakery - # snapcraft (setup.py) -pynacl==1.5.0 - # via - # macaroonbakery - # pymacaroons -pyparsing==3.2.0 - # via - # catkin-pkg - # httplib2 -pyrfc3339==1.1 - # via macaroonbakery - # via snapcraft (setup.py) -python-dateutil==2.9.0.post0 - # via - # catkin-pkg - # pylxd -python-debian==0.1.49 ; sys_platform == "linux" - # via - # craft-archives - # snapcraft (setup.py) -pytz==2024.2 - # via pyrfc3339 -pyxdg==0.28 - # via - # craft-parts - # craft-store - # snapcraft (setup.py) -pyyaml==6.0.2 - # via - # craft-application - # craft-cli - # craft-parts - # craft-providers - # snap-helpers - # snapcraft (setup.py) -raven==6.10.0 - # via snapcraft (setup.py) -requests==2.32.3 - # via - # craft-application - # craft-parts - # craft-providers - # craft-store - # macaroonbakery - # pylxd - # requests-toolbelt - # requests-unixsocket2 - # snapcraft (setup.py) -requests-toolbelt==1.0.0 - # via - # craft-store - # pylxd - # snapcraft (setup.py) -requests-unixsocket2==0.4.2 - # via - # craft-parts - # craft-providers - # snapcraft (setup.py) -secretstorage==3.3.3 - # via keyring -simplejson==3.19.3 - # via snapcraft (setup.py) -six==1.16.0 - # via - # lazr-restfulclient - # macaroonbakery - # pymacaroons - # python-dateutil -snap-helpers==0.4.2 - # via - # craft-application - # snapcraft (setup.py) -tabulate==0.9.0 - # via snapcraft (setup.py) -tinydb==4.8.2 - # via snapcraft (setup.py) -toml==0.10.2 - # via snapcraft (setup.py) -typing-extensions==4.12.2 - # via - # craft-application - # craft-platforms - # pydantic - # pydantic-core - # snapcraft (setup.py) -urllib3==2.2.3 - # via - # requests - # requests-unixsocket2 -validators==0.34.0 - # via snapcraft (setup.py) -wadllib==2.0.0 - # via lazr-restfulclient -ws4py==0.5.1 - # via pylxd - -# The following packages are considered to be unsafe in a requirements file: -# setuptools -python-apt @ https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz ; sys.platform == "linux" diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 382bf8cbac..f040099774 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -174,7 +174,7 @@ parts: python-constraints: - constraints.txt python-requirements: - - requirements.txt + - uv-requirements.txt organize: # Put snapcraftctl and craftctl into its own directory that can be included in the PATH # without including other binaries. @@ -195,7 +195,10 @@ parts: # Use base image's libsodium for PyNaCl. - "SODIUM_INSTALL": "system" - "CFLAGS": "$(pkg-config python-3.12 yaml-0.1 --cflags)" + build-snaps: + - astral-uv override-build: | + uv export --no-dev --no-emit-workspace --output-file uv-requirements.txt ${SNAP}/libexec/snapcraft/craftctl default version=$(PYTHONPATH=$CRAFT_PART_INSTALL/lib/python3.12/site-packages python3 -c "import snapcraft;print(snapcraft.__version__)") From 6c021521f5269a794e6f9ab019e978ee9264160b Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 10:01:23 -0500 Subject: [PATCH 310/333] chore: migrate last of setup.py --- pyproject.toml | 4 ++ setup.cfg | 42 ----------- setup.py | 186 ------------------------------------------------- uv.lock | 78 +++++++++++++++++++-- 4 files changed, 77 insertions(+), 233 deletions(-) delete mode 100644 setup.cfg delete mode 100755 setup.py diff --git a/pyproject.toml b/pyproject.toml index e3f6a2f215..741388dba9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,6 +94,7 @@ docs = [ "sphinxcontrib-details-directive", "sphinx-lint", "sphinx-toolbox", + "sphinxext-rediraffe==0.2.7", "pyspelling", ] lint = [ @@ -189,6 +190,9 @@ local_scheme = "dirty-tag" include = ["snapcraft", "extensions", "keyrings", "schema", "snapcraft_legacy"] namespaces = true +[tool.setuptools.package-data] +snapcraft = ["templates/*"] + [tool.mypy] python_version = "3.12" ignore_missing_imports = true diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index e5487c3071..0000000000 --- a/setup.cfg +++ /dev/null @@ -1,42 +0,0 @@ -[codespell] -ignore-words-list = buildd,crate,keyserver,comandos,ro,astroid,assertIn,socio-economic,wethr -skip = waf,*.tar,*.xz,*.zip,*.bz2,*.7z,*.gz,*.deb,*.rpm,*.snap,*.comp,*.gpg,*.pyc,*.png,*.ico,*.jar,*.so,changelog,.git,.hg,.mypy_cache,.tox,.venv,venv,_build,buck-out,__pycache__,build,dist,.vscode,parts,stage,prime,test_appstream.py,./snapcraft.spec,./.direnv,./.pytest_cache,.ruff_cache,*.asc -quiet-level = 4 - -[flake8] -# E501 line too long -# E203 whitespace before ':' -extend-ignore = E203, E501 -max-complexity = 10 -max-line-length = 88 -exclude = - # No need to traverse our git directory - .direnv, - .git, - .hg, - .mypy_cache, - .tox, - .venv, - .vscode, - _build, - buck-out, - # There's no value in checking cache directories - __pycache__, - # This contains builds of flake8 that we don't want to check - build, - dist, - # snapcraft generated - parts, - stage, - prime - -[pycodestyle] -max-line-length = 88 -ignore = E203,E501 - -[pydocstyle] -# D107 Missing docstring in __init__ (reason: documented in class docstring) -# D203 1 blank line required before class docstring (reason: pep257 default) -# D213 Multi-line docstring summary should start at the second line (reason: pep257 default) -ignore = D107, D203, D213 -ignore_decorators = override diff --git a/setup.py b/setup.py deleted file mode 100755 index 5813d2d467..0000000000 --- a/setup.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python3 -# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- -# -# Copyright 2015-2022,2024 Canonical Ltd. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 3 as -# published by the Free Software Foundation. -# -# 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 <http://www.gnu.org/licenses/>. - -import os -import sys - -from setuptools import find_namespace_packages, setup - -from tools.version import determine_version - - -def recursive_data_files(directory, install_directory): - data_files = [] - for root, _directories, file_names in os.walk(directory): - file_paths = [os.path.join(root, file_name) for file_name in file_names] - data_files.append((os.path.join(install_directory, root), file_paths)) - return data_files - - -# Common distribution data -name = "snapcraft" -description = "Publish your app for Linux users for desktop, cloud, and IoT." -author_email = "snapcraft@lists.snapcraft.io" -url = "https://github.com/canonical/snapcraft" -license_ = "GPL v3" -classifiers = [ - "Development Status :: 4 - Beta", - "Environment :: Console", - "Intended Audience :: Developers", - "Intended Audience :: System Administrators", - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", - "Natural Language :: English", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.12", - "Topic :: Software Development :: Build Tools", - "Topic :: System :: Software Distribution", -] - -# snapcraftctl is not in console_scripts because we need a clean environment. -# Only include it for Linux. -if sys.platform == "linux": - scripts = ["bin/snapcraftctl", "bin/snapcraftctl-compat"] -else: - scripts = [] - -dev_requires = [ - "black", - "codespell[toml]", - "coverage[toml]", - "pyflakes", - "fixtures", - # For Tiobe TiCS - "flake8", - "mccabe", - "mypy", - "testscenarios", - "pexpect", - "pip", - "pycodestyle", - "pydocstyle", - "pyftpdlib", - "pyinstaller; sys_platform == 'win32'", - # For Tiobe TiCS - "pylint", - "pyramid", - "pytest", - "pytest-cov", - "pytest-check", - "pytest-mock", - "pytest-subprocess", - "tox>=4.5", - "types-PyYAML", - # types-requests>=2.31.0.7 requires urllib3>=2 - "types-requests==2.31.0.6", - "types-setuptools", - "types-simplejson", - "types-tabulate", - "types-toml", - "yamllint", -] - -install_requires = [ - "attrs", - "catkin-pkg; sys_platform == 'linux'", - "click", - "craft-application>=4.4.1,<5.0.0", - "craft-archives~=2.0", - "craft-cli>=2.15.0", - "craft-grammar>=2.0.1,<3.0.0", - "craft-parts==2.4.1", - "craft-platforms~=0.4", - "craft-providers>=2.0.4,<3.0.0", - "craft-store>=3.0.2,<4.0.0", - "docutils<0.20", # Frozen until we can update sphinx dependencies. - "gnupg", - "jsonschema==2.5.1", - "launchpadlib", - "lazr.restfulclient", - "lxml", - "macaroonbakery", - "mypy-extensions", - "overrides", - "packaging", - "progressbar", - "pydantic~=2.8", - "pyelftools", - # Pygit2 and libgit2 need to match versions. - # Further info: https://www.pygit2.org/install.html#version-numbers - "pygit2~=1.13.0", - "pylxd; sys_platform == 'linux'", - "pymacaroons", - "python-apt @ https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz ; sys_platform == 'linux'", - "python-debian; sys_platform == 'linux'", - "pyxdg", - "pyyaml", - "raven", - "requests-toolbelt", - "requests-unixsocket2", - "requests", - "simplejson", - "snap-helpers", - "tabulate", - "toml", - "tinydb", - "typing-extensions", - "validators>=0.28.3", -] - -docs_requires = { - "canonical-sphinx[full]>=0.2.0", - "sphinx-autobuild", - "sphinx-autodoc-typehints", - "sphinxcontrib-details-directive", - "sphinx-lint", - "sphinx-toolbox", - "pyspelling", - "sphinxext-rediraffe==0.2.7", -} - -extras_requires = {"dev": dev_requires, "docs": docs_requires} - -setup( - name=name, - version=determine_version(), - description=description, - author_email=author_email, - url=url, - packages=find_namespace_packages(), - license=license_, - classifiers=classifiers, - scripts=scripts, - entry_points=dict( - console_scripts=[ - "snapcraft_legacy = snapcraft_legacy.cli.__main__:run", - "snapcraft = snapcraft.application:main", - ] - ), - data_files=( - recursive_data_files("schema", "share/snapcraft") - + recursive_data_files("keyrings", "share/snapcraft") - + recursive_data_files("extensions", "share/snapcraft") - ), - include_package_data=True, - package_data={ - "snapcraft": ["templates/*"], - }, - python_requires=">=3.10", - install_requires=install_requires, - extras_require=extras_requires, - test_suite="tests.unit", -) diff --git a/uv.lock b/uv.lock index fc32866060..99ea47f32b 100644 --- a/uv.lock +++ b/uv.lock @@ -1756,9 +1756,62 @@ wheels = [ [[package]] name = "python-apt" -version = "0.0.0" -source = { url = "https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz" } -sdist = { hash = "sha256:a895e4d38d04e86f89251d264760837887ddb420fe195e0b576d8a382fb5999e" } +version = "2.4.0+ubuntu4" +source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" } +resolution-markers = [ + "python_full_version >= '3.13'", + "python_full_version < '3.13'", +] +wheels = [ + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.4.0+ubuntu4-cp312-cp312-manylinux_2_35_aarch64.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.4.0+ubuntu4-cp312-cp312-manylinux_2_35_ppc64le.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.4.0+ubuntu4-cp312-cp312-manylinux_2_35_s390x.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.4.0+ubuntu4-cp312-cp312-manylinux_2_35_x86_64.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.4.0+ubuntu4-cp313-cp313-manylinux_2_35_aarch64.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.4.0+ubuntu4-cp313-cp313-manylinux_2_35_ppc64le.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.4.0+ubuntu4-cp313-cp313-manylinux_2_35_s390x.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.4.0+ubuntu4-cp313-cp313-manylinux_2_35_x86_64.whl" }, +] + +[[package]] +name = "python-apt" +version = "2.7.7+ubuntu3" +source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" } +resolution-markers = [ + "python_full_version >= '3.13'", + "python_full_version < '3.13'", +] +wheels = [ + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.7.7+ubuntu3-cp312-cp312-manylinux_2_39_aarch64.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.7.7+ubuntu3-cp312-cp312-manylinux_2_39_ppc64le.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.7.7+ubuntu3-cp312-cp312-manylinux_2_39_riscv64.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.7.7+ubuntu3-cp312-cp312-manylinux_2_39_s390x.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.7.7+ubuntu3-cp312-cp312-manylinux_2_39_x86_64.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.7.7+ubuntu3-cp313-cp313-manylinux_2_39_aarch64.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.7.7+ubuntu3-cp313-cp313-manylinux_2_39_ppc64le.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.7.7+ubuntu3-cp313-cp313-manylinux_2_39_s390x.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.7.7+ubuntu3-cp313-cp313-manylinux_2_39_x86_64.whl" }, +] + +[[package]] +name = "python-apt" +version = "2.9.0+ubuntu1" +source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" } +resolution-markers = [ + "python_full_version >= '3.13'", + "python_full_version < '3.13'", +] +wheels = [ + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.9.0+ubuntu1-cp312-cp312-manylinux_2_40_aarch64.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.9.0+ubuntu1-cp312-cp312-manylinux_2_40_ppc64le.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.9.0+ubuntu1-cp312-cp312-manylinux_2_40_riscv64.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.9.0+ubuntu1-cp312-cp312-manylinux_2_40_s390x.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.9.0+ubuntu1-cp312-cp312-manylinux_2_40_x86_64.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.9.0+ubuntu1-cp313-cp313-manylinux_2_40_aarch64.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.9.0+ubuntu1-cp313-cp313-manylinux_2_40_ppc64le.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.9.0+ubuntu1-cp313-cp313-manylinux_2_40_s390x.whl" }, + { url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/python-apt/python_apt-2.9.0+ubuntu1-cp313-cp313-manylinux_2_40_x86_64.whl" }, +] [[package]] name = "python-dateutil" @@ -2151,6 +2204,7 @@ docs = [ { name = "sphinx-lint" }, { name = "sphinx-toolbox" }, { name = "sphinxcontrib-details-directive" }, + { name = "sphinxext-rediraffe" }, ] lint = [ { name = "codespell" }, @@ -2168,12 +2222,12 @@ types = [ [package.metadata] requires-dist = [ - { name = "attrs", specifier = "==24.2.0" }, + { name = "attrs" }, { name = "catkin-pkg", marker = "sys_platform == 'linux'", specifier = "==1.0.0" }, { name = "click", specifier = "==8.1.7" }, { name = "craft-application", specifier = "~=4.4" }, { name = "craft-archives", specifier = "~=2.0" }, - { name = "craft-cli", specifier = "~=2.9" }, + { name = "craft-cli", specifier = "~=2.15.0" }, { name = "craft-grammar", specifier = ">=2.0.1,<3.0.0" }, { name = "craft-parts", specifier = "==2.3.0" }, { name = "craft-platforms", specifier = "~=0.4" }, @@ -2191,6 +2245,7 @@ requires-dist = [ { name = "packaging" }, { name = "progressbar" }, { name = "pydantic", specifier = "~=2.8" }, + { name = "pydantic", specifier = "~=2.8" }, { name = "pyelftools" }, { name = "pygit2", specifier = "~=1.13.0" }, { name = "pylxd", marker = "sys_platform == 'linux'" }, @@ -2245,6 +2300,7 @@ docs = [ { name = "sphinx-lint" }, { name = "sphinx-toolbox" }, { name = "sphinxcontrib-details-directive" }, + { name = "sphinxext-rediraffe", specifier = "==0.2.7" }, ] lint = [ { name = "codespell", extras = ["toml"] }, @@ -2576,6 +2632,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/92/0a/970b80b4fa1feeb6deb6f2e22d4cb14e388b27b315a1afdb9db930ff91a4/sphinxext_opengraph-0.9.1-py3-none-any.whl", hash = "sha256:b3b230cc6a5b5189139df937f0d9c7b23c7c204493b22646273687969dcb760e", size = 1005241 }, ] +[[package]] +name = "sphinxext-rediraffe" +version = "0.2.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/b4/e5fbb493f796430230189a1ce5f9beff1ac1b98619fc71ed35deca6059a5/sphinxext-rediraffe-0.2.7.tar.gz", hash = "sha256:651dcbfae5ffda9ffd534dfb8025f36120e5efb6ea1a33f5420023862b9f725d", size = 8735 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/4f/c8797e796199e55cf6c8979ecdf5f4b09b81e93f87b3193c759faea63263/sphinxext_rediraffe-0.2.7-py3-none-any.whl", hash = "sha256:9e430a52d4403847f4ffb3a8dd6dfc34a9fe43525305131f52ed899743a5fd8c", size = 8267 }, +] + [[package]] name = "standard-imghdr" version = "3.10.14" From 237e84d6a27393cf3625ef7868bc1c0fd837a250 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 16:30:51 -0500 Subject: [PATCH 311/333] chore: remove unused tools --- tools/environment-setup-local.sh | 54 ------ tools/environment-setup.sh | 45 ----- tools/freeze-requirements.sh | 48 ------ tools/spread-shellcheck.py | 286 ------------------------------- tools/version.py | 79 --------- 5 files changed, 512 deletions(-) delete mode 100755 tools/environment-setup-local.sh delete mode 100755 tools/environment-setup.sh delete mode 100755 tools/freeze-requirements.sh delete mode 100755 tools/spread-shellcheck.py delete mode 100755 tools/version.py diff --git a/tools/environment-setup-local.sh b/tools/environment-setup-local.sh deleted file mode 100755 index 8d717293a2..0000000000 --- a/tools/environment-setup-local.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -ex - -SNAPCRAFT_DIR=${SNAPCRAFT_DIR:=$( cd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null 2>&1 && pwd )} -SNAPCRAFT_VIRTUAL_ENV_DIR=${SNAPCRAFT_VIRTUAL_ENV_DIR:=${HOME}/.venv/snapcraft} - -sudo apt update -sudo apt install --yes \ - execstack \ - g++ \ - gcc \ - intltool \ - libapt-pkg-dev \ - libffi-dev \ - libsodium-dev \ - libssl-dev \ - libxml2-dev \ - libxslt1-dev \ - libyaml-dev \ - make \ - patchelf \ - python3-dev \ - python3-pip \ - python3-venv \ - rpm2cpio \ - squashfs-tools \ - xdelta3 - -# Create a virtual environment -python3 -m venv "${SNAPCRAFT_VIRTUAL_ENV_DIR}" - -# Activate virtual environment -# shellcheck source=/dev/null -source "${SNAPCRAFT_VIRTUAL_ENV_DIR}/bin/activate" - -# Install python dependencies -export CRYPTOGRAPHY_DONT_BUILD_RUST=1 -pip install --upgrade wheel pip setuptools -pip install -r "${SNAPCRAFT_DIR}/requirements-devel.txt" -pip install -r "${SNAPCRAFT_DIR}/requirements.txt" - -# Install the project for quick tests -pip install --editable "${SNAPCRAFT_DIR}" - -# Install shellcheck for static tests. -sudo snap install shellcheck - -# Install pyright for static tests. -sudo snap install pyright --classic - -# Install ruff for linting -sudo snap install ruff - -echo "Virtual environment may be activated by running:" -echo "source ${SNAPCRAFT_VIRTUAL_ENV_DIR}/bin/activate" diff --git a/tools/environment-setup.sh b/tools/environment-setup.sh deleted file mode 100755 index dfe52a4477..0000000000 --- a/tools/environment-setup.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash -e - -SNAPCRAFT_DIR=${SNAPCRAFT_DIR:=$( cd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null 2>&1 && pwd )} - -# Check if SNAPCRAFT_DIR is pointing to snapcraft sources. -if ! grep -q '^name: snapcraft$' "${SNAPCRAFT_DIR}/snap/snapcraft.yaml"; then - echo "This is not the snapcraft.yaml for the snapcraft project" - exit 1 -fi - -# Create the container. -if ! lxc info snapcraft-dev >/dev/null 2>&1; then - lxc init ubuntu:22.04 snapcraft-dev -fi -if ! lxc config get snapcraft-dev raw.idmap | grep -q "both $UID 1000"; then - lxc config set snapcraft-dev raw.idmap "both $UID 1000" -fi - -if ! lxc info snapcraft-dev | grep -q "Status: Running"; then - lxc start snapcraft-dev -fi - -# Wait for cloud-init before moving on. -lxc exec snapcraft-dev -- cloud-init status --wait - -# First login for ubuntu user. -lxc exec snapcraft-dev -- sudo -iu ubuntu bash -c true - -# Now that /home/ubuntu has been used, add the project. -if ! lxc config device show snapcraft-dev | grep -q snapcraft-project; then - lxc config device add snapcraft-dev snapcraft-project disk \ - source="$SNAPCRAFT_DIR" path=/home/ubuntu/snapcraft -fi - -# Install snapcraft and dependencies. -lxc exec snapcraft-dev -- sudo -iu ubuntu /home/ubuntu/snapcraft/tools/environment-setup-local.sh - -# Set virtual environment on login. -lxc exec snapcraft-dev -- sudo -iu ubuntu bash -c \ - "echo 'source /home/ubuntu/.venv/snapcraft/bin/activate' >> .profile" -lxc exec snapcraft-dev -- sudo -iu ubuntu bash -c \ - "echo 'source /home/ubuntu/.venv/snapcraft/bin/activate' >> .bashrc" - -echo "Container ready, enter it by running: " -echo "lxc exec snapcraft-dev -- sudo -iu ubuntu bash" diff --git a/tools/freeze-requirements.sh b/tools/freeze-requirements.sh deleted file mode 100755 index 41b7c45158..0000000000 --- a/tools/freeze-requirements.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash -eux - -requirements_fixups() { - req_file="$1" - - # Python apt library pinned to source. - sed -i '/python-apt=*/d' "$req_file" - echo 'python-apt @ https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz ; sys.platform == "linux"' >> "$req_file" - - # https://bugs.launchpad.net/ubuntu/+source/python-pip/+bug/1635463 - sed -i '/pkg[-_]resources==0.0.0/d' "$req_file" - - # Pinned pyinstaller for windows. - if [[ "$req_file" == "requirements-devel.txt" ]]; then - sed -i '/pyinstaller/d' "$req_file" - echo 'pyinstaller==5.13.1; sys.platform == "win32"' >> "$req_file" - fi -} - -venv_dir="$(mktemp -d)" - -# Enable system-site-packages to find python3-apt. -python3 -m venv "$venv_dir" - -# shellcheck disable=SC1090,SC1091 -source "$venv_dir/bin/activate" - -pip install -U setuptools pip wheel pip-tools - -# Pull in host python3-apt site package to avoid installation. -site_pkgs="$(readlink -f "$venv_dir"/lib/python3.*/site-packages/)" -temp_dir="$(mktemp -d)" -pushd "$temp_dir" -apt download python3-apt -dpkg -x ./*.deb . -cp -r usr/lib/python3/dist-packages/* "$site_pkgs" -popd - -pip-compile --upgrade --output-file requirements.txt -requirements_fixups "requirements.txt" - -pip-compile --upgrade --extra docs --output-file requirements-docs.txt -requirements_fixups "requirements-docs.txt" - -pip-compile --upgrade --extra dev --output-file requirements-devel.txt -requirements_fixups "requirements-devel.txt" - -rm -rf "$venv_dir" diff --git a/tools/spread-shellcheck.py b/tools/spread-shellcheck.py deleted file mode 100755 index 4baeb94453..0000000000 --- a/tools/spread-shellcheck.py +++ /dev/null @@ -1,286 +0,0 @@ -#!/usr/bin/python3 - -# Copyright (C) 2018 Canonical Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 3 as -# published by the Free Software Foundation. -# -# 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 <http://www.gnu.org/licenses/>. - -import argparse -import logging -import os -import subprocess -from concurrent.futures import ThreadPoolExecutor -from multiprocessing import cpu_count - -import yaml - -# path for shellcheck binary -SHELLCHECK = os.getenv("SHELLCHECK", "shellcheck") -# set to non-empty to ignore all errors -NO_FAIL = os.getenv("NO_FAIL") -# set to non empty to enable 'set -x' -D = os.getenv("D") -# set to non-empty to enable verbose logging -V = os.getenv("V") -# set to a number to use these many threads -N = int(os.getenv("N") or cpu_count()) -# file with list of files that can fail validation -CAN_FAIL = os.getenv("CAN_FAIL") - -# names of sections -SECTIONS = frozenset( - [ - "prepare", - "prepare-each", - "restore", - "restore-each", - "debug", - "debug-each", - "execute", - "repack", - ] -) - - -def parse_arguments(): - parser = argparse.ArgumentParser(description="spread shellcheck helper") - parser.add_argument("-s", "--shell", default="bash", help="shell") - parser.add_argument( - "-n", - "--no-errors", - action="store_true", - default=False, - help="ignore all errors ", - ) - parser.add_argument( - "-v", "--verbose", action="store_true", default=False, help="verbose logging" - ) - parser.add_argument( - "--can-fail", - default=None, - help=("file with list of files that are can fail " "validation"), - ) - parser.add_argument( - "-P", - "--max-procs", - default=N, - type=int, - metavar="N", - help="run these many shellchecks in parallel (default: %(default)s)", - ) - parser.add_argument("paths", nargs="+", help="paths to check") - return parser.parse_args() - - -class ShellcheckRunError(Exception): - def __init__(self, stderr): - super().__init__() - self.stderr = stderr - - -class ShellcheckError(Exception): - def __init__(self, path): - super().__init__() - self.sectionerrors = {} - self.path = path - - def addfailure(self, section, error): - self.sectionerrors[section] = error - - def __len__(self): - return len(self.sectionerrors) - - -class ShellcheckFailures(Exception): - def __init__(self, failures=None): - super().__init__() - self.failures = set() - if failures: - self.failures = set(failures) - - def merge(self, otherfailures): - self.failures = self.failures.union(otherfailures.failures) - - def __len__(self): - return len(self.failures) - - def intersection(self, other): - return self.failures.intersection(other) - - def difference(self, other): - return self.failures.difference(other) - - def __iter__(self): - return iter(self.failures) - - -def checksection(data): - # spread shell snippets are executed under 'set -e' shell, make sure - # shellcheck knows about that - data = "set -eu\n" + data - proc = subprocess.Popen( - [SHELLCHECK, "-s", "bash", "-x", "-"], - stdout=subprocess.PIPE, - stdin=subprocess.PIPE, - ) - stdout, _ = proc.communicate(input=data.encode("utf-8"), timeout=10) - if proc.returncode != 0: - raise ShellcheckRunError(stdout) - - -def checkfile(path): - logging.debug("checking file %s", path) - with open(path) as inf: - data = yaml.safe_load(inf) - - errors = ShellcheckError(path) - - for section in SECTIONS & data.keys(): - try: - logging.debug("%s: checking section %s", path, section) - checksection(data[section]) - except ShellcheckRunError as serr: - errors.addfailure(section, serr.stderr.decode("utf-8")) - - if path.endswith("spread.yaml") and "suites" in data: - # check suites - for suite_name, suite in data["suites"].items(): - for section in SECTIONS & suite.keys(): - try: - logging.debug( - "%s (suite %s): checking section %s", path, suite_name, section - ) - checksection(suite[section]) - except ShellcheckRunError as serr: - errors.addfailure( - "suites/" + suite_name + "/" + section, - serr.stderr.decode("utf-8"), - ) - - if errors: - raise errors - - -def findfiles(indir): - for root, _, files in os.walk(indir, topdown=True): - for name in files: - if name in ["spread.yaml", "task.yaml"]: - yield os.path.join(root, name) - - -def checkpath(loc, max_workers): - if os.path.isdir(loc): - # setup iterator - locations = findfiles(loc) - else: - locations = [loc] - - failed = [] - - def check1path(path): - try: - checkfile(path) - except ShellcheckError as err: - return err - return None - - with ThreadPoolExecutor(max_workers=max_workers) as executor: - for serr in executor.map(check1path, locations): - if serr is None: - continue - logging.error( - ("shellcheck failed for file %s in sections: " "%s; error log follows"), - serr.path, - ", ".join(serr.sectionerrors.keys()), - ) - for section, error in serr.sectionerrors.items(): - logging.error("%s: section '%s':\n%s", serr.path, section, error) - failed.append(serr.path) - - if failed: - raise ShellcheckFailures(failures=failed) - - -def loadfilelist(flistpath): - flist = set() - with open(flistpath) as inf: - for line in inf: - if not line.startswith("#"): - flist.add(line.strip()) - return flist - - -def main(opts): - paths = opts.paths or ["."] - failures = ShellcheckFailures() - for pth in paths: - try: - checkpath(pth, opts.max_procs) - except ShellcheckFailures as sf: - failures.merge(sf) - - if failures: - if opts.can_fail: - can_fail = loadfilelist(opts.can_fail) - - unexpected = failures.difference(can_fail) - if unexpected: - logging.error( - ( - "validation failed for the following " - "non-whitelisted files:\n%s" - ), - "\n".join([" - " + f for f in sorted(unexpected)]), - ) - raise SystemExit(1) - - did_not_fail = can_fail - failures.intersection(can_fail) - if did_not_fail: - logging.error( - ( - "the following files are whitelisted " - "but validated successfully:\n%s" - ), - "\n".join([" - " + f for f in sorted(did_not_fail)]), - ) - raise SystemExit(1) - - # no unexpected failures - return - - logging.error( - "validation failed for the following files:\n%s", - "\n".join([" - " + f for f in sorted(failures)]), - ) - - if NO_FAIL or opts.no_errors: - logging.warning("ignoring errors") - else: - raise SystemExit(1) - - -if __name__ == "__main__": - opts = parse_arguments() - if opts.verbose or D or V: - subprocess.call([SHELLCHECK, "--version"]) - lvl = logging.DEBUG - else: - lvl = logging.INFO - logging.basicConfig(level=lvl) - - if CAN_FAIL: - opts.can_fail = CAN_FAIL - - if NO_FAIL: - opts.no_errors = True - - main(opts) diff --git a/tools/version.py b/tools/version.py deleted file mode 100755 index 672d508a92..0000000000 --- a/tools/version.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python3 -# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- -# -# Copyright (C) 2021 Canonical Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 3 as -# published by the Free Software Foundation. -# -# 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 <http://www.gnu.org/licenses/>. - -import fileinput -import os -import pathlib -import subprocess -import sys - - -def determine_version(): - # Examples (git describe -> python package version): - # 4.1.1-0-gad012482d -> 4.1.1 - # 4.1.1-16-g2d8943dbc -> 4.1.1.post16+g2d8943dbc - # - # For shallow clones or repositories missing tags: - # 0ae7c04 - - desc = ( - subprocess.run( - ["git", "describe", "--always", "--long"], - stdout=subprocess.PIPE, - check=False, - text=True, - ) - .stdout - .strip() - ) - - if not desc: - return os.environ.get("SNAP_VERSION", "0.0.0+devel") - - split_desc = desc.split("-") - assert ( - len(split_desc) == 3 - ), f"Failed to parse Snapcraft git version description {desc!r}. Confirm that git repository is present and has the required tags/history." - - version = split_desc[0] - distance = split_desc[1] - commit = split_desc[2] - - if distance == "0": - return version - - return f"{version}.post{distance}+git{commit[1:]}" - - -def set_snapcraft_iss(): - snapcraft_iss_path = pathlib.Path("windows/snapcraft.iss") - assert ( - snapcraft_iss_path.exists() - ), f"Run from project root and ensure {snapcraft_iss_path!s} exists." - with fileinput.input(str(snapcraft_iss_path), inplace=True) as iss_file: - for line in iss_file: - if line.startswith("AppVersion="): - print(f"AppVersion={determine_version()}") - else: - print(line, end="") - - -if __name__ == "__main__": - if len(sys.argv) == 2 and sys.argv[1] == "set-snapcraft-iss": - set_snapcraft_iss() - else: - print(determine_version()) From 18a7596c9451fc7fe6aaf1fadf3aab8734f18ebd Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 10:13:45 -0500 Subject: [PATCH 312/333] build: delete tox.ini --- tox.ini | 178 -------------------------------------------------------- 1 file changed, 178 deletions(-) delete mode 100644 tox.ini diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 7d34e32222..0000000000 --- a/tox.ini +++ /dev/null @@ -1,178 +0,0 @@ -# Differences from the starbase tox.ini: -# * Uses requirements-devel.txt -# * No library code for pyright type checking -# * Documentation envs removed -# * Pytest uses wheel package -# * Legacy tests instead of integration tests -# * Additional test environment "noreq" runs all the tests without requirements.txt -# * lint-shellcheck includes spread-shellcheck.py -# * Additional ruff configuration for snapcraft_legacy -# * Do not use tmpfs for a temporary directory as it does not support user xattrs -# * Legacy tests (inherited from integration tests) include coverage - -[tox] -env_list = # Environments to run when called with no parameters. - lint-{black,ruff,mypy,pyright,shellcheck,codespell,yaml} - test-py312 - test-legacy-py312 -minversion = 4.5 -# Tox will use these requirements to bootstrap a venv if necessary. -# tox-igore-env-name-mismatch allows us to have one virtualenv for all linting. -# By setting requirements here, we make this INI file compatible with older -# versions of tox. Tox >= 3.8 will automatically provision the version provided -# inside of a virtual environment, so users of Ubuntu >= focal can simply -# install tox from apt. Older than that, the user gets an upgrade warning. -requires = - # renovate: datasource=pypi - tox-ignore-env-name-mismatch==0.2.0.post2 - # renovate: datasource=pypi - tox-gh==1.3.2 -# Allow tox to access the user's $TMPDIR environment variable if set. -# This workaround is required to avoid circular dependencies for TMPDIR, -# since tox will otherwise attempt to use the environment's TMPDIR variable. -user_tmp_dir = {env:TMPDIR} - -[testenv] # Default config for all environments. Overridable in each env. -# We have many tests that create temporary files. Unless the user has set a -# TMPDIR, this will prefer putting those temp files in $XDG_RUNTIME_DIR, -# which will speed up those tests since they'll run on a ramdisk. -env_tmp_dir = {user_tmp_dir:{work_dir}}/tox_tmp/{env_name} -set_env = - SNAPCRAFT_IGNORE_YAML_BINDINGS = 1 - TMPDIR={env_tmp_dir} - COVERAGE_FILE={env_tmp_dir}/.coverage_{env_name} - -[test] # Base configuration for unit and integration tests -deps = -r{tox_root}/requirements-devel.txt -package = wheel -allowlist_externals = mkdir -commands_pre = mkdir -p results - -[testenv:test-{py312}] # Configuration for all tests using pytest -base = testenv, test -description = Run unit tests with pytest -labels = - py312: tests, unit-tests -commands = pytest {tty:--color=yes} --cov=snapcraft --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml {posargs:tests/unit} - -[testenv:test-legacy-{py312}] -base = testenv, test -description = Run legacy tests with pytest -labels = - py312: tests, integration-tests -commands = pytest {tty:--color=yes} --cov=snapcraft_legacy --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml {posargs:tests/legacy} - -[testenv:test-noreq] -base = testenv -description = Run all tests without using requirements.txt -package = wheel -deps = python-apt@https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz -extras = dev -allowlist_externals = mkdir -commands_pre = mkdir -p results -commands = - pytest {tty:--color=yes} --cov=snapcraft --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml tests/unit {posargs} - pytest {tty:--color=yes} --junit-xml=results/legacy-test-results-{env_name}.xml tests/legacy {posargs} - -[testenv:test-all-py312] -base = testenv, test -description = Run all tests with the interpreter used in the snap -allowlist_externals = mkdir -commands_pre = mkdir -p results -commands = - pytest {tty:--color=yes} --cov=snapcraft --cov-report=xml:results/coverage-{env_name}.xml --junit-xml=results/test-results-{env_name}.xml tests {posargs} - -[lint] # Standard linting configuration -package = editable -extras = dev -env_dir = {work_dir}/linting -runner = ignore_env_name_mismatch - -[shellcheck] -find = git ls-files --empty-directory --deduplicate -filter = file --mime-type -Nnf- | grep shellscript$ | cut -f1 -d: -spread_filter = grep -E "^tests/spread/.*(spread|task)\.yaml$" - -[testenv:lint-{black,ruff,docstyle,shellcheck,codespell,yaml}] -description = Lint the source code -base = testenv, lint -labels = lint -deps = - -r{tox_root}/requirements-devel.txt -allowlist_externals = - shellcheck: bash, xargs - ruff: ruff -commands_pre = - shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]filter} > {env_tmp_dir}/shellcheck_files' - shellcheck: bash -c '{[shellcheck]find} | {[shellcheck]spread_filter} > {env_tmp_dir}/spread_shellcheck_files' -commands = - black: black --check --diff {tty:--color} {posargs} . - ruff: ruff check --diff --respect-gitignore {posargs} - docstyle: pydocstyle snapcraft - shellcheck: xargs -ra {env_tmp_dir}/shellcheck_files shellcheck - shellcheck: xargs -ra {env_tmp_dir}/spread_shellcheck_files python3 tools/spread-shellcheck.py spread.yaml - codespell: codespell --toml {tox_root}/pyproject.toml {posargs} - yaml: yamllint {posargs} . - -[testenv:lint-{mypy,pyright}] -description = Static type checking -base = testenv -deps = - -r{tox_root}/requirements-devel.txt -env_dir = {work_dir}/typing -runner = ignore_env_name_mismatch -package = editable -extras = [dev, types] -labels = lint, type -allowlist_externals = - pyright: pyright - mypy: mkdir -commands_pre = - mypy: mkdir -p .mypy_cache -commands = - pyright: pyright {posargs} - mypy: mypy --install-types --non-interactive --exclude 'docs/sphinx-resources/conf.py' --exclude 'docs/common' . - -[testenv:format-{black,ruff,codespell}] -description = Automatically format source code -base = testenv, lint -labels = format -deps = - -r{tox_root}/requirements-devel.txt -allowlist_externals: - ruff: ruff -commands = - black: black {tty:--color} {posargs} . - ruff: ruff check --fix --respect-gitignore setup.py snapcraft tests tools - ruff: ruff check --fix --config snapcraft_legacy/ruff.toml snapcraft_legacy tests/legacy - codespell: codespell --toml {tox_root}/pyproject.toml --write-changes {posargs} - -[docs] # Sphinx documentation configuration -extras = docs -package = editable -no_package = true -env_dir = {work_dir}/docs -runner = ignore_env_name_mismatch -deps = - -r{tox_root}/requirements-docs.txt - -[testenv:build-docs] -description = Build sphinx documentation -base = docs -allowlist_externals = bash -commands_pre = - bash -c 'if [[ ! -e docs ]];then echo "No docs directory. Run `tox run -e sphinx-quickstart` to create one.;";return 1;fi' - bash -c 'git submodule update --init docs/sphinx-resources' -# "-W" is to treat warnings as errors -commands = sphinx-build {posargs:-b html} -W {tox_root}/docs {tox_root}/docs/_build - -[testenv:autobuild-docs] -description = Build documentation with an autoupdating server -base = docs -commands = sphinx-autobuild {posargs:-b html --open-browser --port 8080} {tox_root}/docs {tox_root}/docs/_build - -[testenv:lint-docs] -description = Lint the documentation with sphinx-lint -base = docs -commands = sphinx-lint --ignore docs/_build --max-line-length 120 --ignore docs/sphinx-resources -e all {posargs} docs/ -labels = lint From f2be4e2329cbc53a93bd181050ccf8e56a0e53c8 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 10:38:04 -0500 Subject: [PATCH 313/333] chore: organize gitignore This commit doesn't remove any entries, it only organizes them into nice categories --- .gitignore | 147 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 109 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index ca39ce615c..eccc827adf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,45 +1,116 @@ -build -Cargo.lock -.coverage** -coverage-* -demos/*/parts/ -demos/*/prime/ -demos/**/*.snap -demos/*/snap/.snapcraft/ -demos/*/stage/ -.direnv -dist -docs/**.html -docs/reference.md -docs/reference/commands -docs/.sphinx -docs/_build -docs/common -*.egg-info +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +develop-eggs/ +dist/ +downloads/ +eggs/ .eggs/ -.envrc -htmlcov -.idea -.mypy_cache -/parts +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ pip-wheel-metadata/ -/prime -*.pyc -__pycache__ -.pytest_cache -*.comp +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg *.snap -snap/.snapcraft/ +MANIFEST + +# Build outputs +*.comp /snapcraft/_version.py +snap/.snapcraft/ +*.snap + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Docs +docs/_build +# Auto-generated command reference +docs/common/craft-parts +docs/reference/commands + +# Unit test / coverage reports +htmlcov/ +.cache +.coverage +.coverage.* +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +.results.*.xml .spread_multipass .spread-reuse.* -/stage -*.swp -target -tests/unit/snap/ -tests/unit/stage/ -test-results* -.tox +results/ + +# Translations +*.mo +*.pot + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Environments +.env +.envrc +.direnv +.venv/ +.venv.bak/ +venv/ +venv.bak/ +env/ +ENV/ +env.bak/ + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Lifecycle +build/ +parts/ +prime/ +stage/ + +# Python virtual environment +venv/ +.venv/ + +# backups +*~ +.*.*swp + +# Editor configs +.idea .vscode -venv -.venv +.spyderproject +.spyproject From 945ab1505b603f298ff491392bf570d959229edb Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 12:42:08 -0500 Subject: [PATCH 314/333] style: bring in starbase formatter rules --- .github/ISSUE_TEMPLATE/bug.yaml | 1 - .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/release-drafter.yml | 4 +- .github/spread-problem-matcher.json | 20 +- .github/workflows/check-renovate.yaml | 2 +- .github/workflows/publish.yaml | 2 +- .github/workflows/security-scan.yaml | 4 +- .github/workflows/tics.yaml | 6 +- .prettierignore | 6 + .readthedocs.yaml | 4 +- .yamllint.yaml | 2 +- CODE_OF_CONDUCT.md | 26 +- CODE_STYLE.md | 26 +- CONTRIBUTING.md | 71 +- HACKING.md | 10 +- README.md | 4 +- TESTING.md | 92 +- appveyor.yml | 80 +- docker/README.md | 6 +- docs/_static/css/custom.css | 22 +- docs/howto/code/basic/task.yaml | 3 +- docs/howto/code/components-organize/task.yaml | 3 +- docs/howto/code/components/task.yaml | 3 +- .../craft-a-snap/example-python-recipe.yaml | 2 +- docs/reference/code/yt-dlp-recipe.yaml | 6 +- manual-tests.md | 98 +- pyproject.toml | 49 +- schema/snapcraft.json | 2316 ++++++++--------- snap/snapcraft.yaml | 116 +- snapcraft/commands/status.py | 1 + snapcraft/commands/validation_sets.py | 12 +- snapcraft/extensions/_ros2_humble_meta.py | 6 +- snapcraft/extensions/_ros2_jazzy_meta.py | 6 +- snapcraft/extensions/gnome.py | 1 + snapcraft/extensions/kde_neon.py | 1 + snapcraft/linters/library_linter.py | 1 + snapcraft/meta/snap_yaml.py | 3 +- snapcraft/plugins/v2/__init__.py | 1 - snapcraft/providers.py | 1 + snapcraft/snap_config.py | 1 + snapcraft/store/__init__.py | 1 - snapcraft/store/client.py | 7 +- snapcraft/utils.py | 1 + snapcraft_legacy/_store.py | 10 +- snapcraft_legacy/cli/_channel_map.py | 8 +- snapcraft_legacy/cli/_errors.py | 7 +- snapcraft_legacy/cli/_review.py | 2 +- snapcraft_legacy/cli/_runner.py | 3 +- snapcraft_legacy/cli/echo.py | 3 +- snapcraft_legacy/cli/lifecycle.py | 4 +- snapcraft_legacy/cli/store.py | 4 +- snapcraft_legacy/extractors/_errors.py | 4 - snapcraft_legacy/extractors/_metadata.py | 2 +- snapcraft_legacy/file_utils.py | 5 +- .../build_providers/_base_provider.py | 1 - .../build_providers/_multipass/_windows.py | 4 +- .../internal/build_providers/_snap.py | 14 +- .../internal/build_providers/errors.py | 9 - snapcraft_legacy/internal/common.py | 5 +- snapcraft_legacy/internal/deltas/_deltas.py | 2 +- snapcraft_legacy/internal/elf.py | 1 - snapcraft_legacy/internal/errors.py | 33 +- snapcraft_legacy/internal/lifecycle/_clean.py | 3 +- snapcraft_legacy/internal/meta/application.py | 2 +- snapcraft_legacy/internal/meta/errors.py | 13 +- .../internal/meta/package_repository.py | 3 +- snapcraft_legacy/internal/meta/plugs.py | 2 +- snapcraft_legacy/internal/mountinfo.py | 4 +- .../internal/pluginhandler/__init__.py | 5 +- .../internal/pluginhandler/_dirty_report.py | 2 +- .../internal/pluginhandler/_runner.py | 10 +- .../internal/project_loader/__init__.py | 2 +- .../_extensions/_ros1_noetic_meta.py | 23 +- .../_extensions/_ros2_foxy_meta.py | 17 +- .../_extensions/ros1_noetic_robot.py | 4 +- .../_extensions/ros2_foxy_desktop.py | 4 +- .../_extensions/ros2_foxy_ros_base.py | 4 +- .../_extensions/ros2_foxy_ros_core.py | 4 +- .../internal/project_loader/_parts_config.py | 8 +- .../internal/project_loader/errors.py | 6 - .../project_loader/inspection/errors.py | 3 - .../internal/remote_build/_launchpad.py | 8 +- .../internal/remote_build/_worktree.py | 8 +- .../internal/remote_build/errors.py | 13 +- snapcraft_legacy/internal/repo/_base.py | 2 +- .../internal/repo/apt_sources_manager.py | 1 - snapcraft_legacy/internal/repo/errors.py | 15 - snapcraft_legacy/internal/repo/snaps.py | 7 +- snapcraft_legacy/internal/sources/__init__.py | 1 + snapcraft_legacy/internal/sources/_git.py | 6 +- snapcraft_legacy/internal/sources/_local.py | 2 +- .../internal/sources/_subversion.py | 6 +- snapcraft_legacy/internal/sources/errors.py | 10 - .../internal/states/_global_state.py | 1 - snapcraft_legacy/plugins/v2/_kernel_build.py | 30 +- snapcraft_legacy/plugins/v2/_ros.py | 43 +- snapcraft_legacy/plugins/v2/catkin.py | 52 +- snapcraft_legacy/plugins/v2/catkin_tools.py | 43 +- snapcraft_legacy/plugins/v2/colcon.py | 120 +- snapcraft_legacy/plugins/v2/crystal.py | 1 + snapcraft_legacy/project/_project.py | 5 +- snapcraft_legacy/project/_project_options.py | 3 +- snapcraft_legacy/project/errors.py | 2 - .../scripts/generate_reference.py | 14 +- snapcraft_legacy/shell_utils.py | 1 - snapcraft_legacy/storeapi/_snap_api.py | 6 +- snapcraft_legacy/storeapi/_status_tracker.py | 1 - snapcraft_legacy/storeapi/errors.py | 37 +- .../storeapi/v2/validation_sets.py | 10 +- snapcraft_legacy/yaml_utils/__init__.py | 2 +- snapcraft_legacy/yaml_utils/errors.py | 1 - spread.yaml | 319 ++- tests/unit/extensions/test_kde_neon.py | 19 +- tests/unit/extensions/test_kde_neon_6.py | 19 +- tests/unit/services/test_lifecycle.py | 1 + .../services/test_lifecycle_components.py | 3 +- tests/unit/services/test_package.py | 1 + .../unit/services/test_package_components.py | 1 + tests/unit/store/test_client.py | 9 +- tests/unit/test_application.py | 2 +- tests/unit/test_snap_config.py | 1 + 121 files changed, 1930 insertions(+), 2165 deletions(-) create mode 100644 .prettierignore diff --git a/.github/ISSUE_TEMPLATE/bug.yaml b/.github/ISSUE_TEMPLATE/bug.yaml index 81ca677481..928c969583 100644 --- a/.github/ISSUE_TEMPLATE/bug.yaml +++ b/.github/ISSUE_TEMPLATE/bug.yaml @@ -62,4 +62,3 @@ body: id: additional-context attributes: label: Additional context - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9f0d42ea2d..4636f3c747 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,4 +3,4 @@ - [ ] Have you successfully run `tox run -m lint`? - [ ] Have you successfully run `tox run -e test-py310`? (supported versions: `py39`, `py310`, `py311`, `py312`) ------ +--- diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 50f9d88e4c..e78bce4016 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -15,10 +15,10 @@ categories: - title: "Tooling" label: - "tooling" -change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +change-template: "- $TITLE @$AUTHOR (#$NUMBER)" template: | Special thanks to the contributors that made this release happen: $CONTRIBUTORS - + ## Full list of changes $CHANGES diff --git a/.github/spread-problem-matcher.json b/.github/spread-problem-matcher.json index 87326ee58b..546d1d46a9 100644 --- a/.github/spread-problem-matcher.json +++ b/.github/spread-problem-matcher.json @@ -1,14 +1,14 @@ { - "problemMatcher": [ + "problemMatcher": [ + { + "owner": "spread-error", + "pattern": [ { - "owner": "spread-error", - "pattern": [ - { - "regexp": "^\\d+-\\d+-\\d+ \\d+:\\d+:\\d+ ((Error) (preparing|executing|restoring) .+) : .*$", - "message": 1, - "severity": 2 - } - ] + "regexp": "^\\d+-\\d+-\\d+ \\d+:\\d+:\\d+ ((Error) (preparing|executing|restoring) .+) : .*$", + "message": 1, + "severity": 2 } - ] + ] + } + ] } diff --git a/.github/workflows/check-renovate.yaml b/.github/workflows/check-renovate.yaml index 7d13cfbf21..ba9126fad8 100644 --- a/.github/workflows/check-renovate.yaml +++ b/.github/workflows/check-renovate.yaml @@ -10,7 +10,7 @@ on: inputs: enable_ssh_access: type: boolean - description: 'Enable ssh access' + description: "Enable ssh access" required: false default: false diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 0a11f13634..ec52e4e393 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -1,6 +1,6 @@ name: CI -on: +on: pull_request: push: branches: diff --git a/.github/workflows/security-scan.yaml b/.github/workflows/security-scan.yaml index 20770c8ad9..e39816acae 100644 --- a/.github/workflows/security-scan.yaml +++ b/.github/workflows/security-scan.yaml @@ -5,7 +5,7 @@ on: branches: - main - hotfix/* - - work/secscan # For development + - work/secscan # For development jobs: python-scans: @@ -13,5 +13,5 @@ jobs: uses: canonical/starflow/.github/workflows/scan-python.yaml@main with: packages: python-apt-dev - osv-extra-args: '--config=source/osv-scanner.toml' + osv-extra-args: "--config=source/osv-scanner.toml" trivy-extra-args: '--severity HIGH,CRITICAL --ignore-unfixed --skip-dirs "tests/spread/**"' diff --git a/.github/workflows/tics.yaml b/.github/workflows/tics.yaml index b3bd736492..ea9f9b7404 100644 --- a/.github/workflows/tics.yaml +++ b/.github/workflows/tics.yaml @@ -3,9 +3,9 @@ name: TICS on: push: branches: - - main - # to easy test changes to the workflow - - tiobe + - main + # to easy test changes to the workflow + - tiobe jobs: CI: diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..88f5d7117f --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +# Git submodules +docs/sphinx-resources +tests/spread/tools/snapd-testing-tools + +# Don't format spread tests in general, they sometimes expect specific formatting +tests/spread diff --git a/.readthedocs.yaml b/.readthedocs.yaml index d1d77d291a..9862aaf419 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -16,8 +16,8 @@ build: - libapt-pkg-dev jobs: post_checkout: - - git fetch --tags --unshallow # Also fetch tags - - git describe # Make sure we get a proper version + - git fetch --tags --unshallow # Also fetch tags + - git describe # Make sure we get a proper version # Build documentation in the docs/ directory with Sphinx sphinx: diff --git a/.yamllint.yaml b/.yamllint.yaml index 752f322a53..09da41146a 100644 --- a/.yamllint.yaml +++ b/.yamllint.yaml @@ -18,7 +18,7 @@ rules: octal-values: enable truthy: check-keys: false - # Changes from starbase start here + # Changes from starbase start here level: warning indentation: disable trailing-spaces: disable diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index eae850e874..69f4b99747 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -14,22 +14,22 @@ appearance, race, religion, or sexual identity and orientation. Examples of behavior that contributes to creating a positive environment include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting ## Our Responsibilities diff --git a/CODE_STYLE.md b/CODE_STYLE.md index b163e6f353..d8d2eb7100 100644 --- a/CODE_STYLE.md +++ b/CODE_STYLE.md @@ -18,25 +18,25 @@ You can `snap install ruff` to install the linter and formatter onto your host. ## Conditionals -* Always check for expected value e.g.; `if foo is True` instead of `if foo` +- Always check for expected value e.g.; `if foo is True` instead of `if foo` or `if foo is not None`. - + ## Methods -* Return only once from a method unless it is through a guard. -* Method names should start with a =verb= unless it is a `@property`. -* Attribute names should be a `noun`. +- Return only once from a method unless it is through a guard. +- Method names should start with a =verb= unless it is a `@property`. +- Attribute names should be a `noun`. ## Classes -* `classmethods` should be defined before `__init__`. -* Serialization/marshalling/dumping shall use methods named `marshal` and +- `classmethods` should be defined before `__init__`. +- Serialization/marshalling/dumping shall use methods named `marshal` and `unmarshal` but if specific types are serialized we append the information type, e.g.; `unmarshal_dict`. ## Iterating -* Always use generators, list comprehensions, reduce and functional resolution +- Always use generators, list comprehensions, reduce and functional resolution when possible. ## Multiline strings @@ -59,14 +59,14 @@ fix it. ## Tests -* When asserting for equality, we prefer to use the `Equals` matcher from +- When asserting for equality, we prefer to use the `Equals` matcher from testtools: - ``` - self.assertThat(actual, Equals(expected)) - ``` + ``` + self.assertThat(actual, Equals(expected)) + ``` -* When writing unit tests that raise errors, the tests should only check the +- When writing unit tests that raise errors, the tests should only check the class of the exception raised and it's attributes, not the format of the error message. The formatting of the exception as a string should be tested only once, in the module tests/unit/test_errors.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d995ba1aea..9cdd20d317 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,55 +8,54 @@ here. **Prerequisite:** Sign the [contributor license agreement][1]. This is how you give us permission to use your contributions. -1. If there is a [Snapcraft bug][2] you are trying to fix, please refer to - it here. If it is a feature that has not been discussed, please raise - awareness on https://forum.snapcraft.io under the *snapcraft* topic. This - will ensure that we're all on the same page, and your work is not in vain - or duplicating what someone else is already doing. This actually saves time! +1. If there is a [Snapcraft bug][2] you are trying to fix, please refer to + it here. If it is a feature that has not been discussed, please raise + awareness on https://forum.snapcraft.io under the _snapcraft_ topic. This + will ensure that we're all on the same page, and your work is not in vain + or duplicating what someone else is already doing. This actually saves time! -2. We use a forking, feature-based workflow. +2. We use a forking, feature-based workflow. - Make a fork of Snapcraft, and create a branch named specifically for the - feature on which you'd like to work. Make your changes there, adding new - tests as needed, and make sure the existing tests continue to pass when your - changes are complete (for information see the [HACKING][3] and [TESTING][4] - documents). + Make a fork of Snapcraft, and create a branch named specifically for the + feature on which you'd like to work. Make your changes there, adding new + tests as needed, and make sure the existing tests continue to pass when your + changes are complete (for information see the [HACKING][3] and [TESTING][4] + documents). -3. We try to follow a consistent and readable code style. Read the - [CODE_STYLE][5] document and please make sure that your code complies. +3. We try to follow a consistent and readable code style. Read the + [CODE_STYLE][5] document and please make sure that your code complies. -4. Squash commits into one, well-formatted commit. If you really feel like there - should be more than one commit in your branch, then you're probably trying to - introduce more than one feature and you should make another branch for - it. +4. Squash commits into one, well-formatted commit. If you really feel like there + should be more than one commit in your branch, then you're probably trying to + introduce more than one feature and you should make another branch for + it. - This is important: your commit diff says what changed, but only the commit - message can say why the change was necessary. In an effort to take good care - of our `git log`, we try to follow this template for commit messages: + This is important: your commit diff says what changed, but only the commit + message can say why the change was necessary. In an effort to take good care + of our `git log`, we try to follow this template for commit messages: + ``` + <subsystem effected>: lower-case summary of changes - ``` - <subsystem effected>: lower-case summary of changes + More detailed explanatory text, if necessary. Wrap it to 72 characters. + Think of this like an email, where you have a subject line and a body. - More detailed explanatory text, if necessary. Wrap it to 72 characters. - Think of this like an email, where you have a subject line and a body. + ``` - ``` + Try to keep the summary to around 50 characters, and use the imperative mood. + A good rule of thumb is that, if you extract the `<subsystem effected>` from + the summary, it should be able to complete the following sentence: - Try to keep the summary to around 50 characters, and use the imperative mood. - A good rule of thumb is that, if you extract the `<subsystem effected>` from - the summary, it should be able to complete the following sentence: + ``` + If applied, this commit will <insert summary here>. + ``` - ``` - If applied, this commit will <insert summary here>. - ``` - -5. Submit a pull request to get changes from your branch into master. Mention - which bug is being resolved in the description of the pull request (bonus - points if it's a hyperlink to the bug itself). +5. Submit a pull request to get changes from your branch into master. Mention + which bug is being resolved in the description of the pull request (bonus + points if it's a hyperlink to the bug itself). [1]: http://www.ubuntu.com/legal/contributors/ [2]: https://bugs.launchpad.net/snapcraft [3]: HACKING.md [4]: TESTING.md -[5]: CODE_STYLE.md \ No newline at end of file +[5]: CODE_STYLE.md diff --git a/HACKING.md b/HACKING.md index 52ca1d715c..6693175776 100644 --- a/HACKING.md +++ b/HACKING.md @@ -41,9 +41,9 @@ you with tox, but you'll need to install: - Python 3.12 (default on Ubuntu 24.04) with setuptools. - [tox](https://tox.wiki) version 3.8 or later -- [pyright](https://github.com/microsoft/pyright) (also available via snap: `snap install pyright`) +- [pyright](https://github.com/microsoft/pyright) (also available via snap: `snap install pyright`) - [ruff](https://github.com/astral/ruff) (also available via snap: `snap install ruff`) -- [ShellCheck](https://www.shellcheck.net/) (also available via snap: `snap install shellcheck`) +- [ShellCheck](https://www.shellcheck.net/) (also available via snap: `snap install shellcheck`) ### Testing @@ -53,10 +53,8 @@ See the [Testing guide](TESTING.md). Given that the `--debug` option in snapcraft is reserved for project specific debugging, enabling for the `logger.debug` calls is achieved by setting the "SNAPCRAFT_ENABLE_DEVELOPER_DEBUG" environment variable to a truthful value. Snapcraft's internal tools, e.g.; `snapcraftctl` should pick up this environment variable as well. - ## Documentation - ### Build To render the documentation as HTML in `docs/_build`, run: @@ -66,7 +64,7 @@ tox run -e build-docs ``` > **Important** -> +> > Interactive builds are currently defective and cause an infinite loop. [This GitHub issue](https://github.com/sphinx-doc/sphinx/issues/11556#issuecomment-1667451983) posits that this is caused by by pages referencing each other. If you prefer to compose pages interactively, you can host the documentation on a local server: @@ -77,7 +75,6 @@ tox run -e autobuild-docs You can reach the interactive site at http://127.0.0.1:8080 in a web browser. - ### Test The documentation Makefile provided by the [Sphinx Starter Pack](https://github.com/canonical/sphinx-docs-starter-pack) provides a number of natural language checks such as style guide adherence, inclusive words, and product terminology, however they currently aren't configured correctly for Snapcraft. Instead, you can validate for basic language and syntax using two of the development tests. @@ -94,7 +91,6 @@ For a rudimentary spell check, you can use codespell: tox run -e lint-codespell ``` - ## Evaluating pull requests Oftentimes all you want to do is see if a given pull request solves the issue you were having. To make this easier, a snap is published for `amd64` on a channel named `latest/edge/pr-<PR number>` where `PR number` is the number of the pull request. diff --git a/README.md b/README.md index f8189640a1..c4bbf3f163 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,11 @@ [![Coverage Status][codecov-image]][codecov-url] [![Code style: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) - # Snapcraft Package, distribute, and update any app for Linux and IoT. -Snaps are containerised software packages that are simple to create and +Snaps are containerised software packages that are simple to create and install. They auto-update and are safe to run. And because they bundle their dependencies, they work on all major Linux systems without modification. @@ -27,6 +26,5 @@ Learn about the latest features by following Snapcraft on We love contributors. Read the [hacking guide](HACKING.md) if you're interested in helping out. - [codecov-image]: https://codecov.io/github/canonical/snapcraft/coverage.svg?branch=master [codecov-url]: https://codecov.io/github/canonical/snapcraft?branch=master diff --git a/TESTING.md b/TESTING.md index 2d4671d6ce..1d111f8a1c 100644 --- a/TESTING.md +++ b/TESTING.md @@ -67,17 +67,17 @@ To run the unit tests, execute: You can also run a subsuite of the unit suites specifying the path to the directory. For example: - * To run only the unit tests for the plugins: +- To run only the unit tests for the plugins: - ``` - pytest tests/unit/parts/plugins - ``` + ``` + pytest tests/unit/parts/plugins + ``` - * To run only the integration tests for the store: +- To run only the integration tests for the store: - ``` - pytest tests/unit/store - ``` + ``` + pytest tests/unit/store + ``` The snaps tests script has more complex arguments. For an explanation of them, run: @@ -135,60 +135,60 @@ It is possible to emulate an arm64 machine on an amd64 host, which is very usefu 1. Download the latest ubuntu arm64 uefi image from https://cloud-images.ubuntu.com/releases/16.04/release/ 2. Keep a pristine copy of the image, in case you want to reset the machine, replacing <ubuntu-image> with the name of the file you downloaded on step 1: - ``` - $ cp <ubuntu-image> <ubuntu-image>.pristine - ``` + ``` + $ cp <ubuntu-image> <ubuntu-image>.pristine + ``` 3. Download the latest UEFI firmware image QEMU_EFI.fd from https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/ 4. Create a cloud init file, replacing <launchpad-user-name> with your values: - ``` - $ cat > cloud-data.yaml << EOF - #cloud-config - users: - - name: $USER - ssh-import-id: <launchpad-user-name> - sudo: ['ALL=(ALL) NOPASSWD:ALL'] - groups: sudo - shell: /bin/bash - EOF - ``` + ``` + $ cat > cloud-data.yaml << EOF + #cloud-config + users: + - name: $USER + ssh-import-id: <launchpad-user-name> + sudo: ['ALL=(ALL) NOPASSWD:ALL'] + groups: sudo + shell: /bin/bash + EOF + ``` 5. Create a cloud config disk image on the file `cloud-config.img`: - ``` - $ sudo apt install --yes cloud-image-utils - $ cloud-localds --disk-format qcow2 cloud-config.img cloud-data.yaml - ``` + ``` + $ sudo apt install --yes cloud-image-utils + $ cloud-localds --disk-format qcow2 cloud-config.img cloud-data.yaml + ``` 6. Run the image in qemu, replacing <ubuntu-image> with the path of the file you downloaded on step 1. - ``` - $ sudo apt install qemu-system-arm - $ qemu-system-aarch64 \ - -smp 2 \ - -m 1024 \ - -M virt \ - -cpu cortex-a57 \ - -bios QEMU_EFI.fd \ - -nographic \ - -device virtio-blk-device,drive=image \ - -drive if=none,id=image,file=<ubuntu-image> \ - -device virtio-blk-device,drive=cloud \ - -drive if=none,id=cloud,file=cloud-config.img \ - -device virtio-net-device,netdev=user0 \ - -netdev user,id=user0 \ - -redir tcp:2222::22 - ``` + ``` + $ sudo apt install qemu-system-arm + $ qemu-system-aarch64 \ + -smp 2 \ + -m 1024 \ + -M virt \ + -cpu cortex-a57 \ + -bios QEMU_EFI.fd \ + -nographic \ + -device virtio-blk-device,drive=image \ + -drive if=none,id=image,file=<ubuntu-image> \ + -device virtio-blk-device,drive=cloud \ + -drive if=none,id=cloud,file=cloud-config.img \ + -device virtio-net-device,netdev=user0 \ + -netdev user,id=user0 \ + -redir tcp:2222::22 + ``` This will show a few errors, and a weird screen while the machine boots. TODO: research how to make it nicer, but for now, just be patient until the login prompt appears. 7. ssh into the emulated machine: - ``` - $ ssh -p 2222 localhost - ``` + ``` + $ ssh -p 2222 localhost + ``` (Source: https://gist.github.com/george-hawkins/16ee37063213f348a17717a7007d2c79) diff --git a/appveyor.yml b/appveyor.yml index 09c3389a43..a8f1b9a7b5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,11 +7,11 @@ environment: TIMESTAMP_SERVICE: http://timestamp.digicert.com matrix: - - PYTHON: C:\Python310-x64 + - PYTHON: C:\Python310-x64 cache: -- '%LOCALAPPDATA%\pip\Cache\http' -- '%LOCALAPPDATA%\pip\Cache\wheels' + - '%LOCALAPPDATA%\pip\Cache\http' + - '%LOCALAPPDATA%\pip\Cache\wheels' build: off install: @@ -23,51 +23,51 @@ install: venv\Scripts\deactivate.bat build_script: -- cmd: | - echo "Building snapcraft.exe..." - venv\Scripts\activate.bat - pyinstaller.exe snapcraft.spec - venv\Scripts\deactivate.bat + - cmd: | + echo "Building snapcraft.exe..." + venv\Scripts\activate.bat + pyinstaller.exe snapcraft.spec + venv\Scripts\deactivate.bat - echo "Test signing snapcraft.exe..." - powershell.exe windows\generate-self-signed-cert.ps1 - "%SIGNTOOL%" sign /fd SHA256 /td SHA256 /tr "%TIMESTAMP_SERVICE%" /f test-signing.pfx /p Password1234 dist\snapcraft.exe + echo "Test signing snapcraft.exe..." + powershell.exe windows\generate-self-signed-cert.ps1 + "%SIGNTOOL%" sign /fd SHA256 /td SHA256 /tr "%TIMESTAMP_SERVICE%" /f test-signing.pfx /p Password1234 dist\snapcraft.exe - echo "Setting Snapcraft version..." - venv\Scripts\activate.bat - python -m tools.version set-snapcraft-iss - venv\Scripts\deactivate.bat - echo "Building snapcraft inno installer..." - "%INNOCC%" windows\snapcraft.iss + echo "Setting Snapcraft version..." + venv\Scripts\activate.bat + python -m tools.version set-snapcraft-iss + venv\Scripts\deactivate.bat + echo "Building snapcraft inno installer..." + "%INNOCC%" windows\snapcraft.iss - copy dist\snapcraft-installer.exe dist\snapcraft-installer-self-signed.exe - echo "Test signing snapcraft inno installer..." - "%SIGNTOOL%" sign /fd SHA256 /td SHA256 /tr "%TIMESTAMP_SERVICE%" /f test-signing.pfx /p Password1234 dist\snapcraft-installer-self-signed.exe + copy dist\snapcraft-installer.exe dist\snapcraft-installer-self-signed.exe + echo "Test signing snapcraft inno installer..." + "%SIGNTOOL%" sign /fd SHA256 /td SHA256 /tr "%TIMESTAMP_SERVICE%" /f test-signing.pfx /p Password1234 dist\snapcraft-installer-self-signed.exe - echo "Building snapcraft msix installer..." - mkdir dist\msix - copy dist\snapcraft.exe dist\msix\ - copy windows\snapcraft.png dist\msix\ - copy windows\AppxManifest.xml dist\msix\ - "%MAKEAPPX%" pack /h SHA256 /d dist\msix /p dist\snapcraft-installer.msix + echo "Building snapcraft msix installer..." + mkdir dist\msix + copy dist\snapcraft.exe dist\msix\ + copy windows\snapcraft.png dist\msix\ + copy windows\AppxManifest.xml dist\msix\ + "%MAKEAPPX%" pack /h SHA256 /d dist\msix /p dist\snapcraft-installer.msix - echo "Test signing snapcraft msix installer..." - "%SIGNTOOL%" sign /fd SHA256 /td SHA256 /tr "%TIMESTAMP_SERVICE%" /f test-signing.pfx /p Password1234 dist\snapcraft-installer.msix + echo "Test signing snapcraft msix installer..." + "%SIGNTOOL%" sign /fd SHA256 /td SHA256 /tr "%TIMESTAMP_SERVICE%" /f test-signing.pfx /p Password1234 dist\snapcraft-installer.msix test_script: -- cmd: | - echo "Smoke testing snapcraft.exe..." - dist\snapcraft.exe version - mkdir test - cd test - ..\dist\snapcraft.exe init - cd .. + - cmd: | + echo "Smoke testing snapcraft.exe..." + dist\snapcraft.exe version + mkdir test + cd test + ..\dist\snapcraft.exe init + cd .. - echo "Smoke testing snapcraft-installer-self-signed.exe..." - start /wait "SNAPCRAFT INSTALLER" dist\snapcraft-installer-self-signed.exe /VERYSILENT /ALLUSERS - "%SNAPCRAFT_INSTALLED_EXE%" version + echo "Smoke testing snapcraft-installer-self-signed.exe..." + start /wait "SNAPCRAFT INSTALLER" dist\snapcraft-installer-self-signed.exe /VERYSILENT /ALLUSERS + "%SNAPCRAFT_INSTALLED_EXE%" version artifacts: -#- path: dist\snapcraft.exe -- path: dist\snapcraft-installer.exe + #- path: dist\snapcraft.exe + - path: dist\snapcraft-installer.exe #- path: dist\snapcraft-installer.msix diff --git a/docker/README.md b/docker/README.md index 4615244cbb..9972cff446 100644 --- a/docker/README.md +++ b/docker/README.md @@ -8,8 +8,8 @@ matches snap `base`. For example, to build `base: core24` snap: docker run -it -v `pwd`:/project ghcr.io/canonical/snapcraft:8_core24 - * `8` in `8_core24` is the version of snapcraft. - * `\; -v` construction at the end is required to see `snapcraft` output. +- `8` in `8_core24` is the version of snapcraft. +- `\; -v` construction at the end is required to see `snapcraft` output. For more details, see official `snapcraft-rocks` repo from Canonical. @@ -18,7 +18,7 @@ For more details, see official `snapcraft-rocks` repo from Canonical. `podman` was born as a rootless alternative to Docker. It is default on Fedora to have `podman` instead of Docker, but SELinux there doesn't allow containers to write to volumes, so we just turn this "feature" off with - `--security-opt label=disable`. +`--security-opt label=disable`. ```sh podman run -it --rm --security-opt label=disable \ diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css index ef7e97f641..0f09c64e73 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -1,28 +1,28 @@ -@import url('https://fonts.googleapis.com/css2?family=Ubuntu:ital@0;1&display=swap'); +@import url("https://fonts.googleapis.com/css2?family=Ubuntu:ital@0;1&display=swap"); body { - font-family: Ubuntu, "times new roman", times, roman, serif; + font-family: Ubuntu, "times new roman", times, roman, serif; } div .toctree-wrapper { - column-count: 2; + column-count: 2; } -div .toctree-wrapper>ul { - margin: 0; +div .toctree-wrapper > ul { + margin: 0; } ul .toctree-l1 { - margin: 0; - -webkit-column-break-inside: avoid; - page-break-inside: avoid; - break-inside: avoid-column; + margin: 0; + -webkit-column-break-inside: avoid; + page-break-inside: avoid; + break-inside: avoid-column; } .wy-nav-content { - max-width: none; + max-width: none; } .log-snippets { - color: rgb(141, 141, 141); + color: rgb(141, 141, 141); } diff --git a/docs/howto/code/basic/task.yaml b/docs/howto/code/basic/task.yaml index dc65706e68..e8f939ff91 100644 --- a/docs/howto/code/basic/task.yaml +++ b/docs/howto/code/basic/task.yaml @@ -1,7 +1,6 @@ summary: test the "How to package and upload a snap with components" -restore: - rm -r *.snap +restore: rm -r *.snap execute: | unset SNAPCRAFT_BUILD_ENVIRONMENT diff --git a/docs/howto/code/components-organize/task.yaml b/docs/howto/code/components-organize/task.yaml index 87a416fcc0..71970ea009 100644 --- a/docs/howto/code/components-organize/task.yaml +++ b/docs/howto/code/components-organize/task.yaml @@ -1,7 +1,6 @@ summary: test the "How to package and upload a snap with components" -restore: - rm -r *.snap *.comp +restore: rm -r *.snap *.comp execute: | unset SNAPCRAFT_BUILD_ENVIRONMENT diff --git a/docs/howto/code/components/task.yaml b/docs/howto/code/components/task.yaml index 87a416fcc0..71970ea009 100644 --- a/docs/howto/code/components/task.yaml +++ b/docs/howto/code/components/task.yaml @@ -1,7 +1,6 @@ summary: test the "How to package and upload a snap with components" -restore: - rm -r *.snap *.comp +restore: rm -r *.snap *.comp execute: | unset SNAPCRAFT_BUILD_ENVIRONMENT diff --git a/docs/howto/code/craft-a-snap/example-python-recipe.yaml b/docs/howto/code/craft-a-snap/example-python-recipe.yaml index 5c5b12253d..6cb5d91c8e 100644 --- a/docs/howto/code/craft-a-snap/example-python-recipe.yaml +++ b/docs/howto/code/craft-a-snap/example-python-recipe.yaml @@ -2,7 +2,7 @@ name: liquidctl summary: a status and control utility to for power, cooling and LED components -version: '1.0' +version: "1.0" description: | liquidctl is a command-line tool to monitor and control the fan speed, LED colour and pump volumes of specific power supplies, motherboards, diff --git a/docs/reference/code/yt-dlp-recipe.yaml b/docs/reference/code/yt-dlp-recipe.yaml index f5a1c0312f..9c793f587c 100644 --- a/docs/reference/code/yt-dlp-recipe.yaml +++ b/docs/reference/code/yt-dlp-recipe.yaml @@ -3,9 +3,9 @@ name: yt-dlp summary: A fork of youtube-dl with additional features and patches description: | - Download and play videos on your local system. Runs from the command - line and with all the features and patches of youtube-dlc in addition - to the latest youtube-dl. + Download and play videos on your local system. Runs from the command + line and with all the features and patches of youtube-dlc in addition + to the latest youtube-dl. version: test grade: stable confinement: strict diff --git a/manual-tests.md b/manual-tests.md index f5d2d185a9..1803ecb9f5 100644 --- a/manual-tests.md +++ b/manual-tests.md @@ -7,8 +7,7 @@ 5. Enter the password. 6. Enter the one-time password. - * Check that the log in was successful. - + - Check that the log in was successful. # Test file ownership is retained @@ -18,7 +17,6 @@ 4. sudo snapcraft prime 5. ensure that prime/test-owner-file is owned by nobody and nogroup - # Test stage package caching 1. `snapcraft pull` a snap that has `parts` with `stage-packages`. @@ -30,7 +28,6 @@ 7. Run this test again, but run snapcraft on a partition separated from $HOME. - # Test cross-compilation with Go 1. Go to integration_tests/snaps/go-hello. @@ -39,7 +36,6 @@ 4. Install the snap. 5. Run `go-hello`. - # Test cross-compilation with Rust 1. Go to integration_tests/snaps/rust-hello. @@ -48,7 +44,6 @@ 4. Install the snap. 5. Run `rust-hello`. - # Test cross-compilation with Autotools 1. Go to integration_tests/snaps/autotools-hello. @@ -57,7 +52,6 @@ 4. Install the snap. 5. Run `autotools-hello`. - # Test cross-compilation with Waf 1. Go to integration_tests/snaps/waf-with-configflags. @@ -66,28 +60,27 @@ 4. Install the snap. 5. Run `waf-with-configflags`. - # Test the PC kernel. 1. Get the PC kernel source: - $ git clone -b pc https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux-snap/+git/xenial - $ cd xenial + $ git clone -b pc https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux-snap/+git/xenial + $ cd xenial 2. Run `sudo snapcraft`. 3. Create a file called `pc-model.json` with the following contents: - { - "type": "model", - "authority-id": "$account_id", + { + "type": "model", + "authority-id": "$account_id", "brand-id": "$account_id", - "series": "16", - "model": "pc", - "architecture": "amd64", - "gadget": "pc", - "kernel": "$kernel_snap_path", + "series": "16", + "model": "pc", + "architecture": "amd64", + "gadget": "pc", + "kernel": "$kernel_snap_path", "timestamp": "$date" - } + } 4. Replace `$account_id` with the value from https://myapps.developer.ubuntu.com/dev/account/ 5. Replace `$kernel_snap_path` with the path to the snap you just created. @@ -95,29 +88,28 @@ 7. If you haven't created a key, run the following command, replacing `$key_name` with a name for your key: - $ snap create-key $key_name - $ snapcraft register-key + $ snap create-key $key_name + $ snapcraft register-key 8. Sign the model: - $ cat pc-model.json | snap sign -k $key_name > pc.model + $ cat pc-model.json | snap sign -k $key_name > pc.model -10. Install ubuntu-image: +9. Install ubuntu-image: - $ sudo apt install ubuntu-image + $ sudo apt install ubuntu-image -11. Create the image: +10. Create the image: $ sudo ubuntu-image --image-size 3G -O ubuntu-core-16 pc.model --extra-snaps $kernel_snap_path -12. Start the image in kvm: +11. Start the image in kvm: $ kvm -smp 2 -m 1500 -netdev user,id=mynet0,hostfwd=tcp::8022-:22,hostfwd=tcp::8090-:80 -device virtio-net-pci,netdev=mynet0 -drive file=ubuntu-core-16/pc.img,format=raw - * Check that the user can be created. - * Check that it's possible to ssh into the vm. - * Check that it's possible to install a snap. - +- Check that the user can be created. +- Check that it's possible to ssh into the vm. +- Check that it's possible to install a snap. # Test the dragonboard 410c kernel. @@ -126,17 +118,17 @@ 3. Run `snapcraft snap --target-arch arm64` in the `demos/96boards-kernel` directory. 4. Create a file called `dragonboard-model.json` with the following contents: - { - "type": "model", - "authority-id": "$account_id", + { + "type": "model", + "authority-id": "$account_id", "brand-id": "$account_id", - "series": "16", - "model": "dragonboard", - "architecture": "arm64", - "gadget": "dragonboard", - "kernel": "$kernel_snap_path", + "series": "16", + "model": "dragonboard", + "architecture": "arm64", + "gadget": "dragonboard", + "kernel": "$kernel_snap_path", "timestamp": "$date" - } + } 5. Replace `$account_id` with the value from https://myapps.developer.ubuntu.com/dev/account/ 6. Replace `$kernel_snap_path` with the path to the snap you just created. @@ -144,12 +136,12 @@ 8. If you haven't created a key, run the following command, replacing `$key_name` with a name for your key: - $ snap create-key $key_name - $ snapcraft register-key + $ snap create-key $key_name + $ snapcraft register-key 9. Sign the model: - $ cat dragonboard-model.json | snap sign -k $key_name > dragonboard.model + $ cat dragonboard-model.json | snap sign -k $key_name > dragonboard.model 10. Install ubuntu-image: @@ -168,10 +160,9 @@ 15. Insert the sdcard into the dragonboard, and turn it on. - * Check that the user can be created. - * Check that it's possible to ssh into the board. - * Check that it's possible to install a snap. - +- Check that the user can be created. +- Check that it's possible to ssh into the board. +- Check that it's possible to install a snap. # Test installing with `pip` @@ -180,7 +171,6 @@ 3. Follow HACKING.md to install using `pip` while using --editable. 4. Repeat step 2. - # Test push metadata with conflicts 1. 'snapcraft snap' a simple snap @@ -189,13 +179,12 @@ 4. Change the snap's description in the YAML file to something different than you put in the Web 5. Try to update snap's metadata doing `snapcraft push-metadata SNAP` - * Check that it should error with "conflict" on the description field + - Check that it should error with "conflict" on the description field 6. Force the update doing `snapcraft push-metadata SNAP --force` - * Check that it should end ok - * Check in the Web that the description is now what the YAML says - + - Check that it should end ok + - Check in the Web that the description is now what the YAML says # Test push binary metadata with conflicts @@ -205,13 +194,12 @@ 4. Change the snap's icon in the YAML file to something different than you put in the Web 5. Try to update snap's metadata using `snapcraft push-metadata SNAP` - * Check that it should error with "conflict" on the icon field + - Check that it should error with "conflict" on the icon field 6. Force the update doing `snapcraft push-metadata SNAP --force` - * Check that it should end ok - * Check in the Web that the icon is now what the YAML says - + - Check that it should end ok + - Check in the Web that the icon is now what the YAML says # Test creating a macaroon with a specific expiration diff --git a/pyproject.toml b/pyproject.toml index 741388dba9..b8d405e71b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -214,11 +214,6 @@ include = ["snapcraft", "tests"] exclude = ["build", "tests/legacy", "tests/spread"] pythonVersion = "3.12" -[tool.pytest.ini_options] -minversion = "7.0" -required_plugins = ["pytest-cov>=4.0", "pytest-mock>=3.12", "pytest-subprocess>=1.4"] -addopts = ["--cov=snapcraft"] - # Most of this ruff configuration comes from craft-parts [tool.ruff] target-version = "py312" @@ -228,6 +223,7 @@ extend-exclude = [ "__pycache__", "legacy", "tests/legacy", + "snapcraft/_version.py", # setuptools_scm generates old-style type annotations and single quotes ] lint.select = [ "E", "F", # The rules built into Flake8 @@ -312,5 +308,44 @@ max-branches = 16 ] "__init__.py" = ["I001"] # Imports in __init__ filesare allowed to be out of order -[tool.ruff.lint.flake8-annotations] -suppress-none-returning = true # We don't need to explicitly point out that a function doesn't return anything +[tool.ruff.lint.pydocstyle] +ignore-decorators = [ # Functions with these decorators don't have to have docstrings. + "typing.overload", # Default configuration + # The next four are all variations on override, so child classes don't have to repeat parent classes' docstrings. + "overrides.override", + "overrides.overrides", + "typing.override", + "typing_extensions.override", +] + +[tool.ruff.lint.pep8-naming] +# Allow Pydantic's `@validator` decorator to trigger class method treatment. +classmethod-decorators = ["pydantic.validator", "pydantic.root_validator"] + +[tool.pytest.ini_options] +minversion = "7.0" +testpaths = "tests" +xfail_strict = true +markers = ["slow: slow tests"] + +[tool.coverage.run] +branch = true +omit = ["test/**"] + +[tool.coverage.report] +skip_empty = true +exclude_also = [ + "if (typing\\.)?TYPE_CHECKING:", +] + +[tool.codespell] +ignore-words-list = [ + "buildd", +] +skip = [ + # Keyrings aren't code + "*.asc", + # These tests include some non-English text + "*/test_appstream.py", + "*/test_update_metadata.py", +] diff --git a/schema/snapcraft.json b/schema/snapcraft.json index c4c0a5b3ec..059199a797 100644 --- a/schema/snapcraft.json +++ b/schema/snapcraft.json @@ -1,1284 +1,1156 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", - "definitions": { - "grammar-string": { - "oneOf": [ - { - "type": "string", - "usage": "<string>" - }, - { - "type": "array", - "items": { - "minitems": 1, - "uniqueItems": true, - "oneOf": [ - { - "type": "object", - "usage": "on <selector>[,<selector>...]:", - "additionalProperties": false, - "patternProperties": { - "^on\\s+.+$": { - "$ref": "#/definitions/grammar-string" - } - } - }, - { - "type": "object", - "usage": "to <selector>[,<selector>...]:", - "additionalProperties": false, - "patternProperties": { - "^to\\s+.+$": { - "$ref": "#/definitions/grammar-string" - } - } - }, - { - "type": "object", - "usage": "try:", - "additionalProperties": false, - "patternProperties": { - "^try$": { - "$ref": "#/definitions/grammar-string" - } - } - }, - { - "type": "object", - "usage": "else:", - "additionalProperties": false, - "patternProperties": { - "^else$": { - "$ref": "#/definitions/grammar-string" - } - } - }, - { - "type": "string", - "pattern": "else fail" - } - ] - } - } - ] + "$schema": "http://json-schema.org/draft-04/schema#", + "definitions": { + "grammar-string": { + "oneOf": [ + { + "type": "string", + "usage": "<string>" }, - "grammar-array": { - "type": "array", + { + "type": "array", + "items": { "minitems": 1, "uniqueItems": true, - "items": { - "oneOf": [ - { - "type": "string", - "usage": "<string>" - }, - { - "type": "object", - "usage": "on <selector>[,<selector>...]:", - "additionalProperties": false, - "patternProperties": { - "^on\\s+.+$": { - "$ref": "#/definitions/grammar-array" - } - } - }, - { - "type": "object", - "usage": "to <selector>[,<selector>...]:", - "additionalProperties": false, - "patternProperties": { - "^to\\s+.+$": { - "$ref": "#/definitions/grammar-array" - } - } - }, - { - "type": "object", - "usage": "try:", - "additionalProperties": false, - "patternProperties": { - "^try$": { - "$ref": "#/definitions/grammar-array" - } - } - }, - { - "type": "object", - "usage": "else:", - "additionalProperties": false, - "patternProperties": { - "^else$": { - "$ref": "#/definitions/grammar-array" - } - } - } - ] + "oneOf": [ + { + "type": "object", + "usage": "on <selector>[,<selector>...]:", + "additionalProperties": false, + "patternProperties": { + "^on\\s+.+$": { + "$ref": "#/definitions/grammar-string" + } + } + }, + { + "type": "object", + "usage": "to <selector>[,<selector>...]:", + "additionalProperties": false, + "patternProperties": { + "^to\\s+.+$": { + "$ref": "#/definitions/grammar-string" + } + } + }, + { + "type": "object", + "usage": "try:", + "additionalProperties": false, + "patternProperties": { + "^try$": { + "$ref": "#/definitions/grammar-string" + } + } + }, + { + "type": "object", + "usage": "else:", + "additionalProperties": false, + "patternProperties": { + "^else$": { + "$ref": "#/definitions/grammar-string" + } + } + }, + { + "type": "string", + "pattern": "else fail" + } + ] + } + } + ] + }, + "grammar-array": { + "type": "array", + "minitems": 1, + "uniqueItems": true, + "items": { + "oneOf": [ + { + "type": "string", + "usage": "<string>" + }, + { + "type": "object", + "usage": "on <selector>[,<selector>...]:", + "additionalProperties": false, + "patternProperties": { + "^on\\s+.+$": { + "$ref": "#/definitions/grammar-array" + } } - }, - "build-environment-grammar": { - "type": "array", - "minitems": 1, - "uniqueItems": true, - "items": { - "oneOf": [ - { - "type": "object", - "minProperties": 1, - "maxProperties": 1, - "additionalProperties": { - "type": "string" - } - }, - { - "type": "object", - "usage": "on <selector>[,<selector>...]:", - "additionalProperties": false, - "patternProperties": { - "^on\\s+.+$": { - "$ref": "#/definitions/build-environment-grammar" - } - } - }, - { - "type": "object", - "usage": "to <selector>[,<selector>...]:", - "additionalProperties": false, - "patternProperties": { - "^to\\s+.+$": { - "$ref": "#/definitions/build-environment-grammar" - } - } - }, - { - "type": "object", - "usage": "else:", - "additionalProperties": false, - "patternProperties": { - "^else$": { - "$ref": "#/definitions/build-environment-grammar" - } - } - } - ] + }, + { + "type": "object", + "usage": "to <selector>[,<selector>...]:", + "additionalProperties": false, + "patternProperties": { + "^to\\s+.+$": { + "$ref": "#/definitions/grammar-array" + } } - }, - "apt-deb": { + }, + { "type": "object", - "description": "deb repositories", + "usage": "try:", "additionalProperties": false, - "properties": { - "type": { - "type": "string", - "enum": [ - "apt" - ] - }, - "architectures": { - "type": "array", - "minItems": 1, - "uniqueItems": true, - "items": { - "type": "string", - "description": "Architectures to enable, or restrict to, for this repository. Defaults to host architecture." - } - }, - "formats": { - "type": "array", - "description": "deb types to enable. Defaults to [deb, deb-src].", - "minItems": 1, - "uniqueItems": true, - "items": { - "type": "string", - "enum": [ - "deb", - "deb-src" - ] - } - }, - "components": { - "type": "array", - "minItems": 0, - "uniqueItems": true, - "items": { - "type": "string", - "description": "Deb repository components to enable, e.g. 'main, multiverse, unstable'" - } - }, - "key-id": { - "type": "string", - "description": "GPG key identifier / fingerprint. May be used to identify key file in <project>/snap/keys/<key-id>.asc", - "pattern": "^[A-Z0-9]{40}$" - }, - "key-server": { - "type": "string", - "description": "GPG keyserver to use to fetch GPG <key-id>, e.g. 'keyserver.ubuntu.com'. Defaults to keyserver.ubuntu.com if key is not found in project." - }, - "path": { - "type": "string", - "description": "Exact path to repository (relative to URL). Cannot be used with suites or components." - }, - "suites": { - "type": "array", - "minItems": 1, - "uniqueItems": true, - "items": { - "type": "string", - "description": "Deb repository suites to enable, e.g. 'xenial-updates, xenial-security')." - } - }, - "url": { - "type": "string", - "description": "Deb repository URL, e.g. 'http://archive.canonical.com/ubuntu'." - } - }, - "required": [ - "type", - "key-id", - "url" - ], - "validation-failure": "{!r} is not properly configured deb repository" - }, - "apt-ppa": { + "patternProperties": { + "^try$": { + "$ref": "#/definitions/grammar-array" + } + } + }, + { "type": "object", - "description": "PPA repository", + "usage": "else:", "additionalProperties": false, - "properties": { - "type": { - "type": "string", - "enum": [ - "apt" - ] - }, - "ppa": { - "type": "string", - "description": "ppa path: e.g. 'canonical-kernel-team/unstable'" - } - }, - "required": [ - "type", - "ppa" - ], - "validation-failure": "{!r} is not properly configured PPA repository" - }, - "system-username-scope": { - "type": "string", - "description": "short-form user configuration (<username>: <scope>)", - "enum": [ - "shared" - ], - "validation-failure": "{!r} is not a valid user scope. Valid scopes include: 'shared'" - }, - "environment": { + "patternProperties": { + "^else$": { + "$ref": "#/definitions/grammar-array" + } + } + } + ] + } + }, + "build-environment-grammar": { + "type": "array", + "minitems": 1, + "uniqueItems": true, + "items": { + "oneOf": [ + { "type": "object", - "description": "environment entries", - "minItems": 1, + "minProperties": 1, + "maxProperties": 1, "additionalProperties": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "type": "number" - } - ] + "type": "string" } - } + }, + { + "type": "object", + "usage": "on <selector>[,<selector>...]:", + "additionalProperties": false, + "patternProperties": { + "^on\\s+.+$": { + "$ref": "#/definitions/build-environment-grammar" + } + } + }, + { + "type": "object", + "usage": "to <selector>[,<selector>...]:", + "additionalProperties": false, + "patternProperties": { + "^to\\s+.+$": { + "$ref": "#/definitions/build-environment-grammar" + } + } + }, + { + "type": "object", + "usage": "else:", + "additionalProperties": false, + "patternProperties": { + "^else$": { + "$ref": "#/definitions/build-environment-grammar" + } + } + } + ] + } }, - "title": "snapcraft schema", - "type": "object", - "properties": { - "build-packages": { - "$ref": "#/definitions/grammar-array", - "description": "top level build packages." - }, - "adopt-info": { - "type": "string", - "description": "name of the part that provides source files that will be parsed to extract snap metadata information" - }, - "name": { - "description": "name of the snap package", - "allOf": [ - { - "$comment": "string, but not too long. the failure message avoids printing repr of the thing, as it could be huge", - "type": "string", - "validation-failure": "snap names need to be strings.", - "maxLength": 40 - }, - { - "pattern": "^[a-z0-9-]*[a-z][a-z0-9-]*$", - "validation-failure": "{.instance!r} is not a valid snap name. Snap names can only use ASCII lowercase letters, numbers, and hyphens, and must have at least one letter." - }, - { - "pattern": "^[^-]", - "validation-failure": "{.instance!r} is not a valid snap name. Snap names cannot start with a hyphen." - }, - { - "pattern": "[^-]$", - "validation-failure": "{.instance!r} is not a valid snap name. Snap names cannot end with a hyphen." - }, - { - "not": { - "pattern": "--" - }, - "validation-failure": "{.instance!r} is not a valid snap name. Snap names cannot have two hyphens in a row." - } - ] - }, - "title": { - "$comment": "https://forum.snapcraft.io/t/title-length-in-snapcraft-yaml-snap-yaml/8625/10", - "description": "title for the snap", - "type": "string", - "maxLength": 40 + "apt-deb": { + "type": "object", + "description": "deb repositories", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": ["apt"] }, "architectures": { - "description": "architectures on which to build, and on which the resulting snap runs", - "type": "array", - "minItems": 1, - "uniqueItems": true, - "format": "architectures", - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "additionalProperties": false, - "required": [ - "build-on" - ], - "properties": { - "build-on": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "array", - "minItems": 1, - "uniqueItems": true - } - ] - }, - "run-on": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "array", - "minItems": 1, - "uniqueItems": true - } - ] - } - } - } - ] - } - }, - "version": { - "description": "package version", - "allOf": [ - { - "type": "string", - "validation-failure": "snap versions need to be strings. They must also be wrapped in quotes when the value will be interpreted by the YAML parser as a non-string. Examples: '1', '1.2', '1.2.3', git (will be replaced by a git describe based version string)." - }, - { - "pattern": "^[a-zA-Z0-9](?:[a-zA-Z0-9:.+~-]*[a-zA-Z0-9+~])?$", - "maxLength": 32, - "validation-failure": "{.instance!r} is not a valid snap version string. Snap versions consist of upper- and lower-case alphanumeric characters, as well as periods, colons, plus signs, tildes, and hyphens. They cannot begin with a period, colon, plus sign, tilde, or hyphen. They cannot end with a period, colon, or hyphen." - } - ] - }, - "version-script": { - "type": "string", - "description": "a script that echoes the version to set." - }, - "license": { - "type": "string", - "description": "the license the package holds" - }, - "icon": { - "type": "string", - "description": "path to a 512x512 icon representing the package.", - "format": "icon-path" - }, - "summary": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { "type": "string", - "description": "one line summary for the package", - "maxLength": 78 + "description": "Architectures to enable, or restrict to, for this repository. Defaults to host architecture." + } }, - "description": { + "formats": { + "type": "array", + "description": "deb types to enable. Defaults to [deb, deb-src].", + "minItems": 1, + "uniqueItems": true, + "items": { "type": "string", - "description": "long description of the package", - "pattern": ".+", - "validation-failure": "{.instance!r} is not a valid description string." + "enum": ["deb", "deb-src"] + } }, - "assumes": { - "type": "array", - "description": "featureset the snap requires in order to work.", - "minItems": 1, - "uniqueItems": true, - "items": [ - { - "type": "string" - } - ] - }, - "type": { + "components": { + "type": "array", + "minItems": 0, + "uniqueItems": true, + "items": { "type": "string", - "description": "the snap type, the implicit type is 'app'", - "enum": [ - "app", - "base", - "gadget", - "kernel", - "snapd" - ] + "description": "Deb repository components to enable, e.g. 'main, multiverse, unstable'" + } }, - "frameworks": { - "type": "array", - "minItems": 1, - "uniqueItems": true, - "items": [ - { - "type": "string" - } - ] - }, - "confinement": { - "type": "string", - "description": "the type of confinement supported by the snap", - "default": "strict", - "enum": [ - "classic", - "devmode", - "strict" - ] + "key-id": { + "type": "string", + "description": "GPG key identifier / fingerprint. May be used to identify key file in <project>/snap/keys/<key-id>.asc", + "pattern": "^[A-Z0-9]{40}$" }, - "grade": { - "type": "string", - "description": "the quality grade of the snap", - "default": "stable", - "enum": [ - "stable", - "devel" - ] + "key-server": { + "type": "string", + "description": "GPG keyserver to use to fetch GPG <key-id>, e.g. 'keyserver.ubuntu.com'. Defaults to keyserver.ubuntu.com if key is not found in project." }, - "base": { - "type": "string", - "description": "the base snap to use" + "path": { + "type": "string", + "description": "Exact path to repository (relative to URL). Cannot be used with suites or components." }, - "build-base": { + "suites": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { "type": "string", - "description": "force a build environment based on base to create a snap" + "description": "Deb repository suites to enable, e.g. 'xenial-updates, xenial-security')." + } }, - "epoch": { - "description": "the snap epoch, used to specify upgrade paths", - "format": "epoch" + "url": { + "type": "string", + "description": "Deb repository URL, e.g. 'http://archive.canonical.com/ubuntu'." + } + }, + "required": ["type", "key-id", "url"], + "validation-failure": "{!r} is not properly configured deb repository" + }, + "apt-ppa": { + "type": "object", + "description": "PPA repository", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "enum": ["apt"] }, - "compression": { - "description": "compression to use for snap archive - default is otherwise determined by 'snap pack'", + "ppa": { + "type": "string", + "description": "ppa path: e.g. 'canonical-kernel-team/unstable'" + } + }, + "required": ["type", "ppa"], + "validation-failure": "{!r} is not properly configured PPA repository" + }, + "system-username-scope": { + "type": "string", + "description": "short-form user configuration (<username>: <scope>)", + "enum": ["shared"], + "validation-failure": "{!r} is not a valid user scope. Valid scopes include: 'shared'" + }, + "environment": { + "type": "object", + "description": "environment entries", + "minItems": 1, + "additionalProperties": { + "anyOf": [ + { "type": "string", - "enum": [ - "lzo", - "xz" - ] - }, - "environment": { - "description": "environment entries for the snap as a whole", - "$ref": "#/definitions/environment" + "minLength": 1 + }, + { + "type": "number" + } + ] + } + } + }, + "title": "snapcraft schema", + "type": "object", + "properties": { + "build-packages": { + "$ref": "#/definitions/grammar-array", + "description": "top level build packages." + }, + "adopt-info": { + "type": "string", + "description": "name of the part that provides source files that will be parsed to extract snap metadata information" + }, + "name": { + "description": "name of the snap package", + "allOf": [ + { + "$comment": "string, but not too long. the failure message avoids printing repr of the thing, as it could be huge", + "type": "string", + "validation-failure": "snap names need to be strings.", + "maxLength": 40 }, - "passthrough": { - "type": "object", - "description": "properties to be passed into snap.yaml as-is" + { + "pattern": "^[a-z0-9-]*[a-z][a-z0-9-]*$", + "validation-failure": "{.instance!r} is not a valid snap name. Snap names can only use ASCII lowercase letters, numbers, and hyphens, and must have at least one letter." }, - "layout": { - "type": "object", - "description": "layout property to be passed into the snap.yaml as-is" + { + "pattern": "^[^-]", + "validation-failure": "{.instance!r} is not a valid snap name. Snap names cannot start with a hyphen." }, - "package-repositories": { - "type": "array", - "description": "additional repository configuration.", - "minItems": 0, - "uniqueItems": true, - "items": [ - { - "oneOf": [ - { - "$ref": "#/definitions/apt-deb" - }, - { - "$ref": "#/definitions/apt-ppa" - } - ] - } - ] + { + "pattern": "[^-]$", + "validation-failure": "{.instance!r} is not a valid snap name. Snap names cannot end with a hyphen." }, - "system-usernames": { + { + "not": { + "pattern": "--" + }, + "validation-failure": "{.instance!r} is not a valid snap name. Snap names cannot have two hyphens in a row." + } + ] + }, + "title": { + "$comment": "https://forum.snapcraft.io/t/title-length-in-snapcraft-yaml-snap-yaml/8625/10", + "description": "title for the snap", + "type": "string", + "maxLength": 40 + }, + "architectures": { + "description": "architectures on which to build, and on which the resulting snap runs", + "type": "array", + "minItems": 1, + "uniqueItems": true, + "format": "architectures", + "items": { + "anyOf": [ + { + "type": "string" + }, + { "type": "object", - "description": "system username", "additionalProperties": false, - "validation-failure": "{!r} is not a valid system-username.", - "patternProperties": { - "^snap_(daemon|microk8s|aziotedge|aziotdu)$": { - "oneOf": [ - { - "$ref": "#/definitions/system-username-scope" - }, - { - "type": "object", - "description": "long-form user configuration", - "additionalProperties": false, - "properties": { - "scope": { - "$ref": "#/definitions/system-username-scope" - } - }, - "required": [ - "scope" - ] - } - ] - } - } - }, - "donation": { - "oneOf": [ - { - "type": "array", - "minItems": 1, - "uniqueItems": true, - "items": [ - { - "type": "string" - } - ] - }, - { + "required": ["build-on"], + "properties": { + "build-on": { + "anyOf": [ + { "type": "string" - } - ] - }, - "issues": { - "oneOf": [ - { + }, + { "type": "array", "minItems": 1, - "uniqueItems": true, - "items": [ - { - "type": "string" - } - ] - }, - { + "uniqueItems": true + } + ] + }, + "run-on": { + "anyOf": [ + { "type": "string" - } - ] - }, - "contact": { - "oneOf": [ - { + }, + { "type": "array", "minItems": 1, - "uniqueItems": true, - "items": [ - { - "type": "string" - } - ] - }, - { - "type": "string" - } - ] - }, - "source-code": { - "type": "string" - }, - "website": { - "type": "string" - }, - "apps": { - "type": "object", - "additionalProperties": false, - "validation-failure": "{!r} is not a valid app name. App names consist of upper- and lower-case alphanumeric characters and hyphens. They cannot start or end with a hyphen.", - "patternProperties": { - "^[a-zA-Z0-9](?:-?[a-zA-Z0-9])*$": { - "type": "object", - "required": [ - "command" - ], - "dependencies": { - "bus-name": [ - "daemon" - ], - "activates-on": [ - "daemon" - ], - "refresh-mode": [ - "daemon" - ], - "stop-mode": [ - "daemon" - ], - "stop-command": [ - "daemon" - ], - "start-timeout": [ - "daemon" - ], - "stop-timeout": [ - "daemon" - ], - "watchdog-timeout": [ - "daemon" - ], - "restart-delay": [ - "daemon" - ], - "post-stop-command": [ - "daemon" - ], - "reload-command": [ - "daemon" - ], - "restart-condition": [ - "daemon" - ], - "before": [ - "daemon" - ], - "after": [ - "daemon" - ], - "timer": [ - "daemon" - ], - "install-mode": [ - "daemon" - ] - }, - "additionalProperties": false, - "properties": { - "autostart": { - "type": "string", - "description": "Name of the desktop file placed by the application in $SNAP_USER_DATA/.config/autostart to indicate that application should be started with the user's desktop session.", - "pattern": "^[A-Za-z0-9. _#:$-]+\\.desktop$", - "validation-failure": "{.instance!r} is not a valid desktop file name (e.g. myapp.desktop)" - }, - "common-id": { - "type": "string", - "description": "common identifier across multiple packaging formats" - }, - "bus-name": { - "type": "string", - "description": "D-Bus name this service is reachable as", - "pattern": "^[A-Za-z0-9/. _#:$-]*$", - "validation-failure": "{.instance!r} is not a valid bus name." - }, - "activates-on": { - "type": "array", - "description": "dbus interface slots this service activates on", - "minitems": 1, - "uniqueItems": true, - "items": { - "type": "string" - } - }, - "desktop": { - "type": "string", - "description": "path to a desktop file representing the app, relative to the prime directory" - }, - "command": { - "type": "string", - "description": "command executed to run the binary" - }, - "completer": { - "type": "string", - "description": "bash completion script relative to the prime directory" - }, - "stop-command": { - "type": "string", - "description": "command executed to stop a service" - }, - "post-stop-command": { - "type": "string", - "description": "command executed after stopping a service" - }, - "start-timeout": { - "type": "string", - "pattern": "^[0-9]+(ns|us|ms|s|m)*$", - "validation-failure": "{.instance!r} is not a valid timeout value.", - "description": "Optional time to wait for daemon to start - <n>ns | <n>us | <n>ms | <n>s | <n>m" - }, - "stop-timeout": { - "type": "string", - "pattern": "^[0-9]+(ns|us|ms|s|m)*$", - "validation-failure": "{.instance!r} is not a valid timeout value.", - "description": "Optional time to wait for daemon to stop - <n>ns | <n>us | <n>ms | <n>s | <n>m" - }, - "watchdog-timeout": { - "type": "string", - "pattern": "^[0-9]+(ns|us|ms|s|m)*$", - "validation-failure": "{.instance!r} is not a valid timeout value.", - "description": "Service watchdog timeout - <n>ns | <n>us | <n>ms | <n>s | <n>m" - }, - "reload-command": { - "type": "string", - "description": "Command to use to ask the service to reload its configuration." - }, - "restart-delay": { - "type": "string", - "pattern": "^[0-9]+(ns|us|ms|s|m)*$", - "validation-failure": "{.instance!r} is not a valid delay value.", - "description": "Delay between service restarts - <n>ns | <n>us | <n>ms | <n>s | <n>m. Defaults to unset. See the systemd.service manual on RestartSec for details." - }, - "timer": { - "type": "string", - "description": "The service is activated by a timer, app must be a daemon. (systemd.time calendar event string)" - }, - "daemon": { - "type": "string", - "description": "signals that the app is a service.", - "enum": [ - "simple", - "forking", - "oneshot", - "notify", - "dbus" - ] - }, - "after": { - "type": "array", - "description": "List of applications that are ordered to be started after the current one", - "minitems": 1, - "uniqueItems": true, - "items": { - "type": "string" - } - }, - "before": { - "type": "array", - "description": "List of applications that are ordered to be started before the current one", - "minitems": 1, - "uniqueItems": true, - "items": { - "type": "string" - } - }, - "refresh-mode": { - "type": "string", - "description": "controls if the app should be restarted at all", - "enum": [ - "endure", - "restart", - "ignore-running" - ] - }, - "stop-mode": { - "type": "string", - "description": "controls how the daemon should be stopped", - "enum": [ - "sigterm", - "sigterm-all", - "sighup", - "sighup-all", - "sigusr1", - "sigusr1-all", - "sigusr2", - "sigusr2-all", - "sigint", - "sigint-all" - ] - }, - "restart-condition": { - "type": "string", - "enum": [ - "on-success", - "on-failure", - "on-abnormal", - "on-abort", - "on-watchdog", - "always", - "never" - ] - }, - "install-mode": { - "type": "string", - "enum": [ - "enable", - "disable" - ] - }, - "slots": { - "type": "array", - "minitems": 1, - "uniqueItems": true, - "items": { - "type": "string" - } - }, - "plugs": { - "type": "array", - "minitems": 1, - "uniqueItems": true, - "items": { - "type": "string" - } - }, - "aliases": { - "type": "array", - "uniqueItems": true, - "items": { - "type": "string", - "pattern": "^[a-zA-Z0-9][-_.a-zA-Z0-9]*$", - "validation-failure": "{.instance!r} is not a valid alias. Aliases must be strings, begin with an ASCII alphanumeric character, and can only use ASCII alphanumeric characters and the following special characters: . _ -" - } - }, - "environment": { - "description": "environment entries for the specific app.", - "$ref": "#/definitions/environment" - }, - "adapter": { - "$comment": "Full should be the default, but it requires command-chain which isn't available in snapd until 2.36, which isn't yet stable. Until 2.36 is generally available, continue with legacy as the default.", - "type": "string", - "description": "What kind of wrapper to generate for the given command", - "enum": [ - "none", - "legacy", - "full" - ], - "default": "legacy" - }, - "command-chain": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[A-Za-z0-9/._#:$-]*$", - "validation-failure": "{.instance!r} is not a valid command-chain entry. Command chain entries must be strings, and can only use ASCII alphanumeric characters and the following special characters: / . _ # : $ -" - } - }, - "sockets": { - "type": "object", - "additionalProperties": false, - "validation-failure": "{!r} is not a valid socket name. Socket names consist of lower-case alphanumeric characters and hyphens.", - "patternProperties": { - "^[a-z][a-z0-9_-]*$": { - "type": "object", - "required": [ - "listen-stream" - ], - "description": "Sockets for automatic service activation", - "additionalProperties": false, - "properties": { - "listen-stream": { - "anyOf": [ - { - "type": "integer", - "usage": "port number, an integer between 1 and 65535", - "minimum": 1, - "maximum": 65535 - }, - { - "type": "string", - "usage": "socket path, a string" - } - ] - }, - "socket-mode": { - "type": "integer" - } - } - } - } - }, - "passthrough": { - "type": "object", - "description": "properties to be passed into snap.yaml as-is" - }, - "extensions": { - "type": "array", - "minitems": 1, - "uniqueItems": true, - "items": { - "enum": [ - "env-injector", - "flutter-stable", - "flutter-beta", - "flutter-dev", - "flutter-master", - "gnome", - "gnome-3-28", - "gnome-3-34", - "gnome-3-38", - "kde-neon", - "kde-neon-6", - "ros1-noetic", - "ros1-noetic-desktop", - "ros1-noetic-perception", - "ros1-noetic-robot", - "ros1-noetic-ros-base", - "ros1-noetic-ros-core", - "ros2-foxy", - "ros2-foxy-ros-base", - "ros2-foxy-ros-core", - "ros2-foxy-desktop", - "ros2-humble", - "ros2-humble-ros-base", - "ros2-humble-ros-core", - "ros2-humble-desktop" - ] - } - } - } - } + "uniqueItems": true + } + ] + } } + } + ] + } + }, + "version": { + "description": "package version", + "allOf": [ + { + "type": "string", + "validation-failure": "snap versions need to be strings. They must also be wrapped in quotes when the value will be interpreted by the YAML parser as a non-string. Examples: '1', '1.2', '1.2.3', git (will be replaced by a git describe based version string)." }, - "hooks": { - "type": "object", - "additionalProperties": false, - "validation-failure": "{!r} is not a valid hook name. Hook names consist of lower-case alphanumeric characters and hyphens. They cannot start or end with a hyphen.", - "patternProperties": { - "^[a-z](?:-?[a-z0-9])*$": { - "type": "object", - "additionalProperties": false, - "properties": { - "command-chain": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[A-Za-z0-9/._#:$-]*$", - "validation-failure": "{.instance!r} is not a valid command-chain entry. Command chain entries must be strings, and can only use ASCII alphanumeric characters and the following special characters: / . _ # : $ -" - } - }, - "environment": { - "description": "environment entries for this hook", - "$ref": "#/definitions/environment" - }, - "plugs": { - "type": "array", - "minitems": 1, - "uniqueItems": true, - "items": { - "type": "string" - } - }, - "passthrough": { - "type": "object", - "description": "properties to be passed into snap.yaml as-is" - } - } - } + { + "pattern": "^[a-zA-Z0-9](?:[a-zA-Z0-9:.+~-]*[a-zA-Z0-9+~])?$", + "maxLength": 32, + "validation-failure": "{.instance!r} is not a valid snap version string. Snap versions consist of upper- and lower-case alphanumeric characters, as well as periods, colons, plus signs, tildes, and hyphens. They cannot begin with a period, colon, plus sign, tilde, or hyphen. They cannot end with a period, colon, or hyphen." + } + ] + }, + "version-script": { + "type": "string", + "description": "a script that echoes the version to set." + }, + "license": { + "type": "string", + "description": "the license the package holds" + }, + "icon": { + "type": "string", + "description": "path to a 512x512 icon representing the package.", + "format": "icon-path" + }, + "summary": { + "type": "string", + "description": "one line summary for the package", + "maxLength": 78 + }, + "description": { + "type": "string", + "description": "long description of the package", + "pattern": ".+", + "validation-failure": "{.instance!r} is not a valid description string." + }, + "assumes": { + "type": "array", + "description": "featureset the snap requires in order to work.", + "minItems": 1, + "uniqueItems": true, + "items": [ + { + "type": "string" + } + ] + }, + "type": { + "type": "string", + "description": "the snap type, the implicit type is 'app'", + "enum": ["app", "base", "gadget", "kernel", "snapd"] + }, + "frameworks": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": [ + { + "type": "string" + } + ] + }, + "confinement": { + "type": "string", + "description": "the type of confinement supported by the snap", + "default": "strict", + "enum": ["classic", "devmode", "strict"] + }, + "grade": { + "type": "string", + "description": "the quality grade of the snap", + "default": "stable", + "enum": ["stable", "devel"] + }, + "base": { + "type": "string", + "description": "the base snap to use" + }, + "build-base": { + "type": "string", + "description": "force a build environment based on base to create a snap" + }, + "epoch": { + "description": "the snap epoch, used to specify upgrade paths", + "format": "epoch" + }, + "compression": { + "description": "compression to use for snap archive - default is otherwise determined by 'snap pack'", + "type": "string", + "enum": ["lzo", "xz"] + }, + "environment": { + "description": "environment entries for the snap as a whole", + "$ref": "#/definitions/environment" + }, + "passthrough": { + "type": "object", + "description": "properties to be passed into snap.yaml as-is" + }, + "layout": { + "type": "object", + "description": "layout property to be passed into the snap.yaml as-is" + }, + "package-repositories": { + "type": "array", + "description": "additional repository configuration.", + "minItems": 0, + "uniqueItems": true, + "items": [ + { + "oneOf": [ + { + "$ref": "#/definitions/apt-deb" + }, + { + "$ref": "#/definitions/apt-ppa" } - }, - "parts": { - "type": "object", - "minProperties": 1, - "additionalProperties": false, - "validation-failure": "{!r} is not a valid part name. Part names consist of lower-case alphanumeric characters, hyphens and plus signs. As a special case, 'plugins' is also not a valid part name.", - "patternProperties": { - "^(?!plugins$)[a-z0-9][a-z0-9+-]*$": { - "type": [ - "object", - "null" - ], - "minProperties": 1, - "required": [ - "plugin" - ], - "properties": { - "plugin": { - "type": "string", - "description": "plugin name" - }, - "source": { - "$ref": "#/definitions/grammar-string" - }, - "source-checksum": { - "type": "string", - "default": "" - }, - "source-branch": { - "type": "string", - "default": "" - }, - "source-commit": { - "type": "string", - "default": "" - }, - "source-depth": { - "type": "integer", - "default": 0 - }, - "source-submodules": { - "type": "array", - "minItems": 0, - "uniqueItems": true, - "items": { - "type": "string", - "description": "submodules to fetch, by pathname in source tree" - } - }, - "source-subdir": { - "type": "string", - "default": "" - }, - "source-tag": { - "type": "string", - "default": "" - }, - "source-type": { - "type": "string", - "default": "", - "enum": [ - "bzr", - "git", - "hg", - "mercurial", - "subversion", - "svn", - "tar", - "zip", - "deb", - "rpm", - "7z", - "local" - ] - }, - "disable-parallel": { - "type": "boolean", - "default": false - }, - "after": { - "type": "array", - "minitems": 1, - "uniqueItems": true, - "items": { - "type": "string" - }, - "default": [] - }, - "stage-snaps": { - "$comment": "For some reason 'default' doesn't work if in the ref", - "$ref": "#/definitions/grammar-array", - "default": [] - }, - "stage-packages": { - "$comment": "For some reason 'default' doesn't work if in the ref", - "$ref": "#/definitions/grammar-array", - "default": [] - }, - "build-snaps": { - "$comment": "For some reason 'default' doesn't work if in the ref", - "$ref": "#/definitions/grammar-array", - "default": [] - }, - "build-packages": { - "$comment": "For some reason 'default' doesn't work if in the ref", - "$ref": "#/definitions/grammar-array", - "default": [] - }, - "build-environment": { - "$ref": "#/definitions/build-environment-grammar", - "default": [] - }, - "build-attributes": { - "type": "array", - "minitems": 1, - "uniqueItems": true, - "items": { - "type": "string", - "enum": [ - "core22-step-dependencies", - "enable-patchelf", - "no-patchelf", - "no-install", - "debug", - "keep-execstack" - ] - }, - "default": [] - }, - "organize": { - "type": "object", - "default": {}, - "additionalProperties": { - "type": "string", - "minLength": 1 - } - }, - "filesets": { - "type": "object", - "default": {}, - "additionalProperties": { - "type": "array", - "minitems": 1 - } - }, - "stage": { - "type": "array", - "minitems": 1, - "uniqueItems": true, - "items": { - "type": "string" - }, - "default": [ - "*" - ] - }, - "prime": { - "type": "array", - "minitems": 1, - "uniqueItems": true, - "items": { - "type": "string" - }, - "default": [ - "*" - ] - }, - "override-pull": { - "type": "string", - "default": "snapcraftctl pull" - }, - "override-build": { - "type": "string", - "default": "snapcraftctl build" - }, - "override-stage": { - "type": "string", - "default": "snapcraftctl stage" - }, - "override-prime": { - "type": "string", - "default": "snapcraftctl prime" - }, - "parse-info": { - "type": "array", - "minitems": 1, - "uniqueItems": true, - "items": { - "type": "string" - }, - "default": [] - } - } + ] + } + ] + }, + "system-usernames": { + "type": "object", + "description": "system username", + "additionalProperties": false, + "validation-failure": "{!r} is not a valid system-username.", + "patternProperties": { + "^snap_(daemon|microk8s|aziotedge|aziotdu)$": { + "oneOf": [ + { + "$ref": "#/definitions/system-username-scope" + }, + { + "type": "object", + "description": "long-form user configuration", + "additionalProperties": false, + "properties": { + "scope": { + "$ref": "#/definitions/system-username-scope" } + }, + "required": ["scope"] } + ] + } + } + }, + "donation": { + "oneOf": [ + { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": [ + { + "type": "string" + } + ] }, - "plugs": { - "type": "object" - }, - "slots": { - "type": "object" + { + "type": "string" + } + ] + }, + "issues": { + "oneOf": [ + { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": [ + { + "type": "string" + } + ] }, - "ua-services": { - "type": "array", - "description": "UA services to enable.", - "minItems": 1, - "uniqueItems": true, - "items": [ - { - "type": "string" - } - ] + { + "type": "string" } + ] }, - "allOf": [ + "contact": { + "oneOf": [ { - "anyOf": [ - { - "usage": "type: <base|kernel|snapd> (without a base)", - "properties": { - "type": { - "enum": [ - "base", - "kernel", - "snapd" - ] - } - }, - "allOf": [ + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": [ + { + "type": "string" + } + ] + }, + { + "type": "string" + } + ] + }, + "source-code": { + "type": "string" + }, + "website": { + "type": "string" + }, + "apps": { + "type": "object", + "additionalProperties": false, + "validation-failure": "{!r} is not a valid app name. App names consist of upper- and lower-case alphanumeric characters and hyphens. They cannot start or end with a hyphen.", + "patternProperties": { + "^[a-zA-Z0-9](?:-?[a-zA-Z0-9])*$": { + "type": "object", + "required": ["command"], + "dependencies": { + "bus-name": ["daemon"], + "activates-on": ["daemon"], + "refresh-mode": ["daemon"], + "stop-mode": ["daemon"], + "stop-command": ["daemon"], + "start-timeout": ["daemon"], + "stop-timeout": ["daemon"], + "watchdog-timeout": ["daemon"], + "restart-delay": ["daemon"], + "post-stop-command": ["daemon"], + "reload-command": ["daemon"], + "restart-condition": ["daemon"], + "before": ["daemon"], + "after": ["daemon"], + "timer": ["daemon"], + "install-mode": ["daemon"] + }, + "additionalProperties": false, + "properties": { + "autostart": { + "type": "string", + "description": "Name of the desktop file placed by the application in $SNAP_USER_DATA/.config/autostart to indicate that application should be started with the user's desktop session.", + "pattern": "^[A-Za-z0-9. _#:$-]+\\.desktop$", + "validation-failure": "{.instance!r} is not a valid desktop file name (e.g. myapp.desktop)" + }, + "common-id": { + "type": "string", + "description": "common identifier across multiple packaging formats" + }, + "bus-name": { + "type": "string", + "description": "D-Bus name this service is reachable as", + "pattern": "^[A-Za-z0-9/. _#:$-]*$", + "validation-failure": "{.instance!r} is not a valid bus name." + }, + "activates-on": { + "type": "array", + "description": "dbus interface slots this service activates on", + "minitems": 1, + "uniqueItems": true, + "items": { + "type": "string" + } + }, + "desktop": { + "type": "string", + "description": "path to a desktop file representing the app, relative to the prime directory" + }, + "command": { + "type": "string", + "description": "command executed to run the binary" + }, + "completer": { + "type": "string", + "description": "bash completion script relative to the prime directory" + }, + "stop-command": { + "type": "string", + "description": "command executed to stop a service" + }, + "post-stop-command": { + "type": "string", + "description": "command executed after stopping a service" + }, + "start-timeout": { + "type": "string", + "pattern": "^[0-9]+(ns|us|ms|s|m)*$", + "validation-failure": "{.instance!r} is not a valid timeout value.", + "description": "Optional time to wait for daemon to start - <n>ns | <n>us | <n>ms | <n>s | <n>m" + }, + "stop-timeout": { + "type": "string", + "pattern": "^[0-9]+(ns|us|ms|s|m)*$", + "validation-failure": "{.instance!r} is not a valid timeout value.", + "description": "Optional time to wait for daemon to stop - <n>ns | <n>us | <n>ms | <n>s | <n>m" + }, + "watchdog-timeout": { + "type": "string", + "pattern": "^[0-9]+(ns|us|ms|s|m)*$", + "validation-failure": "{.instance!r} is not a valid timeout value.", + "description": "Service watchdog timeout - <n>ns | <n>us | <n>ms | <n>s | <n>m" + }, + "reload-command": { + "type": "string", + "description": "Command to use to ask the service to reload its configuration." + }, + "restart-delay": { + "type": "string", + "pattern": "^[0-9]+(ns|us|ms|s|m)*$", + "validation-failure": "{.instance!r} is not a valid delay value.", + "description": "Delay between service restarts - <n>ns | <n>us | <n>ms | <n>s | <n>m. Defaults to unset. See the systemd.service manual on RestartSec for details." + }, + "timer": { + "type": "string", + "description": "The service is activated by a timer, app must be a daemon. (systemd.time calendar event string)" + }, + "daemon": { + "type": "string", + "description": "signals that the app is a service.", + "enum": ["simple", "forking", "oneshot", "notify", "dbus"] + }, + "after": { + "type": "array", + "description": "List of applications that are ordered to be started after the current one", + "minitems": 1, + "uniqueItems": true, + "items": { + "type": "string" + } + }, + "before": { + "type": "array", + "description": "List of applications that are ordered to be started before the current one", + "minitems": 1, + "uniqueItems": true, + "items": { + "type": "string" + } + }, + "refresh-mode": { + "type": "string", + "description": "controls if the app should be restarted at all", + "enum": ["endure", "restart", "ignore-running"] + }, + "stop-mode": { + "type": "string", + "description": "controls how the daemon should be stopped", + "enum": [ + "sigterm", + "sigterm-all", + "sighup", + "sighup-all", + "sigusr1", + "sigusr1-all", + "sigusr2", + "sigusr2-all", + "sigint", + "sigint-all" + ] + }, + "restart-condition": { + "type": "string", + "enum": [ + "on-success", + "on-failure", + "on-abnormal", + "on-abort", + "on-watchdog", + "always", + "never" + ] + }, + "install-mode": { + "type": "string", + "enum": ["enable", "disable"] + }, + "slots": { + "type": "array", + "minitems": 1, + "uniqueItems": true, + "items": { + "type": "string" + } + }, + "plugs": { + "type": "array", + "minitems": 1, + "uniqueItems": true, + "items": { + "type": "string" + } + }, + "aliases": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "pattern": "^[a-zA-Z0-9][-_.a-zA-Z0-9]*$", + "validation-failure": "{.instance!r} is not a valid alias. Aliases must be strings, begin with an ASCII alphanumeric character, and can only use ASCII alphanumeric characters and the following special characters: . _ -" + } + }, + "environment": { + "description": "environment entries for the specific app.", + "$ref": "#/definitions/environment" + }, + "adapter": { + "$comment": "Full should be the default, but it requires command-chain which isn't available in snapd until 2.36, which isn't yet stable. Until 2.36 is generally available, continue with legacy as the default.", + "type": "string", + "description": "What kind of wrapper to generate for the given command", + "enum": ["none", "legacy", "full"], + "default": "legacy" + }, + "command-chain": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[A-Za-z0-9/._#:$-]*$", + "validation-failure": "{.instance!r} is not a valid command-chain entry. Command chain entries must be strings, and can only use ASCII alphanumeric characters and the following special characters: / . _ # : $ -" + } + }, + "sockets": { + "type": "object", + "additionalProperties": false, + "validation-failure": "{!r} is not a valid socket name. Socket names consist of lower-case alphanumeric characters and hyphens.", + "patternProperties": { + "^[a-z][a-z0-9_-]*$": { + "type": "object", + "required": ["listen-stream"], + "description": "Sockets for automatic service activation", + "additionalProperties": false, + "properties": { + "listen-stream": { + "anyOf": [ { - "required": [ - "type" - ] + "type": "integer", + "usage": "port number, an integer between 1 and 65535", + "minimum": 1, + "maximum": 65535 }, { - "not": { - "required": [ - "base" - ] - } - } - ] - }, - { - "usage": "base: <base> and type: <app|gadget>", - "properties": { - "type": { - "enum": [ - "app", - "gadget" - ] + "type": "string", + "usage": "socket path, a string" } + ] }, - "allOf": [ - { - "required": [ - "base" - ] - } - ] - }, - { - "usage": "base: bare (with a build-base)", - "properties": { - "base": { - "enum": [ - "bare" - ] - } - }, - "required": [ - "build-base" - ] + "socket-mode": { + "type": "integer" + } + } } - ] + } + }, + "passthrough": { + "type": "object", + "description": "properties to be passed into snap.yaml as-is" + }, + "extensions": { + "type": "array", + "minitems": 1, + "uniqueItems": true, + "items": { + "enum": [ + "env-injector", + "flutter-stable", + "flutter-beta", + "flutter-dev", + "flutter-master", + "gnome", + "gnome-3-28", + "gnome-3-34", + "gnome-3-38", + "kde-neon", + "kde-neon-6", + "ros1-noetic", + "ros1-noetic-desktop", + "ros1-noetic-perception", + "ros1-noetic-robot", + "ros1-noetic-ros-base", + "ros1-noetic-ros-core", + "ros2-foxy", + "ros2-foxy-ros-base", + "ros2-foxy-ros-core", + "ros2-foxy-desktop", + "ros2-humble", + "ros2-humble-ros-base", + "ros2-humble-ros-core", + "ros2-humble-desktop" + ] + } + } + } + } + } + }, + "hooks": { + "type": "object", + "additionalProperties": false, + "validation-failure": "{!r} is not a valid hook name. Hook names consist of lower-case alphanumeric characters and hyphens. They cannot start or end with a hyphen.", + "patternProperties": { + "^[a-z](?:-?[a-z0-9])*$": { + "type": "object", + "additionalProperties": false, + "properties": { + "command-chain": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[A-Za-z0-9/._#:$-]*$", + "validation-failure": "{.instance!r} is not a valid command-chain entry. Command chain entries must be strings, and can only use ASCII alphanumeric characters and the following special characters: / . _ # : $ -" + } + }, + "environment": { + "description": "environment entries for this hook", + "$ref": "#/definitions/environment" + }, + "plugs": { + "type": "array", + "minitems": 1, + "uniqueItems": true, + "items": { + "type": "string" + } + }, + "passthrough": { + "type": "object", + "description": "properties to be passed into snap.yaml as-is" + } + } + } + } + }, + "parts": { + "type": "object", + "minProperties": 1, + "additionalProperties": false, + "validation-failure": "{!r} is not a valid part name. Part names consist of lower-case alphanumeric characters, hyphens and plus signs. As a special case, 'plugins' is also not a valid part name.", + "patternProperties": { + "^(?!plugins$)[a-z0-9][a-z0-9+-]*$": { + "type": ["object", "null"], + "minProperties": 1, + "required": ["plugin"], + "properties": { + "plugin": { + "type": "string", + "description": "plugin name" + }, + "source": { + "$ref": "#/definitions/grammar-string" + }, + "source-checksum": { + "type": "string", + "default": "" + }, + "source-branch": { + "type": "string", + "default": "" + }, + "source-commit": { + "type": "string", + "default": "" + }, + "source-depth": { + "type": "integer", + "default": 0 + }, + "source-submodules": { + "type": "array", + "minItems": 0, + "uniqueItems": true, + "items": { + "type": "string", + "description": "submodules to fetch, by pathname in source tree" + } + }, + "source-subdir": { + "type": "string", + "default": "" + }, + "source-tag": { + "type": "string", + "default": "" + }, + "source-type": { + "type": "string", + "default": "", + "enum": [ + "bzr", + "git", + "hg", + "mercurial", + "subversion", + "svn", + "tar", + "zip", + "deb", + "rpm", + "7z", + "local" + ] + }, + "disable-parallel": { + "type": "boolean", + "default": false + }, + "after": { + "type": "array", + "minitems": 1, + "uniqueItems": true, + "items": { + "type": "string" + }, + "default": [] + }, + "stage-snaps": { + "$comment": "For some reason 'default' doesn't work if in the ref", + "$ref": "#/definitions/grammar-array", + "default": [] + }, + "stage-packages": { + "$comment": "For some reason 'default' doesn't work if in the ref", + "$ref": "#/definitions/grammar-array", + "default": [] + }, + "build-snaps": { + "$comment": "For some reason 'default' doesn't work if in the ref", + "$ref": "#/definitions/grammar-array", + "default": [] + }, + "build-packages": { + "$comment": "For some reason 'default' doesn't work if in the ref", + "$ref": "#/definitions/grammar-array", + "default": [] + }, + "build-environment": { + "$ref": "#/definitions/build-environment-grammar", + "default": [] + }, + "build-attributes": { + "type": "array", + "minitems": 1, + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "core22-step-dependencies", + "enable-patchelf", + "no-patchelf", + "no-install", + "debug", + "keep-execstack" + ] + }, + "default": [] + }, + "organize": { + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string", + "minLength": 1 + } + }, + "filesets": { + "type": "object", + "default": {}, + "additionalProperties": { + "type": "array", + "minitems": 1 + } + }, + "stage": { + "type": "array", + "minitems": 1, + "uniqueItems": true, + "items": { + "type": "string" + }, + "default": ["*"] + }, + "prime": { + "type": "array", + "minitems": 1, + "uniqueItems": true, + "items": { + "type": "string" + }, + "default": ["*"] + }, + "override-pull": { + "type": "string", + "default": "snapcraftctl pull" + }, + "override-build": { + "type": "string", + "default": "snapcraftctl build" + }, + "override-stage": { + "type": "string", + "default": "snapcraftctl stage" + }, + "override-prime": { + "type": "string", + "default": "snapcraftctl prime" + }, + "parse-info": { + "type": "array", + "minitems": 1, + "uniqueItems": true, + "items": { + "type": "string" + }, + "default": [] + } + } + } + } + }, + "plugs": { + "type": "object" + }, + "slots": { + "type": "object" + }, + "ua-services": { + "type": "array", + "description": "UA services to enable.", + "minItems": 1, + "uniqueItems": true, + "items": [ + { + "type": "string" + } + ] + } + }, + "allOf": [ + { + "anyOf": [ + { + "usage": "type: <base|kernel|snapd> (without a base)", + "properties": { + "type": { + "enum": ["base", "kernel", "snapd"] + } + }, + "allOf": [ + { + "required": ["type"] + }, + { + "not": { + "required": ["base"] + } + } + ] }, { - "anyOf": [ - { - "required": [ - "summary", - "description", - "version" - ] - }, - { - "required": [ - "adopt-info" - ] - } - ] + "usage": "base: <base> and type: <app|gadget>", + "properties": { + "type": { + "enum": ["app", "gadget"] + } + }, + "allOf": [ + { + "required": ["base"] + } + ] + }, + { + "usage": "base: bare (with a build-base)", + "properties": { + "base": { + "enum": ["bare"] + } + }, + "required": ["build-base"] } - ], - "required": [ - "name", - "parts" - ], - - "dependencies": { - "license-agreement": [ - "license" - ], - "license-version": [ - "license" - ] + ] }, - "additionalProperties": false + { + "anyOf": [ + { + "required": ["summary", "description", "version"] + }, + { + "required": ["adopt-info"] + } + ] + } + ], + "required": ["name", "parts"], + + "dependencies": { + "license-agreement": ["license"], + "license-version": ["license"] + }, + "additionalProperties": false } diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index f040099774..8dec7ee923 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -2,10 +2,10 @@ name: snapcraft base: core24 summary: easily create snaps description: | - Snapcraft aims to make upstream developers' lives easier and as such is not - a single toolset, but instead is a collection of tools that enable the - natural workflow of an upstream to be extended with a simple release step - into Snappy. + Snapcraft aims to make upstream developers' lives easier and as such is not + a single toolset, but instead is a collection of tools that enable the + natural workflow of an upstream to be extended with a simple release step + into Snappy. adopt-info: snapcraft confinement: classic license: GPL-3.0 @@ -19,7 +19,6 @@ environment: # Ubuntu 20.04 for armhf, ppc64el, riscv64, and s390x CRYPTOGRAPHY_OPENSSL_NO_LEGACY: "1" - apps: snapcraft: environment: @@ -70,12 +69,11 @@ parts: - "-usr/lib/x86_64-linux-gnu/libperl*" - "-usr/lib/x86_64-linux-gnu/libgdbm*" - patchelf: plugin: autotools source: https://github.com/canonical/patchelf source-type: git - source-branch: '0.9+snapcraft' + source-branch: "0.9+snapcraft" autotools-configure-parameters: - --prefix=/ build-attributes: @@ -100,28 +98,28 @@ parts: snapcraft-libs: plugin: nil stage-packages: - - apt - - apt-transport-https - - apt-utils - - binutils - - execstack - - gpg - - gpgv - - libsodium23 - - libxml2 - - libxslt1.1 - - libpython3-stdlib - - libpython3.12-stdlib - - libpython3.12-minimal - - python3-pip - - python3-setuptools - - python3-wheel - - python3-venv - - python3-minimal - - python3-pkg-resources - - python3.12-minimal - - squashfs-tools - - xdelta3 + - apt + - apt-transport-https + - apt-utils + - binutils + - execstack + - gpg + - gpgv + - libsodium23 + - libxml2 + - libxslt1.1 + - libpython3-stdlib + - libpython3.12-stdlib + - libpython3.12-minimal + - python3-pip + - python3-setuptools + - python3-wheel + - python3-venv + - python3-minimal + - python3-pkg-resources + - python3.12-minimal + - squashfs-tools + - xdelta3 build-attributes: - enable-patchelf override-build: | @@ -169,47 +167,47 @@ parts: source: . plugin: python python-packages: - - wheel - - pip + - wheel + - pip python-constraints: - - constraints.txt + - constraints.txt python-requirements: - - uv-requirements.txt + - uv-requirements.txt organize: - # Put snapcraftctl and craftctl into its own directory that can be included in the PATH - # without including other binaries. - bin/craftctl: libexec/snapcraft/craftctl - bin/snapcraftctl: bin/scriptlet-bin/snapcraftctl - # Also install the compatibility wrapper for core22+. - bin/snapcraftctl-compat: libexec/snapcraft/snapcraftctl - # Include general data in the share directory - "**/site-packages/extensions": share/snapcraft/extensions - "**/site-packages/keyrings": share/snapcraft/keyrings - "**/site-packages/schema": share/snapcraft/schema + # Put snapcraftctl and craftctl into its own directory that can be included in the PATH + # without including other binaries. + bin/craftctl: libexec/snapcraft/craftctl + bin/snapcraftctl: bin/scriptlet-bin/snapcraftctl + # Also install the compatibility wrapper for core22+. + bin/snapcraftctl-compat: libexec/snapcraft/snapcraftctl + # Include general data in the share directory + "**/site-packages/extensions": share/snapcraft/extensions + "**/site-packages/keyrings": share/snapcraft/keyrings + "**/site-packages/schema": share/snapcraft/schema build-attributes: - enable-patchelf build-environment: - # Build PyNaCl from source since the wheel files interact - # strangely with classic snaps. Well, build it all from source. - - "PIP_NO_BINARY": ":all:" - # Use base image's libsodium for PyNaCl. - - "SODIUM_INSTALL": "system" - - "CFLAGS": "$(pkg-config python-3.12 yaml-0.1 --cflags)" + # Build PyNaCl from source since the wheel files interact + # strangely with classic snaps. Well, build it all from source. + - "PIP_NO_BINARY": ":all:" + # Use base image's libsodium for PyNaCl. + - "SODIUM_INSTALL": "system" + - "CFLAGS": "$(pkg-config python-3.12 yaml-0.1 --cflags)" build-snaps: - - astral-uv + - astral-uv override-build: | - uv export --no-dev --no-emit-workspace --output-file uv-requirements.txt - ${SNAP}/libexec/snapcraft/craftctl default + uv export --no-dev --no-emit-workspace --output-file uv-requirements.txt + ${SNAP}/libexec/snapcraft/craftctl default - version=$(PYTHONPATH=$CRAFT_PART_INSTALL/lib/python3.12/site-packages python3 -c "import snapcraft;print(snapcraft.__version__)") - ${SNAP}/libexec/snapcraft/craftctl set version="$version" + version=$(PYTHONPATH=$CRAFT_PART_INSTALL/lib/python3.12/site-packages python3 -c "import snapcraft;print(snapcraft.__version__)") + ${SNAP}/libexec/snapcraft/craftctl set version="$version" - [ -n "$(echo $version | grep "+git")" ] && grade=devel || grade=stable - sed -i -e '1 s|^#!/.*|#!/snap/snapcraft/current/bin/python -E|' $SNAPCRAFT_PART_INSTALL/bin/craftctl - ${SNAP}/libexec/snapcraft/craftctl set grade="$grade" + [ -n "$(echo $version | grep "+git")" ] && grade=devel || grade=stable + sed -i -e '1 s|^#!/.*|#!/snap/snapcraft/current/bin/python -E|' $SNAPCRAFT_PART_INSTALL/bin/craftctl + ${SNAP}/libexec/snapcraft/craftctl set grade="$grade" - # The new implementation still requires this. - ln -sf ../usr/bin/python3.12 $SNAPCRAFT_PART_INSTALL/bin/python3 + # The new implementation still requires this. + ln -sf ../usr/bin/python3.12 $SNAPCRAFT_PART_INSTALL/bin/python3 after: [snapcraft-libs, libgit2] chisel: diff --git a/snapcraft/commands/status.py b/snapcraft/commands/status.py index bdb55059f3..b38ec25b77 100644 --- a/snapcraft/commands/status.py +++ b/snapcraft/commands/status.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Snapcraft Store Account management commands.""" + import itertools import operator import textwrap diff --git a/snapcraft/commands/validation_sets.py b/snapcraft/commands/validation_sets.py index d310d3aeeb..0791166303 100644 --- a/snapcraft/commands/validation_sets.py +++ b/snapcraft/commands/validation_sets.py @@ -210,11 +210,13 @@ def edit_validation_sets( try: with validation_sets_path.open() as file: data = craft_application.util.safe_yaml_load(file) - edited_validation_sets = validation_sets.EditableBuildAssertion.from_yaml_data( - data=data, - # filepath is only shown for pydantic errors and snapcraft should - # not expose the temp file name - filepath=Path("validation-sets"), + edited_validation_sets = ( + validation_sets.EditableBuildAssertion.from_yaml_data( + data=data, + # filepath is only shown for pydantic errors and snapcraft should + # not expose the temp file name + filepath=Path("validation-sets"), + ) ) return edited_validation_sets except (yaml.YAMLError, CraftValidationError) as err: diff --git a/snapcraft/extensions/_ros2_humble_meta.py b/snapcraft/extensions/_ros2_humble_meta.py index 3d23330d71..c84bcd9d32 100644 --- a/snapcraft/extensions/_ros2_humble_meta.py +++ b/snapcraft/extensions/_ros2_humble_meta.py @@ -72,9 +72,9 @@ def get_app_snippet(self, *, app_name: str) -> Dict[str, Any]: "$SNAP/opt/ros/underlay_ws/usr/lib/python3/dist-packages", ] - app_snippet["environment"][ - "PYTHONPATH" - ] = f'{python_paths}:{":".join(new_python_paths)}' + app_snippet["environment"]["PYTHONPATH"] = ( + f"{python_paths}:{':'.join(new_python_paths)}" + ) return app_snippet diff --git a/snapcraft/extensions/_ros2_jazzy_meta.py b/snapcraft/extensions/_ros2_jazzy_meta.py index b230119661..f0c0f0f4aa 100644 --- a/snapcraft/extensions/_ros2_jazzy_meta.py +++ b/snapcraft/extensions/_ros2_jazzy_meta.py @@ -72,9 +72,9 @@ def get_app_snippet(self, *, app_name: str) -> Dict[str, Any]: "$SNAP/opt/ros/underlay_ws/usr/lib/python3/dist-packages", ] - app_snippet["environment"][ - "PYTHONPATH" - ] = f'{python_paths}:{":".join(new_python_paths)}' + app_snippet["environment"]["PYTHONPATH"] = ( + f"{python_paths}:{':'.join(new_python_paths)}" + ) return app_snippet diff --git a/snapcraft/extensions/gnome.py b/snapcraft/extensions/gnome.py index 0f0c3be7ab..22e44115cc 100644 --- a/snapcraft/extensions/gnome.py +++ b/snapcraft/extensions/gnome.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Generic GNOME extension to support core22 and onwards.""" + import dataclasses import functools import re diff --git a/snapcraft/extensions/kde_neon.py b/snapcraft/extensions/kde_neon.py index 17eaf8e322..550846f0fe 100644 --- a/snapcraft/extensions/kde_neon.py +++ b/snapcraft/extensions/kde_neon.py @@ -16,6 +16,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Generic KDE NEON extension to support core22 and onwards.""" + import dataclasses import functools import re diff --git a/snapcraft/linters/library_linter.py b/snapcraft/linters/library_linter.py index e3c2c9d82b..4d65a5cca1 100644 --- a/snapcraft/linters/library_linter.py +++ b/snapcraft/linters/library_linter.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Library linter implementation.""" + import re import subprocess from pathlib import Path diff --git a/snapcraft/meta/snap_yaml.py b/snapcraft/meta/snap_yaml.py index dcd8a3a814..09e188dac0 100644 --- a/snapcraft/meta/snap_yaml.py +++ b/snapcraft/meta/snap_yaml.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Create snap.yaml metadata file.""" + from __future__ import annotations import re @@ -560,7 +561,7 @@ def _populate_environment( def _process_components( - components: dict[str, models.Component] | None + components: dict[str, models.Component] | None, ) -> dict[str, ComponentMetadata] | None: """Convert Components from a project to ComponentMetadata for a snap.yaml. diff --git a/snapcraft/plugins/v2/__init__.py b/snapcraft/plugins/v2/__init__.py index b10899a060..5960f3e239 100644 --- a/snapcraft/plugins/v2/__init__.py +++ b/snapcraft/plugins/v2/__init__.py @@ -16,7 +16,6 @@ """Legacy support for v2 plugins.""" - from snapcraft_legacy.plugins.v2 import ( AutotoolsPlugin, CatkinPlugin, diff --git a/snapcraft/providers.py b/snapcraft/providers.py index ae050a3bf3..a521e5a3af 100644 --- a/snapcraft/providers.py +++ b/snapcraft/providers.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Snapcraft-specific code to interface with craft-providers.""" + import io import os import sys diff --git a/snapcraft/snap_config.py b/snapcraft/snap_config.py index 9f5d1620ea..e68815d7ab 100644 --- a/snapcraft/snap_config.py +++ b/snapcraft/snap_config.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Snap config file definitions and helpers.""" + from typing import Annotated, Literal, Optional import craft_application.models diff --git a/snapcraft/store/__init__.py b/snapcraft/store/__init__.py index 6c6c5d77af..1088aba640 100644 --- a/snapcraft/store/__init__.py +++ b/snapcraft/store/__init__.py @@ -16,7 +16,6 @@ """Snapcraft CLI interface for the Snap Store.""" - from . import constants from ._legacy_account import LegacyUbuntuOne from .channel_map import ChannelMap diff --git a/snapcraft/store/client.py b/snapcraft/store/client.py index 8be1737c3d..cc004fa6e3 100644 --- a/snapcraft/store/client.py +++ b/snapcraft/store/client.py @@ -99,9 +99,7 @@ def _prompt_login() -> Tuple[str, str]: def _get_hostname( - hostname: Optional[ - str - ] = platform.node(), # noqa: B008 Function call in arg defaults + hostname: Optional[str] = platform.node(), # noqa: B008 Function call in arg defaults ) -> str: """Return the computer's network name or UNNKOWN if it cannot be determined.""" if not hostname: @@ -641,8 +639,7 @@ def notify_upload( # noqa: PLR0913[too-many-arguments] "Components are currently unsupported for on-prem stores" ) emit.debug( - f"Ignoring snap_file_size of {snap_file_size!r} and " - f"built_at {built_at!r}" + f"Ignoring snap_file_size of {snap_file_size!r} and built_at {built_at!r}" ) revision_request = cast( diff --git a/snapcraft/utils.py b/snapcraft/utils.py index 9d9acc7646..b6c3ae7ed6 100644 --- a/snapcraft/utils.py +++ b/snapcraft/utils.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Utilities for snapcraft.""" + from __future__ import annotations import multiprocessing diff --git a/snapcraft_legacy/_store.py b/snapcraft_legacy/_store.py index 7bce81fe48..6f2289fba6 100644 --- a/snapcraft_legacy/_store.py +++ b/snapcraft_legacy/_store.py @@ -430,9 +430,7 @@ def list_keys(): headers=["", "Name", "SHA3-384 fingerprint", ""], tablefmt="plain", ) - print( - "The following keys are available on this system:" - ) + print("The following keys are available on this system:") print(tabulated_keys) else: print( @@ -502,9 +500,9 @@ def wrapped_env(*args, **kwargs): return func(*args, **kwargs) finally: if credentials: - os.environ[ - storeapi.constants.ENVIRONMENT_STORE_CREDENTIALS - ] = credentials + os.environ[storeapi.constants.ENVIRONMENT_STORE_CREDENTIALS] = ( + credentials + ) return wrapped_env diff --git a/snapcraft_legacy/cli/_channel_map.py b/snapcraft_legacy/cli/_channel_map.py index 6f01bb3974..035f177697 100644 --- a/snapcraft_legacy/cli/_channel_map.py +++ b/snapcraft_legacy/cli/_channel_map.py @@ -111,10 +111,10 @@ def _get_channel_lines_for_channel( # noqa: C901 channel_info = snap_channel_map.get_channel_info(channel_name) try: - progressive_mapped_channel: Optional[ - MappedChannel - ] = snap_channel_map.get_mapped_channel( - channel_name=channel_name, architecture=architecture, progressive=True + progressive_mapped_channel: Optional[MappedChannel] = ( + snap_channel_map.get_mapped_channel( + channel_name=channel_name, architecture=architecture, progressive=True + ) ) except ValueError: progressive_mapped_channel = None diff --git a/snapcraft_legacy/cli/_errors.py b/snapcraft_legacy/cli/_errors.py index 3ced16ad13..c35519e227 100644 --- a/snapcraft_legacy/cli/_errors.py +++ b/snapcraft_legacy/cli/_errors.py @@ -283,10 +283,7 @@ def _print_trace_output(exc_info, file=sys.stdout) -> None: def _is_send_to_sentry(exc_info) -> bool: # noqa: C901 # Check to see if error reporting has been disabled - if ( - strtobool(os.getenv("SNAPCRAFT_ENABLE_ERROR_REPORTING", "y")) - == 0 - ): + if strtobool(os.getenv("SNAPCRAFT_ENABLE_ERROR_REPORTING", "y")) == 0: return False # Check the environment to see if we should allow for silent reporting @@ -384,6 +381,6 @@ def _submit_trace(exc_info): "raven.processors.RemoveStackLocalsProcessor", "raven.processors.SanitizePasswordsProcessor", ), - **kwargs + **kwargs, ) client.captureException(exc_info=exc_info) diff --git a/snapcraft_legacy/cli/_review.py b/snapcraft_legacy/cli/_review.py index e7690dfa93..c16ad89a07 100644 --- a/snapcraft_legacy/cli/_review.py +++ b/snapcraft_legacy/cli/_review.py @@ -27,7 +27,7 @@ def review_snap(*, snap_file: str) -> None: # Review the snap. if review_tools.is_available(): echo.info( - "Running the review tools before pushing this snap to the Snap " "Store." + "Running the review tools before pushing this snap to the Snap Store." ) # TODO just raise when we can override. try: diff --git a/snapcraft_legacy/cli/_runner.py b/snapcraft_legacy/cli/_runner.py index d01c4bb5cf..0154d67b95 100644 --- a/snapcraft_legacy/cli/_runner.py +++ b/snapcraft_legacy/cli/_runner.py @@ -86,7 +86,8 @@ def configure_requests_ca() -> None: context_settings=dict(help_option_names=["-h", "--help"]), ) @click.version_option( - message=SNAPCRAFT_VERSION_TEMPLATE, version=snapcraft_legacy.__version__ # type: ignore + message=SNAPCRAFT_VERSION_TEMPLATE, + version=snapcraft_legacy.__version__, # type: ignore ) @click.pass_context @add_provider_options(hidden=True) diff --git a/snapcraft_legacy/cli/echo.py b/snapcraft_legacy/cli/echo.py index ade1831393..495dfb6859 100644 --- a/snapcraft_legacy/cli/echo.py +++ b/snapcraft_legacy/cli/echo.py @@ -18,6 +18,7 @@ These methods, which are named after common logging levels, wrap around click.echo adding the corresponding color codes for each level. """ + import os import shutil import sys @@ -92,7 +93,7 @@ def exit_error( resolution: Optional[str] = None, details: Optional[str] = None, docs_url: Optional[str] = None, - exit_code: int = 2 + exit_code: int = 2, ): """Display an error and gracefully exit.""" message_parts = [brief] diff --git a/snapcraft_legacy/cli/lifecycle.py b/snapcraft_legacy/cli/lifecycle.py index 4bac289da8..6adf09a51f 100644 --- a/snapcraft_legacy/cli/lifecycle.py +++ b/snapcraft_legacy/cli/lifecycle.py @@ -107,7 +107,9 @@ def _execute( # noqa: C901 # validate experimental plugins plugins = [part.plugin for part in project_config.parts.all_parts] - if not kwargs.get("enable_experimental_plugins") and any(isinstance(plugin, KernelPlugin) for plugin in plugins): + if not kwargs.get("enable_experimental_plugins") and any( + isinstance(plugin, KernelPlugin) for plugin in plugins + ): raise SnapcraftEnvironmentError( "*EXPERIMENTAL* 'kernel' plugin used, but not enabled. " "Enable with '--enable-experimental-plugins' flag." diff --git a/snapcraft_legacy/cli/store.py b/snapcraft_legacy/cli/store.py index 75ca04c09e..f6fc3cb125 100644 --- a/snapcraft_legacy/cli/store.py +++ b/snapcraft_legacy/cli/store.py @@ -68,9 +68,7 @@ def _human_readable_acls(store_client: storeapi.StoreClient) -> str: channels: {channels} permissions: {permissions} expires: {expires} - """.format( - **human_readable_acl - ) + """.format(**human_readable_acl) ) diff --git a/snapcraft_legacy/extractors/_errors.py b/snapcraft_legacy/extractors/_errors.py index 9d3ee346bb..ffc6e155e3 100644 --- a/snapcraft_legacy/extractors/_errors.py +++ b/snapcraft_legacy/extractors/_errors.py @@ -18,7 +18,6 @@ class UnhandledFileError(MetadataExtractionError): - fmt = ( "Failed to extract metadata from {path!r}: " "This file is not handled by {extractor_name!r}." @@ -29,7 +28,6 @@ def __init__(self, path: str, extractor_name: str) -> None: class AppstreamFileParseError(MetadataExtractionError): - fmt = "Failed to extract metadata from {path!r}: it's not a valid XML file." def __init__(self, path: str) -> None: @@ -37,7 +35,6 @@ def __init__(self, path: str) -> None: class SetupPyFileParseError(MetadataExtractionError): - fmt = ( "Failed to extract metadata from {path!r}: " "the logic in setup.py is currently not handled." @@ -48,7 +45,6 @@ def __init__(self, path: str) -> None: class SetupPyImportError(MetadataExtractionError): - fmt = ( "Failed to extract metadata from {path!r}: " "some packages or modules used could not be imported: " diff --git a/snapcraft_legacy/extractors/_metadata.py b/snapcraft_legacy/extractors/_metadata.py index 5678ea8112..3a1fc967c3 100644 --- a/snapcraft_legacy/extractors/_metadata.py +++ b/snapcraft_legacy/extractors/_metadata.py @@ -34,7 +34,7 @@ def __init__( version: Optional[str] = None, grade: Optional[str] = None, icon: Optional[str] = None, - desktop_file_paths: Optional[List[str]] = None + desktop_file_paths: Optional[List[str]] = None, ) -> None: """Create a new ExtractedMetadata instance. diff --git a/snapcraft_legacy/file_utils.py b/snapcraft_legacy/file_utils.py index 2689c6e9d6..54e61853a9 100644 --- a/snapcraft_legacy/file_utils.py +++ b/snapcraft_legacy/file_utils.py @@ -197,8 +197,9 @@ def link_or_copy_tree( os.path.exists(destination_tree) or os.path.islink(destination_tree) ): raise errors.SnapcraftEnvironmentError( - "Cannot overwrite non-directory {!r} with directory " - "{!r}".format(destination_tree, source_tree) + "Cannot overwrite non-directory {!r} with directory {!r}".format( + destination_tree, source_tree + ) ) create_similar_directory(source_tree, destination_tree) diff --git a/snapcraft_legacy/internal/build_providers/_base_provider.py b/snapcraft_legacy/internal/build_providers/_base_provider.py index d401878e53..f624afca18 100644 --- a/snapcraft_legacy/internal/build_providers/_base_provider.py +++ b/snapcraft_legacy/internal/build_providers/_base_provider.py @@ -45,7 +45,6 @@ def _get_platform() -> str: class Provider(abc.ABC): - _INSTANCE_PROJECT_DIR = "~/project" def __init__( diff --git a/snapcraft_legacy/internal/build_providers/_multipass/_windows.py b/snapcraft_legacy/internal/build_providers/_multipass/_windows.py index f6a93fb8a0..6ecfd29ef5 100644 --- a/snapcraft_legacy/internal/build_providers/_multipass/_windows.py +++ b/snapcraft_legacy/internal/build_providers/_multipass/_windows.py @@ -92,9 +92,7 @@ def _run_installer(installer_path: str, echoer): [Environment]::Exit(1) }} }} - """.format( - path=installer_path - ) + """.format(path=installer_path) try: subprocess.check_call(["powershell.exe", "-Command", cmd]) diff --git a/snapcraft_legacy/internal/build_providers/_snap.py b/snapcraft_legacy/internal/build_providers/_snap.py index 28a9d757f1..36f8e42db6 100644 --- a/snapcraft_legacy/internal/build_providers/_snap.py +++ b/snapcraft_legacy/internal/build_providers/_snap.py @@ -56,7 +56,7 @@ def __init__( snap_name: str, remote_snap_dir: str, latest_revision: Optional[str], - inject_from_host: bool = True + inject_from_host: bool = True, ) -> None: # name of the snap instance, which may have an alias self.snap_instance_name = snap_name @@ -137,7 +137,9 @@ def push_host_snap(self, *, file_pusher: Callable[..., None]) -> None: # TODO not being able to lock down on a snap revision can lead to races. host_snap_repo = self._get_snap_repo() with tempfile.TemporaryDirectory() as temp_dir: - snap_file_path = os.path.join(temp_dir, "{}.snap".format(self.snap_instance_name)) + snap_file_path = os.path.join( + temp_dir, "{}.snap".format(self.snap_instance_name) + ) assertion_file_path = os.path.join( temp_dir, "{}.assert".format(self.snap_instance_name) ) @@ -170,7 +172,11 @@ def _set_data(self) -> None: if not snap_revision.startswith("x") and snap_channel: switch_cmd = [ - "snap", "switch", self.snap_name, "--channel", snap_channel + "snap", + "switch", + self.snap_name, + "--channel", + snap_channel, ] if snap_revision.startswith("x"): @@ -304,7 +310,7 @@ def __init__( registry_filepath: str, runner: Callable[..., Optional[bytes]], file_pusher: Callable[..., None], - inject_from_host: bool = True + inject_from_host: bool = True, ) -> None: """ Initialize a SnapInjector instance. diff --git a/snapcraft_legacy/internal/build_providers/errors.py b/snapcraft_legacy/internal/build_providers/errors.py index 18e62d45b4..372d183819 100644 --- a/snapcraft_legacy/internal/build_providers/errors.py +++ b/snapcraft_legacy/internal/build_providers/errors.py @@ -27,7 +27,6 @@ class ProviderBaseError(_SnapcraftError): class ProviderNotSupportedError(ProviderBaseError): - fmt = ( "The {provider!r} provider is not supported, please choose a " "different one and try again." @@ -38,7 +37,6 @@ def __init__(self, *, provider: str) -> None: class ProviderNotFound(ProviderBaseError): - fmt = "You need {provider!r} set-up to build snaps: {error_message}." def __init__( @@ -54,7 +52,6 @@ def __init__( class _GenericProviderError(ProviderBaseError): - _FMT_ERROR_MESSAGE_AND_EXIT_CODE = ( "An error occurred with the instance when trying to {action} with " "{provider_name!r}: returned exit code {exit_code!r}: {error_message}.\n" @@ -101,7 +98,6 @@ def __init__( class ProviderCommunicationError(ProviderBaseError): - fmt = ( "An error occurred when trying to communicate with the " "{provider_name!r} provider: {message}." @@ -191,7 +187,6 @@ def __init__( class ProviderExecError(ProviderBaseError): - fmt = ( "An error occurred when trying to execute {command_string!r} with " "{provider_name!r}: returned exit code {exit_code!r}." @@ -280,7 +275,6 @@ def __init__( class ProviderInfoError(ProviderBaseError): - fmt = ( "An error occurred when using {provider_name!r} to " "query the status of the instance: returned exit code {exit_code!r}: {stderr!s}." @@ -293,7 +287,6 @@ def __init__(self, *, provider_name: str, exit_code: int, stderr: bytes) -> None class ProviderInstanceNotFoundError(ProviderBaseError): - fmt = "Cannot find an instance named {instance_name!r}." def __init__(self, *, instance_name: str) -> None: @@ -301,7 +294,6 @@ def __init__(self, *, instance_name: str) -> None: class ProviderInfoDataKeyError(ProviderBaseError): - fmt = ( "The data returned by {provider_name!r} was not expected. " "It is missing a required key {missing_key!r} in {data!r}." @@ -316,7 +308,6 @@ def __init__( class ProviderBadDataError(ProviderBaseError): - fmt = ( "The data returned by {provider_name!r} was not expected " "or in the wrong format: {data!r}." diff --git a/snapcraft_legacy/internal/common.py b/snapcraft_legacy/internal/common.py index 33f7f26e37..b3d40c2656 100644 --- a/snapcraft_legacy/internal/common.py +++ b/snapcraft_legacy/internal/common.py @@ -180,8 +180,9 @@ def is_snap() -> bool: snap_name = os.environ.get("SNAP_NAME", "") is_snap = snap_name == "snapcraft" logger.debug( - "snapcraft is running as a snap {!r}, " - "SNAP_NAME set to {!r}".format(is_snap, snap_name) + "snapcraft is running as a snap {!r}, SNAP_NAME set to {!r}".format( + is_snap, snap_name + ) ) return is_snap diff --git a/snapcraft_legacy/internal/deltas/_deltas.py b/snapcraft_legacy/internal/deltas/_deltas.py index ee67f57a43..ef0293f0c5 100644 --- a/snapcraft_legacy/internal/deltas/_deltas.py +++ b/snapcraft_legacy/internal/deltas/_deltas.py @@ -49,7 +49,7 @@ def __init__( target_path: str, delta_tool: str, delta_format: str, - delta_file_extname: str = "delta" + delta_file_extname: str = "delta", ) -> None: self.source_path = source_path self.target_path = target_path diff --git a/snapcraft_legacy/internal/elf.py b/snapcraft_legacy/internal/elf.py index dc6c07b28d..dbda03dc85 100644 --- a/snapcraft_legacy/internal/elf.py +++ b/snapcraft_legacy/internal/elf.py @@ -240,7 +240,6 @@ def __init__( arch: ElfArchitectureTuple, soname_cache: SonameCache, ) -> None: - self.soname = soname self.soname_path = soname_path self.search_paths = search_paths diff --git a/snapcraft_legacy/internal/errors.py b/snapcraft_legacy/internal/errors.py index c787ea8cdf..adaec1cb23 100644 --- a/snapcraft_legacy/internal/errors.py +++ b/snapcraft_legacy/internal/errors.py @@ -253,7 +253,6 @@ def __init__( class PrimeFileConflictError(SnapcraftError): - fmt = ( "Failed to filter files: " "The following files have been excluded by the `stage` keyword, " @@ -264,10 +263,8 @@ class PrimeFileConflictError(SnapcraftError): class PluginError(SnapcraftError): - fmt = ( - "Failed to load plugin: " - "{message}" + "Failed to load plugin: {message}" # FIXME include how to fix each of the possible plugin errors. # https://bugs.launchpad.net/snapcraft/+bug/1727484 # --elopio - 2017-10-25 @@ -295,7 +292,6 @@ def __init__( class SnapcraftPartConflictError(SnapcraftError): - fmt = ( "Failed to stage: " "Parts {other_part_name!r} and {part_name!r} have the following " @@ -321,7 +317,6 @@ def __init__(self, *, part_name, other_part_name, conflict_files): class SnapcraftOrganizeError(SnapcraftError): - fmt = "Failed to organize part {part_name!r}: {message}" def __init__(self, part_name, message): @@ -329,10 +324,8 @@ def __init__(self, part_name, message): class InvalidWikiEntryError(SnapcraftError): - fmt = ( - "Invalid wiki entry: " - "{error!r}" + "Invalid wiki entry: {error!r}" # FIXME include how to fix each of the possible wiki errors. # https://bugs.launchpad.net/snapcraft/+bug/1727490 # --elopio - 2017-10-25 @@ -343,7 +336,6 @@ def __init__(self, error=None): class MissingGadgetError(SnapcraftError): - fmt = ( "Failed to generate snap metadata: " "Missing gadget.yaml file.\n" @@ -356,7 +348,6 @@ class MissingGadgetError(SnapcraftError): class PluginOutdatedError(SnapcraftError): - fmt = "This plugin is outdated: {message}" def __init__(self, message): @@ -364,7 +355,6 @@ def __init__(self, message): class ToolMissingError(SnapcraftReportableError): - fmt = ( "A tool snapcraft depends on could not be found: {command_name!r}.\n" "Ensure the tool is installed and available, and try again." @@ -375,22 +365,18 @@ def __init__(self, *, command_name: str) -> None: class RequiredCommandFailure(SnapcraftError): - fmt = "{command!r} failed." class RequiredCommandNotFound(SnapcraftError): - fmt = "{cmd_list[0]!r} not found." class RequiredPathDoesNotExist(SnapcraftError): - fmt = "Required path does not exist: {path!r}" class SnapcraftPathEntryError(SnapcraftError): - fmt = ( "Failed to generate snap metadata: " "The path {value!r} set for {key!r} in {app!r} does not exist. " @@ -399,7 +385,6 @@ class SnapcraftPathEntryError(SnapcraftError): class InvalidPullPropertiesError(SnapcraftError): - fmt = ( "Failed to load plugin: " "Invalid pull properties specified by {plugin_name!r} plugin: " @@ -413,7 +398,6 @@ def __init__(self, plugin_name, properties): class InvalidBuildPropertiesError(SnapcraftError): - fmt = ( "Failed to load plugin: " "Invalid build properties specified by {plugin_name!r} plugin: " @@ -427,7 +411,6 @@ def __init__(self, plugin_name, properties): class StagePackageDownloadError(SnapcraftError): - fmt = ( "Failed to fetch stage packages: " "Error downloading packages for part {part_name!r}: {message}." @@ -438,27 +421,22 @@ def __init__(self, part_name, message): class OsReleaseIdError(SnapcraftError): - fmt = "Unable to determine host OS ID" class OsReleaseNameError(SnapcraftError): - fmt = "Unable to determine host OS name" class OsReleaseVersionIdError(SnapcraftError): - fmt = "Unable to determine host OS version ID" class OsReleaseCodenameError(SnapcraftError): - fmt = "Unable to determine host OS version codename" class InvalidContainerImageInfoError(SnapcraftError): - fmt = ( "Failed to parse container image info: " "SNAPCRAFT_IMAGE_INFO is not a valid JSON string: {image_info}" @@ -473,7 +451,6 @@ class PatcherError(SnapcraftError): class PatcherGenericError(PatcherError): - fmt = ( "{elf_file!r} cannot be patched to function properly in a classic " "confined snap: {message}" @@ -487,7 +464,6 @@ def __init__(self, *, elf_file, process_exception): class PatcherNewerPatchelfError(PatcherError): - fmt = ( "{elf_file!r} cannot be patched to function properly in a classic " "confined snap: {message}.\n" @@ -509,7 +485,6 @@ def __init__(self, *, elf_file, process_exception, patchelf_version): class StagePackageMissingError(SnapcraftError): - fmt = ( "{package!r} is required inside the snap for this part to work " "properly.\n" @@ -525,7 +500,6 @@ class MetadataExtractionError(SnapcraftError): class MissingMetadataFileError(MetadataExtractionError): - fmt = ( "Failed to generate snap metadata: " "Part {part_name!r} has a 'parse-info' referring to metadata file " @@ -537,7 +511,6 @@ def __init__(self, part_name: str, path: str) -> None: class UnhandledMetadataFileTypeError(MetadataExtractionError): - fmt = ( "Failed to extract metadata from {path!r}: " "This type of file is not supported for supplying metadata." @@ -548,7 +521,6 @@ def __init__(self, path: str) -> None: class InvalidExtractorValueError(MetadataExtractionError): - fmt = ( "Failed to extract metadata from {path!r}: " "Extractor {extractor_name!r} didn't return ExtractedMetadata as " @@ -645,7 +617,6 @@ def __init__(self, message: str) -> None: class SnapcraftInvalidCLIConfigError(SnapcraftError): - fmt = "The cli configuration file {config_file!r} has invalid data: {error!r}." def __init__(self, *, config_file: str, error: str) -> None: diff --git a/snapcraft_legacy/internal/lifecycle/_clean.py b/snapcraft_legacy/internal/lifecycle/_clean.py index a6cb4fba93..9a68a7bd8f 100644 --- a/snapcraft_legacy/internal/lifecycle/_clean.py +++ b/snapcraft_legacy/internal/lifecycle/_clean.py @@ -69,8 +69,7 @@ def _clean_parts(part_names, step, config, staged_state, primed_state): parts_not_being_cleaned = dirty_part_names.difference(part_names) if parts_not_being_cleaned: logger.warning( - "Cleaned {!r}, which makes the following {} out of date: " - "{}".format( + "Cleaned {!r}, which makes the following {} out of date: {}".format( part_name, formatting_utils.pluralize( parts_not_being_cleaned, "part", "parts" diff --git a/snapcraft_legacy/internal/meta/application.py b/snapcraft_legacy/internal/meta/application.py index 2915828c51..9cf598dacf 100644 --- a/snapcraft_legacy/internal/meta/application.py +++ b/snapcraft_legacy/internal/meta/application.py @@ -50,7 +50,7 @@ def __init__( install_mode: str = None, command_chain: List[str] = None, passthrough: Dict[str, Any] = None, - commands: Dict[str, Command] = None + commands: Dict[str, Command] = None, ) -> None: """Initialize an application entry. diff --git a/snapcraft_legacy/internal/meta/errors.py b/snapcraft_legacy/internal/meta/errors.py index a98565ee58..ff54d1a247 100644 --- a/snapcraft_legacy/internal/meta/errors.py +++ b/snapcraft_legacy/internal/meta/errors.py @@ -30,7 +30,6 @@ class SnapMetaGenerationError(errors.SnapcraftError): class MissingSnapcraftYamlKeysError(SnapMetaGenerationError): - fmt = ( "Failed to generate snap metadata: " "Missing required key(s) in snapcraft.yaml: {keys}. " @@ -43,7 +42,6 @@ def __init__(self, keys: List[str]) -> None: class AdoptedPartMissingError(SnapMetaGenerationError): - fmt = ( "Failed to generate snap metadata: " "'adopt-info' refers to a part named {part!r}, but it is not defined " @@ -55,7 +53,6 @@ def __init__(self, part: str) -> None: class AdoptedPartNotParsingInfo(SnapMetaGenerationError): - fmt = ( "Failed to generate snap metadata: " "'adopt-info' refers to part {part!r}, but that part is lacking the " @@ -67,7 +64,6 @@ def __init__(self, part: str) -> None: class AmbiguousPassthroughKeyError(SnapMetaGenerationError): - fmt = ( "Failed to generate snap metadata: " "The following keys are specified in their regular location " @@ -80,7 +76,6 @@ def __init__(self, keys: List[str]) -> None: class InvalidAppCommandError(errors.SnapcraftError): - fmt = ( "Failed to generate snap metadata: " "The specified command {command!r} defined in the app {app_name!r} does " @@ -93,7 +88,6 @@ def __init__(self, command, app_name): class InvalidAppCommandNotFound(errors.SnapcraftError): - fmt = ( "Failed to generate snap metadata: " "The specified command {command!r} defined in the app {app_name!r} does " @@ -106,7 +100,6 @@ def __init__(self, command, app_name): class InvalidAppCommandNotExecutable(errors.SnapcraftError): - fmt = ( "Failed to generate snap metadata: " "The specified command {command!r} defined in the app {app_name!r} " @@ -118,7 +111,6 @@ def __init__(self, command: str, app_name: str) -> None: class InvalidAppCommandFormatError(errors.SnapcraftError): - fmt = ( "Failed to generate snap metadata: " "The specified command {command!r} defined in the app {app_name!r} does " @@ -132,7 +124,6 @@ def __init__(self, command: str, app_name: str) -> None: class InvalidCommandChainError(errors.SnapcraftError): - fmt = ( "Failed to generate snap metadata: " "The command-chain item {item!r} defined in the app {app_name!r} does " @@ -145,10 +136,8 @@ def __init__(self, item: str, app_name: str) -> None: class InvalidDesktopFileError(errors.SnapcraftError): - fmt = ( - "Failed to generate desktop file: " - "Invalid desktop file {filename!r}: {message}." + "Failed to generate desktop file: Invalid desktop file {filename!r}: {message}." # FIXME include how to fix each of the possible desktop file errors. # https://bugs.launchpad.net/snapcraft/+bug/1727435 # --elopio - 2017-10-25 diff --git a/snapcraft_legacy/internal/meta/package_repository.py b/snapcraft_legacy/internal/meta/package_repository.py index b5cbe3126f..5079e28e17 100644 --- a/snapcraft_legacy/internal/meta/package_repository.py +++ b/snapcraft_legacy/internal/meta/package_repository.py @@ -27,8 +27,7 @@ class PackageRepository(abc.ABC): @abc.abstractmethod - def marshal(self) -> Dict[str, Any]: - ... + def marshal(self) -> Dict[str, Any]: ... @classmethod def unmarshal(cls, data: Dict[str, str]) -> "PackageRepository": diff --git a/snapcraft_legacy/internal/meta/plugs.py b/snapcraft_legacy/internal/meta/plugs.py index 7a7845283f..37893ab1cf 100644 --- a/snapcraft_legacy/internal/meta/plugs.py +++ b/snapcraft_legacy/internal/meta/plugs.py @@ -155,7 +155,7 @@ def validate(self) -> None: message=( "Specifying a snap channel in 'default_provider' is not supported: " f"{self._default_provider}" - ) + ), ) @classmethod diff --git a/snapcraft_legacy/internal/mountinfo.py b/snapcraft_legacy/internal/mountinfo.py index 5aea923ef7..616570b66f 100644 --- a/snapcraft_legacy/internal/mountinfo.py +++ b/snapcraft_legacy/internal/mountinfo.py @@ -58,9 +58,7 @@ def __init__(self, *, mountinfo_file: str = "/proc/self/mountinfo") -> None: # Maintain two dicts pointing to the same underlying objects: # a dict of mount points to Mounts, and a dict of roots to Mounts. self._mount_point_mounts = {} # type: Dict[str, Mount] - root_mounts = collections.defaultdict( - list - ) # type: Dict[str, List[Mount]] # noqa + root_mounts = collections.defaultdict(list) # type: Dict[str, List[Mount]] # noqa with contextlib.suppress(FileNotFoundError): with open(mountinfo_file) as f: diff --git a/snapcraft_legacy/internal/pluginhandler/__init__.py b/snapcraft_legacy/internal/pluginhandler/__init__.py index e388f6a847..14c766a3dd 100644 --- a/snapcraft_legacy/internal/pluginhandler/__init__.py +++ b/snapcraft_legacy/internal/pluginhandler/__init__.py @@ -771,8 +771,9 @@ def _get_machine_manifest(self): ) except subprocess.CalledProcessError as e: logger.warning( - "'uname' exited with code {}: unable to record machine " - "manifest".format(e.returncode) + "'uname' exited with code {}: unable to record machine manifest".format( + e.returncode + ) ) return {} diff --git a/snapcraft_legacy/internal/pluginhandler/_dirty_report.py b/snapcraft_legacy/internal/pluginhandler/_dirty_report.py index a708d2b249..6620cb81ad 100644 --- a/snapcraft_legacy/internal/pluginhandler/_dirty_report.py +++ b/snapcraft_legacy/internal/pluginhandler/_dirty_report.py @@ -50,7 +50,7 @@ def __init__( *, dirty_properties: StrCollection = None, dirty_project_options: StrCollection = None, - changed_dependencies: DependencyCollection = None + changed_dependencies: DependencyCollection = None, ) -> None: """Create a new DirtyReport. diff --git a/snapcraft_legacy/internal/pluginhandler/_runner.py b/snapcraft_legacy/internal/pluginhandler/_runner.py index 54e7423031..d6878dbe5a 100644 --- a/snapcraft_legacy/internal/pluginhandler/_runner.py +++ b/snapcraft_legacy/internal/pluginhandler/_runner.py @@ -203,8 +203,9 @@ def _handle_builtin_function(self, scriptlet_name, function_call) -> None: # This means a snapcraft developer messed up adding a new # snapcraftctl function. Should never be encountered in real life. raise ValueError( - "{!r} scriptlet called a function with invalid json: " - "{}".format(scriptlet_name, function_call) + "{!r} scriptlet called a function with invalid json: {}".format( + scriptlet_name, function_call + ) ) from e try: @@ -226,8 +227,9 @@ def _handle_builtin_function(self, scriptlet_name, function_call) -> None: # This means a snapcraft developer messed up adding a new # snapcraftctl function. Should never be encountered in real life. raise ValueError( - "{!r} scriptlet called an undefined builtin function: " - "{}".format(scriptlet_name, function_name) + "{!r} scriptlet called an undefined builtin function: {}".format( + scriptlet_name, function_name + ) ) from e function(**function_args) diff --git a/snapcraft_legacy/internal/project_loader/__init__.py b/snapcraft_legacy/internal/project_loader/__init__.py index 9c15fe124c..5cbac6f08c 100644 --- a/snapcraft_legacy/internal/project_loader/__init__.py +++ b/snapcraft_legacy/internal/project_loader/__init__.py @@ -88,7 +88,7 @@ def _validate_replacement(attr: str, variable: str, value: Optional[str]) -> Non # expand to shell syntax for variables (`$item` and `${item}`) expanded_variables_to_validate = ( - *(f"${item}" for item in variables_to_validate ), + *(f"${item}" for item in variables_to_validate), *(f"${{{item}}}" for item in variables_to_validate), ) diff --git a/snapcraft_legacy/internal/project_loader/_extensions/_ros1_noetic_meta.py b/snapcraft_legacy/internal/project_loader/_extensions/_ros1_noetic_meta.py index 21bc40638f..f979dc6107 100644 --- a/snapcraft_legacy/internal/project_loader/_extensions/_ros1_noetic_meta.py +++ b/snapcraft_legacy/internal/project_loader/_extensions/_ros1_noetic_meta.py @@ -53,20 +53,21 @@ def __init__(self, *, extension_name: str, yaml_data: Dict[str, Any]) -> None: self.part_snippet_extra = dict() self.root_snippet["plugs"] = { - self.ros_noetic_snaps.content: - { - "interface": "content", - "content": self.ros_noetic_snaps.content, - "target": "$SNAP/opt/ros/underlay_ws", - "default-provider": self.ros_noetic_snaps.content, - } + self.ros_noetic_snaps.content: { + "interface": "content", + "content": self.ros_noetic_snaps.content, + "target": "$SNAP/opt/ros/underlay_ws", + "default-provider": self.ros_noetic_snaps.content, + } } self.part_snippet_extra["ros-content-sharing-extension-cmake-args"] = [ f'-DCMAKE_SYSTEM_PREFIX_PATH="/snap/{self.ros_noetic_snaps.sdk}/current/usr"' ] - self.part_snippet_extra["stage-packages"] = [f"ros-{self.ROS_DISTRO}-ros-environment"] + self.part_snippet_extra["stage-packages"] = [ + f"ros-{self.ROS_DISTRO}-ros-environment" + ] self.part_snippet_extra["ros-build-snaps"] = [self.ros_noetic_snaps.sdk] @@ -76,12 +77,14 @@ def __init__(self, *, extension_name: str, yaml_data: Dict[str, Any]) -> None: "$SNAP/opt/ros/underlay_ws/usr/lib/python3/dist-packages", ] - self.app_snippet["environment"]["PYTHONPATH"] = f'{python_paths}:{":".join(new_python_paths)}' + self.app_snippet["environment"]["PYTHONPATH"] = ( + f"{python_paths}:{':'.join(new_python_paths)}" + ) @overrides def get_part_snippet(self, *, plugin_name: str) -> Dict[str, Any]: # If the part uses a ROS plugin, return the extra bits containing ROS plugin specifics entries # If not, still return the base ROS plugin entries. if plugin_name in ["catkin", "catkin-tools", "colcon"]: - return {**self.part_snippet,**self.part_snippet_extra} + return {**self.part_snippet, **self.part_snippet_extra} return self.part_snippet diff --git a/snapcraft_legacy/internal/project_loader/_extensions/_ros2_foxy_meta.py b/snapcraft_legacy/internal/project_loader/_extensions/_ros2_foxy_meta.py index 0d9086e83b..c57b964842 100644 --- a/snapcraft_legacy/internal/project_loader/_extensions/_ros2_foxy_meta.py +++ b/snapcraft_legacy/internal/project_loader/_extensions/_ros2_foxy_meta.py @@ -61,13 +61,12 @@ def __init__(self, *, extension_name: str, yaml_data: Dict[str, Any]) -> None: ] self.root_snippet["plugs"] = { - self.ros2_foxy_snaps.content: - { - "interface": "content", - "content": self.ros2_foxy_snaps.content, - "target": "$SNAP/opt/ros/underlay_ws", - "default-provider": self.ros2_foxy_snaps.content, - } + self.ros2_foxy_snaps.content: { + "interface": "content", + "content": self.ros2_foxy_snaps.content, + "target": "$SNAP/opt/ros/underlay_ws", + "default-provider": self.ros2_foxy_snaps.content, + } } self.part_snippet["colcon-cmake-args"] = [ @@ -82,4 +81,6 @@ def __init__(self, *, extension_name: str, yaml_data: Dict[str, Any]) -> None: "$SNAP/opt/ros/underlay_ws/usr/lib/python3/dist-packages", ] - self.app_snippet["environment"]["PYTHONPATH"] = f'{python_paths}:{":".join(new_python_paths)}' + self.app_snippet["environment"]["PYTHONPATH"] = ( + f"{python_paths}:{':'.join(new_python_paths)}" + ) diff --git a/snapcraft_legacy/internal/project_loader/_extensions/ros1_noetic_robot.py b/snapcraft_legacy/internal/project_loader/_extensions/ros1_noetic_robot.py index 5d4c763ea8..38454038d9 100644 --- a/snapcraft_legacy/internal/project_loader/_extensions/ros1_noetic_robot.py +++ b/snapcraft_legacy/internal/project_loader/_extensions/ros1_noetic_robot.py @@ -29,6 +29,4 @@ class ExtensionImpl(RosNoeticMetaBase): @functools.cached_property @overrides def ros_noetic_snaps(self) -> ROS2NoeticSnaps: - return ROS2NoeticSnaps( - content="ros-noetic-robot", sdk="ros-noetic-robot-dev" - ) + return ROS2NoeticSnaps(content="ros-noetic-robot", sdk="ros-noetic-robot-dev") diff --git a/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_desktop.py b/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_desktop.py index 5c1f6327a7..4cb8126df2 100644 --- a/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_desktop.py +++ b/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_desktop.py @@ -29,6 +29,4 @@ class ExtensionImpl(RosFoxyMetaBase): @functools.cached_property @overrides def ros2_foxy_snaps(self) -> ROS2FoxySnaps: - return ROS2FoxySnaps( - content="ros-foxy-desktop", sdk="ros-foxy-desktop-dev" - ) + return ROS2FoxySnaps(content="ros-foxy-desktop", sdk="ros-foxy-desktop-dev") diff --git a/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_ros_base.py b/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_ros_base.py index 806a7c81ce..ee980d933c 100644 --- a/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_ros_base.py +++ b/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_ros_base.py @@ -29,6 +29,4 @@ class ExtensionImpl(RosFoxyMetaBase): @functools.cached_property @overrides def ros2_foxy_snaps(self) -> ROS2FoxySnaps: - return ROS2FoxySnaps( - content="ros-foxy-ros-base", sdk="ros-foxy-ros-base-dev" - ) + return ROS2FoxySnaps(content="ros-foxy-ros-base", sdk="ros-foxy-ros-base-dev") diff --git a/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_ros_core.py b/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_ros_core.py index b6671149c0..f3a8d99b65 100644 --- a/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_ros_core.py +++ b/snapcraft_legacy/internal/project_loader/_extensions/ros2_foxy_ros_core.py @@ -29,6 +29,4 @@ class ExtensionImpl(RosFoxyMetaBase): @functools.cached_property @overrides def ros2_foxy_snaps(self) -> ROS2FoxySnaps: - return ROS2FoxySnaps( - content="ros-foxy-ros-core", sdk="ros-foxy-ros-core-dev" - ) + return ROS2FoxySnaps(content="ros-foxy-ros-core", sdk="ros-foxy-ros-core-dev") diff --git a/snapcraft_legacy/internal/project_loader/_parts_config.py b/snapcraft_legacy/internal/project_loader/_parts_config.py index 26835dbe80..6329914d48 100644 --- a/snapcraft_legacy/internal/project_loader/_parts_config.py +++ b/snapcraft_legacy/internal/project_loader/_parts_config.py @@ -161,8 +161,7 @@ def validate(self, part_names): for part_name in part_names: if part_name not in self._part_names: raise snapcraft_legacy.internal.errors.SnapcraftEnvironmentError( - "The part named {!r} is not defined in " - "{!r}".format( + "The part named {!r} is not defined in {!r}".format( part_name, self._project.info.snapcraft_yaml_file_path ) ) @@ -178,8 +177,9 @@ def load_part(self, part_name, plugin_name, part_properties): ) logger.debug( - "Setting up part {!r} with plugin {!r} and " - "properties {!r}.".format(part_name, plugin_name, part_properties) + "Setting up part {!r} with plugin {!r} and properties {!r}.".format( + part_name, plugin_name, part_properties + ) ) stage_packages_repo = repo.Repo diff --git a/snapcraft_legacy/internal/project_loader/errors.py b/snapcraft_legacy/internal/project_loader/errors.py index 09b187ffab..88974cfbd3 100644 --- a/snapcraft_legacy/internal/project_loader/errors.py +++ b/snapcraft_legacy/internal/project_loader/errors.py @@ -20,12 +20,10 @@ class ProjectLoaderError(snapcraft_legacy.internal.errors.SnapcraftError): - fmt = "" class VariableEvaluationError(ProjectLoaderError): - fmt = ( "Cannot evaluate project variable {variable!r}: {reason}\n" "For more information, check out: {docs_url}" @@ -36,12 +34,10 @@ def __init__(self, variable: str, reason: str, docs_url: str) -> None: class InvalidEpochError(ProjectLoaderError): - fmt = "epochs are positive integers followed by an optional asterisk" class DuplicateAliasError(ProjectLoaderError): - fmt = "Multiple parts have the same alias defined: {aliases!r}" def __str__(self): @@ -52,7 +48,6 @@ def __str__(self): class SnapcraftLogicError(ProjectLoaderError): - fmt = "Issue detected while analyzing snapcraft.yaml: {message}" def __init__(self, message): @@ -121,7 +116,6 @@ def __init__(self, extension_name: str) -> None: class SnapcraftAfterPartMissingError(ProjectLoaderError): - fmt = ( "Failed to get part information: " "Cannot find the definition for part {after_part_name!r}, required by part " diff --git a/snapcraft_legacy/internal/project_loader/inspection/errors.py b/snapcraft_legacy/internal/project_loader/inspection/errors.py index 7358972f45..57c1f5f9e1 100644 --- a/snapcraft_legacy/internal/project_loader/inspection/errors.py +++ b/snapcraft_legacy/internal/project_loader/inspection/errors.py @@ -18,7 +18,6 @@ class NoSuchFileError(snapcraft_legacy.internal.errors.SnapcraftError): - fmt = ( "Failed to find part that provided path: {path!r} does not " "exist.\n" @@ -37,7 +36,6 @@ def get_exit_code(self): class ProvidesInvalidFilePathError(SnapcraftInspectError): - fmt = ( "Failed to find part that provides path: {path!r} is not in the " "staging or priming area.\n" @@ -49,7 +47,6 @@ def __init__(self, path): class UntrackedFileError(SnapcraftInspectError): - fmt = "No known parts provided {path!r}. It may have been provided by a scriptlet." def __init__(self, path): diff --git a/snapcraft_legacy/internal/remote_build/_launchpad.py b/snapcraft_legacy/internal/remote_build/_launchpad.py index 853c35ed5e..c5feb51364 100644 --- a/snapcraft_legacy/internal/remote_build/_launchpad.py +++ b/snapcraft_legacy/internal/remote_build/_launchpad.py @@ -130,8 +130,12 @@ def _credentials_filepath(self) -> pathlib.Path: If the credentials file does not exist in the default location but exists in the legacy location, emit a deprecation warning and return the legacy location. """ - credentials_filepath = platformdirs.user_data_path("snapcraft") / "launchpad-credentials" - legacy_credentials_filepath = platformdirs.user_data_path("snapcraft") / "provider/launchpad/credentials" + credentials_filepath = ( + platformdirs.user_data_path("snapcraft") / "launchpad-credentials" + ) + legacy_credentials_filepath = ( + platformdirs.user_data_path("snapcraft") / "provider/launchpad/credentials" + ) if not credentials_filepath.exists() and legacy_credentials_filepath.exists(): logger.warning( diff --git a/snapcraft_legacy/internal/remote_build/_worktree.py b/snapcraft_legacy/internal/remote_build/_worktree.py index 465e381a28..76e6d41d63 100644 --- a/snapcraft_legacy/internal/remote_build/_worktree.py +++ b/snapcraft_legacy/internal/remote_build/_worktree.py @@ -50,14 +50,10 @@ def __init__( self._package_all_sources = package_all_sources # Get snapcraft yaml (as OrderedDict). - self._snapcraft_config = ( - self._project.info.get_raw_snapcraft() - ) # type: OrderedDict + self._snapcraft_config = self._project.info.get_raw_snapcraft() # type: OrderedDict # Working copy. - self._prepared_snapcraft_config = ( - self._project.info.get_raw_snapcraft() - ) # type: OrderedDict + self._prepared_snapcraft_config = self._project.info.get_raw_snapcraft() # type: OrderedDict # Working tree base directory. self._base_dir = worktree_dir diff --git a/snapcraft_legacy/internal/remote_build/errors.py b/snapcraft_legacy/internal/remote_build/errors.py index c7c2d9f6a2..2d2e04e8aa 100644 --- a/snapcraft_legacy/internal/remote_build/errors.py +++ b/snapcraft_legacy/internal/remote_build/errors.py @@ -25,7 +25,6 @@ class RemoteBuildBaseError(_SnapcraftError): class RemoteBuildNotFoundError(RemoteBuildBaseError): - fmt = ( "Remote build not found, please make sure project {name!r} and build " "number {req_number} are correct. If this is an old build, it may " @@ -37,17 +36,14 @@ def __init__(self, *, name: str, req_number: int) -> None: class NoLaunchpadUsernameError(RemoteBuildBaseError): - fmt = "Please set your Launchpad username using the '--user' option." class NotGitRepositoryError(RemoteBuildBaseError): - fmt = "Current directory is not a git repository." class GitNotFoundVersionError(RemoteBuildBaseError): - fmt = ( "This remote-build project requires `git` to be installed " "because of it use of `version: git`. Either install `git`, " @@ -57,7 +53,6 @@ class GitNotFoundVersionError(RemoteBuildBaseError): class GitNotFoundProviderError(RemoteBuildBaseError): - fmt = ( "The remote build provider ({provider!r}) requires " "the use of the `git` utility, and `git` is not installed. " @@ -69,7 +64,6 @@ def __init__(self, *, provider: str) -> None: class BaseRequiredError(RemoteBuildBaseError): - fmt = ( "Remote build currently requires that the project uses bases.\n" "Please specify an appropriate `base` keyword and try again." @@ -77,7 +71,6 @@ class BaseRequiredError(RemoteBuildBaseError): class RemoteBuilderNotSupportedError(RemoteBuildBaseError): - fmt = ( "Remote builder {provider!r} is not supported, please choose " "a different one and try again." @@ -88,12 +81,10 @@ def __init__(self, *, provider: str) -> None: class RemoteBuildTimeoutError(RemoteBuildBaseError): - fmt = "Remote build exceeded configured timeout." class RemoteBuilderError(RemoteBuildBaseError): - fmt = "Remote builder failed with error: {builder_error!r}" def __init__(self, *, builder_error: str) -> None: @@ -101,7 +92,6 @@ def __init__(self, *, builder_error: str) -> None: class UnsupportedArchitectureError(RemoteBuildBaseError): - fmt = ( "The following architectures are not supported by the remote builder: " "{archs}.\nPlease remove them from the architecture list " @@ -113,7 +103,6 @@ def __init__(self, *, archs: List[str]) -> None: class UnsupportedVersionScriptError(RemoteBuildBaseError): - fmt = ( "Remote-build does not support the use of `version-script`.\n" "Please use `snapcraftctl set-version` part scriptlet with " @@ -122,7 +111,6 @@ class UnsupportedVersionScriptError(RemoteBuildBaseError): class AcceptPublicUploadError(RemoteBuildBaseError): - fmt = ( "Remote build needs explicit acknowledgement that data sent to build servers " "is public.\n" @@ -152,6 +140,7 @@ def get_brief(self) -> str: def get_resolution(self) -> str: return "Verify connectivity to https://api.launchpad.net and retry build." + class RemoteBuildFailedError(RemoteBuildBaseError): """Remote build failed.""" diff --git a/snapcraft_legacy/internal/repo/_base.py b/snapcraft_legacy/internal/repo/_base.py index e5ebbafc15..370c21df2d 100644 --- a/snapcraft_legacy/internal/repo/_base.py +++ b/snapcraft_legacy/internal/repo/_base.py @@ -211,7 +211,7 @@ def _mark_origin_stage_package( ) -> Set[str]: """Mark all files in sources_dir as coming from stage_package.""" file_list = set() - for (root, dirs, files) in os.walk(sources_dir): + for root, dirs, files in os.walk(sources_dir): for file_name in files: file_path = os.path.join(root, file_name) diff --git a/snapcraft_legacy/internal/repo/apt_sources_manager.py b/snapcraft_legacy/internal/repo/apt_sources_manager.py index ba7ba04c33..d867d07e47 100644 --- a/snapcraft_legacy/internal/repo/apt_sources_manager.py +++ b/snapcraft_legacy/internal/repo/apt_sources_manager.py @@ -107,7 +107,6 @@ class AptSourcesManager: :param sources_list_d: Path to sources.list.d directory. """ - def __init__( self, *, diff --git a/snapcraft_legacy/internal/repo/errors.py b/snapcraft_legacy/internal/repo/errors.py index 19985097d0..5df006f9ef 100644 --- a/snapcraft_legacy/internal/repo/errors.py +++ b/snapcraft_legacy/internal/repo/errors.py @@ -30,7 +30,6 @@ class RepoError(errors.SnapcraftError): class NoNativeBackendError(RepoError): - fmt = "Native builds aren't supported on {distro}." def __init__(self): @@ -42,7 +41,6 @@ def __init__(self): class CacheUpdateFailedError(RepoError): - fmt = ( "Failed to update the package cache: " "Some files could not be downloaded:{errors}" @@ -79,7 +77,6 @@ def get_resolution(self) -> str: class FileProviderNotFound(RepoError): - fmt = "{file_path} is not provided by any package." def __init__(self, *, file_path: Path) -> None: @@ -87,7 +84,6 @@ def __init__(self, *, file_path: Path) -> None: class BuildPackageNotFoundError(RepoError): - fmt = "Could not find a required package in 'build-packages': {package}" def __init__(self, package): @@ -95,7 +91,6 @@ def __init__(self, package): class BuildPackagesNotInstalledError(RepoError): - fmt = "Could not install all requested build packages: {packages}" def __init__(self, *, packages: List[str]) -> None: @@ -103,7 +98,6 @@ def __init__(self, *, packages: List[str]) -> None: class PackageFetchError(RepoError): - fmt = "Package fetch error: {message}" def __init__(self, message: str) -> None: @@ -111,7 +105,6 @@ def __init__(self, message: str) -> None: class PackageBrokenError(RepoError): - fmt = "The package {package} has unmet dependencies: {deps}" def __init__(self, package: str, deps: List[str]) -> None: @@ -153,7 +146,6 @@ def get_resolution(self) -> str: class UnpackError(RepoError): - fmt = "Error while provisioning {package!r}" def __init__(self, package): @@ -161,7 +153,6 @@ def __init__(self, package): class SnapUnavailableError(RepoError): - fmt = ( "Failed to install or refresh a snap: {snap_name!r} does not exist " "or is not available on the desired channel {snap_channel!r}. " @@ -174,7 +165,6 @@ def __init__(self, *, snap_name: str, snap_channel: str) -> None: class SnapFindError(RepoError): - fmt = ( "Could not find the snap {snap_name!r} installed on this host.\n" "Install the snap and try again." @@ -185,7 +175,6 @@ def __init__(self, *, snap_name): class SnapInstallError(RepoError): - fmt = "Error while installing snap {snap_name!r} from channel {snap_channel!r}" def __init__(self, *, snap_name, snap_channel): @@ -193,7 +182,6 @@ def __init__(self, *, snap_name, snap_channel): class SnapDownloadError(RepoError): - fmt = "Error while downloading snap {snap_name!r} from channel {snap_channel!r}" def __init__(self, *, snap_name, snap_channel): @@ -201,7 +189,6 @@ def __init__(self, *, snap_name, snap_channel): class SnapGetAssertionError(RepoError): - fmt = ( "Error while retrieving assertion with parameters " "{assertion_params!r}\n" @@ -213,7 +200,6 @@ def __init__(self, *, assertion_params: Sequence[str]) -> None: class SnapRefreshError(RepoError): - fmt = "Error while refreshing snap {snap_name!r} to channel {snap_channel!r}" def __init__(self, *, snap_name, snap_channel): @@ -221,7 +207,6 @@ def __init__(self, *, snap_name, snap_channel): class SnapdConnectionError(RepoError): - fmt = ( "Failed to get information for snap {snap_name!r}: " "could not connect to {url!r}." diff --git a/snapcraft_legacy/internal/repo/snaps.py b/snapcraft_legacy/internal/repo/snaps.py index 0a779b0550..6d2fa7cb8e 100644 --- a/snapcraft_legacy/internal/repo/snaps.py +++ b/snapcraft_legacy/internal/repo/snaps.py @@ -160,8 +160,9 @@ def is_classic(self) -> bool: # hard to debug as they only occur there, logging in debug mode # will help uncover the root cause if it happens again. logger.debug( - "Current store channels are {!r} and the store" - "payload is {!r}".format(store_channels, self._store_snap_info) + "Current store channels are {!r} and the storepayload is {!r}".format( + store_channels, self._store_snap_info + ) ) raise @@ -183,7 +184,7 @@ def local_download(self, *, snap_path: str, assertion_path: str) -> None: [ "snap-declaration", # use the snap name without any alias - f"snap-name={self.name.partition('_')[0]}" + f"snap-name={self.name.partition('_')[0]}", ] ) assertions.append( diff --git a/snapcraft_legacy/internal/sources/__init__.py b/snapcraft_legacy/internal/sources/__init__.py index 6c7c64a88a..13f952c82e 100644 --- a/snapcraft_legacy/internal/sources/__init__.py +++ b/snapcraft_legacy/internal/sources/__init__.py @@ -80,6 +80,7 @@ snapcraft help <plugin> """ + import logging import os import os.path diff --git a/snapcraft_legacy/internal/sources/_git.py b/snapcraft_legacy/internal/sources/_git.py index 13ef300713..54766ebd80 100644 --- a/snapcraft_legacy/internal/sources/_git.py +++ b/snapcraft_legacy/internal/sources/_git.py @@ -162,7 +162,7 @@ def _fetch_origin_commit(self): "origin", self.source_commit, ], - **self._call_kwargs + **self._call_kwargs, ) def _pull_existing(self): @@ -191,7 +191,7 @@ def _pull_existing(self): self._run( [self.command, "-C", self.source_dir, "reset", "--hard", reset_spec], - **self._call_kwargs + **self._call_kwargs, ) if self.source_submodules is None or len(self.source_submodules) > 0: @@ -229,7 +229,7 @@ def _clone_new(self): self._run( [self.command, "-C", self.source_dir, "checkout", self.source_commit], - **self._call_kwargs + **self._call_kwargs, ) def is_local(self): diff --git a/snapcraft_legacy/internal/sources/_local.py b/snapcraft_legacy/internal/sources/_local.py index a658d388c0..bda2150025 100644 --- a/snapcraft_legacy/internal/sources/_local.py +++ b/snapcraft_legacy/internal/sources/_local.py @@ -50,7 +50,7 @@ def _check(self, target): self._updated_files = set() self._updated_directories = set() - for (root, directories, files) in os.walk(self.source_abspath, topdown=True): + for root, directories, files in os.walk(self.source_abspath, topdown=True): ignored = set(self._ignore(root, directories + files, check=True)) if ignored: # Prune our search appropriately given an ignore list, i.e. diff --git a/snapcraft_legacy/internal/sources/_subversion.py b/snapcraft_legacy/internal/sources/_subversion.py index 0835a4a60e..e11becf0aa 100644 --- a/snapcraft_legacy/internal/sources/_subversion.py +++ b/snapcraft_legacy/internal/sources/_subversion.py @@ -69,7 +69,7 @@ def pull(self): self._run( [self.command, "update"] + opts, cwd=self.source_dir, - **self._call_kwargs + **self._call_kwargs, ) else: if os.path.isdir(self.source): @@ -81,12 +81,12 @@ def pull(self): self.source_dir, ] + opts, - **self._call_kwargs + **self._call_kwargs, ) else: self._run( [self.command, "checkout", self.source, self.source_dir] + opts, - **self._call_kwargs + **self._call_kwargs, ) self.source_details = self._get_source_details() diff --git a/snapcraft_legacy/internal/sources/errors.py b/snapcraft_legacy/internal/sources/errors.py index aba3d79630..31afa05dc1 100644 --- a/snapcraft_legacy/internal/sources/errors.py +++ b/snapcraft_legacy/internal/sources/errors.py @@ -30,7 +30,6 @@ class VCSError(SnapcraftSourceError): class SnapcraftSourceNotFoundError(SnapcraftSourceError): - fmt = ( "Failed to pull source: {source!r}.\n" "Please ensure the source path is correct and that it is accessible.\n" @@ -42,7 +41,6 @@ def __init__(self, source): class SnapcraftSourceUnhandledError(SnapcraftSourceError): - fmt = ( "Failed to pull source: " "unable to determine source type of {source!r}.\n" @@ -56,7 +54,6 @@ def __init__(self, source): class SnapcraftSourceInvalidOptionError(SnapcraftSourceError): - fmt = ( "Failed to pull source: " "{option!r} cannot be used with a {source_type} source.\n" @@ -68,7 +65,6 @@ def __init__(self, source_type: str, option: str) -> None: class SnapcraftSourceIncompatibleOptionsError(SnapcraftSourceError): - fmt = ( "Failed to pull source: " "cannot specify both {humanized_options} for a {source_type} source.\n" @@ -84,7 +80,6 @@ def __init__(self, source_type: str, options: List[str]) -> None: class DigestDoesNotMatchError(SnapcraftSourceError): - fmt = "Expected the digest for source to be {expected}, but it was {calculated}" def __init__(self, expected, calculated): @@ -92,7 +87,6 @@ def __init__(self, expected, calculated): class InvalidDebError(SnapcraftSourceError): - fmt = ( "The {deb_file} used does not contain valid data. " "Ensure a proper deb file is passed for .deb files " @@ -101,7 +95,6 @@ class InvalidDebError(SnapcraftSourceError): class InvalidSnapError(SnapcraftSourceError): - fmt = ( "The snap file does not contain valid data. " "Ensure the source lists a proper snap file" @@ -109,7 +102,6 @@ class InvalidSnapError(SnapcraftSourceError): class SourceUpdateUnsupportedError(SnapcraftSourceError): - fmt = "Failed to update source: {source!s} sources don't support updating." def __init__(self, source): @@ -117,7 +109,6 @@ def __init__(self, source): class SnapcraftPullError(SnapcraftSourceError): - fmt = "Failed to pull source, command {command!r} exited with code {exit_code}." def __init__(self, command, exit_code): @@ -129,7 +120,6 @@ def __init__(self, command, exit_code): class SnapcraftRequestError(SnapcraftSourceError): - fmt = "Network request error: {message}" diff --git a/snapcraft_legacy/internal/states/_global_state.py b/snapcraft_legacy/internal/states/_global_state.py index 4d3468579f..260ca575c6 100644 --- a/snapcraft_legacy/internal/states/_global_state.py +++ b/snapcraft_legacy/internal/states/_global_state.py @@ -33,7 +33,6 @@ class GlobalState(State): - yaml_tag = "!GlobalState" @classmethod diff --git a/snapcraft_legacy/plugins/v2/_kernel_build.py b/snapcraft_legacy/plugins/v2/_kernel_build.py index 48ec7243b2..08f5d85f98 100644 --- a/snapcraft_legacy/plugins/v2/_kernel_build.py +++ b/snapcraft_legacy/plugins/v2/_kernel_build.py @@ -181,9 +181,7 @@ def _download_generic_initrd_cmd(target_arch: str) -> List[str]: if [ ! -e ${{UC_INITRD_DEB}} ]; then download_core_initrd {arch} ${{UC_INITRD_DEB}} fi - """.format( - arch=target_arch - ) + """.format(arch=target_arch) ) return [cmd] @@ -214,9 +212,7 @@ def _download_snap_bootstrap_cmd(target_arch: str) -> List[str]: if [ ! -e ${{UC_INITRD_DEB}}/usr/lib/snapd ]; then download_snap_bootstrap {arch} ${{UC_INITRD_DEB}} fi - """.format( - arch=target_arch - ) + """.format(arch=target_arch) ) return [cmd] @@ -231,9 +227,7 @@ def _clone_zfs_cmd(enable_zfs: bool, dest_dir: str) -> List[str]: echo "cloning zfs..." git clone --depth=1 {zfs_url} {dest_dir}/zfs -b master fi - """.format( - dest_dir=dest_dir, zfs_url=_ZFS_URL - ) + """.format(dest_dir=dest_dir, zfs_url=_ZFS_URL) ) ] return [ @@ -249,9 +243,7 @@ def _clean_old_build_cmd(dest_dir: str) -> List[str]: echo "Cleaning previous build first..." [ -e {dest_dir}/modules ] && rm -rf {dest_dir}/modules [ -L {dest_dir}/lib/modules ] && rm -rf {dest_dir}/lib/modules - """.format( - dest_dir=dest_dir - ) + """.format(dest_dir=dest_dir) ) ] @@ -293,15 +285,13 @@ def _do_base_config_cmd( fakeroot debian/rules clean rm -rf CONFIGS/ popd - fi""".format( - config_flavour=config_flavour, dest_dir=dest_dir - ) + fi""".format(config_flavour=config_flavour, dest_dir=dest_dir) ) cmd.extend([conf_cmd]) else: make_cmd = make_cmd.copy() make_cmd[1] = "-j1" # FIXME: make this more robust - cmd.append(f'\t{" ".join(make_cmd + defconfig)}') + cmd.append(f"\t{' '.join(make_cmd + defconfig)}") cmd.append("fi") @@ -524,7 +514,6 @@ def _get_perf_build_commands( ] - def _make_initrd_cmd( initrd_compression: Optional[str], initrd_compression_options: Optional[List[str]], @@ -917,7 +906,6 @@ def _make_initrd_cmd( ] - def get_build_commands( make_cmd: List[str], make_targets: List[str], @@ -1118,9 +1106,7 @@ def _arrange_install_dir_cmd(install_dir: str) -> List[str]: # create symlinks for modules and firmware for convenience ln -sf ../modules {install_dir}/lib/modules ln -sf ../firmware {install_dir}/lib/firmware - """.format( - install_dir=install_dir - ) + """.format(install_dir=install_dir) ) ] @@ -1142,7 +1128,6 @@ def _compression_cmd( return cmd - def _get_post_install_cmd( device_trees: Optional[List[str]], initrd_compression: Optional[str], @@ -1192,7 +1177,6 @@ def _get_post_install_cmd( ] - def _get_install_command( device_trees: Optional[List[str]], make_cmd: List[str], diff --git a/snapcraft_legacy/plugins/v2/_ros.py b/snapcraft_legacy/plugins/v2/_ros.py index a97a7aaa70..364147d630 100644 --- a/snapcraft_legacy/plugins/v2/_ros.py +++ b/snapcraft_legacy/plugins/v2/_ros.py @@ -77,7 +77,9 @@ class RosPlugin(PluginV2): """Base class for ROS-related plugins. Not intended for use by end users.""" def get_build_snaps(self) -> Set[str]: - return set(self.options.ros_build_snaps) if self.options.ros_build_snaps else set() + return ( + set(self.options.ros_build_snaps) if self.options.ros_build_snaps else set() + ) def get_build_packages(self) -> Set[str]: return { @@ -122,7 +124,6 @@ def _get_build_commands(self) -> List[str]: """ def _get_list_packages_commands(self) -> List[str]: - cmd = list() # Clean up previously established list of packages in build snaps @@ -133,25 +134,25 @@ def _get_list_packages_commands(self) -> List[str]: for ros_build_snap in self.options.ros_build_snaps: snap_name = _get_parsed_snap(ros_build_snap)[0] path = f"/snap/{snap_name}/current/opt/ros" - cmd.extend([ - # Retrieve the list of all ROS packages available in the build snap - f"if [ -d {path} ]; then", - f"ROS_PACKAGE_PATH={path} " - 'rospack list-names | (xargs rosdep resolve --rosdistro "${ROS_DISTRO}" || echo "") | ' - 'awk "/#apt/{getline;print;}" >> "${SNAPCRAFT_PART_INSTALL}/.installed_packages.txt"', - "fi", - - # Retrieve the list of all non-ROS packages available in the build snap - f'if [ -d "{path}/${{ROS_DISTRO}}/" ]; then', - f'rosdep keys --rosdistro "${{ROS_DISTRO}}" --from-paths "{path}/${{ROS_DISTRO}}" --ignore-packages-from-source ' - '| (xargs rosdep resolve --rosdistro "${ROS_DISTRO}" || echo "") | grep -v "#" >> "${SNAPCRAFT_PART_INSTALL}"/.installed_packages.txt', - "fi", - - f'if [ -d "{path}/snap/" ]; then', - f'rosdep keys --rosdistro "${{ROS_DISTRO}}" --from-paths "{path}/snap" --ignore-packages-from-source ' - '| (xargs rosdep resolve --rosdistro "${ROS_DISTRO}" || echo "") | grep -v "#" >> "${SNAPCRAFT_PART_INSTALL}"/.installed_packages.txt', - "fi", - ]) + cmd.extend( + [ + # Retrieve the list of all ROS packages available in the build snap + f"if [ -d {path} ]; then", + f"ROS_PACKAGE_PATH={path} " + 'rospack list-names | (xargs rosdep resolve --rosdistro "${ROS_DISTRO}" || echo "") | ' + 'awk "/#apt/{getline;print;}" >> "${SNAPCRAFT_PART_INSTALL}/.installed_packages.txt"', + "fi", + # Retrieve the list of all non-ROS packages available in the build snap + f'if [ -d "{path}/${{ROS_DISTRO}}/" ]; then', + f'rosdep keys --rosdistro "${{ROS_DISTRO}}" --from-paths "{path}/${{ROS_DISTRO}}" --ignore-packages-from-source ' + '| (xargs rosdep resolve --rosdistro "${ROS_DISTRO}" || echo "") | grep -v "#" >> "${SNAPCRAFT_PART_INSTALL}"/.installed_packages.txt', + "fi", + f'if [ -d "{path}/snap/" ]; then', + f'rosdep keys --rosdistro "${{ROS_DISTRO}}" --from-paths "{path}/snap" --ignore-packages-from-source ' + '| (xargs rosdep resolve --rosdistro "${ROS_DISTRO}" || echo "") | grep -v "#" >> "${SNAPCRAFT_PART_INSTALL}"/.installed_packages.txt', + "fi", + ] + ) cmd.append("") return cmd diff --git a/snapcraft_legacy/plugins/v2/catkin.py b/snapcraft_legacy/plugins/v2/catkin.py index 52c21bdac2..d73be0c30e 100644 --- a/snapcraft_legacy/plugins/v2/catkin.py +++ b/snapcraft_legacy/plugins/v2/catkin.py @@ -16,24 +16,24 @@ """The catkin plugin for ROS 1 parts. - - catkin-packages: - (list of strings) - List of catkin packages to build. If not specified, all packages in the - workspace will be built. If set to an empty list ([]), no packages will - be built, which could be useful if you only want ROS debs in the snap. - - - catkin-packages-ignore: - (list of strings) - List of catkin packages to ignore (i.e. not build or install). If not - specified or set to an empty list ([]), no packages will be ignored. - - - catkin-cmake-args: - (list of strings) - Arguments to pass to cmake projects. - - This plugin requires certain variables that are specified by the `ros1-noetic` - extension. If you're not using the extension, set these in your `build-environment`: - - ROS_DISTRO: "noetic" +- catkin-packages: + (list of strings) + List of catkin packages to build. If not specified, all packages in the + workspace will be built. If set to an empty list ([]), no packages will + be built, which could be useful if you only want ROS debs in the snap. + +- catkin-packages-ignore: + (list of strings) + List of catkin packages to ignore (i.e. not build or install). If not + specified or set to an empty list ([]), no packages will be ignored. + +- catkin-cmake-args: + (list of strings) + Arguments to pass to cmake projects. + +This plugin requires certain variables that are specified by the `ros1-noetic` +extension. If you're not using the extension, set these in your `build-environment`: + - ROS_DISTRO: "noetic" """ from typing import Any, Dict, List, Set @@ -118,12 +118,16 @@ def _get_workspace_activation_commands(self) -> List[str]: if self.options.ros_build_snaps: for ros_build_snap in self.options.ros_build_snaps: snap_name = _get_parsed_snap(ros_build_snap)[0] - activation_commands.extend(self._get_source_command(f"/snap/{snap_name}/current")) + activation_commands.extend( + self._get_source_command(f"/snap/{snap_name}/current") + ) activation_commands.append("") # Source ROS ws in stage-snaps next activation_commands.append("## Sourcing ROS ws in stage snaps") - activation_commands.extend(self._get_source_command("${SNAPCRAFT_PART_INSTALL}")) + activation_commands.extend( + self._get_source_command("${SNAPCRAFT_PART_INSTALL}") + ) activation_commands.append("") # Finally source system's ROS ws @@ -134,7 +138,6 @@ def _get_workspace_activation_commands(self) -> List[str]: return activation_commands def _get_build_commands(self) -> List[str]: - build_command = [ "catkin_make_isolated", "--install", @@ -155,9 +158,12 @@ def _get_build_commands(self) -> List[str]: if self.options.catkin_packages_ignore: build_command.extend(["--ignore-pkg", *self.options.catkin_packages_ignore]) - if self.options.catkin_cmake_args or self.options.ros_content_sharing_extension_cmake_args: + if ( + self.options.catkin_cmake_args + or self.options.ros_content_sharing_extension_cmake_args + ): build_command.append("--cmake-args") build_command.extend(self.options.catkin_cmake_args) build_command.extend(self.options.ros_content_sharing_extension_cmake_args) - return (["## Build command", " ".join(build_command)]) + return ["## Build command", " ".join(build_command)] diff --git a/snapcraft_legacy/plugins/v2/catkin_tools.py b/snapcraft_legacy/plugins/v2/catkin_tools.py index 5c466525af..c103e2a48d 100644 --- a/snapcraft_legacy/plugins/v2/catkin_tools.py +++ b/snapcraft_legacy/plugins/v2/catkin_tools.py @@ -16,19 +16,19 @@ """The catkin tools plugin for ROS 1 parts. - - catkin-tools-packages: - (list of strings) - List of catkin packages to build. If not specified, all packages in the - workspace will be built. If set to an empty list ([]), no packages will - be built, which could be useful if you only want ROS debs in the snap. - - - catkin-tools-cmake-args: - (list of strings) - Arguments to pass to cmake projects. - - This plugin requires certain variables that are specified by the `ros1-noetic` - extension. If you're not using the extension, set these in your `build-environment`: - - ROS_DISTRO: "noetic" +- catkin-tools-packages: + (list of strings) + List of catkin packages to build. If not specified, all packages in the + workspace will be built. If set to an empty list ([]), no packages will + be built, which could be useful if you only want ROS debs in the snap. + +- catkin-tools-cmake-args: + (list of strings) + Arguments to pass to cmake projects. + +This plugin requires certain variables that are specified by the `ros1-noetic` +extension. If you're not using the extension, set these in your `build-environment`: + - ROS_DISTRO: "noetic" """ from typing import Any, Dict, List, Set @@ -108,12 +108,16 @@ def _get_workspace_activation_commands(self) -> List[str]: if self.options.ros_build_snaps: for ros_build_snap in self.options.ros_build_snaps: snap_name = _get_parsed_snap(ros_build_snap)[0] - activation_commands.extend(self._get_source_command(f"/snap/{snap_name}/current")) + activation_commands.extend( + self._get_source_command(f"/snap/{snap_name}/current") + ) activation_commands.append("") # Source ROS ws in stage-snaps next activation_commands.append("## Sourcing ROS ws in stage snaps") - activation_commands.extend(self._get_source_command("${SNAPCRAFT_PART_INSTALL}")) + activation_commands.extend( + self._get_source_command("${SNAPCRAFT_PART_INSTALL}") + ) activation_commands.append("") # Finally source system's ROS ws @@ -166,15 +170,16 @@ def _get_build_commands(self) -> List[str]: '"${SNAPCRAFT_PART_INSTALL}/opt/ros/${ROS_DISTRO}"', ] - if self.options.catkin_tools_cmake_args or self.options.ros_content_sharing_extension_cmake_args: + if ( + self.options.catkin_tools_cmake_args + or self.options.ros_content_sharing_extension_cmake_args + ): cmake_args = [] if self.options.catkin_tools_cmake_args: cmake_args.extend(self.options.catkin_tools_cmake_args) if self.options.ros_content_sharing_extension_cmake_args: cmake_args.extend(self.options.ros_content_sharing_extension_cmake_args) - catkin_config_command.extend( - ["--cmake-args", *cmake_args] - ) + catkin_config_command.extend(["--cmake-args", *cmake_args]) commands.append(" ".join(catkin_config_command)) diff --git a/snapcraft_legacy/plugins/v2/colcon.py b/snapcraft_legacy/plugins/v2/colcon.py index b4e9d57882..3d07aeeafd 100644 --- a/snapcraft_legacy/plugins/v2/colcon.py +++ b/snapcraft_legacy/plugins/v2/colcon.py @@ -16,42 +16,42 @@ """The colcon plugin for ROS 2 parts. - - colcon-packages: - (list of strings) - List of colcon packages to build. If not specified, all packages in the - workspace will be built. If set to an empty list ([]), no packages will - be built, which could be useful if you only want ROS debs in the snap. - - - colcon-packages-ignore: - (list of strings) - List of colcon packages to ignore. If not specified or set to an empty - list ([]), no packages will be ignored. - - - colcon-cmake-args: - (list of strings) - Arguments to pass to cmake projects. Note that any arguments here which match - colcon arguments need to be prefixed with a space. This can be done by quoting - each argument with a leading space. - - - colcon-catkin-cmake-args: - (list of strings) - Arguments to pass to catkin packages. Note that any arguments here which match - colcon arguments need to be prefixed with a space. This can be done by quoting - each argument with a leading space. - - - colcon-ament-cmake-args: - (list of strings) - Arguments to pass to ament_cmake packages. Note that any arguments here which - match colcon arguments need to be prefixed with a space. This can be done by - quoting each argument with a leading space. - - This plugin expects the build-environment `ROS_DISTRO` and `ROS_BUILD_BASE` - to be populated by the `ros2-<distro>` extension. - - This plugin also expects certain variables that are specified by the extension, - specific to the ROS distro. If not using the extension, set these in your - `build-environment`: - - ROS_DISTRO: "foxy" +- colcon-packages: + (list of strings) + List of colcon packages to build. If not specified, all packages in the + workspace will be built. If set to an empty list ([]), no packages will + be built, which could be useful if you only want ROS debs in the snap. + +- colcon-packages-ignore: + (list of strings) + List of colcon packages to ignore. If not specified or set to an empty + list ([]), no packages will be ignored. + +- colcon-cmake-args: + (list of strings) + Arguments to pass to cmake projects. Note that any arguments here which match + colcon arguments need to be prefixed with a space. This can be done by quoting + each argument with a leading space. + +- colcon-catkin-cmake-args: + (list of strings) + Arguments to pass to catkin packages. Note that any arguments here which match + colcon arguments need to be prefixed with a space. This can be done by quoting + each argument with a leading space. + +- colcon-ament-cmake-args: + (list of strings) + Arguments to pass to ament_cmake packages. Note that any arguments here which + match colcon arguments need to be prefixed with a space. This can be done by + quoting each argument with a leading space. + +This plugin expects the build-environment `ROS_DISTRO` and `ROS_BUILD_BASE` +to be populated by the `ros2-<distro>` extension. + +This plugin also expects certain variables that are specified by the extension, +specific to the ROS distro. If not using the extension, set these in your +`build-environment`: + - ROS_DISTRO: "foxy" """ from typing import Any, Dict, List, Set @@ -180,7 +180,6 @@ def _get_workspace_activation_commands(self) -> List[str]: return activation_commands def _get_build_commands(self) -> List[str]: - build_command = [ "colcon", "build", @@ -194,36 +193,45 @@ def _get_build_commands(self) -> List[str]: ] if self.options.colcon_packages_ignore: - build_command.extend(["--packages-ignore", *self.options.colcon_packages_ignore]) + build_command.extend( + ["--packages-ignore", *self.options.colcon_packages_ignore] + ) if self.options.colcon_packages: build_command.extend(["--packages-select", *self.options.colcon_packages]) # compile in release only if user did not set the build type in cmake-args if not any("-DCMAKE_BUILD_TYPE=" in s for s in self.options.colcon_cmake_args): - build_command.extend(["--cmake-args", "-DCMAKE_BUILD_TYPE=Release", - *self.options.colcon_cmake_args - ]) - elif len(self.options.colcon_cmake_args)>0: + build_command.extend( + [ + "--cmake-args", + "-DCMAKE_BUILD_TYPE=Release", + *self.options.colcon_cmake_args, + ] + ) + elif len(self.options.colcon_cmake_args) > 0: build_command.extend(["--cmake-args", *self.options.colcon_cmake_args]) if self.options.colcon_ament_cmake_args: - build_command.extend(["--ament-cmake-args", *self.options.colcon_ament_cmake_args]) + build_command.extend( + ["--ament-cmake-args", *self.options.colcon_ament_cmake_args] + ) if self.options.colcon_catkin_cmake_args: - build_command.extend(["--catkin-cmake-args", *self.options.colcon_catkin_cmake_args]) + build_command.extend( + ["--catkin-cmake-args", *self.options.colcon_catkin_cmake_args] + ) # Specify the number of workers - build_command.extend(["--parallel-workers", '"${SNAPCRAFT_PARALLEL_BUILD_COUNT}"']) - - return ( - ["## Build command", " ".join(build_command)] - + [ - "## Post build command", - # Remove the COLCON_IGNORE marker so that, at staging, - # catkin can crawl the entire folder to look up for packages. - 'if [ -f "${SNAPCRAFT_PART_INSTALL}"/opt/ros/snap/COLCON_IGNORE ]; then', - 'rm "${SNAPCRAFT_PART_INSTALL}"/opt/ros/snap/COLCON_IGNORE', - "fi", - ] + build_command.extend( + ["--parallel-workers", '"${SNAPCRAFT_PARALLEL_BUILD_COUNT}"'] ) + + return ["## Build command", " ".join(build_command)] + [ + "## Post build command", + # Remove the COLCON_IGNORE marker so that, at staging, + # catkin can crawl the entire folder to look up for packages. + 'if [ -f "${SNAPCRAFT_PART_INSTALL}"/opt/ros/snap/COLCON_IGNORE ]; then', + 'rm "${SNAPCRAFT_PART_INSTALL}"/opt/ros/snap/COLCON_IGNORE', + "fi", + ] diff --git a/snapcraft_legacy/plugins/v2/crystal.py b/snapcraft_legacy/plugins/v2/crystal.py index 61b854f38c..18e11cf033 100644 --- a/snapcraft_legacy/plugins/v2/crystal.py +++ b/snapcraft_legacy/plugins/v2/crystal.py @@ -31,6 +31,7 @@ (list of strings, default: '[]') These options are passed to `shards build`. """ + import os import shlex import shutil diff --git a/snapcraft_legacy/project/_project.py b/snapcraft_legacy/project/_project.py index 7acbb327b6..0176df85e8 100644 --- a/snapcraft_legacy/project/_project.py +++ b/snapcraft_legacy/project/_project.py @@ -38,9 +38,8 @@ def __init__( debug=False, snapcraft_yaml_file_path=None, work_dir: str = None, - is_managed_host: bool = False + is_managed_host: bool = False, ) -> None: - project_dir = os.getcwd() if is_managed_host: work_dir = os.path.expanduser("~") @@ -59,7 +58,7 @@ def __init__( target_deb_arch, debug, work_dir=work_dir, - architectures=self.info.architectures if self.info else None + architectures=self.info.architectures if self.info else None, ) self._is_managed_host = is_managed_host diff --git a/snapcraft_legacy/project/_project_options.py b/snapcraft_legacy/project/_project_options.py index a00f9bb92d..a83aac0491 100644 --- a/snapcraft_legacy/project/_project_options.py +++ b/snapcraft_legacy/project/_project_options.py @@ -364,9 +364,8 @@ def __init__( debug=False, *, work_dir: str = None, - architectures = None, + architectures=None, ) -> None: - # Here for backwards compatibility. project_dir = os.getcwd() if work_dir is None: diff --git a/snapcraft_legacy/project/errors.py b/snapcraft_legacy/project/errors.py index 0e98f73ba9..8cba9a2863 100644 --- a/snapcraft_legacy/project/errors.py +++ b/snapcraft_legacy/project/errors.py @@ -23,7 +23,6 @@ class MissingSnapcraftYamlError(SnapcraftError): - fmt = ( "Could not find {snapcraft_yaml_file_path}. Are you sure you are " "in the right directory?\n" @@ -35,7 +34,6 @@ def __init__(self, *, snapcraft_yaml_file_path): class DuplicateSnapcraftYamlError(SnapcraftError): - fmt = ( "Found a {snapcraft_yaml_file_path!r} and a " "{other_snapcraft_yaml_file_path!r}.\n" diff --git a/snapcraft_legacy/scripts/generate_reference.py b/snapcraft_legacy/scripts/generate_reference.py index 7cb4f055c1..73c7d95d26 100755 --- a/snapcraft_legacy/scripts/generate_reference.py +++ b/snapcraft_legacy/scripts/generate_reference.py @@ -47,9 +47,9 @@ def __init__(self, output_file): self.topics = [] self.plugins = [] self.output_file = output_file - assert os.path.isdir( - os.path.dirname(self.output_file) - ), "Directory {} does not exist.".format(os.path.dirname(self.output_file)) + assert os.path.isdir(os.path.dirname(self.output_file)), ( + "Directory {} does not exist.".format(os.path.dirname(self.output_file)) + ) self._read() self._write() @@ -81,9 +81,7 @@ def _write(self): reference_text += """ ### Topic: {} -{}""".format( - entry[0].title(), entry[1].replace("# ", "#### ") - ) +{}""".format(entry[0].title(), entry[1].replace("# ", "#### ")) reference_text += """ ## snapcraft's Plugins @@ -95,9 +93,7 @@ def _write(self): reference_text += """ ### The {} plugin -{}""".format( - entry[0], entry[1] - ) +{}""".format(entry[0], entry[1]) with open(os.path.join(self.output_file), "w") as f: f.write(str(reference_text)) diff --git a/snapcraft_legacy/shell_utils.py b/snapcraft_legacy/shell_utils.py index 3fc7ea0016..78194caf57 100644 --- a/snapcraft_legacy/shell_utils.py +++ b/snapcraft_legacy/shell_utils.py @@ -16,7 +16,6 @@ """Utilities to run inside a correct snapcrafting environment.""" - import tempfile from snapcraft_legacy.internal import common diff --git a/snapcraft_legacy/storeapi/_snap_api.py b/snapcraft_legacy/storeapi/_snap_api.py index 0e24458efc..23613603ab 100644 --- a/snapcraft_legacy/storeapi/_snap_api.py +++ b/snapcraft_legacy/storeapi/_snap_api.py @@ -85,9 +85,9 @@ def get_info(self, snap_name: str, *, arch: str = None) -> SnapInfo: ) params = dict() - params[ - "fields" - ] = "channel-map,snap-id,name,publisher,confinement,revision,download" + params["fields"] = ( + "channel-map,snap-id,name,publisher,confinement,revision,download" + ) if arch is not None: params["architecture"] = arch logger.debug("Getting information for {}".format(snap_name)) diff --git a/snapcraft_legacy/storeapi/_status_tracker.py b/snapcraft_legacy/storeapi/_status_tracker.py index f3384d19d4..886c360091 100644 --- a/snapcraft_legacy/storeapi/_status_tracker.py +++ b/snapcraft_legacy/storeapi/_status_tracker.py @@ -10,7 +10,6 @@ class StatusTracker: - __messages = { "being_processed": "Processing...", "ready_to_release": "Ready to release!", diff --git a/snapcraft_legacy/storeapi/errors.py b/snapcraft_legacy/storeapi/errors.py index 93b341ac7a..afb450ff1a 100644 --- a/snapcraft_legacy/storeapi/errors.py +++ b/snapcraft_legacy/storeapi/errors.py @@ -48,7 +48,6 @@ def __init__(self, **kwargs): class GeneralStoreError(StoreError): - fmt = "Store Error: {message}" def __init__(self, message, response=None): @@ -156,7 +155,6 @@ def get_resolution(self) -> str: class NoSnapIdError(StoreError): - fmt = ( "Failed to get snap ID for snap {snap_name!r}. This is an error in " "the store, please open a new topic in the 'store' category in the " @@ -172,7 +170,6 @@ class StoreDownloadError(StoreError): class DownloadNotFoundError(StoreDownloadError): - fmt = "Downloaded file not found {path!r}." def __init__(self, *, path: str) -> None: @@ -180,7 +177,6 @@ def __init__(self, *, path: str) -> None: class SHAMismatchError(StoreDownloadError): - fmt = ( "The SHA3-384 checksum for {path!r} was {calculated!r}: expected {expected!r}." ) @@ -190,7 +186,6 @@ def __init__(self, *, path: str, expected: str, calculated: str) -> None: class DeveloperAgreementSignError(StoreError): - fmt = ( "There was an error while signing developer agreement.\n" "Reason: {reason!r}\n" @@ -202,7 +197,6 @@ def __init__(self, response): class NeedTermsSignedError(StoreError): - fmt = ( "Developer Terms of Service agreement must be signed " "before continuing: {message}" @@ -213,7 +207,6 @@ def __init__(self, message): class StoreAccountInformationError(StoreError): - fmt = "Error fetching account information from store: {error}" def __init__(self, response): @@ -236,7 +229,6 @@ def __init__(self, response): class StoreKeyRegistrationError(StoreError): - fmt = "Key registration failed: {error}" def __init__(self, response): @@ -278,8 +270,7 @@ class StoreRegistrationError(StoreError): ) __FMT_RETRY_WAIT = ( - "You must wait {retry_after} seconds before trying to register " - "your next snap." + "You must wait {retry_after} seconds before trying to register your next snap." ) __FMT_INVALID = "{message}" @@ -338,11 +329,8 @@ def __str__(self): class StoreUpDownError(StoreError): - fmt = ( - "There was an error uploading the package.\n" - "Reason: {reason!r}\n" - "Text: {text!r}" + "There was an error uploading the package.\nReason: {reason!r}\nText: {text!r}" ) def __init__(self, response): @@ -350,7 +338,6 @@ def __init__(self, response): class StoreUploadError(StoreError): - __FMT_NOT_REGISTERED = ( "This snap is not registered. Register the snap and try again." ) @@ -385,7 +372,6 @@ def __init__(self, snap_name, response): class StoreReviewError(StoreError): - __FMT_NEED_MANUAL_REVIEW = ( "The Store automatic review failed.\n" "A human will soon review your snap, but if you can't wait please " @@ -426,7 +412,6 @@ def __init__(self, result): class StoreReleaseError(StoreError): - fmt = "{message}" __FMT_NOT_REGISTERED = ( @@ -508,7 +493,6 @@ def __fmt_error_unknown(self, response): class StoreMetadataError(StoreError): - __FMT_NOT_FOUND = ( "Sorry, updating the information in the store has failed, first run " "`snapcraft register {snap_name}` and then " @@ -559,7 +543,6 @@ def __init__(self, snap_name, response, metadata): class StoreValidationError(StoreError): - fmt = "Received error {status_code!r}: {text!r}" def __init__(self, snap_id, response, message=None): @@ -577,7 +560,6 @@ def __init__(self, snap_id, response, message=None): class StoreValidationSetsError(StoreError): - fmt = "Issues encountered with validation set: {error}" def __init__(self, response): @@ -596,7 +578,6 @@ def __init__(self, response): class StoreSnapBuildError(StoreError): - fmt = "Could not assert build: {error}" def __init__(self, response): @@ -614,7 +595,6 @@ def __init__(self, response): class StoreSnapRevisionsError(StoreError): - fmt = ( "Error fetching revisions of snap id {snap_id!r} for {arch!r} " "in {series!r} series: {error}." @@ -641,7 +621,6 @@ def __init__(self, response, snap_id, series, arch): class StoreDeltaApplicationError(StoreError): - fmt = "{message}" def __init__(self, message): @@ -742,7 +721,6 @@ def get_resolution(self) -> str: class StoreSnapStatusError(StoreSnapRevisionsError): - fmt = ( "Error fetching status of snap id {snap_id!r} for {arch!r} " "in {series!r} series: {error}." @@ -750,7 +728,6 @@ class StoreSnapStatusError(StoreSnapRevisionsError): class StoreChannelClosingError(StoreError): - fmt = "Could not close channel: {error}" def __init__(self, response): @@ -764,7 +741,6 @@ def __init__(self, response): class StoreChannelClosingPermissionError(StoreError): - fmt = ( "Your account lacks permission to close channels for this snap. Make " "sure the logged in account has upload permissions on {snap_name!r} " @@ -776,7 +752,6 @@ def __init__(self, snap_name, snap_series): class StoreBuildAssertionPermissionError(StoreError): - fmt = ( "Your account lacks permission to assert builds for this snap. Make " "sure you are logged in as the publisher of {snap_name!r} " @@ -788,12 +763,10 @@ def __init__(self, snap_name, snap_series): class StoreAssertionError(StoreError): - fmt = "Error signing {endpoint} assertion for {snap_name}: {error!s}" class KeyAlreadyExistsError(StoreError): - fmt = "The key {key_name!r} already exists" def __init__(self, key_name): @@ -801,7 +774,6 @@ def __init__(self, key_name): class KeyAlreadyRegisteredError(StoreError): - fmt = "You have already registered a key named {key_name!r}" def __init__(self, key_name): @@ -809,7 +781,6 @@ def __init__(self, key_name): class NoKeysError(StoreError): - fmt = ( "You have no usable keys.\nPlease create at least one key with " "`snapcraft create-key` for use with snap." @@ -817,7 +788,6 @@ class NoKeysError(StoreError): class NoSuchKeyError(StoreError): - fmt = ( "You have no usable key named {key_name!r}.\nSee the keys available " "in your system with `snapcraft keys`." @@ -828,7 +798,6 @@ def __init__(self, key_name): class KeyNotRegisteredError(StoreError): - fmt = ( "The key {key_name!r} is not registered in the Store.\nPlease " "register it with `snapcraft register-key {key_name!r}` before " @@ -840,7 +809,6 @@ def __init__(self, key_name): class InvalidValidationRequestsError(StoreError): - fmt = "Invalid validation requests (format must be name=revision): {requests}" def __init__(self, requests): @@ -849,7 +817,6 @@ def __init__(self, requests): class SignBuildAssertionError(StoreError): - fmt = "Failed to sign build assertion for {snap_name!r}" def __init__(self, snap_name): diff --git a/snapcraft_legacy/storeapi/v2/validation_sets.py b/snapcraft_legacy/storeapi/v2/validation_sets.py index 90f0545c79..bd85fb78ec 100644 --- a/snapcraft_legacy/storeapi/v2/validation_sets.py +++ b/snapcraft_legacy/storeapi/v2/validation_sets.py @@ -35,7 +35,7 @@ def cast_dict_scalars_to_strings(data: dict) -> dict[str, Any]: def _to_string( - data: dict | list | str | int | float | str | bool | None + data: dict | list | str | int | float | str | bool | None, ) -> dict[str, Any] | list | str | None: """Recurse through nested dicts and lists and cast scalar values to strings. @@ -56,8 +56,10 @@ def _to_string( return data + Presence = Literal["required", "optional", "invalid"] + class Component(models.CraftBaseModel): """Represent a Component in a Validation Set.""" @@ -67,6 +69,7 @@ class Component(models.CraftBaseModel): revision: int | None = None """Component revision""" + class Snap(models.CraftBaseModel): """Represent a Snap in a Validation Set.""" @@ -85,11 +88,13 @@ class Snap(models.CraftBaseModel): components: dict[str, Presence | Component] | None = None """Snap components""" + class EditableBuildAssertion(models.CraftBaseModel): """Subset of a build assertion that can be edited by the user. https://dashboard.snapcraft.io/docs/reference/v2/en/validation-sets.html#request-json-schema """ + account_id: str """The "account-id" assertion header""" @@ -116,6 +121,7 @@ class BuildAssertion(EditableBuildAssertion): https://dashboard.snapcraft.io/docs/reference/v2/en/validation-sets.html#response-json-schema """ + authority_id: str """The "authority-id" assertion header""" @@ -145,6 +151,7 @@ def remove_sign_key(cls, values): class Headers(models.CraftBaseModel): """Assertion headers for a validation set.""" + headers: BuildAssertion """Assertion headers""" @@ -154,5 +161,6 @@ class ValidationSets(models.CraftBaseModel): https://dashboard.snapcraft.io/docs/reference/v2/en/validation-sets.html#id4 """ + assertions: list[Headers] """List of validation-set assertions""" diff --git a/snapcraft_legacy/yaml_utils/__init__.py b/snapcraft_legacy/yaml_utils/__init__.py index 42e49f4a35..6e8ac15535 100644 --- a/snapcraft_legacy/yaml_utils/__init__.py +++ b/snapcraft_legacy/yaml_utils/__init__.py @@ -89,7 +89,7 @@ def dump( data: Union[Dict[str, Any], yaml.YAMLObject], *, stream: Optional[TextIO] = None, - sort_keys=True + sort_keys=True, ) -> Optional[str]: """Safely dump YAML in ordered manner.""" return yaml.dump( diff --git a/snapcraft_legacy/yaml_utils/errors.py b/snapcraft_legacy/yaml_utils/errors.py index c3adb14954..683b48c4dc 100644 --- a/snapcraft_legacy/yaml_utils/errors.py +++ b/snapcraft_legacy/yaml_utils/errors.py @@ -28,7 +28,6 @@ class YamlValidationError(SnapcraftError): - fmt = "Issues while validating {source}: {message}" @classmethod diff --git a/spread.yaml b/spread.yaml index b7ac155b78..2e5e2d65b2 100644 --- a/spread.yaml +++ b/spread.yaml @@ -183,167 +183,166 @@ restore-each: | "$TOOLS_DIR"/restore.sh suites: - tests/spread/core20/: - summary: core20 specific tests - systems: - - ubuntu-20.04* - - tests/spread/core22/: - summary: core22 specific tests - systems: - - ubuntu-22.04 - - ubuntu-22.04-64 - - ubuntu-22.04-amd64 - - ubuntu-22.04-arm64 - - ubuntu-22.04-armhf - - ubuntu-22.04-s390x - - ubuntu-22.04-ppc64el - environment: - SNAPCRAFT_BUILD_ENVIRONMENT: "" - - tests/spread/core22/environment/: - summary: core22 environment tests - systems: - - ubuntu-22.04* - - tests/spread/core22/scriptlets/: - summary: core22 scriptlet tests - systems: - - ubuntu-22.04* - - tests/spread/core22/manifest/: - summary: core22 manifest tests - systems: - - ubuntu-22.04* - - tests/spread/core22/architectures/: - summary: core22 architecture tests - systems: - - ubuntu-22.04 - - ubuntu-22.04-64 - - ubuntu-22.04-amd64 - - tests/spread/core22/linters/: - summary: core22 linter tests - environment: - SNAPCRAFT_ENABLE_DEVELOPER_DEBUG: "n" - - systems: - - ubuntu-22.04* - - tests/spread/core22/patchelf/: - summary: core22 patchelf tests - systems: - - ubuntu-22.04* - - tests/spread/core24/: - summary: core24 specific tests - systems: - - ubuntu-24.04* - environment: - SNAPCRAFT_BUILD_ENVIRONMENT: "" - - tests/spread/core24-suites/environment/: - summary: core24 environment tests - systems: - - ubuntu-24.04* - - tests/spread/core24-suites/scriptlets/: - summary: core24 scriptlet tests - systems: - - ubuntu-24.04* - - tests/spread/core24-suites/manifest/: - summary: core24 manifest tests - systems: - - ubuntu-24.04* - - tests/spread/core24-suites/patchelf/: - summary: core24 patchelf tests - systems: - - ubuntu-24.04* - - # General, core suite - tests/spread/general/: - summary: tests of snapcraft core functionality - systems: - - ubuntu-20.04* - - ubuntu-22.04* - - tests/spread/general/hooks/: - summary: tests of snapcraft hook functionality - systems: - - ubuntu-20.04* - - ubuntu-22.04* - -# 'build-base: devel' fails due to an issue with the 24.10 buildd image (#4921) -# tests/spread/core-devel/: -# summary: tests of devel base snaps -# environment: -# SNAPCRAFT_BUILD_ENVIRONMENT: "" - - # General, core suite - tests/spread/cross-compile/: - summary: tests of supported cross-compile functionality - systems: - - ubuntu-20.04 - - ubuntu-20.04-64 - - ubuntu-20.04-amd64 - - # Use of multipass and lxd build providers - tests/spread/providers/: - summary: tests of snapcraft using build providers - systems: - - ubuntu-20.04-64 - - ubuntu-22.04-64 - kill-timeout: 180m - priority: 90 # Run this test relatively early since fetching images can take time - tests/spread/providers/legacy/: - summary: tests of snapcraft using build providers - systems: - - ubuntu-20.04-64 - kill-timeout: 180m - priority: 90 # Run this test relatively early since fetching images can take time - - # Plugin-specific suites - tests/spread/plugins/v2/: - summary: tests of snapcraft's v2 plugins - systems: - - ubuntu-20.04* - tests/spread/plugins/craft-parts/: - summary: tests of snapcraft's craft-part's based plugins - systems: - - ubuntu-22.04* - -# Extensions tests - tests/spread/extensions/: - summary: tests of snapcraft's extensions - kill-timeout: 20m - -# External snap tests - tests/spread/snaps/: - environment: - SNAPCRAFT_BUILD_ENVIRONMENT: "" - manual: true - summary: external snaps - prepare: | - sudo apt-get install git - sudo apt-mark auto git - - tests/spread/store/: - summary: tests of store-related snapcraft commands - manual: true - environment: - STORE_DASHBOARD_URL: https://dashboard.staging.snapcraft.io - STORE_API_URL: https://api.staging.snapcraft.io - STORE_UPLOAD_URL: https://storage.staging.snapcraftcontent.com - UBUNTU_ONE_SSO_URL: https://login.staging.ubuntu.com - - docs/howto/code/: - summary: tests how-to guides from the docs - systems: - - ubuntu-24.04-64 + tests/spread/core20/: + summary: core20 specific tests + systems: + - ubuntu-20.04* + + tests/spread/core22/: + summary: core22 specific tests + systems: + - ubuntu-22.04 + - ubuntu-22.04-64 + - ubuntu-22.04-amd64 + - ubuntu-22.04-arm64 + - ubuntu-22.04-armhf + - ubuntu-22.04-s390x + - ubuntu-22.04-ppc64el + environment: + SNAPCRAFT_BUILD_ENVIRONMENT: "" + + tests/spread/core22/environment/: + summary: core22 environment tests + systems: + - ubuntu-22.04* + + tests/spread/core22/scriptlets/: + summary: core22 scriptlet tests + systems: + - ubuntu-22.04* + + tests/spread/core22/manifest/: + summary: core22 manifest tests + systems: + - ubuntu-22.04* + + tests/spread/core22/architectures/: + summary: core22 architecture tests + systems: + - ubuntu-22.04 + - ubuntu-22.04-64 + - ubuntu-22.04-amd64 + + tests/spread/core22/linters/: + summary: core22 linter tests + environment: + SNAPCRAFT_ENABLE_DEVELOPER_DEBUG: "n" + + systems: + - ubuntu-22.04* + tests/spread/core22/patchelf/: + summary: core22 patchelf tests + systems: + - ubuntu-22.04* + + tests/spread/core24/: + summary: core24 specific tests + systems: + - ubuntu-24.04* + environment: + SNAPCRAFT_BUILD_ENVIRONMENT: "" + + tests/spread/core24-suites/environment/: + summary: core24 environment tests + systems: + - ubuntu-24.04* + + tests/spread/core24-suites/scriptlets/: + summary: core24 scriptlet tests + systems: + - ubuntu-24.04* + + tests/spread/core24-suites/manifest/: + summary: core24 manifest tests + systems: + - ubuntu-24.04* + + tests/spread/core24-suites/patchelf/: + summary: core24 patchelf tests + systems: + - ubuntu-24.04* + + # General, core suite + tests/spread/general/: + summary: tests of snapcraft core functionality + systems: + - ubuntu-20.04* + - ubuntu-22.04* + + tests/spread/general/hooks/: + summary: tests of snapcraft hook functionality + systems: + - ubuntu-20.04* + - ubuntu-22.04* + + # 'build-base: devel' fails due to an issue with the 24.10 buildd image (#4921) + # tests/spread/core-devel/: + # summary: tests of devel base snaps + # environment: + # SNAPCRAFT_BUILD_ENVIRONMENT: "" + + # General, core suite + tests/spread/cross-compile/: + summary: tests of supported cross-compile functionality + systems: + - ubuntu-20.04 + - ubuntu-20.04-64 + - ubuntu-20.04-amd64 + + # Use of multipass and lxd build providers + tests/spread/providers/: + summary: tests of snapcraft using build providers + systems: + - ubuntu-20.04-64 + - ubuntu-22.04-64 + kill-timeout: 180m + priority: 90 # Run this test relatively early since fetching images can take time + tests/spread/providers/legacy/: + summary: tests of snapcraft using build providers + systems: + - ubuntu-20.04-64 + kill-timeout: 180m + priority: 90 # Run this test relatively early since fetching images can take time + + # Plugin-specific suites + tests/spread/plugins/v2/: + summary: tests of snapcraft's v2 plugins + systems: + - ubuntu-20.04* + tests/spread/plugins/craft-parts/: + summary: tests of snapcraft's craft-part's based plugins + systems: + - ubuntu-22.04* + + # Extensions tests + tests/spread/extensions/: + summary: tests of snapcraft's extensions + kill-timeout: 20m + + # External snap tests + tests/spread/snaps/: + environment: + SNAPCRAFT_BUILD_ENVIRONMENT: "" + manual: true + summary: external snaps + prepare: | + sudo apt-get install git + sudo apt-mark auto git + + tests/spread/store/: + summary: tests of store-related snapcraft commands + manual: true + environment: + STORE_DASHBOARD_URL: https://dashboard.staging.snapcraft.io + STORE_API_URL: https://api.staging.snapcraft.io + STORE_UPLOAD_URL: https://storage.staging.snapcraftcontent.com + UBUNTU_ONE_SSO_URL: https://login.staging.ubuntu.com + + docs/howto/code/: + summary: tests how-to guides from the docs + systems: + - ubuntu-24.04-64 path: /snapcraft/ include: diff --git a/tests/unit/extensions/test_kde_neon.py b/tests/unit/extensions/test_kde_neon.py index cc7d5fd16f..279e21a51a 100644 --- a/tests/unit/extensions/test_kde_neon.py +++ b/tests/unit/extensions/test_kde_neon.py @@ -686,12 +686,15 @@ def test_get_parts_snippet_with_external_sdk_different_channel( kde_neon_extension_with_default_build_snap_from_latest_edge_core24, ): source = get_extensions_data_dir() / "desktop" / "command-chain-kde" - assert kde_neon_extension_with_default_build_snap_from_latest_edge_core24.get_parts_snippet() == { - "kde-neon/sdk": { - "source": str(source), - "plugin": "make", - "make-parameters": [ - "GPU_WRAPPER=gpu-2404-wrapper", - ], + assert ( + kde_neon_extension_with_default_build_snap_from_latest_edge_core24.get_parts_snippet() + == { + "kde-neon/sdk": { + "source": str(source), + "plugin": "make", + "make-parameters": [ + "GPU_WRAPPER=gpu-2404-wrapper", + ], + } } - } + ) diff --git a/tests/unit/extensions/test_kde_neon_6.py b/tests/unit/extensions/test_kde_neon_6.py index 173b7f5dc6..49aec14aa7 100644 --- a/tests/unit/extensions/test_kde_neon_6.py +++ b/tests/unit/extensions/test_kde_neon_6.py @@ -696,12 +696,15 @@ def test_get_parts_snippet_with_external_sdk_different_channel( kde_neon_6_extension_with_default_build_snap_from_latest_edge_core24, ): source = get_extensions_data_dir() / "desktop" / "command-chain-kde" - assert kde_neon_6_extension_with_default_build_snap_from_latest_edge_core24.get_parts_snippet() == { - "kde-neon-6/sdk": { - "source": str(source), - "plugin": "make", - "make-parameters": [ - "GPU_WRAPPER=gpu-2404-wrapper", - ], + assert ( + kde_neon_6_extension_with_default_build_snap_from_latest_edge_core24.get_parts_snippet() + == { + "kde-neon-6/sdk": { + "source": str(source), + "plugin": "make", + "make-parameters": [ + "GPU_WRAPPER=gpu-2404-wrapper", + ], + } } - } + ) diff --git a/tests/unit/services/test_lifecycle.py b/tests/unit/services/test_lifecycle.py index 36e0db8a75..77a7dfeeee 100644 --- a/tests/unit/services/test_lifecycle.py +++ b/tests/unit/services/test_lifecycle.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Tests for the Snapcraft Lifecycle service.""" + import json import platform import shutil diff --git a/tests/unit/services/test_lifecycle_components.py b/tests/unit/services/test_lifecycle_components.py index 314373a9d0..b8c01e91af 100644 --- a/tests/unit/services/test_lifecycle_components.py +++ b/tests/unit/services/test_lifecycle_components.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Tests for Components in Snapcraft's Lifecycle service.""" + import pytest from snapcraft import errors @@ -22,7 +23,6 @@ @pytest.fixture def extra_project_params(extra_project_params): - extra_project_params["components"] = { "firstcomponent": { "type": "test", @@ -52,7 +52,6 @@ def extra_project_params(extra_project_params): ], ) def test_lifecycle_get_prime_dir(lifecycle_service, component, expected_prime): - lifecycle_service.setup() assert ( diff --git a/tests/unit/services/test_package.py b/tests/unit/services/test_package.py index 9590130d01..dc1d0b78dc 100644 --- a/tests/unit/services/test_package.py +++ b/tests/unit/services/test_package.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Tests for the Snapcraft Package service.""" + import datetime import shutil from pathlib import Path diff --git a/tests/unit/services/test_package_components.py b/tests/unit/services/test_package_components.py index a4b93b3120..06321bede3 100644 --- a/tests/unit/services/test_package_components.py +++ b/tests/unit/services/test_package_components.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Tests for Components in Snapcraft's Package service.""" + import shutil from pathlib import Path from textwrap import dedent diff --git a/tests/unit/store/test_client.py b/tests/unit/store/test_client.py index f501151ebe..e0c0ee12b8 100644 --- a/tests/unit/store/test_client.py +++ b/tests/unit/store/test_client.py @@ -1190,8 +1190,7 @@ def test_list_confdbs_unmarshal_error(fake_client, list_confdbs_payload): assert str(raised.value) == "Received invalid confdbs set from the store" assert raised.value.details == ( - "Bad confdbs set content:\n" - "- field 'name' required in top-level configuration" + "Bad confdbs set content:\n- field 'name' required in top-level configuration" ) @@ -1237,8 +1236,7 @@ def test_build_confdbs_unmarshal_error(fake_client, build_confdbs_payload): assert str(raised.value) == "Received invalid confdbs set from the store" assert raised.value.details == ( - "Bad confdbs set content:\n" - "- field 'name' required in top-level configuration" + "Bad confdbs set content:\n- field 'name' required in top-level configuration" ) @@ -1303,8 +1301,7 @@ def test_post_confdbs_unmarshal_error(fake_client, post_confdbs_payload): assert str(raised.value) == "Received invalid confdbs set from the store" assert raised.value.details == ( - "Bad confdbs set content:\n" - "- field 'name' required in top-level configuration" + "Bad confdbs set content:\n- field 'name' required in top-level configuration" ) diff --git a/tests/unit/test_application.py b/tests/unit/test_application.py index 96510664a3..0dbd984f22 100644 --- a/tests/unit/test_application.py +++ b/tests/unit/test_application.py @@ -750,7 +750,7 @@ def test_get_argv_command(command, monkeypatch): "sys.argv", [ "snapcraft", - "--verbosity" "trace", + "--verbositytrace", "--build-for=armhf", "--shell-after", command, diff --git a/tests/unit/test_snap_config.py b/tests/unit/test_snap_config.py index 7cc56b770a..b57e71e372 100644 --- a/tests/unit/test_snap_config.py +++ b/tests/unit/test_snap_config.py @@ -15,6 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """Unit tests for SnapConfig class.""" + from unittest.mock import MagicMock, patch import pytest From b2703f07e34870bdcfeb2f6fa8c4b48e106dac49 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 15:20:41 -0500 Subject: [PATCH 315/333] test: mark slow tests --- tests/legacy/unit/build_providers/test_snap.py | 8 ++++++++ tests/legacy/unit/commands/test_gated.py | 2 ++ tests/legacy/unit/commands/test_validate.py | 2 ++ tests/legacy/unit/lifecycle/test_lifecycle.py | 4 ++++ tests/legacy/unit/lifecycle/test_status_cache.py | 2 ++ tests/legacy/unit/meta/test_meta.py | 12 ++++++++++++ tests/legacy/unit/pluginhandler/test_clean.py | 5 +++++ .../unit/pluginhandler/test_pluginhandler.py | 2 ++ .../legacy/unit/pluginhandler/test_scriptlets.py | 3 +++ tests/legacy/unit/pluginhandler/test_state.py | 10 ++++++++++ tests/legacy/unit/sources/test_git.py | 3 +++ tests/legacy/unit/store/test_store_client.py | 15 +++++++++++++++ tests/unit/commands/test_remote.py | 1 + 13 files changed, 69 insertions(+) diff --git a/tests/legacy/unit/build_providers/test_snap.py b/tests/legacy/unit/build_providers/test_snap.py index 762ad15c88..91b563fbf6 100644 --- a/tests/legacy/unit/build_providers/test_snap.py +++ b/tests/legacy/unit/build_providers/test_snap.py @@ -20,6 +20,7 @@ from unittest.mock import ANY, call, patch import fixtures +import pytest from testtools.matchers import Contains, Equals, FileContains, Not from snapcraft_legacy.internal.build_providers._snap import ( @@ -280,6 +281,7 @@ def test_snapcraft_installed_on_host_aliased_from_store(self): ), ) + @pytest.mark.slow def test_snapcraft_installed_on_host_from_store_but_injection_disabled(self): self.useFixture(fixture_setup.FakeStore()) @@ -319,6 +321,7 @@ def test_snapcraft_installed_on_host_from_store_but_injection_disabled(self): ), ) + @pytest.mark.slow def test_snapcraft_installed_on_host_in_parallel_install_from_store(self): """Handle a parallel-installed snapcraft and install from the store.""" self.useFixture(fixture_setup.FakeStore()) @@ -479,6 +482,7 @@ def test_snapcraft_installed_on_host_in_parallel_inject_from_host(self): ), ) + @pytest.mark.slow def test_snapcraft_not_installed_on_host(self): self.useFixture(fixture_setup.FakeStore()) @@ -517,6 +521,7 @@ def test_snapcraft_not_installed_on_host(self): ), ) + @pytest.mark.slow def test_snapcraft_not_installed_on_host_with_channel_from_environment(self): self.useFixture(fixture_setup.FakeStore()) self.useFixture( @@ -560,6 +565,7 @@ def test_snapcraft_not_installed_on_host_with_channel_from_environment(self): ), ) + @pytest.mark.slow def test_no_registry(self): self.useFixture(fixture_setup.FakeStore()) @@ -651,6 +657,7 @@ def test_snapcraft_installed_on_host_from_store_rerun_is_nop(self): self.provider.run_mock.assert_not_called() + @pytest.mark.slow def test_snapcraft_installed_on_host_from_store_rerun_refreshes(self): self.useFixture(fixture_setup.FakeStore()) @@ -684,6 +691,7 @@ def test_snapcraft_installed_on_host_from_store_rerun_refreshes(self): ] ) + @pytest.mark.slow def test_snapd_not_on_host_installs_from_store(self): self.useFixture(fixture_setup.FakeStore()) diff --git a/tests/legacy/unit/commands/test_gated.py b/tests/legacy/unit/commands/test_gated.py index a7a355cfce..615f4e3801 100644 --- a/tests/legacy/unit/commands/test_gated.py +++ b/tests/legacy/unit/commands/test_gated.py @@ -16,6 +16,7 @@ import textwrap +import pytest from testtools.matchers import Contains, Equals import snapcraft_legacy.storeapi.errors @@ -25,6 +26,7 @@ account_info_data = {"snaps": {"16": {"core": {"snap-id": "good"}}}} +@pytest.mark.slow class GatedCommandTestCase(StoreCommandsBaseTestCase): def test_gated_unknown_snap(self): raised = self.assertRaises( diff --git a/tests/legacy/unit/commands/test_validate.py b/tests/legacy/unit/commands/test_validate.py index a968cad1ed..daa77f3021 100644 --- a/tests/legacy/unit/commands/test_validate.py +++ b/tests/legacy/unit/commands/test_validate.py @@ -16,6 +16,7 @@ from unittest import mock import fixtures +import pytest from testtools.matchers import Contains, Equals, FileExists import snapcraft_legacy.storeapi.errors @@ -23,6 +24,7 @@ from . import StoreCommandsBaseTestCase +@pytest.mark.slow class ValidateCommandTestCase(StoreCommandsBaseTestCase): def setUp(self): super().setUp() diff --git a/tests/legacy/unit/lifecycle/test_lifecycle.py b/tests/legacy/unit/lifecycle/test_lifecycle.py index 814c6a23a9..db58760503 100644 --- a/tests/legacy/unit/lifecycle/test_lifecycle.py +++ b/tests/legacy/unit/lifecycle/test_lifecycle.py @@ -21,6 +21,7 @@ from unittest import mock import fixtures +import pytest from testtools.matchers import ( Contains, DirExists, @@ -45,6 +46,7 @@ from . import LifecycleTestBase +@pytest.mark.slow class ExecutionTestCase(LifecycleTestBase): def test_replace_in_parts(self): class Options: @@ -409,6 +411,7 @@ def test_non_prime_and_no_version(self): lifecycle.execute(steps.PULL, project_config) +@pytest.mark.slow class CleanTestCase(LifecycleTestBase): def test_clean_removes_global_state(self): project_config = self.make_snapcraft_project( @@ -444,6 +447,7 @@ def test_clean_leaves_prime_alone_for_tried(self, mock_for_root): ) +@pytest.mark.slow class RecordSnapcraftYamlTestCase(LifecycleTestBase): def test_prime_without_build_info_does_not_record(self): self.useFixture(fixtures.EnvironmentVariable("SNAPCRAFT_BUILD_INFO", None)) diff --git a/tests/legacy/unit/lifecycle/test_status_cache.py b/tests/legacy/unit/lifecycle/test_status_cache.py index 01e7b4176e..af3794d79c 100644 --- a/tests/legacy/unit/lifecycle/test_status_cache.py +++ b/tests/legacy/unit/lifecycle/test_status_cache.py @@ -21,7 +21,9 @@ from . import LifecycleTestBase +import pytest +@pytest.mark.slow class StatusCacheTestCase(LifecycleTestBase): def setUp(self): super().setUp() diff --git a/tests/legacy/unit/meta/test_meta.py b/tests/legacy/unit/meta/test_meta.py index 766f74846e..f1065ea086 100644 --- a/tests/legacy/unit/meta/test_meta.py +++ b/tests/legacy/unit/meta/test_meta.py @@ -24,6 +24,7 @@ import fixtures import testtools +import pytest from testtools.matchers import ( Annotate, Contains, @@ -43,6 +44,7 @@ from tests.legacy import fixture_setup, unit +@pytest.mark.slow class CreateBaseTestCase(unit.TestCase): def setUp(self): super().setUp() @@ -414,6 +416,7 @@ def test_ambiguous_key_fails(self): ) self.assertThat(raised.keys, Equals("'confinement'")) + @pytest.mark.slow def test_app_ambiguous_key_fails(self): self.config_data["apps"] = { "foo": { @@ -438,6 +441,7 @@ def test_hook_ambiguous_key_fails(self): ) self.assertThat(raised.keys, Equals("'plugs'")) + @pytest.mark.slow def test_warn_once_only(self): fake_logger = fixtures.FakeLogger(level=logging.INFO) self.useFixture(fake_logger) @@ -638,6 +642,7 @@ def setUp(self): class CreateMetadataFromSourceTestCase(CreateMetadataFromSourceBaseTestCase): + @pytest.mark.slow def test_create_metadata_with_missing_parse_info(self): del self.config_data["summary"] del self.config_data["parts"]["test-part"]["parse-info"] @@ -654,6 +659,7 @@ def test_create_metadata_with_wrong_adopt_info(self): ) self.assertThat(raised.part, Equals("wrong-part")) + @pytest.mark.slow def test_metadata_doesnt_overwrite_specified(self): fake_logger = fixtures.FakeLogger(level=logging.WARNING) self.useFixture(fake_logger) @@ -683,6 +689,7 @@ def _fake_extractor(file_path, workdir): ), ) + @pytest.mark.slow def test_metadata_with_unexisting_icon(self): def _fake_extractor(file_path, workdir): return extractors.ExtractedMetadata( @@ -694,6 +701,7 @@ def _fake_extractor(file_path, workdir): # The meta generation should just ignore the dead path, and not fail. self.generate_meta_yaml(build=True) + @pytest.mark.slow def test_metadata_satisfies_required_property(self): del self.config_data["summary"] @@ -711,6 +719,7 @@ def _fake_extractor(file_path, workdir): self.assertThat(y["summary"], Equals("extracted summary")) self.assertThat(y["description"], Equals(self.config_data["description"])) + @pytest.mark.slow def test_metadata_not_all_properties_satisfied(self): del self.config_data["summary"] del self.config_data["description"] @@ -813,6 +822,7 @@ def test_local_is_not_copied_to_snap_with_build_aux(self): self.assert_create_meta_with_hook("build-aux/snap") +@pytest.mark.slow class MetadataFromSourceWithIconFileTestCase(CreateMetadataFromSourceBaseTestCase): def assert_no_overwrite(self, snapcraft_assets_dir, directory, file_name): os.makedirs(directory) @@ -855,6 +865,7 @@ def test_build_aux_gui_png(self): self.assert_no_overwrite("build-aux/snap", "build-aux/snap/gui", "icon.png") +@pytest.mark.slow class MetadataFromSourceWithDesktopFileTestCase(CreateMetadataFromSourceBaseTestCase): def assert_no_overwrite(self, snapcraft_assets_dir, directory): os.makedirs(directory) @@ -892,6 +903,7 @@ def test_build_aux_gui(self): self.assert_no_overwrite("build-aux/snap", "build-aux/snap/gui") +@pytest.mark.slow class ScriptletsMetadataTestCase(CreateMetadataFromSourceBaseTestCase): def assert_scriptlets_satisfy_required_property( self, keyword, original, value, setter diff --git a/tests/legacy/unit/pluginhandler/test_clean.py b/tests/legacy/unit/pluginhandler/test_clean.py index f65a8f23c7..74fc710c6f 100644 --- a/tests/legacy/unit/pluginhandler/test_clean.py +++ b/tests/legacy/unit/pluginhandler/test_clean.py @@ -16,6 +16,7 @@ import pathlib from unittest.mock import MagicMock, call, patch +import pytest from testtools.matchers import Equals from snapcraft_legacy import file_utils @@ -73,6 +74,7 @@ def test_clean_part_remaining_parts(self, mock_listdir, mock_rmdir, mock_is_clea mock_listdir.assert_called_once_with(partdir) self.assertFalse(mock_rmdir.called) + @pytest.mark.slow def test_clean_prime_multiple_independent_parts(self): # Create part1 and get it through the "build" step. handler1 = self.load_part("part1") @@ -123,6 +125,7 @@ def test_clean_prime_multiple_independent_parts(self): "Expected part2's primeped files to be untouched", ) + @pytest.mark.slow def test_clean_prime_after_fileset_change(self): # Create part1 and get it through the "build" step. handler = self.load_part("part1") @@ -188,6 +191,7 @@ def test_clean_prime_old_prime_state(self): self.assertThat(raised.step, Equals(steps.PRIME)) self.assertTrue(os.path.isfile(primed_file)) + @pytest.mark.slow def test_clean_stage_multiple_independent_parts(self): # Create part1 and get it through the "build" step. handler1 = self.load_part("part1") @@ -299,6 +303,7 @@ def test_clean_stage_old_stage_state(self): self.assertTrue(os.path.isfile(staged_file)) +@pytest.mark.slow class TestCleanPrime: scenarios = [ ("all", {"fileset": ["*"]}), diff --git a/tests/legacy/unit/pluginhandler/test_pluginhandler.py b/tests/legacy/unit/pluginhandler/test_pluginhandler.py index d65989f191..7b0bcb0815 100644 --- a/tests/legacy/unit/pluginhandler/test_pluginhandler.py +++ b/tests/legacy/unit/pluginhandler/test_pluginhandler.py @@ -789,6 +789,7 @@ def test_organize( ) +@pytest.mark.slow class RealStageTestCase(unit.TestCase): def setUp(self): super().setUp() @@ -1435,6 +1436,7 @@ def test_get_excludes(self): class SourcesTestCase(unit.TestCase): + @pytest.mark.slow def test_do_not_follow_links(self): properties = dict(source=".") handler = self.load_part("test-part", part_properties=properties) diff --git a/tests/legacy/unit/pluginhandler/test_scriptlets.py b/tests/legacy/unit/pluginhandler/test_scriptlets.py index a166dd7f4e..f266d46798 100644 --- a/tests/legacy/unit/pluginhandler/test_scriptlets.py +++ b/tests/legacy/unit/pluginhandler/test_scriptlets.py @@ -21,6 +21,7 @@ from unittest import mock import fixtures +import pytest import testtools from testscenarios.scenarios import multiply_scenarios from testtools.matchers import Equals @@ -31,6 +32,8 @@ from tests.legacy.unit.commands import CommandBaseTestCase +pytestmark = [pytest.mark.slow] + class ScriptletCommandsTestCase(CommandBaseTestCase): def setUp(self): super().setUp() diff --git a/tests/legacy/unit/pluginhandler/test_state.py b/tests/legacy/unit/pluginhandler/test_state.py index 633a55b2d8..6fc9b7cf4b 100644 --- a/tests/legacy/unit/pluginhandler/test_state.py +++ b/tests/legacy/unit/pluginhandler/test_state.py @@ -19,6 +19,7 @@ from unittest.mock import call, patch import fixtures +import pytest from testtools.matchers import Contains, Equals from snapcraft_legacy import extractors @@ -313,6 +314,7 @@ def _fake_extractor(file_path, workdir): files, Equals([os.path.join(self.handler.part_build_dir, "metadata-file")]) ) + @pytest.mark.slow def test_build_state_with_scriptlet_metadata(self): self.handler = self.load_part( "test_part", @@ -385,6 +387,7 @@ def test_stage_state(self): self.assertTrue(type(state.project_options) is OrderedDict) self.assertThat(len(state.project_options), Equals(0)) + @pytest.mark.slow def test_stage_state_with_scriptlet_metadata(self): self.handler = self.load_part( "test_part", @@ -532,6 +535,7 @@ def test_clean_stage_old_state(self): self.assertThat(raised.step, Equals(steps.STAGE)) + @pytest.mark.slow @patch("shutil.copy") def test_prime_state(self, mock_copy): self.assertRaises(errors.NoLatestStepError, self.handler.latest_step) @@ -571,6 +575,7 @@ def test_prime_state(self, mock_copy): self.assertTrue(type(state.project_options) is OrderedDict) self.assertThat(len(state.project_options), Equals(0)) + @pytest.mark.slow def test_prime_state_with_scriptlet_metadata(self): self.handler = self.load_part( "test_part", @@ -608,6 +613,7 @@ def test_prime_state_with_scriptlet_metadata(self): metadata = state.scriptlet_metadata self.assertThat(metadata.get_version(), Equals("override-version")) + @pytest.mark.slow @patch("shutil.copy") def test_prime_state_with_stuff_already_primed(self, mock_copy): self.assertRaises(errors.NoLatestStepError, self.handler.latest_step) @@ -650,6 +656,7 @@ def test_prime_state_with_stuff_already_primed(self, mock_copy): self.assertTrue(type(state.project_options) is OrderedDict) self.assertThat(len(state.project_options), Equals(0)) + @pytest.mark.slow @patch("snapcraft_legacy.internal.elf.ElfFile._extract_attributes") @patch("snapcraft_legacy.internal.elf.ElfFile.load_dependencies") @patch("snapcraft_legacy.internal.pluginhandler._migrate_files") @@ -721,6 +728,7 @@ def test_prime_state_with_dependencies( self.assertTrue(type(state.project_options) is OrderedDict) self.assertThat(len(state.project_options), Equals(0)) + @pytest.mark.slow @patch("snapcraft_legacy.internal.elf.ElfFile._extract_attributes") @patch("snapcraft_legacy.internal.elf.ElfFile.load_dependencies") @patch("snapcraft_legacy.internal.pluginhandler._migrate_files") @@ -779,6 +787,7 @@ def test_prime_state_missing_libraries( # The rest should be considered missing. self.assertThat(state.dependency_paths, Equals({"lib3"})) + @pytest.mark.slow @patch("snapcraft_legacy.internal.elf.ElfFile._extract_attributes") @patch("snapcraft_legacy.internal.elf.ElfFile.load_dependencies") @patch("snapcraft_legacy.internal.pluginhandler._migrate_files") @@ -825,6 +834,7 @@ def test_prime_state_with_shadowed_dependencies( self.assertTrue(type(state) is states.PrimeState) self.assertThat(state.dependency_paths, Equals({"foo/bar"})) + @pytest.mark.slow @patch("shutil.copy") def test_prime_state_with_prime_keyword(self, mock_copy): self.handler = self.load_part("test_part", part_properties={"prime": ["bin/1"]}) diff --git a/tests/legacy/unit/sources/test_git.py b/tests/legacy/unit/sources/test_git.py index dc1753f1ca..221b71fb2d 100644 --- a/tests/legacy/unit/sources/test_git.py +++ b/tests/legacy/unit/sources/test_git.py @@ -20,6 +20,7 @@ from unittest import mock import fixtures +import pytest from testtools.matchers import Equals from snapcraft_legacy.internal import sources @@ -652,6 +653,7 @@ def check_file_contents(self, path, expected): self.assertThat(body, Equals(expected)) +@pytest.mark.slow class TestGitConflicts(GitBaseTestCase): """Test that git pull errors don't kill the parser""" @@ -773,6 +775,7 @@ def test_git_submodules(self): ) +@pytest.mark.slow class GitDetailsTestCase(GitBaseTestCase): def setUp(self): def _add_and_commit_file(filename, content=None, message=None): diff --git a/tests/legacy/unit/store/test_store_client.py b/tests/legacy/unit/store/test_store_client.py index 3309bf13bf..2bfe0b7493 100644 --- a/tests/legacy/unit/store/test_store_client.py +++ b/tests/legacy/unit/store/test_store_client.py @@ -48,6 +48,7 @@ def setUp(self): self.client.login(email="dummy", password="test correct password", ttl=2) +@pytest.mark.slow class DownloadTestCase(StoreTestCase): # sha3-384 of tests/data/test-snap.snap EXPECTED_SHA3_384 = "" @@ -153,6 +154,7 @@ def test_download_with_hash_mismatch_raises_exception(self): ) +@pytest.mark.slow class PushSnapBuildTestCase(StoreTestCase): def test_push_snap_build_invalid_data(self): raised = self.assertRaises( @@ -171,6 +173,7 @@ def test_push_snap_build_successfully(self): self.client.push_snap_build("snap-id", "dummy") +@pytest.mark.slow class GetAccountInformationTestCase(StoreTestCase): def test_get_account_information_successfully(self): self.assertThat( @@ -242,6 +245,7 @@ def test_get_account_information_successfully(self): ) +@pytest.mark.slow class RegisterKeyTestCase(StoreTestCase): def test_register_key_successfully(self): # No exception will be raised if this is successful. @@ -269,6 +273,7 @@ def test_invalid_data(self): ) +@pytest.mark.slow class RegisterTestCase(StoreTestCase): def test_register_name_successfully(self): # No exception will be raised if this is successful @@ -374,6 +379,7 @@ def test_unhandled_registration_error_path(self): ) +@pytest.mark.slow class ValidationSetsTestCase(StoreTestCase): def setUp(self): super().setUp() @@ -534,6 +540,7 @@ def test_get_invalid_sequence(self): ) +@pytest.mark.slow class ValidationsTestCase(StoreTestCase): def setUp(self): super().setUp() @@ -618,6 +625,7 @@ def test_push_bad_response(self): self.assertIn("Invalid response from the server", self.fake_logger.output) +@pytest.mark.slow class ReleaseTest(StoreTestCase): def test_release_snap(self): channel_map = self.client.release("test-snap", "19", ["beta"]) @@ -689,6 +697,7 @@ def test_release_to_curly_braced_channel(self): ) +@pytest.mark.slow class GetSnapStatusTestCase(StoreTestCase): def setUp(self): super().setUp() @@ -799,6 +808,7 @@ def test_get_snap_status_no_id(self): self.assertThat(e.snap_name, Equals("no-id")) +@pytest.mark.slow class SnapsMetricsTest(StoreTestCase): def test_get_metrics(self): mf = metrics.MetricsFilter( @@ -868,6 +878,7 @@ def test_get_metrics_unmarshal_error(self): ) +@pytest.mark.slow class WhoAmITest(StoreTestCase): def test_whoami(self): self.assertThat( @@ -876,6 +887,7 @@ def test_whoami(self): ) +@pytest.mark.slow class SignDeveloperAgreementTestCase(StoreTestCase): def test_sign_dev_agreement_success(self): response = { @@ -904,6 +916,7 @@ def test_sign_dev_agreement_exception(self): ) +@pytest.mark.slow class UploadMetadataTestCase(StoreTestCase): def setUp(self): super().setUp() @@ -1003,6 +1016,7 @@ def test_braces_in_error_messages_are_literals(self): self.assertThat(str(raised), Equals(dedent(should).strip())) +@pytest.mark.slow class UploadBinaryMetadataTestCase(StoreTestCase): def setUp(self): super().setUp() @@ -1091,6 +1105,7 @@ def test_braces_in_error_messages_are_literals(self): self.assertThat(str(raised), Equals(dedent(should).strip())) +@pytest.mark.slow class SnapNotFoundTestCase(StoreTestCase): def _setup_snap(self): """Login, register and upload a snap. diff --git a/tests/unit/commands/test_remote.py b/tests/unit/commands/test_remote.py index eb9a32c8ec..3e1856cacb 100644 --- a/tests/unit/commands/test_remote.py +++ b/tests/unit/commands/test_remote.py @@ -224,6 +224,7 @@ def test_command_accept_upload( mock_run_remote_build.assert_called_once() +@pytest.mark.slow @pytest.mark.parametrize("base", const.CURRENT_BASES) @pytest.mark.usefixtures( "mock_argv", "mock_confirm", "emitter", "fake_services", "fake_sudo" From eef0002c0e49fb1dd6cc141383ece449f0dbb95a Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 15:41:58 -0500 Subject: [PATCH 316/333] chore: remove outdated/unused top-level files --- .shellcheckrc | 5 -- manual-tests.md | 212 ------------------------------------------------ runtests.sh | 70 ---------------- todo.org | 88 -------------------- units.py | 5 -- 5 files changed, 380 deletions(-) delete mode 100644 .shellcheckrc delete mode 100644 manual-tests.md delete mode 100755 runtests.sh delete mode 100644 todo.org delete mode 100644 units.py diff --git a/.shellcheckrc b/.shellcheckrc deleted file mode 100644 index 99235f886e..0000000000 --- a/.shellcheckrc +++ /dev/null @@ -1,5 +0,0 @@ -# NOTE: these disables are only necessary while the core24 spread tests are -# being fixed; they refer to unreachable code, unused variable, etc. -# This file must be removed once all tests in tests/spread/core24/ are fixed. -disable=SC2317,SC2034,SC2154 - diff --git a/manual-tests.md b/manual-tests.md deleted file mode 100644 index 1803ecb9f5..0000000000 --- a/manual-tests.md +++ /dev/null @@ -1,212 +0,0 @@ -# Test log in with one-time password - -1. Set up an SSO account with two-factor authentication. -2. Run snapcraft logout -3. Run snapcraft login -4. Enter the email address. -5. Enter the password. -6. Enter the one-time password. - - - Check that the log in was successful. - -# Test file ownership is retained - -1. 'snapcraft build' a simple snap -2. sudo touch install/test-owner-file -3. sudo chown nobody:nogroup install/test-owner-file -4. sudo snapcraft prime -5. ensure that prime/test-owner-file is owned by nobody and nogroup - -# Test stage package caching - -1. `snapcraft pull` a snap that has `parts` with `stage-packages`. -2. Run `snapcraft clean`. -3. Verify there is cached apt data in `~/.cache/snapcraft/<hash>/` -4. Run `snapcraft pull` again and notice the download is minimal. -5. Wipe the cached apt data. -6. Run `snapcraft pull` again and notice the download is as in `1.`. -7. Run this test again, but run snapcraft on a partition separated - from $HOME. - -# Test cross-compilation with Go - -1. Go to integration_tests/snaps/go-hello. -2. Run `snapcraft snap --target-arch=armhf`. -3. Copy the snap to a Raspberry Pi. -4. Install the snap. -5. Run `go-hello`. - -# Test cross-compilation with Rust - -1. Go to integration_tests/snaps/rust-hello. -2. Run `snapcraft snap --target-arch=armhf`. -3. Copy the snap to a Raspberry Pi. -4. Install the snap. -5. Run `rust-hello`. - -# Test cross-compilation with Autotools - -1. Go to integration_tests/snaps/autotools-hello. -2. Run `snapcraft snap --target-arch=armhf`. -3. Copy the snap to a Raspberry Pi. -4. Install the snap. -5. Run `autotools-hello`. - -# Test cross-compilation with Waf - -1. Go to integration_tests/snaps/waf-with-configflags. -2. Run `snapcraft snap --target-arch=armhf`. -3. Copy the snap to a Raspberry Pi. -4. Install the snap. -5. Run `waf-with-configflags`. - -# Test the PC kernel. - -1. Get the PC kernel source: - - $ git clone -b pc https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux-snap/+git/xenial - $ cd xenial - -2. Run `sudo snapcraft`. -3. Create a file called `pc-model.json` with the following contents: - - { - "type": "model", - "authority-id": "$account_id", - "brand-id": "$account_id", - "series": "16", - "model": "pc", - "architecture": "amd64", - "gadget": "pc", - "kernel": "$kernel_snap_path", - "timestamp": "$date" - } - -4. Replace `$account_id` with the value from https://myapps.developer.ubuntu.com/dev/account/ -5. Replace `$kernel_snap_path` with the path to the snap you just created. -6. Replace `$date` with the output of the command `date -Iseconds --utc`. -7. If you haven't created a key, run the following command, replacing - `$key_name` with a name for your key: - - $ snap create-key $key_name - $ snapcraft register-key - -8. Sign the model: - - $ cat pc-model.json | snap sign -k $key_name > pc.model - -9. Install ubuntu-image: - - $ sudo apt install ubuntu-image - -10. Create the image: - - $ sudo ubuntu-image --image-size 3G -O ubuntu-core-16 pc.model --extra-snaps $kernel_snap_path - -11. Start the image in kvm: - - $ kvm -smp 2 -m 1500 -netdev user,id=mynet0,hostfwd=tcp::8022-:22,hostfwd=tcp::8090-:80 -device virtio-net-pci,netdev=mynet0 -drive file=ubuntu-core-16/pc.img,format=raw - -- Check that the user can be created. -- Check that it's possible to ssh into the vm. -- Check that it's possible to install a snap. - -# Test the dragonboard 410c kernel. - -1. Download https://developer.qualcomm.com/download/db410c/linux-board-support-package-v1.2.zip -2. Extract it and copy the file `firmware.tar` to the directory `demos/96boards-kernel`. -3. Run `snapcraft snap --target-arch arm64` in the `demos/96boards-kernel` directory. -4. Create a file called `dragonboard-model.json` with the following contents: - - { - "type": "model", - "authority-id": "$account_id", - "brand-id": "$account_id", - "series": "16", - "model": "dragonboard", - "architecture": "arm64", - "gadget": "dragonboard", - "kernel": "$kernel_snap_path", - "timestamp": "$date" - } - -5. Replace `$account_id` with the value from https://myapps.developer.ubuntu.com/dev/account/ -6. Replace `$kernel_snap_path` with the path to the snap you just created. -7. Replace `$date` with the output of the command `date -Iseconds --utc`. -8. If you haven't created a key, run the following command, replacing - `$key_name` with a name for your key: - - $ snap create-key $key_name - $ snapcraft register-key - -9. Sign the model: - - $ cat dragonboard-model.json | snap sign -k $key_name > dragonboard.model - -10. Install ubuntu-image: - - $ sudo apt install ubuntu-image - -11. Create the image: - - $ sudo ubuntu-image -O ubuntu-core-16 dragonboard.model --extra-snaps $kernel_snap_path - -12. Insert an sdcard into the host PC. -13. Umount the sdcard partitions. -14. Flash the image, replacing sdX with the path to the sdcard: - - $ sudo dd if=ubuntu-core-16/dragonboard.img of=/dev/sdX bs=32M - $ sync - -15. Insert the sdcard into the dragonboard, and turn it on. - -- Check that the user can be created. -- Check that it's possible to ssh into the board. -- Check that it's possible to install a snap. - -# Test installing with `pip` - -1. Follow HACKING.md to install using `pip` without using --editable. -2. Make sure Snapcraft works by running `snapcraft init` followed by `snapcraft`. -3. Follow HACKING.md to install using `pip` while using --editable. -4. Repeat step 2. - -# Test push metadata with conflicts - -1. 'snapcraft snap' a simple snap -2. Do a simple 'snapcraft push SNAP' -3. Go to the Web and change snap's description -4. Change the snap's description in the YAML file to something different than you put in the Web -5. Try to update snap's metadata doing `snapcraft push-metadata SNAP` - - - Check that it should error with "conflict" on the description field - -6. Force the update doing `snapcraft push-metadata SNAP --force` - - - Check that it should end ok - - Check in the Web that the description is now what the YAML says - -# Test push binary metadata with conflicts - -1. 'snapcraft snap' a simple snap -2. Do a simple 'snapcraft push SNAP' -3. Go to the Web and change snap's icon -4. Change the snap's icon in the YAML file to something different than you put in the Web -5. Try to update snap's metadata using `snapcraft push-metadata SNAP` - - - Check that it should error with "conflict" on the icon field - -6. Force the update doing `snapcraft push-metadata SNAP --force` - - - Check that it should end ok - - Check in the Web that the icon is now what the YAML says - -# Test creating a macaroon with a specific expiration - -1. Take note of the current date. Pick a date two days later, and convert it - into ISO 8601. For example, midnight on February 5th, 2019 is - '2019-02-05T00:00:00'. -2. Run 'snapcraft export-login --expires="2019-02-05T00:00:00" exported', using - the expiration date you calculated. -3. Snapcraft will print the capabilities of the exported login. Verify that the - expiration date you requested is the one that it prints. diff --git a/runtests.sh b/runtests.sh deleted file mode 100755 index b17489f685..0000000000 --- a/runtests.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash -# -*- Mode:sh; indent-tabs-mode:nil; tab-width:4 -*- -# -# Copyright (C) 2015-2018 Canonical Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 3 as -# published by the Free Software Foundation. -# -# 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.f-1 -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -set -e - -usage() { - echo "Usage: " - echo " ./runtests.sh static" - echo " ./runtests.sh tests/integration[/<test-suite>]" - echo " ./runtests.sh spread" - echo "" - echo "<test-suite> can be one of: $(find tests/integration/ -mindepth 1 -maxdepth 1 -type d ! -name __pycache__ | tr '\n' ' ')" - echo "<use-run> makes use of run instead of discover to run the tests" -} - -run_static_tests() { - make tests-static -} - -run_snapcraft_tests(){ - test_suite="$1" - - python3 -m unittest discover -b -v -s "$test_suite" -t . -} - -run_spread(){ - TMP_SPREAD="$(mktemp -d)" - curl -s https://storage.googleapis.com/snapd-spread-tests/spread/spread-amd64.tar.gz | tar xzv -C "$TMP_SPREAD" - - if [[ "$#" -eq 0 ]]; then - "$TMP_SPREAD/spread" -v lxd: - else - "$TMP_SPREAD/spread" -v "$@" - fi -} - -if [[ "$#" -eq 0 ]]; then - usage - exit 1 -fi - -test_suite=$1 -shift - -if [[ "$test_suite" == "static" ]]; then - run_static_tests -elif [[ "$test_suite" == "spread" ]]; then - run_spread "$@" -elif [[ "$test_suite" == "-h" ]] || [[ "$test_suite" == "help" ]]; then - usage - exit 0 -else - run_snapcraft_tests "$test_suite" "$@" -fi - -echo -e '\e[1;32mEverything passed\e[0m' diff --git a/todo.org b/todo.org deleted file mode 100644 index bce3474c32..0000000000 --- a/todo.org +++ /dev/null @@ -1,88 +0,0 @@ -#+TITLE: Snapcraft Tasks -#+STARTUP: content -#+TODO: TODO(t) STRT(s) | DONE(d) CANCELED(c) - -* Specifications - -** 2020 - -*** STRT [[file:specifications/core20-plugins.org][Snapcraft Core20 Plugins]] [7/11] - -- [X] Move =BasePlugin= to a v1 import path -- [X] Add backwards compatibility for =BasePlugin= -- [X] Rework in-tree plugin importing into a map -- [X] Introduce =snapcraft.plugins.v2.PluginV2= -- [X] Add =PluginHandler= logic for the =core20= plugin -- [ ] Plugin manifest generation. -- [ ] Detection of property changes for rebuilds. -- [X] Add CLI support for =help= -- [X] Add CLI support for =list-plugins= -- [ ] Add CLI support for =expand-plugins= -- [X] Introduce new custom plugin loading logic for =core20= - -*** TODO [[file:specifications/enabling-experimental-features.org][Enabling Experimental Features]] - -*** DONE [[file:specifications/enabling-experimental-lzo-compression.org][Enabling Experimental LZO Compression]] [3/3] -CLOSED: [2020-06-24] -- [X] Amend schema to allow =compression= -- [X] Replace =mksquashfs= with =snap pack= -- [X] Toggle compression with =snap pack= - -*** STRT [[file:specifications/progressive-releases.org][Progressive Releases]] [6/11] - -- [X] Implement channel-map endpoint -- [X] Add support for the status command -- [X] Add support for the release command -- [X] Add support for the close command -- [X] Add support for the promote command -- [X] Add support for the upload and release command -- [ ] Migrate promote away from using the state endpoint -- [ ] Remove the state endpoint -- [ ] Add support for metrics -- [ ] Add support for specific channel-map endpoint errors -- [ ] Remove experimental flag - -*** TODO [[file:specifications/environment-management.org][Build Environment Management]] [/] - -- [ ] Implement general datastore. -- [ ] Implement provider datastore. -- [ ] Migrate BuildProviders to new provider datastores. -- [ ] Implement =snapcraft clean --all-projects= command. -- [ ] Implement =snapcraft clean --all-projects --dry-run= command. -- [ ] Update providers to match documented lifecycle. -- [ ] Update documentation on snapcraft.io. - -*** STRT [[file:specifications/flutter-extension.org][Flutter Extension]] [2/4] - -- [X] Add extension variant for master -- [X] Add extension variant for dev -- [ ] Add extension variant for beta -- [ ] Add extension variant for stable - -*** TODO [[file:specifications/default-tracks.org][Default Tracks]] [2/4] - -- [X] Implement =snapcraft set-default-tracks= -- [ ] Error handling for setting invalid track names ([[https://bugs.launchpad.net/snapcraft/+bug/1892553][LP: 1892553]]) -- [X] Implement =snapcraft list-tracks= -- [ ] Add documentation for track management to the [[https://snapcraft.io/docs/release-management][Release management]] docs. - -*** TODO [[file:specifications/configurable-apt-mirror.org][Configurable APT Mirror]] [0/7] -- [ ] Add =--snapcraft-apt-mirror= command-line argument with matching - =SNAPCRAFT_APT_MIRROR= environment variable. -- [ ] Replace usage of =SNAPCRAFT_BUILD_ENVIRONMENT_PRIMARY_MIRROR= with - =SNAPCRAFT_APT_MIRROR=. - -*** DONE [[file:specifications/desktop-extensions-font-hook.org][Desktop Extensions Font Hook]] [3/3] -CLOSED: [2020-10-01 jue 10:00] - -- [X] Support hook stubs when =command-chain= is defined -- [X] Generate =configure= hook =command-chain= in desktop parts -- [X] Extend yaml for neon, gnome-2-28 and gnome-3-34 to use desktop - part's =command-chain= for the =configure= hook - -*** DONE [[file:specifications/history-to-releases.org][Snap Store API migration from v1 history to v2 releases]] [3/3] -CLOSED: [2020-10-22] - -- [X] Add bindings to Snap Store package -- [X] Use releases bindings for CLI implementing new output -- [X] Remove v1 history bindings diff --git a/units.py b/units.py deleted file mode 100644 index 16351b2fa9..0000000000 --- a/units.py +++ /dev/null @@ -1,5 +0,0 @@ -import unittest - -unittest.main( - "snapcraft_legacy.tests.unit.commands.test_build", argv=["BuildCommandTestCase"] -) # noqa From eeb8424f43409f7a2e39a0fb40b89dadceb0e826 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 15:53:29 -0500 Subject: [PATCH 317/333] docs: delete now-obsolete TESTING.md The only part of TESTING.md that remained relevant to modern Snapcraft was the information on Spread, which itself was slightly out of date. This migrates that Spread info to HACKING.MD and deletes the rest. --- HACKING.md | 54 ++++++++++++++- TESTING.md | 195 ----------------------------------------------------- 2 files changed, 53 insertions(+), 196 deletions(-) delete mode 100644 TESTING.md diff --git a/HACKING.md b/HACKING.md index 6693175776..1a8b5fb39d 100644 --- a/HACKING.md +++ b/HACKING.md @@ -47,7 +47,59 @@ you with tox, but you'll need to install: ### Testing -See the [Testing guide](TESTING.md). +By default, our CI suite will run both unit and integration testing on every PR. Generally speaking, it's good to run unit tests before pushing any code anyways as they are quick and great for catching bugs early. Integration tests, on the other hand, are quite heavy and slow to run locally. Due to this, we only recommend running the integration tests locally if there is an obvious need, such as debugging an integration test that failed in CI. + +#### Unit testing + +For unit testing, use the provided make recipes: + +```shell +make test # All unit tests +make test-fast # Only the fast tests +make test-slow # Only the slow tests +``` + +#### Integration testing + +For integration testing, Snapcraft uses [Spread](https://github.com/canonical/spread). Spread is a system for distributing tests and executing them in different backends, in parallel. + +To test with Spread, first fetch the Spread testing tools: + +```shell +git submodule update --init +``` + +Next, build Snapcraft into a snap: + +```shell +snapcraft pack +``` + +Then, move the resulting snap into the tests directory: + +```shell +mv *.snap tests/ +``` + +Next, install Spread with Go: + +```shell +go install github.com/snapcore/spread/cmd/spread@latest +``` + +Ensure that the installation added the `$HOME/go/bin` directory to the `$PATH` environment variable. + +Then, you can run the integration tests using a local LXD backend with: + +```shell +spread -v lxd: +``` + +You can also run them in Google Cloud if you have a Google Cloud credentials JSON file. In order to do this, run: + +```shell +SPREAD_GOOGLE_KEY={credentials_path} spread -v google: +``` ### Enabling debug output diff --git a/TESTING.md b/TESTING.md deleted file mode 100644 index 1d111f8a1c..0000000000 --- a/TESTING.md +++ /dev/null @@ -1,195 +0,0 @@ -# Snapcraft tests - -## Manual tests - -Snapcraft has a few manual tests documented in [manual-tests.md](manual-tests.md). -These are tests for features that are not possible to automate, or that the complexity of automating them is too high while the time it takes to run them by hand is not too much. - -We try very hard to automate as much as possible and to keep the manual test suite as small as possible. Please do not add a manual test before discussing it with the team, and make sure that there are very good reasons not to automate it. - -When running manual tests against the production store, make sure to use the test user email account and the well-known test prefixes, since these snaps will pollute the store. To register a user, use an email address like snapcraft-test+<your-user-name>-<unique-id>@canonical.com (e.g., snapcraft-test+elopio-123@canonical.com). This will send the confirmation email and any notifications to the inbox of snapcraft-test@canonical.com, and the snapcraft team has the password to access that inbox. To register a snap or anything else that has a name, like tracks, keys, etc., prefix the name with test-snapcraft and your name (e.g., test-snapcraft-snap-elopio-123, test-snapcraft-track-elopio-111). - -### Staging server - -Snapcraft has the ability to upload snaps for publication in the Snappy Store. If you're working on a feature that requires you to interact with the store, you might want to use the staging server instead of the production store. To do that, make sure you have an account on the [staging server](https://login.staging.ubuntu.com), then run: - - source tools/staging_env.sh - -You will see a prompt indicating that you are going to be talking to the staging server. Once you are done working with the staging servers you can run `deactivate`. - -## Automated tests in the snapcraft repository - -The snapcraft repository has multiple suites of automated tests which run the code at different levels, following different principles of what to execute, how to force different code paths, and how to verify the results. - -### Static tests - -The static tests suite performs a static analysis on the source code without executing it. It will catch syntax and code style errors. - -### Unit tests - -The unit tests is a suite of low-level white box tests. They exercise units of code to verify that the different parts work as expected in a fully isolated way. Ideally, these tests should call only public functions, objects and methods, leaving the internals of snapcraft as implementation details that can change without having to modifying any tests. To isolate the units from their environment and dependencies we can replace those with test doubles. In order to set up test doubles, we prefer dependency injection through arguments than excessive mocking. These tests can verify the results checking the output printed to the command line, checking the files created during the execution, inspecting the calls made to the test doubles and verifying that the expected exceptions were thrown. - -These tests are in the `tests/unit` directory. - -### Integration tests - -The integration tests are a group of suites that exercise snapcraft as a black box. They are only allowed to set up the environment where snapcraft runs and create files; but for the execution phase of the test they can only run the snapcraft command or one of its subcommands. To verify the results they can check the output printed to the command line, the return value of the snapcraft command, and any files created during the execution. - -These tests are in the `tests/integration` directory, with the `snapcraft.yamls` and other source files for the tests snaps in `tests/integration/snaps`. - -At any time, an integration test may fail and given the use of temporary directories it can be hard to inspect what went on. When working on a specific test case you can set the environment variable `SNAPCRAFT_TEST_KEEP_DATA_PATH` to a directory path for the sepecic test. -This mechanism will only work when working with individual tests and will fail to run with a batch of them. - -### Snaps tests - -The snaps tests is a suite of high-level tests that try to simulate real-world scenarios of a user interacting with snapcraft. They cover the call to snapcraft to generate a snap file from the source files of a fully functional project, the installation of the resulting snap, and the execution of the binaries and services of this snap. - -These tests are in the `snaps_tests` directory, with the sources for the test snaps in the `demos` directory. - -### Setting up the environment - -In order to run these tests suites, first you will need to set up your development environment. Follow the steps in the [Hacking guide](HACKING.md) to install for development. - -### Running the tests - -To run the static tests, execute: - - make tests-static - -To run the unit tests, execute: - - make test-units - -...or use pytest directly: - - pytest tests/unit - -You can also run a subsuite of the unit suites specifying the path to the directory. -For example: - -- To run only the unit tests for the plugins: - - ``` - pytest tests/unit/parts/plugins - ``` - -- To run only the integration tests for the store: - - ``` - pytest tests/unit/store - ``` - -The snaps tests script has more complex arguments. For an explanation of them, run: - - python3 -m snaps_tests -h - -The integration and snaps suites can be run using the snapcraft source from the repository, or using the snapacraft command installed in the system. By default, they will use the source code, so you can modify your clone of the repository and verify that your changes are correct. If instead you want to verify that the snapcraft version installed in your system is correct, run them with the environment variable `SNAPCRAFT_PACKAGE_TYPE` set to either "snap" or "deb", like this: - - SNAPCRAFT_PACKAGE_TYPE=snap ./runtests.sh tests/integration - -or - - SNAPCRAFT_PACKAGE_TYPE=type ./runtests.sh tests/integration - -## Setting up the store test user - -The store tests by default will start fake servers that are configured to reply like the real store does. But you can run them also against the staging and production store servers. To do that, you will need to set the `TEST_STORE` environment variable to either `staging` or `production`, and you also have to pass credentials for a valid user in that store with the environment variable `TEST_USER_EMAIL` and `TEST_USER_PASSWORD`, like this: - - TEST_STORE=staging TEST_USER_EMAIL=test@example.com TEST_USER_PASSWORD=Hola123* ./runtests.sh tests/integration/store - -To prepare a user for testing, go to https://login.staging.ubuntu.com/ (or -https://login.ubuntu.com/ for the production store) and create a new user. Then -go to https://dashboard.staging.snapcraft.io/ (or -https://dashboard.staging.snapcraft.io/ for the production store) to sign the -developer agreement. - -Note that most testing should be done on the staging server. If multiple tests -have to be executed on production, notify the store team before. - -## Testing on macOS - -We can currently run a minimal subset of snapcraft integration tests on macOS. They are run by travis, using a brew formula that builds the installer from the branch. Once the virtualization tool for Ubuntu on mac is finalized, the full suite can be executed. - -For manual exploratory testing, the team has one mac machine available. - -## Spread tests for the snapcraft snap - -[Spread](https://github.com/canonical/spread) is a system to distribute tests and execute them in different backends, in parallel. We are currently using spread only to run the integration suite using the installed snapcraft snap from the edge channel. - -To run them, first, download the spread binary: - - curl -s -O https://storage.googleapis.com/snapd-spread-tests/spread/spread-amd64.tar.gz && tar xzvf spread-amd64.tar.gz - -Then, you can run them using a local LXD as the backend with: - - ./spread -v lxd: - -Or, you can run them in google if you have a `SPREAD_GOOGLE_KEY`, with: - - SPREAD_GOOGLE_KEY={key} ./spread -v google: - -## Testing arm - -It is possible to emulate an arm64 machine on an amd64 host, which is very useful for running manual exploratory tests for snapcraft. To set it up: - -1. Download the latest ubuntu arm64 uefi image from https://cloud-images.ubuntu.com/releases/16.04/release/ -2. Keep a pristine copy of the image, in case you want to reset the machine, replacing <ubuntu-image> with the name of the file you downloaded on step 1: - - ``` - $ cp <ubuntu-image> <ubuntu-image>.pristine - ``` - -3. Download the latest UEFI firmware image QEMU_EFI.fd from https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/ -4. Create a cloud init file, replacing <launchpad-user-name> with your values: - - ``` - $ cat > cloud-data.yaml << EOF - #cloud-config - users: - - name: $USER - ssh-import-id: <launchpad-user-name> - sudo: ['ALL=(ALL) NOPASSWD:ALL'] - groups: sudo - shell: /bin/bash - EOF - ``` - -5. Create a cloud config disk image on the file `cloud-config.img`: - - ``` - $ sudo apt install --yes cloud-image-utils - $ cloud-localds --disk-format qcow2 cloud-config.img cloud-data.yaml - ``` - -6. Run the image in qemu, replacing <ubuntu-image> with the path of the file you downloaded on step 1. - - ``` - $ sudo apt install qemu-system-arm - $ qemu-system-aarch64 \ - -smp 2 \ - -m 1024 \ - -M virt \ - -cpu cortex-a57 \ - -bios QEMU_EFI.fd \ - -nographic \ - -device virtio-blk-device,drive=image \ - -drive if=none,id=image,file=<ubuntu-image> \ - -device virtio-blk-device,drive=cloud \ - -drive if=none,id=cloud,file=cloud-config.img \ - -device virtio-net-device,netdev=user0 \ - -netdev user,id=user0 \ - -redir tcp:2222::22 - ``` - -This will show a few errors, and a weird screen while the machine boots. -TODO: research how to make it nicer, but for now, just be patient until the login prompt appears. - -7. ssh into the emulated machine: - - ``` - $ ssh -p 2222 localhost - ``` - -(Source: https://gist.github.com/george-hawkins/16ee37063213f348a17717a7007d2c79) - -To test snapcraft on an armhf machine, currently the only simple option is to install ubuntu classic on BeagleBoard (https://elinux.org/BeagleBoardUbuntu) or on Raspberry Pi 2 (https://wiki.ubuntu.com/ARM/RaspberryPi). From 591c19813c441be3921661742fe99acf60cd6776 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 16:31:17 -0500 Subject: [PATCH 318/333] docs: update HACKING.md with new environment information --- HACKING.md | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/HACKING.md b/HACKING.md index 1a8b5fb39d..b5455b4fa6 100644 --- a/HACKING.md +++ b/HACKING.md @@ -23,27 +23,13 @@ newgrp lxd Setup the environment by running: ```shell -./tools/environment-setup.sh +make setup ``` -To work inside this environment, run: - -```shell -lxc exec snapcraft-dev -- sudo -iu ubuntu bash -``` - -Import your keys (`ssh-import-id`) and add a `Host` entry to your ssh config if you are interested in [Code's](https://snapcraft.io/code) [Remote-SSH](https://code.visualstudio.com/docs/remote/ssh) plugin. - ### Tooling We use a large number of tools for our project. Most of these are installed for -you with tox, but you'll need to install: - -- Python 3.12 (default on Ubuntu 24.04) with setuptools. -- [tox](https://tox.wiki) version 3.8 or later -- [pyright](https://github.com/microsoft/pyright) (also available via snap: `snap install pyright`) -- [ruff](https://github.com/astral/ruff) (also available via snap: `snap install ruff`) -- [ShellCheck](https://www.shellcheck.net/) (also available via snap: `snap install shellcheck`) +you with `make setup`, but you'll need to install Python 3.12 separately. ### Testing @@ -112,7 +98,7 @@ Given that the `--debug` option in snapcraft is reserved for project specific de To render the documentation as HTML in `docs/_build`, run: ```shell -tox run -e build-docs +make docs ``` > **Important** @@ -122,7 +108,7 @@ tox run -e build-docs If you prefer to compose pages interactively, you can host the documentation on a local server: ```shell -tox run -e autobuild-docs +make auto-docs ``` You can reach the interactive site at http://127.0.0.1:8080 in a web browser. @@ -134,13 +120,13 @@ The documentation Makefile provided by the [Sphinx Starter Pack](https://github. To check for syntax errors in documentation, run: ```shell -tox run -e lint-docs +make lint-docs ``` For a rudimentary spell check, you can use codespell: ```shell -tox run -e lint-codespell +make lint-codespell ``` ## Evaluating pull requests From 3d2480c5e4795107f9a1efaa8c65f552cb490269 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 16:55:15 -0500 Subject: [PATCH 319/333] build: add python-apt wheels --- pyproject.toml | 1 - requirements-noble.txt | 3 +++ snap/snapcraft.yaml | 2 ++ uv.lock | 37 ++++++++++++++++++++++++++++++++++++- 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 requirements-noble.txt diff --git a/pyproject.toml b/pyproject.toml index b8d405e71b..9114e97144 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,6 @@ dependencies = [ "pygit2~=1.13.0", "pylxd ; sys_platform == 'linux'", "pymacaroons", - "python-apt @ https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz ; sys_platform == 'linux'", "python-debian ; sys_platform == 'linux'", "pyxdg", "pyyaml", diff --git a/requirements-noble.txt b/requirements-noble.txt new file mode 100644 index 0000000000..865b447c73 --- /dev/null +++ b/requirements-noble.txt @@ -0,0 +1,3 @@ +# Update this by finding the latest version of the tarball at https://launchpad.net/ubuntu/noble/+source/python-apt +python-apt @ https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.7.7ubuntu4/python-apt_2.7.7ubuntu4.tar.xz \ + --hash=sha256:9833fcccf33e0fbf00d62df93c0b6165dc00edd9f635251be4cde1a9dc708e88 diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 8dec7ee923..a8f9a4575f 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -163,6 +163,7 @@ parts: - enable-patchelf prime: - -usr/include + snapcraft: source: . plugin: python @@ -173,6 +174,7 @@ parts: - constraints.txt python-requirements: - uv-requirements.txt + - requirements-noble.txt organize: # Put snapcraftctl and craftctl into its own directory that can be included in the PATH # without including other binaries. diff --git a/uv.lock b/uv.lock index 99ea47f32b..99112a9991 100644 --- a/uv.lock +++ b/uv.lock @@ -1020,6 +1020,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/60/42/227f748dc222b7a1c5cb40c7c74ab4162c7fc146b88980776b490ab673a1/macaroonbakery-1.3.4-py2.py3-none-any.whl", hash = "sha256:1e952a189f5c1e96ef82b081b2852c770d7daa20987e2088e762dd5689fb253b", size = 103184 }, ] +[[package]] +name = "macholib" +version = "1.16.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "altgraph" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/95/ee/af1a3842bdd5902ce133bd246eb7ffd4375c38642aeb5dc0ae3a0329dfa2/macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30", size = 59309 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/5d/c059c180c84f7962db0aeae7c3b9303ed1d73d76f2bfbc32bc231c8be314/macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c", size = 38094 }, +] + [[package]] name = "markdown" version = "3.7" @@ -1546,6 +1558,14 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/55/d4/54f5f5c73b803e6256ea97ffc6ba8a305d9a5f57f85f9b00b282512bf18a/pyinstaller-6.11.1.tar.gz", hash = "sha256:491dfb4d9d5d1d9650d9507daec1ff6829527a254d8e396badd60a0affcb72ef", size = 4249772 } wheels = [ + { url = "https://files.pythonhosted.org/packages/96/15/b0f1c0985ee32fcd2f6ad9a486ef94e4db3fef9af025a3655e76cb708009/pyinstaller-6.11.1-py3-none-macosx_10_13_universal2.whl", hash = "sha256:44e36172de326af6d4e7663b12f71dbd34e2e3e02233e181e457394423daaf03", size = 991780 }, + { url = "https://files.pythonhosted.org/packages/fd/0f/9f54cb18abe2b1d89051bc9214c0cb40d7b5f4049c151c315dacc067f4a2/pyinstaller-6.11.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:6d12c45a29add78039066a53fb05967afaa09a672426072b13816fe7676abfc4", size = 711739 }, + { url = "https://files.pythonhosted.org/packages/32/f7/79d10830780eff8339bfa793eece1df4b2459e35a712fc81983e8536cc29/pyinstaller-6.11.1-py3-none-manylinux2014_i686.whl", hash = "sha256:ddc0fddd75f07f7e423da1f0822e389a42af011f9589e0269b87e0d89aa48c1f", size = 714053 }, + { url = "https://files.pythonhosted.org/packages/25/f7/9961ef02cdbd2dbb1b1a215292656bd0ea72a83aafd8fb6373513849711e/pyinstaller-6.11.1-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:0d6475559c4939f0735122989611d7f739ed3bf02f666ce31022928f7a7e4fda", size = 719133 }, + { url = "https://files.pythonhosted.org/packages/6f/4d/7f854842a1ce798de762a0b0bc5d5a4fc26ad06164a98575dc3c54abed1f/pyinstaller-6.11.1-py3-none-manylinux2014_s390x.whl", hash = "sha256:e21c7806e34f40181e7606926a14579f848bfb1dc52cbca7eea66eccccbfe977", size = 709591 }, + { url = "https://files.pythonhosted.org/packages/7f/e0/00d29fc90c3ba50620c61554e26ebb4d764569507be7cd1c8794aa696f9a/pyinstaller-6.11.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:32c742a24fe65d0702958fadf4040f76de85859c26bec0008766e5dbabc5b68f", size = 710068 }, + { url = "https://files.pythonhosted.org/packages/3e/57/d14b44a69f068d2caaee49d15e45f9fa0f37c6a2d2ad778c953c1722a1ca/pyinstaller-6.11.1-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:208c0ef6dab0837a0a273ea32d1a3619a208e3d1fe3fec3785eea71a77fd00ce", size = 714439 }, + { url = "https://files.pythonhosted.org/packages/88/01/256824bb57ca208099c86c2fb289f888ca7732580e91ced48fa14e5903b2/pyinstaller-6.11.1-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:ad84abf465bcda363c1d54eafa76745d77b6a8a713778348377dc98d12a452f7", size = 710457 }, { url = "https://files.pythonhosted.org/packages/7c/f0/98c9138f5f0ff17462f1ad6d712dcfa643b9a283d6238d464d8145bc139d/pyinstaller-6.11.1-py3-none-win32.whl", hash = "sha256:2e8365276c5131c9bef98e358fbc305e4022db8bedc9df479629d6414021956a", size = 1280261 }, { url = "https://files.pythonhosted.org/packages/7d/08/f43080614b3e8bce481d4dfd580e579497c7dcdaf87656d9d2ad912e5796/pyinstaller-6.11.1-py3-none-win_amd64.whl", hash = "sha256:7ac83c0dc0e04357dab98c487e74ad2adb30e7eb186b58157a8faf46f1fa796f", size = 1340482 }, { url = "https://files.pythonhosted.org/packages/ed/56/953c6594cb66e249563854c9cc04ac5a055c6c99d1614298feeaeaa9b87e/pyinstaller-6.11.1-py3-none-win_arm64.whl", hash = "sha256:35e6b8077d240600bb309ed68bb0b1453fd2b7ab740b66d000db7abae6244423", size = 1267519 }, @@ -2164,6 +2184,18 @@ dependencies = [ ] [package.dev-dependencies] +apt-jammy = [ + { name = "python-apt", version = "2.4.0+ubuntu4", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, +] +apt-noble = [ + { name = "python-apt", version = "2.7.7+ubuntu3", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, +] +apt-oracular = [ + { name = "python-apt", version = "2.9.0+ubuntu1", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, +] +apt-plucky = [ + { name = "python-apt", version = "2.9.0+ubuntu1", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, +] dev = [ { name = "coverage" }, { name = "fixtures" }, @@ -2250,7 +2282,6 @@ requires-dist = [ { name = "pygit2", specifier = "~=1.13.0" }, { name = "pylxd", marker = "sys_platform == 'linux'" }, { name = "pymacaroons" }, - { name = "python-apt", marker = "sys_platform == 'linux'", url = "https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.4.0ubuntu1/python-apt_2.4.0ubuntu1.tar.xz" }, { name = "python-debian", marker = "sys_platform == 'linux'" }, { name = "pyxdg" }, { name = "pyyaml" }, @@ -2268,6 +2299,10 @@ requires-dist = [ ] [package.metadata.requires-dev] +apt-jammy = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = "~=2.4.0" }] +apt-noble = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = "~=2.7.0" }] +apt-oracular = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = ">=2.9.0" }] +apt-plucky = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = ">=2.9.0" }] dev = [ { name = "coverage", extras = ["toml"] }, { name = "fixtures" }, From a347b7c77f660c4f70cc153c358f9b56287fdd79 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 18:01:56 -0500 Subject: [PATCH 320/333] ci: update workflow files for starflow/uv --- .github/PULL_REQUEST_TEMPLATE.md | 4 +- .github/workflows/cla-check.yaml | 9 ---- .github/workflows/policy.yaml | 15 ++++++ .github/workflows/qa.yaml | 16 ++++++ .github/workflows/security-scan.yaml | 17 ------ .github/workflows/tics.yaml | 32 ++++++++---- .github/workflows/tox.yaml | 78 ---------------------------- 7 files changed, 54 insertions(+), 117 deletions(-) delete mode 100644 .github/workflows/cla-check.yaml create mode 100644 .github/workflows/policy.yaml create mode 100644 .github/workflows/qa.yaml delete mode 100644 .github/workflows/security-scan.yaml delete mode 100644 .github/workflows/tox.yaml diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4636f3c747..1e2afba20c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ - [ ] Have you followed the [guidelines for contributing](https://github.com/canonical/snapcraft/blob/main/CONTRIBUTING.md)? - [ ] Have you signed the [CLA](http://www.ubuntu.com/legal/contributors/)? -- [ ] Have you successfully run `tox run -m lint`? -- [ ] Have you successfully run `tox run -e test-py310`? (supported versions: `py39`, `py310`, `py311`, `py312`) +- [ ] Have you successfully run `make lint`? +- [ ] Have you successfully run `make test`? --- diff --git a/.github/workflows/cla-check.yaml b/.github/workflows/cla-check.yaml deleted file mode 100644 index cdb271af63..0000000000 --- a/.github/workflows/cla-check.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: cla-check -on: [pull_request] - -jobs: - cla-check: - runs-on: ubuntu-latest - steps: - - name: Check if CLA signed - uses: canonical/has-signed-canonical-cla@v1 diff --git a/.github/workflows/policy.yaml b/.github/workflows/policy.yaml new file mode 100644 index 0000000000..8d88bc3a91 --- /dev/null +++ b/.github/workflows/policy.yaml @@ -0,0 +1,15 @@ +name: Check policy +on: + pull_request: + push: + branches: + - main + - hotfix/* + - work/check-policy # For development + +jobs: + policy: + uses: canonical/starflow/.github/workflows/policy.yaml@main + python-scans: + name: Security scan + uses: canonical/starflow/.github/workflows/scan-python.yaml@main \ No newline at end of file diff --git a/.github/workflows/qa.yaml b/.github/workflows/qa.yaml new file mode 100644 index 0000000000..b57282a5ec --- /dev/null +++ b/.github/workflows/qa.yaml @@ -0,0 +1,16 @@ +name: QA +on: + push: + branches: + - "main" + - "feature/*" + - "hotfix/*" + - "release/*" + - "renovate/*" + pull_request: + +jobs: + lint: + uses: canonical/starflow/.github/workflows/lint-python.yaml@main + test: + uses: canonical/starflow/.github/workflows/test-python.yaml@main \ No newline at end of file diff --git a/.github/workflows/security-scan.yaml b/.github/workflows/security-scan.yaml deleted file mode 100644 index e39816acae..0000000000 --- a/.github/workflows/security-scan.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: Security scan -on: - pull_request: - push: - branches: - - main - - hotfix/* - - work/secscan # For development - -jobs: - python-scans: - name: Scan Python project - uses: canonical/starflow/.github/workflows/scan-python.yaml@main - with: - packages: python-apt-dev - osv-extra-args: "--config=source/osv-scanner.toml" - trivy-extra-args: '--severity HIGH,CRITICAL --ignore-unfixed --skip-dirs "tests/spread/**"' diff --git a/.github/workflows/tics.yaml b/.github/workflows/tics.yaml index ea9f9b7404..fb91b6da83 100644 --- a/.github/workflows/tics.yaml +++ b/.github/workflows/tics.yaml @@ -9,7 +9,7 @@ on: jobs: CI: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v4 @@ -22,26 +22,36 @@ jobs: sudo apt-get update echo "::endgroup::" echo "::group::apt-get install..." - sudo apt-get install -y python3 python3-dev libapt-pkg-dev libyaml-dev xdelta3 patchelf + sudo apt-get install -y python3 python3-dev libapt-pkg-dev libyaml-dev umoci echo "::endgroup::" - echo "::group::pip install" - python -m pip install 'tox<5.0' tox-gh + echo "::group::snap install" + sudo snap install --classic astral-uv + echo "::endgroup::" + echo "::group::install requirements" + uv sync --frozen --group dev echo "::endgroup::" - - name: Setup Tox environment - run: tox --workdir /tmp/tox run-parallel --parallel auto --parallel-no-spinner --parallel-live --colored yes -e test-all-py310 --notest + - name: Install project + run: | + python -m pip install -e . - - name: Test with tox - run: tox --workdir /tmp/tox run --skip-pkg-install --result-json results/tox-py310.json --colored yes -e test-all-py310 + - name: Run coverage + run: | + make test-coverage + + - name: Upload test results + if: success() || failure() + uses: actions/upload-artifact@v4 + with: + name: test-results-ubuntu-24.04 + path: results/ - name: Run TICS analysis uses: tiobe/tics-github-action@v3 - env: - PATH: "/tmp/tox/test-all-py310/bin:/snap/bin:/home/runner/.local/bin:/home/runner/.cargo/bin:/bin:/usr/bin:/usr/local/bin:" with: mode: qserver project: snapcraft viewerUrl: https://canonical.tiobe.com/tiobeweb/TICS/api/cfg?name=default branchdir: ${{ github.workspace }} ticsAuthToken: ${{ secrets.TICSAUTHTOKEN }} - installTics: true + installTics: true \ No newline at end of file diff --git a/.github/workflows/tox.yaml b/.github/workflows/tox.yaml deleted file mode 100644 index fff2b8a938..0000000000 --- a/.github/workflows/tox.yaml +++ /dev/null @@ -1,78 +0,0 @@ -name: Tox -on: - push: - branches: - - "main" - - "snapcraft/7.0" - - "release/*" - - "hotfix/*" - pull_request: - -jobs: - linters: - runs-on: ubuntu-24.04 - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Install dependencies - run: | - echo "::group::Begin snap install" - echo "Installing snaps in the background while running apt and pip..." - sudo snap install --no-wait --classic pyright --revision 735 # version 1.1.344 - sudo snap install --no-wait shellcheck ruff - echo "::endgroup::" - echo "::group::apt-get update" - sudo apt-get update - echo "::endgroup::" - echo "::group::apt-get install..." - sudo apt-get install --yes python3 python3-dev libapt-pkg-dev libyaml-dev xdelta3 - echo "::endgroup::" - echo "::group::pip install" - python -m pip install 'tox<5.0' tox-gh - echo "::endgroup::" - echo "::group::Create virtual environments for linting processes." - tox run --colored yes -m lint build-docs --notest - echo "::endgroup::" - echo "::group::Build docs." - tox run --colored yes -e build-docs - echo "::endgroup::" - echo "::group::Wait for snap to complete" - snap watch --last=install - echo "::endgroup::" - - name: Run Linters - run: tox run --colored yes --skip-pkg-install -m lint - tests: - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Install dependencies - run: | - echo "::group::apt-get update" - sudo apt-get update - echo "::endgroup::" - echo "::group::apt-get install..." - sudo apt-get install -y python3 python3-dev libapt-pkg-dev libyaml-dev xdelta3 - echo "::endgroup::" - echo "::group::pip install" - python -m pip install 'tox<5.0' tox-gh - echo "::endgroup::" - mkdir -p results - - name: Setup Tox environments - run: tox run-parallel --parallel auto --parallel-no-spinner --parallel-live --colored yes -e test-py312,test-legacy-py312 --notest - - name: Test with tox - run: tox run --skip-pkg-install --result-json results/tox-ubuntu-24.04.json --colored yes -e test-py312,test-legacy-py312 - - name: Upload code coverage - uses: codecov/codecov-action@v5 - with: - directory: ./results/ - files: coverage*.xml - - name: Upload test results - if: success() || failure() - uses: actions/upload-artifact@v4 - with: - name: test-results-ubuntu-24.04 - path: results/ From 82d8f2e21c5fb3694fae5b5a592b78658085df12 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Wed, 29 Jan 2025 18:02:39 -0500 Subject: [PATCH 321/333] style: add pre-commit config --- .pre-commit-config.yaml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..7fed7d6cb4 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,28 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: "v5.0.0" + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + - id: check-merge-conflict + - id: check-toml + - id: fix-byte-order-marker + - id: mixed-line-ending + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.9.3" + hooks: + # Run the linter + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + # Run the formatter + - id: ruff-format + - repo: https://github.com/pre-commit/mirrors-prettier + rev: "" # Intentionally blank, despite the warning. + hooks: + - id: prettier + additional_dependencies: + - prettier@3.4.2 From 0dedd09ccc9ea7d502c582c4b8e768b55f782528 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Thu, 30 Jan 2025 09:10:56 -0500 Subject: [PATCH 322/333] ci(docs): update readthedocs config to use uv --- .readthedocs.yaml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 9862aaf419..d5ef338b0b 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -15,6 +15,15 @@ build: apt_packages: - libapt-pkg-dev jobs: + create_environment: + - asdf plugin add uv + - asdf install uv latest + - asdf global uv latest + install: + - uv sync --frozen --group docs --group dev-noble + build: + html: + - uv run sphinx-build -T -b dirhtml docs $READTHEDOCS_OUTPUT/html post_checkout: - git fetch --tags --unshallow # Also fetch tags - git describe # Make sure we get a proper version @@ -22,11 +31,4 @@ build: # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/conf.py - builder: dirhtml fail_on_warning: true - -python: - install: - - requirements: requirements-docs.txt - - method: pip - path: . From 50c2c4160322308c3c7912280c68e08c3eeeafc3 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Thu, 30 Jan 2025 10:34:01 -0500 Subject: [PATCH 323/333] chore: correct all typing errors --- pyproject.toml | 3 +++ snapcraft/commands/account.py | 2 +- snapcraft/commands/extensions.py | 6 ++++-- snapcraft/commands/plugins.py | 2 +- snapcraft/commands/status.py | 4 ++-- snapcraft/commands/upload.py | 2 +- snapcraft/elf/_elf_file.py | 2 +- snapcraft/models/project.py | 2 +- snapcraft/parts/lifecycle.py | 8 +++++--- snapcraft/parts/parts.py | 5 +++-- snapcraft/parts/yaml_utils.py | 5 +++-- uv.lock | 23 ++++++++++++++++++++--- 12 files changed, 45 insertions(+), 19 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9114e97144..dfebbb1c0b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -340,6 +340,9 @@ exclude_also = [ [tool.codespell] ignore-words-list = [ "buildd", + "crate", + "assertIn", + "socio-economic", ] skip = [ # Keyrings aren't code diff --git a/snapcraft/commands/account.py b/snapcraft/commands/account.py index 7593fa3999..6e9f9f7e8f 100644 --- a/snapcraft/commands/account.py +++ b/snapcraft/commands/account.py @@ -186,7 +186,7 @@ def fill_parser(self, parser: "argparse.ArgumentParser") -> None: ) @overrides - def run(self, parsed_args): + def run(self, parsed_args) -> None: if parsed_args.experimental_login: raise ArgumentParsingError( "--experimental-login no longer supported. " diff --git a/snapcraft/commands/extensions.py b/snapcraft/commands/extensions.py index d4afe5c256..2de4575b91 100644 --- a/snapcraft/commands/extensions.py +++ b/snapcraft/commands/extensions.py @@ -65,7 +65,7 @@ class ListExtensionsCommand(AppCommand): ) @overrides - def run(self, parsed_args): + def run(self, parsed_args) -> None: extension_presentation: Dict[str, ExtensionModel] = {} # New extensions. @@ -78,7 +78,9 @@ def run(self, parsed_args): # Extensions from snapcraft_legacy. for _extension_name in supported_extension_names(): - extension_class = find_extension(_extension_name) + # Ignore assignment type error as the conversion from legacy to modern Snapcraft `Extension` + # should be trivial + extension_class = find_extension(_extension_name) # type: ignore[assignment] extension_name = _extension_name.replace("_", "-") extension_bases = list(extension_class.get_supported_bases()) if extension_name in extension_presentation: diff --git a/snapcraft/commands/plugins.py b/snapcraft/commands/plugins.py index c1427db4df..38a495d571 100644 --- a/snapcraft/commands/plugins.py +++ b/snapcraft/commands/plugins.py @@ -59,7 +59,7 @@ def fill_parser(self, parser: "argparse.ArgumentParser") -> None: ) @overrides - def run(self, parsed_args): + def run(self, parsed_args) -> None: if parsed_args.base == "core20": raise errors.LegacyFallback() diff --git a/snapcraft/commands/status.py b/snapcraft/commands/status.py index b38ec25b77..904e236e10 100644 --- a/snapcraft/commands/status.py +++ b/snapcraft/commands/status.py @@ -72,7 +72,7 @@ def fill_parser(self, parser: "argparse.ArgumentParser") -> None: ) @overrides - def run(self, parsed_args): + def run(self, parsed_args) -> None: snap_channel_map = store.StoreClientCLI().get_channel_map( snap_name=parsed_args.name ) @@ -392,7 +392,7 @@ def fill_parser(self, parser: "argparse.ArgumentParser") -> None: ) @overrides - def run(self, parsed_args): + def run(self, parsed_args) -> None: snap_channel_map = store.StoreClientCLI().get_channel_map( snap_name=parsed_args.name ) diff --git a/snapcraft/commands/upload.py b/snapcraft/commands/upload.py index e589878679..e6855ee2d2 100644 --- a/snapcraft/commands/upload.py +++ b/snapcraft/commands/upload.py @@ -102,7 +102,7 @@ def fill_parser(self, parser: "argparse.ArgumentParser") -> None: ) @overrides - def run(self, parsed_args): + def run(self, parsed_args) -> None: snap_file = pathlib.Path(parsed_args.snap_file) if not snap_file.exists() or not snap_file.is_file(): raise ArgumentParsingError(f"{str(snap_file)!r} is not a valid file") diff --git a/snapcraft/elf/_elf_file.py b/snapcraft/elf/_elf_file.py index 55fc44a3c3..91418b1425 100644 --- a/snapcraft/elf/_elf_file.py +++ b/snapcraft/elf/_elf_file.py @@ -57,7 +57,7 @@ def add_version(self, version: str) -> None: class SonameCache: """A cache for sonames.""" - def __init__(self): + def __init__(self) -> None: self._soname_paths: _SonameCacheDict = {} def __getitem__(self, key): diff --git a/snapcraft/models/project.py b/snapcraft/models/project.py index 7c95a789c3..e6bdc149b1 100644 --- a/snapcraft/models/project.py +++ b/snapcraft/models/project.py @@ -1013,7 +1013,7 @@ def _providers_base(cls, base: str) -> bases.BaseAlias | None: @pydantic.field_validator("plugs") @classmethod - def _validate_plugs(cls, plugs): + def _validate_plugs(cls, plugs) -> dict[str, ContentPlug | Any]: empty_plugs = [] if plugs is not None: for plug_name, plug in plugs.items(): diff --git a/snapcraft/parts/lifecycle.py b/snapcraft/parts/lifecycle.py index 83fff103d6..b24cb9ba27 100644 --- a/snapcraft/parts/lifecycle.py +++ b/snapcraft/parts/lifecycle.py @@ -22,7 +22,7 @@ import subprocess from datetime import datetime from pathlib import Path -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, cast import craft_parts from craft_cli import emit @@ -212,7 +212,8 @@ def _run_command( # noqa PLR0913 (too-many-arguments) if parsed_args.debug: emit.progress(str(err), permanent=True) launch_shell() - raise errors.FilePermissionError(err.filename, reason=err.strerror) + # Casting as a str as OSError should always contain an error message + raise errors.FilePermissionError(err.filename, reason=cast(str, err.strerror)) except OSError as err: msg = err.strerror if err.filename: @@ -220,7 +221,8 @@ def _run_command( # noqa PLR0913 (too-many-arguments) if parsed_args.debug: emit.progress(msg, permanent=True) launch_shell() - raise errors.SnapcraftError(msg) from err + # Casting as a str as OSError should always contain an error message + raise errors.SnapcraftError(cast(str, msg)) from err except errors.SnapcraftError as err: if parsed_args.debug: emit.progress(str(err), permanent=True) diff --git a/snapcraft/parts/parts.py b/snapcraft/parts/parts.py index dcccf4b52d..6417fa12e5 100644 --- a/snapcraft/parts/parts.py +++ b/snapcraft/parts/parts.py @@ -19,7 +19,7 @@ import pathlib import subprocess import types -from typing import Any, Dict, List, Optional, Set +from typing import Any, Dict, List, Optional, Set, cast import craft_parts from craft_archives import repo @@ -227,7 +227,8 @@ def run( msg = err.strerror if err.filename: msg = f"{err.filename}: {msg}" - raise errors.PartsLifecycleError(msg) from err + # Casting as a str as OSError should always contain an error message + raise errors.PartsLifecycleError(cast(str, msg)) from err except Exception as err: raise errors.PartsLifecycleError(str(err)) from err diff --git a/snapcraft/parts/yaml_utils.py b/snapcraft/parts/yaml_utils.py index f91bb76d81..e14d8fb465 100644 --- a/snapcraft/parts/yaml_utils.py +++ b/snapcraft/parts/yaml_utils.py @@ -18,7 +18,7 @@ from dataclasses import dataclass from pathlib import Path -from typing import Any, Dict, List, Optional, TextIO +from typing import Any, Dict, List, Optional, TextIO, cast import yaml import yaml.error @@ -271,6 +271,7 @@ def process_yaml(project_file: Path) -> Dict[str, Any]: msg = err.strerror if err.filename: msg = f"{msg}: {err.filename!r}." - raise errors.SnapcraftError(msg) from err + # Casting as a str as OSError should always contain an error message + raise errors.SnapcraftError(cast(str, msg)) from err return yaml_data diff --git a/uv.lock b/uv.lock index 99112a9991..785b372fc4 100644 --- a/uv.lock +++ b/uv.lock @@ -457,7 +457,7 @@ wheels = [ [[package]] name = "craft-parts" -version = "2.3.0" +version = "2.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "overrides" }, @@ -467,7 +467,10 @@ dependencies = [ { name = "requests" }, { name = "requests-unixsocket2" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a7/2f/299694e04ea30f21ab1638ab54342f38a711b198f5fbf0bb9f5a085053d0/craft_parts-2.3.0.tar.gz", hash = "sha256:96516a8a4314659f53f6f2999a38250f8bc5308bb41ac74df9b23e330aaa34ae", size = 639970 } +sdist = { url = "https://files.pythonhosted.org/packages/b1/6c/ff0f9aa805da1670e408c644fbe5740d69056691de4953dbaa7546d80ce6/craft_parts-2.4.1.tar.gz", hash = "sha256:18f6c9a45fb99e5a366fcd9b827df8886d955dace9ded9f08759206f5e5ef729", size = 640144 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/13/0dbcca9f1fb0b2b61809cb65fcba88d6b676f015f87628ca603161be47ed/craft_parts-2.4.1-py3-none-any.whl", hash = "sha256:22adf92b77c25868518fa426ad789aee794b17c0e8c0408d22e902c846d3d325", size = 449809 }, +] [[package]] name = "craft-platforms" @@ -2240,6 +2243,13 @@ docs = [ ] lint = [ { name = "codespell" }, + { name = "mypy" }, + { name = "types-pyyaml" }, + { name = "types-requests" }, + { name = "types-setuptools" }, + { name = "types-simplejson" }, + { name = "types-tabulate" }, + { name = "types-toml" }, { name = "yamllint" }, ] types = [ @@ -2261,7 +2271,7 @@ requires-dist = [ { name = "craft-archives", specifier = "~=2.0" }, { name = "craft-cli", specifier = "~=2.15.0" }, { name = "craft-grammar", specifier = ">=2.0.1,<3.0.0" }, - { name = "craft-parts", specifier = "==2.3.0" }, + { name = "craft-parts", specifier = "==2.4.1" }, { name = "craft-platforms", specifier = "~=0.4" }, { name = "craft-store", specifier = ">=3.0.2,<4.0.0" }, { name = "cryptography", specifier = "==43.0.3" }, @@ -2339,6 +2349,13 @@ docs = [ ] lint = [ { name = "codespell", extras = ["toml"] }, + { name = "mypy" }, + { name = "types-pyyaml" }, + { name = "types-requests", specifier = "==2.31.0.6" }, + { name = "types-setuptools" }, + { name = "types-simplejson" }, + { name = "types-tabulate" }, + { name = "types-toml" }, { name = "yamllint", specifier = "~=1.34" }, ] types = [ From 3aa02f515dc40dfb48b67d8c3a742581181a814a Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Thu, 30 Jan 2025 10:35:03 -0500 Subject: [PATCH 324/333] style: run prettier --- .github/workflows/policy.yaml | 2 +- .github/workflows/qa.yaml | 2 +- .github/workflows/tics.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/policy.yaml b/.github/workflows/policy.yaml index 8d88bc3a91..9c59dc18be 100644 --- a/.github/workflows/policy.yaml +++ b/.github/workflows/policy.yaml @@ -12,4 +12,4 @@ jobs: uses: canonical/starflow/.github/workflows/policy.yaml@main python-scans: name: Security scan - uses: canonical/starflow/.github/workflows/scan-python.yaml@main \ No newline at end of file + uses: canonical/starflow/.github/workflows/scan-python.yaml@main diff --git a/.github/workflows/qa.yaml b/.github/workflows/qa.yaml index b57282a5ec..2ac023b012 100644 --- a/.github/workflows/qa.yaml +++ b/.github/workflows/qa.yaml @@ -13,4 +13,4 @@ jobs: lint: uses: canonical/starflow/.github/workflows/lint-python.yaml@main test: - uses: canonical/starflow/.github/workflows/test-python.yaml@main \ No newline at end of file + uses: canonical/starflow/.github/workflows/test-python.yaml@main diff --git a/.github/workflows/tics.yaml b/.github/workflows/tics.yaml index fb91b6da83..d97fbb5ed8 100644 --- a/.github/workflows/tics.yaml +++ b/.github/workflows/tics.yaml @@ -54,4 +54,4 @@ jobs: viewerUrl: https://canonical.tiobe.com/tiobeweb/TICS/api/cfg?name=default branchdir: ${{ github.workspace }} ticsAuthToken: ${{ secrets.TICSAUTHTOKEN }} - installTics: true \ No newline at end of file + installTics: true From 022cdad1203dcbb3c57a53471d0ca3f34998964e Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Thu, 30 Jan 2025 11:19:31 -0500 Subject: [PATCH 325/333] ci: configure starflow test run --- .github/workflows/qa.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/qa.yaml b/.github/workflows/qa.yaml index 2ac023b012..8c5db516ce 100644 --- a/.github/workflows/qa.yaml +++ b/.github/workflows/qa.yaml @@ -14,3 +14,11 @@ jobs: uses: canonical/starflow/.github/workflows/lint-python.yaml@main test: uses: canonical/starflow/.github/workflows/test-python.yaml@main + with: + # Snapcraft currently only tests on Python 3.12 on Ubuntu 24.04 + fast-test-platforms: '["ubuntu-24.04"]' + slow-test-platforms: '["ubuntu-24.04"]' + lowest-python-platform: "ubuntu-24.04" + fast-test-python-versions: '["3.12"]' + slow-test-python-versions: '["3.12"]' + lowest-python-version: "3.12" From d4078a013856a9161b5da94bad1df1c9d823bf5a Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Thu, 30 Jan 2025 15:29:58 -0500 Subject: [PATCH 326/333] chore: move docutils into docs dependency group --- pyproject.toml | 2 +- uv.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dfebbb1c0b..78d0a4dde2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,6 @@ dependencies = [ "craft-platforms~=0.4", "craft-store>=3.0.2,<4.0.0", "cryptography==43.0.3", # Pinned due to https://github.com/canonical/snapcraft/issues/5217 - "docutils<0.20", # Frozen until we can update sphinx dependencies. "gnupg", "jsonschema==2.5.1", "launchpadlib", @@ -88,6 +87,7 @@ dev = [ ] docs = [ "canonical-sphinx[full]>=0.2.0", + "docutils<0.20", # Frozen until we can update sphinx dependencies. "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinxcontrib-details-directive", diff --git a/uv.lock b/uv.lock index 785b372fc4..67323dbf61 100644 --- a/uv.lock +++ b/uv.lock @@ -2140,7 +2140,7 @@ wheels = [ [[package]] name = "snapcraft" -version = "8.5.1.post87+dirty" +version = "8.5.1.post88+dirty" source = { editable = "." } dependencies = [ { name = "attrs" }, @@ -2154,7 +2154,6 @@ dependencies = [ { name = "craft-platforms" }, { name = "craft-store" }, { name = "cryptography" }, - { name = "docutils" }, { name = "gnupg" }, { name = "jsonschema" }, { name = "launchpadlib" }, @@ -2233,6 +2232,7 @@ dev-plucky = [ ] docs = [ { name = "canonical-sphinx", extra = ["full"] }, + { name = "docutils" }, { name = "pyspelling" }, { name = "sphinx-autobuild" }, { name = "sphinx-autodoc-typehints" }, @@ -2275,7 +2275,6 @@ requires-dist = [ { name = "craft-platforms", specifier = "~=0.4" }, { name = "craft-store", specifier = ">=3.0.2,<4.0.0" }, { name = "cryptography", specifier = "==43.0.3" }, - { name = "docutils", specifier = "<0.20" }, { name = "gnupg" }, { name = "jsonschema", specifier = "==2.5.1" }, { name = "launchpadlib" }, @@ -2339,6 +2338,7 @@ dev-oracular = [{ name = "python-apt", marker = "sys_platform == 'linux'", speci dev-plucky = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = ">=2.9.0" }] docs = [ { name = "canonical-sphinx", extras = ["full"], specifier = ">=0.2.0" }, + { name = "docutils", specifier = "<0.20" }, { name = "pyspelling" }, { name = "sphinx-autobuild" }, { name = "sphinx-autodoc-typehints" }, From b98588d87f0316840c4dad254d2772a65fa334e4 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Thu, 30 Jan 2025 15:45:32 -0500 Subject: [PATCH 327/333] chore: pin craft-application for test failures --- pyproject.toml | 2 +- uv.lock | 90 ++++++++++++++++++-------------------------------- 2 files changed, 34 insertions(+), 58 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 78d0a4dde2..b0d63c6717 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ dependencies = [ "attrs", "catkin-pkg==1.0.0 ; sys_platform == 'linux'", "click==8.1.7", - "craft-application>=4.4.1,<5.0.0", + "craft-application==4.4.1", # Pinned due to https://github.com/canonical/snapcraft/issues/5231 "craft-archives~=2.0", "craft-cli~=2.15.0", "craft-grammar>=2.0.1,<3.0.0", diff --git a/uv.lock b/uv.lock index 67323dbf61..7c3eaaa84d 100644 --- a/uv.lock +++ b/uv.lock @@ -382,10 +382,9 @@ wheels = [ [[package]] name = "craft-application" -version = "4.8.2" +version = "4.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "annotated-types" }, { name = "craft-archives" }, { name = "craft-cli" }, { name = "craft-grammar" }, @@ -402,9 +401,9 @@ dependencies = [ { name = "snap-helpers" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/09/a4/03f588d549e60067f3093cd3541b283400a61e5893f0d740d47b9fdedb6e/craft_application-4.8.2.tar.gz", hash = "sha256:4070a035952bc3fa8aa16cc1b488814e92375dc6d27905c250e23cf42849bae7", size = 228126 } +sdist = { url = "https://files.pythonhosted.org/packages/35/62/f25c8814bfcbc361f2fb424a7e2d2ab20bd84543e41f9411ab2edb0b5dfe/craft_application-4.4.1.tar.gz", hash = "sha256:16627b3a57010bb6ada1dd5fea0565590e77d2092108cab5e3afc2b8bcfc15e8", size = 209220 } wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/5a/385cdacac2ad5b41e5b481d9c25b71dc1c34188d183a376ba3e331653c88/craft_application-4.8.2-py3-none-any.whl", hash = "sha256:77ef9217211cf6d6d164288f65879f94f15c282ddf8f1ab58a324b645a7e88bf", size = 146039 }, + { url = "https://files.pythonhosted.org/packages/ff/dd/d5baa0157652eb2ff6a17da1d2d50efc00df43c2a99ab1d911d03ebcf464/craft_application-4.4.1-py3-none-any.whl", hash = "sha256:4eb61a319e26946ff02ec6c1467084a7bb212600380dd651b75cdd4a2fbb3cd8", size = 135798 }, ] [[package]] @@ -1441,55 +1440,50 @@ wheels = [ [[package]] name = "pydantic" -version = "2.10.6" +version = "2.8.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, { name = "pydantic-core" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 } +sdist = { url = "https://files.pythonhosted.org/packages/8b/7b/23dc30fba5793d7be3307f33bebb36e08f78f8af9c03fce608833f01bebd/pydantic-2.8.0.tar.gz", hash = "sha256:d970ffb9d030b710795878940bd0489842c638e7252fc4a19c3ae2f7da4d6141", size = 738772 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 }, + { url = "https://files.pythonhosted.org/packages/d3/07/bbfddb7b532b727a5769a8468a67ab388e74c029d4940e5de6b25231aba2/pydantic-2.8.0-py3-none-any.whl", hash = "sha256:ead4f3a1e92386a734ca1411cb25d94147cf8778ed5be6b56749047676d6364e", size = 423079 }, ] [[package]] name = "pydantic-core" -version = "2.27.2" +version = "2.20.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, - { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, - { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, - { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, - { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, - { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, - { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, - { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, - { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, - { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, - { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, - { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, - { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, - { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, - { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, - { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, - { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, - { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, - { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, - { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, - { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, - { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, - { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, - { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, - { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, - { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, - { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, - { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, +sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/9802d053f33dbcf110d46e3f28667b06cd764b164f1e3f4189848cdd6e78/pydantic_core-2.20.0.tar.gz", hash = "sha256:366be8e64e0cb63d87cf79b4e1765c0703dd6313c729b22e7b9e378db6b96877", size = 388463 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/d7/b748dc1e92f019d0bf49dd62762425a1d4c713250b5dfac82616648a0e8c/pydantic_core-2.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d6f8c49657f3eb7720ed4c9b26624063da14937fc94d1812f1e04a2204db3e17", size = 1839193 }, + { url = "https://files.pythonhosted.org/packages/df/20/e1a1a03a9c116bd63d68dabd51250e76e45e3a849456b32dd8fb5148c817/pydantic_core-2.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad1bd2f377f56fec11d5cfd0977c30061cd19f4fa199bf138b200ec0d5e27eeb", size = 1767120 }, + { url = "https://files.pythonhosted.org/packages/51/05/b903f4fd7f34d8548534b1e21f972664f9a5d03b884781b86d3f422997ca/pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed741183719a5271f97d93bbcc45ed64619fa38068aaa6e90027d1d17e30dc8d", size = 1789229 }, + { url = "https://files.pythonhosted.org/packages/dc/d0/0686c898da81a339701fca5669bd8496c5923755d84dacb65c4d71dd2ab0/pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d82e5ed3a05f2dcb89c6ead2fd0dbff7ac09bc02c1b4028ece2d3a3854d049ce", size = 1773878 }, + { url = "https://files.pythonhosted.org/packages/be/c3/3510274ee06bc18c7c43923be40a0fcd7510daf6df5fab41a70463302130/pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2ba34a099576234671f2e4274e5bc6813b22e28778c216d680eabd0db3f7dad", size = 1975737 }, + { url = "https://files.pythonhosted.org/packages/7c/23/f8a75d2f766f9fbe4a080c1ca2e00e2eb61f237b9d930976d0aba95cd691/pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:879ae6bb08a063b3e1b7ac8c860096d8fd6b48dd9b2690b7f2738b8c835e744b", size = 2592099 }, + { url = "https://files.pythonhosted.org/packages/99/6a/8c9e41bd2848e6f2a970f93f4cf0f2f62ce5248ab2b23b85dd7247069f1a/pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0eefc7633a04c0694340aad91fbfd1986fe1a1e0c63a22793ba40a18fcbdc8", size = 2100808 }, + { url = "https://files.pythonhosted.org/packages/34/a9/33f27da3de0dfff881beca6c2e19b05f928f24ff3346c1ff6faae85f6cf4/pydantic_core-2.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73deadd6fd8a23e2f40b412b3ac617a112143c8989a4fe265050fd91ba5c0608", size = 1900858 }, + { url = "https://files.pythonhosted.org/packages/0c/00/fde56cd48a4ebb9d7dfe9e38aa14737be7349dd8d30de162955182e38e16/pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:35681445dc85446fb105943d81ae7569aa7e89de80d1ca4ac3229e05c311bdb1", size = 1966902 }, + { url = "https://files.pythonhosted.org/packages/de/dc/bc741bf0a400f983cab9e5d4feac936040c0fc7665a65da5bc6c8db275a2/pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0f6dd3612a3b9f91f2e63924ea18a4476656c6d01843ca20a4c09e00422195af", size = 2119825 }, + { url = "https://files.pythonhosted.org/packages/a8/51/0d66a7a600f0e33eaeafb65ce5693a90130d00072eaecb184881dd5bd37a/pydantic_core-2.20.0-cp312-none-win32.whl", hash = "sha256:7e37b6bb6e90c2b8412b06373c6978d9d81e7199a40e24a6ef480e8acdeaf918", size = 1717259 }, + { url = "https://files.pythonhosted.org/packages/4a/d4/ec35826073e92b0b37c2df2075b0aa7abecc2d8217480a90e864f7f3e39f/pydantic_core-2.20.0-cp312-none-win_amd64.whl", hash = "sha256:7d4df13d1c55e84351fab51383520b84f490740a9f1fec905362aa64590b7a5d", size = 1898028 }, + { url = "https://files.pythonhosted.org/packages/82/0d/25e4087d8380fa696cbde556fa2694947038872d50cb01f86909d59fc4b4/pydantic_core-2.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:d43e7ab3b65e4dc35a7612cfff7b0fd62dce5bc11a7cd198310b57f39847fd6c", size = 1838761 }, + { url = "https://files.pythonhosted.org/packages/cb/ac/42aa7ee25d816c9fed9fe1bf4ee11472ba8057814262c8f713fa010ed4d7/pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b6a24d7b5893392f2b8e3b7a0031ae3b14c6c1942a4615f0d8794fdeeefb08b", size = 1789150 }, + { url = "https://files.pythonhosted.org/packages/0b/3e/d93ae7810b35d44d8777768b561001eff279040580aebf71ce9c8e9a613f/pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2f13c3e955a087c3ec86f97661d9f72a76e221281b2262956af381224cfc243", size = 1773533 }, + { url = "https://files.pythonhosted.org/packages/f5/fd/a07dc6fcdf9e0b2f5e4c016dd74a188fc19311aceac89cee1fd2471e3b06/pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:72432fd6e868c8d0a6849869e004b8bcae233a3c56383954c228316694920b38", size = 1975497 }, + { url = "https://files.pythonhosted.org/packages/b8/d1/9148ea8c18212a297c6b256e0197268523f30e02057474157784c9f5835e/pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d70a8ff2d4953afb4cbe6211f17268ad29c0b47e73d3372f40e7775904bc28fc", size = 2591911 }, + { url = "https://files.pythonhosted.org/packages/2a/fb/379309fab9af69d30c523978a971f8050d96bd3e36fb317b2c57bfd65548/pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e49524917b8d3c2f42cd0d2df61178e08e50f5f029f9af1f402b3ee64574392", size = 2100735 }, + { url = "https://files.pythonhosted.org/packages/6f/23/f100db088bb343a4a9e8d3085cb84d349bcf6004b101eebb5c8812226e23/pydantic_core-2.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4f0f71653b1c1bad0350bc0b4cc057ab87b438ff18fa6392533811ebd01439c", size = 1900739 }, + { url = "https://files.pythonhosted.org/packages/10/4e/a4808cc751651329b7f0372454bbe486e79e7189b974748fba361abadecc/pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:16197e6f4fdecb9892ed2436e507e44f0a1aa2cff3b9306d1c879ea2f9200997", size = 1966597 }, + { url = "https://files.pythonhosted.org/packages/10/a8/1ce3a2af38c87890ad27d97f405cadab56aecdbf7e8e88dc39f45eeb63ab/pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:763602504bf640b3ded3bba3f8ed8a1cc2fc6a87b8d55c1c5689f428c49c947e", size = 2119457 }, + { url = "https://files.pythonhosted.org/packages/60/8c/1da883ec849c75256210db8370906a151898e5dce5be85ced7881e980a44/pydantic_core-2.20.0-cp313-none-win32.whl", hash = "sha256:a3f243f318bd9523277fa123b3163f4c005a3e8619d4b867064de02f287a564d", size = 1717499 }, + { url = "https://files.pythonhosted.org/packages/59/04/475e9c2013aeb8d130d40818466b1f8eee017d2e3a5ecc3324211fe69c8f/pydantic_core-2.20.0-cp313-none-win_amd64.whl", hash = "sha256:03aceaf6a5adaad3bec2233edc5a7905026553916615888e53154807e404545c", size = 1923306 }, ] [[package]] @@ -2140,7 +2134,6 @@ wheels = [ [[package]] name = "snapcraft" -version = "8.5.1.post88+dirty" source = { editable = "." } dependencies = [ { name = "attrs" }, @@ -2186,18 +2179,6 @@ dependencies = [ ] [package.dev-dependencies] -apt-jammy = [ - { name = "python-apt", version = "2.4.0+ubuntu4", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, -] -apt-noble = [ - { name = "python-apt", version = "2.7.7+ubuntu3", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, -] -apt-oracular = [ - { name = "python-apt", version = "2.9.0+ubuntu1", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, -] -apt-plucky = [ - { name = "python-apt", version = "2.9.0+ubuntu1", source = { registry = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/" }, marker = "sys_platform == 'linux'" }, -] dev = [ { name = "coverage" }, { name = "fixtures" }, @@ -2267,7 +2248,7 @@ requires-dist = [ { name = "attrs" }, { name = "catkin-pkg", marker = "sys_platform == 'linux'", specifier = "==1.0.0" }, { name = "click", specifier = "==8.1.7" }, - { name = "craft-application", specifier = "~=4.4" }, + { name = "craft-application", specifier = "==4.4.1" }, { name = "craft-archives", specifier = "~=2.0" }, { name = "craft-cli", specifier = "~=2.15.0" }, { name = "craft-grammar", specifier = ">=2.0.1,<3.0.0" }, @@ -2286,7 +2267,6 @@ requires-dist = [ { name = "packaging" }, { name = "progressbar" }, { name = "pydantic", specifier = "~=2.8" }, - { name = "pydantic", specifier = "~=2.8" }, { name = "pyelftools" }, { name = "pygit2", specifier = "~=1.13.0" }, { name = "pylxd", marker = "sys_platform == 'linux'" }, @@ -2308,10 +2288,6 @@ requires-dist = [ ] [package.metadata.requires-dev] -apt-jammy = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = "~=2.4.0" }] -apt-noble = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = "~=2.7.0" }] -apt-oracular = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = ">=2.9.0" }] -apt-plucky = [{ name = "python-apt", marker = "sys_platform == 'linux'", specifier = ">=2.9.0" }] dev = [ { name = "coverage", extras = ["toml"] }, { name = "fixtures" }, From 00223d89ffe750dd91acc31ff72141f0d6db85d7 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Thu, 30 Jan 2025 15:50:35 -0500 Subject: [PATCH 328/333] fix(docs): properly ignore lines being too long for now --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6e9fee48c5..93b96c6d5c 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ lint-docs: ##- Lint the documentation ifneq ($(CI),) @echo ::group::$@ endif - uv run $(UV_DOCS_GROUPS) sphinx-lint --ignore docs/reference/commands --ignore docs/_build --enable all $(DOCS) -d missing-underscore-after-hyperlink,missing-space-in-hyperlink + uv run $(UV_DOCS_GROUPS) sphinx-lint --ignore docs/reference/commands --ignore docs/_build --enable all $(DOCS) -d missing-underscore-after-hyperlink,missing-space-in-hyperlink,line-too-long ifneq ($(CI),) @echo ::endgroup:: endif From 963ad50cd9e7591774eaa2152c7302bcc618f6f3 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Thu, 30 Jan 2025 15:58:52 -0500 Subject: [PATCH 329/333] test(spread): remove nonexistent files from spread.yaml --- spread.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/spread.yaml b/spread.yaml index 2e5e2d65b2..8d9a6b8027 100644 --- a/spread.yaml +++ b/spread.yaml @@ -94,7 +94,7 @@ backends: "if [ -d /etc/ssh/sshd_config.d/ ] then echo 'PasswordAuthentication yes' > /etc/ssh/sshd_config.d/10-custom.conf - echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config.d/10-custom.conf + echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config.d/10-custom.conf else sed -i /etc/ssh/sshd_config -E -e 's/^#?PasswordAuthentication.*/PasswordAuthentication yes/' -e 's/^#?PermitRootLogin.*/PermitRootLogin yes/' fi" @@ -348,6 +348,3 @@ path: /snapcraft/ include: - docs/ - tests/ - - requirements.txt - - requirements-devel.txt - - runtests.sh From 0dd76943160d989d9e809f14b9097fc7c07553ad Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Thu, 30 Jan 2025 15:54:25 -0500 Subject: [PATCH 330/333] ci: make trivy ignore things we don't need to scan requirements-noble.txt cannot be built by Trivy and there's no reason for us to scan spread tests --- .github/workflows/policy.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/policy.yaml b/.github/workflows/policy.yaml index 9c59dc18be..604e0d5375 100644 --- a/.github/workflows/policy.yaml +++ b/.github/workflows/policy.yaml @@ -13,3 +13,10 @@ jobs: python-scans: name: Security scan uses: canonical/starflow/.github/workflows/scan-python.yaml@main + with: + # 1. requirements-noble.txt can't build on jammy + # 2. Ignore requirements files in spread tests, as some of these intentionally + # contain vulnerable versions. + # 3. Docs contain requirements.txt files that don't specify versions. + requirements-find-args: '! -name requirements-noble.txt ! -path "./tests/spread*" ! -path "./docs/**"' + trivy-extra-args: "--severity HIGH,CRITICAL --ignore-unfixed --skip-dirs tests/spread/" From 54b12c1880130d371d6f4cd29a8f0ee12ed2de95 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Fri, 7 Feb 2025 15:23:10 -0500 Subject: [PATCH 331/333] fix: adjust crystal plugin for new data_files location --- snapcraft_legacy/plugins/v2/crystal.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/snapcraft_legacy/plugins/v2/crystal.py b/snapcraft_legacy/plugins/v2/crystal.py index 18e11cf033..70c90520ba 100644 --- a/snapcraft_legacy/plugins/v2/crystal.py +++ b/snapcraft_legacy/plugins/v2/crystal.py @@ -96,7 +96,10 @@ def get_build_commands(self) -> List[str]: else: build_options = "" - env = dict(LANG="C.UTF-8", LC_ALL="C.UTF-8") + # Make sure snap-related environment variables survive through the shell call + # Filter environment variables for only the ones beginning with "SNAP" + snap_dict = {key: os.environ[key] for key in os.environ if key.startswith("SNAP")} + env = dict(LANG="C.UTF-8", LC_ALL="C.UTF-8", **snap_dict) env_flags = [f"{key}={value}" for key, value in env.items()] return [ From e96fb3df89b0fb0bbf5d46ef694802cd058fec17 Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Tue, 11 Feb 2025 14:28:07 -0500 Subject: [PATCH 332/333] style: run formatters --- CODE_STYLE.md | 6 +-- docs/_static/css/custom.css | 18 ++++----- schema/snapcraft.json | 75 +++---------------------------------- 3 files changed, 17 insertions(+), 82 deletions(-) diff --git a/CODE_STYLE.md b/CODE_STYLE.md index d8d2eb7100..0c9eee6dc3 100644 --- a/CODE_STYLE.md +++ b/CODE_STYLE.md @@ -62,9 +62,9 @@ fix it. - When asserting for equality, we prefer to use the `Equals` matcher from testtools: - ``` - self.assertThat(actual, Equals(expected)) - ``` + ``` + self.assertThat(actual, Equals(expected)) + ``` - When writing unit tests that raise errors, the tests should only check the class of the exception raised and it's attributes, not the format of the diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css index 0f09c64e73..83174e022b 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -1,28 +1,28 @@ @import url("https://fonts.googleapis.com/css2?family=Ubuntu:ital@0;1&display=swap"); body { - font-family: Ubuntu, "times new roman", times, roman, serif; + font-family: Ubuntu, "times new roman", times, roman, serif; } div .toctree-wrapper { - column-count: 2; + column-count: 2; } div .toctree-wrapper > ul { - margin: 0; + margin: 0; } ul .toctree-l1 { - margin: 0; - -webkit-column-break-inside: avoid; - page-break-inside: avoid; - break-inside: avoid-column; + margin: 0; + -webkit-column-break-inside: avoid; + page-break-inside: avoid; + break-inside: avoid-column; } .wy-nav-content { - max-width: none; + max-width: none; } .log-snippets { - color: rgb(141, 141, 141); + color: rgb(141, 141, 141); } diff --git a/schema/snapcraft.json b/schema/snapcraft.json index 059199a797..61fedc5028 100644 --- a/schema/snapcraft.json +++ b/schema/snapcraft.json @@ -702,30 +702,11 @@ "stop-mode": { "type": "string", "description": "controls how the daemon should be stopped", - "enum": [ - "sigterm", - "sigterm-all", - "sighup", - "sighup-all", - "sigusr1", - "sigusr1-all", - "sigusr2", - "sigusr2-all", - "sigint", - "sigint-all" - ] + "enum": ["sigterm", "sigterm-all", "sighup", "sighup-all", "sigusr1", "sigusr1-all", "sigusr2", "sigusr2-all", "sigint", "sigint-all"] }, "restart-condition": { "type": "string", - "enum": [ - "on-success", - "on-failure", - "on-abnormal", - "on-abort", - "on-watchdog", - "always", - "never" - ] + "enum": ["on-success", "on-failure", "on-abnormal", "on-abort", "on-watchdog", "always", "never"] }, "install-mode": { "type": "string", @@ -816,33 +797,7 @@ "minitems": 1, "uniqueItems": true, "items": { - "enum": [ - "env-injector", - "flutter-stable", - "flutter-beta", - "flutter-dev", - "flutter-master", - "gnome", - "gnome-3-28", - "gnome-3-34", - "gnome-3-38", - "kde-neon", - "kde-neon-6", - "ros1-noetic", - "ros1-noetic-desktop", - "ros1-noetic-perception", - "ros1-noetic-robot", - "ros1-noetic-ros-base", - "ros1-noetic-ros-core", - "ros2-foxy", - "ros2-foxy-ros-base", - "ros2-foxy-ros-core", - "ros2-foxy-desktop", - "ros2-humble", - "ros2-humble-ros-base", - "ros2-humble-ros-core", - "ros2-humble-desktop" - ] + "enum": ["env-injector", "flutter-stable", "flutter-beta", "flutter-dev", "flutter-master", "gnome", "gnome-3-28", "gnome-3-34", "gnome-3-38", "kde-neon", "kde-neon-6", "ros1-noetic", "ros1-noetic-desktop", "ros1-noetic-perception", "ros1-noetic-robot", "ros1-noetic-ros-base", "ros1-noetic-ros-core", "ros2-foxy", "ros2-foxy-ros-base", "ros2-foxy-ros-core", "ros2-foxy-desktop", "ros2-humble", "ros2-humble-ros-base", "ros2-humble-ros-core", "ros2-humble-desktop"] } } } @@ -940,20 +895,7 @@ "source-type": { "type": "string", "default": "", - "enum": [ - "bzr", - "git", - "hg", - "mercurial", - "subversion", - "svn", - "tar", - "zip", - "deb", - "rpm", - "7z", - "local" - ] + "enum": ["bzr", "git", "hg", "mercurial", "subversion", "svn", "tar", "zip", "deb", "rpm", "7z", "local"] }, "disable-parallel": { "type": "boolean", @@ -998,14 +940,7 @@ "uniqueItems": true, "items": { "type": "string", - "enum": [ - "core22-step-dependencies", - "enable-patchelf", - "no-patchelf", - "no-install", - "debug", - "keep-execstack" - ] + "enum": ["core22-step-dependencies", "enable-patchelf", "no-patchelf", "no-install", "debug", "keep-execstack"] }, "default": [] }, From b5a60bd203c59b6f6fdb7fe6c3be86cef0a3227d Mon Sep 17 00:00:00 2001 From: Imani Pelton <imani@bepri.dev> Date: Tue, 11 Feb 2025 14:58:22 -0500 Subject: [PATCH 333/333] ci(docs): update RTD configuration --- .readthedocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 82b873cf2b..ca75114f14 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -28,4 +28,4 @@ build: create_environment: - uv venv "${READTHEDOCS_VIRTUALENV_PATH}" install: - - UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv sync --frozen --group docs + - UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv sync --frozen --group docs --group dev-noble