diff options
author | Antonin Godard <antonin.godard@bootlin.com> | 2025-04-18 17:15:25 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2025-04-24 11:53:00 +0100 |
commit | 8c24921ba61b05b903e3b94ecdb131f5a9dbe247 (patch) | |
tree | edd16f9f307ca0ca7844c49917a6e460d481bc04 /bitbake | |
parent | da63ef8c75065cc36b62000aafdd9a325611043c (diff) | |
download | poky-8c24921ba61b05b903e3b94ecdb131f5a9dbe247.tar.gz |
bitbake: utils: format and improve docstrings
Format the docstrings of the utils modules to be automatically
documented with the autodoc Sphinx extensions. Sphinx syntax can be used
in those for proper formatting. Cross-referencing with :term: is not
possible in these.
(Bitbake rev: 2fa1c7ad43639c6d25c94b7794bcce5f5ff74e10)
Signed-off-by: Antonin Godard <antonin.godard@bootlin.com>
Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r-- | bitbake/lib/bb/utils.py | 601 |
1 files changed, 453 insertions, 148 deletions
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py index a1e093925b..a2806fd360 100644 --- a/bitbake/lib/bb/utils.py +++ b/bitbake/lib/bb/utils.py | |||
@@ -82,7 +82,16 @@ def explode_version(s): | |||
82 | return r | 82 | return r |
83 | 83 | ||
84 | def split_version(s): | 84 | def split_version(s): |
85 | """Split a version string into its constituent parts (PE, PV, PR)""" | 85 | """Split a version string into its constituent parts (PE, PV, PR). |
86 | |||
87 | Arguments: | ||
88 | |||
89 | - ``s``: version string. The format of the input string should be:: | ||
90 | |||
91 | ${PE}:${PV}-${PR} | ||
92 | |||
93 | Returns a tuple ``(pe, pv, pr)``. | ||
94 | """ | ||
86 | s = s.strip(" <>=") | 95 | s = s.strip(" <>=") |
87 | e = 0 | 96 | e = 0 |
88 | if s.count(':'): | 97 | if s.count(':'): |
@@ -134,16 +143,30 @@ def vercmp(ta, tb): | |||
134 | return r | 143 | return r |
135 | 144 | ||
136 | def vercmp_string(a, b): | 145 | def vercmp_string(a, b): |
137 | """ Split version strings and compare them """ | 146 | """ Split version strings using ``bb.utils.split_version()`` and compare |
147 | them with ``bb.utils.vercmp().`` | ||
148 | |||
149 | Arguments: | ||
150 | |||
151 | - ``a``: left version string operand. | ||
152 | - ``b``: right version string operand. | ||
153 | |||
154 | Returns what ``bb.utils.vercmp()`` returns.""" | ||
138 | ta = split_version(a) | 155 | ta = split_version(a) |
139 | tb = split_version(b) | 156 | tb = split_version(b) |
140 | return vercmp(ta, tb) | 157 | return vercmp(ta, tb) |
141 | 158 | ||
142 | def vercmp_string_op(a, b, op): | 159 | def vercmp_string_op(a, b, op): |
143 | """ | 160 | """ |
144 | Compare two versions and check if the specified comparison operator matches the result of the comparison. | 161 | Takes the return value ``bb.utils.vercmp()`` and returns the operation |
145 | This function is fairly liberal about what operators it will accept since there are a variety of styles | 162 | defined by ``op`` between the return value and 0. |
146 | depending on the context. | 163 | |
164 | Arguments: | ||
165 | |||
166 | - ``a``: left version string operand. | ||
167 | - ``b``: right version string operand. | ||
168 | - ``op``: operator string. Can be one of ``=``, ``==``, ``<=``, ``>=``, | ||
169 | ``>``, ``>>``, ``<``, ``<<`` or ``!=``. | ||
147 | """ | 170 | """ |
148 | res = vercmp_string(a, b) | 171 | res = vercmp_string(a, b) |
149 | if op in ('=', '=='): | 172 | if op in ('=', '=='): |
@@ -163,9 +186,16 @@ def vercmp_string_op(a, b, op): | |||
163 | 186 | ||
164 | def explode_deps(s): | 187 | def explode_deps(s): |
165 | """ | 188 | """ |
166 | Take an RDEPENDS style string of format: | 189 | Takes an RDEPENDS style string of format:: |
167 | "DEPEND1 (optional version) DEPEND2 (optional version) ..." | 190 | |
168 | and return a list of dependencies. | 191 | DEPEND1 (optional version) DEPEND2 (optional version) ... |
192 | |||
193 | Arguments: | ||
194 | |||
195 | - ``s``: input RDEPENDS style string | ||
196 | |||
197 | Returns a list of dependencies. | ||
198 | |||
169 | Version information is ignored. | 199 | Version information is ignored. |
170 | """ | 200 | """ |
171 | r = [] | 201 | r = [] |
@@ -187,9 +217,17 @@ def explode_deps(s): | |||
187 | 217 | ||
188 | def explode_dep_versions2(s, *, sort=True): | 218 | def explode_dep_versions2(s, *, sort=True): |
189 | """ | 219 | """ |
190 | Take an RDEPENDS style string of format: | 220 | Takes an RDEPENDS style string of format:: |
191 | "DEPEND1 (optional version) DEPEND2 (optional version) ..." | 221 | |
192 | and return a dictionary of dependencies and versions. | 222 | DEPEND1 (optional version) DEPEND2 (optional version) ... |
223 | |||
224 | Arguments: | ||
225 | |||
226 | - ``s``: input RDEPENDS style string | ||
227 | - ``*``: *Unused*. | ||
228 | - ``sort``: whether to sort the output or not. | ||
229 | |||
230 | Returns a dictionary of dependencies and versions. | ||
193 | """ | 231 | """ |
194 | r = collections.OrderedDict() | 232 | r = collections.OrderedDict() |
195 | l = s.replace(",", "").split() | 233 | l = s.replace(",", "").split() |
@@ -254,10 +292,17 @@ def explode_dep_versions2(s, *, sort=True): | |||
254 | 292 | ||
255 | def explode_dep_versions(s): | 293 | def explode_dep_versions(s): |
256 | """ | 294 | """ |
257 | Take an RDEPENDS style string of format: | 295 | Take an RDEPENDS style string of format:: |
258 | "DEPEND1 (optional version) DEPEND2 (optional version) ..." | 296 | |
259 | skip null value and items appeared in dependency string multiple times | 297 | DEPEND1 (optional version) DEPEND2 (optional version) ... |
260 | and return a dictionary of dependencies and versions. | 298 | |
299 | Skips null values and items appeared in dependency string multiple times. | ||
300 | |||
301 | Arguments: | ||
302 | |||
303 | - ``s``: input RDEPENDS style string | ||
304 | |||
305 | Returns a dictionary of dependencies and versions. | ||
261 | """ | 306 | """ |
262 | r = explode_dep_versions2(s) | 307 | r = explode_dep_versions2(s) |
263 | for d in r: | 308 | for d in r: |
@@ -271,7 +316,17 @@ def explode_dep_versions(s): | |||
271 | 316 | ||
272 | def join_deps(deps, commasep=True): | 317 | def join_deps(deps, commasep=True): |
273 | """ | 318 | """ |
274 | Take the result from explode_dep_versions and generate a dependency string | 319 | Take a result from ``bb.utils.explode_dep_versions()`` and generate a |
320 | dependency string. | ||
321 | |||
322 | Arguments: | ||
323 | |||
324 | - ``deps``: dictionary of dependencies and versions. | ||
325 | - ``commasep``: makes the return value separated by commas if ``True``, | ||
326 | separated by spaces otherwise. | ||
327 | |||
328 | Returns a comma-separated (space-separated if ``comma-sep`` is ``False``) | ||
329 | string of dependencies and versions. | ||
275 | """ | 330 | """ |
276 | result = [] | 331 | result = [] |
277 | for dep in deps: | 332 | for dep in deps: |
@@ -433,7 +488,11 @@ def better_eval(source, locals, extraglobals = None): | |||
433 | 488 | ||
434 | @contextmanager | 489 | @contextmanager |
435 | def fileslocked(files, *args, **kwargs): | 490 | def fileslocked(files, *args, **kwargs): |
436 | """Context manager for locking and unlocking file locks.""" | 491 | """Context manager for locking and unlocking file locks. Uses |
492 | ``bb.utils.lockfile()`` and ``bb.utils.unlockfile()`` to lock and unlock | ||
493 | files. | ||
494 | |||
495 | No return value.""" | ||
437 | locks = [] | 496 | locks = [] |
438 | if files: | 497 | if files: |
439 | for lockfile in files: | 498 | for lockfile in files: |
@@ -450,14 +509,23 @@ def fileslocked(files, *args, **kwargs): | |||
450 | 509 | ||
451 | def lockfile(name, shared=False, retry=True, block=False): | 510 | def lockfile(name, shared=False, retry=True, block=False): |
452 | """ | 511 | """ |
453 | Use the specified file as a lock file, return when the lock has | 512 | Use the specified file (with filename ``name``) as a lock file, return when |
454 | been acquired. Returns a variable to pass to unlockfile(). | 513 | the lock has been acquired. Returns a variable to pass to unlockfile(). |
455 | Parameters: | 514 | |
456 | retry: True to re-try locking if it fails, False otherwise | 515 | Arguments: |
457 | block: True to block until the lock succeeds, False otherwise | 516 | |
517 | - ``shared``: sets the lock as a shared lock instead of an | ||
518 | exclusive lock. | ||
519 | - ``retry``: ``True`` to re-try locking if it fails, ``False`` | ||
520 | otherwise. | ||
521 | - ``block``: ``True`` to block until the lock succeeds, | ||
522 | ``False`` otherwise. | ||
523 | |||
458 | The retry and block parameters are kind of equivalent unless you | 524 | The retry and block parameters are kind of equivalent unless you |
459 | consider the possibility of sending a signal to the process to break | 525 | consider the possibility of sending a signal to the process to break |
460 | out - at which point you want block=True rather than retry=True. | 526 | out - at which point you want block=True rather than retry=True. |
527 | |||
528 | Returns the locked file descriptor in case of success, ``None`` otherwise. | ||
461 | """ | 529 | """ |
462 | basename = os.path.basename(name) | 530 | basename = os.path.basename(name) |
463 | if len(basename) > 255: | 531 | if len(basename) > 255: |
@@ -516,7 +584,13 @@ def lockfile(name, shared=False, retry=True, block=False): | |||
516 | 584 | ||
517 | def unlockfile(lf): | 585 | def unlockfile(lf): |
518 | """ | 586 | """ |
519 | Unlock a file locked using lockfile() | 587 | Unlock a file locked using ``bb.utils.lockfile()``. |
588 | |||
589 | Arguments: | ||
590 | |||
591 | - ``lf``: the locked file descriptor. | ||
592 | |||
593 | No return value. | ||
520 | """ | 594 | """ |
521 | try: | 595 | try: |
522 | # If we had a shared lock, we need to promote to exclusive before | 596 | # If we had a shared lock, we need to promote to exclusive before |
@@ -544,7 +618,11 @@ def _hasher(method, filename): | |||
544 | 618 | ||
545 | def md5_file(filename): | 619 | def md5_file(filename): |
546 | """ | 620 | """ |
547 | Return the hex string representation of the MD5 checksum of filename. | 621 | Arguments: |
622 | |||
623 | - ``filename``: path to the input file. | ||
624 | |||
625 | Returns the hexadecimal string representation of the MD5 checksum of filename. | ||
548 | """ | 626 | """ |
549 | import hashlib | 627 | import hashlib |
550 | try: | 628 | try: |
@@ -556,39 +634,59 @@ def md5_file(filename): | |||
556 | 634 | ||
557 | def sha256_file(filename): | 635 | def sha256_file(filename): |
558 | """ | 636 | """ |
559 | Return the hex string representation of the 256-bit SHA checksum of | 637 | Returns the hexadecimal representation of the 256-bit SHA checksum of |
560 | filename. | 638 | filename. |
639 | |||
640 | Arguments: | ||
641 | |||
642 | - ``filename``: path to the file. | ||
561 | """ | 643 | """ |
562 | import hashlib | 644 | import hashlib |
563 | return _hasher(hashlib.sha256(), filename) | 645 | return _hasher(hashlib.sha256(), filename) |
564 | 646 | ||
565 | def sha1_file(filename): | 647 | def sha1_file(filename): |
566 | """ | 648 | """ |
567 | Return the hex string representation of the SHA1 checksum of the filename | 649 | Returns the hexadecimal representation of the SHA1 checksum of the filename |
650 | |||
651 | Arguments: | ||
652 | |||
653 | - ``filename``: path to the file. | ||
568 | """ | 654 | """ |
569 | import hashlib | 655 | import hashlib |
570 | return _hasher(hashlib.sha1(), filename) | 656 | return _hasher(hashlib.sha1(), filename) |
571 | 657 | ||
572 | def sha384_file(filename): | 658 | def sha384_file(filename): |
573 | """ | 659 | """ |
574 | Return the hex string representation of the SHA384 checksum of the filename | 660 | Returns the hexadecimal representation of the SHA384 checksum of the filename |
661 | |||
662 | Arguments: | ||
663 | |||
664 | - ``filename``: path to the file. | ||
575 | """ | 665 | """ |
576 | import hashlib | 666 | import hashlib |
577 | return _hasher(hashlib.sha384(), filename) | 667 | return _hasher(hashlib.sha384(), filename) |
578 | 668 | ||
579 | def sha512_file(filename): | 669 | def sha512_file(filename): |
580 | """ | 670 | """ |
581 | Return the hex string representation of the SHA512 checksum of the filename | 671 | Returns the hexadecimal representation of the SHA512 checksum of the filename |
672 | |||
673 | Arguments: | ||
674 | |||
675 | - ``filename``: path to the file. | ||
582 | """ | 676 | """ |
583 | import hashlib | 677 | import hashlib |
584 | return _hasher(hashlib.sha512(), filename) | 678 | return _hasher(hashlib.sha512(), filename) |
585 | 679 | ||
586 | def goh1_file(filename): | 680 | def goh1_file(filename): |
587 | """ | 681 | """ |
588 | Return the hex string representation of the Go mod h1 checksum of the | 682 | Returns the hexadecimal string representation of the Go mod h1 checksum of the |
589 | filename. The Go mod h1 checksum uses the Go dirhash package. The package | 683 | filename. The Go mod h1 checksum uses the Go dirhash package. The package |
590 | defines hashes over directory trees and is used by go mod for mod files and | 684 | defines hashes over directory trees and is used by go mod for mod files and |
591 | zip archives. | 685 | zip archives. |
686 | |||
687 | Arguments: | ||
688 | |||
689 | - ``filename``: path to the file. | ||
592 | """ | 690 | """ |
593 | import hashlib | 691 | import hashlib |
594 | import zipfile | 692 | import zipfile |
@@ -609,8 +707,8 @@ def goh1_file(filename): | |||
609 | return method.hexdigest() | 707 | return method.hexdigest() |
610 | 708 | ||
611 | def preserved_envvars_exported(): | 709 | def preserved_envvars_exported(): |
612 | """Variables which are taken from the environment and placed in and exported | 710 | """Returns the list of variables which are taken from the environment and |
613 | from the metadata""" | 711 | placed in and exported from the metadata.""" |
614 | return [ | 712 | return [ |
615 | 'BB_TASKHASH', | 713 | 'BB_TASKHASH', |
616 | 'HOME', | 714 | 'HOME', |
@@ -624,7 +722,8 @@ def preserved_envvars_exported(): | |||
624 | ] | 722 | ] |
625 | 723 | ||
626 | def preserved_envvars(): | 724 | def preserved_envvars(): |
627 | """Variables which are taken from the environment and placed in the metadata""" | 725 | """Returns the list of variables which are taken from the environment and |
726 | placed in the metadata.""" | ||
628 | v = [ | 727 | v = [ |
629 | 'BBPATH', | 728 | 'BBPATH', |
630 | 'BB_PRESERVE_ENV', | 729 | 'BB_PRESERVE_ENV', |
@@ -633,7 +732,9 @@ def preserved_envvars(): | |||
633 | return v + preserved_envvars_exported() | 732 | return v + preserved_envvars_exported() |
634 | 733 | ||
635 | def check_system_locale(): | 734 | def check_system_locale(): |
636 | """Make sure the required system locale are available and configured""" | 735 | """Make sure the required system locale are available and configured. |
736 | |||
737 | No return value.""" | ||
637 | default_locale = locale.getlocale(locale.LC_CTYPE) | 738 | default_locale = locale.getlocale(locale.LC_CTYPE) |
638 | 739 | ||
639 | try: | 740 | try: |
@@ -651,6 +752,12 @@ def filter_environment(good_vars): | |||
651 | """ | 752 | """ |
652 | Create a pristine environment for bitbake. This will remove variables that | 753 | Create a pristine environment for bitbake. This will remove variables that |
653 | are not known and may influence the build in a negative way. | 754 | are not known and may influence the build in a negative way. |
755 | |||
756 | Arguments: | ||
757 | |||
758 | - ``good_vars``: list of variable to exclude from the filtering. | ||
759 | |||
760 | No return value. | ||
654 | """ | 761 | """ |
655 | 762 | ||
656 | removed_vars = {} | 763 | removed_vars = {} |
@@ -695,6 +802,8 @@ def clean_environment(): | |||
695 | """ | 802 | """ |
696 | Clean up any spurious environment variables. This will remove any | 803 | Clean up any spurious environment variables. This will remove any |
697 | variables the user hasn't chosen to preserve. | 804 | variables the user hasn't chosen to preserve. |
805 | |||
806 | No return value. | ||
698 | """ | 807 | """ |
699 | if 'BB_PRESERVE_ENV' not in os.environ: | 808 | if 'BB_PRESERVE_ENV' not in os.environ: |
700 | good_vars = approved_variables() | 809 | good_vars = approved_variables() |
@@ -705,6 +814,8 @@ def clean_environment(): | |||
705 | def empty_environment(): | 814 | def empty_environment(): |
706 | """ | 815 | """ |
707 | Remove all variables from the environment. | 816 | Remove all variables from the environment. |
817 | |||
818 | No return value. | ||
708 | """ | 819 | """ |
709 | for s in list(os.environ.keys()): | 820 | for s in list(os.environ.keys()): |
710 | os.unsetenv(s) | 821 | os.unsetenv(s) |
@@ -713,6 +824,12 @@ def empty_environment(): | |||
713 | def build_environment(d): | 824 | def build_environment(d): |
714 | """ | 825 | """ |
715 | Build an environment from all exported variables. | 826 | Build an environment from all exported variables. |
827 | |||
828 | Arguments: | ||
829 | |||
830 | - ``d``: the data store. | ||
831 | |||
832 | No return value. | ||
716 | """ | 833 | """ |
717 | import bb.data | 834 | import bb.data |
718 | for var in bb.data.keys(d): | 835 | for var in bb.data.keys(d): |
@@ -737,7 +854,17 @@ def _check_unsafe_delete_path(path): | |||
737 | return False | 854 | return False |
738 | 855 | ||
739 | def remove(path, recurse=False, ionice=False): | 856 | def remove(path, recurse=False, ionice=False): |
740 | """Equivalent to rm -f or rm -rf""" | 857 | """Equivalent to rm -f or rm -rf. |
858 | |||
859 | Arguments: | ||
860 | |||
861 | - ``path``: path to file/directory to remove. | ||
862 | - ``recurse``: deletes recursively if ``True``. | ||
863 | - ``ionice``: prepends ``ionice -c 3`` to the ``rm`` command. See ``man | ||
864 | ionice``. | ||
865 | |||
866 | No return value. | ||
867 | """ | ||
741 | if not path: | 868 | if not path: |
742 | return | 869 | return |
743 | if recurse: | 870 | if recurse: |
@@ -758,7 +885,17 @@ def remove(path, recurse=False, ionice=False): | |||
758 | raise | 885 | raise |
759 | 886 | ||
760 | def prunedir(topdir, ionice=False): | 887 | def prunedir(topdir, ionice=False): |
761 | """ Delete everything reachable from the directory named in 'topdir'. """ | 888 | """ |
889 | Delete everything reachable from the directory named in ``topdir``. | ||
890 | |||
891 | Arguments: | ||
892 | |||
893 | - ``topdir``: directory path. | ||
894 | - ``ionice``: prepends ``ionice -c 3`` to the ``rm`` command. See ``man | ||
895 | ionice``. | ||
896 | |||
897 | No return value. | ||
898 | """ | ||
762 | # CAUTION: This is dangerous! | 899 | # CAUTION: This is dangerous! |
763 | if _check_unsafe_delete_path(topdir): | 900 | if _check_unsafe_delete_path(topdir): |
764 | raise Exception('bb.utils.prunedir: called with dangerous path "%s", refusing to delete!' % topdir) | 901 | raise Exception('bb.utils.prunedir: called with dangerous path "%s", refusing to delete!' % topdir) |
@@ -770,8 +907,15 @@ def prunedir(topdir, ionice=False): | |||
770 | # | 907 | # |
771 | def prune_suffix(var, suffixes, d): | 908 | def prune_suffix(var, suffixes, d): |
772 | """ | 909 | """ |
773 | See if var ends with any of the suffixes listed and | 910 | Check if ``var`` ends with any of the suffixes listed in ``suffixes`` and |
774 | remove it if found | 911 | remove it if found. |
912 | |||
913 | Arguments: | ||
914 | |||
915 | - ``var``: string to check for suffixes. | ||
916 | - ``suffixes``: list of strings representing suffixes to check for. | ||
917 | |||
918 | Returns the string ``var`` without the suffix. | ||
775 | """ | 919 | """ |
776 | for suffix in suffixes: | 920 | for suffix in suffixes: |
777 | if suffix and var.endswith(suffix): | 921 | if suffix and var.endswith(suffix): |
@@ -780,7 +924,13 @@ def prune_suffix(var, suffixes, d): | |||
780 | 924 | ||
781 | def mkdirhier(directory): | 925 | def mkdirhier(directory): |
782 | """Create a directory like 'mkdir -p', but does not complain if | 926 | """Create a directory like 'mkdir -p', but does not complain if |
783 | directory already exists like os.makedirs | 927 | directory already exists like ``os.makedirs()``. |
928 | |||
929 | Arguments: | ||
930 | |||
931 | - ``directory``: path to the directory. | ||
932 | |||
933 | No return value. | ||
784 | """ | 934 | """ |
785 | if '${' in str(directory): | 935 | if '${' in str(directory): |
786 | bb.fatal("Directory name {} contains unexpanded bitbake variable. This may cause build failures and WORKDIR polution.".format(directory)) | 936 | bb.fatal("Directory name {} contains unexpanded bitbake variable. This may cause build failures and WORKDIR polution.".format(directory)) |
@@ -791,10 +941,24 @@ def mkdirhier(directory): | |||
791 | raise e | 941 | raise e |
792 | 942 | ||
793 | def movefile(src, dest, newmtime = None, sstat = None): | 943 | def movefile(src, dest, newmtime = None, sstat = None): |
794 | """Moves a file from src to dest, preserving all permissions and | 944 | """Moves a file from ``src`` to ``dest``, preserving all permissions and |
795 | attributes; mtime will be preserved even when moving across | 945 | attributes; mtime will be preserved even when moving across |
796 | filesystems. Returns true on success and false on failure. Move is | 946 | filesystems. Returns ``True`` on success and ``False`` on failure. Move is |
797 | atomic. | 947 | atomic. |
948 | |||
949 | Arguments: | ||
950 | |||
951 | - ``src`` -- Source file. | ||
952 | - ``dest`` -- Destination file. | ||
953 | - ``newmtime`` -- new mtime to be passed as float seconds since the epoch. | ||
954 | - ``sstat`` -- os.stat_result to use for the destination file. | ||
955 | |||
956 | Returns an ``os.stat_result`` of the destination file if the | ||
957 | source file is a symbolic link or the ``sstat`` argument represents a | ||
958 | symbolic link - in which case the destination file will also be created as | ||
959 | a symbolic link. | ||
960 | |||
961 | Otherwise, returns ``newmtime`` on success and ``False`` on failure. | ||
798 | """ | 962 | """ |
799 | 963 | ||
800 | #print "movefile(" + src + "," + dest + "," + str(newmtime) + "," + str(sstat) + ")" | 964 | #print "movefile(" + src + "," + dest + "," + str(newmtime) + "," + str(sstat) + ")" |
@@ -885,9 +1049,24 @@ def movefile(src, dest, newmtime = None, sstat = None): | |||
885 | 1049 | ||
886 | def copyfile(src, dest, newmtime = None, sstat = None): | 1050 | def copyfile(src, dest, newmtime = None, sstat = None): |
887 | """ | 1051 | """ |
888 | Copies a file from src to dest, preserving all permissions and | 1052 | Copies a file from ``src`` to ``dest``, preserving all permissions and |
889 | attributes; mtime will be preserved even when moving across | 1053 | attributes; mtime will be preserved even when moving across |
890 | filesystems. Returns true on success and false on failure. | 1054 | filesystems. |
1055 | |||
1056 | Arguments: | ||
1057 | |||
1058 | - ``src``: Source file. | ||
1059 | - ``dest``: Destination file. | ||
1060 | - ``newmtime``: new mtime to be passed as float seconds since the epoch. | ||
1061 | - ``sstat``: os.stat_result to use for the destination file. | ||
1062 | |||
1063 | Returns an ``os.stat_result`` of the destination file if the | ||
1064 | source file is a symbolic link or the ``sstat`` argument represents a | ||
1065 | symbolic link - in which case the destination file will also be created as | ||
1066 | a symbolic link. | ||
1067 | |||
1068 | Otherwise, returns ``newmtime`` on success and ``False`` on failure. | ||
1069 | |||
891 | """ | 1070 | """ |
892 | #print "copyfile(" + src + "," + dest + "," + str(newmtime) + "," + str(sstat) + ")" | 1071 | #print "copyfile(" + src + "," + dest + "," + str(newmtime) + "," + str(sstat) + ")" |
893 | try: | 1072 | try: |
@@ -965,10 +1144,16 @@ def copyfile(src, dest, newmtime = None, sstat = None): | |||
965 | 1144 | ||
966 | def break_hardlinks(src, sstat = None): | 1145 | def break_hardlinks(src, sstat = None): |
967 | """ | 1146 | """ |
968 | Ensures src is the only hardlink to this file. Other hardlinks, | 1147 | Ensures ``src`` is the only hardlink to this file. Other hardlinks, |
969 | if any, are not affected (other than in their st_nlink value, of | 1148 | if any, are not affected (other than in their st_nlink value, of |
970 | course). Returns true on success and false on failure. | 1149 | course). |
971 | 1150 | ||
1151 | Arguments: | ||
1152 | |||
1153 | - ``src``: source file path. | ||
1154 | - ``sstat``: os.stat_result to use when checking if the file is a link. | ||
1155 | |||
1156 | Returns ``True`` on success and ``False`` on failure. | ||
972 | """ | 1157 | """ |
973 | try: | 1158 | try: |
974 | if not sstat: | 1159 | if not sstat: |
@@ -982,11 +1167,24 @@ def break_hardlinks(src, sstat = None): | |||
982 | 1167 | ||
983 | def which(path, item, direction = 0, history = False, executable=False): | 1168 | def which(path, item, direction = 0, history = False, executable=False): |
984 | """ | 1169 | """ |
985 | Locate `item` in the list of paths `path` (colon separated string like $PATH). | 1170 | Locate ``item`` in the list of paths ``path`` (colon separated string like |
986 | If `direction` is non-zero then the list is reversed. | 1171 | ``$PATH``). |
987 | If `history` is True then the list of candidates also returned as result,history. | 1172 | |
988 | If `executable` is True then the candidate has to be an executable file, | 1173 | Arguments: |
989 | otherwise the candidate simply has to exist. | 1174 | |
1175 | - ``path``: list of colon-separated paths. | ||
1176 | - ``item``: string to search for. | ||
1177 | - ``direction``: if non-zero then the list is reversed. | ||
1178 | - ``history``: if ``True`` then the list of candidates also returned as | ||
1179 | ``result,history`` where ``history`` is the list of previous path | ||
1180 | checked. | ||
1181 | - ``executable``: if ``True`` then the candidate defined by ``path`` has | ||
1182 | to be an executable file, otherwise if ``False`` the candidate simply | ||
1183 | has to exist. | ||
1184 | |||
1185 | Returns the item if found in the list of path, otherwise an empty string. | ||
1186 | If ``history`` is ``True``, return the list of previous path checked in a | ||
1187 | tuple with the found (or not found) item as ``(item, history)``. | ||
990 | """ | 1188 | """ |
991 | 1189 | ||
992 | if executable: | 1190 | if executable: |
@@ -1017,6 +1215,8 @@ def which(path, item, direction = 0, history = False, executable=False): | |||
1017 | def umask(new_mask): | 1215 | def umask(new_mask): |
1018 | """ | 1216 | """ |
1019 | Context manager to set the umask to a specific mask, and restore it afterwards. | 1217 | Context manager to set the umask to a specific mask, and restore it afterwards. |
1218 | |||
1219 | No return value. | ||
1020 | """ | 1220 | """ |
1021 | current_mask = os.umask(new_mask) | 1221 | current_mask = os.umask(new_mask) |
1022 | try: | 1222 | try: |
@@ -1027,7 +1227,17 @@ def umask(new_mask): | |||
1027 | def to_boolean(string, default=None): | 1227 | def to_boolean(string, default=None): |
1028 | """ | 1228 | """ |
1029 | Check input string and return boolean value True/False/None | 1229 | Check input string and return boolean value True/False/None |
1030 | depending upon the checks | 1230 | depending upon the checks. |
1231 | |||
1232 | Arguments: | ||
1233 | |||
1234 | - ``string``: input string. | ||
1235 | - ``default``: default return value if the input ``string`` is ``None``, | ||
1236 | ``0``, ``False`` or an empty string. | ||
1237 | |||
1238 | Returns ``True`` if the string is one of "y", "yes", "1", "true", ``False`` | ||
1239 | if the string is one of "n", "no", "0", or "false". Return ``default`` if | ||
1240 | the input ``string`` is ``None``, ``0``, ``False`` or an empty string. | ||
1031 | """ | 1241 | """ |
1032 | if not string: | 1242 | if not string: |
1033 | return default | 1243 | return default |
@@ -1048,18 +1258,17 @@ def contains(variable, checkvalues, truevalue, falsevalue, d): | |||
1048 | 1258 | ||
1049 | Arguments: | 1259 | Arguments: |
1050 | 1260 | ||
1051 | variable -- the variable name. This will be fetched and expanded (using | 1261 | - ``variable``: the variable name. This will be fetched and expanded (using |
1052 | d.getVar(variable)) and then split into a set(). | 1262 | d.getVar(variable)) and then split into a set(). |
1263 | - ``checkvalues``: if this is a string it is split on whitespace into a set(), | ||
1264 | otherwise coerced directly into a set(). | ||
1265 | - ``truevalue``: the value to return if checkvalues is a subset of variable. | ||
1266 | - ``falsevalue``: the value to return if variable is empty or if checkvalues is | ||
1267 | not a subset of variable. | ||
1268 | - ``d``: the data store. | ||
1053 | 1269 | ||
1054 | checkvalues -- if this is a string it is split on whitespace into a set(), | 1270 | Returns ``True`` if the variable contains the values specified, ``False`` |
1055 | otherwise coerced directly into a set(). | 1271 | otherwise. |
1056 | |||
1057 | truevalue -- the value to return if checkvalues is a subset of variable. | ||
1058 | |||
1059 | falsevalue -- the value to return if variable is empty or if checkvalues is | ||
1060 | not a subset of variable. | ||
1061 | |||
1062 | d -- the data store. | ||
1063 | """ | 1272 | """ |
1064 | 1273 | ||
1065 | val = d.getVar(variable) | 1274 | val = d.getVar(variable) |
@@ -1079,18 +1288,17 @@ def contains_any(variable, checkvalues, truevalue, falsevalue, d): | |||
1079 | 1288 | ||
1080 | Arguments: | 1289 | Arguments: |
1081 | 1290 | ||
1082 | variable -- the variable name. This will be fetched and expanded (using | 1291 | - ``variable``: the variable name. This will be fetched and expanded (using |
1083 | d.getVar(variable)) and then split into a set(). | 1292 | d.getVar(variable)) and then split into a set(). |
1084 | 1293 | - ``checkvalues``: if this is a string it is split on whitespace into a set(), | |
1085 | checkvalues -- if this is a string it is split on whitespace into a set(), | 1294 | otherwise coerced directly into a set(). |
1086 | otherwise coerced directly into a set(). | 1295 | - ``truevalue``: the value to return if checkvalues is a subset of variable. |
1087 | 1296 | - ``falsevalue``: the value to return if variable is empty or if checkvalues is | |
1088 | truevalue -- the value to return if checkvalues is a subset of variable. | 1297 | not a subset of variable. |
1298 | - ``d``: the data store. | ||
1089 | 1299 | ||
1090 | falsevalue -- the value to return if variable is empty or if checkvalues is | 1300 | Returns ``True`` if the variable contains any of the values specified, |
1091 | not a subset of variable. | 1301 | ``False`` otherwise. |
1092 | |||
1093 | d -- the data store. | ||
1094 | """ | 1302 | """ |
1095 | val = d.getVar(variable) | 1303 | val = d.getVar(variable) |
1096 | if not val: | 1304 | if not val: |
@@ -1105,17 +1313,17 @@ def contains_any(variable, checkvalues, truevalue, falsevalue, d): | |||
1105 | return falsevalue | 1313 | return falsevalue |
1106 | 1314 | ||
1107 | def filter(variable, checkvalues, d): | 1315 | def filter(variable, checkvalues, d): |
1108 | """Return all words in the variable that are present in the checkvalues. | 1316 | """Return all words in the variable that are present in the ``checkvalues``. |
1109 | 1317 | ||
1110 | Arguments: | 1318 | Arguments: |
1111 | 1319 | ||
1112 | variable -- the variable name. This will be fetched and expanded (using | 1320 | - ``variable``: the variable name. This will be fetched and expanded (using |
1113 | d.getVar(variable)) and then split into a set(). | 1321 | d.getVar(variable)) and then split into a set(). |
1114 | 1322 | - ``checkvalues``: if this is a string it is split on whitespace into a set(), | |
1115 | checkvalues -- if this is a string it is split on whitespace into a set(), | 1323 | otherwise coerced directly into a set(). |
1116 | otherwise coerced directly into a set(). | 1324 | - ``d``: the data store. |
1117 | 1325 | ||
1118 | d -- the data store. | 1326 | Returns a list of string. |
1119 | """ | 1327 | """ |
1120 | 1328 | ||
1121 | val = d.getVar(variable) | 1329 | val = d.getVar(variable) |
@@ -1131,8 +1339,27 @@ def filter(variable, checkvalues, d): | |||
1131 | 1339 | ||
1132 | def get_referenced_vars(start_expr, d): | 1340 | def get_referenced_vars(start_expr, d): |
1133 | """ | 1341 | """ |
1134 | :return: names of vars referenced in start_expr (recursively), in quasi-BFS order (variables within the same level | 1342 | Get the names of the variables referenced in a given expression. |
1135 | are ordered arbitrarily) | 1343 | |
1344 | Arguments: | ||
1345 | |||
1346 | - ``start_expr``: the expression where to look for variables references. | ||
1347 | |||
1348 | For example:: | ||
1349 | |||
1350 | ${VAR_A} string ${VAR_B} | ||
1351 | |||
1352 | Or:: | ||
1353 | |||
1354 | ${@d.getVar('VAR')} | ||
1355 | |||
1356 | If a variables makes references to other variables, the latter are also | ||
1357 | returned recursively. | ||
1358 | |||
1359 | - ``d``: the data store. | ||
1360 | |||
1361 | Returns the names of vars referenced in ``start_expr`` (recursively), in | ||
1362 | quasi-BFS order (variables within the same level are ordered arbitrarily). | ||
1136 | """ | 1363 | """ |
1137 | 1364 | ||
1138 | seen = set() | 1365 | seen = set() |
@@ -1212,7 +1439,9 @@ def multiprocessingpool(*args, **kwargs): | |||
1212 | return multiprocessing.Pool(*args, **kwargs) | 1439 | return multiprocessing.Pool(*args, **kwargs) |
1213 | 1440 | ||
1214 | def exec_flat_python_func(func, *args, **kwargs): | 1441 | def exec_flat_python_func(func, *args, **kwargs): |
1215 | """Execute a flat python function (defined with def funcname(args):...)""" | 1442 | """Execute a flat python function (defined with ``def funcname(args): ...``) |
1443 | |||
1444 | Returns the return value of the function.""" | ||
1216 | # Prepare a small piece of python code which calls the requested function | 1445 | # Prepare a small piece of python code which calls the requested function |
1217 | # To do this we need to prepare two things - a set of variables we can use to pass | 1446 | # To do this we need to prepare two things - a set of variables we can use to pass |
1218 | # the values of arguments into the calling function, and the list of arguments for | 1447 | # the values of arguments into the calling function, and the list of arguments for |
@@ -1238,48 +1467,57 @@ def edit_metadata(meta_lines, variables, varfunc, match_overrides=False): | |||
1238 | """Edit lines from a recipe or config file and modify one or more | 1467 | """Edit lines from a recipe or config file and modify one or more |
1239 | specified variable values set in the file using a specified callback | 1468 | specified variable values set in the file using a specified callback |
1240 | function. Lines are expected to have trailing newlines. | 1469 | function. Lines are expected to have trailing newlines. |
1241 | Parameters: | 1470 | |
1242 | meta_lines: lines from the file; can be a list or an iterable | 1471 | Arguments: |
1243 | (e.g. file pointer) | 1472 | |
1244 | variables: a list of variable names to look for. Functions | 1473 | - ``meta_lines``: lines from the file; can be a list or an iterable |
1245 | may also be specified, but must be specified with '()' at | 1474 | (e.g. file pointer) |
1246 | the end of the name. Note that the function doesn't have | 1475 | - ``variables``: a list of variable names to look for. Functions |
1247 | any intrinsic understanding of :append, :prepend, :remove, | 1476 | may also be specified, but must be specified with ``()`` at |
1248 | or overrides, so these are considered as part of the name. | 1477 | the end of the name. Note that the function doesn't have |
1249 | These values go into a regular expression, so regular | 1478 | any intrinsic understanding of ``:append``, ``:prepend``, ``:remove``, |
1250 | expression syntax is allowed. | 1479 | or overrides, so these are considered as part of the name. |
1251 | varfunc: callback function called for every variable matching | 1480 | These values go into a regular expression, so regular |
1252 | one of the entries in the variables parameter. The function | 1481 | expression syntax is allowed. |
1253 | should take four arguments: | 1482 | - ``varfunc``: callback function called for every variable matching |
1254 | varname: name of variable matched | 1483 | one of the entries in the variables parameter. |
1255 | origvalue: current value in file | 1484 | |
1256 | op: the operator (e.g. '+=') | 1485 | The function should take four arguments: |
1257 | newlines: list of lines up to this point. You can use | 1486 | |
1258 | this to prepend lines before this variable setting | 1487 | - ``varname``: name of variable matched |
1259 | if you wish. | 1488 | - ``origvalue``: current value in file |
1260 | and should return a four-element tuple: | 1489 | - ``op``: the operator (e.g. ``+=``) |
1261 | newvalue: new value to substitute in, or None to drop | 1490 | - ``newlines``: list of lines up to this point. You can use |
1262 | the variable setting entirely. (If the removal | 1491 | this to prepend lines before this variable setting |
1263 | results in two consecutive blank lines, one of the | 1492 | if you wish. |
1264 | blank lines will also be dropped). | 1493 | |
1265 | newop: the operator to use - if you specify None here, | 1494 | And should return a four-element tuple: |
1266 | the original operation will be used. | 1495 | |
1267 | indent: number of spaces to indent multi-line entries, | 1496 | - ``newvalue``: new value to substitute in, or ``None`` to drop |
1268 | or -1 to indent up to the level of the assignment | 1497 | the variable setting entirely. (If the removal |
1269 | and opening quote, or a string to use as the indent. | 1498 | results in two consecutive blank lines, one of the |
1270 | minbreak: True to allow the first element of a | 1499 | blank lines will also be dropped). |
1271 | multi-line value to continue on the same line as | 1500 | - ``newop``: the operator to use - if you specify ``None`` here, |
1272 | the assignment, False to indent before the first | 1501 | the original operation will be used. |
1273 | element. | 1502 | - ``indent``: number of spaces to indent multi-line entries, |
1274 | To clarify, if you wish not to change the value, then you | 1503 | or ``-1`` to indent up to the level of the assignment |
1275 | would return like this: return origvalue, None, 0, True | 1504 | and opening quote, or a string to use as the indent. |
1276 | match_overrides: True to match items with _overrides on the end, | 1505 | - ``minbreak``: ``True`` to allow the first element of a |
1277 | False otherwise | 1506 | multi-line value to continue on the same line as |
1507 | the assignment, ``False`` to indent before the first | ||
1508 | element. | ||
1509 | |||
1510 | To clarify, if you wish not to change the value, then you | ||
1511 | would return like this:: | ||
1512 | |||
1513 | return origvalue, None, 0, True | ||
1514 | - ``match_overrides``: True to match items with _overrides on the end, | ||
1515 | False otherwise | ||
1516 | |||
1278 | Returns a tuple: | 1517 | Returns a tuple: |
1279 | updated: | 1518 | |
1280 | True if changes were made, False otherwise. | 1519 | - ``updated``: ``True`` if changes were made, ``False`` otherwise. |
1281 | newlines: | 1520 | - ``newlines``: Lines after processing. |
1282 | Lines after processing | ||
1283 | """ | 1521 | """ |
1284 | 1522 | ||
1285 | var_res = {} | 1523 | var_res = {} |
@@ -1423,12 +1661,13 @@ def edit_metadata(meta_lines, variables, varfunc, match_overrides=False): | |||
1423 | 1661 | ||
1424 | 1662 | ||
1425 | def edit_metadata_file(meta_file, variables, varfunc): | 1663 | def edit_metadata_file(meta_file, variables, varfunc): |
1426 | """Edit a recipe or config file and modify one or more specified | 1664 | """Edit a recipe or configuration file and modify one or more specified |
1427 | variable values set in the file using a specified callback function. | 1665 | variable values set in the file using a specified callback function. |
1428 | The file is only written to if the value(s) actually change. | 1666 | The file is only written to if the value(s) actually change. |
1429 | This is basically the file version of edit_metadata(), see that | 1667 | This is basically the file version of ``bb.utils.edit_metadata()``, see that |
1430 | function's description for parameter/usage information. | 1668 | function's description for parameter/usage information. |
1431 | Returns True if the file was written to, False otherwise. | 1669 | |
1670 | Returns ``True`` if the file was written to, ``False`` otherwise. | ||
1432 | """ | 1671 | """ |
1433 | with open(meta_file, 'r') as f: | 1672 | with open(meta_file, 'r') as f: |
1434 | (updated, newlines) = edit_metadata(f, variables, varfunc) | 1673 | (updated, newlines) = edit_metadata(f, variables, varfunc) |
@@ -1439,20 +1678,24 @@ def edit_metadata_file(meta_file, variables, varfunc): | |||
1439 | 1678 | ||
1440 | 1679 | ||
1441 | def edit_bblayers_conf(bblayers_conf, add, remove, edit_cb=None): | 1680 | def edit_bblayers_conf(bblayers_conf, add, remove, edit_cb=None): |
1442 | """Edit bblayers.conf, adding and/or removing layers | 1681 | """Edit ``bblayers.conf``, adding and/or removing layers. |
1443 | Parameters: | 1682 | |
1444 | bblayers_conf: path to bblayers.conf file to edit | 1683 | Arguments: |
1445 | add: layer path (or list of layer paths) to add; None or empty | 1684 | |
1446 | list to add nothing | 1685 | - ``bblayers_conf``: path to ``bblayers.conf`` file to edit |
1447 | remove: layer path (or list of layer paths) to remove; None or | 1686 | - ``add``: layer path (or list of layer paths) to add; ``None`` or empty |
1448 | empty list to remove nothing | 1687 | list to add nothing |
1449 | edit_cb: optional callback function that will be called after | 1688 | - ``remove``: layer path (or list of layer paths) to remove; ``None`` or |
1450 | processing adds/removes once per existing entry. | 1689 | empty list to remove nothing |
1690 | - ``edit_cb``: optional callback function that will be called | ||
1691 | after processing adds/removes once per existing entry. | ||
1692 | |||
1451 | Returns a tuple: | 1693 | Returns a tuple: |
1452 | notadded: list of layers specified to be added but weren't | 1694 | |
1453 | (because they were already in the list) | 1695 | - ``notadded``: list of layers specified to be added but weren't |
1454 | notremoved: list of layers that were specified to be removed | 1696 | (because they were already in the list) |
1455 | but weren't (because they weren't in the list) | 1697 | - ``notremoved``: list of layers that were specified to be removed |
1698 | but weren't (because they weren't in the list) | ||
1456 | """ | 1699 | """ |
1457 | 1700 | ||
1458 | def remove_trailing_sep(pth): | 1701 | def remove_trailing_sep(pth): |
@@ -1572,7 +1815,22 @@ def get_collection_res(d): | |||
1572 | 1815 | ||
1573 | 1816 | ||
1574 | def get_file_layer(filename, d, collection_res={}): | 1817 | def get_file_layer(filename, d, collection_res={}): |
1575 | """Determine the collection (as defined by a layer's layer.conf file) containing the specified file""" | 1818 | """Determine the collection (or layer name, as defined by a layer's |
1819 | ``layer.conf`` file) containing the specified file. | ||
1820 | |||
1821 | Arguments: | ||
1822 | |||
1823 | - ``filename``: the filename to look for. | ||
1824 | - ``d``: the data store. | ||
1825 | - ``collection_res``: dictionary with the layer names as keys and file | ||
1826 | patterns to match as defined with the BBFILE_COLLECTIONS and | ||
1827 | BBFILE_PATTERN variables respectively. The return value of | ||
1828 | ``bb.utils.get_collection_res()`` is the default if this variable is | ||
1829 | not specified. | ||
1830 | |||
1831 | Returns the layer name containing the file. If multiple layers contain the | ||
1832 | file, the last matching layer name from collection_res is returned. | ||
1833 | """ | ||
1576 | if not collection_res: | 1834 | if not collection_res: |
1577 | collection_res = get_collection_res(d) | 1835 | collection_res = get_collection_res(d) |
1578 | 1836 | ||
@@ -1610,7 +1868,13 @@ class PrCtlError(Exception): | |||
1610 | 1868 | ||
1611 | def signal_on_parent_exit(signame): | 1869 | def signal_on_parent_exit(signame): |
1612 | """ | 1870 | """ |
1613 | Trigger signame to be sent when the parent process dies | 1871 | Trigger ``signame`` to be sent when the parent process dies. |
1872 | |||
1873 | Arguments: | ||
1874 | |||
1875 | - ``signame``: name of the signal. See ``man signal``. | ||
1876 | |||
1877 | No return value. | ||
1614 | """ | 1878 | """ |
1615 | signum = getattr(signal, signame) | 1879 | signum = getattr(signal, signame) |
1616 | # http://linux.die.net/man/2/prctl | 1880 | # http://linux.die.net/man/2/prctl |
@@ -1697,6 +1961,13 @@ def disable_network(uid=None, gid=None): | |||
1697 | Disable networking in the current process if the kernel supports it, else | 1961 | Disable networking in the current process if the kernel supports it, else |
1698 | just return after logging to debug. To do this we need to create a new user | 1962 | just return after logging to debug. To do this we need to create a new user |
1699 | namespace, then map back to the original uid/gid. | 1963 | namespace, then map back to the original uid/gid. |
1964 | |||
1965 | Arguments: | ||
1966 | |||
1967 | - ``uid``: original user id. | ||
1968 | - ``gid``: original user group id. | ||
1969 | |||
1970 | No return value. | ||
1700 | """ | 1971 | """ |
1701 | libc = ctypes.CDLL('libc.so.6') | 1972 | libc = ctypes.CDLL('libc.so.6') |
1702 | 1973 | ||
@@ -1766,9 +2037,14 @@ class LogCatcher(logging.Handler): | |||
1766 | 2037 | ||
1767 | def is_semver(version): | 2038 | def is_semver(version): |
1768 | """ | 2039 | """ |
1769 | Is the version string following the semver semantic? | 2040 | Arguments: |
2041 | |||
2042 | - ``version``: the version string. | ||
1770 | 2043 | ||
1771 | https://semver.org/spec/v2.0.0.html | 2044 | Returns ``True`` if the version string follow semantic versioning, ``False`` |
2045 | otherwise. | ||
2046 | |||
2047 | See https://semver.org/spec/v2.0.0.html. | ||
1772 | """ | 2048 | """ |
1773 | regex = re.compile( | 2049 | regex = re.compile( |
1774 | r""" | 2050 | r""" |
@@ -1806,6 +2082,8 @@ def rename(src, dst): | |||
1806 | def environment(**envvars): | 2082 | def environment(**envvars): |
1807 | """ | 2083 | """ |
1808 | Context manager to selectively update the environment with the specified mapping. | 2084 | Context manager to selectively update the environment with the specified mapping. |
2085 | |||
2086 | No return value. | ||
1809 | """ | 2087 | """ |
1810 | backup = dict(os.environ) | 2088 | backup = dict(os.environ) |
1811 | try: | 2089 | try: |
@@ -1822,6 +2100,13 @@ def is_local_uid(uid=''): | |||
1822 | """ | 2100 | """ |
1823 | Check whether uid is a local one or not. | 2101 | Check whether uid is a local one or not. |
1824 | Can't use pwd module since it gets all UIDs, not local ones only. | 2102 | Can't use pwd module since it gets all UIDs, not local ones only. |
2103 | |||
2104 | Arguments: | ||
2105 | |||
2106 | - ``uid``: user id. If not specified the user id is determined from | ||
2107 | ``os.getuid()``. | ||
2108 | |||
2109 | Returns ``True`` is the user id is local, ``False`` otherwise. | ||
1825 | """ | 2110 | """ |
1826 | if not uid: | 2111 | if not uid: |
1827 | uid = os.getuid() | 2112 | uid = os.getuid() |
@@ -1836,7 +2121,7 @@ def is_local_uid(uid=''): | |||
1836 | 2121 | ||
1837 | def mkstemp(suffix=None, prefix=None, dir=None, text=False): | 2122 | def mkstemp(suffix=None, prefix=None, dir=None, text=False): |
1838 | """ | 2123 | """ |
1839 | Generates a unique filename, independent of time. | 2124 | Generates a unique temporary file, independent of time. |
1840 | 2125 | ||
1841 | mkstemp() in glibc (at least) generates unique file names based on the | 2126 | mkstemp() in glibc (at least) generates unique file names based on the |
1842 | current system time. When combined with highly parallel builds, and | 2127 | current system time. When combined with highly parallel builds, and |
@@ -1845,6 +2130,18 @@ def mkstemp(suffix=None, prefix=None, dir=None, text=False): | |||
1845 | 2130 | ||
1846 | This function adds additional entropy to the file name so that a collision | 2131 | This function adds additional entropy to the file name so that a collision |
1847 | is independent of time and thus extremely unlikely. | 2132 | is independent of time and thus extremely unlikely. |
2133 | |||
2134 | Arguments: | ||
2135 | |||
2136 | - ``suffix``: filename suffix. | ||
2137 | - ``prefix``: filename prefix. | ||
2138 | - ``dir``: directory where the file will be created. | ||
2139 | - ``text``: if ``True``, the file is opened in text mode. | ||
2140 | |||
2141 | Returns a tuple containing: | ||
2142 | |||
2143 | - the file descriptor for the created file | ||
2144 | - the name of the file. | ||
1848 | """ | 2145 | """ |
1849 | entropy = "".join(random.choices("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", k=20)) | 2146 | entropy = "".join(random.choices("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", k=20)) |
1850 | if prefix: | 2147 | if prefix: |
@@ -1855,12 +2152,20 @@ def mkstemp(suffix=None, prefix=None, dir=None, text=False): | |||
1855 | 2152 | ||
1856 | def path_is_descendant(descendant, ancestor): | 2153 | def path_is_descendant(descendant, ancestor): |
1857 | """ | 2154 | """ |
1858 | Returns True if the path `descendant` is a descendant of `ancestor` | 2155 | Returns ``True`` if the path ``descendant`` is a descendant of ``ancestor`` |
1859 | (including being equivalent to `ancestor` itself). Otherwise returns False. | 2156 | (including being equivalent to ``ancestor`` itself). Otherwise returns |
2157 | ``False``. | ||
2158 | |||
1860 | Correctly accounts for symlinks, bind mounts, etc. by using | 2159 | Correctly accounts for symlinks, bind mounts, etc. by using |
1861 | os.path.samestat() to compare paths | 2160 | ``os.path.samestat()`` to compare paths. |
2161 | |||
2162 | May raise any exception that ``os.stat()`` raises. | ||
2163 | |||
2164 | Arguments: | ||
1862 | 2165 | ||
1863 | May raise any exception that os.stat() raises | 2166 | - ``descendant``: path to check for being an ancestor. |
2167 | - ``ancestor``: path to the ancestor ``descendant`` will be checked | ||
2168 | against. | ||
1864 | """ | 2169 | """ |
1865 | 2170 | ||
1866 | ancestor_stat = os.stat(ancestor) | 2171 | ancestor_stat = os.stat(ancestor) |