Quick answer: Use pathlib.Path(path).stem for the final filename without its final suffix, or os.path.splitext() when you need the root and extension as a pair. Hidden files and compound suffixes need an explicit policy.

To get a filename without its extension in Python, use Path.stem from pathlib for most new code. It reads clearly, works with full paths, and avoids manual string slicing.
The older os.path.splitext() function is still useful, especially in codebases that already use the os.path module. The official PurePath.stem documentation describes the pathlib property, and the official os.path.splitext documentation explains how Python separates a final extension from a path.
This guide covers simple filenames, full paths, compound extensions, and folder loops. For related file handling tasks, see PythonPool guides on basename extraction, checking whether a file exists, getting file size, looping through files in a directory, and getting the current directory.
Use pathlib Path.stem
Path.stem returns the final path component without its last suffix. It is the simplest option when you already have a path or can create one.
from pathlib import Path
path = Path("reports/sales.csv")
print(path.stem)
The output is sales. The folder name is ignored because stem works on the final part of the path.
This approach is concise and portable. It works the same way on macOS, Linux, and Windows paths when you use Path objects.
Handle Compound Extensions
A file such as archive.tar.gz has more than one suffix. Path.stem removes only the final suffix, so the result is archive.tar. If you need to remove all suffixes, remove each suffix deliberately.
from pathlib import Path
path = Path("archive.tar.gz")
name = path.name
for suffix in path.suffixes:
name = name.removesuffix(suffix)
print(name)
This returns archive. Use this pattern only when every suffix should be removed. For many files, keeping .tar in the stem is useful because it describes the archive type.
The important point is to choose the behavior that matches your file naming rules instead of removing dots blindly.

Use os.path.splitext
os.path.splitext() returns a pair: the path without the final extension and the extension itself.
import os
filename = "sales.csv"
name, extension = os.path.splitext(filename)
print(name)
print(extension)
This prints sales and .csv. It is a stable standard-library option for scripts that already use os.path.
Like Path.stem, it removes only the final extension. That behavior is usually correct for ordinary text, data, and source files.
Get The Name From A Full Path
When you start with a full path string, first extract the base filename, then remove the extension.
import os
path = "/data/reports/sales.csv"
filename = os.path.basename(path)
name, _extension = os.path.splitext(filename)
print(name)
The result is sales. The underscore prefix on _extension signals that the extension is intentionally unused.
If you use pathlib, Path(path).stem can do this in one expression. Use the style that matches the rest of your code.

Get Stems While Looping Through Files
File stems are often needed while scanning a folder, for example when building output names or labels from input files.
from pathlib import Path
folder = Path("reports")
for path in folder.glob("*.csv"):
print(path.stem)
glob("*.csv") limits the loop to matching files, and path.stem returns each filename without the extension.
This is cleaner than splitting every file name manually inside the loop. It also keeps the extension filter and stem extraction easy to read.
Create A Helper Function
If many parts of a project need the same behavior, wrap it in a small helper. That keeps your extension rule in one place.
from pathlib import Path
def filename_without_extension(file_path):
path = Path(file_path)
return path.stem
print(filename_without_extension("notes.txt"))
print(filename_without_extension("/tmp/archive.tar.gz"))
This helper removes only the final suffix, so the second output is archive.tar. That is often the expected result for compressed archives.
If your project needs to remove all suffixes, create a separate helper with a clear name such as filename_without_suffixes. Avoid mixing both meanings under one function name.
When Not To Use split
String methods such as split(".") or rfind(".") can work for very small examples, but they are easier to get wrong. Hidden files, folder names with dots, and compound suffixes can all produce surprising results.
Use Path.stem or os.path.splitext() when the input is a file path. Those APIs encode the path rules for you and make the intent obvious to future readers.
Manual string splitting is best reserved for data that is not a path. Once the value represents a file location, path-aware APIs are the safer choice.

Practical Selection Guide
Use Path(filename).stem for modern scripts and applications. Use os.path.splitext(filename)[0] in older os.path-based code. Use Path(path).name when you need the filename with its extension, and use Path(path).stem when you need the filename without it.
For batch jobs, decide up front whether compound suffixes should stay or be removed. A data file named backup.tar.gz may need the stem backup.tar in one workflow and backup in another. Write that rule explicitly so results stay predictable.
The practical default is simple: prefer pathlib, use stem for the final filename part, and reach for splitext() only when your codebase already uses os.path.
Use pathlib For Readable Paths
Path.stem removes the final suffix from the final path component and leaves the parent path out of the returned stem. Path.name gives the filename, while suffix and suffixes expose one or all recognized final suffixes. Use the object-oriented API when the rest of the code already uses pathlib.
from pathlib import Path
path = Path("reports/annual.tar.gz")
print(path.name)
print(path.stem)
print(path.suffix)
print(path.suffixes)

Use splitext For A Root And Extension
os.path.splitext() returns (root, ext), preserving the directory portion in root. It removes only the final extension and treats a leading dot in a final component as part of a hidden filename rather than a normal extension.
import os
for value in ["report.csv", "archive.tar.gz", ".env"]:
root, extension = os.path.splitext(value)
print(value, root, extension)
Decide What Compound Means
There is no universal definition of an extension. For archive.tar.gz, stem returns archive.tar and suffixes returns [‘.tar’, ‘.gz’]. If the application treats .tar.gz as one format, remove the known compound suffix rather than repeatedly stripping every period. Keep the rule close to the file-format boundary.
from pathlib import Path
path = Path("archive.tar.gz")
if path.name.endswith(".tar.gz"):
base = path.name.removesuffix(".tar.gz")
print(base)
Compare the official pathlib and splitext() behavior for the filenames your application accepts.
For related filesystem work, continue with copying files, renaming files, and finding the current directory.
Frequently Asked Questions
How do I get a filename without its extension in Python?
Use pathlib.Path(path).stem for the final filename component without its final suffix.
What does os.path.splitext() return?
It returns a pair containing the path root and the final extension, including the leading period when one exists.
How do I remove all extensions from a filename?
Use Path.suffixes with a deliberate policy or repeatedly split suffixes; do not assume every period represents an extension.
How are hidden files such as .env handled?
A leading dot in a final component is treated as part of the name, so .env has no ordinary suffix under pathlib and splitext rules.