0

I am working on API and I really cannot rename variable name to process things fast but I cannot make run the code(Python 3.11).

The problem:

def __init__(self, from: str = None)
    self.from = from

when I try to run this piece of beautifully written gem, I got an error.

def __init__(self, from: str = None
                   ^^^^
SyntaxError: invalid syntax

Even the pylance had problem with the syntax but I manage to fix it with # type: ignore at the beginning of the script.

Any advice?

Editor: VSCode

I have tried Google but didn't help much. :)

Ezachiel
  • 11
  • 3
  • 3
    `from` is a reserved keyword and cannot be used as an identifier name. Period. Your only choice is to use a different signature (rename the parameter, or accept a dictionary instead?) – Brian61354270 Jan 15 '23 at 22:18
  • 1
    As a side note, `name: str = None` is strictly speaking a type error. `name: Optional[str] = None` or `name: str | None = None` would be more correct – Brian61354270 Jan 15 '23 at 22:20
  • Thank you Brian, you didn't make me happy. Thank you – Ezachiel Jan 15 '23 at 22:26
  • @Brian I think a good argument could be made that `foo: SomeType = None` is very clear, ergonomic, and not particularly error-prone, while `foo: SomeType | None = None` is redundant boilerplate that wastes more time (including, most importantly, time of people reading the code) than it recoups in "yes I really did mean `None` is allowed here, that wasn't a mistake" value. (In other words, a good argument could be made that a static type analyzer should absolutely accept `= None` at the declaration site as equivalent to `| None = None`.) – mtraceur Jan 15 '23 at 22:27
  • okay, I fixed the name but my recursions don't seem so beautiful like before -*moisturized* – Ezachiel Jan 16 '23 at 14:23

2 Answers2

2

The error message isn't very clear, but from is a reserved keyword

https://docs.python.org/3/reference/lexical_analysis.html#keywords

    ...
except Exception as ex:
    raise ValueError("oops") from ex
def my_generator(some_iter):
    ...
    yield from some_iter
from foo import bar

If you must to keep the name (say, frontending some other frozen frozen API), you could extract it from **kwargs

def __init__(self, *args, **kwargs):
    self._from = kwargs["from"]

You may also have to be careful creating instance of the class

AwkwardFromArgClass(**{"from": "from value"})
ti7
  • 16,375
  • 6
  • 40
  • 68
  • A good practice for alternative parameter names instead of "from" is to answer: *what* does this argument represent/contain? For example, an `IPv4Address` class which can take a string (`IPv4('8.8.8.8')`) can use `address` instead of `from` as the parameter name. – mtraceur Jan 15 '23 at 22:36
  • 1
    When the keyword is really the best word, [PEP-8 recommends *appending* a single *suffix* `_`](https://peps.python.org/pep-0008/#function-and-method-arguments): "If a function argument’s name clashes with a reserved keyword, it is generally better to append a single trailing underscore rather than use an abbreviation or spelling corruption. Thus `class_` is better than `clss`. (Perhaps better is to avoid such clashes by using a synonym.)" – mtraceur Jan 15 '23 at 22:41
  • ah, it's a bit religious for such a class, but I prefer the `_` prefix here to help it be clearer that `_from` is a internal member (still avoiding `SyntaxError`) https://stackoverflow.com/questions/1301346/ .. but practically, something like your suggestion of "address" or "don't do that" will be much better! .. and perhaps most practically, a style like using `kwargs["from"]` provides a great opportunity to accept _both_ an old and new value optionally (perhaps via `KeyError`), inject a warning, and ultimately hope to transition to a friendlier name! – ti7 Jan 15 '23 at 22:53
  • Yes, when it's a *private attribute* it should be a prefix `_` - the quoted PEP 8 guideline for suffix `_` applies to *public parameters* (and I would say to *public attributes* and so on). – mtraceur Jan 15 '23 at 22:59
0

You cannot use from as an argument name because is a default syntax used to import modules like from math import sin to import only the sin function.

Try renaming it from_ with F2

marick
  • 109
  • 6