(passfile: pathlib.Path)
| 92 | |
| 93 | |
| 94 | def _read_password_file(passfile: pathlib.Path) \ |
| 95 | -> typing.List[typing.Tuple[str, ...]]: |
| 96 | |
| 97 | passtab = [] |
| 98 | |
| 99 | try: |
| 100 | if not passfile.exists(): |
| 101 | return [] |
| 102 | |
| 103 | if not passfile.is_file(): |
| 104 | warnings.warn( |
| 105 | 'password file {!r} is not a plain file'.format(passfile)) |
| 106 | |
| 107 | return [] |
| 108 | |
| 109 | if _system != 'Windows': |
| 110 | if passfile.stat().st_mode & (stat.S_IRWXG | stat.S_IRWXO): |
| 111 | warnings.warn( |
| 112 | 'password file {!r} has group or world access; ' |
| 113 | 'permissions should be u=rw (0600) or less'.format( |
| 114 | passfile)) |
| 115 | |
| 116 | return [] |
| 117 | |
| 118 | with passfile.open('rt') as f: |
| 119 | for line in f: |
| 120 | line = line.strip() |
| 121 | if not line or line.startswith('#'): |
| 122 | # Skip empty lines and comments. |
| 123 | continue |
| 124 | # Backslash escapes both itself and the colon, |
| 125 | # which is a record separator. |
| 126 | line = line.replace(R'\\', '\n') |
| 127 | passtab.append(tuple( |
| 128 | p.replace('\n', R'\\') |
| 129 | for p in re.split(r'(?<!\\):', line, maxsplit=4) |
| 130 | )) |
| 131 | except IOError: |
| 132 | pass |
| 133 | |
| 134 | return passtab |
| 135 | |
| 136 | |
| 137 | def _read_password_from_pgpass( |
no outgoing calls
no test coverage detected
searching dependent graphs…