# Buggy code
def itransform(
    self,
    points: Any,
    switch: bool = False,
    time_3rd: bool = False,
    radians: bool = False,
    errcheck: bool = False,
    direction: Union[TransformDirection, str] = TransformDirection.FORWARD,
) -> Iterator[Iterable]:
    """
    Iterator/generator version of the function pyproj.Transformer.transform.

    .. versionadded:: 2.1.1 errcheck
    .. versionadded:: 2.2.0 direction

    Parameters
    ----------
    points: list
        List of point tuples.
    switch: boolean, optional
        If True x, y or lon,lat coordinates of points are switched to y, x
        or lat, lon. Default is False.
    time_3rd: boolean, optional
        If the input coordinates are 3 dimensional and the 3rd dimension is time.
    radians: boolean, optional
        If True, will expect input data to be in radians and will return radians
        if the projection is geographic. Default is False (degrees). Ignored for
        pipeline transformations.
    errcheck: boolean, optional (default False)
        If True an exception is raised if the transformation is invalid.
        By default errcheck=False and an invalid transformation
        returns ``inf`` and no exception is raised.
    direction: pyproj.enums.TransformDirection, optional
        The direction of the transform.
        Default is :attr:`pyproj.enums.TransformDirection.FORWARD`.


    Example:

    >>> from pyproj import Transformer
    >>> transformer = Transformer.from_crs(4326, 2100)
    >>> points = [(22.95, 40.63), (22.81, 40.53), (23.51, 40.86)]
    >>> for pt in transformer.itransform(points): '{:.3f} {:.3f}'.format(*pt)
    '2221638.801 2637034.372'
    '2212924.125 2619851.898'
    '2238294.779 2703763.736'
    >>> pipeline_str = (
    ...     "+proj=pipeline +step +proj=longlat +ellps=WGS84 "
    ...     "+step +proj=unitconvert +xy_in=rad +xy_out=deg"
    ... )
    >>> pipe_trans = Transformer.from_pipeline(pipeline_str)
    >>> for pt in pipe_trans.itransform([(2.1, 0.001)]):
    ...     '{:.3f} {:.3f}'.format(*pt)
    '120.321 0.057'
    >>> transproj = Transformer.from_crs(
    ...     {"proj":'geocent', "ellps":'WGS84', "datum":'WGS84'},
    ...     "EPSG:4326",
    ...     always_xy=True,
    ... )
    >>> for pt in transproj.itransform(
    ...     [(-2704026.010, -4253051.810, 3895878.820)],
    ...     radians=True,
    ... ):
    ...     '{:.3f} {:.3f} {:.3f}'.format(*pt)
    '-2.137 0.661 -20.531'
    >>> transprojr = Transformer.from_crs(
    ...     "EPSG:4326",
    ...     {"proj":'geocent', "ellps":'WGS84', "datum":'WGS84'},
    ...     always_xy=True,
    ... )
    >>> for pt in transprojr.itransform(
    ...     [(-2.137, 0.661, -20.531)],
    ...     radians=True
    ... ):
    ...     '{:.3f} {:.3f} {:.3f}'.format(*pt)
    '-2704214.394 -4254414.478 3894270.731'
    >>> transproj_eq = Transformer.from_proj(
    ...     'EPSG:4326',
    ...     '+proj=longlat +datum=WGS84 +no_defs +type=crs',
    ...     always_xy=True,
    ...     skip_equivalent=True
    ... )
    >>> for pt in transproj_eq.itransform([(-2.137, 0.661)]):
    ...     '{:.3f} {:.3f}'.format(*pt)
    '-2.137 0.661'

    """
    it = iter(points)  # point iterator
    # get first point to check stride
    try:
        fst_pt = next(it)
    except StopIteration:
        raise ValueError("iterable must contain at least one point")

    stride = len(fst_pt)
    if stride not in (2, 3, 4):
        raise ValueError("points can contain up to 4 coordinates")

    if time_3rd and stride != 3:
        raise ValueError("'time_3rd' is only valid for 3 coordinates.")

    # create a coordinate sequence generator etc. x1,y1,z1,x2,y2,z2,....
    # chain so the generator returns the first point that was already acquired
    coord_gen = chain(fst_pt, (coords[c] for coords in it for c in range(stride)))

    while True:
        # create a temporary buffer storage for
        # the next 64 points (64*stride*8 bytes)
        buff = array("d", islice(coord_gen, 0, 64 * stride))
        if len(buff) == 0:
            break

        self._transformer._transform_sequence(
            stride,
            buff,
            switch=switch,
            direction=direction,
            time_3rd=time_3rd,
            radians=radians,
            errcheck=errcheck,
        )

        for pt in zip(*([iter(buff)] * stride)):
            yield pt


# Traceback (pyproj.exceptions.ProjError)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/pyproj/transformer.py", line 446, in transform
errcheck=errcheck,
File "pyproj/_transformer.pyx", line 463, in pyproj._transformer._Transformer._transform
pyproj.exceptions.ProjError: transform error: latitude or longitude exceeded limits

# Fixed code
def itransform(
    self,
    points: Any,
    switch: bool = False,
    time_3rd: bool = False,
    radians: bool = False,
    errcheck: bool = False,
    direction: Union[TransformDirection, str] = TransformDirection.FORWARD,
) -> Iterator[Iterable]:
    """
    Iterator/generator version of the function pyproj.Transformer.transform.

    .. versionadded:: 2.1.1 errcheck
    .. versionadded:: 2.2.0 direction

    Parameters
    ----------
    points: list
        List of point tuples.
    switch: boolean, optional
        If True x, y or lon,lat coordinates of points are switched to y, x
        or lat, lon. Default is False.
    time_3rd: boolean, optional
        If the input coordinates are 3 dimensional and the 3rd dimension is time.
    radians: boolean, optional
        If True, will expect input data to be in radians and will return radians
        if the projection is geographic. Default is False (degrees). Ignored for
        pipeline transformations.
    errcheck: boolean, optional (default False)
        If True an exception is raised if the transformation is invalid.
        By default errcheck=False and an invalid transformation
        returns ``inf`` and no exception is raised.
    direction: pyproj.enums.TransformDirection, optional
        The direction of the transform.
        Default is :attr:`pyproj.enums.TransformDirection.FORWARD`.


    Example:

    >>> from pyproj import Transformer
    >>> transformer = Transformer.from_crs(4326, 2100)
    >>> points = [(22.95, 40.63), (22.81, 40.53), (23.51, 40.86)]
    >>> for pt in transformer.itransform(points): '{:.3f} {:.3f}'.format(*pt)
    '2221638.801 2637034.372'
    '2212924.125 2619851.898'
    '2238294.779 2703763.736'
    >>> pipeline_str = (
    ...     "+proj=pipeline +step +proj=longlat +ellps=WGS84 "
    ...     "+step +proj=unitconvert +xy_in=rad +xy_out=deg"
    ... )
    >>> pipe_trans = Transformer.from_pipeline(pipeline_str)
    >>> for pt in pipe_trans.itransform([(2.1, 0.001)]):
    ...     '{:.3f} {:.3f}'.format(*pt)
    '2.100 0.001'
    >>> transproj = Transformer.from_crs(
    ...     {"proj":'geocent', "ellps":'WGS84', "datum":'WGS84'},
    ...     "EPSG:4326",
    ...     always_xy=True,
    ... )
    >>> for pt in transproj.itransform(
    ...     [(-2704026.010, -4253051.810, 3895878.820)],
    ...     radians=True,
    ... ):
    ...     '{:.3f} {:.3f} {:.3f}'.format(*pt)
    '-2.137 0.661 -20.531'
    >>> transprojr = Transformer.from_crs(
    ...     "EPSG:4326",
    ...     {"proj":'geocent', "ellps":'WGS84', "datum":'WGS84'},
    ...     always_xy=True,
    ... )
    >>> for pt in transprojr.itransform(
    ...     [(-2.137, 0.661, -20.531)],
    ...     radians=True
    ... ):
    ...     '{:.3f} {:.3f} {:.3f}'.format(*pt)
    '-2704214.394 -4254414.478 3894270.731'
    >>> transproj_eq = Transformer.from_proj(
    ...     'EPSG:4326',
    ...     '+proj=longlat +datum=WGS84 +no_defs +type=crs',
    ...     always_xy=True,
    ...     skip_equivalent=True
    ... )
    >>> for pt in transproj_eq.itransform([(-2.137, 0.661)]):
    ...     '{:.3f} {:.3f}'.format(*pt)
    '-2.137 0.661'

    """
    it = iter(points)  # point iterator
    # get first point to check stride
    try:
        fst_pt = next(it)
    except StopIteration:
        raise ValueError("iterable must contain at least one point")

    stride = len(fst_pt)
    if stride not in (2, 3, 4):
        raise ValueError("points can contain up to 4 coordinates")

    if time_3rd and stride != 3:
        raise ValueError("'time_3rd' is only valid for 3 coordinates.")

    # create a coordinate sequence generator etc. x1,y1,z1,x2,y2,z2,....
    # chain so the generator returns the first point that was already acquired
    coord_gen = chain(fst_pt, (coords[c] for coords in it for c in range(stride)))

    while True:
        # create a temporary buffer storage for
        # the next 64 points (64*stride*8 bytes)
        buff = array("d", islice(coord_gen, 0, 64 * stride))
        if len(buff) == 0:
            break

        self._transformer._transform_sequence(
            stride,
            buff,
            switch=switch,
            direction=direction,
            time_3rd=time_3rd,
            radians=radians,
            errcheck=errcheck,
        )

        for pt in zip(*([iter(buff)] * stride)):
            yield pt