Update (2023-05-12)

I opened a PR to make slice generic. The change would introduce quite a few mypy errors in many existing projects. The good people at python/typeshed made it clear that until we have type variable defaults (proposed in PEP 696, but not yet accepted) and the slice type utilizes them, they will not accept the change to make it generic.

I will try to keep up to date on the progress with PEP 696 and to implement the missing changes as soon as possible.


Original answer

As it stands right now, the built-in slice type is not generic, so it has no type parameters (unlike e.g. list). There has been a long-standing discussion about this (since 2015) and the relevant typeshed issue is still open. IMO it should definitely be made generic, but it is unclear if/when that will happen.

slice arguments can be of any type (source). This means a statement like e.g. slice("foo", [-1], object()) will pass mypy --strict (even though it may be of questionable utility).

That means there is currently no way to constrain a slice type variable in terms of its start/stop/step attribute types.

And since you cannot even subclass slice, there is not even a way to easily make your own generic slice-like type.

Answer from Daniel Fainberg on Stack Overflow
🌐
Python
docs.python.org › 3 › c-api › slice.html
Slice Objects — Python 3.15.2 documentation
Return the length of the slice. Always successful. Doesn’t call Python code. Added in version 3.6.1. ... Part of the Stable ABI. The type of Python Ellipsis object.
🌐
W3Schools
w3schools.com › python › ref_func_slice.asp
Python slice() Function
abs() all() any() ascii() bin() bool() bytearray() bytes() callable() chr() compile() complex() delattr() dict() dir() divmod() enumerate() eval() exec() filter() float() format() frozenset() getattr() globals() hasattr() hex() id() input() int() isinstance() issubclass() iter() len() list() locals() map() max() memoryview() min() next() object() oct() open() ord() pow() print() range() reversed() round() set() setattr() slice() sorted() str() sum() super() tuple() type() vars() zip() Python String Methods ·
🌐
DataCamp
datacamp.com › home › tutorials › python › python slice: useful methods for everyday coding
Python Slice: Useful Methods for Everyday Coding | DataCamp
January 15, 2025 - As I said, slicing is a core feature in Python, allowing developers to extract portions of sequences like lists, strings, and tuples. Python offers two primary ways to slice sequences without importing anything: the slicing : syntax and the slice() function.
🌐
Railsware
railsware.com › home › engineering › indexing and slicing for lists, tuples, strings, other sequential types in python
Python Indexing and Slicing for Lists, Tuples, Strings, other Sequential Types | Railsware Blog
September 28, 2026 - Python supports slice notation for any sequential data type like lists, strings, tuples, bytes, bytearrays, and ranges. Also, any new data structure can add its support as well. This is greatly used (and abused) in NumPy and Pandas libraries, ...
🌐
Real Python
realpython.com › ref › builtin-functions › slice
slice() | Python’s Built-in Functions – Real Python
Returns a slice object that can be used to extract a portion of a sequence. Since Python 3.12, slice objects are hashable, provided that start, stop, and step are hashable, so they can be dictionary keys or set members.
🌐
The Python Coding Stack
thepythoncodingstack.com › notes from the near future › a slicing story
A Slicing Story - The Python Coding Stack
September 24, 2023 - You can read more about shallow and deep copies in an article I wrote in the pre-Substack era: Shallow and Deep Copy in Python and How to Use __copy__(). So, slicing creates a copy of the subset of the sequence, right? Not so fast… · I have used lists in all the examples in this article so far. You can slice other sequences, too: And this also creates a copy. When slicing strings or tuples, there's no other option other than creating a copy since they're immutable data types.
🌐
Python Tutorial
pythontutorial.net › home › advanced python › python slicing in depth
Python Slicing in Depth
March 27, 2025 - Everything in Python is an object including the slice. A slice is actually an object of the slice type.
Find elsewhere
🌐
Programiz
programiz.com › python-programming › methods › built-in › slice
Python slice() | Programiz
March 14, 2024 - The slice() function returns a slice object. In this tutorial, we will learn to use Python slice() function in detail with the help of examples.
🌐
The Teclado Blog
blog.teclado.com › python-slices
Python Slices - The Teclado Blog
April 7, 2019 - What you might have noticed from the example above is that slicing a sequence gives us a sequence of the same type back. Remember that strings are just sequences of characters, and are therefore perfect candidates for slicing! Instead of going through this process of defining a slice object, binding it to a variable, and then providing that variable name as part of the subscript syntax, we can do the following: t = (1, 2, 3, 4, 5) print(t[slice(1, 4)]) # (2, 3, 4) However, there is a faster way still, which we’re going to cover next. Python has an alternative syntax for defining a slice directly in the square brackets we use as part of the subscript syntax.
Top answer
1 of 6
113

You create a slice by calling slice with the same fields you would use if doing [start:end:step] notation:

Use with AIsl = slice(0,4)

To use the slice, just pass it as if it were the index into a list or string:

Use with AI>>> s = "ABCDEFGHIJKL"
>>> sl = slice(0,4)
>>> print(s[sl])
'ABCD'

Let's say you have a file of fixed-length text fields. You could define a list of slices to easily extract the values from each "record" in this file.

Use with AIdata = """\
0010GEORGE JETSON    12345 SPACESHIP ST   HOUSTON       TX
0020WILE E COYOTE    312 ACME BLVD        TUCSON        AZ
0030FRED FLINTSTONE  246 GRANITE LANE     BEDROCK       CA
0040JONNY QUEST      31416 SCIENCE AVE    PALO ALTO     CA""".splitlines()


fieldslices = [slice(*fielddef) for fielddef in [
    (0,4), (4, 21), (21,42), (42,56), (56,58),
    ]]
fields = "id name address city state".split()

for rec in data:
    for field,sl in zip(fields, fieldslices):
        print("{} : {}".format(field, rec[sl]))
    print('')

# or this same code using itemgetter, to make a function that
# extracts all slices from a string into a tuple of values
import operator
rec_reader = operator.itemgetter(*fieldslices)
for rec in data:
    for field, field_value in zip(fields, rec_reader(rec)):
        print("{} : {}".format(field, field_value))
    print('')

Prints:

Use with AIid : 0010
name : GEORGE JETSON    
address : 12345 SPACESHIP ST   
city : HOUSTON       
state : TX

id : 0020
name : WILE E COYOTE    
address : 312 ACME BLVD        
city : TUCSON        
state : AZ

id : 0030
name : FRED FLINTSTONE  
address : 246 GRANITE LANE     
city : BEDROCK       
state : CA

id : 0040
name : JONNY QUEST      
address : 31416 SCIENCE AVE    
city : PALO ALTO     
state : CA
2 of 6
41

Square brackets following a sequence denote either indexing or slicing depending on what's inside the brackets:

Use with AI>>> "Python rocks"[1]    # index
'y'
>>> "Python rocks"[1:10:2]    # slice
'yhnrc'

Both of these cases are handled by the __getitem__() method of the sequence (or __setitem__() if on the left of an equals sign.) The index or slice is passed to the methods as a single argument, and the way Python does this is by converting the slice notation, (1:10:2, in this case) to a slice object: slice(1,10,2).

So if you are defining your own sequence-like class or overriding the __getitem__ or __setitem__ or __delitem__ methods of another class, you need to test the index argument to determine if it is an int or a slice, and process accordingly:

Use with AIdef __getitem__(self, index):
    if isinstance(index, int):
        ...    # process index as an integer
    elif isinstance(index, slice):
        start, stop, step = index.indices(len(self))    # index is a slice
        ...    # process slice
    else:
        raise TypeError("index must be int or slice")

A slice object has three attributes: start, stop and step, and one method: indices, which takes a single argument, the length of the object, and returns a 3-tuple: (start, stop, step).

🌐
Codecademy
codecademy.com › docs › python › built-in functions › slice()
Python | Built-in Functions | slice() | Codecademy
September 26, 2025 - Creates a slice object that specifies how to slice sequences like strings, lists, tuples, and ranges
🌐
Python Morsels
pythonmorsels.com › implementing-slicing
Implementing slicing - Python Morsels
August 3, 2026 - That way slicing ProxySequence ... ProxySequence(string) >>> p[1:] ProxySequence('bcdefghi') Python's slicing syntax is powered by slice objects....
🌐
Simplilearn
simplilearn.com › home › resources › software development › your ultimate python tutorial for beginners › everything you need to know about python slicing
Everything You Need to Know About Python Slicing
January 26, 2025 - Python is a widely used, general-purpose programming language. So what is slicing and negative indices? Learn all about Python slicing, index, & more. Read On!
Address: 5851 Legacy Circle, 6th Floor, Plano, TX 75024 United States
🌐
Codingem
codingem.com › home › slicing in python: the slice() function & [::] notation
Slicing in Python: The slice() Function & [::] Notation
November 1, 2022 - Alternatively, you can use built-in slice objects when slicing iterables. In Python, there is a built-in type called a slice.
🌐
Analytics Vidhya
analyticsvidhya.com › home › python slicing: 9 useful methods for everyday coding
Python Slicing: 9 Useful Methods for Everyday Coding
May 16, 2025 - One is [start: end: step] and the other is the .slice(start, stop, step) function. In this section, first we will go through the syntax of these slicing operations, after this we will explore the major types of slicing that we can perform in Python.
🌐
Real Python
realpython.com › ref › glossary › slice
slice | Python Glossary – Real Python
An object that allows you to extract a portion of a sequence, such as a list, tuple, or string.
🌐
Toppr
toppr.com › guides › python-guide › references › methods-and-functions › methods › built-in › slice › python-slice
Python slice() function | What is a slice function in Python? |
July 14, 2021 - Python slice() function is a pre-defined Python function that returns a slice object that can be used to access specific data from strings, lists, tuples, etc. Python slice() is used to extract a subset of data elements that are stored in strings, tuples, lists, etc. as per the programmer's needs.
🌐
DEV Community
dev.to › mike-vincent › quarks-outlines-python-slice-objects-2dea
Quark's Outlines: Python Slice Objects - DEV Community
May 9, 2026 - You can also create a slice object yourself using the built-in slice() function. A slice object has three parts: a start, a stop, and a step. These tell Python where to begin, where to end, and how far to jump between values.
Top answer
1 of 1
8

You want a TypeVar with a bound of Sequence.

from typing import Sequence, TypeVar, cast

_T = TypeVar("_T", bound=Sequence)


def slice(seq: _T) -> _T:
    return cast(_T, seq[1:3])


assert slice("abcde") == "bc"
assert slice(b"xyz") == b"yz"
assert slice([2, 7, 1, 8]) == [7, 1]

Note the cast inside slice is necessary because the slice operator isn't actually guaranteed (at least as of Python 3.8 according to the Sequence abstract class) to return the same type as the original object.

You can get around this and have stronger typing by defining your own Slicable protocol (for which you need to stop shadowing the builtin slice type):

from typing import Protocol, TypeVar

_S = TypeVar('_S', bound='Slicable')


class Slicable(Protocol):
    def __getitem__(self: _S, i: slice) -> _S: ...


_T = TypeVar('_T', bound=Slicable)


def my_slice(seq: _T) -> _T:
    return seq[1:3]


assert my_slice("abcde") == "bc"
assert my_slice(b"xyz") == b"yz"
assert my_slice([2, 7, 1, 8]) == [7, 1]

With this typing no casting is needed, and my_slice will only permit arguments whose types implement slicing operations that return the same type of object. For example, if I define a class whose __getitem__ returns an arbitrary string:

class TrickySlicable:
    def __getitem__(self, i: slice) -> str:
        return "foo"

my_slice(TrickySlicable())  # error: Value of type variable "_T" of "my_slice" cannot be "TrickySlicable"

Similar failures are produced for dict arguments (which implement __getitem__ but not with a slice as the index) and types that don't implement __getitem__ at all.