Skip to content

yex.Filename

yex.filename #

Filename #

Bases: str

The name of a file on disk.

This can just be a filename. But if you call resolve(), it will attempt to find you an existing file with that name.

abspath property #

Returns our absolute path.

(We may not currently exist, so this file may not currently exist either.)

basename property #

The name of the file, without any path and without any extension.

For example, "/usr/share/wombat.pdf" returns "wombat".

Returns str (not Filename).

from_parser(parser, default_extension='tex') classmethod #

Reads a filename from a token stream.

Filenames must consist only of Letter and Other tokens.

Parameters:

Name Type Description Default
parser yex.parse.Parser

the stream to read the filename from

required
default_extension typing.Union[str, None]

the extension to add if the filename has no extension. If it doesn't begin with a dot, a dot is added anyway. If it's None, no extension will be added.

'tex'

Raises:

Type Description
NeededFilenameError

if there isn't a filename to be found.

Source code in yex/filename.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
@classmethod
def from_parser(cls,
                parser: 'yex.parse.Parser',
                default_extension: Union[str, None] = 'tex',
        ) -> Self:
    """
    Reads a filename from a token stream.

    Filenames must consist only of Letter and Other tokens.

    Args:
        parser: the stream to read the filename from
        default_extension: the extension to add
            if the filename has no extension. If it doesn't begin
            with a dot, a dot is added anyway. If it's None,
            no extension will be added.

    Raises:
       NeededFilenameError: if there isn't a filename to be found.
    """

    logger.debug("Setting filename from parser")

    parser.eat_optional_spaces()
    name = ''

    for token in parser.another(level='reading'):
        if isinstance(token, (yex.parse.Letter, yex.parse.Other)):
            name += token.ch
        else:
            parser.push(token)
            break

    if name=='':
        raise yex.exception.NeededFilenameError()

    if default_extension:
        name = cls._maybe_add_extension(name, default_extension)

    result = cls(name,
            default_extension = None,
            )
    logger.debug('Filename found: %s', result)
    return result

resolve() #

Attempts to find an existing file with the given name.

If one is found, we return a new Filename with the absolute path.

If one is not found, we raise FileNotFoundError.

Raises:

Type Description
FileNotFoundError

if there is no such file.

Returns:

Type Description
typing.Self

Filename

Source code in yex/filename.py
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def resolve(self) -> Self:
    """
    Attempts to find an existing file with the given name.

    If one is found, we return a new Filename with the
    absolute path.

    If one is not found, we raise FileNotFoundError.

    Raises:
        FileNotFoundError: if there is no such file.

    Returns:
        Filename
    """

    cls = self.__class__

    def _exists(name):
        if os.path.exists(name):
            logger.debug(f"    -- %s exists", name)
            return os.path.abspath(name)
        else:
            logger.debug(f"    -- %s does not exist", name)
            return None

    logger.debug(f"Searching for {self.name}...")

    if os.path.isabs(self.name):

        path = _exists(self.name)

        if path is not None:
            logger.debug("  -- absolute path, exists")
            return cls(path,
                    default_extension = None,
                    )

        logger.debug("  -- absolute path, does not exist")
        raise FileNotFoundError(self)

    in_current_dir = _exists(os.path.abspath(self.name))
    if in_current_dir is not None:
        logger.debug("  -- exists in current directory")
        return cls(in_current_dir,
                default_extension = None,
                )

    config_dirs = [
            appdirs.user_data_dir(appname=APPNAME),
            appdirs.site_data_dir(appname=APPNAME),
    ]

    for config_dir in config_dirs:

        path = _exists(
                os.path.join(
                    config_dir,
                    self.name))

        if path is not None:
            logger.debug("    -- exists in %s", path)
            return cls(path,
                default_extension = None,
                    )

    logger.debug("  -- can't find it")
    raise FileNotFoundError(self)