├── .github └── workflows │ └── test.yml ├── .gitignore ├── AUTHORS ├── HACKING ├── LICENSE ├── MANIFEST.in ├── Makefile ├── NEWS ├── README.md ├── RELEASE ├── TODO ├── examples ├── dump_partitions.py ├── fill_free_space_with_new_partition.py ├── gpt_type_uuid.py ├── import_partition.py ├── make_one_primary_partition.py └── query_device_capacity.py ├── include ├── _pedmodule.h ├── convert.h ├── docstrings │ ├── pyconstraint.h │ ├── pydevice.h │ ├── pydisk.h │ ├── pyfilesys.h │ ├── pygeom.h │ └── pynatmath.h ├── exceptions.h ├── pyconstraint.h ├── pydevice.h ├── pydisk.h ├── pyfilesys.h ├── pygeom.h ├── pynatmath.h ├── pytimer.h ├── pyunit.h └── typeobjects │ ├── pyconstraint.h │ ├── pydevice.h │ ├── pydisk.h │ ├── pyfilesys.h │ ├── pygeom.h │ ├── pynatmath.h │ └── pytimer.h ├── setup.py ├── src ├── _pedmodule.c ├── convert.c ├── fdisk │ ├── fdisk.py │ └── localtest ├── parted │ ├── __init__.py │ ├── alignment.py │ ├── cachedlist.py │ ├── constraint.py │ ├── decorators.py │ ├── device.py │ ├── disk.py │ ├── filesystem.py │ ├── geometry.py │ └── partition.py ├── pyconstraint.c ├── pydevice.c ├── pydisk.c ├── pyfilesys.c ├── pygeom.c ├── pynatmath.c ├── pytimer.c └── pyunit.c └── tests ├── README.rst ├── __init__.py ├── baseclass.py ├── pylint └── runpylint.py ├── test__ped_alignment.py ├── test__ped_chsgeometry.py ├── test__ped_constraint.py ├── test__ped_device.py ├── test__ped_disk.py ├── test__ped_disktype.py ├── test__ped_filesystem.py ├── test__ped_filesystemtype.py ├── test__ped_geometry.py ├── test__ped_partition.py ├── test__ped_ped.py ├── test_parted_alignment.py ├── test_parted_constraint.py ├── test_parted_device.py ├── test_parted_disk.py ├── test_parted_filesystem.py ├── test_parted_geometry.py ├── test_parted_parted.py └── test_parted_partition.py /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | unit-tests: 13 | runs-on: ubuntu-latest 14 | container: 15 | image: registry.fedoraproject.org/fedora:latest 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: container running 19 | run: | 20 | # Install required RPMS 21 | dnf install -y \ 22 | bash \ 23 | e2fsprogs \ 24 | findutils \ 25 | gcc \ 26 | make \ 27 | parted \ 28 | parted-devel \ 29 | pkg-config \ 30 | python3 \ 31 | python3-coverage \ 32 | python3-devel \ 33 | python3-pip \ 34 | python3-pytest \ 35 | python3-types-six \ 36 | udev 37 | env PYTHON=python3 make test coverage COVERAGE=coverage 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.swp 3 | .coverage 4 | .tox 5 | ChangeLog 6 | MANIFEST 7 | build 8 | coverage-report.log 9 | dist 10 | pyparted.spec 11 | tests/pylint/.pylint.d 12 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | David Cantrell 2 | Chris Lumens 3 | David Campbell 4 | Peter Jones 5 | 6 | Python 3 Porting: 7 | Alex Skinner 8 | Gabriel de Perthuis 9 | -------------------------------------------------------------------------------- /HACKING: -------------------------------------------------------------------------------- 1 | Contributing to pyparted 2 | 3 | This guide helps explain how to get your contributions accepted in to the 4 | project. Coding style, patch generation, and how to submit patches are 5 | all discussed here. 6 | 7 | 8 | CODING STYLE FOR C 9 | 10 | Please follow the coding style you see in the C source files here. The project 11 | is developed on Linux, which gcc is the compiler. That affords us a lot of 12 | flexibility with regards to standards, but try to adhere to ISO C99 whenever 13 | possible and avoid using gcc extensions. There is a possibility that this 14 | project may need to be ported to a non-gcc compiler. 15 | 16 | Here are the major coding style highlights for this project: 17 | 18 | 1) Indentation is four spaces. Please do not use tab and do not use more 19 | or less than 4 spaces. A lot of the source files have vim control 20 | settings at the bottom so if you are using vim, the indentation will 21 | automatically be set up properly with the Tab key. However, if you are 22 | unlucky and do not have vim, just make sure you use 4 spaces for indent. 23 | Editor hints will be accepted for other editors, so long as the additions 24 | to the source files are minimal (i.e., we're not looking for editor 25 | configuration files). 26 | 27 | Examples: 28 | 29 | GOOD: 30 | int main(int argc, char **argv) { 31 | int i; 32 | i = EXIT_SUCCESS; 33 | 34 | if (i == -1) { 35 | return EXIT_FAILURE; 36 | } 37 | 38 | return i; 39 | } 40 | 41 | 2) Spaces after keywords. Do not place an open paren next to 'if' or 'for'. 42 | Examples: 43 | 44 | GOOD: 45 | 46 | if (i < j) { 47 | for (i=0; i < 30; i++) { 48 | 49 | BAD: 50 | 51 | if(i < j) { 52 | for(i=0; i < 30; i++) { 53 | 54 | 3) Open brace stays on the same line for the function declaration or 55 | statement it belongs to. Examples: 56 | 57 | GOOD: 58 | 59 | if (i < j ) { 60 | 61 | BAD: 62 | 63 | if (i < j) 64 | { 65 | 66 | 4) No brace-less blocks. If an 'if' test just requires one statement in 67 | the block, do still wrap it in braces. This is to maintain consistency 68 | with all blocks in the code. Examples: 69 | 70 | GOOD: 71 | 72 | if (i < j) { 73 | printf("i is less than j!\n"); 74 | } 75 | 76 | BAD: 77 | 78 | if (i < j) 79 | printf("i is less than j!\n"); 80 | 81 | 5) No K&R style function declarations. Examples: 82 | 83 | GOOD: 84 | 85 | int main(int argc, char **argv) { 86 | 87 | BAD: 88 | 89 | int main(argc, argv) 90 | int argc; 91 | char **argv; 92 | { 93 | 94 | 6) Let expressions breathe. There's no reason to remove all spaces from 95 | a complex expression. Examples: 96 | 97 | GOOD: 98 | 99 | i = (a + b) << c >> d | e * f; 100 | 101 | BAD: 102 | 103 | i = (a+b)<>d|e*f; 104 | 105 | 7) Function declarations have the return type on the same line as the 106 | function. For long argument lists, wrap them to line up with the 107 | parens. There is no space between the function name and the open 108 | paren. Examples: 109 | 110 | GOOD: 111 | 112 | int main(int argc, char **argv) { 113 | 114 | void check_a_variable(int a, char b, int c, struct astruct, 115 | int *d, char *e, void *buf) { 116 | 117 | BAD: 118 | 119 | int 120 | main (int argc, char **argv) 121 | { 122 | 123 | 8) Name variables and functions using lowercase names and underscores rather 124 | than CamelCase. Examples: 125 | 126 | GOOD: 127 | 128 | int c; 129 | char *host_name = NULL; 130 | void function_name(int argument); 131 | 132 | BAD: 133 | 134 | int counterForCountingThings; 135 | char *hostName = NULL; 136 | void functionName(int argument); 137 | 138 | 139 | CODING STYLE FOR PYTHON 140 | 141 | First, read PEP-8: http://www.python.org/dev/peps/pep-0008/ 142 | 143 | Second, please follow the coding style you see in the Python source files here. 144 | Here are the major coding style highlights for this project: 145 | 146 | 1) 4-space indentation. Do not use tabs in Python code. 147 | 148 | 2) Use CamelCase for class names. 149 | 150 | 3) For method names, the standard CamelCase naming with the first 151 | character being lowercase is preferred. 152 | 153 | 4) Use properties instead of get/set methods. 154 | 155 | 5) Use _ to prefix class variables accessed via properties. 156 | 157 | 6) Hide anything with __ prefixes if it does not need to be fully public. 158 | 159 | 7) List one module per import statement. Do not use a comma to list several 160 | modules on one import line. 161 | 162 | 163 | GENERATING PATCHES 164 | 165 | When you make changes to the code, you should generate a patch to send 166 | upstream. Before editing, it's a good idea to copy the original source 167 | file to a new name so you can edit the other copy. Here is a basic 168 | workflow: 169 | 170 | $ cd pyparted-VERSION/src 171 | $ cp -p _pedmodule.c _pedmodule.c.orig 172 | $ vim _pedmodule.c # make your changes 173 | 174 | Generating a patch is done using GNU diffutils or a diff(1) command 175 | capable of producing a unified diff: 176 | 177 | $ diff -u _pedmodule.c.orig _pedmodule.c > mypatch 178 | 179 | Submit the 'mypatch' file and explain your changes and why we should merge 180 | your changes. 181 | 182 | If you are making a lot of changes to many files, it's probably easier to 183 | use the git version control system. You can clone the upstream repository 184 | and commit your changes locally and then generate a set of diffs against 185 | the latest upstream code. 186 | 187 | $ git clone https://github.com/dcantrell/pyparted.git 188 | $ cd pyparted 189 | $ # make your changes to files here 190 | $ git add FILE # repeat this add/commit process for 191 | $ git commit # each logical change to the code 192 | $ git fetch 193 | $ git rebase origin 194 | $ git format-patch origin 195 | 196 | The output of git format-patch will be a set of files containing a patch 197 | for each add/commit you made locally. The patches will be made against 198 | the latest upstream. Submit your patch files upstream. 199 | 200 | 201 | SUBMITTING PATCHES 202 | 203 | The best way to submit patches is to fork the repo on github and send a pull 204 | request with your changes: 205 | 206 | https://github.com/dcantrell/pyparted 207 | 208 | Attach your patch and explanation and it'll be reviewed. There may be some 209 | back and forth as your patch is reviewed and considered for inclusion. 210 | 211 | Alternatively, you can email the project maintainer(s) directly. The git log 212 | and AUTHORS file contain email addresses of those who work on pyparted. 213 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS BUGS COPYING HACKING NEWS RELEASE TODO 2 | include MANIFEST.in 3 | include Makefile 4 | recursive-include include *.h 5 | recursive-include tests *.py 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for pyparted 3 | # Copyright The pyparted Project Authors 4 | # SPDX-License-Identifier: GPL-2.0-or-later 5 | # 6 | 7 | PYTHON ?= python3 8 | 9 | DESTDIR ?= / 10 | 11 | PACKAGE = $(shell $(PYTHON) setup.py --name) 12 | VERSION = $(shell $(PYTHON) setup.py --version) 13 | 14 | TAG = v$(VERSION) 15 | 16 | COVERAGE = coverage3 17 | 18 | default: all 19 | 20 | all: 21 | @$(PYTHON) setup.py build 22 | 23 | test: all 24 | @env PYTHONPATH=$$(find $$(pwd) -name "*.so" | head -n 1 | xargs dirname):src/parted:src \ 25 | $(PYTHON) -m unittest discover -v 26 | 27 | coverage: all 28 | @echo "*** Running unittests with $(COVERAGE) for $(PYTHON) ***" 29 | @env PYTHONPATH=$$(find $$(pwd) -name "*.so" | head -n 1 | xargs dirname):src/parted:src \ 30 | $(COVERAGE) run --branch -m unittest discover -v 31 | $(COVERAGE) report --include="build/lib.*/parted/*" --show-missing 32 | $(COVERAGE) report --include="build/lib.*/parted/*" > coverage-report.log 33 | 34 | check: clean 35 | $(MAKE) ; \ 36 | env PYTHONPATH=$$(find $$(pwd) -name "*.so" | head -n 1 | xargs dirname):src/parted:src \ 37 | tests/pylint/runpylint.py 38 | 39 | dist: 40 | @$(PYTHON) setup.py sdist 41 | 42 | tag: dist 43 | @if [ -z "$(GPGKEY)" ]; then \ 44 | echo "GPGKEY environment variable missing, please set this to the key ID" ; \ 45 | echo "you want to use to tag the repository." ; \ 46 | exit 1 ; \ 47 | fi 48 | @git tag -u $(GPGKEY) -m "Tag as $(TAG)" -f $(TAG) 49 | @echo "Tagged as $(TAG) (GPG signed)" 50 | 51 | release: tag 52 | ( cd dist ; gzip -dc $(PACKAGE)-$(VERSION).tar.gz | tar -xvf - ) 53 | ( cd dist/$(PACKAGE)-$(VERSION) && $(PYTHON) setup.py build ) || exit 1 54 | @echo 55 | @echo "$(PACKAGE)-$(VERSION) can be pushed to the git repo:" 56 | @echo " git push && git push --tags" 57 | @echo 58 | @echo "*** Remember to run 'make pypi' afterwards ***" 59 | @echo 60 | 61 | pypi: 62 | @echo "************************************************************************" 63 | @echo "* Username and password are for your pypi.org login. *" 64 | @echo "* NOTE: You must be a listed maintainer for pyparted for this to work. *" 65 | @echo "* See ~/.pypirc *" 66 | @echo "************************************************************************" 67 | @echo 68 | twine upload \ 69 | dist/$(PACKAGE)-$(VERSION).tar.gz \ 70 | dist/$(PACKAGE)-$(VERSION).tar.gz.asc 71 | 72 | rpmlog: 73 | @prevtag="$$(git tag -l | grep -v "^start$$" | tail -n 2 | head -n 1)" ; \ 74 | git log --pretty="format:- %s (%ae)" $${prevtag}.. | \ 75 | sed -e 's/@.*)/)/' | \ 76 | sed -e 's/%/%%/g' | \ 77 | grep -v "New version" | \ 78 | fold -s -w 77 | \ 79 | while read line ; do \ 80 | if [ ! "$$(echo $$line | cut -c-2)" = "- " ]; then \ 81 | echo " $$line" ; \ 82 | else \ 83 | echo "$$line" ; \ 84 | fi ; \ 85 | done 86 | 87 | bumpver: 88 | @OLDSUBVER=$$(echo $(VERSION) | rev | cut -d '.' -f 1 | rev) ; \ 89 | NEWSUBVER=$$(($${OLDSUBVER} + 1)) ; \ 90 | BASEVER="$$(echo $(VERSION) | sed -e "s|\.$${OLDSUBVER}$$||g")" ; \ 91 | NEWVERSION="$${BASEVER}.$${NEWSUBVER}" ; \ 92 | sed -i "s/pyparted_version = '$(VERSION)'/pyparted_version = '$${NEWVERSION}'/" setup.py ; \ 93 | echo "New version is $${NEWVERSION}" 94 | 95 | install: all 96 | @$(PYTHON) setup.py install --root $(DESTDIR) -c -O1 97 | 98 | clean: 99 | -rm -r build 100 | 101 | ci: check coverage 102 | 103 | verrel: 104 | @echo $(PACKAGE)-$(VERSION) 105 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | pyparted-2.1.0 2 | -------------- 3 | 4 | pyparted supports new libparted API functions, but those functions are not 5 | yet available in an official release on ftp.gnu.org. On Fedora systems, the 6 | parted-1.9.0-23 package and later revisions contain the necessary API support. 7 | 8 | 9 | pyparted-2.0.0 10 | -------------- 11 | 12 | Complete rewrite of pyparted. There are now two Python modules exposing the 13 | pyparted API: 14 | 15 | _ped Low level module interfacing with libparted. 16 | parted Higher level module written in Python building on _ped. 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pyparted 2 | 3 | ## Python bindings for libparted 4 | 5 | --- 6 | 7 | ### Overview 8 | 9 | pyparted is a set of native Python bindings for libparted. libparted 10 | is the library portion of the GNU parted project. With pyparted, you 11 | can write applications that interact with disk partition tables and 12 | filesystems. 13 | 14 | The Python bindings are implemented in two layers. Since libparted 15 | itself is written in C without any real implementation of objects, a 16 | simple 1:1 mapping of externally accessible libparted functions was 17 | written. This mapping is provided in the _ped Python module. You can 18 | use that module if you want to, but it's really just meant for the 19 | larger parted module. 20 | 21 | | Module | Description | 22 | | :--- | :--- | 23 | | _ped | libparted Python bindings, direct 1:1: function mapping | 24 | | parted | Native Python code building on _ped, complete with classes, exceptions, and advanced functionality. | 25 | 26 | The _ped module is written and maintained by hand. I chose to do this 27 | rather than rely on a tool like SWIG or Pyrex for several reasons. 28 | Mostly because I was the GNU parted maintainer, but also because 29 | libparted is sort of complex. It's a lowlevel system tool and I found 30 | it doesn't translate well in the tools I tried. This is nothing 31 | against those tools, I just don't think libparted is ideal to go 32 | through SWIG or Pyrex. By writing my own bindings, I can also find 33 | bugs in libparted that I may have overlooked before. See the WHY file 34 | for more explanation as to why I wrote the bindings by hand. 35 | 36 | ### History 37 | 38 | pyparted started life at Red Hat and continues there today. The main 39 | reason for writing it was to let anaconda (the Red Hat installation 40 | program, now used by RHEL and Fedora and many other distributions) 41 | interact with libparted. Anaconda is written in Python, so native 42 | bindings made sense. 43 | 44 | pyparted went through many rewrites, but the end result was always the 45 | same. And incomplete API via Python with just enough provided for 46 | anaconda to do its job. 47 | 48 | The latest iteration of pyparted aims to be a complete API mapping and 49 | even provide a nice set of classes so that people might want to 50 | integrate it in to other installers or even write other applications 51 | (maybe a Python based alternative to parted(8) or fdisk(8)). 52 | 53 | ### Examples 54 | 55 | Example code is provided in the examples directory. These may help 56 | provide a gentle introduction to the usage concepts of pyparted. More 57 | examples are always welcome, as are improved explanatory commentary 58 | for those that exist. 59 | 60 | ### Questions 61 | 62 | If you are reporting a pyparted failure in Fedora, it's most useful if 63 | you file a bug at http://bugzilla.redhat.com/ against the appropriate 64 | Fedora release you are using. 65 | 66 | Alternatively, you can file bugs directly on the project page: 67 | https://github.com/dcantrell/pyparted/issues 68 | 69 | If you just have questions about pyparted, you can email us directly 70 | using the contact information in the AUTHORS file. We will do our 71 | best to help you. 72 | -------------------------------------------------------------------------------- /RELEASE: -------------------------------------------------------------------------------- 1 | Instructions for making a new release: 2 | 3 | 1) git checkout master 4 | 2) git clean -d -x -f # I hope you've committed or stashed everything 5 | # you are working on 6 | 3) git fetch 7 | 4) git rebase origin 8 | 5) make bumpver 9 | 6) git commit -a -m "New version." 10 | 7) git clean -d -x -f 11 | 8) make release 12 | 9) gpg --detach-sign -a dist/$(make verrel).tar.gz 13 | 10) make pypi 14 | 15 | The tar.gz and tar.gz.asc files should be uploaded as release artifacts to 16 | github as a new release. 17 | 18 | If packaging in RPM format, you might find the 'make rpmlog' target useful. 19 | It gives you an RPM spec file formatted changelog block that contains the 20 | git shortlog entries of all changes since the last tag. 21 | 22 | 8) git push 23 | 9) git push --tags 24 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - Methods in the parted module that just return data and take in no 2 | parameters...make those read-only properties and get rid of the 3 | method. Since we have more or less established the API now, mark 4 | the methods as Deprecated and leave them around for a release 5 | before removing them. 6 | 7 | - add parted.Device.toSectors() method that takes in a size specification, 8 | such as 10.5MB, as a string and converts that size to a sector count 9 | based on the sector size of that Device 10 | 11 | - use disttools from Python to do as much work as possible 12 | 13 | - Walk through all of the src/py*.c files and make sure libparted exceptions 14 | are captured and filtered back up through Python. Will need to define some 15 | sane Python exception classes for libparted's exceptions. 16 | 17 | - Handle exceptions from libparted and pass to Python as necessary. The 18 | PED_ASSERT things are where libparted aborts, so we may want to catch things 19 | before it goes in to libparted so we can throw an exception rather than 20 | letting the library abort(). The ped_exception_throw() instances are all 21 | libparted's own exception-like system. 22 | 23 | - Handle exceptions throughout the _ped module code. Unique exceptions as 24 | much as possible. 25 | 26 | - Figure out what, if anything, we can do with timers. They are optional in 27 | libparted, but do we want to support them in pyparted? 28 | 29 | - Error handling in the get and set methods. 30 | 31 | - Free memory in error handling cases. 32 | 33 | - Exception handling: 34 | - Audit error messages to make them more useful. 35 | 36 | - All test cases with '# TODO' in the runTest() method. Be sure to uncomment 37 | them once you have written the test. 38 | 39 | - Make sure PyTypeObjects that have a tp_init are allocating memory that the 40 | garbage collector knows about. I'm not sure if PyType_GenericAlloc or 41 | PyType_GenericNew do this. 42 | 43 | - Coding policy that we need to make sure we're doing: 44 | If object creation fails, we need to use PyObject_GC_Del() to destroy it 45 | before throwing an exception at the user. For all other instances where 46 | we need to delete or destroy the object, use Py_XDECREF(). Once the ref 47 | count is zero, the GC will take over and run dealloc() for that object, 48 | which will eventually run PyObject_GC_Del(). Basically, we should only 49 | be using PyObject_GC_Del() in the convert functions or in __init__ 50 | constructors where we are making a new object for the user. 51 | 52 | NOTE: If we need to destroy an object due to creation failure and the 53 | object we are creating has other PyObject members, call Py_XDECREF on 54 | those members rather than destroing them. We can't ensure that there 55 | will be no other references to those members, so let the normal object 56 | destructor handle PyObject members, but forcefully destroy the object 57 | we are trying to create. 58 | 59 | - destroy() methods don't seem to be destroying the Python object. 60 | 61 | - Make sure this new code works in Python 3000 62 | 63 | - Look through all PyTypeObject objects and see where we can expand 64 | their functionality. Can we add str() support, for instance. 65 | 66 | - Move the constraint functions presently in _ped to be in the __init_() 67 | method for _ped.Constraint, similar to what was done for _ped_Disk_init: 68 | constraint_new_from_min_max 69 | constraint_new_from_min 70 | constraint_new_from_max 71 | constraint_any 72 | constraint_exact 73 | 74 | - parted module: 75 | - Write docstrings for everything 76 | 77 | - autoconf 78 | - More detailed API checks for libparted and Python 79 | 80 | ... and much much more 81 | -------------------------------------------------------------------------------- /examples/dump_partitions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright 2019 Geoff Williams 4 | # 5 | # This example script is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by the Free 7 | # Software Foundation, either version 3 of the License, or (at your option) any 8 | # later version so long as this copyright notice remains intact. 9 | # 10 | # This example script is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 13 | # details. 14 | # 15 | # You should have received a copy of the GNU General Public License along with 16 | # this example script. If not, see . 17 | 18 | __author__ = """Geoff Williams """ 19 | __copyright__ = """Copyright 2019 Geoff Williams""" 20 | 21 | """ 22 | print the partitions in a device/file according to pyparted 23 | """ 24 | 25 | import parted 26 | import sys 27 | import uuid 28 | 29 | # adjust as needed, eg /dev/sdc.. 30 | device = "sdcard.img" 31 | 32 | if len(sys.argv) == 2: 33 | device = sys.argv[1] 34 | 35 | # A device is a "thing" with own properties (type, manufacturer etc) - its a 36 | # high level abstraction that lets you just identify you have the right device 37 | device = parted.getDevice(device) 38 | 39 | # grab a "disk" instance - the other choice is `freshDisk`, wheras `newDisk` 40 | # seems to just read an existing disk (which is what we want for adding new 41 | # partition) 42 | disk = parted.newDisk(device) 43 | 44 | print("***** sanity check *****") 45 | print(f"result: {disk.check()}") 46 | 47 | print("===== device ====") 48 | print(f" model: {device.model}") 49 | print(f" path: {device.path}") 50 | print(f" sectorSize: {device.sectorSize}") 51 | print(f" physicalSectorSize: {device.physicalSectorSize}") 52 | print(f" length: {device.length}") 53 | # this next line can crash if you have a wonky GPT... 54 | # print(f" size (MB): {device.getSize()}") 55 | 56 | print("===== disk ====") 57 | print(f" type: {disk.type}") 58 | print(f" lastPartitionNumber: {disk.lastPartitionNumber}") 59 | print(f" primaryPartitionCount: {disk.primaryPartitionCount}") 60 | print(" free space regions:") 61 | free_space_regions = disk.getFreeSpaceRegions() 62 | for i, free_space_region in enumerate(free_space_regions): 63 | print(f" {i}:") 64 | print(f" start: {free_space_region.start}") 65 | print(f" end: {free_space_region.end}") 66 | print(f" length: {free_space_region.length}") 67 | 68 | 69 | print("===== partitions ====") 70 | for partition in disk.partitions: 71 | # print(str(partition)) - gives a nice human-readable dump 72 | print(f"Partition {partition.number}:") 73 | print(f" length: {partition.getLength()}") 74 | print(f" active: {partition.active}") 75 | print(f" busy: {partition.busy}") 76 | print(f" path: {partition.path}") 77 | print(f" type: {partition.type}") 78 | if hasattr(parted, "DISK_TYPE_PARTITION_TYPE_ID") and disk.supportsFeature( 79 | parted.DISK_TYPE_PARTITION_TYPE_ID 80 | ): 81 | print(f" type id: {partition.type_id}") 82 | if hasattr(parted, "DISK_TYPE_PARTITION_TYPE_UUID") and disk.supportsFeature( 83 | parted.DISK_TYPE_PARTITION_TYPE_UUID 84 | ): 85 | uuid_str = str(uuid.UUID(bytes=partition.type_uuid)) 86 | print(f" type uuid: {uuid_str}") 87 | print(f" size(MB): {partition.getSize()}") 88 | 89 | # supported only by GPT partition tables 90 | # will throw exception on MSDOS partition tables (fixed upstream) 91 | print(f" name: {partition.name}") 92 | filesystem = partition.fileSystem 93 | print(f" filesystem:") 94 | if filesystem: 95 | print(f" type: {filesystem.type}") 96 | print(f" checked: {filesystem.checked}") 97 | else: 98 | print(f" Filesystem info missing! you have an unformatted partition...") 99 | 100 | geometry = partition.geometry 101 | print(f" geometry:") 102 | print(f" start: {geometry.start}") 103 | print(f" end: {geometry.end}") 104 | print(f" length: {geometry.length}") 105 | -------------------------------------------------------------------------------- /examples/fill_free_space_with_new_partition.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright 2019 Geoff Williams 4 | # 5 | # This example script is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by the Free 7 | # Software Foundation, either version 3 of the License, or (at your option) any 8 | # later version so long as this copyright notice remains intact. 9 | # 10 | # This example script is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 13 | # details. 14 | # 15 | # You should have received a copy of the GNU General Public License along with 16 | # this example script. If not, see . 17 | 18 | __author__ = """Geoff Williams """ 19 | __copyright__ = """Copyright 2019 Geoff Williams""" 20 | 21 | """ 22 | Allocate free space to a partition. This demo is setup for a raw image file 23 | `sdcard.img` which is assumed to already contain partitions but with some 24 | unallocated space at the end of the drive. If you have an image file that you 25 | have _grown_ for this purpose (eg with `dd` or `truncate`) and it is GPT, you 26 | need to run: 27 | 28 | sgdisk -e FILE 29 | 30 | before running this script since GPT demands 33 backup blocks at the end of 31 | the disk. If you forget to do this you will get errors like this: 32 | 33 | File "/home/geoff/.local/lib/python3.7/site-packages/parted/decorators.py", line 42, in new 34 | ret = fn(*args, **kwds) 35 | File "/home/geoff/.local/lib/python3.7/site-packages/parted/disk.py", line 245, in addPartition 36 | constraint.getPedConstraint()) 37 | _ped.PartitionException: Unable to satisfy all constraints on the partition. 38 | 39 | Lets grow our SD card image: 40 | $ dd if=/dev/zero bs=1M count=100 >> sdcard.img 41 | $ sgdisk -e sdcard.img 42 | """ 43 | 44 | # pip3 install pyparted 45 | import parted 46 | 47 | # adjust as needed, eg /dev/sdc.. 48 | device = "sdcard.img" 49 | device = parted.getDevice(device) 50 | disk = parted.newDisk(device) 51 | free_space_regions = disk.getFreeSpaceRegions() 52 | 53 | # grab the free space region at the end of the disk 54 | geometry = free_space_regions[-1] 55 | 56 | # filesystem will be shown as blank by parted until it has been _formatted_ 57 | filesystem = parted.FileSystem(type="ext4", geometry=geometry) 58 | new_partition = parted.Partition( 59 | disk=disk, type=parted.PARTITION_NORMAL, fs=filesystem, geometry=geometry 60 | ) 61 | 62 | # name isn't in the constructor but we can set it separately 63 | new_partition.name = "bob" 64 | 65 | disk.addPartition(partition=new_partition, constraint=device.optimalAlignedConstraint) 66 | 67 | disk.commit() 68 | print("created partition OK") 69 | 70 | # Now you can format the partition in the image file after setting it up as a 71 | # loopback device, eg: 72 | # sudo losetup -f -P sdcard.img 73 | # sudo mkfs.ext4 /dev/loop6p3 74 | # Partitions are `1` indexed so `p3` is the third partition, not the fourth 75 | # After formatting, the filesystem will be shown as `ext4` in `parted` and the 76 | # new partition is ready to use. 77 | # 78 | # Cleanup your loopback device: 79 | # sudo losetup -d /dev/loop6 80 | -------------------------------------------------------------------------------- /examples/gpt_type_uuid.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # This example script is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by the Free 5 | # Software Foundation, either version 3 of the License, or (at your option) any 6 | # later version so long as this copyright notice remains intact. 7 | # 8 | # This example script is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 11 | # details. 12 | # 13 | # You should have received a copy of the GNU General Public License along with 14 | # this example script. If not, see . 15 | 16 | """ 17 | print and change the GPT partition type UUID 18 | """ 19 | 20 | import parted 21 | import sys 22 | import uuid 23 | 24 | # adjust as needed, eg /dev/sdc.. 25 | device = "sdcard.img" 26 | 27 | if len(sys.argv) not in (3, 4): 28 | print(f"{sys.argv[0]}: DEVICE PART-NUM [NEW-UUID]") 29 | sys.exit(1) 30 | 31 | devpath = sys.argv[1] 32 | partnum = int(sys.argv[2]) 33 | newuuid = None 34 | if len(sys.argv) == 4: 35 | newuuid = uuid.UUID(sys.argv[3]) 36 | 37 | device = parted.getDevice(devpath) 38 | disk = parted.newDisk(device) 39 | 40 | if partnum == 0 or partnum > len(disk.partitions): 41 | print( 42 | f"{sys.argv[0]}: partition {partnum} must be in range 1:{len(disk.partitions)}" 43 | ) 44 | sys.exit(1) 45 | 46 | part = disk.partitions[partnum - 1] 47 | 48 | if not hasattr(parted, "DISK_TYPE_PARTITION_TYPE_UUID"): 49 | print(f"{sys.argv[0]}: build against parted version >= 3.5 is required") 50 | sys.exit(1) 51 | 52 | if not disk.supportsFeature(parted.DISK_TYPE_PARTITION_TYPE_UUID): 53 | print( 54 | f"{sys.argv[0]}: disk label {disk.type} does not support partition type UUIDs" 55 | ) 56 | sys.exit(1) 57 | 58 | if newuuid is not None: 59 | part.type_uuid = newuuid.bytes 60 | disk.commit() 61 | 62 | print(str(uuid.UUID(bytes=part.type_uuid))) 63 | -------------------------------------------------------------------------------- /examples/import_partition.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright 2019 Geoff Williams 4 | # 5 | # This example script is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by the Free 7 | # Software Foundation, either version 3 of the License, or (at your option) any 8 | # later version so long as this copyright notice remains intact. 9 | # 10 | # This example script is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 13 | # details. 14 | # 15 | # You should have received a copy of the GNU General Public License along with 16 | # this example script. If not, see . 17 | 18 | __author__ = """Geoff Williams """ 19 | __copyright__ = """Copyright 2019 Geoff Williams""" 20 | 21 | """ 22 | Import a filesystem dump from file `new_partition.img` into a raw GPT image 23 | `sdcard.img` as a new partition. 24 | """ 25 | 26 | # pip3 install pyparted 27 | import parted 28 | import pprint 29 | import subprocess 30 | import os 31 | 32 | 33 | def pad_block(image_file): 34 | """ 35 | Pad a block to the nearest 1MiB (2048 sectors) 36 | """ 37 | # how many sectors (LBAs) does the whole disk use right now? 38 | sector_count = int(os.path.getsize(image_file) / 512) 39 | 40 | # partitions need to start at 1MiB offsets 41 | sector_alignment = sector_count % 2048 42 | 43 | if sector_alignment == 0: 44 | print("PADDING: already OK") 45 | else: 46 | padding_needed = 2048 - (sector_count % 2048) 47 | 48 | print(f"Padding {padding_needed} sectors to fill 1MiB block") 49 | with open(image_file, "ab") as file: 50 | file.write(bytearray(padding_needed * 512)) 51 | 52 | new_sectors = int(os.path.getsize(image_file) / 512) 53 | print(f"Padded {sector_count} --> {new_sectors}") 54 | 55 | 56 | # Example using a raw image file created with `dd` (already contains partitions) 57 | sdcard = "sdcard.img" 58 | 59 | # 100MiB file created with `dd`, formatted ext4 60 | new_partition_file = "new_partition.img" 61 | 62 | # Grab the sizes of the SD card and the new partition before we start work 63 | new_partition_size = os.path.getsize(new_partition_file) 64 | new_partition_size_sectors = int(new_partition_size / 512) 65 | sdcard_original_size = os.path.getsize(sdcard) 66 | original_sectors = int(sdcard_original_size / 512) 67 | 68 | 69 | # GPT stores a backup at the end of the drive that uses 33 blocks of 512 byte 70 | # sectors - see https://en.wikipedia.org/wiki/GUID_Partition_Table and this 71 | # second copy is required to both exist and be in the right place for the disk 72 | # to be readable. If we just append our new partition, we can use `sgdisk -e` to 73 | # move the backup back to the end of the disk, however, it will leave a gap that 74 | # breaks both our alignment and starting sector calculation so we will write out 75 | # the current GPT to a backup file, pad the image, append our new filesystem, 76 | # pad the imagage again and restore the backup GPT to give us a layout like: 77 | # 78 | # | existing data | 79 | # | padding to 1MiB boundary | 80 | # | ------------------------ | 81 | # | new partition | 82 | # | padding to 1MiB boundary | 83 | # | ------------------------ | 84 | # | restored GPT | 85 | 86 | gpt_backup = "gpt.dat" 87 | gpt_offset = -1 88 | gpt_size = 33 * 512 89 | print("Taking backup of GPT") 90 | with open(sdcard, "rb") as file: 91 | 92 | # seek to the start of the GPT data 33 LBA from the end of the disk, then 93 | # read it into a `gpt_data` 94 | file.seek(-gpt_size, os.SEEK_END) # Note minus sign, doesn't work in `wb` mode(?) 95 | gpt_offset = file.tell() 96 | print(f"GPT offset: {gpt_offset}") 97 | gpt_data = file.read() 98 | 99 | # sanity check that we read the right amount of data 100 | gpt_data_len = len(gpt_data) 101 | if gpt_data_len != gpt_size: 102 | raise ValueError(f"GPT backup bad: {gpt_data_len} != {gpt_size}") 103 | 104 | # write out our GPT backup 105 | with open(gpt_backup, "wb") as g: 106 | g.write(gpt_data) 107 | 108 | # sanity check we wrote the right amount of data 109 | gpt_backup_len = os.path.getsize(gpt_backup) 110 | if gpt_backup_len != gpt_size: 111 | raise ValueError(f"GPT backup bad: {gpt_backup_len} != {gpt_size}") 112 | 113 | # Truncate the last 33 LBA (GPT backup) 114 | with open(sdcard, "rb+") as file: 115 | file.truncate(gpt_offset) 116 | 117 | new_sectors = int(os.path.getsize(sdcard) / 512) 118 | 119 | if (original_sectors - new_sectors) != 33: 120 | raise ValueError(f"bad truncation {original_sectors} - {new_sectors} != 33") 121 | 122 | # now that the GPT is gone, pad out the image file ready for the new partition 123 | # and record the resulting image size. This gives us the starting point for our 124 | # new partition aligned to a 1MiB boundary 125 | pad_block(sdcard) 126 | partition_insertion_point = os.path.getsize(sdcard) 127 | partition_insertion_point_sector = int(partition_insertion_point / 512) 128 | subprocess.run( 129 | f"cat {new_partition_file} >> {sdcard}", shell=True, capture_output=True, check=True 130 | ) 131 | 132 | # pad out the block after writing our new partition 133 | pad_block(sdcard) 134 | 135 | # Restore the backup GPT 136 | subprocess.run( 137 | f"cat {gpt_backup} >> {sdcard}", shell=True, capture_output=True, check=True 138 | ) 139 | 140 | # Fix the backup GPT by "moving" it to end of disk (its already there but 141 | # contains checksums that needs recomputing as well as pointers to its position 142 | # on disk) 143 | subprocess.run(f"sgdisk -e {sdcard}", shell=True, capture_output=True, check=True) 144 | 145 | 146 | # Now the disk image contains the new partition and the GPT is adjusted for the 147 | # new free space. We just have to add our new partition and its ready to use 148 | device = parted.getDevice(sdcard) 149 | disk = parted.newDisk(device) 150 | 151 | geometry = parted.Geometry( 152 | device, start=partition_insertion_point_sector, length=new_partition_size_sectors 153 | ) 154 | 155 | print(f"New partition geometry:\n{geometry}") 156 | 157 | filesystem = parted.FileSystem(type="ext2", geometry=geometry) 158 | new_partition = parted.Partition( 159 | disk=disk, type=parted.PARTITION_NORMAL, fs=filesystem, geometry=geometry 160 | ) 161 | # name isn't in the constructor but we can set it separately 162 | new_partition.name = "myimportedpartition" 163 | disk.addPartition( 164 | partition=new_partition, constraint=parted.Constraint(exactGeom=geometry) 165 | ) 166 | 167 | disk.commit() 168 | print("created partition OK") 169 | -------------------------------------------------------------------------------- /examples/make_one_primary_partition.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | # 3 | # Copyright 2015 John Florian 4 | # 5 | # This example script is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by the Free 7 | # Software Foundation, either version 3 of the License, or (at your option) any 8 | # later version so long as this copyright notice remains intact. 9 | # 10 | # This example script is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 13 | # details. 14 | # 15 | # You should have received a copy of the GNU General Public License along with 16 | # this example script. If not, see . 17 | 18 | """ 19 | An example program that creates a single, bootable primary partition on a disk. 20 | """ 21 | from glob import glob 22 | from logging import getLogger 23 | import logging 24 | 25 | import parted 26 | 27 | 28 | __author__ = """John Florian """ 29 | __copyright__ = """Copyright 2015 John Florian""" 30 | 31 | 32 | class _ConsoleHandler(logging.StreamHandler): 33 | def __init__(self): 34 | super().__init__() 35 | self.setFormatter(logging.Formatter("{levelname} - {message}", style="{")) 36 | 37 | 38 | class ExampleDevice(object): 39 | """ 40 | A simple model of a block storage device that wraps up some examples of 41 | pyparted capabilities. 42 | """ 43 | 44 | def __init__(self, path): 45 | """ 46 | Initialize the ExampleDevice object. 47 | """ 48 | self.path = path 49 | self.logger = getLogger(__name__) 50 | 51 | @property 52 | def partition_names(self): 53 | """ 54 | @return: A list of partition device names on the block device. 55 | @rtype: str 56 | """ 57 | names = glob("{}[0-9]*".format(self.path)) 58 | self.logger.debug("has partitions %s", names) 59 | return names 60 | 61 | def partition(self): 62 | """ 63 | Create a partition table on the block device. 64 | 65 | The newly created partition will have the following characteristics: 66 | - a primary partition using 100% of the device capacity 67 | - optimal alignment given the disk topology information 68 | - a MS-DOS disk label for simple BIOS booting on PC-type hardware 69 | - marked as bootable 70 | """ 71 | self.logger.info("creating primary partition") 72 | device = parted.getDevice(self.path) 73 | self.logger.debug("created %s", device) 74 | disk = parted.freshDisk(device, "msdos") 75 | self.logger.debug("created %s", disk) 76 | geometry = parted.Geometry( 77 | device=device, start=1, length=device.getLength() - 1 78 | ) 79 | self.logger.debug("created %s", geometry) 80 | filesystem = parted.FileSystem(type="ext3", geometry=geometry) 81 | self.logger.debug("created %s", filesystem) 82 | partition = parted.Partition( 83 | disk=disk, type=parted.PARTITION_NORMAL, fs=filesystem, geometry=geometry 84 | ) 85 | self.logger.debug("created %s", partition) 86 | disk.addPartition( 87 | partition=partition, constraint=device.optimalAlignedConstraint 88 | ) 89 | partition.setFlag(parted.PARTITION_BOOT) 90 | disk.commit() 91 | 92 | def wipe_dev(self, dev_path): 93 | """ 94 | Wipe a device (partition or otherwise) of meta-data, be it file system, 95 | LVM, etc. 96 | 97 | @param dev_path: Device path of the partition to be wiped. 98 | @type dev_path: str 99 | """ 100 | self.logger.debug("wiping %s", dev_path) 101 | with open(dev_path, "wb") as p: 102 | p.write(bytearray(1024)) 103 | 104 | def wipe(self): 105 | """ 106 | Wipe the block device of meta-data, be it file system, LVM, etc. 107 | 108 | This is not intended to be secure, but rather to ensure that 109 | auto-discovery tools don't recognize anything here. 110 | """ 111 | self.logger.info("wiping partitions and other meta-data") 112 | for partition in self.partition_names: 113 | self.wipe_dev(partition) 114 | self.wipe_dev(self.path) 115 | 116 | 117 | if __name__ == "__main__": 118 | # It should be plenty obvious what needs to be done here. If it's not 119 | # obvious to you, please don't run this!!! 120 | my_unimportant_test_disk = "/dev/sdX__FIXME" 121 | 122 | # Set up a logger for nice visibility. 123 | logger = getLogger(__name__) 124 | logger.setLevel(logging.DEBUG) 125 | logger.addHandler(_ConsoleHandler()) 126 | 127 | # Ok, now for the good stuff, the actual example. 128 | guinea_pig = ExampleDevice(my_unimportant_test_disk) 129 | guinea_pig.wipe() 130 | guinea_pig.partition() 131 | -------------------------------------------------------------------------------- /examples/query_device_capacity.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | # 3 | # Copyright 2017 John Florian 4 | # 5 | # This example script is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by the Free 7 | # Software Foundation, either version 3 of the License, or (at your option) any 8 | # later version so long as this copyright notice remains intact. 9 | # 10 | # This example script is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 13 | # details. 14 | # 15 | # You should have received a copy of the GNU General Public License along with 16 | # this example script. If not, see . 17 | 18 | __author__ = """John Florian """ 19 | __copyright__ = """Copyright 2017 John Florian""" 20 | 21 | """ 22 | An example program that queries the capacity of a device that supports 23 | removable media, such as CompactFlash card reader. 24 | """ 25 | import parted 26 | 27 | device_name = "/dev/sdd" 28 | 29 | 30 | def to_mebibytes(value): 31 | return value / (2**20) 32 | 33 | 34 | def to_megabytes(value): 35 | return value / (10**6) 36 | 37 | 38 | while True: 39 | print("press Enter after inserting a new card and letting things settle") 40 | input() 41 | dev = parted.getDevice(device_name) 42 | capacity = dev.length * dev.sectorSize 43 | print( 44 | "{} has a capacity of {:n} bytes " 45 | "({:n} MB or {:n} MiB)".format( 46 | device_name, 47 | capacity, 48 | to_megabytes(capacity), 49 | to_mebibytes(capacity), 50 | ) 51 | ) 52 | 53 | # Important! parted caches details so it's necessary to invalidate its 54 | # cache to ensure accurate results when using removable media. See 55 | # https://github.com/dcantrell/pyparted/issues/33 for more details. 56 | dev.removeFromCache() 57 | -------------------------------------------------------------------------------- /include/_pedmodule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * _pedmodule.h 3 | * 4 | * Copyright The pyparted Project Authors 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | */ 7 | 8 | #ifndef _PARTEDMODULE_H_INCLUDED 9 | #define _PARTEDMODULE_H_INCLUDED 10 | 11 | #include 12 | 13 | extern PyObject *py_libparted_get_version(PyObject *, PyObject *); 14 | extern PyObject *py_pyparted_version(PyObject *, PyObject *); 15 | extern PyMODINIT_FUNC PyInit__ped(void); 16 | 17 | #endif /* _PARTEDMODULE_H_INCLUDED */ 18 | -------------------------------------------------------------------------------- /include/convert.h: -------------------------------------------------------------------------------- 1 | /* 2 | * convert.h 3 | * Functions for converting to/from Python _ped types and C libparted types 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef CONVERT_H_INCLUDED 10 | #define CONVERT_H_INCLUDED 11 | 12 | #include 13 | 14 | #include "pyconstraint.h" 15 | #include "pydevice.h" 16 | #include "pydisk.h" 17 | #include "pyfilesys.h" 18 | #include "pygeom.h" 19 | #include "pynatmath.h" 20 | #include "pytimer.h" 21 | 22 | #define TP_FLAGS (Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE) 23 | 24 | PedAlignment *_ped_Alignment2PedAlignment(PyObject *); 25 | _ped_Alignment *PedAlignment2_ped_Alignment(PedAlignment *); 26 | 27 | PedConstraint *_ped_Constraint2PedConstraint(PyObject *); 28 | _ped_Constraint *PedConstraint2_ped_Constraint(PedConstraint *); 29 | 30 | PedDevice *_ped_Device2PedDevice(PyObject *); 31 | _ped_Device *PedDevice2_ped_Device(PedDevice *); 32 | 33 | PedDisk *_ped_Disk2PedDisk(PyObject *); 34 | _ped_Disk *PedDisk2_ped_Disk(PedDisk *); 35 | 36 | PedDiskType *_ped_DiskType2PedDiskType(PyObject *); 37 | _ped_DiskType *PedDiskType2_ped_DiskType(const PedDiskType *); 38 | 39 | PedFileSystem *_ped_FileSystem2PedFileSystem(PyObject *); 40 | _ped_FileSystem *PedFileSystem2_ped_FileSystem(PedFileSystem *); 41 | 42 | PedFileSystemType *_ped_FileSystemType2PedFileSystemType(PyObject *); 43 | _ped_FileSystemType *PedFileSystemType2_ped_FileSystemType(const PedFileSystemType *); 44 | 45 | PedGeometry *_ped_Geometry2PedGeometry(PyObject *); 46 | _ped_Geometry *PedGeometry2_ped_Geometry(PedGeometry *); 47 | 48 | PedCHSGeometry *_ped_CHSGeometry2PedCHSGeometry(PyObject *); 49 | _ped_CHSGeometry *PedCHSGeometry2_ped_CHSGeometry(PedCHSGeometry *); 50 | 51 | PedPartition *_ped_Partition2PedPartition(_ped_Partition *); 52 | _ped_Partition *PedPartition2_ped_Partition(PedPartition *, _ped_Disk *); 53 | 54 | PedTimer *_ped_Timer2PedTimer(PyObject *); 55 | _ped_Timer *PedTimer2_ped_Timer(PedTimer *); 56 | 57 | #endif /* CONVERT_H_INCLUDED */ 58 | -------------------------------------------------------------------------------- /include/docstrings/pyconstraint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pyconstraint.h 3 | * pyparted docstrings for pyconstraint.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef DOCSTRINGS_PYCONSTRAINT_H_INCLUDED 10 | #define DOCSTRINGS_PYCONSTRAINT_H_INCLUDED 11 | 12 | #include 13 | 14 | PyDoc_STRVAR(constraint_duplicate_doc, 15 | "duplicate(Constraint) -> Constraint\n\n" 16 | "Return a new Constraint that is a copy of the given Constraint."); 17 | 18 | PyDoc_STRVAR(constraint_intersect_doc, 19 | "intersect(Constraint) -> Constraint\n\n" 20 | "Return a Constraint that requires a region to satisfy both this\n" 21 | "Constraint object and the one passed in to the method. Any\n" 22 | "region satisfying both Constraints will also satisfy the returned\n" 23 | "Constraint."); 24 | 25 | PyDoc_STRVAR(constraint_solve_max_doc, 26 | "solve_max() -> Constraint\n\n" 27 | "Find the largest region that satisfies this Constraint object and\n" 28 | "return a new Constraint. There may be more than one solution.\n" 29 | "There are no guarantees about which solution will be returned.\n"); 30 | 31 | PyDoc_STRVAR(constraint_solve_nearest_doc, 32 | "solve_nearest(Geometry) -> Constraint\n\n" 33 | "Return the nearest region to Geometry that will satisfy this\n" 34 | "Constraint object. This function does not guarantee what nearest\n" 35 | "means."); 36 | 37 | PyDoc_STRVAR(constraint_is_solution_doc, 38 | "is_solution(Geometry) -> bool\n\n" 39 | "Return True if Geometry satisfies this Constraint, False otherwise."); 40 | 41 | PyDoc_STRVAR(_ped_Constraint_doc, 42 | "A _ped.Constraint object describes a set of restrictions on other pyparted\n" 43 | "operations. Constraints can restrict the location and alignment of the start\n" 44 | "and end of a partition, and its minimum and maximum size. Constraint\n" 45 | "operations include various methods of creating constraints, intersecting,\n" 46 | "and solving sets of constraints.\n\n" 47 | "Most constraint operations can raise _ped.CreateException if creating\n" 48 | "temporary objects fails, or ArithmeticError if an error occurrs during\n" 49 | "calculations."); 50 | 51 | #endif /* DOCSTRINGS_PYCONSTRAINT_H_INCLUDED */ 52 | -------------------------------------------------------------------------------- /include/docstrings/pyfilesys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pyfilesys.h 3 | * pyparted docstrings for pyfilesys.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef DOCSTRINGS_PYFILESYS_H_INCLUDED 10 | #define DOCSTRINGS_PYFILESYS_H_INCLUDED 11 | 12 | #include 13 | 14 | PyDoc_STRVAR(_ped_FileSystemType_doc, 15 | "A _ped.FileSystemType object gives a name to a single filesystem that parted\n" 16 | "understands. parted maintains a list of these objects which can be\n" 17 | "traversed with the self.get_next method or accessed directly via self.get()."); 18 | 19 | PyDoc_STRVAR(_ped_FileSystem_doc, 20 | "A _ped.FileSystem object describes a filesystem that exists in a given\n" 21 | "region on a device. The region is given by a _ped.Geometry object, and\n" 22 | "the filesystem is further described by a _ped.FileSystemType object.\n\n" 23 | "Filesystem operations are especially prone to failures, and pyparted raises\n" 24 | "a variety of exceptions when error conditions are encountered. The most\n" 25 | "common is _ped.FileSystemException, though _ped.IOException and\n" 26 | "_ped.CreateException may also be raised."); 27 | 28 | #endif /* DOCSTRINGS_PYFILESYS_H_INCLUDED */ 29 | -------------------------------------------------------------------------------- /include/docstrings/pygeom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pygeom.h 3 | * pyparted docstrings for pygeom.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef DOCSTRINGS_PYGEOM_H_INCLUDED 10 | #define DOCSTRINGS_PYGEOM_H_INCLUDED 11 | 12 | #include 13 | 14 | PyDoc_STRVAR(geometry_duplicate_doc, 15 | "duplicate(self) -> _ped.Geometry\n\n" 16 | "Create an identical copy of self. Raises _ped.CreateException if the\n" 17 | "operation fails"); 18 | 19 | PyDoc_STRVAR(geometry_intersect_doc, 20 | "intersect(self, Geometry) -> _ped.Geometry\n\n" 21 | "Create a new Geometry describing the region common to both self and\n" 22 | "Geometry. Raises ArithmeticError if the two regions do not intersect."); 23 | 24 | PyDoc_STRVAR(geometry_set_doc, 25 | "set(self, start, length) -> boolean\n\n" 26 | "Sets a new start Sector and length Sector in the Geometry object,\n" 27 | "also implicitly setting the end Sector as well."); 28 | 29 | PyDoc_STRVAR(geometry_set_start_doc, 30 | "set_start(self, start) -> boolean\n\n" 31 | "Sets a new start Sector without modifying the end Sector. Length\n" 32 | "will be modified to match the new starting position."); 33 | 34 | PyDoc_STRVAR(geometry_set_end_doc, 35 | "set_end(self, end) -> boolean\n\n" 36 | "Sets a new ending Sector without modifying the start Sector. Length\n" 37 | "will be modified to match the new ending position."); 38 | 39 | PyDoc_STRVAR(geometry_test_overlap_doc, 40 | "test_overlap(self, Geometry) -> boolean\n\n" 41 | "Return whether self and Geometry are on the same physical device and\n" 42 | "share at least part of the same region."); 43 | 44 | PyDoc_STRVAR(geometry_test_inside_doc, 45 | "test_inside(self, Geometry) -> boolean\n\n" 46 | "Return whether Geometry is entirely within self and on the same physical\n" 47 | "device."); 48 | 49 | PyDoc_STRVAR(geometry_test_equal_doc, 50 | "test_equal(self, Geometry) -> boolean\n\n" 51 | "Return whether self and Geometry are on the same device and have the same\n" 52 | "region."); 53 | 54 | PyDoc_STRVAR(geometry_test_sector_inside_doc, 55 | "test_sector_inside(self, Sector) -> boolean\n\n" 56 | "Return whether Sector is entirely within the region described by self."); 57 | 58 | PyDoc_STRVAR(geometry_read_doc, 59 | "read(self, buffer, offset, count) -> boolean\n\n" 60 | "Read data from the region described by self. This method reads count\n" 61 | "Sectors starting at Sector offset (from the start of the region, not\n" 62 | "from the start of the disk) into buffer. This method raises\n" 63 | "_ped.IOException on error."); 64 | 65 | PyDoc_STRVAR(geometry_sync_doc, 66 | "sync(self) -> boolean\n\n" 67 | "Flushes all caches on the device described by self. This operation can be\n" 68 | "slow because it must guarantee cache coherency among multiple caches. This\n" 69 | "method raises _ped.IOException on error."); 70 | 71 | PyDoc_STRVAR(geometry_sync_fast_doc, 72 | "sync_fast(self) -> boolean\n\n" 73 | "Flushes all caches on the device described by self without guaranteeing\n" 74 | "cache coherency. This makes it fast but more prone to error. This method\n" 75 | "raises _ped.IOException on error."); 76 | 77 | PyDoc_STRVAR(geometry_write_doc, 78 | "write(self, buffer, offset, count) -> boolean\n\n" 79 | "Write data into the region described by self. This method writes count\n" 80 | "Sectors of buffer into the region starting at Sector offset. The offset is\n" 81 | "from the beginning of the region, not of the disk. This method raises\n" 82 | "_ped.IOException on error."); 83 | 84 | PyDoc_STRVAR(geometry_check_doc, 85 | "check(self, offset, granularity, count, timer=None) -> Sector\n\n" 86 | "This method checks the region described by self for errors on the disk.\n" 87 | "The region to check starts at offset Sectors from the beginning of the\n" 88 | "region and is count Sectors long. granularity specifies how Sectors should\n" 89 | "be grouped together.\n\n" 90 | "This method returns the first bad sector, or 0 if there are no errors."); 91 | 92 | PyDoc_STRVAR(geometry_map_doc, 93 | "map(self, Geometry, Sector) -> integer\n\n" 94 | "Given a Geometry that overlaps with self and a Sector inside Geometry,\n" 95 | "this method translates the address of Sector into an address inside self.\n" 96 | "The new address is returned, or ArithmeticError is raised if Sector does\n" 97 | "not exist within self."); 98 | 99 | PyDoc_STRVAR(_ped_Geometry_doc, 100 | "A _ped.Geometry object describes a continuous region on a physical device.\n" 101 | "This device is given by the dev attribute when the Geometry is created.\n" 102 | "Most methods on this object involve creating new Geometry objects as needed\n" 103 | "and can therefore raise _ped.CreateException when an error occurs creating\n" 104 | "the new object. Most methods can also raise _ped.IOException when reading\n" 105 | "or writing the underlying physical device fails.\n\n" 106 | "libparted (and therefore pyparted) attempts to enforce the following\n" 107 | "conditions on Geometry objects:\n\n" 108 | "\t- start + length - 1 == end\n" 109 | "\t- length > 0\n" 110 | "\t- start >= 0\n" 111 | "\t- end < dev.length"); 112 | 113 | #endif /* DOCSTRINGS_PYGEOM_H_INCLUDED */ 114 | -------------------------------------------------------------------------------- /include/docstrings/pynatmath.h: -------------------------------------------------------------------------------- 1 | /* 2 | * docstrings/pynatmath.h 3 | * pyparted docstrings for for pynatmath.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef DOCSTRINGS_PYNATMATH_H_INCLUDED 10 | #define DOCSTRINGS_PYNATMATH_H_INCLUDED 11 | 12 | #include 13 | 14 | PyDoc_STRVAR(alignment_duplicate_doc, 15 | "duplicate(self) -> _ped.Alignment\n\n" 16 | "Create an identical copy of self. Raises _ped.CreateException if the\n" 17 | "operation fails"); 18 | 19 | PyDoc_STRVAR(alignment_intersect_doc, 20 | "intersect(self, Alignment) -> _ped.Alignment\n\n" 21 | "Create a new Alignment that describes the intersection of self and\n" 22 | "Alignment. A sector will satisfy the new Alignment if and only if it\n" 23 | "satisfies both of the original alignments, where 'satisfy' is determined\n" 24 | "by is_aligned(). The proof of this is relatively complicated and is\n" 25 | "described thoroughly in the libparted source. This method raises\n" 26 | "ArithmeticError if no intersection can be found."); 27 | 28 | PyDoc_STRVAR(alignment_align_up_doc, 29 | "align_up(self, Geometry, Sector) -> Sector\n\n" 30 | "Returns the closest Sector to the input Sector that lies inside Geometry\n" 31 | "and satisfies the alignment constraint. This method prefers, but does not\n" 32 | "guarantee, that the result is beyond Sector. If no such Sector can be\n" 33 | "found, an ArithmeticError is raised."); 34 | 35 | PyDoc_STRVAR(alignment_align_down_doc, 36 | "align_down(self, Geometry, Sector) -> Sector\n\n" 37 | "Returns the closest Sector to the input Sector that lies inside Geometry\n" 38 | "and satisfies the alignment constraint. This method prefers, but does not\n" 39 | "guarantee, that the result is below Sector. If no such Sector can be\n" 40 | "found, an ArithmeticError is raised."); 41 | 42 | PyDoc_STRVAR(alignment_align_nearest_doc, 43 | "align_nearest(self, Geometry, Sector) -> Sector\n\n" 44 | "Returns the closest Sector to the input Sector that lies inside Geometry\n" 45 | "and satisfies the aligmnent constraint. If no such Sector can be found,\n" 46 | "an ArithmeticError is raised."); 47 | 48 | PyDoc_STRVAR(alignment_is_aligned_doc, 49 | "is_aligned(self, Geometry, Sector) -> boolean\n\n" 50 | "Returns whether or not Sector lies inside Geometry and satisfies the\n" 51 | "alignment constraint. This method defines what 'satisfy' means for\n" 52 | "intersection."); 53 | 54 | PyDoc_STRVAR(_ped_Alignment_doc, 55 | "A _ped.Alignment object describes constraints on how sectors and Geometry\n" 56 | "objects are aligned. It includes a variety of methods for aligning sectors\n" 57 | "and calculating the intersection of two Alignment objects. Most methods on\n" 58 | "this object can raise _ped.CreateException if creating temporary objects\n" 59 | "fails and ArithmeticError if calculating alignments and intersections fails."); 60 | 61 | #endif /* DOCSTRINGS_PYNATMATH_H_INCLUDED */ 62 | -------------------------------------------------------------------------------- /include/exceptions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * exceptions.h 3 | * 4 | * Copyright The pyparted Project Authors 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | */ 7 | 8 | #ifndef _EXCEPTIONS_H_INCLUDED 9 | #define _EXCEPTIONS_H_INCLUDED 10 | 11 | #include 12 | 13 | /* custom exceptions for _ped */ 14 | extern PyObject *AlignmentException; 15 | extern PyObject *CreateException; 16 | extern PyObject *ConstraintException; 17 | extern PyObject *DeviceException; 18 | extern PyObject *DiskException; 19 | extern PyObject *DiskLabelException; 20 | extern PyObject *FileSystemException; 21 | extern PyObject *GeometryException; 22 | extern PyObject *IOException; 23 | extern PyObject *NotNeededException; 24 | extern PyObject *PartedException; 25 | extern PyObject *PartitionException; 26 | extern PyObject *TimerException; 27 | extern PyObject *UnknownDeviceException; 28 | extern PyObject *UnknownTypeException; 29 | 30 | extern unsigned int partedExnRaised; 31 | extern char *partedExnMessage; 32 | 33 | #endif /* _EXCEPTIONS_H_INCLUDED */ 34 | -------------------------------------------------------------------------------- /include/pyconstraint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pyconstraint.h 3 | * pyparted type definitions for pyconstraint.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef PYCONSTRAINT_H_INCLUDED 10 | #define PYCONSTRAINT_H_INCLUDED 11 | 12 | #include 13 | 14 | #include 15 | 16 | /* 1:1 function mappings for constraint.h in libparted */ 17 | PyObject *py_ped_constraint_new_from_min_max(PyObject *, PyObject *); 18 | PyObject *py_ped_constraint_new_from_min(PyObject *, PyObject *); 19 | PyObject *py_ped_constraint_new_from_max(PyObject *, PyObject *); 20 | PyObject *py_ped_constraint_duplicate(PyObject *, PyObject *); 21 | PyObject *py_ped_constraint_intersect(PyObject *, PyObject *); 22 | PyObject *py_ped_constraint_solve_max(PyObject *, PyObject *); 23 | PyObject *py_ped_constraint_solve_nearest(PyObject *, PyObject *); 24 | PyObject *py_ped_constraint_is_solution(PyObject *, PyObject *); 25 | PyObject *py_ped_constraint_any(PyObject *, PyObject *); 26 | PyObject *py_ped_constraint_exact(PyObject *, PyObject *); 27 | 28 | /* _ped.Constraint type is the Python equiv of PedConstraint in libparted */ 29 | typedef struct { 30 | PyObject_HEAD 31 | 32 | /* PedConstraint members */ 33 | PyObject *start_align; /* _ped.Alignment */ 34 | PyObject *end_align; /* _ped.Alignment */ 35 | PyObject *start_range; /* _ped.Geometry */ 36 | PyObject *end_range; /* _ped.Geometry */ 37 | long long min_size; /* PedSector */ 38 | long long max_size; /* PedSector */ 39 | } _ped_Constraint; 40 | 41 | void _ped_Constraint_dealloc(_ped_Constraint *); 42 | int _ped_Constraint_compare(_ped_Constraint *, PyObject *); 43 | PyObject *_ped_Constraint_richcompare(_ped_Constraint *, PyObject *, int); 44 | PyObject *_ped_Constraint_str(_ped_Constraint *); 45 | int _ped_Constraint_traverse(_ped_Constraint *, visitproc, void *); 46 | int _ped_Constraint_clear(_ped_Constraint *); 47 | int _ped_Constraint_init(_ped_Constraint *, PyObject *, PyObject *); 48 | PyObject *_ped_Constraint_get(_ped_Constraint *, void *); 49 | int _ped_Constraint_set(_ped_Constraint *, PyObject *, void *); 50 | 51 | extern PyTypeObject _ped_Constraint_Type_obj; 52 | 53 | #endif /* PYCONSTRAINT_H_INCLUDED */ 54 | -------------------------------------------------------------------------------- /include/pydevice.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pydevice.h 3 | * pyparted type definitions for pydevice.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef PYDEVICE_H_INCLUDED 10 | #define PYDEVICE_H_INCLUDED 11 | 12 | #include 13 | 14 | #include 15 | 16 | /* _ped.CHSGeometry type is the Python equiv of PedCHSGeometry in libparted */ 17 | typedef struct { 18 | PyObject_HEAD 19 | 20 | /* a PedCHSGeometry stores three ints */ 21 | int cylinders; 22 | int heads; 23 | int sectors; 24 | } _ped_CHSGeometry; 25 | 26 | void _ped_CHSGeometry_dealloc(_ped_CHSGeometry *); 27 | int _ped_CHSGeometry_compare(_ped_CHSGeometry *, PyObject *); 28 | PyObject *_ped_CHSGeometry_richcompare(_ped_CHSGeometry *, PyObject *, int); 29 | PyObject *_ped_CHSGeometry_str(_ped_CHSGeometry *); 30 | int _ped_CHSGeometry_traverse(_ped_CHSGeometry *, visitproc, void *); 31 | int _ped_CHSGeometry_clear(_ped_CHSGeometry *); 32 | PyObject *_ped_CHSGeometry_get(_ped_CHSGeometry *, void *); 33 | 34 | extern PyTypeObject _ped_CHSGeometry_Type_obj; 35 | 36 | /* _ped.Device type is the Python equivalent of PedDevice in libparted */ 37 | typedef struct { 38 | PyObject_HEAD 39 | 40 | /* a PedDevice is complex, we will store primitives when appropriate or 41 | * just other Python objects we've created for the typedefs in libparted */ 42 | char *model; 43 | char *path; 44 | long long type; 45 | long long sector_size; 46 | long long phys_sector_size; 47 | long long length; /* PedSector */ 48 | int open_count; 49 | int read_only; 50 | int external_mode; 51 | int dirty; 52 | int boot_dirty; 53 | PyObject *hw_geom; /* a _ped.CHSGeometry */ 54 | PyObject *bios_geom; /* a _ped.CHSGeometry */ 55 | short host; 56 | short did; 57 | } _ped_Device; 58 | 59 | void _ped_Device_dealloc(_ped_Device *); 60 | int _ped_Device_compare(_ped_Device *, PyObject *); 61 | PyObject *_ped_Device_richcompare(_ped_Device *, PyObject *, int); 62 | PyObject *_ped_Device_str(_ped_Device *); 63 | int _ped_Device_traverse(_ped_Device *, visitproc, void *); 64 | int _ped_Device_clear(_ped_Device *); 65 | PyObject *_ped_Device_get(_ped_Device *, void *); 66 | 67 | extern PyTypeObject _ped_Device_Type_obj; 68 | 69 | /* 1:1 function mappings for device.h in libparted */ 70 | PyObject *py_ped_disk_probe(PyObject *, PyObject *); 71 | PyObject *py_ped_device_probe_all(PyObject *, PyObject *); 72 | PyObject *py_ped_device_free_all(PyObject *, PyObject *); 73 | PyObject *py_ped_device_get(PyObject *, PyObject *); 74 | PyObject *py_ped_device_get_next(PyObject *, PyObject *); 75 | PyObject *py_ped_device_is_busy(PyObject *, PyObject *); 76 | PyObject *py_ped_device_open(PyObject *, PyObject *); 77 | PyObject *py_ped_device_close(PyObject *, PyObject *); 78 | PyObject *py_ped_device_destroy(PyObject *, PyObject *); 79 | PyObject *py_ped_device_cache_remove(PyObject *, PyObject *); 80 | PyObject *py_ped_device_begin_external_access(PyObject *, PyObject *); 81 | PyObject *py_ped_device_end_external_access(PyObject *, PyObject *); 82 | PyObject *py_ped_device_read(PyObject *, PyObject *); 83 | PyObject *py_ped_device_write(PyObject *, PyObject *); 84 | PyObject *py_ped_device_sync(PyObject *, PyObject *); 85 | PyObject *py_ped_device_sync_fast(PyObject *, PyObject *); 86 | PyObject *py_ped_device_check(PyObject *, PyObject *); 87 | PyObject *py_ped_device_get_constraint(PyObject *, PyObject *); 88 | PyObject *py_ped_device_get_minimal_aligned_constraint(PyObject *, PyObject *); 89 | PyObject *py_ped_device_get_optimal_aligned_constraint(PyObject *, PyObject *); 90 | PyObject *py_ped_device_get_minimum_alignment(PyObject *, PyObject *); 91 | PyObject *py_ped_device_get_optimum_alignment(PyObject *, PyObject *); 92 | PyObject *py_ped_unit_get_size(PyObject *, PyObject *); 93 | PyObject *py_ped_unit_format_custom_byte(PyObject *, PyObject *); 94 | PyObject *py_ped_unit_format_byte(PyObject *, PyObject *); 95 | PyObject *py_ped_unit_format_custom(PyObject *, PyObject *); 96 | PyObject *py_ped_unit_format(PyObject *, PyObject *); 97 | PyObject *py_ped_unit_parse(PyObject *, PyObject *); 98 | PyObject *py_ped_unit_parse_custom(PyObject *, PyObject *); 99 | 100 | #endif /* PYDEVICE_H_INCLUDED */ 101 | -------------------------------------------------------------------------------- /include/pydisk.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pydisk.h 3 | * pyparted type definitions for pydisk.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef PYDISK_H_INCLUDED 10 | #define PYDISK_H_INCLUDED 11 | 12 | #include 13 | 14 | #include 15 | 16 | /* _ped.Partition type is the Python equivalent of PedPartition 17 | * in libparted */ 18 | typedef struct { 19 | PyObject_HEAD 20 | 21 | /* PedPartition members */ 22 | PyObject *disk; /* _ped.Disk */ 23 | PyObject *geom; /* _ped.Geometry */ 24 | int type; /* PedPartitionType */ 25 | PyObject *fs_type; /* _ped.FileSystemType */ 26 | 27 | /* store the PedPartition from libparted */ 28 | PedPartition *ped_partition; 29 | 30 | int _owned; /* Belongs to a Disk or not */ 31 | } _ped_Partition; 32 | 33 | void _ped_Partition_dealloc(_ped_Partition *); 34 | int _ped_Partition_compare(_ped_Partition *, PyObject *); 35 | PyObject *_ped_Partition_richcompare(_ped_Partition *, PyObject *, int); 36 | PyObject *_ped_Partition_str(_ped_Partition *); 37 | int _ped_Partition_traverse(_ped_Partition *, visitproc, void *); 38 | int _ped_Partition_clear(_ped_Partition *); 39 | int _ped_Partition_init(_ped_Partition *, PyObject *, PyObject *); 40 | PyObject *_ped_Partition_get(_ped_Partition *, void *); 41 | int _ped_Partition_set(_ped_Partition *, PyObject *, void *); 42 | 43 | extern PyTypeObject _ped_Partition_Type_obj; 44 | 45 | /* _ped.Disk type is the Python equivalent of PedDisk in libparted */ 46 | typedef struct { 47 | PyObject_HEAD 48 | 49 | /* PedDisk members */ 50 | PyObject *dev; /* _ped.Device */ 51 | PyObject *type; /* _ped.DiskType */ 52 | 53 | /* store the PedDisk from libparted */ 54 | PedDisk *ped_disk; 55 | } _ped_Disk; 56 | 57 | void _ped_Disk_dealloc(_ped_Disk *); 58 | int _ped_Disk_compare(_ped_Disk *, PyObject *); 59 | PyObject *_ped_Disk_richcompare(_ped_Disk *, PyObject *, int); 60 | PyObject *_ped_Disk_str(_ped_Disk *); 61 | int _ped_Disk_traverse(_ped_Disk *, visitproc, void *); 62 | int _ped_Disk_clear(_ped_Disk *); 63 | int _ped_Disk_init(_ped_Disk *, PyObject *, PyObject *); 64 | 65 | extern PyTypeObject _ped_Disk_Type_obj; 66 | 67 | /* _ped.DiskType type is the Python equivalent of PedDiskType in libparted */ 68 | typedef struct { 69 | PyObject_HEAD 70 | 71 | /* PedDiskType members */ 72 | char *name; 73 | long long features; /* PedDiskTypeFeature */ 74 | } _ped_DiskType; 75 | 76 | void _ped_DiskType_dealloc(_ped_DiskType *); 77 | int _ped_DiskType_compare(_ped_DiskType *, PyObject *); 78 | PyObject *_ped_DiskType_richcompare(_ped_DiskType *, PyObject *, int); 79 | PyObject *_ped_DiskType_str(_ped_DiskType *); 80 | int _ped_DiskType_traverse(_ped_DiskType *, visitproc, void *); 81 | int _ped_DiskType_clear(_ped_DiskType *); 82 | PyObject *_ped_DiskType_get(_ped_DiskType *, void *); 83 | 84 | extern PyTypeObject _ped_DiskType_Type_obj; 85 | 86 | /* 1:1 function mappings for disk.h in libparted */ 87 | PyObject *py_ped_disk_type_get_next(PyObject *, PyObject *); 88 | PyObject *py_ped_disk_type_get(PyObject *, PyObject *); 89 | PyObject *py_ped_disk_type_check_feature(PyObject *, PyObject *); 90 | PyObject *py_ped_disk_clobber(PyObject *, PyObject *); 91 | PyObject *py_ped_disk_duplicate(PyObject *, PyObject *); 92 | PyObject *py_ped_disk_destroy(PyObject *, PyObject *); 93 | PyObject *py_ped_disk_commit(PyObject *, PyObject *); 94 | PyObject *py_ped_disk_commit_to_dev(PyObject *, PyObject *); 95 | PyObject *py_ped_disk_commit_to_os(PyObject *, PyObject *); 96 | PyObject *py_ped_disk_check(PyObject *, PyObject *); 97 | PyObject *py_ped_disk_print(PyObject *, PyObject *); 98 | PyObject *py_ped_disk_get_primary_partition_count(PyObject *, PyObject *); 99 | PyObject *py_ped_disk_get_last_partition_num(PyObject *, PyObject *); 100 | PyObject *py_ped_disk_get_max_primary_partition_count(PyObject *, PyObject *); 101 | PyObject *py_ped_disk_get_max_supported_partition_count(PyObject *, PyObject *); 102 | PyObject *py_ped_disk_get_partition_alignment(PyObject *, PyObject *); 103 | PyObject *py_ped_disk_max_partition_length(PyObject *, PyObject *); 104 | PyObject *py_ped_disk_max_partition_start_sector(PyObject *, PyObject *); 105 | PyObject *py_ped_disk_set_flag(PyObject *, PyObject *); 106 | PyObject *py_ped_disk_get_flag(PyObject *, PyObject *); 107 | PyObject *py_ped_disk_is_flag_available(PyObject *, PyObject *); 108 | PyObject *py_ped_disk_flag_get_name(PyObject *, PyObject *); 109 | PyObject *py_ped_disk_flag_get_by_name(PyObject *, PyObject *); 110 | PyObject *py_ped_disk_flag_next(PyObject *, PyObject *); 111 | PyObject *py_ped_partition_destroy(_ped_Partition *, PyObject *); 112 | PyObject *py_ped_partition_is_active(_ped_Partition *, PyObject *); 113 | PyObject *py_ped_partition_set_flag(_ped_Partition *, PyObject *); 114 | PyObject *py_ped_partition_get_flag(_ped_Partition *, PyObject *); 115 | PyObject *py_ped_partition_is_flag_available(_ped_Partition *, PyObject *); 116 | PyObject *py_ped_partition_set_system(_ped_Partition *, PyObject *); 117 | PyObject *py_ped_partition_set_name(_ped_Partition *, PyObject *); 118 | PyObject *py_ped_partition_get_name(_ped_Partition *, PyObject *); 119 | #if PED_DISK_TYPE_LAST_FEATURE > 2 120 | PyObject *py_ped_partition_set_type_id(_ped_Partition *, PyObject *); 121 | PyObject *py_ped_partition_get_type_id(_ped_Partition *, PyObject *); 122 | #endif /* PED_DISK_TYPE_LAST_FEATURE > 2 */ 123 | #if PED_DISK_TYPE_LAST_FEATURE > 4 124 | PyObject *py_ped_partition_set_type_uuid(_ped_Partition *, PyObject *); 125 | PyObject *py_ped_partition_get_type_uuid(_ped_Partition *, PyObject *); 126 | #endif /* PED_DISK_TYPE_LAST_FEATURE > 4 */ 127 | PyObject *py_ped_partition_is_busy(_ped_Partition *, PyObject *); 128 | PyObject *py_ped_partition_get_path(_ped_Partition *, PyObject *); 129 | PyObject *py_ped_partition_reset_num(_ped_Partition *, PyObject *); 130 | PyObject *py_ped_partition_type_get_name(PyObject *, PyObject *); 131 | PyObject *py_ped_partition_flag_get_name(PyObject *, PyObject *); 132 | PyObject *py_ped_partition_flag_get_by_name(PyObject *, PyObject *); 133 | PyObject *py_ped_partition_flag_next(PyObject *, PyObject *); 134 | PyObject *py_ped_disk_add_partition(PyObject *, PyObject *); 135 | PyObject *py_ped_disk_remove_partition(PyObject *, PyObject *); 136 | PyObject *py_ped_disk_delete_partition(PyObject *, PyObject *); 137 | PyObject *py_ped_disk_delete_all(PyObject *, PyObject *); 138 | PyObject *py_ped_disk_set_partition_geom(PyObject *, PyObject *); 139 | PyObject *py_ped_disk_maximize_partition(PyObject *, PyObject *); 140 | PyObject *py_ped_disk_get_max_partition_geometry(PyObject *, PyObject *); 141 | PyObject *py_ped_disk_minimize_extended_partition(PyObject *, PyObject *); 142 | PyObject *py_ped_disk_next_partition(PyObject *, PyObject *); 143 | PyObject *py_ped_disk_get_partition(PyObject *, PyObject *); 144 | PyObject *py_ped_disk_get_partition_by_sector(PyObject *, PyObject *); 145 | PyObject *py_ped_disk_extended_partition(PyObject *, PyObject *); 146 | PyObject *py_ped_disk_new_fresh(PyObject *, PyObject *); 147 | PyObject *py_ped_disk_new(PyObject *, PyObject *); 148 | 149 | #endif /* PYDISK_H_INCLUDED */ 150 | -------------------------------------------------------------------------------- /include/pyfilesys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pyfilesys.h 3 | * pyparted type definitions for pyfilesys.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef PYFILESYS_H_INCLUDED 10 | #define PYFILESYS_H_INCLUDED 11 | 12 | #include 13 | 14 | #include 15 | 16 | /* These functions need to be added to libparted. Remove when that's done. */ 17 | #define ped_file_system_destroy(fs) 18 | 19 | /* 1:1 function mappings for filesys.h in libparted */ 20 | PyObject *py_ped_file_system_type_get(PyObject *, PyObject *); 21 | PyObject *py_ped_file_system_type_get_next(PyObject *, PyObject *); 22 | PyObject *py_ped_file_system_probe_specific(PyObject *, PyObject *); 23 | PyObject *py_ped_file_system_probe(PyObject *, PyObject *); 24 | 25 | /* _ped.FileSystemType type is the Python equivalent of PedFileSystemType 26 | * in libparted */ 27 | typedef struct { 28 | PyObject_HEAD 29 | 30 | /* PedFileSystemType members */ 31 | char *name; 32 | } _ped_FileSystemType; 33 | 34 | void _ped_FileSystemType_dealloc(_ped_FileSystemType *); 35 | int _ped_FileSystemType_compare(_ped_FileSystemType *, PyObject *); 36 | PyObject *_ped_FileSystemType_richcompare(_ped_FileSystemType *, PyObject *, 37 | int); 38 | PyObject *_ped_FileSystemType_str(_ped_FileSystemType *); 39 | int _ped_FileSystemType_traverse(_ped_FileSystemType *, visitproc, void *); 40 | int _ped_FileSystemType_clear(_ped_FileSystemType *); 41 | PyObject *_ped_FileSystemType_get(_ped_FileSystemType *, void *); 42 | 43 | extern PyTypeObject _ped_FileSystemType_Type_obj; 44 | 45 | /* _ped.FileSystem type is the Python equiv of PedFileSystem in libparted */ 46 | typedef struct { 47 | PyObject_HEAD 48 | 49 | /* PedFileSystem members */ 50 | PyObject *type; /* _ped.FileSystemType */ 51 | PyObject *geom; /* _ped.Geometry */ 52 | int checked; 53 | 54 | /* store the PedFileSystem from libparted */ 55 | PedFileSystem *ped_filesystem; 56 | } _ped_FileSystem; 57 | 58 | void _ped_FileSystem_dealloc(_ped_FileSystem *); 59 | int _ped_FileSystem_compare(_ped_FileSystem *, PyObject *); 60 | PyObject *_ped_FileSystem_richcompare(_ped_FileSystem *, PyObject *, int); 61 | PyObject *_ped_FileSystem_str(_ped_FileSystem *); 62 | int _ped_FileSystem_traverse(_ped_FileSystem *, visitproc, void *); 63 | int _ped_FileSystem_clear(_ped_FileSystem *); 64 | int _ped_FileSystem_init(_ped_FileSystem *, PyObject *, PyObject *); 65 | PyObject *_ped_FileSystem_get(_ped_FileSystem *, void *); 66 | 67 | extern PyTypeObject _ped_FileSystem_Type_obj; 68 | 69 | #endif /* PYFILESYS_H_INCLUDED */ 70 | -------------------------------------------------------------------------------- /include/pygeom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pygeom.h 3 | * pyparted type definitions for pygeom.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef PYGEOM_H_INCLUDED 10 | #define PYGEOM_H_INCLUDED 11 | 12 | #include 13 | 14 | #include 15 | 16 | /* 1:1 function mappings for geom.h in libparted */ 17 | PyObject *py_ped_geometry_duplicate(PyObject *, PyObject *); 18 | PyObject *py_ped_geometry_intersect(PyObject *, PyObject *); 19 | PyObject *py_ped_geometry_set(PyObject *, PyObject *); 20 | PyObject *py_ped_geometry_set_start(PyObject *, PyObject *); 21 | PyObject *py_ped_geometry_set_end(PyObject *, PyObject *); 22 | PyObject *py_ped_geometry_test_overlap(PyObject *, PyObject *); 23 | PyObject *py_ped_geometry_test_inside(PyObject *, PyObject *); 24 | PyObject *py_ped_geometry_test_equal(PyObject *, PyObject *); 25 | PyObject *py_ped_geometry_test_sector_inside(PyObject *, PyObject *); 26 | PyObject *py_ped_geometry_read(PyObject *, PyObject *); 27 | PyObject *py_ped_geometry_sync(PyObject *, PyObject *); 28 | PyObject *py_ped_geometry_sync_fast(PyObject *, PyObject *); 29 | PyObject *py_ped_geometry_write(PyObject *, PyObject *); 30 | PyObject *py_ped_geometry_check(PyObject *, PyObject *); 31 | PyObject *py_ped_geometry_map(PyObject *, PyObject *); 32 | 33 | /* _ped.Geometry type is the Python equivalent of PedGeometry in libparted */ 34 | typedef struct { 35 | PyObject_HEAD 36 | 37 | /* PedGeometry members */ 38 | PyObject *dev; /* _ped.Device */ 39 | 40 | /* store the PedGeometry from libparted */ 41 | PedGeometry *ped_geometry; 42 | } _ped_Geometry; 43 | 44 | void _ped_Geometry_dealloc(_ped_Geometry *); 45 | int _ped_Geometry_compare(_ped_Geometry *, PyObject *); 46 | PyObject *_ped_Geometry_richcompare(_ped_Geometry *, PyObject *, int); 47 | PyObject *_ped_Geometry_str(_ped_Geometry *); 48 | int _ped_Geometry_traverse(_ped_Geometry *, visitproc, void *); 49 | int _ped_Geometry_clear(_ped_Geometry *); 50 | int _ped_Geometry_init(_ped_Geometry *, PyObject *, PyObject *); 51 | PyObject *_ped_Geometry_get(_ped_Geometry *, void *); 52 | int _ped_Geometry_set(_ped_Geometry *, PyObject *, void *); 53 | 54 | extern PyTypeObject _ped_Geometry_Type_obj; 55 | 56 | #endif /* PYGEOM_H_INCLUDED */ 57 | -------------------------------------------------------------------------------- /include/pynatmath.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pynatmath.h 3 | * pyparted type definitions for pynatmath.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef PYNATMATH_H_INCLUDED 10 | #define PYNATMATH_H_INCLUDED 11 | 12 | #include 13 | 14 | #include 15 | 16 | /* 1:1 function mappings for natmath.h in libparted */ 17 | PyObject *py_ped_alignment_duplicate(PyObject *, PyObject *); 18 | PyObject *py_ped_alignment_intersect(PyObject *, PyObject *); 19 | PyObject *py_ped_alignment_align_up(PyObject *, PyObject *); 20 | PyObject *py_ped_alignment_align_down(PyObject *, PyObject *); 21 | PyObject *py_ped_alignment_align_nearest(PyObject *, PyObject *); 22 | PyObject *py_ped_alignment_is_aligned(PyObject *, PyObject *); 23 | 24 | /* _ped.Alignment type is the Python equivalent of PedAlignment in libparted */ 25 | typedef struct { 26 | PyObject_HEAD 27 | 28 | /* PedAlignment members */ 29 | long long offset; /* PedSector */ 30 | long long grain_size; /* PedSector */ 31 | } _ped_Alignment; 32 | 33 | void _ped_Alignment_dealloc(_ped_Alignment *); 34 | int _ped_Alignment_compare(_ped_Alignment *, PyObject *); 35 | PyObject *_ped_Alignment_richcompare(_ped_Alignment *, PyObject *, int); 36 | PyObject *_ped_Alignment_str(_ped_Alignment *); 37 | int _ped_Alignment_traverse(_ped_Alignment *, visitproc, void *); 38 | int _ped_Alignment_clear(_ped_Alignment *); 39 | int _ped_Alignment_init(_ped_Alignment *, PyObject *, PyObject *); 40 | PyObject *_ped_Alignment_get(_ped_Alignment *, void *); 41 | int _ped_Alignment_set(_ped_Alignment *, PyObject *, void *); 42 | 43 | extern PyTypeObject _ped_Alignment_Type_obj; 44 | 45 | #endif /* PYNATMATH_H_INCLUDED */ 46 | -------------------------------------------------------------------------------- /include/pytimer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pytimer.h 3 | * pyparted type definitions for pytimer.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef PYTIMER_H_INCLUDED 10 | #define PYTIMER_H_INCLUDED 11 | 12 | #include 13 | 14 | #include 15 | 16 | /* 1:1 function mappings for timer.h in libparted */ 17 | PyObject *py_ped_timer_destroy(PyObject *, PyObject *); 18 | PyObject *py_ped_timer_new_nested(PyObject *, PyObject *); 19 | PyObject *py_ped_timer_destroy_nested(PyObject *, PyObject *); 20 | PyObject *py_ped_timer_touch(PyObject *, PyObject *); 21 | PyObject *py_ped_timer_reset(PyObject *, PyObject *); 22 | PyObject *py_ped_timer_update(PyObject *, PyObject *); 23 | PyObject *py_ped_timer_set_state_name(PyObject *, PyObject *); 24 | 25 | /* _ped.Timer type is the Python equivalent of PedTimer in libparted */ 26 | typedef struct { 27 | PyObject_HEAD 28 | 29 | /* PedTimer members */ 30 | float frac; 31 | time_t start; 32 | time_t now; 33 | time_t predicted_end; 34 | char *state_name; 35 | PedTimerHandler *handler; 36 | void *context; 37 | } _ped_Timer; 38 | 39 | void _ped_Timer_dealloc(_ped_Timer *); 40 | int _ped_Timer_compare(_ped_Timer *, PyObject *); 41 | PyObject *_ped_Timer_richcompare(_ped_Timer *, PyObject *, int); 42 | PyObject *_ped_Timer_str(_ped_Timer *); 43 | int _ped_Timer_traverse(_ped_Timer *, visitproc, void *); 44 | int _ped_Timer_clear(_ped_Timer *); 45 | int _ped_Timer_init(_ped_Timer *, PyObject *, PyObject *); 46 | PyObject *_ped_Timer_get(_ped_Timer *, void *); 47 | int _ped_Timer_set(_ped_Timer *, PyObject *, void *); 48 | 49 | extern PyTypeObject _ped_Timer_Type_obj; 50 | 51 | #endif /* PYTIMER_H_INCLUDED */ 52 | -------------------------------------------------------------------------------- /include/pyunit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pyunit.h 3 | * pyparted type definitions for pyunit.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef PYUNIT_H_INCLUDED 10 | #define PYUNIT_H_INCLUDED 11 | 12 | #include 13 | 14 | #include 15 | 16 | /* a PedUnit is a long int in C, so we store it that way in Python */ 17 | 18 | /* 1:1 function mappings for unit.h in libparted */ 19 | PyObject *py_ped_unit_set_default(PyObject *, PyObject *); 20 | PyObject *py_ped_unit_get_default(PyObject *, PyObject *); 21 | PyObject *py_ped_unit_get_name(PyObject *, PyObject *); 22 | PyObject *py_ped_unit_get_by_name(PyObject *, PyObject *); 23 | 24 | #endif /* PYUNIT_H_INCLUDED */ 25 | -------------------------------------------------------------------------------- /include/typeobjects/pyconstraint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pyconstraint.h 3 | * pyparted type objects for pyconstraint.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef TYPEOBJECTS_PYCONSTRAINT_H_INCLUDED 10 | #define TYPEOBJECTS_PYCONSTRAINT_H_INCLUDED 11 | 12 | #include 13 | #include 14 | 15 | /* _ped.Constraint type object */ 16 | static PyMemberDef _ped_Constraint_members[] = { 17 | {"start_align", T_OBJECT, offsetof(_ped_Constraint, start_align), 0, 18 | "The _ped.Alignment describing the starting alignment constraints of the partition."}, 19 | {"end_align", T_OBJECT, offsetof(_ped_Constraint, end_align), 0, 20 | "The _ped.Alignment describing the ending alignment constraints of the partition."}, 21 | {"start_range", T_OBJECT, offsetof(_ped_Constraint, start_range), 0, 22 | "The _ped.Geometry describing the minimum size constraints of the partition."}, 23 | {"end_range", T_OBJECT, offsetof(_ped_Constraint, end_range), 0, 24 | "The _ped.Geometry describing the maximum size constraints of the partition."}, 25 | {NULL} 26 | }; 27 | 28 | static PyMethodDef _ped_Constraint_methods[] = { 29 | {"duplicate", (PyCFunction) py_ped_constraint_duplicate, 30 | METH_VARARGS, constraint_duplicate_doc}, 31 | {"intersect", (PyCFunction) py_ped_constraint_intersect, 32 | METH_VARARGS, constraint_intersect_doc}, 33 | {"solve_max", (PyCFunction) py_ped_constraint_solve_max, 34 | METH_VARARGS, constraint_solve_max_doc}, 35 | {"solve_nearest", (PyCFunction) py_ped_constraint_solve_nearest, 36 | METH_VARARGS, constraint_solve_nearest_doc}, 37 | {"is_solution", (PyCFunction) py_ped_constraint_is_solution, 38 | METH_VARARGS, constraint_is_solution_doc}, 39 | {NULL} 40 | }; 41 | 42 | static PyGetSetDef _ped_Constraint_getset[] = { 43 | {"min_size", (getter) _ped_Constraint_get, 44 | (setter) _ped_Constraint_set, 45 | "The minimum size in _ped.Sectors of the partition.", "min_size"}, 46 | {"max_size", (getter) _ped_Constraint_get, 47 | (setter) _ped_Constraint_set, 48 | "The maximum size in _ped.Sectors of the partition.", "max_size"}, 49 | {NULL} /* Sentinel */ 50 | }; 51 | 52 | PyTypeObject _ped_Constraint_Type_obj = { 53 | PyVarObject_HEAD_INIT(&PyType_Type,0) 54 | .tp_name = "_ped.Constraint", 55 | .tp_basicsize = sizeof(_ped_Constraint), 56 | /* .tp_itemsize = XXX */ 57 | .tp_dealloc = (destructor) _ped_Constraint_dealloc, 58 | /* .tp_getattr = XXX */ 59 | /* .tp_setattr = XXX */ 60 | /* .tp_repr = XXX */ 61 | /* .tp_as_number = XXX */ 62 | /* .tp_as_sequence = XXX */ 63 | /* .tp_as_mapping = XXX */ 64 | .tp_hash = PyObject_HashNotImplemented, 65 | .tp_call = NULL, 66 | .tp_str = (reprfunc) _ped_Constraint_str, 67 | .tp_getattro = PyObject_GenericGetAttr, 68 | .tp_setattro = PyObject_GenericSetAttr, 69 | /* .tp_as_buffer = XXX */ 70 | .tp_flags = TP_FLAGS, 71 | .tp_doc = _ped_Constraint_doc, 72 | .tp_traverse = (traverseproc) _ped_Constraint_traverse, 73 | .tp_clear = (inquiry) _ped_Constraint_clear, 74 | .tp_richcompare = (richcmpfunc) _ped_Constraint_richcompare, 75 | /* .tp_weaklistoffset = XXX */ 76 | /* .tp_iter = XXX */ 77 | /* .tp_iternext = XXX */ 78 | .tp_methods = _ped_Constraint_methods, 79 | .tp_members = _ped_Constraint_members, 80 | .tp_getset = _ped_Constraint_getset, 81 | .tp_base = NULL, 82 | .tp_dict = NULL, 83 | /* .tp_descr_get = XXX */ 84 | /* .tp_descr_set = XXX */ 85 | /* .tp_dictoffset = XXX */ 86 | .tp_init = (initproc) _ped_Constraint_init, 87 | .tp_alloc = PyType_GenericAlloc, 88 | .tp_new = PyType_GenericNew, 89 | /* .tp_free = XXX */ 90 | /* .tp_is_gc = XXX */ 91 | .tp_bases = NULL, 92 | /* .tp_del = XXX */ 93 | }; 94 | 95 | #endif /* TYPEOBJECTS_PYCONSTRAINT_H_INCLUDED */ 96 | -------------------------------------------------------------------------------- /include/typeobjects/pyfilesys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pyfilesys.h 3 | * pyparted type objects for pyfilesys.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef TYPEOBJECTS_PYFILESYS_H_INCLUDED 10 | #define TYPEOBJECTS_PYFILESYS_H_INCLUDED 11 | 12 | #include 13 | #include 14 | 15 | /* _ped.FileSystemType type object */ 16 | static PyMemberDef _ped_FileSystemType_members[] = { 17 | {NULL} 18 | }; 19 | 20 | static PyMethodDef _ped_FileSystemType_methods[] = { 21 | {NULL} 22 | }; 23 | 24 | static PyGetSetDef _ped_FileSystemType_getset[] = { 25 | {"name", (getter) _ped_FileSystemType_get, NULL, 26 | "The name of the FileSystemType.", "name"}, 27 | {NULL} /* Sentinel */ 28 | }; 29 | 30 | PyTypeObject _ped_FileSystemType_Type_obj = { 31 | PyVarObject_HEAD_INIT(&PyType_Type,0) 32 | .tp_name = "_ped.FileSystemType", 33 | .tp_basicsize = sizeof(_ped_FileSystemType), 34 | /* .tp_itemsize = XXX */ 35 | .tp_dealloc = (destructor) _ped_FileSystemType_dealloc, 36 | /* .tp_getattr = XXX */ 37 | /* .tp_setattr = XXX */ 38 | /* .tp_repr = XXX */ 39 | /* .tp_as_number = XXX */ 40 | /* .tp_as_sequence = XXX */ 41 | /* .tp_as_mapping = XXX */ 42 | .tp_hash = PyObject_HashNotImplemented, 43 | .tp_call = NULL, 44 | .tp_str = (reprfunc) _ped_FileSystemType_str, 45 | .tp_getattro = PyObject_GenericGetAttr, 46 | .tp_setattro = PyObject_GenericSetAttr, 47 | /* .tp_as_buffer = XXX */ 48 | .tp_flags = TP_FLAGS, 49 | .tp_doc = _ped_FileSystemType_doc, 50 | .tp_traverse = (traverseproc) _ped_FileSystemType_traverse, 51 | .tp_clear = (inquiry) _ped_FileSystemType_clear, 52 | .tp_richcompare = (richcmpfunc) _ped_FileSystemType_richcompare, 53 | /* .tp_weaklistoffset = XXX */ 54 | /* .tp_iter = XXX */ 55 | /* .tp_iternext = XXX */ 56 | .tp_methods = _ped_FileSystemType_methods, 57 | .tp_members = _ped_FileSystemType_members, 58 | .tp_getset = _ped_FileSystemType_getset, 59 | .tp_base = NULL, 60 | .tp_dict = NULL, 61 | /* .tp_descr_get = XXX */ 62 | /* .tp_descr_set = XXX */ 63 | /* .tp_dictoffset = XXX */ 64 | .tp_init = NULL, 65 | .tp_alloc = PyType_GenericAlloc, 66 | .tp_new = NULL, 67 | /* .tp_free = XXX */ 68 | /* .tp_is_gc = XXX */ 69 | .tp_bases = NULL, 70 | /* .tp_del = XXX */ 71 | }; 72 | 73 | /* _ped.FileSystem type object */ 74 | static PyMemberDef _ped_FileSystem_members[] = { 75 | {"type", T_OBJECT, offsetof(_ped_FileSystem, type), READONLY, 76 | "A _ped.FileSystemType object describing the filesystem on self.geom."}, 77 | {"geom", T_OBJECT, offsetof(_ped_FileSystem, geom), READONLY, 78 | "The on-disk region where this FileSystem object exists."}, 79 | {NULL} 80 | }; 81 | 82 | PyTypeObject _ped_FileSystem_Type_obj = { 83 | PyVarObject_HEAD_INIT(&PyType_Type,0) 84 | .tp_name = "_ped.FileSystem", 85 | .tp_basicsize = sizeof(_ped_FileSystem), 86 | /* .tp_itemsize = XXX */ 87 | .tp_dealloc = (destructor) _ped_FileSystem_dealloc, 88 | /* .tp_getattr = XXX */ 89 | /* .tp_setattr = XXX */ 90 | /* .tp_repr = XXX */ 91 | /* .tp_as_number = XXX */ 92 | /* .tp_as_sequence = XXX */ 93 | /* .tp_as_mapping = XXX */ 94 | .tp_hash = PyObject_HashNotImplemented, 95 | .tp_call = NULL, 96 | .tp_str = (reprfunc) _ped_FileSystem_str, 97 | .tp_getattro = PyObject_GenericGetAttr, 98 | .tp_setattro = PyObject_GenericSetAttr, 99 | /* .tp_as_buffer = XXX */ 100 | .tp_flags = TP_FLAGS, 101 | .tp_doc = _ped_FileSystem_doc, 102 | .tp_traverse = (traverseproc) _ped_FileSystem_traverse, 103 | .tp_clear = (inquiry) _ped_FileSystem_clear, 104 | .tp_richcompare = (richcmpfunc) _ped_FileSystem_richcompare, 105 | /* .tp_weaklistoffset = XXX */ 106 | /* .tp_iter = XXX */ 107 | /* .tp_iternext = XXX */ 108 | /* .tp_methods = XXX */ 109 | .tp_members = _ped_FileSystem_members, 110 | /* .tp_getset = XXX */ 111 | .tp_base = NULL, 112 | .tp_dict = NULL, 113 | /* .tp_descr_get = XXX */ 114 | /* .tp_descr_set = XXX */ 115 | /* .tp_dictoffset = XXX */ 116 | .tp_init = (initproc) _ped_FileSystem_init, 117 | .tp_alloc = PyType_GenericAlloc, 118 | .tp_new = PyType_GenericNew, 119 | /* .tp_free = XXX */ 120 | /* .tp_is_gc = XXX */ 121 | .tp_bases = NULL, 122 | /* .tp_del = XXX */ 123 | }; 124 | 125 | #endif /* TYPEOBJECTS_PYFILESYS_H_INCLUDED */ 126 | -------------------------------------------------------------------------------- /include/typeobjects/pygeom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pygeom.h 3 | * pyparted type objects for pygeom.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef TYPEOBJECTS_PYGEOM_H_INCLUDED 10 | #define TYPEOBJECTS_PYGEOM_H_INCLUDED 11 | 12 | #include 13 | #include 14 | 15 | /* _ped.Geometry type object */ 16 | static PyMemberDef _ped_Geometry_members[] = { 17 | {"dev", T_OBJECT, offsetof(_ped_Geometry, dev), READONLY, 18 | "The _ped.Device described by this _ped.Geometry object."}, 19 | {NULL} 20 | }; 21 | 22 | static PyMethodDef _ped_Geometry_methods[] = { 23 | {"duplicate", (PyCFunction) py_ped_geometry_duplicate, METH_VARARGS, 24 | geometry_duplicate_doc}, 25 | {"intersect", (PyCFunction) py_ped_geometry_intersect, METH_VARARGS, 26 | geometry_intersect_doc}, 27 | {"set", (PyCFunction) py_ped_geometry_set, METH_VARARGS, 28 | geometry_set_doc}, 29 | {"set_start", (PyCFunction) py_ped_geometry_set_start, METH_VARARGS, 30 | geometry_set_start_doc}, 31 | {"set_end", (PyCFunction) py_ped_geometry_set_end, METH_VARARGS, 32 | geometry_set_end_doc}, 33 | {"test_overlap", (PyCFunction) py_ped_geometry_test_overlap, 34 | METH_VARARGS, geometry_test_overlap_doc}, 35 | {"test_inside", (PyCFunction) py_ped_geometry_test_inside, 36 | METH_VARARGS, geometry_test_inside_doc}, 37 | {"test_equal", (PyCFunction) py_ped_geometry_test_equal, 38 | METH_VARARGS, geometry_test_equal_doc}, 39 | {"test_sector_inside", (PyCFunction) py_ped_geometry_test_sector_inside, 40 | METH_VARARGS, geometry_test_sector_inside_doc}, 41 | {"read", (PyCFunction) py_ped_geometry_read, METH_VARARGS, 42 | geometry_read_doc}, 43 | {"sync", (PyCFunction) py_ped_geometry_sync, METH_VARARGS, 44 | geometry_sync_doc}, 45 | {"sync_fast", (PyCFunction) py_ped_geometry_sync_fast, METH_VARARGS, 46 | geometry_sync_fast_doc}, 47 | {"write", (PyCFunction) py_ped_geometry_write, METH_VARARGS, 48 | geometry_write_doc}, 49 | {"check", (PyCFunction) py_ped_geometry_check, METH_VARARGS, 50 | geometry_check_doc}, 51 | {"map", (PyCFunction) py_ped_geometry_map, METH_VARARGS, 52 | geometry_map_doc}, 53 | {NULL} 54 | }; 55 | 56 | static PyGetSetDef _ped_Geometry_getset[] = { 57 | {"start", (getter) _ped_Geometry_get, 58 | (setter) _ped_Geometry_set, 59 | "The starting Sector of the region.", "start"}, 60 | {"length", (getter) _ped_Geometry_get, 61 | (setter) _ped_Geometry_set, 62 | "The length of the region described by this Geometry object.", 63 | "length"}, 64 | {"end", (getter) _ped_Geometry_get, 65 | (setter) _ped_Geometry_set, 66 | "The ending Sector of the region.", "end"}, 67 | {NULL} /* Sentinel */ 68 | }; 69 | 70 | PyTypeObject _ped_Geometry_Type_obj = { 71 | PyVarObject_HEAD_INIT(&PyType_Type,0) 72 | .tp_name = "_ped.Geometry", 73 | .tp_basicsize = sizeof(_ped_Geometry), 74 | /* .tp_itemsize = XXX */ 75 | .tp_dealloc = (destructor) _ped_Geometry_dealloc, 76 | /* .tp_getattr = XXX */ 77 | /* .tp_setattr = XXX */ 78 | /* .tp_repr = XXX */ 79 | /* .tp_as_number = XXX */ 80 | /* .tp_as_sequence = XXX */ 81 | /* .tp_as_mapping = XXX */ 82 | .tp_hash = PyObject_HashNotImplemented, 83 | .tp_call = NULL, 84 | .tp_str = (reprfunc) _ped_Geometry_str, 85 | .tp_getattro = PyObject_GenericGetAttr, 86 | .tp_setattro = PyObject_GenericSetAttr, 87 | /* .tp_as_buffer = XXX */ 88 | .tp_flags = TP_FLAGS, 89 | .tp_doc = _ped_Geometry_doc, 90 | .tp_traverse = (traverseproc) _ped_Geometry_traverse, 91 | .tp_clear = (inquiry) _ped_Geometry_clear, 92 | .tp_richcompare = (richcmpfunc) _ped_Geometry_richcompare, 93 | /* .tp_weaklistoffset = XXX */ 94 | /* .tp_iter = XXX */ 95 | /* .tp_iternext = XXX */ 96 | .tp_methods = _ped_Geometry_methods, 97 | .tp_members = _ped_Geometry_members, 98 | .tp_getset = _ped_Geometry_getset, 99 | .tp_base = NULL, 100 | .tp_dict = NULL, 101 | /* .tp_descr_get = XXX */ 102 | /* .tp_descr_set = XXX */ 103 | /* .tp_dictoffset = XXX */ 104 | .tp_init = (initproc) _ped_Geometry_init, 105 | .tp_alloc = PyType_GenericAlloc, 106 | .tp_new = PyType_GenericNew, 107 | /* .tp_free = XXX */ 108 | /* .tp_is_gc = XXX */ 109 | .tp_bases = NULL, 110 | /* .tp_del = XXX */ 111 | }; 112 | 113 | #endif /* TYPEOBJECTS_PYGEOM_H_INCLUDED */ 114 | -------------------------------------------------------------------------------- /include/typeobjects/pynatmath.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pynatmath.h 3 | * pyparted type objects for pynatmath.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef TYPEOBJECTS_PYNATMATH_H_INCLUDED 10 | #define TYPEOBJECTS_PYNATMATH_H_INCLUDED 11 | 12 | #include 13 | #include 14 | 15 | /* _ped.Alignment type object */ 16 | static PyMemberDef _ped_Alignment_members[] = { 17 | {NULL} 18 | }; 19 | 20 | static PyMethodDef _ped_Alignment_methods[] = { 21 | {"duplicate", (PyCFunction) py_ped_alignment_duplicate, METH_VARARGS, 22 | alignment_duplicate_doc}, 23 | {"intersect", (PyCFunction) py_ped_alignment_intersect, METH_VARARGS, 24 | alignment_intersect_doc}, 25 | {"align_up", (PyCFunction) py_ped_alignment_align_up, METH_VARARGS, 26 | alignment_align_up_doc}, 27 | {"align_down", (PyCFunction) py_ped_alignment_align_down, 28 | METH_VARARGS, alignment_align_down_doc}, 29 | {"align_nearest", (PyCFunction) py_ped_alignment_align_nearest, 30 | METH_VARARGS, alignment_align_nearest_doc}, 31 | {"is_aligned", (PyCFunction) py_ped_alignment_is_aligned, 32 | METH_VARARGS, alignment_is_aligned_doc}, 33 | {NULL} 34 | }; 35 | 36 | static PyGetSetDef _ped_Alignment_getset[] = { 37 | {"offset", (getter) _ped_Alignment_get, 38 | (setter) _ped_Alignment_set, 39 | "Offset in sectors from the start of a _ped.Geometry.", "offset"}, 40 | {"grain_size", (getter) _ped_Alignment_get, 41 | (setter) _ped_Alignment_set, 42 | "Alignment grain_size", "grain_size"}, 43 | {NULL} /* Sentinel */ 44 | }; 45 | 46 | PyTypeObject _ped_Alignment_Type_obj = { 47 | PyVarObject_HEAD_INIT(&PyType_Type,0) 48 | .tp_name = "_ped.Alignment", 49 | .tp_basicsize = sizeof(_ped_Alignment), 50 | /* .tp_itemsize = XXX */ 51 | .tp_dealloc = (destructor) _ped_Alignment_dealloc, 52 | /* .tp_getattr = XXX */ 53 | /* .tp_setattr = XXX */ 54 | /* .tp_repr = XXX */ 55 | /* .tp_as_number = XXX */ 56 | /* .tp_as_sequence = XXX */ 57 | /* .tp_as_mapping = XXX */ 58 | .tp_hash = PyObject_HashNotImplemented, 59 | .tp_call = NULL, 60 | .tp_str = (reprfunc) _ped_Alignment_str, 61 | .tp_getattro = PyObject_GenericGetAttr, 62 | .tp_setattro = PyObject_GenericSetAttr, 63 | /* .tp_as_buffer = XXX */ 64 | .tp_flags = TP_FLAGS, 65 | .tp_doc = _ped_Alignment_doc, 66 | .tp_traverse = (traverseproc) _ped_Alignment_traverse, 67 | .tp_clear = (inquiry) _ped_Alignment_clear, 68 | .tp_richcompare = (richcmpfunc) _ped_Alignment_richcompare, 69 | /* .tp_weaklistoffset = XXX */ 70 | /* .tp_iter = XXX */ 71 | /* .tp_iternext = XXX */ 72 | .tp_methods = _ped_Alignment_methods, 73 | .tp_members = _ped_Alignment_members, 74 | .tp_getset = _ped_Alignment_getset, 75 | .tp_base = NULL, 76 | .tp_dict = NULL, 77 | /* .tp_descr_get = XXX */ 78 | /* .tp_descr_set = XXX */ 79 | /* .tp_dictoffset = XXX */ 80 | .tp_init = (initproc) _ped_Alignment_init, 81 | .tp_alloc = PyType_GenericAlloc, 82 | .tp_new = PyType_GenericNew, 83 | /* .tp_free = XXX */ 84 | /* .tp_is_gc = XXX */ 85 | .tp_bases = NULL, 86 | /* .tp_del = XXX */ 87 | }; 88 | 89 | #endif /* TYPEOBJECTS_PYNATMATH_H_INCLUDED */ 90 | -------------------------------------------------------------------------------- /include/typeobjects/pytimer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pytimer.h 3 | * pyparted type objects for pytimer.c 4 | * 5 | * Copyright The pyparted Project Authors 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | */ 8 | 9 | #ifndef TYPEOBJECTS_PYTIMER_H_INCLUDED 10 | #define TYPEOBJECTS_PYTIMER_H_INCLUDED 11 | 12 | #include 13 | #include 14 | 15 | /* _ped.Timer type object */ 16 | static PyMemberDef _ped_Timer_members[] = { 17 | {NULL} 18 | }; 19 | 20 | static PyMethodDef _ped_Timer_methods[] = { 21 | {"destroy", (PyCFunction) py_ped_timer_destroy, METH_VARARGS, NULL}, 22 | {"new_nested", (PyCFunction) py_ped_timer_new_nested, METH_VARARGS, NULL}, 23 | {"destroy_nested", (PyCFunction) py_ped_timer_destroy_nested, 24 | METH_VARARGS, NULL}, 25 | {"touch", (PyCFunction) py_ped_timer_touch, METH_VARARGS, NULL}, 26 | {"reset", (PyCFunction) py_ped_timer_reset, METH_VARARGS, NULL}, 27 | {"update", (PyCFunction) py_ped_timer_update, METH_VARARGS, NULL}, 28 | {"set_state_name", (PyCFunction) py_ped_timer_set_state_name, 29 | METH_VARARGS, NULL}, 30 | {NULL} 31 | }; 32 | 33 | static PyGetSetDef _ped_Timer_getset[] = { 34 | {"frac", (getter) _ped_Timer_get, (setter) _ped_Timer_set, 35 | "PedTimer frac", "frac"}, 36 | {"start", (getter) _ped_Timer_get, (setter) _ped_Timer_set, 37 | "PedTimer.start", "start"}, 38 | {"now", (getter) _ped_Timer_get, (setter) _ped_Timer_set, 39 | "PedTimer.now", "now"}, 40 | {"predicted_end", (getter) _ped_Timer_get, (setter) _ped_Timer_set, 41 | "PedTimer.predicted_end", "predicted_end"}, 42 | {"state_name", (getter) _ped_Timer_get, (setter) _ped_Timer_set, 43 | "PedTimer.state_name", "state_name"}, 44 | {NULL} /* Sentinel */ 45 | }; 46 | 47 | PyTypeObject _ped_Timer_Type_obj = { 48 | PyVarObject_HEAD_INIT(&PyType_Type,0) 49 | .tp_name = "_ped.Timer", 50 | .tp_basicsize = sizeof(_ped_Timer), 51 | /* .tp_itemsize = XXX */ 52 | .tp_dealloc = (destructor) _ped_Timer_dealloc, 53 | /* .tp_getattr = XXX */ 54 | /* .tp_setattr = XXX */ 55 | /* .tp_repr = XXX */ 56 | /* .tp_as_number = XXX */ 57 | /* .tp_as_sequence = XXX */ 58 | /* .tp_as_mapping = XXX */ 59 | .tp_hash = PyObject_HashNotImplemented, 60 | .tp_call = NULL, 61 | .tp_str = (reprfunc) _ped_Timer_str, 62 | .tp_getattro = PyObject_GenericGetAttr, 63 | .tp_setattro = PyObject_GenericSetAttr, 64 | /* .tp_as_buffer = XXX */ 65 | .tp_flags = TP_FLAGS, 66 | .tp_doc = "PedTimer objects", 67 | .tp_traverse = (traverseproc) _ped_Timer_traverse, 68 | .tp_clear = (inquiry) _ped_Timer_clear, 69 | .tp_richcompare = (richcmpfunc) _ped_Timer_richcompare, 70 | /* .tp_weaklistoffset = XXX */ 71 | /* .tp_iter = XXX */ 72 | /* .tp_iternext = XXX */ 73 | .tp_methods = _ped_Timer_methods, 74 | .tp_members = _ped_Timer_members, 75 | .tp_getset = _ped_Timer_getset, 76 | .tp_base = NULL, 77 | .tp_dict = NULL, 78 | /* .tp_descr_get = XXX */ 79 | /* .tp_descr_set = XXX */ 80 | /* .tp_dictoffset = XXX */ 81 | .tp_init = (initproc) _ped_Timer_init, 82 | .tp_alloc = PyType_GenericAlloc, 83 | .tp_new = PyType_GenericNew, 84 | /* .tp_free = XXX */ 85 | /* .tp_is_gc = XXX */ 86 | .tp_bases = NULL, 87 | /* .tp_del = XXX */ 88 | }; 89 | 90 | #endif /* TYPEOBJECTS_PYTIMER_H_INCLUDED */ 91 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # setup.py script for pyparted 2 | # Copyright (C) 2011-2017 Red Hat, Inc. 3 | # 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 2 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 | # 18 | # Author(s): David Cantrell 19 | # Alex Skinner 20 | # 21 | # pylint: skip-file 22 | 23 | import subprocess 24 | import glob 25 | import os 26 | import platform 27 | import sys 28 | from setuptools import setup, Extension 29 | 30 | pyparted_version = '3.13.0' 31 | python_version = sys.version_info 32 | 33 | need_libparted_version = '3.4' 34 | need_python_version = (3, 5) 35 | 36 | if python_version < need_python_version: 37 | raise RuntimeError("pyparted requires Python version %d.%d or higher" 38 | % need_python_version) 39 | # Recipe from: 40 | # http://code.activestate.com/recipes/502261-python-distutils-pkg-config/ 41 | def pkgconfig(*packages, **kwargs): 42 | flag_map = {'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries'} 43 | try: 44 | for token in subprocess.check_output(["pkg-config", "--libs", "--cflags"] + list(packages), 45 | universal_newlines=True).split(): 46 | kwargs.setdefault(flag_map.get(token[:2]), []).append(token[2:]) 47 | return kwargs 48 | except subprocess.CalledProcessError as e: 49 | sys.exit("Cannot find pkg-config dependencies:\n" + e.output) 50 | 51 | # This list is in the format necessary for the define_macros parameter 52 | # for an Extension() module definition. See: 53 | # http://docs.python.org/distutils/setupscript.html#preprocessor-options 54 | features = [('PYPARTED_VERSION', "\"%s\"" % pyparted_version), 55 | ('PY_SSIZE_T_CLEAN', None)] 56 | 57 | setup(name='pyparted', 58 | version=pyparted_version, 59 | author='David Cantrell', 60 | author_email='dcantrell@redhat.com', 61 | url='https://github.com/dcantrell/pyparted/', 62 | description='Python bindings for GNU parted', 63 | license='GPLv2+', 64 | packages=['parted'], 65 | package_dir={'parted': 'src/parted'}, 66 | ext_modules=[Extension('_ped', 67 | sorted(glob.glob(os.path.join('src', '*.c'))), 68 | define_macros=features, 69 | **pkgconfig('libparted >= %s' % need_libparted_version, 70 | include_dirs=['include'])) 71 | ]) 72 | -------------------------------------------------------------------------------- /src/fdisk/fdisk.py: -------------------------------------------------------------------------------- 1 | # 2 | # fdisk.py 3 | # Partitioning utility with an fdisk-style interface, but written in 4 | # Python and using the pyparted Python module. 5 | # 6 | # Copyright The pyparted Project Authors 7 | # SPDX-License-Identifier: GPL-2.0-or-later 8 | # 9 | 10 | import getopt 11 | import os 12 | import parted 13 | import sys 14 | 15 | def usage(cmd): 16 | sys.stdout.write("Usage: %s [-b SSZ] [-u] DISK Change partition table\n" % (cmd,)) 17 | sys.stdout.write(" %s [-l] [-b SSZ] [-u] DISK List partition table(s)\n" % (cmd,)) 18 | sys.stdout.write(" %s -s PARTITION Give partition size(s) in blocks\n\n" % (cmd,)) 19 | sys.stdout.write("Here DISK is something like /dev/hdb or /dev/sda\n") 20 | sys.stdout.write("and PARTITION is something like /dev/hda7\n\n") 21 | sys.stdout.write("Options:\n") 22 | sys.stdout.write(" -b=SSZ, --sectorsize=SSZ Sector size (in bytes) to use\n") 23 | sys.stdout.write(" -l, --list List partition table(s)\n") 24 | sys.stdout.write(" -u, --showsectors Give Start and End in sector units\n") 25 | sys.stdout.write(" -s, --showblocks Give Start and End in block units\n") 26 | sys.stdout.write(" -V, --version Show fdisk version\n") 27 | sys.stdout.write(" -?, --help Display fdisk usage screen\n") 28 | 29 | def displayVersion(cmd): 30 | ver = parted.version() 31 | 32 | sys.stdout.write("%s:\n" % (cmd,)) 33 | sys.stdout.write("pyparted version: %s.%s.%s\n" % (ver["pyparted"][0], ver["pyparted"][1], ver["pyparted"][2])) 34 | sys.stdout.write("libparted version: %s\n" % ver["libparted"]) 35 | 36 | def listPartitionTable(path, sectorsize, showsectors, showblocks): 37 | device = parted.getDevice(path) 38 | (cylinders, heads, sectors) = device.biosGeometry 39 | sizeInBytes = device.length * device.sectorSize 40 | disk = parted.Disk(device) 41 | 42 | partlist = [] 43 | for partition in disk.partitions: 44 | if partition.type == parted.PARTITION_PROTECTED or \ 45 | partition.type == parted.PARTITION_METADATA or \ 46 | partition.type == parted.PARTITION_FREESPACE: 47 | continue 48 | 49 | partlist.append((partition, 50 | partition.path, 51 | partition.getFlag(parted.PARTITION_BOOT), 52 | partition.geometry.start, 53 | partition.geometry.end, 54 | partition.geometry.length, 55 | partition.type, 56 | partition.fileSystem)) 57 | 58 | colLength = 0 59 | for parts in partlist: 60 | path = parts[1] 61 | if len(path) > colLength: 62 | colLength = len(path) 63 | 64 | sys.stdout.write("Disk %s: %%d %%s, %d bytes\n" % (disk.device.path, sizeInBytes)) 65 | sys.stdout.write("%d heads, %d sectors/track, %d cylinders\n" % (heads, sectors, cylinders,)) 66 | sys.stdout.write("Units = FIXME\n") 67 | sys.stdout.write("Disk identifier: FIXME\n\n") 68 | 69 | sys.stdout.write("%-11s %-4s %-11s %-11s %-12s %-4s %s\n" % ("Device", "Boot", "Start", "End", "Blocks", "Id", "System",)) 70 | 71 | for parts in partlist: 72 | (partition, path, bootable, start, end, length, ty, fs) = parts 73 | 74 | if bootable: 75 | bootflag = '*' 76 | else: 77 | bootflag = '' 78 | 79 | sys.stdout.write("%-11s %-4s %-11d %-11d %-12d %-4s" % (path, bootflag, start, end, length, ty,)) 80 | 81 | if fs is None: 82 | # no filesystem, check flags 83 | if partition.getFlag(parted.PARTITION_SWAP): 84 | sys.stdout.write(" Linux swap\n") 85 | elif partition.getFlag(parted.PARTITION_RAID): 86 | sys.stdout.write(" RAID\n") 87 | elif partition.getFlag(parted.PARTITION_LVM): 88 | sys.stdout.write(" Linux LVM\n") 89 | elif partition.getFlag(parted.PARTITION_HPSERVICE): 90 | sys.stdout.write(" HP Service\n") 91 | elif partition.getFlag(parted.PARTITION_PALO): 92 | sys.stdout.write(" PALO\n") 93 | elif partition.getFlag(parted.PARTITION_PREP): 94 | sys.stdout.write(" PReP\n") 95 | elif partition.getFlag(parted.MSFT_RESERVED): 96 | sys.stdout.write(" MSFT Reserved\n") 97 | else: 98 | sys.stdout.write(" unknown\n") 99 | else: 100 | sys.stdout.write(" %s\n" % (fs.type,)) 101 | 102 | #Disk /dev/sda: 250.0 GB, 250059350016 bytes 103 | #255 heads, 63 sectors/track, 30401 cylinders 104 | #Units = cylinders of 16065 * 512 = 8225280 bytes 105 | #Disk identifier: 0x00000000 106 | # 107 | # Device Boot Start End Blocks Id System 108 | #/dev/sda1 1 26 204819+ ee GPT 109 | #/dev/sda2 26 4203 33554432 af Unknown 110 | #/dev/sda3 * 4203 4229 204800 83 Linux 111 | #/dev/sda4 4229 30402 210234515+ 8e Linux LVM 112 | 113 | def main(argv): 114 | cmd = os.path.basename(sys.argv[0]) 115 | opts, args = [], [] 116 | showhelp, showlist, showsectors, showblocks = False, False, False, False 117 | 118 | # These three are unused for now so I'm marking them with an underscore 119 | # to make pylint happy. 120 | sectorsize, _cylinders, _heads, _sectors = None, None, None, None 121 | 122 | if len(sys.argv) == 1: 123 | showhelp = True 124 | 125 | try: 126 | opts, args = getopt.getopt(sys.argv[1:], "lb:C:H:S:usV?", 127 | ["list", "sectorsize=", "cylinders=", 128 | "heads=", "sectors=", "showsectors", 129 | "showblocks", "version", "help"]) 130 | except getopt.GetoptError: 131 | showhelp = True 132 | 133 | for o, a in opts: 134 | if o in ('-l', '--list'): 135 | showlist = True 136 | elif o in ('-b', '--sectorsize'): 137 | sectorsize = a 138 | elif o in ('-C', '--cylinders'): 139 | _cylinders = a 140 | elif o in ('-H', '--heads'): 141 | _heads = a 142 | elif o in ('-S', '--sectors'): 143 | _sectors = a 144 | elif o in ('-u', '--showsectors'): 145 | showsectors = True 146 | elif o in ('-s', '--showblocks'): 147 | showblocks = True 148 | elif o in ('-V', '--version'): 149 | displayVersion(cmd) 150 | sys.exit(0) 151 | elif o in ('-?', '--help'): 152 | usage(cmd) 153 | sys.exit(0) 154 | else: 155 | sys.stderr.write("Invalid option: %s\n\n" % (o,)) 156 | showhelp = True 157 | 158 | if showhelp: 159 | usage(cmd) 160 | sys.exit(1) 161 | 162 | for arg in args: 163 | if showlist: 164 | listPartitionTable(arg, sectorsize, showsectors, showblocks) 165 | 166 | if __name__ == "__main__": 167 | main(sys.argv) 168 | -------------------------------------------------------------------------------- /src/fdisk/localtest: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export PYTHONPATH=$(pwd)/..:$(pwd)/../.libs 3 | python fdisk.py $* 4 | -------------------------------------------------------------------------------- /src/parted/alignment.py: -------------------------------------------------------------------------------- 1 | # 2 | # geometry.py 3 | # Python bindings for libparted (built on top of the _ped Python module). 4 | # 5 | # Copyright The pyparted Project Authors 6 | # SPDX-License-Identifier: GPL-2.0-or-later 7 | # 8 | 9 | import parted 10 | import _ped 11 | 12 | from parted.decorators import localeC 13 | 14 | 15 | class Alignment(object): 16 | """Alignment() 17 | 18 | An Alignment object describes constraints on how sectors and Geometry 19 | objects are aligned. Being aligned means that the sector be located at 20 | a specific sector multiple on a device, or that a geometry must start 21 | and end at sectors at those specific multiples. Most methods on this 22 | object raise ArithmeticError if calculating alignments fails.""" 23 | 24 | @localeC 25 | def __init__(self, *args, **kwargs): 26 | """Create a new Alignment object from the sectors offset and 27 | grainSize.""" 28 | if "PedAlignment" in kwargs: 29 | self.__alignment = kwargs.get("PedAlignment") 30 | elif "offset" in kwargs and "grainSize" in kwargs: 31 | self.__alignment = _ped.Alignment( 32 | kwargs.get("offset"), kwargs.get("grainSize") 33 | ) 34 | else: 35 | raise parted.AlignmentException( 36 | "no offset+grainSize or PedAlignment specified" 37 | ) 38 | 39 | offset = property( 40 | lambda s: s.__alignment.offset, lambda s, v: setattr(s.__alignment, "offset", v) 41 | ) 42 | grainSize = property( 43 | lambda s: s.__alignment.grain_size, 44 | lambda s, v: setattr(s.__alignment, "grain_size", v), 45 | ) 46 | 47 | def __eq__(self, other): 48 | return not self.__ne__(other) 49 | 50 | def __ne__(self, other): 51 | if not isinstance(self, other.__class__): 52 | return True 53 | 54 | return self.offset != other.offset or self.grainSize != other.grainSize 55 | 56 | def __str__(self): 57 | s = ( 58 | "parted.Alignment instance --\n" 59 | " offset: %(offset)s grainSize: %(grainSize)s\n" 60 | " PedAlignment: %(ped)r" 61 | % { 62 | "offset": self.offset, 63 | "grainSize": self.grainSize, 64 | "ped": self.__alignment, 65 | } 66 | ) 67 | return s 68 | 69 | @localeC 70 | def intersect(self, b): 71 | """Create and return a new Alignment that describes the intersection of 72 | self and alignment b. A sector will satisfy the new alignment iff 73 | it satisfies both of the original alignments. Whether a sector 74 | satisfies a given alignment is determined by is_aligned().""" 75 | return parted.Alignment( 76 | PedAlignment=self.__alignment.intersect(b.getPedAlignment()) 77 | ) 78 | 79 | @localeC 80 | def alignUp(self, geom, sector): 81 | """Return the closest sector to the provided sector that lies inside 82 | geom and satisfies the alignment constraint self. This method 83 | prefers, but does not guarantee, that the result is beyond sector. 84 | If no such sector can be found, an ArithmeticError is raised.""" 85 | return self.__alignment.align_up(geom.getPedGeometry(), sector) 86 | 87 | @localeC 88 | def alignDown(self, geom, sector): 89 | """Return the closest sector to the provided sector that lies inside 90 | geom and satisfies the alignment constraint self. This method 91 | prefers, but does not guarantee, that the result is below sector. 92 | If no such sector can be found, an ArithmeticError is raised.""" 93 | return self.__alignment.align_down(geom.getPedGeometry(), sector) 94 | 95 | @localeC 96 | def alignNearest(self, geom, sector): 97 | """Return the closest sector to the input sector that lies inside 98 | geom and satisfies the alignment constraint self. If no such sector 99 | can be found, an ArithmeticError is raised.""" 100 | return self.__alignment.align_nearest(geom.getPedGeometry(), sector) 101 | 102 | @localeC 103 | def isAligned(self, geom, sector): 104 | """Determine whether sector lies inside geom and satisfies the 105 | alignment constraint self.""" 106 | if not geom: 107 | raise TypeError("missing parted.Geometry parameter") 108 | 109 | if sector is None: 110 | raise TypeError("missing sector parameter") 111 | 112 | return self.__alignment.is_aligned(geom.getPedGeometry(), sector) 113 | 114 | def getPedAlignment(self): 115 | """Return the _ped.Alignment object contained in this Alignment. 116 | For internal module use only.""" 117 | return self.__alignment 118 | -------------------------------------------------------------------------------- /src/parted/cachedlist.py: -------------------------------------------------------------------------------- 1 | # 2 | # Python bindings for libparted (built on top of the _ped Python module). 3 | # 4 | # Copyright The pyparted Project Authors 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | # 7 | 8 | import sys 9 | 10 | if sys.version_info.major >= 3 and sys.version_info.minor >= 3: 11 | from collections.abc import Sequence 12 | else: 13 | from collections import Sequence 14 | 15 | 16 | class CachedList(Sequence): 17 | """CachedList() 18 | 19 | Provides an immutable list that is constructed from a function that 20 | could take a while to run. This is basically the same concept as 21 | memoization, except that the function does not take any parameters 22 | and therefore there is nothing to use as a memo. 23 | 24 | The constructor function is provided to __init__, must not take any 25 | parameters, and must return a list. The invalidate() method indicates 26 | that the list is no longer valid and should be reconstucted by 27 | calling the function again. It is up to client code to call invalidate. 28 | The rest of the procedure is handled by this class. 29 | 30 | In all ways, this should appear to be just like a list.""" 31 | 32 | def __init__(self, lstFn): 33 | """Construct a new CachedList. The lstFn is a function that takes 34 | no parameters and returns a list. It will be called lazily - the 35 | list is not constructed until the first access, which could be 36 | quite a while after this method is called.""" 37 | self._invalid = True 38 | self._lst = [] 39 | self._lstFn = lstFn 40 | 41 | def __rebuildList(self): 42 | if self._invalid: 43 | self._lst = self._lstFn() 44 | self._invalid = False 45 | 46 | def __contains__(self, value): 47 | self.__rebuildList() 48 | return self._lst.__contains__(value) 49 | 50 | def __getitem__(self, index): 51 | self.__rebuildList() 52 | return self._lst.__getitem__(index) 53 | 54 | def __iter__(self): 55 | self.__rebuildList() 56 | return self._lst.__iter__() 57 | 58 | def __len__(self): 59 | self.__rebuildList() 60 | return len(self._lst) 61 | 62 | def __repr__(self): 63 | self.__rebuildList() 64 | return repr(self._lst) 65 | 66 | def __str__(self): 67 | self.__rebuildList() 68 | return str(self._lst) 69 | 70 | def __hash__(self): 71 | return hash(str(self)) 72 | 73 | def count(self, value): 74 | self.__rebuildList() 75 | return self._lst.count(value) 76 | 77 | def index(self, value, *args, **kwargs): 78 | self.__rebuildList() 79 | return self._lst.index(value, *args, **kwargs) 80 | 81 | def invalidate(self): 82 | """Indicate that the list is no longer valid, due to some external 83 | changes. The next access to the list will result in the provided 84 | list construction function being called to build a new list.""" 85 | self._invalid = True 86 | -------------------------------------------------------------------------------- /src/parted/constraint.py: -------------------------------------------------------------------------------- 1 | # 2 | # constraint.py 3 | # Python bindings for libparted (built on top of the _ped Python module). 4 | # 5 | # Copyright The pyparted Project Authors 6 | # SPDX-License-Identifier: GPL-2.0-or-later 7 | # 8 | 9 | import parted 10 | import _ped 11 | 12 | from parted.decorators import localeC 13 | 14 | 15 | class Constraint(object): 16 | """Constraint() 17 | 18 | A Constraint object describes a set of restrictions on other pyparted 19 | operations. Constraints can restrict the location and alignment of the 20 | start and end of a partition, and its minimum and maximum size. Most 21 | constraint operations can raise CreateException if creating temporary 22 | objects fails, or ArithmeticError if an error occurs during 23 | calculations.""" 24 | 25 | @localeC 26 | def __init__(self, *args, **kwargs): 27 | """Create a new Constraint object. There are many different ways to 28 | create a Constraint, all depending on the parameters passed to 29 | __init__. If minGeom and maxGeom are supplied, the constraint will 30 | be created to satisfy both. If only one of minGeom or maxGeom are 31 | supplied, the constraint is only guaranteed to solve the given 32 | parameter. If exactGeom is given, the constraint will only be 33 | satisfied by the given geometry. If device is given, any region 34 | on that device will satisfy the constraint. 35 | 36 | If none of the previously mentioned parameters are supplied, all of 37 | startAlign, EndAlign, startRange, endRange, minSize, and maxSize 38 | must be given.""" 39 | if "PedConstraint" in kwargs: 40 | self.__constraint = kwargs.get("PedConstraint") 41 | elif "minGeom" in kwargs and "maxGeom" in kwargs: 42 | ming = kwargs.get("minGeom").getPedGeometry() 43 | maxg = kwargs.get("maxGeom").getPedGeometry() 44 | self.__constraint = _ped.constraint_new_from_min_max(ming, maxg) 45 | elif "minGeom" in kwargs: 46 | ming = kwargs.get("minGeom").getPedGeometry() 47 | self.__constraint = _ped.constraint_new_from_min(ming) 48 | elif "maxGeom" in kwargs: 49 | maxg = kwargs.get("maxGeom").getPedGeometry() 50 | self.__constraint = _ped.constraint_new_from_max(maxg) 51 | elif "exactGeom" in kwargs: 52 | exact = kwargs.get("exactGeom").getPedGeometry() 53 | self.__constraint = _ped.constraint_exact(exact) 54 | elif "device" in kwargs: 55 | dev = kwargs.get("device").getPedDevice() 56 | self.__constraint = _ped.constraint_any(dev) 57 | elif ( 58 | "startAlign" in kwargs 59 | and "endAlign" in kwargs 60 | and "startRange" in kwargs 61 | and "endRange" in kwargs 62 | and "minSize" in kwargs 63 | and "maxSize" in kwargs 64 | ): 65 | starta = kwargs.get("startAlign").getPedAlignment() 66 | enda = kwargs.get("endAlign").getPedAlignment() 67 | startr = kwargs.get("startRange").getPedGeometry() 68 | endr = kwargs.get("endRange").getPedGeometry() 69 | mins = kwargs.get("minSize") 70 | maxs = kwargs.get("maxSize") 71 | self.__constraint = _ped.Constraint(starta, enda, startr, endr, mins, maxs) 72 | else: 73 | raise parted.ConstraintException("missing initialization parameters") 74 | 75 | def __eq__(self, other): 76 | return not self.__ne__(other) 77 | 78 | def __ne__(self, other): 79 | if hash(self) == hash(other): 80 | return False 81 | 82 | if not isinstance(self, other.__class__): 83 | return True 84 | 85 | c1 = self.getPedConstraint() 86 | c2 = other.getPedConstraint() 87 | 88 | return ( 89 | self.minSize != other.minSize 90 | or self.maxSize != other.maxSize 91 | or c1.start_align != c2.start_align 92 | or c1.end_align != c2.end_align 93 | or c1.start_range != c2.start_range 94 | or c1.end_range != c2.end_range 95 | ) 96 | 97 | startAlign = property( 98 | lambda s: parted.Alignment(PedAlignment=s.__constraint.start_align), 99 | lambda s, v: setattr(s.__constraint, "start_align", v.getPedAlignment()), 100 | ) 101 | 102 | endAlign = property( 103 | lambda s: parted.Alignment(PedAlignment=s.__constraint.end_align), 104 | lambda s, v: setattr(s.__constraint, "end_align", v.getPedAlignment()), 105 | ) 106 | 107 | startRange = property( 108 | lambda s: parted.Geometry(PedGeometry=s.__constraint.start_range), 109 | lambda s, v: setattr(s.__constraint, "start_range", v.getPedGeometry()), 110 | ) 111 | 112 | endRange = property( 113 | lambda s: parted.Geometry(PedGeometry=s.__constraint.end_range), 114 | lambda s, v: setattr(s.__constraint, "end_range", v.getPedGeometry()), 115 | ) 116 | 117 | minSize = property( 118 | lambda s: s.__constraint.min_size, 119 | lambda s, v: setattr(s.__constraint, "min_size", v), 120 | ) 121 | 122 | maxSize = property( 123 | lambda s: s.__constraint.max_size, 124 | lambda s, v: setattr(s.__constraint, "max_size", v), 125 | ) 126 | 127 | def __str__(self): 128 | s = ( 129 | "parted.Constraint instance --\n" 130 | " startAlign: %(startAlign)r endAlign: %(endAlign)r\n" 131 | " startRange: %(startRange)r endRange: %(endRange)r\n" 132 | " minSize: %(minSize)s maxSize: %(maxSize)s\n" 133 | " PedConstraint: %(ped)r" 134 | % { 135 | "startAlign": self.startAlign, 136 | "endAlign": self.endAlign, 137 | "startRange": self.startRange, 138 | "endRange": self.endRange, 139 | "minSize": self.minSize, 140 | "maxSize": self.maxSize, 141 | "ped": self.__constraint, 142 | } 143 | ) 144 | return s 145 | 146 | @localeC 147 | def intersect(self, b): 148 | """Return a new constraint that is the intersection of self and the 149 | provided constraint b. The returned constraint will therefore be 150 | more restrictive than either input as it will have to satisfy 151 | both.""" 152 | return parted.Constraint( 153 | PedConstraint=self.__constraint.intersect(b.getPedConstraint()) 154 | ) 155 | 156 | @localeC 157 | def solveMax(self): 158 | """Return a new geometry that is the largest region satisfying self. 159 | There may be more than one solution, and there are no guarantees as 160 | to which solution will be returned.""" 161 | return parted.Geometry(PedGeometry=self.__constraint.solve_max()) 162 | 163 | @localeC 164 | def solveNearest(self, geom): 165 | """Return a new geometry that is the nearest region to geom that 166 | satisfies self. This function does not guarantee any specific 167 | meaning of 'nearest'.""" 168 | return parted.Geometry( 169 | PedGeometry=self.__constraint.solve_nearest(geom.getPedGeometry()) 170 | ) 171 | 172 | @localeC 173 | def isSolution(self, geom): 174 | """Does geom satisfy this constraint?""" 175 | return self.__constraint.is_solution(geom.getPedGeometry()) 176 | 177 | def getPedConstraint(self): 178 | """Return the _ped.Constraint object contained in this Constraint. 179 | For internal module use only.""" 180 | return self.__constraint 181 | -------------------------------------------------------------------------------- /src/parted/decorators.py: -------------------------------------------------------------------------------- 1 | # 2 | # Python bindings for libparted (built on top of the _ped Python module). 3 | # 4 | # Copyright The pyparted Project Authors 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | # 7 | 8 | import locale 9 | import functools 10 | 11 | 12 | def localeC(fn): 13 | # setlocale is not thread-safe, and anaconda (at least) may call this from 14 | # another thread. This is just a luxury to have untranslated tracebacks, 15 | # so it's not worth tracebacking itself. 16 | def _setlocale(l): 17 | try: 18 | locale.setlocale(locale.LC_MESSAGES, l) 19 | # pylint: disable=bare-except 20 | except: 21 | pass 22 | 23 | @functools.wraps(fn) 24 | def new(*args, **kwds): 25 | oldlocale = locale.getlocale(locale.LC_MESSAGES) 26 | _setlocale("C") 27 | try: 28 | ret = fn(*args, **kwds) 29 | finally: 30 | _setlocale(oldlocale) 31 | return ret 32 | 33 | return new 34 | -------------------------------------------------------------------------------- /src/parted/filesystem.py: -------------------------------------------------------------------------------- 1 | # 2 | # filesystem.py 3 | # Python bindings for libparted (built on top of the _ped Python module). 4 | # 5 | # Copyright The pyparted Project Authors 6 | # SPDX-License-Identifier: GPL-2.0-or-later 7 | # 8 | 9 | import _ped 10 | import parted 11 | 12 | from parted.decorators import localeC 13 | 14 | # XXX: add docstrings! 15 | 16 | 17 | class FileSystem(object): 18 | # pylint: disable=W0622 19 | @localeC 20 | def __init__(self, type=None, geometry=None, checked=False, PedFileSystem=None): 21 | if checked: 22 | c = 1 23 | else: 24 | c = 0 25 | 26 | if PedFileSystem is None: 27 | if type is None: 28 | raise parted.FileSystemException("no type specified") 29 | elif geometry is None: 30 | raise parted.FileSystemException("no geometry specified") 31 | 32 | self._type = type 33 | self._geometry = geometry 34 | self._checked = checked 35 | self.__fileSystem = _ped.FileSystem( 36 | type=fileSystemType[type], geom=geometry.getPedGeometry(), checked=c 37 | ) 38 | else: 39 | self.__fileSystem = PedFileSystem 40 | self._type = self.__fileSystem.type.name 41 | self._geometry = parted.Geometry(PedGeometry=self.__fileSystem.geom) 42 | 43 | if self.__fileSystem.checked: 44 | self._checked = True 45 | else: 46 | self._checked = False 47 | 48 | def __eq__(self, other): 49 | return not self.__ne__(other) 50 | 51 | def __ne__(self, other): 52 | if not isinstance(self, other.__class__): 53 | return True 54 | 55 | return self.type != other.type or self.geometry != other.geometry 56 | 57 | def __str__(self): 58 | s = ( 59 | "parted.FileSystem instance --\n" 60 | " type: %(type)s geometry: %(geometry)r checked: %(checked)s\n" 61 | " PedFileSystem: %(ped)r" 62 | % { 63 | "type": self.type, 64 | "geometry": self.geometry, 65 | "checked": self.checked, 66 | "ped": self.__fileSystem, 67 | } 68 | ) 69 | return s 70 | 71 | @property 72 | def type(self): 73 | """The type of this filesystem, e.g. ext3.""" 74 | return self._type 75 | 76 | @property 77 | def geometry(self): 78 | """The Geometry object describing this filesystem.""" 79 | return self._geometry 80 | 81 | @property 82 | def checked(self): 83 | """True if this filesystem has been checked, False otherwise.""" 84 | return bool(self._checked) 85 | 86 | def getPedFileSystem(self): 87 | """Return the _ped.FileSystem object contained in this FileSystem. 88 | For internal module use only.""" 89 | return self.__fileSystem 90 | 91 | 92 | # collect all filesystem types and store them in a hash 93 | fileSystemType = {} 94 | __type = _ped.file_system_type_get_next() 95 | fileSystemType[__type.name] = __type 96 | 97 | while True: 98 | try: 99 | __type = _ped.file_system_type_get_next(__type) 100 | fileSystemType[__type.name] = __type 101 | except (IndexError, TypeError, _ped.UnknownTypeException): 102 | break 103 | -------------------------------------------------------------------------------- /src/parted/geometry.py: -------------------------------------------------------------------------------- 1 | # 2 | # geometry.py 3 | # Python bindings for libparted (built on top of the _ped Python module). 4 | # 5 | # Copyright The pyparted Project Authors 6 | # SPDX-License-Identifier: GPL-2.0-or-later 7 | # 8 | 9 | import math 10 | import warnings 11 | 12 | import parted 13 | import _ped 14 | 15 | from parted.decorators import localeC 16 | 17 | 18 | class Geometry(object): 19 | """Geometry() 20 | 21 | Geometry represents a region on a device in the system - a disk or 22 | partition. It is expressed in terms of a starting sector and a length. 23 | Many methods (read and write methods in particular) throughout pyparted 24 | take in a Geometry object as an argument.""" 25 | 26 | @localeC 27 | def __init__( 28 | self, device=None, start=None, length=None, end=None, PedGeometry=None 29 | ): 30 | """Create a new Geometry object for the given _ped.Device that extends 31 | for length sectors from the start sector. Optionally, an end sector 32 | can also be provided.""" 33 | if PedGeometry: 34 | self.__geometry = PedGeometry 35 | 36 | if device is None: 37 | self._device = parted.Device(PedDevice=self.__geometry.dev) 38 | else: 39 | self._device = device 40 | elif not end: 41 | self._device = device 42 | self.__geometry = _ped.Geometry(self.device.getPedDevice(), start, length) 43 | elif not length and (end > start): 44 | self._device = device 45 | self.__geometry = _ped.Geometry( 46 | self.device.getPedDevice(), start, (end - start + 1), end=end 47 | ) 48 | elif start and length and end and (end > start): 49 | self._device = device 50 | self.__geometry = _ped.Geometry( 51 | self.device.getPedDevice(), start, length, end=end 52 | ) 53 | else: 54 | raise parted.GeometryException( 55 | "must specify PedGeometry or (device, start, length) or (device, start, end) or (device, start, length, end)" 56 | ) 57 | 58 | def __eq__(self, other): 59 | return not self.__ne__(other) 60 | 61 | def __ne__(self, other): 62 | if not isinstance(self, other.__class__): 63 | return True 64 | 65 | return ( 66 | self.device != other.device 67 | or self.start != other.start 68 | or self.length != other.length 69 | ) 70 | 71 | def __str__(self): 72 | s = ( 73 | "parted.Geometry instance --\n" 74 | " start: %(start)s end: %(end)s length: %(length)s\n" 75 | " device: %(device)r PedGeometry: %(ped)r" 76 | % { 77 | "start": self.start, 78 | "end": self.end, 79 | "length": self.length, 80 | "device": self.device, 81 | "ped": self.__geometry, 82 | } 83 | ) 84 | return s 85 | 86 | @property 87 | def device(self): 88 | """The Device this geometry describes.""" 89 | return self._device 90 | 91 | start = property( 92 | lambda s: s.__geometry.start, lambda s, v: s.__geometry.set_start(v) 93 | ) 94 | end = property(lambda s: s.__geometry.end, lambda s, v: s.__geometry.set_end(v)) 95 | length = property( 96 | lambda s: s.__geometry.length, 97 | lambda s, v: s.__geometry.set(s.__geometry.start, v), 98 | ) 99 | 100 | @localeC 101 | def check(self, offset, granularity, count, timer=None): 102 | """Check the region described by self for errors on the disk. 103 | offset -- The beginning of the region to check, in sectors from the 104 | start of the geometry. 105 | granularity -- How sectors should be grouped together 106 | count -- How many sectors from the region to check.""" 107 | if not timer: 108 | return self.__geometry.check(offset, granularity, count) 109 | else: 110 | return self.__geometry.check(offset, granularity, count, timer) 111 | 112 | @localeC 113 | def contains(self, b): 114 | """Return whether Geometry b is contained entirely within self and on 115 | the same physical device.""" 116 | return self.__geometry.test_inside(b.getPedGeometry()) 117 | 118 | @localeC 119 | def containsSector(self, sector): 120 | """Return whether the sectory is contained entirely within self.""" 121 | return self.__geometry.test_sector_inside(sector) 122 | 123 | @localeC 124 | def getSize(self, unit="MB"): 125 | """Return the size of the geometry in the unit specified. The unit 126 | is given as a string corresponding to one of the following 127 | abbreviations: b (bytes), KB (kilobytes), MB (megabytes), GB 128 | (gigabytes), TB (terabytes). An invalid unit string will raise a 129 | SyntaxError exception. The default unit is MB.""" 130 | warnings.warn("use the getLength method", DeprecationWarning) 131 | lunit = unit.lower() 132 | size = self.length * self.device.sectorSize 133 | 134 | if lunit not in parted._exponent.keys(): 135 | raise SyntaxError("invalid unit %s given" % (unit)) 136 | 137 | return size / math.pow(1024.0, parted._exponent[lunit]) 138 | 139 | @localeC 140 | def getLength(self, unit="sectors"): 141 | """Return the length of the geometry in sectors. Optionally, a SI or 142 | IEC prefix followed by a 'B' may be given in order to convert the 143 | length into bytes. The allowed values include B, kB, MB, GB, TB, KiB, 144 | MiB, GiB, and TiB.""" 145 | sectors = self.length 146 | if unit == "sectors": 147 | return sectors 148 | return parted.formatBytes(sectors * self.device.sectorSize, unit) 149 | 150 | @localeC 151 | def intersect(self, b): 152 | """Return a new Geometry describing the region common to both self 153 | and Geometry b. Raises ArithmeticError if the regions do not 154 | intersect.""" 155 | return Geometry(PedGeometry=self.__geometry.intersect(b.getPedGeometry())) 156 | 157 | @localeC 158 | def map(self, src, sector): 159 | """Given a Geometry src that overlaps with self and a sector inside src, 160 | this method translates the address of the sector into an address 161 | inside self. If self does not contain sector, ArithmeticError will 162 | be raised.""" 163 | return parted.Geometry( 164 | PedGeometry=self.__geometry.map(src.getPedGeometry(), sector) 165 | ) 166 | 167 | @localeC 168 | def overlapsWith(self, b): 169 | """Return whether self and b are on the same device and share at least 170 | some of the same region.""" 171 | try: 172 | self.__geometry.intersect(b.getPedGeometry()) 173 | return True 174 | except ArithmeticError: 175 | return False 176 | 177 | @localeC 178 | def read(self, offset, count): 179 | """Read data from the region described by self. 180 | offset -- The number of sectors from the beginning of the region 181 | (not the beginning of the disk) to read. 182 | count -- The number of sectors to read.""" 183 | return self.__geometry.read(offset, count) 184 | 185 | @localeC 186 | def sync(self, fast=False): 187 | """Flushes all caches on the device described by self. If fast is 188 | True, the flush will be quicked by cache coherency is not 189 | guaranteed.""" 190 | if fast: 191 | return self.__geometry.sync_fast() 192 | else: 193 | return self.__geometry.sync() 194 | 195 | @localeC 196 | def write(self, buf, offset, count): 197 | """Write data into the region described by self. 198 | buf -- The data to be written. 199 | offset -- Where to start writing to region, expressed as the number 200 | of sectors from the start of the region (not the disk). 201 | count -- How many sectors of buf to write out.""" 202 | return self.__geometry.write(buf, offset, count) 203 | 204 | def getPedGeometry(self): 205 | """Return the _ped.Geometry object contained in this Geometry. 206 | For internal module use only.""" 207 | return self.__geometry 208 | -------------------------------------------------------------------------------- /src/pytimer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pytimer.c 3 | * 4 | * Copyright The pyparted Project Authors 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | */ 7 | 8 | #include 9 | 10 | #include "convert.h" 11 | #include "exceptions.h" 12 | #include "pytimer.h" 13 | #include "typeobjects/pytimer.h" 14 | 15 | /* _ped.Timer functions */ 16 | void _ped_Timer_dealloc(_ped_Timer *self) 17 | { 18 | PyObject_GC_UnTrack(self); 19 | free(self->state_name); 20 | PyObject_GC_Del(self); 21 | } 22 | 23 | int _ped_Timer_compare(_ped_Timer *self, PyObject *obj) 24 | { 25 | _ped_Timer *comp = NULL; 26 | int check = PyObject_IsInstance(obj, (PyObject *) &_ped_Timer_Type_obj); 27 | 28 | if (PyErr_Occurred()) { 29 | return -1; 30 | } 31 | 32 | if (!check) { 33 | PyErr_SetString(PyExc_ValueError, "object comparing to must be a _ped.Timer"); 34 | return -1; 35 | } 36 | 37 | comp = (_ped_Timer *) obj; 38 | 39 | if ((self->frac == comp->frac) && 40 | (self->start == comp->start) && 41 | (self->now == comp->now) && 42 | (self->predicted_end == comp->predicted_end) && 43 | (!strcmp(self->state_name, comp->state_name)) && 44 | (self->handler == comp->handler) && 45 | (self->context == comp->context)) { 46 | return 0; 47 | } else { 48 | return 1; 49 | } 50 | } 51 | 52 | PyObject *_ped_Timer_richcompare(_ped_Timer *a, PyObject *b, int op) 53 | { 54 | int rv; 55 | 56 | if (op == Py_EQ || op == Py_NE) { 57 | rv = _ped_Timer_compare(a, b); 58 | 59 | if (PyErr_Occurred()) { 60 | return NULL; 61 | } 62 | 63 | return PyBool_FromLong(op == Py_EQ ? rv == 0 : rv != 0); 64 | } else if ((op == Py_LT) || (op == Py_LE) || (op == Py_GT) || (op == Py_GE)) { 65 | PyErr_SetString(PyExc_TypeError, "comparison operator not supported for _ped.Timer"); 66 | return NULL; 67 | } else { 68 | PyErr_SetString(PyExc_ValueError, "unknown richcompare op"); 69 | return NULL; 70 | } 71 | } 72 | 73 | PyObject *_ped_Timer_str(_ped_Timer *self) 74 | { 75 | PyObject *ret = NULL; 76 | char *buf = NULL; 77 | 78 | if (asprintf(&buf, "_ped.Timer instance --\n" 79 | " start: %s now: %s\n" 80 | " predicted_end: %s frac: %f\n" 81 | " state_name: %s", 82 | ctime(&(self->start)), ctime(&(self->now)), 83 | ctime(&(self->predicted_end)), self->frac, 84 | self->state_name) == -1) { 85 | return PyErr_NoMemory(); 86 | } 87 | 88 | ret = Py_BuildValue("s", buf); 89 | free(buf); 90 | return ret; 91 | } 92 | 93 | int _ped_Timer_traverse(_ped_Timer *self, visitproc visit, void *arg) 94 | { 95 | return 0; 96 | } 97 | 98 | int _ped_Timer_clear(_ped_Timer *self) 99 | { 100 | return 0; 101 | } 102 | 103 | int _ped_Timer_init(_ped_Timer *self, PyObject *args, PyObject *kwds) 104 | { 105 | /* XXX: timers aren't really done yet in pyparted */ 106 | PyErr_SetString(PyExc_NotImplementedError, NULL); 107 | return -1; 108 | } 109 | 110 | PyObject *_ped_Timer_get(_ped_Timer *self, void *closure) 111 | { 112 | char *member = (char *) closure; 113 | 114 | if (member == NULL) { 115 | PyErr_SetString(PyExc_TypeError, "Empty _ped.Timer()"); 116 | return NULL; 117 | } 118 | 119 | if (!strcmp(member, "frac")) { 120 | return Py_BuildValue("f", self->frac); 121 | } else if (!strcmp(member, "start")) { 122 | return Py_BuildValue("d", self->start); 123 | } else if (!strcmp(member, "now")) { 124 | return Py_BuildValue("d", self->now); 125 | } else if (!strcmp(member, "predicted_end")) { 126 | return Py_BuildValue("d", self->predicted_end); 127 | } else if (!strcmp(member, "state_name")) { 128 | if (self->state_name != NULL) { 129 | return PyUnicode_FromString(self->state_name); 130 | } else { 131 | return PyUnicode_FromString(""); 132 | } 133 | } else { 134 | PyErr_Format(PyExc_AttributeError, "_ped.Timer object has no attribute %s", member); 135 | return NULL; 136 | } 137 | } 138 | 139 | int _ped_Timer_set(_ped_Timer *self, PyObject *value, void *closure) 140 | { 141 | char *member = (char *) closure; 142 | 143 | if (member == NULL) { 144 | PyErr_SetString(PyExc_TypeError, "Empty _ped.Timer()"); 145 | return -1; 146 | } 147 | 148 | if (!strcmp(member, "frac")) { 149 | if (!PyArg_ParseTuple(value, "f", &self->frac)) { 150 | return -1; 151 | } 152 | } else if (!strcmp(member, "start")) { 153 | self->start = PyFloat_AsDouble(value); 154 | 155 | if (PyErr_Occurred()) { 156 | return -1; 157 | } 158 | } else if (!strcmp(member, "now")) { 159 | self->now = PyFloat_AsDouble(value); 160 | 161 | if (PyErr_Occurred()) { 162 | return -1; 163 | } 164 | } else if (!strcmp(member, "predicted_end")) { 165 | self->predicted_end = PyFloat_AsDouble(value); 166 | 167 | if (PyErr_Occurred()) { 168 | return -1; 169 | } 170 | } else if (!strcmp(member, "state_name")) { 171 | self->state_name = (char *) PyUnicode_AsUTF8(value); 172 | 173 | if (PyErr_Occurred()) { 174 | return -1; 175 | } 176 | /* self->state_name now points to the internal buffer of a PyUnicode obj 177 | * which may be freed when its refcount drops to zero, so strdup it. 178 | */ 179 | if (self->state_name) { 180 | self->state_name = strdup(self->state_name); 181 | 182 | if (!self->state_name) { 183 | PyErr_NoMemory(); 184 | return -2; 185 | } 186 | } 187 | } else { 188 | PyErr_Format(PyExc_AttributeError, "_ped.Timer object has no attribute %s", member); 189 | return -1; 190 | } 191 | 192 | return 0; 193 | } 194 | 195 | /* 1:1 function mappings for timer.h in libparted */ 196 | PyObject *py_ped_timer_destroy(PyObject *s, PyObject *args) 197 | { 198 | Py_CLEAR(s); 199 | 200 | Py_RETURN_NONE; 201 | } 202 | 203 | PyObject *py_ped_timer_new_nested(PyObject *s, PyObject *args) 204 | { 205 | float nest_frac; 206 | PedTimer *parent = NULL, *timer = NULL; 207 | _ped_Timer *ret = NULL; 208 | 209 | if (!PyArg_ParseTuple(args, "f", &nest_frac)) { 210 | return NULL; 211 | } 212 | 213 | parent = _ped_Timer2PedTimer(s); 214 | 215 | if (parent == NULL) { 216 | return NULL; 217 | } 218 | 219 | timer = ped_timer_new_nested(parent, nest_frac); 220 | ped_timer_destroy(parent); 221 | 222 | if (timer) { 223 | ret = PedTimer2_ped_Timer(timer); 224 | } else { 225 | PyErr_SetString(CreateException, "Could not create new nested timer"); 226 | return NULL; 227 | } 228 | 229 | ped_timer_destroy(timer); 230 | return (PyObject *) ret; 231 | } 232 | 233 | PyObject *py_ped_timer_destroy_nested(PyObject *s, PyObject *args) 234 | { 235 | PedTimer *timer = NULL; 236 | 237 | timer = _ped_Timer2PedTimer(s); 238 | 239 | if (timer == NULL) { 240 | return NULL; 241 | } 242 | 243 | ped_timer_destroy_nested(timer); 244 | ped_timer_destroy(timer); 245 | Py_CLEAR(s); 246 | 247 | Py_RETURN_NONE; 248 | } 249 | 250 | PyObject *py_ped_timer_touch(PyObject *s, PyObject *args) 251 | { 252 | PedTimer *timer = NULL; 253 | 254 | timer = _ped_Timer2PedTimer(s); 255 | 256 | if (timer == NULL) { 257 | return NULL; 258 | } 259 | 260 | ped_timer_touch(timer); 261 | ped_timer_destroy(timer); 262 | 263 | Py_RETURN_NONE; 264 | } 265 | 266 | PyObject *py_ped_timer_reset(PyObject *s, PyObject *args) 267 | { 268 | PedTimer *timer = NULL; 269 | 270 | timer = _ped_Timer2PedTimer(s); 271 | 272 | if (timer == NULL) { 273 | return NULL; 274 | } 275 | 276 | ped_timer_reset(timer); 277 | ped_timer_destroy(timer); 278 | 279 | Py_RETURN_NONE; 280 | } 281 | 282 | PyObject *py_ped_timer_update(PyObject *s, PyObject *args) 283 | { 284 | float frac; 285 | PedTimer *timer = NULL; 286 | 287 | if (!PyArg_ParseTuple(args, "f", &frac)) { 288 | return NULL; 289 | } 290 | 291 | timer = _ped_Timer2PedTimer(s); 292 | 293 | if (timer == NULL) { 294 | return NULL; 295 | } 296 | 297 | ped_timer_update(timer, frac); 298 | ped_timer_destroy(timer); 299 | 300 | Py_RETURN_NONE; 301 | } 302 | 303 | PyObject *py_ped_timer_set_state_name(PyObject *s, PyObject *args) 304 | { 305 | char *str = NULL; 306 | PedTimer *timer = NULL; 307 | 308 | if (!PyArg_ParseTuple(args, "z", &str)) { 309 | return NULL; 310 | } 311 | 312 | timer = _ped_Timer2PedTimer(s); 313 | 314 | if (timer == NULL) { 315 | return NULL; 316 | } 317 | 318 | ped_timer_set_state_name(timer, str); 319 | ped_timer_destroy(timer); 320 | free(str); 321 | 322 | Py_RETURN_NONE; 323 | } 324 | -------------------------------------------------------------------------------- /src/pyunit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pyunit.c 3 | * 4 | * Copyright The pyparted Project Authors 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | */ 7 | 8 | #include 9 | 10 | #include "convert.h" 11 | #include "exceptions.h" 12 | #include "pydevice.h" 13 | #include "pyunit.h" 14 | 15 | /* 1:1 function mappings for unit.h in libparted */ 16 | PyObject *py_ped_unit_set_default(PyObject *s, PyObject *args) 17 | { 18 | int unit; 19 | 20 | if (!PyArg_ParseTuple(args, "i", &unit)) { 21 | return NULL; 22 | } 23 | 24 | if (unit < PED_UNIT_FIRST || unit > PED_UNIT_LAST) { 25 | PyErr_SetString(PyExc_ValueError, "Invalid unit provided."); 26 | return NULL; 27 | } 28 | 29 | ped_unit_set_default(unit); 30 | 31 | Py_RETURN_NONE; 32 | } 33 | 34 | PyObject *py_ped_unit_get_default(PyObject *s, PyObject *args) 35 | { 36 | return PyLong_FromLong(ped_unit_get_default()); 37 | } 38 | 39 | PyObject *py_ped_unit_get_size(PyObject *s, PyObject *args) 40 | { 41 | long long ret = -1; 42 | PedDevice *dev = NULL; 43 | int unit; 44 | 45 | if (!PyArg_ParseTuple(args, "i", &unit)) { 46 | return NULL; 47 | } 48 | 49 | if (unit < PED_UNIT_FIRST || unit > PED_UNIT_LAST) { 50 | PyErr_SetString(PyExc_ValueError, "Invalid unit provided."); 51 | return NULL; 52 | } 53 | 54 | dev = _ped_Device2PedDevice(s); 55 | 56 | if (dev == NULL) { 57 | return NULL; 58 | } 59 | 60 | ret = ped_unit_get_size(dev, unit); 61 | 62 | if (ret == 0) { 63 | if (partedExnRaised) { 64 | partedExnRaised = 0; 65 | 66 | if (!PyErr_Occurred()) { 67 | PyErr_SetString(PyExc_ValueError, partedExnMessage); 68 | } 69 | } else { 70 | PyErr_SetString(PyExc_ValueError, "Could not get size"); 71 | } 72 | 73 | return NULL; 74 | } 75 | 76 | return PyLong_FromLongLong(ret); 77 | } 78 | 79 | PyObject *py_ped_unit_get_name(PyObject *s, PyObject *args) 80 | { 81 | const char *name; 82 | int unit; 83 | 84 | if (!PyArg_ParseTuple(args, "i", &unit)) { 85 | return NULL; 86 | } 87 | 88 | if (unit < PED_UNIT_FIRST || unit > PED_UNIT_LAST) { 89 | PyErr_SetString(PyExc_ValueError, "Invalid unit provided."); 90 | return NULL; 91 | } 92 | 93 | /* 94 | * DO NOT free the result from ped_unit_get_name(), it's a pointer to 95 | * a value in the static unit_names[] array in libparted. 96 | */ 97 | name = ped_unit_get_name(unit); 98 | 99 | if (name != NULL) { 100 | return PyUnicode_FromString(name); 101 | } else { 102 | return PyUnicode_FromString(""); 103 | } 104 | } 105 | 106 | PyObject *py_ped_unit_get_by_name(PyObject *s, PyObject *args) 107 | { 108 | int ret; 109 | char *name = NULL; 110 | 111 | if (!PyArg_ParseTuple(args, "z", &name)) { 112 | return NULL; 113 | } 114 | 115 | ret = ped_unit_get_by_name(name); 116 | 117 | if (ret < PED_UNIT_FIRST || ret > PED_UNIT_LAST) { 118 | PyErr_SetString(UnknownTypeException, name); 119 | return NULL; 120 | } 121 | 122 | return Py_BuildValue("i", ret); 123 | } 124 | 125 | PyObject *py_ped_unit_format_custom_byte(PyObject *s, PyObject *args) 126 | { 127 | PyObject *ret = NULL; 128 | char *pedret = NULL; 129 | PedSector sector; 130 | int unit; 131 | PedDevice *out_dev = NULL; 132 | 133 | if (!PyArg_ParseTuple(args, "Li", §or, &unit)) { 134 | return NULL; 135 | } 136 | 137 | if (unit < PED_UNIT_FIRST || unit > PED_UNIT_LAST) { 138 | PyErr_SetString(PyExc_ValueError, "Invalid unit provided."); 139 | return NULL; 140 | } 141 | 142 | out_dev = _ped_Device2PedDevice(s); 143 | 144 | if (out_dev == NULL) { 145 | return NULL; 146 | } 147 | 148 | pedret = ped_unit_format_custom_byte(out_dev, sector, unit); 149 | 150 | if (pedret != NULL) { 151 | ret = PyUnicode_FromString(pedret); 152 | free(pedret); 153 | } else { 154 | ret = PyUnicode_FromString(""); 155 | } 156 | 157 | return ret; 158 | } 159 | 160 | PyObject *py_ped_unit_format_byte(PyObject *s, PyObject *args) 161 | { 162 | PyObject *ret = NULL; 163 | char *pedret = NULL; 164 | PedSector sector; 165 | PedDevice *out_dev = NULL; 166 | 167 | if (!PyArg_ParseTuple(args, "L", §or)) { 168 | return NULL; 169 | } 170 | 171 | out_dev = _ped_Device2PedDevice(s); 172 | 173 | if (out_dev == NULL) { 174 | return NULL; 175 | } 176 | 177 | pedret = ped_unit_format_byte(out_dev, sector); 178 | 179 | if (pedret != NULL) { 180 | ret = PyUnicode_FromString(pedret); 181 | free(pedret); 182 | } else { 183 | ret = PyUnicode_FromString(""); 184 | } 185 | 186 | return ret; 187 | } 188 | 189 | PyObject *py_ped_unit_format_custom(PyObject *s, PyObject *args) 190 | { 191 | PyObject *ret = NULL; 192 | char *pedret = NULL; 193 | PedDevice *out_dev = NULL; 194 | PedSector sector; 195 | int unit; 196 | 197 | if (!PyArg_ParseTuple(args, "Li", §or, &unit)) { 198 | return NULL; 199 | } 200 | 201 | out_dev = _ped_Device2PedDevice(s); 202 | 203 | if (out_dev == NULL) { 204 | return NULL; 205 | } 206 | 207 | pedret = ped_unit_format_custom(out_dev, sector, unit); 208 | 209 | if (pedret != NULL) { 210 | ret = PyUnicode_FromString(pedret); 211 | free(pedret); 212 | } else { 213 | ret = PyUnicode_FromString(""); 214 | } 215 | 216 | return ret; 217 | } 218 | 219 | PyObject *py_ped_unit_format(PyObject *s, PyObject *args) 220 | { 221 | PyObject *ret = NULL; 222 | char *pedret = NULL; 223 | PedDevice *out_dev = NULL; 224 | PedSector sector; 225 | 226 | if (!PyArg_ParseTuple(args, "L", §or)) { 227 | return NULL; 228 | } 229 | 230 | out_dev = _ped_Device2PedDevice(s); 231 | 232 | if (out_dev == NULL) { 233 | return NULL; 234 | } 235 | 236 | pedret = ped_unit_format(out_dev, sector); 237 | 238 | if (pedret != NULL) { 239 | ret = PyUnicode_FromString(pedret); 240 | free(pedret); 241 | } else { 242 | ret = PyUnicode_FromString(""); 243 | } 244 | 245 | return ret; 246 | } 247 | 248 | PyObject *py_ped_unit_parse(PyObject *s, PyObject *args) 249 | { 250 | int ret; 251 | char *str = NULL; 252 | PedDevice *out_dev = NULL; 253 | PedSector sector; 254 | PyObject *in_geom = NULL; 255 | PedGeometry *out_geom = NULL; 256 | 257 | if (!PyArg_ParseTuple(args, "zLO!", &str, §or, &_ped_Geometry_Type_obj, &in_geom)) { 258 | return NULL; 259 | } 260 | 261 | out_dev = _ped_Device2PedDevice(s); 262 | 263 | if (out_dev == NULL) { 264 | return NULL; 265 | } 266 | 267 | out_geom = _ped_Geometry2PedGeometry(in_geom); 268 | 269 | if (out_geom == NULL) { 270 | return NULL; 271 | } 272 | 273 | ret = ped_unit_parse(str, out_dev, §or, &out_geom); 274 | 275 | if (ret) { 276 | Py_RETURN_TRUE; 277 | } else { 278 | Py_RETURN_FALSE; 279 | } 280 | } 281 | 282 | PyObject *py_ped_unit_parse_custom(PyObject *s, PyObject *args) 283 | { 284 | int ret; 285 | char *str = NULL; 286 | PedDevice *out_dev = NULL; 287 | int unit; 288 | PedSector sector; 289 | PyObject *in_geom = NULL; 290 | PedGeometry *out_geom = NULL; 291 | 292 | if (!PyArg_ParseTuple(args, "ziLO!", &str, &unit, §or, &_ped_Geometry_Type_obj, &in_geom)) { 293 | return NULL; 294 | } 295 | 296 | if (unit < PED_UNIT_FIRST || unit > PED_UNIT_LAST) { 297 | PyErr_SetString(PyExc_ValueError, "Invalid unit provided."); 298 | return NULL; 299 | } 300 | 301 | out_dev = _ped_Device2PedDevice(s); 302 | 303 | if (out_dev == NULL) { 304 | return NULL; 305 | } 306 | 307 | out_geom = _ped_Geometry2PedGeometry(in_geom); 308 | 309 | if (out_geom == NULL) { 310 | return NULL; 311 | } 312 | 313 | ret = ped_unit_parse_custom(str, out_dev, unit, §or, &out_geom); 314 | 315 | if (ret) { 316 | Py_RETURN_TRUE; 317 | } else { 318 | Py_RETURN_FALSE; 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /tests/README.rst: -------------------------------------------------------------------------------- 1 | Testing pyparted 2 | ================ 3 | 4 | Pyparted test suite inherits from the standard :class:`unittest.TestCase` class. 5 | To execute it from inside the source directory run the command:: 6 | 7 | make test 8 | 9 | It is also possible to generate test coverage reports using the Python coverage 10 | tool. To do that execute:: 11 | 12 | make coverage 13 | 14 | To execute the Pylint code analysis tool run:: 15 | 16 | make check 17 | 18 | Running Pylint requires Python3 due to usage of pocket-lint. 19 | 20 | 21 | Test Suite Architecture 22 | ------------------------ 23 | 24 | Pyparted test suite relies on several base classes listed below. All test 25 | cases inherit from them. 26 | 27 | - :class:`unittest.TestCase` - the standard unit test class in Python. 28 | Used only for base classes described below and for test cases which 29 | don't need access to filesystems or disks; 30 | 31 | 32 | - :class:`~tests.baseclass.RequiresDeviceNode` - base class for any test case 33 | that requires a temporary device node; 34 | 35 | - :class:`~tests.baseclass.RequiresDevice` - base class for any test case that 36 | requires a _ped.Device or parted.Device object first; 37 | 38 | - :class:`~tests.baseclass.RequiresFileSystem` - base class for any test case 39 | that requires a filesystem on a device; 40 | 41 | - :class:`~tests.baseclass.RequiresDeviceAlignment`- base class for certain 42 | alignment tests that require a _ped.Device; 43 | 44 | - :class:`~tests.baseclass.RequiresLabeledDevice` - base class for any test 45 | case that requires a labeled device; 46 | 47 | - :class:`~tests.baseclass.RequiresDisk` - base class for any test case that 48 | requires a _ped.Disk or parted.Disk; 49 | 50 | - :class:`~tests.baseclass.RequiresMount` - base class for any test case that 51 | requires a filesystem made and mounted; 52 | 53 | - :class:`~tests.baseclass.RequiresPartition` - base class for any test case 54 | that requires a _ped.Partition; 55 | 56 | - :class:`~tests.baseclass.RequiresDiskTypes` - base class for any test case 57 | that requires a hash table of all _ped.DiskType objects available; 58 | 59 | - :class:`~tests.baseclass.BuildList` - base class for any test case that 60 | requires a list being built via successive calls of some function. The 61 | function must raise IndexError when there's no more output to add to the 62 | return list. This class is most useful for all those _get_next methods. 63 | It is used in combination with other base classes; 64 | 65 | 66 | Test scenarios are defined inside the `runTest` method of each test class using 67 | multiple assert statements. 68 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcantrell/pyparted/8fe351b0617f08cd982ce6c80afbfbd3127cf5d5/tests/__init__.py -------------------------------------------------------------------------------- /tests/baseclass.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright The pyparted Project Authors 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | # 5 | 6 | import _ped 7 | import parted 8 | import os 9 | import tempfile 10 | import unittest 11 | 12 | # Base class for any test case that requires a temp device node 13 | class RequiresDeviceNode(unittest.TestCase): 14 | def setUp(self): 15 | super().setUp() 16 | 17 | self.temp_prefix = "temp-device-" 18 | (self.fd, self.path) = tempfile.mkstemp(prefix=self.temp_prefix) 19 | self.f = os.fdopen(self.fd) 20 | self.f.seek(140000) 21 | os.write(self.fd, b"0") 22 | 23 | def tearDown(self): 24 | os.close(self.fd) 25 | 26 | if self.path and os.path.exists(self.path): 27 | os.unlink(self.path) 28 | 29 | self.fd = None 30 | self.path = None 31 | self.temp_prefix = None 32 | 33 | 34 | # Base class for any test case that requires a _ped.Device or parted.Device 35 | # object first. 36 | class RequiresDevice(RequiresDeviceNode): 37 | def setUp(self): 38 | super().setUp() 39 | self.addCleanup(self.removeDevice) 40 | self._device = _ped.device_get(self.path) 41 | self.device = parted.getDevice(self.path) 42 | 43 | def removeDevice(self): 44 | self.device = None 45 | self._device = None 46 | 47 | 48 | # Base class for any test case that requires a filesystem on a device. 49 | class RequiresFileSystem(unittest.TestCase): 50 | def setUp(self): 51 | super().setUp() 52 | 53 | self._fileSystemType = {} 54 | ty = _ped.file_system_type_get_next() 55 | self._fileSystemType[ty.name] = ty 56 | 57 | while True: 58 | try: 59 | ty = _ped.file_system_type_get_next(ty) 60 | self._fileSystemType[ty.name] = ty 61 | except (IndexError, TypeError, _ped.UnknownTypeException): 62 | break 63 | 64 | self.temp_prefix = "temp-device-" 65 | ( 66 | self.fd, 67 | self.path, 68 | ) = tempfile.mkstemp(prefix=self.temp_prefix) 69 | self.f = os.fdopen(self.fd) 70 | self.f.seek(140000) 71 | os.write(self.fd, b"0") 72 | self.f.close() 73 | 74 | os.system("mke2fs -F -q %s" % (self.path,)) 75 | 76 | self._device = _ped.device_get(self.path) 77 | self._geometry = _ped.Geometry(self._device, 0, self._device.length - 1) 78 | 79 | def tearDown(self): 80 | if self.path and os.path.exists(self.path): 81 | os.unlink(self.path) 82 | 83 | self.mountpoint = None 84 | 85 | 86 | # Base class for certain alignment tests that require a _ped.Device 87 | class RequiresDeviceAlignment(RequiresDevice): 88 | def roundDownTo(self, sector, grain_size): 89 | if sector < 0: 90 | shift = sector % grain_size + grain_size 91 | else: 92 | shift = sector % grain_size 93 | 94 | return sector - shift 95 | 96 | def roundUpTo(self, sector, grain_size): 97 | if sector % grain_size: 98 | return self.roundDownTo(sector, grain_size) + grain_size 99 | else: 100 | return sector 101 | 102 | def closestInsideGeometry(self, alignment, geometry, sector): 103 | if alignment.grain_size == 0: 104 | if alignment.is_aligned(geometry, sector) and ( 105 | (geometry is None) or geometry.test_sector_inside(sector) 106 | ): 107 | return sector 108 | else: 109 | return -1 110 | 111 | if sector < geometry.start: 112 | sector += self.roundUpTo(geometry.start - sector, alignment.grain_size) 113 | 114 | if sector > geometry.end: 115 | sector -= self.roundUpTo(sector - geometry.end, alignment.grain_size) 116 | 117 | if not geometry.test_sector_inside(sector): 118 | return -1 119 | 120 | return sector 121 | 122 | def closest(self, sector, a, b): 123 | if a == -1: 124 | return b 125 | 126 | if b == -1: 127 | return a 128 | 129 | if abs(sector - a) < abs(sector - b): 130 | return a 131 | else: 132 | return b 133 | 134 | 135 | # Base class for any test case that requires a labeled device 136 | class RequiresLabeledDevice(RequiresDevice): 137 | def setUp(self): 138 | super().setUp() 139 | os.system("parted -s %s mklabel msdos" % (self.path,)) 140 | 141 | 142 | # Base class for any test case that requires a _ped.Disk or parted.Disk. 143 | class RequiresDisk(RequiresDevice): 144 | def setUp(self): 145 | super().setUp() 146 | self._disk = _ped.disk_new_fresh(self._device, _ped.disk_type_get("msdos")) 147 | self.disk = parted.Disk(PedDisk=self._disk) 148 | 149 | def reopen(self): 150 | self._disk = _ped.disk_new(self._device) 151 | self.disk = parted.Disk(PedDisk=self._disk) 152 | 153 | 154 | # Base class for any test case that requires a GPT-labeled _ped.Disk or parted.Disk. 155 | class RequiresGPTDisk(RequiresDevice): 156 | def setUp(self): 157 | super().setUp() 158 | self._disk = _ped.disk_new_fresh(self._device, _ped.disk_type_get("gpt")) 159 | self.disk = parted.Disk(PedDisk=self._disk) 160 | 161 | def reopen(self): 162 | self._disk = _ped.disk_new(self._device) 163 | self.disk = parted.Disk(PedDisk=self._disk) 164 | 165 | 166 | # Base class for any test case that requires a filesystem made and mounted. 167 | class RequiresMount(RequiresDevice): 168 | def setUp(self): 169 | super().setUp() 170 | self.addCleanup(self.removeMountpoint) 171 | self.mountpoint = None 172 | 173 | def mkfs(self): 174 | os.system("mkfs.ext2 -F -q %s" % self.path) 175 | 176 | def doMount(self): 177 | self.mountpoint = tempfile.mkdtemp() 178 | os.system("mount -o loop %s %s" % (self.path, self.mountpoint)) 179 | 180 | def removeMountpoint(self): 181 | if self.mountpoint and os.path.exists(self.mountpoint): 182 | os.system("umount %s" % self.mountpoint) 183 | os.rmdir(self.mountpoint) 184 | 185 | 186 | # Base class for any test case that requires a _ped.Partition. 187 | class RequiresPartition(RequiresDisk): 188 | def setUp(self): 189 | super().setUp() 190 | self._part = _ped.Partition( 191 | disk=self._disk, 192 | type=_ped.PARTITION_NORMAL, 193 | start=1, 194 | end=100, 195 | fs_type=_ped.file_system_type_get("ext2"), 196 | ) 197 | 198 | def reopen(self): 199 | super().reopen() 200 | self._part = self._disk.next_partition(self._disk.next_partition()) 201 | 202 | 203 | # Base class for any test case that requires a _ped.Partition on GPT disk. 204 | class RequiresGPTPartition(RequiresGPTDisk): 205 | def setUp(self): 206 | super().setUp() 207 | self._part = _ped.Partition( 208 | disk=self._disk, 209 | type=_ped.PARTITION_NORMAL, 210 | start=0, 211 | end=100, 212 | fs_type=_ped.file_system_type_get("ext2"), 213 | ) 214 | 215 | def reopen(self): 216 | super().reopen() 217 | self._part = self._disk.next_partition() 218 | 219 | 220 | # Base class for any test case that requires a hash table of all 221 | # _ped.DiskType objects available 222 | class RequiresDiskTypes(unittest.TestCase): 223 | def setUp(self): 224 | super().setUp() 225 | self.disktype = {} 226 | ty = _ped.disk_type_get_next() 227 | self.disktype[ty.name] = ty 228 | 229 | while True: 230 | try: 231 | ty = _ped.disk_type_get_next(ty) 232 | self.disktype[ty.name] = ty 233 | except (IndexError, TypeError, _ped.UnknownTypeException): 234 | break 235 | 236 | 237 | # Base class for any test case that requires a list being built via successive 238 | # calls of some function. The function must raise IndexError when there's no 239 | # more output to add to the return list. This class is most useful for all 240 | # those _get_next methods. 241 | class BuildList: 242 | def getDeviceList(self, func): 243 | lst = [] 244 | prev = None 245 | 246 | while True: 247 | try: 248 | if not prev: 249 | prev = func() 250 | else: 251 | prev = func(prev) 252 | 253 | lst.append(prev) 254 | except IndexError: 255 | break 256 | 257 | return lst 258 | -------------------------------------------------------------------------------- /tests/pylint/runpylint.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | 5 | from pocketlint import PocketLintConfig, PocketLinter 6 | 7 | 8 | class PypartedLintConfig(PocketLintConfig): 9 | @property 10 | def extraArgs(self): 11 | return ["--extension-pkg-whitelist", "_ped"] 12 | 13 | 14 | if __name__ == "__main__": 15 | conf = PypartedLintConfig() 16 | linter = PocketLinter(conf) 17 | rc = linter.run() 18 | sys.exit(rc) 19 | -------------------------------------------------------------------------------- /tests/test__ped_chsgeometry.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright The pyparted Project Authors 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | # 5 | 6 | import _ped 7 | import unittest 8 | 9 | from tests.baseclass import RequiresDevice 10 | 11 | # One class per method, multiple tests per class. For these simple methods, 12 | # that seems like good organization. More complicated methods may require 13 | # multiple classes and their own test suite. 14 | class CHSGeometryNewTestCase(unittest.TestCase): 15 | def runTest(self): 16 | # You're not allowed to create a new CHSGeometry object by hand. 17 | self.assertRaises(TypeError, _ped.CHSGeometry) 18 | 19 | 20 | class CHSGeometryGetSetTestCase(RequiresDevice): 21 | def runTest(self): 22 | # A device has a CHSGeometry, so we can use that to attempt accessing 23 | # parameters. 24 | chs = self._device.hw_geom 25 | self.assertIsInstance(chs, _ped.CHSGeometry) 26 | 27 | # All attributes are read-only. 28 | self.assertRaises(AttributeError, setattr, chs, "cylinders", 47) 29 | self.assertRaises(AttributeError, setattr, chs, "heads", 47) 30 | self.assertRaises(AttributeError, setattr, chs, "sectors", 47) 31 | 32 | self.assertIsInstance(chs.cylinders, int) 33 | self.assertIsInstance(chs.heads, int) 34 | self.assertIsInstance(chs.sectors, int) 35 | 36 | 37 | class CHSGeometryStrTestCase(RequiresDevice): 38 | def runTest(self): 39 | expected = ( 40 | "_ped.CHSGeometry instance --\n cylinders: %d heads: %d sectors: %d" 41 | % ( 42 | self._device.hw_geom.cylinders, 43 | self._device.hw_geom.heads, 44 | self._device.hw_geom.sectors, 45 | ) 46 | ) 47 | result = str(self._device.hw_geom) 48 | self.assertEqual(result, expected) 49 | -------------------------------------------------------------------------------- /tests/test__ped_disk.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright The pyparted Project Authors 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | # 5 | 6 | import _ped 7 | import unittest 8 | 9 | from tests.baseclass import RequiresDevice, RequiresLabeledDevice, RequiresDisk 10 | 11 | # One class per method, multiple tests per class. For these simple methods, 12 | # that seems like good organization. More complicated methods may require 13 | # multiple classes and their own test suite. 14 | class DiskNewUnlabeledTestCase(RequiresDevice): 15 | def runTest(self): 16 | self.assertRaises(_ped.DiskLabelException, _ped.Disk, self._device) 17 | 18 | 19 | class DiskNewLabeledTestCase(RequiresLabeledDevice): 20 | def runTest(self): 21 | result = _ped.Disk(self._device) 22 | self.assertIsInstance(result, _ped.Disk) 23 | self.assertEqual(result.type.name, "msdos") 24 | 25 | 26 | @unittest.skip("Unimplemented test case.") 27 | class DiskGetSetTestCase(unittest.TestCase): 28 | # TODO 29 | def runTest(self): 30 | self.fail("Unimplemented test case.") 31 | 32 | 33 | @unittest.skip("Unimplemented test case.") 34 | class DiskClobberTestCase(unittest.TestCase): 35 | # TODO 36 | def runTest(self): 37 | self.fail("Unimplemented test case.") 38 | 39 | 40 | @unittest.skip("Unimplemented test case.") 41 | class DiskClobberExcludeTestCase(unittest.TestCase): 42 | # TODO 43 | def runTest(self): 44 | self.fail("Unimplemented test case.") 45 | 46 | 47 | @unittest.skip("Unimplemented test case.") 48 | class DiskDuplicateTestCase(unittest.TestCase): 49 | # TODO 50 | def runTest(self): 51 | self.fail("Unimplemented test case.") 52 | 53 | 54 | @unittest.skip("Unimplemented test case.") 55 | class DiskDestroyTestCase(unittest.TestCase): 56 | # TODO 57 | def runTest(self): 58 | self.fail("Unimplemented test case.") 59 | 60 | 61 | class DiskCommitTestCase(RequiresDisk): 62 | def runTest(self): 63 | self.assertTrue(self._disk.commit()) 64 | 65 | 66 | class DiskCommitToDevTestCase(RequiresDisk): 67 | def runTest(self): 68 | self.assertTrue(self._disk.commit_to_dev()) 69 | 70 | 71 | class DiskCommitToOsTestCase(RequiresDisk): 72 | def runTest(self): 73 | self.assertTrue(self._disk.commit_to_os()) 74 | 75 | 76 | class DiskCheckTestCase(RequiresDisk): 77 | def runTest(self): 78 | self.assertTrue(self._disk.check()) 79 | 80 | 81 | @unittest.skip("Unimplemented test case.") 82 | class DiskPrintTestCase(unittest.TestCase): 83 | # TODO 84 | def runTest(self): 85 | self.fail("Unimplemented test case.") 86 | 87 | 88 | class DiskGetPrimaryPartitionCountTestCase(RequiresDisk): 89 | def runTest(self): 90 | # XXX: this could probably test more 91 | self.assertEqual(self._disk.get_primary_partition_count(), 0) 92 | 93 | 94 | class DiskGetLastPartitionNumTestCase(RequiresDisk): 95 | def runTest(self): 96 | # XXX: this could probably test more 97 | self.assertEqual(self._disk.get_last_partition_num(), -1) 98 | 99 | 100 | class DiskGetMaxPrimaryPartitionCountTestCase(RequiresDisk): 101 | def runTest(self): 102 | self.assertEqual(self._disk.get_max_primary_partition_count(), 4) 103 | 104 | 105 | class DiskGetMaxSupportedPartitionCountTestCase(RequiresDisk): 106 | def runTest(self): 107 | self.assertEqual(self._disk.get_max_supported_partition_count(), 64) 108 | 109 | 110 | class DiskGetPartitionAlignmentTestCase(RequiresDisk): 111 | def runTest(self): 112 | alignment = self._disk.get_partition_alignment() 113 | self.assertIsInstance(alignment, _ped.Alignment) 114 | # These 2 tests assume an MSDOS label as given by RequiresDisk 115 | self.assertEqual(alignment.offset, 0) 116 | self.assertEqual(alignment.grain_size, 1) 117 | 118 | 119 | class DiskMaxPartitionLengthTestCase(RequiresDisk): 120 | def runTest(self): 121 | # This test assumes an MSDOS label as given by RequiresDisk 122 | self.assertEqual(self._disk.max_partition_length(), 4294967295) 123 | 124 | 125 | class DiskMaxPartitionStartSectorTestCase(RequiresDisk): 126 | def runTest(self): 127 | # This test assumes an MSDOS label as given by RequiresDisk 128 | self.assertEqual(self._disk.max_partition_start_sector(), 4294967295) 129 | 130 | 131 | class DiskSetFlagTestCase(RequiresDisk): 132 | def runTest(self): 133 | # These 2 tests assume an MSDOS label as given by RequiresDisk 134 | self._disk.set_flag(_ped.DISK_CYLINDER_ALIGNMENT, 1) 135 | self.assertEqual(self._disk.get_flag(_ped.DISK_CYLINDER_ALIGNMENT), True) 136 | self._disk.set_flag(_ped.DISK_CYLINDER_ALIGNMENT, 0) 137 | self.assertEqual(self._disk.get_flag(_ped.DISK_CYLINDER_ALIGNMENT), False) 138 | 139 | 140 | class DiskGetFlagTestCase(RequiresDisk): 141 | def runTest(self): 142 | flag = self._disk.get_flag(_ped.DISK_CYLINDER_ALIGNMENT) 143 | self.assertIsInstance(flag, bool) 144 | 145 | 146 | class DiskIsFlagAvailableTestCase(RequiresDisk): 147 | def runTest(self): 148 | # We don't know which flags should be available and which shouldn't, 149 | # but we can at least check that there aren't any tracebacks from 150 | # trying all of the valid ones. 151 | for flag in [_ped.DISK_CYLINDER_ALIGNMENT, _ped.DISK_GPT_PMBR_BOOT]: 152 | self.assertIsInstance(self._disk.is_flag_available(flag), bool) 153 | 154 | # However, an invalid flag should definitely not be available. 155 | self.assertFalse(self._disk.is_flag_available(1000)) 156 | 157 | 158 | @unittest.skip("Unimplemented test case.") 159 | class DiskAddPartitionTestCase(unittest.TestCase): 160 | # TODO 161 | def runTest(self): 162 | self.fail("Unimplemented test case.") 163 | 164 | 165 | @unittest.skip("Unimplemented test case.") 166 | class DiskRemovePartitionTestCase(unittest.TestCase): 167 | # TODO 168 | def runTest(self): 169 | self.fail("Unimplemented test case.") 170 | 171 | 172 | @unittest.skip("Unimplemented test case.") 173 | class DiskDeletePartitionTestCase(unittest.TestCase): 174 | # TODO 175 | def runTest(self): 176 | self.fail("Unimplemented test case.") 177 | 178 | 179 | @unittest.skip("Unimplemented test case.") 180 | class DiskDeleteAllTestCase(unittest.TestCase): 181 | # TODO 182 | def runTest(self): 183 | self.fail("Unimplemented test case.") 184 | 185 | 186 | @unittest.skip("Unimplemented test case.") 187 | class DiskSetPartitionGeomTestCase(unittest.TestCase): 188 | # TODO 189 | def runTest(self): 190 | self.fail("Unimplemented test case.") 191 | 192 | 193 | @unittest.skip("Unimplemented test case.") 194 | class DiskMaxmimzePartitionTestCase(unittest.TestCase): 195 | # TODO 196 | def runTest(self): 197 | self.fail("Unimplemented test case.") 198 | 199 | 200 | @unittest.skip("Unimplemented test case.") 201 | class DiskGetMaxPartitionGeoemtryTestCase(unittest.TestCase): 202 | # TODO 203 | def runTest(self): 204 | self.fail("Unimplemented test case.") 205 | 206 | 207 | @unittest.skip("Unimplemented test case.") 208 | class DiskMinimizeExtendedPartitionTestCase(unittest.TestCase): 209 | # TODO 210 | def runTest(self): 211 | self.fail("Unimplemented test case.") 212 | 213 | 214 | @unittest.skip("Unimplemented test case.") 215 | class DiskNextPartitionTestCase(unittest.TestCase): 216 | # TODO 217 | def runTest(self): 218 | self.fail("Unimplemented test case.") 219 | 220 | 221 | @unittest.skip("Unimplemented test case.") 222 | class DiskGetPartitionTestCase(unittest.TestCase): 223 | # TODO 224 | def runTest(self): 225 | self.fail("Unimplemented test case.") 226 | 227 | 228 | @unittest.skip("Unimplemented test case.") 229 | class DiskGetPartitionBySectorTestCase(unittest.TestCase): 230 | # TODO 231 | def runTest(self): 232 | self.fail("Unimplemented test case.") 233 | 234 | 235 | class DiskExtendedPartitionTestCase(RequiresDisk): 236 | def runTest(self): 237 | self.assertRaises(_ped.PartitionException, self._disk.extended_partition) 238 | 239 | 240 | class DiskStrTestCase(RequiresDisk): 241 | def runTest(self): 242 | expected = "_ped.Disk instance --\n dev: %s type: %s" % ( 243 | repr(self._disk.dev), 244 | repr(self._disk.type), 245 | ) 246 | self.assertEqual(expected, str(self._disk)) 247 | -------------------------------------------------------------------------------- /tests/test__ped_disktype.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright The pyparted Project Authors 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | # 5 | 6 | import _ped 7 | import sys 8 | import unittest 9 | from tests.baseclass import RequiresDiskTypes 10 | 11 | # One class per method, multiple tests per class. For these simple methods, 12 | # that seems like good organization. More complicated methods may require 13 | # multiple classes and their own test suite. 14 | class DiskTypeNewTestCase(unittest.TestCase): 15 | def runTest(self): 16 | # You're not allowed to create a new DiskType object by hand. 17 | self.assertRaises(TypeError, _ped.DiskType) 18 | 19 | 20 | class DiskTypeGetSetTestCase(RequiresDiskTypes): 21 | def runTest(self): 22 | # All attributes are read-only. 23 | for name in self.disktype.keys(): 24 | t = self.disktype[name] 25 | 26 | self.assertRaises(AttributeError, setattr, t, "name", "fakename") 27 | self.assertRaises(AttributeError, setattr, t, "features", 47) 28 | 29 | if sys.version_info >= (3,): 30 | bigint = int 31 | uni = str 32 | else: 33 | bigint = long # pylint: disable=undefined-variable 34 | uni = unicode # pylint: disable=undefined-variable 35 | self.assertIsInstance(t.name, uni) 36 | self.assertEqual(t.name, name) 37 | self.assertIsInstance(t.features, bigint) 38 | 39 | 40 | class DiskTypeCheckFeatureTestCase(RequiresDiskTypes): 41 | def runTest(self): 42 | # The following types have no features [that libparted supports] 43 | for name in ["aix", "sun", "bsd", "loop"]: 44 | self.assertFalse(self.disktype[name].check_feature(_ped.DISK_TYPE_EXTENDED)) 45 | self.assertFalse( 46 | self.disktype[name].check_feature(_ped.DISK_TYPE_PARTITION_NAME) 47 | ) 48 | 49 | # The following types support DISK_TYPE_EXTENDED 50 | for name in ["msdos"]: 51 | self.assertTrue(self.disktype[name].check_feature(_ped.DISK_TYPE_EXTENDED)) 52 | self.assertFalse( 53 | self.disktype[name].check_feature(_ped.DISK_TYPE_PARTITION_NAME) 54 | ) 55 | 56 | if hasattr(_ped, "DISK_TYPE_PARTITION_TYPE_ID"): 57 | self.assertTrue( 58 | self.disktype[name].check_feature(_ped.DISK_TYPE_PARTITION_TYPE_ID) 59 | ) 60 | 61 | if hasattr(_ped, "DISK_TYPE_PARTITION_TYPE_UUID"): 62 | self.assertFalse( 63 | self.disktype[name].check_feature( 64 | _ped.DISK_TYPE_PARTITION_TYPE_UUID 65 | ) 66 | ) 67 | 68 | if hasattr(_ped, "DISK_TYPE_DISK_UUID"): 69 | self.assertFalse( 70 | self.disktype[name].check_feature(_ped.DISK_TYPE_DISK_UUID) 71 | ) 72 | 73 | if hasattr(_ped, "DISK_TYPE_PARTITION_UUID"): 74 | self.assertFalse( 75 | self.disktype[name].check_feature(_ped.DISK_TYPE_PARTITION_UUID) 76 | ) 77 | 78 | # The following types support DISK_TYPE_PARTITION_NAME 79 | for name in ["amiga", "gpt", "mac", "pc98"]: 80 | self.assertFalse(self.disktype[name].check_feature(_ped.DISK_TYPE_EXTENDED)) 81 | self.assertTrue( 82 | self.disktype[name].check_feature(_ped.DISK_TYPE_PARTITION_NAME) 83 | ) 84 | 85 | # The following types support DISK_TYPE_PARTITION_TYPE_UUID 86 | for name in ["gpt"]: 87 | if hasattr(_ped, "DISK_TYPE_PARTITION_TYPE_UUID"): 88 | self.assertTrue( 89 | self.disktype[name].check_feature( 90 | _ped.DISK_TYPE_PARTITION_TYPE_UUID 91 | ) 92 | ) 93 | 94 | if hasattr(_ped, "DISK_TYPE_DISK_UUID"): 95 | self.assertTrue( 96 | self.disktype[name].check_feature(_ped.DISK_TYPE_DISK_UUID) 97 | ) 98 | 99 | if hasattr(_ped, "DISK_TYPE_PARTITION_UUID"): 100 | self.assertTrue( 101 | self.disktype[name].check_feature(_ped.DISK_TYPE_PARTITION_UUID) 102 | ) 103 | 104 | # The following types support all features 105 | for name in ["dvh"]: 106 | self.assertTrue(self.disktype[name].check_feature(_ped.DISK_TYPE_EXTENDED)) 107 | self.assertTrue( 108 | self.disktype[name].check_feature(_ped.DISK_TYPE_PARTITION_NAME) 109 | ) 110 | 111 | 112 | class DiskTypeStrTestCase(RequiresDiskTypes): 113 | def runTest(self): 114 | types = { 115 | "msdos": "_ped.DiskType instance --\n name: msdos features:", 116 | "aix": "_ped.DiskType instance --\n name: aix features: ", 117 | "sun": "_ped.DiskType instance --\n name: sun features: ", 118 | "amiga": "_ped.DiskType instance --\n name: amiga features: ", 119 | "gpt": "_ped.DiskType instance --\n name: gpt features: ", 120 | "mac": "_ped.DiskType instance --\n name: mac features: ", 121 | "bsd": "_ped.DiskType instance --\n name: bsd features: ", 122 | "pc98": "_ped.DiskType instance --\n name: pc98 features: ", 123 | "loop": "_ped.DiskType instance --\n name: loop features: ", 124 | "dvh": "_ped.DiskType instance --\n name: dvh features: ", 125 | } 126 | 127 | for t, expected in types.items(): 128 | self.assertIn(expected, str(self.disktype[t])) 129 | -------------------------------------------------------------------------------- /tests/test__ped_filesystem.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright The pyparted Project Authors 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | # 5 | 6 | import sys 7 | import _ped 8 | from tests.baseclass import RequiresFileSystem 9 | 10 | # One class per method, multiple tests per class. For these simple methods, 11 | # that seems like good organization. More complicated methods may require 12 | # multiple classes and their own test suite. 13 | class FileSystemNewTestCase(RequiresFileSystem): 14 | def runTest(self): 15 | fstype = _ped.file_system_type_get("ext2") 16 | 17 | with self.assertRaises(TypeError): 18 | _ped.FileSystem(type=None, geom=None) 19 | _ped.FileSystem(type=fstype, geom=None) 20 | 21 | fs = _ped.FileSystem(type=fstype, geom=self._geometry) 22 | self.assertIsInstance(fs, _ped.FileSystem) 23 | 24 | 25 | class FileSystemGetSetTestCase(RequiresFileSystem): 26 | def runTest(self): 27 | fstype = _ped.file_system_type_get("ext2") 28 | fs = _ped.FileSystem(type=fstype, geom=self._geometry) 29 | 30 | self.assertIsInstance(fs, _ped.FileSystem) 31 | self.assertEqual(fs.type, fstype) 32 | self.assertEqual(getattr(fs, "type"), fstype) 33 | # read-only attribute 34 | if sys.version_info[0] == 3: 35 | self.assertRaises(AttributeError, setattr, fs, "type", fstype) 36 | else: 37 | self.assertRaises(TypeError, setattr, fs, "type", fstype) 38 | self.assertRaises(AttributeError, getattr, fs, "junk") 39 | 40 | 41 | class FileSystemStrTestCase(RequiresFileSystem): 42 | def runTest(self): 43 | fstype = _ped.file_system_type_get("ext2") 44 | fs = _ped.FileSystem(type=fstype, geom=self._geometry) 45 | # don't use assertEqual b/c __str__ includes memory addresses of 46 | # fstype and geom objects. This is easier. 47 | self.assertTrue(str(fs).startswith("_ped.FileSystem instance --")) 48 | -------------------------------------------------------------------------------- /tests/test__ped_filesystemtype.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright The pyparted Project Authors 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | # 5 | 6 | import _ped 7 | import unittest 8 | 9 | # One class per method, multiple tests per class. For these simple methods, 10 | # that seems like good organization. More complicated methods may require 11 | # multiple classes and their own test suite. 12 | class FileSystemTypeNewTestCase(unittest.TestCase): 13 | def runTest(self): 14 | # You can't create a FileSystemType by hand. 15 | self.assertRaises(TypeError, _ped.FileSystemType) 16 | 17 | 18 | class FileSystemTypeGetSetTestCase(unittest.TestCase): 19 | def runTest(self): 20 | fstype = _ped.file_system_type_get("ext3") 21 | 22 | self.assertIsInstance(fstype, _ped.FileSystemType) 23 | self.assertEqual(fstype.name, "ext3") 24 | self.assertEqual(getattr(fstype, "name"), "ext3") 25 | self.assertRaises(AttributeError, setattr, fstype, "name", "vfat") 26 | self.assertRaises(AttributeError, getattr, fstype, "junk") 27 | 28 | 29 | class FileSystemTypeStrTestCase(unittest.TestCase): 30 | def runTest(self): 31 | fstype = _ped.file_system_type_get("ext3") 32 | 33 | self.assertEqual(str(fstype), "_ped.FileSystemType instance --\n name: ext3") 34 | -------------------------------------------------------------------------------- /tests/test_parted_alignment.py: -------------------------------------------------------------------------------- 1 | # 2 | # Test cases for the methods in the parted.alignment module itself 3 | # 4 | # Copyright The pyparted Project Authors 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | # 7 | 8 | import _ped 9 | import parted 10 | import unittest 11 | from tests.baseclass import RequiresDevice 12 | 13 | # One class per method, multiple tests per class. For these simple methods, 14 | # that seems like good organization. More complicated methods may require 15 | # multiple classes and their own test suite. 16 | class AlignmentNewTestCase(unittest.TestCase): 17 | def setUp(self): 18 | super().setUp() 19 | self.pa = _ped.Alignment(0, 100) 20 | 21 | def runTest(self): 22 | # Check that not passing args to parted.Alignment.__init__ is caught. 23 | self.assertRaises(parted.AlignmentException, parted.Alignment) 24 | 25 | # And then the correct ways of creating a parted.Alignment 26 | a = parted.Alignment(offset=0, grainSize=100) 27 | self.assertIsInstance(a, parted.Alignment) 28 | 29 | b = parted.Alignment(PedAlignment=self.pa) 30 | self.assertIsInstance(b, parted.Alignment) 31 | 32 | # Test for _ped.Alignment equality 33 | self.assertEqual(b.getPedAlignment(), self.pa) 34 | 35 | 36 | class AlignmentGetSetTestCase(unittest.TestCase): 37 | def setUp(self): 38 | super().setUp() 39 | self.a = parted.Alignment(offset=27, grainSize=49) 40 | 41 | def runTest(self): 42 | # Test that passing the args to __init__ works. 43 | self.assertIsInstance(self.a, parted.Alignment) 44 | self.assertEqual(self.a.offset, 27) 45 | self.assertEqual(self.a.grainSize, 49) 46 | 47 | # Test that setting directly and getting with getattr works. 48 | self.a.offset = 10 49 | self.a.grainSize = 90 50 | 51 | self.assertEqual(getattr(self.a, "offset"), 10) 52 | self.assertEqual(getattr(self.a, "grainSize"), 90) 53 | 54 | # Check that setting with setattr and getting directly works. 55 | setattr(self.a, "offset", 20) 56 | setattr(self.a, "grainSize", 80) 57 | 58 | self.assertEqual(self.a.offset, 20) 59 | self.assertEqual(self.a.grainSize, 80) 60 | 61 | # Check that values have the right type. 62 | self.assertRaises(TypeError, setattr, self.a, "offset", "string") 63 | 64 | # Check that looking for invalid attributes fails properly. 65 | self.assertRaises(AttributeError, getattr, self.a, "blah") 66 | 67 | 68 | @unittest.skip("Unimplemented test case.") 69 | class AlignmentIntersectTestCase(unittest.TestCase): 70 | def runTest(self): 71 | # TODO 72 | self.fail("Unimplemented test case.") 73 | 74 | 75 | @unittest.skip("Unimplemented test case.") 76 | class AlignmentAlignUpTestCase(unittest.TestCase): 77 | def runTest(self): 78 | # TODO 79 | self.fail("Unimplemented test case.") 80 | 81 | 82 | @unittest.skip("Unimplemented test case.") 83 | class AlignmentAlignDownTestCase(unittest.TestCase): 84 | def runTest(self): 85 | # TODO 86 | self.fail("Unimplemented test case.") 87 | 88 | 89 | @unittest.skip("Unimplemented test case.") 90 | class AlignmentAlignNearestTestCase(unittest.TestCase): 91 | def runTest(self): 92 | # TODO 93 | self.fail("Unimplemented test case.") 94 | 95 | 96 | class AlignmentIsAlignedTestCase(RequiresDevice): 97 | def setUp(self): 98 | super().setUp() 99 | self.g = parted.Geometry(device=self.device, start=0, length=100) 100 | self.a = parted.Alignment(offset=10, grainSize=0) 101 | 102 | def runTest(self): 103 | # Test a couple ways of passing bad arguments. 104 | self.assertRaises(TypeError, self.a.isAligned, None, 12) 105 | self.assertRaises(TypeError, self.a.isAligned, self.g, None) 106 | 107 | # Sector must be inside the geometry. 108 | self.assertFalse(self.a.isAligned(self.g, 400)) 109 | 110 | # If grain_size is 0, sector must be the same as offset. 111 | self.assertTrue(self.a.isAligned(self.g, 10)) 112 | self.assertFalse(self.a.isAligned(self.g, 0)) 113 | self.assertFalse(self.a.isAligned(self.g, 47)) 114 | 115 | # If grain_size is anything else, there's real math involved. 116 | self.a.grainSize = 5 117 | self.assertTrue(self.a.isAligned(self.g, 20)) 118 | self.assertFalse(self.a.isAligned(self.g, 23)) 119 | 120 | 121 | class AlignmentGetPedAlignmentTestCase(unittest.TestCase): 122 | def setUp(self): 123 | super().setUp() 124 | self.pa = _ped.Alignment(0, 100) 125 | self.alignment = parted.Alignment(PedAlignment=self.pa) 126 | 127 | def runTest(self): 128 | # Test to make sure we get a _ped.Alignment 129 | self.assertIsInstance(self.alignment.getPedAlignment(), _ped.Alignment) 130 | 131 | # Test for _ped.Alignment equality 132 | self.assertEqual(self.alignment.getPedAlignment(), self.pa) 133 | 134 | 135 | @unittest.skip("Unimplemented test case.") 136 | class AlignmentStrTestCase(unittest.TestCase): 137 | def runTest(self): 138 | # TODO 139 | self.fail("Unimplemented test case.") 140 | -------------------------------------------------------------------------------- /tests/test_parted_constraint.py: -------------------------------------------------------------------------------- 1 | # 2 | # Test cases for the methods in the parted.constraint module itself 3 | # 4 | # Copyright The pyparted Project Authors 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | # 7 | 8 | import _ped 9 | import parted 10 | import unittest 11 | from tests.baseclass import RequiresDevice 12 | 13 | # One class per method, multiple tests per class. For these simple methods, 14 | # that seems like good organization. More complicated methods may require 15 | # multiple classes and their own test suite. 16 | class ConstraintNewTestCase(RequiresDevice): 17 | def runTest(self): 18 | align1 = parted.Alignment(offset=10, grainSize=5) 19 | align2 = parted.Alignment(offset=10, grainSize=5) 20 | geom1 = parted.Geometry(device=self.device, start=0, length=50) 21 | geom2 = parted.Geometry(device=self.device, start=0, length=100) 22 | 23 | # Check that not passing enough args to parted.Constraint.__init__ 24 | # is caught. 25 | self.assertRaises(parted.ConstraintException, parted.Constraint) 26 | self.assertRaises( 27 | parted.ConstraintException, 28 | parted.Constraint, 29 | startAlign=align1, 30 | endAlign=align2, 31 | ) 32 | 33 | # And then the correct ways of creating a _ped.Constraint. 34 | c = parted.Constraint(minGeom=geom1, maxGeom=geom2) 35 | self.assertIsInstance(c, parted.Constraint) 36 | 37 | c = parted.Constraint(minGeom=geom1) 38 | self.assertIsInstance(c, parted.Constraint) 39 | 40 | c = parted.Constraint(maxGeom=geom2) 41 | self.assertIsInstance(c, parted.Constraint) 42 | 43 | c = parted.Constraint(exactGeom=geom1) 44 | self.assertIsInstance(c, parted.Constraint) 45 | 46 | c = parted.Constraint(device=self.device) 47 | self.assertIsInstance(c, parted.Constraint) 48 | 49 | c = parted.Constraint( 50 | startAlign=align1, 51 | endAlign=align2, 52 | startRange=geom1, 53 | endRange=geom2, 54 | minSize=10, 55 | maxSize=100, 56 | ) 57 | self.assertIsInstance(c, parted.Constraint) 58 | 59 | # Use a _ped.Constraint as the initializer 60 | pc = _ped.Constraint( 61 | align1.getPedAlignment(), 62 | align2.getPedAlignment(), 63 | geom1.getPedGeometry(), 64 | geom2.getPedGeometry(), 65 | 10, 66 | 100, 67 | ) 68 | c = parted.Constraint(PedConstraint=pc) 69 | self.assertIsInstance(c, parted.Constraint) 70 | self.assertEqual(c.getPedConstraint(), pc) 71 | 72 | 73 | class ConstraintGetSetTestCase(RequiresDevice): 74 | def setUp(self): 75 | super().setUp() 76 | align1 = parted.Alignment(offset=10, grainSize=5) 77 | align2 = parted.Alignment(offset=10, grainSize=5) 78 | geom1 = parted.Geometry(device=self.device, start=0, length=50) 79 | geom2 = parted.Geometry(device=self.device, start=25, length=50) 80 | 81 | self.c = parted.Constraint( 82 | startAlign=align1, 83 | endAlign=align2, 84 | startRange=geom1, 85 | endRange=geom2, 86 | minSize=10, 87 | maxSize=100, 88 | ) 89 | 90 | def runTest(self): 91 | # Test that properties work 92 | self.assertEqual(self.c.minSize, 10) 93 | self.assertEqual(self.c.maxSize, 100) 94 | self.assertIsInstance(self.c.startAlign, parted.Alignment) 95 | self.assertIsInstance(self.c.endAlign, parted.Alignment) 96 | self.assertIsInstance(self.c.startRange, parted.Geometry) 97 | self.assertIsInstance(self.c.endRange, parted.Geometry) 98 | 99 | # Test that setting directly and getting with getattr works. 100 | self.c.minSize = 15 101 | self.c.maxSize = 75 102 | 103 | self.assertEqual(getattr(self.c, "minSize"), 15) 104 | self.assertEqual(getattr(self.c, "maxSize"), 75) 105 | self.assertIsInstance(getattr(self.c, "startAlign"), parted.Alignment) 106 | self.assertIsInstance(getattr(self.c, "endAlign"), parted.Alignment) 107 | self.assertIsInstance(getattr(self.c, "startRange"), parted.Geometry) 108 | self.assertIsInstance(getattr(self.c, "endRange"), parted.Geometry) 109 | 110 | # Test that setting with setattr and getting directly works. 111 | setattr(self.c, "minSize", 10) 112 | setattr(self.c, "maxSize", 90) 113 | 114 | self.assertEqual(self.c.minSize, 10) 115 | self.assertEqual(self.c.maxSize, 90) 116 | 117 | # Test that values have the right type. 118 | self.assertRaises(TypeError, setattr, self.c, "minSize", "string") 119 | 120 | # Test that looking for invalid attributes fails properly. 121 | self.assertRaises(AttributeError, getattr, self.c, "blah") 122 | 123 | self.assertRaises(AttributeError, setattr, self.c, "startRange", 47) 124 | self.assertRaises(AttributeError, setattr, self.c, "endRange", 47) 125 | 126 | 127 | @unittest.skip("Unimplemented test case.") 128 | class ConstraintIntersectTestCase(unittest.TestCase): 129 | def runTest(self): 130 | # TODO 131 | self.fail("Unimplemented test case.") 132 | 133 | 134 | @unittest.skip("Unimplemented test case.") 135 | class ConstraintSolveMaxTestCase(unittest.TestCase): 136 | def runTest(self): 137 | # TODO 138 | self.fail("Unimplemented test case.") 139 | 140 | 141 | @unittest.skip("Unimplemented test case.") 142 | class ConstraintSolveNearestTestCase(unittest.TestCase): 143 | def runTest(self): 144 | # TODO 145 | self.fail("Unimplemented test case.") 146 | 147 | 148 | @unittest.skip("Unimplemented test case.") 149 | class ConstraintIsSolutionTestCase(unittest.TestCase): 150 | def runTest(self): 151 | # TODO 152 | self.fail("Unimplemented test case.") 153 | 154 | 155 | @unittest.skip("Unimplemented test case.") 156 | class ConstraintGetPedConstraintTestCase(unittest.TestCase): 157 | def runTest(self): 158 | # TODO 159 | self.fail("Unimplemented test case.") 160 | 161 | 162 | @unittest.skip("Unimplemented test case.") 163 | class ConstraintStrTestCase(unittest.TestCase): 164 | def runTest(self): 165 | # TODO 166 | self.fail("Unimplemented test case.") 167 | -------------------------------------------------------------------------------- /tests/test_parted_device.py: -------------------------------------------------------------------------------- 1 | # 2 | # Test cases for the methods in the parted.device module itself 3 | # 4 | # Copyright The pyparted Project Authors 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | # 7 | 8 | import unittest 9 | from tests.baseclass import RequiresDevice 10 | 11 | # One class per method, multiple tests per class. For these simple methods, 12 | # that seems like good organization. More complicated methods may require 13 | # multiple classes and their own test suite. 14 | @unittest.skip("Unimplemented test case.") 15 | class DeviceNewTestCase(unittest.TestCase): 16 | def runTest(self): 17 | # TODO 18 | self.fail("Unimplemented test case.") 19 | 20 | 21 | @unittest.skip("Unimplemented test case.") 22 | class DeviceGetSetTestCase(unittest.TestCase): 23 | def runTest(self): 24 | # TODO 25 | self.fail("Unimplemented test case.") 26 | 27 | 28 | @unittest.skip("Unimplemented test case.") 29 | class DeviceOpenTestCase(unittest.TestCase): 30 | def runTest(self): 31 | # TODO 32 | self.fail("Unimplemented test case.") 33 | 34 | 35 | @unittest.skip("Unimplemented test case.") 36 | class DeviceCloseTestCase(unittest.TestCase): 37 | def runTest(self): 38 | # TODO 39 | self.fail("Unimplemented test case.") 40 | 41 | 42 | @unittest.skip("Unimplemented test case.") 43 | class DeviceDestroyTestCase(unittest.TestCase): 44 | def runTest(self): 45 | # TODO 46 | self.fail("Unimplemented test case.") 47 | 48 | 49 | @unittest.skip("Unimplemented test case.") 50 | class DeviceRemoveFromCacheTestCase(unittest.TestCase): 51 | def runTest(self): 52 | # TODO 53 | self.fail("Unimplemented test case.") 54 | 55 | 56 | @unittest.skip("Unimplemented test case.") 57 | class DeviceBeginExternalAccessTestCase(unittest.TestCase): 58 | def runTest(self): 59 | # TODO 60 | self.fail("Unimplemented test case.") 61 | 62 | 63 | @unittest.skip("Unimplemented test case.") 64 | class DeviceEndExternalAccessTestCase(unittest.TestCase): 65 | def runTest(self): 66 | # TODO 67 | self.fail("Unimplemented test case.") 68 | 69 | 70 | @unittest.skip("Unimplemented test case.") 71 | class DeviceReadTestCase(unittest.TestCase): 72 | def runTest(self): 73 | # TODO 74 | self.fail("Unimplemented test case.") 75 | 76 | 77 | @unittest.skip("Unimplemented test case.") 78 | class DeviceWriteTestCase(unittest.TestCase): 79 | def runTest(self): 80 | # TODO 81 | self.fail("Unimplemented test case.") 82 | 83 | 84 | @unittest.skip("Unimplemented test case.") 85 | class DeviceSyncTestCase(unittest.TestCase): 86 | def runTest(self): 87 | # TODO 88 | self.fail("Unimplemented test case.") 89 | 90 | 91 | @unittest.skip("Unimplemented test case.") 92 | class DeviceCheckTestCase(unittest.TestCase): 93 | def runTest(self): 94 | # TODO 95 | self.fail("Unimplemented test case.") 96 | 97 | 98 | @unittest.skip("Unimplemented test case.") 99 | class DeviceStartSectorToCylinderTestCase(unittest.TestCase): 100 | def runTest(self): 101 | # TODO 102 | self.fail("Unimplemented test case.") 103 | 104 | 105 | @unittest.skip("Unimplemented test case.") 106 | class DeviceEndSectorToCylinderTestCase(unittest.TestCase): 107 | def runTest(self): 108 | # TODO 109 | self.fail("Unimplemented test case.") 110 | 111 | 112 | @unittest.skip("Unimplemented test case.") 113 | class DeviceStartCylinderToSectorTestCase(unittest.TestCase): 114 | def runTest(self): 115 | # TODO 116 | self.fail("Unimplemented test case.") 117 | 118 | 119 | @unittest.skip("Unimplemented test case.") 120 | class DeviceEndCylinderToSectorTestCase(unittest.TestCase): 121 | def runTest(self): 122 | # TODO 123 | self.fail("Unimplemented test case.") 124 | 125 | 126 | @unittest.skip("Unimplemented test case.") 127 | class DeviceGetSizeTestCase(unittest.TestCase): 128 | def runTest(self): 129 | # TODO 130 | self.fail("Unimplemented test case.") 131 | 132 | 133 | class DeviceGetLengthTestCase(RequiresDevice): 134 | def runTest(self): 135 | self.assertEqual(self.device.getLength(), self.device.length) 136 | 137 | 138 | @unittest.skip("Unimplemented test case.") 139 | class DeviceGetSizeAsSectorsTestCase(unittest.TestCase): 140 | def runTest(self): 141 | # TODO 142 | self.fail("Unimplemented test case.") 143 | 144 | 145 | @unittest.skip("Unimplemented test case.") 146 | class DeviceGetConstraintTestCase(unittest.TestCase): 147 | def runTest(self): 148 | # TODO 149 | self.fail("Unimplemented test case.") 150 | 151 | 152 | @unittest.skip("Unimplemented test case.") 153 | class DeviceGetPedDeviceTestCase(unittest.TestCase): 154 | def runTest(self): 155 | # TODO 156 | self.fail("Unimplemented test case.") 157 | 158 | 159 | @unittest.skip("Unimplemented test case.") 160 | class DeviceStrTestCase(unittest.TestCase): 161 | def runTest(self): 162 | # TODO 163 | self.fail("Unimplemented test case.") 164 | -------------------------------------------------------------------------------- /tests/test_parted_disk.py: -------------------------------------------------------------------------------- 1 | # 2 | # Test cases for the methods in the parted.disk module itself 3 | # 4 | # Copyright The pyparted Project Authors 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | # 7 | 8 | import parted 9 | import unittest 10 | 11 | from tests.baseclass import RequiresDisk 12 | 13 | # One class per method, multiple tests per class. For these simple methods, 14 | # that seems like good organization. More complicated methods may require 15 | # multiple classes and their own test suite. 16 | @unittest.skip("Unimplemented test case.") 17 | class DiskNewTestCase(unittest.TestCase): 18 | def runTest(self): 19 | # TODO 20 | self.fail("Unimplemented test case.") 21 | 22 | 23 | @unittest.skip("Unimplemented test case.") 24 | class DiskGetSetTestCase(unittest.TestCase): 25 | def runTest(self): 26 | # TODO 27 | self.fail("Unimplemented test case.") 28 | 29 | 30 | @unittest.skip("Unimplemented test case.") 31 | class DiskClobberTestCase(unittest.TestCase): 32 | def runTest(self): 33 | # TODO 34 | self.fail("Unimplemented test case.") 35 | 36 | 37 | @unittest.skip("Unimplemented test case.") 38 | class DiskDuplicateTestCase(unittest.TestCase): 39 | def runTest(self): 40 | # TODO 41 | self.fail("Unimplemented test case.") 42 | 43 | 44 | @unittest.skip("Unimplemented test case.") 45 | class DiskDestroyTestCase(unittest.TestCase): 46 | def runTest(self): 47 | # TODO 48 | self.fail("Unimplemented test case.") 49 | 50 | 51 | @unittest.skip("Unimplemented test case.") 52 | class DiskCommitTestCase(unittest.TestCase): 53 | def runTest(self): 54 | # TODO 55 | self.fail("Unimplemented test case.") 56 | 57 | 58 | @unittest.skip("Unimplemented test case.") 59 | class DiskCommitToDeviceTestCase(unittest.TestCase): 60 | def runTest(self): 61 | # TODO 62 | self.fail("Unimplemented test case.") 63 | 64 | 65 | @unittest.skip("Unimplemented test case.") 66 | class DiskCommitToOSTestCase(unittest.TestCase): 67 | def runTest(self): 68 | # TODO 69 | self.fail("Unimplemented test case.") 70 | 71 | 72 | @unittest.skip("Unimplemented test case.") 73 | class DiskCheckTestCase(unittest.TestCase): 74 | def runTest(self): 75 | # TODO 76 | self.fail("Unimplemented test case.") 77 | 78 | 79 | @unittest.skip("Unimplemented test case.") 80 | class DiskSupportsFeatureTestCase(unittest.TestCase): 81 | def runTest(self): 82 | # TODO 83 | self.fail("Unimplemented test case.") 84 | 85 | 86 | class DiskAddPartitionTestCase(RequiresDisk): 87 | """ 88 | addPartition should return True if partition is added successfully(even 89 | without committing) 90 | """ 91 | 92 | def runTest(self): 93 | self.disk.setFlag(parted.DISK_CYLINDER_ALIGNMENT) 94 | 95 | length = 100 96 | geom = parted.Geometry(self.device, start=100, length=length) 97 | part = parted.Partition(self.disk, parted.PARTITION_NORMAL, geometry=geom) 98 | constraint = parted.Constraint(exactGeom=geom) 99 | self.assertTrue(self.disk.addPartition(part, constraint)) 100 | 101 | 102 | @unittest.skip("Unimplemented test case.") 103 | class DiskRemovePartitionTestCase(unittest.TestCase): 104 | def runTest(self): 105 | # TODO 106 | self.fail("Unimplemented test case.") 107 | 108 | 109 | @unittest.skip("Unimplemented test case.") 110 | class DiskDeletePartitionTestCase(unittest.TestCase): 111 | def runTest(self): 112 | # TODO 113 | self.fail("Unimplemented test case.") 114 | 115 | 116 | @unittest.skip("Unimplemented test case.") 117 | class DiskDeleteAllPartitionsTestCase(unittest.TestCase): 118 | def runTest(self): 119 | # TODO 120 | self.fail("Unimplemented test case.") 121 | 122 | 123 | @unittest.skip("Unimplemented test case.") 124 | class DiskSetPartitionGeometryTestCase(unittest.TestCase): 125 | def runTest(self): 126 | # TODO 127 | self.fail("Unimplemented test case.") 128 | 129 | 130 | @unittest.skip("Unimplemented test case.") 131 | class DiskMaximizePartitionTestCase(unittest.TestCase): 132 | def runTest(self): 133 | # TODO 134 | self.fail("Unimplemented test case.") 135 | 136 | 137 | @unittest.skip("Unimplemented test case.") 138 | class DiskCalculateMaxPartitionGeometryTestCase(unittest.TestCase): 139 | def runTest(self): 140 | # TODO 141 | self.fail("Unimplemented test case.") 142 | 143 | 144 | @unittest.skip("Unimplemented test case.") 145 | class DiskMinimizeExtendedPartitionTestCase(unittest.TestCase): 146 | def runTest(self): 147 | # TODO 148 | self.fail("Unimplemented test case.") 149 | 150 | 151 | @unittest.skip("Unimplemented test case.") 152 | class DiskGetPartitionBySectorTestCase(unittest.TestCase): 153 | def runTest(self): 154 | # TODO 155 | self.fail("Unimplemented test case.") 156 | 157 | 158 | class DiskGetMaxSupportedPartitionCountTestCase(RequiresDisk): 159 | """ 160 | maxSupportedPartitionCount should return value 64, based on default 161 | value MAX_NUM_PARTS(parted/libparted/arch/linux.c) applied if it cannot 162 | find value in /sys/block/DEV/ext_range (RequiresDisk implies there is 163 | no ext_range value). Also see testcase 164 | DiskGetMaxSupportedPartitionCountTestCase in tests/test__ped_disk , 165 | which tests value returned by source C function defined in module _ped 166 | """ 167 | 168 | def runTest(self): 169 | self.assertEqual(self.disk.maxSupportedPartitionCount, 64) 170 | 171 | 172 | class DiskMaxPartitionLengthTestCase(RequiresDisk): 173 | def runTest(self): 174 | # This test assumes an MSDOS label as given by RequiresDisk 175 | self.assertEqual(self.disk.maxPartitionLength, 4294967295) 176 | 177 | 178 | class DiskMaxPartitionStartSectorTestCase(RequiresDisk): 179 | def runTest(self): 180 | # This test assumes an MSDOS label as given by RequiresDisk 181 | self.assertEqual(self.disk.maxPartitionStartSector, 4294967295) 182 | 183 | 184 | class DiskGetFlagTestCase(RequiresDisk): 185 | def runTest(self): 186 | flag = self.disk.getFlag(parted.DISK_CYLINDER_ALIGNMENT) 187 | self.assertIsInstance(flag, bool) 188 | 189 | 190 | class DiskSetFlagTestCase(RequiresDisk): 191 | def runTest(self): 192 | # This test assumes an MSDOS label as given by RequiresDisk 193 | self.disk.setFlag(parted.DISK_CYLINDER_ALIGNMENT) 194 | flag = self.disk.getFlag(parted.DISK_CYLINDER_ALIGNMENT) 195 | self.assertEqual(flag, True) 196 | 197 | 198 | class DiskUnsetFlagTestCase(RequiresDisk): 199 | def runTest(self): 200 | # This test assumes an MSDOS label as given by RequiresDisk 201 | self.disk.unsetFlag(parted.DISK_CYLINDER_ALIGNMENT) 202 | flag = self.disk.getFlag(parted.DISK_CYLINDER_ALIGNMENT) 203 | self.assertEqual(flag, False) 204 | 205 | 206 | class DiskIsFlagAvailableTestCase(RequiresDisk): 207 | def runTest(self): 208 | # This test assumes an MSDOS label as given by RequiresDisk 209 | available = self.disk.isFlagAvailable(parted.DISK_CYLINDER_ALIGNMENT) 210 | self.assertEqual(available, True) 211 | 212 | 213 | @unittest.skip("Unimplemented test case.") 214 | class DiskGetExtendedPartitionTestCase(unittest.TestCase): 215 | def runTest(self): 216 | # TODO 217 | self.fail("Unimplemented test case.") 218 | 219 | 220 | @unittest.skip("Unimplemented test case.") 221 | class DiskGetLogicalPartitionsTestCase(unittest.TestCase): 222 | def runTest(self): 223 | # TODO 224 | self.fail("Unimplemented test case.") 225 | 226 | 227 | @unittest.skip("Unimplemented test case.") 228 | class DiskGetPrimaryPartitionsTestCase(unittest.TestCase): 229 | def runTest(self): 230 | # TODO 231 | self.fail("Unimplemented test case.") 232 | 233 | 234 | @unittest.skip("Unimplemented test case.") 235 | class DiskGetRaidPartitionsTestCase(unittest.TestCase): 236 | def runTest(self): 237 | # TODO 238 | self.fail("Unimplemented test case.") 239 | 240 | 241 | @unittest.skip("Unimplemented test case.") 242 | class DiskGetLVMPartitionsTestCase(unittest.TestCase): 243 | def runTest(self): 244 | # TODO 245 | self.fail("Unimplemented test case.") 246 | 247 | 248 | @unittest.skip("Unimplemented test case.") 249 | class DiskGetFreeSpaceRegionsTestCase(unittest.TestCase): 250 | def runTest(self): 251 | # TODO 252 | self.fail("Unimplemented test case.") 253 | 254 | 255 | @unittest.skip("Unimplemented test case.") 256 | class DiskGetFreeSpacePartitionsTestCase(unittest.TestCase): 257 | def runTest(self): 258 | # TODO 259 | self.fail("Unimplemented test case.") 260 | 261 | 262 | @unittest.skip("Unimplemented test case.") 263 | class DiskGetFirstPartitionTestCase(unittest.TestCase): 264 | def runTest(self): 265 | # TODO 266 | self.fail("Unimplemented test case.") 267 | 268 | 269 | @unittest.skip("Unimplemented test case.") 270 | class DiskGetPartitionByPathTestCase(unittest.TestCase): 271 | def runTest(self): 272 | # TODO 273 | self.fail("Unimplemented test case.") 274 | 275 | 276 | @unittest.skip("Unimplemented test case.") 277 | class DiskGetPedDiskTestCase(unittest.TestCase): 278 | def runTest(self): 279 | # TODO 280 | self.fail("Unimplemented test case.") 281 | 282 | 283 | @unittest.skip("Unimplemented test case.") 284 | class DiskStrTestCase(unittest.TestCase): 285 | def runTest(self): 286 | # TODO 287 | self.fail("Unimplemented test case.") 288 | -------------------------------------------------------------------------------- /tests/test_parted_filesystem.py: -------------------------------------------------------------------------------- 1 | # 2 | # Test cases for the methods in the parted.filesystem module itself 3 | # 4 | # Copyright The pyparted Project Authors 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | # 7 | 8 | import unittest 9 | 10 | # One class per method, multiple tests per class. For these simple methods, 11 | # that seems like good organization. More complicated methods may require 12 | # multiple classes and their own test suite. 13 | @unittest.skip("Unimplemented test case.") 14 | class FileSystemNewTestCase(unittest.TestCase): 15 | def runTest(self): 16 | # TODO 17 | self.fail("Unimplemented test case.") 18 | 19 | 20 | @unittest.skip("Unimplemented test case.") 21 | class FileSystemGetSetTestCase(unittest.TestCase): 22 | def runTest(self): 23 | # TODO 24 | self.fail("Unimplemented test case.") 25 | 26 | 27 | @unittest.skip("Unimplemented test case.") 28 | class FileSystemGetPedFileSystemTestCase(unittest.TestCase): 29 | def runTest(self): 30 | # TODO 31 | self.fail("Unimplemented test case.") 32 | 33 | 34 | @unittest.skip("Unimplemented test case.") 35 | class FileSystemStrTestCase(unittest.TestCase): 36 | def runTest(self): 37 | # TODO 38 | self.fail("Unimplemented test case.") 39 | -------------------------------------------------------------------------------- /tests/test_parted_geometry.py: -------------------------------------------------------------------------------- 1 | # 2 | # Test cases for the methods in the parted.geometry module itself 3 | # 4 | # Copyright The pyparted Project Authors 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | # 7 | 8 | import parted 9 | import unittest 10 | 11 | from tests.baseclass import RequiresDevice 12 | 13 | # One class per method, multiple tests per class. For these simple methods, 14 | # that seems like good organization. More complicated methods may require 15 | # multiple classes and their own test suite. 16 | @unittest.skip("Unimplemented test case.") 17 | class GeometryNewTestCase(unittest.TestCase): 18 | def runTest(self): 19 | # TODO 20 | self.fail("Unimplemented test case.") 21 | 22 | 23 | @unittest.skip("Unimplemented test case.") 24 | class GeometryGetSetTestCase(unittest.TestCase): 25 | def runTest(self): 26 | # TODO 27 | self.fail("Unimplemented test case.") 28 | 29 | 30 | @unittest.skip("Unimplemented test case.") 31 | class GeometryCheckTestCase(unittest.TestCase): 32 | def runTest(self): 33 | # TODO 34 | self.fail("Unimplemented test case.") 35 | 36 | 37 | @unittest.skip("Unimplemented test case.") 38 | class GeometryContainsTestCase(unittest.TestCase): 39 | def runTest(self): 40 | # TODO 41 | self.fail("Unimplemented test case.") 42 | 43 | 44 | @unittest.skip("Unimplemented test case.") 45 | class GeometryContainsSectorTestCase(unittest.TestCase): 46 | def runTest(self): 47 | # TODO 48 | self.fail("Unimplemented test case.") 49 | 50 | 51 | @unittest.skip("Unimplemented test case.") 52 | class GeometryEqualTestCase(unittest.TestCase): 53 | def runTest(self): 54 | # TODO 55 | self.fail("Unimplemented test case.") 56 | 57 | 58 | @unittest.skip("Unimplemented test case.") 59 | class GeometryGetSizeTestCase(unittest.TestCase): 60 | def runTest(self): 61 | # TODO 62 | self.fail("Unimplemented test case.") 63 | 64 | 65 | class GeometryGetLengthTestCase(RequiresDevice): 66 | def runTest(self): 67 | length = 137 68 | geom = parted.Geometry(self.device, start=100, length=length) 69 | 70 | self.assertEqual(geom.getLength(), geom.length) 71 | self.assertEqual(geom.getLength(), length) 72 | 73 | 74 | @unittest.skip("Unimplemented test case.") 75 | class GeometryIntersectTestCase(unittest.TestCase): 76 | def runTest(self): 77 | # TODO 78 | self.fail("Unimplemented test case.") 79 | 80 | 81 | @unittest.skip("Unimplemented test case.") 82 | class GeometryMapTestCase(unittest.TestCase): 83 | def runTest(self): 84 | # TODO 85 | self.fail("Unimplemented test case.") 86 | 87 | 88 | @unittest.skip("Unimplemented test case.") 89 | class GeometryOverlapsWithTestCase(unittest.TestCase): 90 | def runTest(self): 91 | # TODO 92 | self.fail("Unimplemented test case.") 93 | 94 | 95 | @unittest.skip("Unimplemented test case.") 96 | class GeometryReadTestCase(unittest.TestCase): 97 | def runTest(self): 98 | # TODO 99 | self.fail("Unimplemented test case.") 100 | 101 | 102 | @unittest.skip("Unimplemented test case.") 103 | class GeometrySyncTestCase(unittest.TestCase): 104 | def runTest(self): 105 | # TODO 106 | self.fail("Unimplemented test case.") 107 | 108 | 109 | class GeometryWriteTestCase(RequiresDevice): 110 | def setUp(self): 111 | super().setUp() 112 | self.geom = parted.Geometry(self.device, start=10, length=100) 113 | 114 | def runTest(self): 115 | self._device.open() 116 | self.assertTrue( 117 | self.geom.write("".join(["\x00"] * self.device.sectorSize), 0, 1) 118 | ) 119 | self.assertTrue( 120 | self.geom.write("".join(["\x01"] * self.device.sectorSize), 0, 1) 121 | ) 122 | self._device.close() 123 | 124 | 125 | @unittest.skip("Unimplemented test case.") 126 | class GeometryGetPedGeometryTestCase(unittest.TestCase): 127 | def runTest(self): 128 | # TODO 129 | self.fail("Unimplemented test case.") 130 | 131 | 132 | @unittest.skip("Unimplemented test case.") 133 | class GeometryStrTestCase(unittest.TestCase): 134 | def runTest(self): 135 | # TODO 136 | self.fail("Unimplemented test case.") 137 | -------------------------------------------------------------------------------- /tests/test_parted_parted.py: -------------------------------------------------------------------------------- 1 | # 2 | # Test cases for the methods in the parted module itself 3 | # 4 | # Copyright The pyparted Project Authors 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | # 7 | 8 | from __future__ import division 9 | 10 | import _ped 11 | import parted 12 | import unittest 13 | from tests.baseclass import RequiresDevice, RequiresDeviceNode 14 | 15 | # One class per method, multiple tests per class. For these simple methods, 16 | # that seems like good organization. More complicated methods may require 17 | # multiple classes and their own test suite. 18 | class FormatBytesTestCase(unittest.TestCase): 19 | def runTest(self): 20 | self.assertRaises(SyntaxError, parted.formatBytes, 57, "GIB") 21 | self.assertEqual(1e-24, parted.formatBytes(1, "YB")) 22 | self.assertEqual(1 / 2**80, parted.formatBytes(1, "YiB")) 23 | self.assertEqual(1, parted.formatBytes(1, "B")) 24 | self.assertEqual(1, parted.formatBytes(1e24, "YB")) 25 | self.assertEqual(1, parted.formatBytes(2**80, "YiB")) 26 | 27 | 28 | class BytesToSectorsTestCase(unittest.TestCase): 29 | def runTest(self): 30 | self.assertRaises(SyntaxError, parted.sizeToSectors, 9, "yb", 1) 31 | self.assertEqual( 32 | int(parted.sizeToSectors(7777.0, "B", 512)), 33 | parted.sizeToSectors(7777.0, "B", 512), 34 | ) 35 | self.assertEqual(parted.sizeToSectors(1000, "B", 512), 2) 36 | 37 | 38 | class GetLabelsTestCase(unittest.TestCase): 39 | def runTest(self): 40 | self.assertGreater(len(parted.getLabels()), 0) 41 | self.assertSetEqual(parted.getLabels("ppcc"), set()) 42 | self.assertSetEqual(parted.getLabels("sparc6"), set()) 43 | self.assertSetEqual(parted.getLabels("i586"), {"gpt", "msdos"}) 44 | self.assertSetEqual(parted.getLabels("s390"), {"dasd", "msdos"}) 45 | self.assertSetEqual(parted.getLabels("s390x"), {"dasd", "msdos"}) 46 | self.assertSetEqual(parted.getLabels("sparc"), {"sun"}) 47 | self.assertSetEqual(parted.getLabels("sparc64"), {"sun"}) 48 | self.assertSetEqual(parted.getLabels("ppc"), {"amiga", "gpt", "mac", "msdos"}) 49 | self.assertSetEqual(parted.getLabels("ppc64"), {"amiga", "gpt", "mac", "msdos"}) 50 | self.assertSetEqual(parted.getLabels("ppc64le"), {"gpt", "msdos"}) 51 | self.assertSetEqual(parted.getLabels("alpha"), {"bsd", "msdos"}) 52 | self.assertSetEqual(parted.getLabels("ia64"), {"gpt", "msdos"}) 53 | self.assertSetEqual(parted.getLabels("aarch64"), {"gpt", "msdos"}) 54 | self.assertSetEqual(parted.getLabels("armv7l"), {"gpt", "msdos"}) 55 | self.assertSetEqual(parted.getLabels("riscv32"), {"gpt", "msdos"}) 56 | self.assertSetEqual(parted.getLabels("riscv64"), {"gpt", "msdos"}) 57 | self.assertSetEqual(parted.getLabels("loongarch32"), {"gpt", "msdos"}) 58 | self.assertSetEqual(parted.getLabels("loongarch64"), {"gpt", "msdos"}) 59 | 60 | 61 | class GetDeviceTestCase(RequiresDeviceNode): 62 | def runTest(self): 63 | # Check that a DiskException is raised for an invalid path 64 | self.assertRaises(parted.DeviceException, parted.getDevice, None) 65 | self.assertRaises(parted.IOException, parted.getDevice, "") 66 | self.assertRaises(parted.IOException, parted.getDevice, "/dev/whatever") 67 | 68 | # Check that we get a parted.Device back 69 | self.assertIsInstance(parted.getDevice(self.path), parted.Device) 70 | 71 | # Make sure the device node paths match 72 | self.assertEqual(parted.getDevice(self.path).path, self.path) 73 | 74 | 75 | class GetAllDevicesTestCase(unittest.TestCase): 76 | def setUp(self): 77 | self.devices = parted.getAllDevices() 78 | 79 | def runTest(self): 80 | # Check self.devices and see that it's a list 81 | self.assertEqual(type(self.devices).__name__, "list") 82 | 83 | # And make sure each element of the list is a parted.Device 84 | for dev in self.devices: 85 | self.assertIsInstance(dev, parted.Device) 86 | 87 | 88 | @unittest.skip("Unimplemented test case.") 89 | class ProbeForSpecificFileSystemTestCase(unittest.TestCase): 90 | def runTest(self): 91 | # TODO 92 | self.fail("Unimplemented test case.") 93 | 94 | 95 | @unittest.skip("Unimplemented test case.") 96 | class ProbeFileSystemTestCase(unittest.TestCase): 97 | def runTest(self): 98 | # TODO 99 | self.fail("Unimplemented test case.") 100 | 101 | 102 | class FreshDiskTestCase(RequiresDevice): 103 | def runTest(self): 104 | # Make sure we get SyntaxError when using an invalid disk type 105 | self.assertRaises(KeyError, parted.freshDisk, self.device, "cheese") 106 | self.assertRaises(KeyError, parted.freshDisk, self.device, "crackers") 107 | 108 | # Create a new disk for each disk type key, verify each one 109 | # XXX: Skip over dvh for now (SGI disk label), which doesn't seem to have 110 | # working libparted support. If anyone with an SGI cares, patches welcome. 111 | for key in parted.diskType.keys(): 112 | if key in ["dvh", "aix"]: 113 | continue 114 | disk = parted.freshDisk(self.device, key) 115 | self.assertIsInstance(disk, parted.Disk) 116 | self.assertEqual(disk.type, key) 117 | 118 | # Create a new disk each disk type value, verify each one 119 | for value in parted.diskType.values(): 120 | if value.name in ["dvh", "aix"]: 121 | continue 122 | disk = parted.freshDisk(self.device, value) 123 | self.assertIsInstance(disk, parted.Disk) 124 | self.assertEqual(parted.diskType[disk.type], value) 125 | 126 | 127 | @unittest.skip("Unimplemented test case.") 128 | class IsAlignToCylindersTestCase(unittest.TestCase): 129 | def runTest(self): 130 | # TODO 131 | self.fail("Unimplemented test case.") 132 | 133 | 134 | @unittest.skip("Unimplemented test case.") 135 | class ToggleAlignToCylindersTestCase(unittest.TestCase): 136 | def runTest(self): 137 | # TODO 138 | self.fail("Unimplemented test case.") 139 | 140 | 141 | class VersionTestCase(unittest.TestCase): 142 | def runTest(self): 143 | ver = parted.version() 144 | self.assertEqual(ver["libparted"], _ped.libparted_version()) 145 | self.assertEqual(ver["pyparted"], _ped.pyparted_version()) 146 | --------------------------------------------------------------------------------