Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-37206: Unrepresentable default values no longer represented as None. #13933

Merged

Conversation

serhiy-storchaka
Copy link
Member

@serhiy-storchaka serhiy-storchaka commented Jun 9, 2019

@@ -92,7 +92,7 @@ test_objects_converter
[clinic start generated code]*/

PyDoc_STRVAR(test_objects_converter__doc__,
"test_objects_converter($module, a, b=None, /)\n"
"test_objects_converter($module, a, b=<unspecified>, /)\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be considerable that <unspecified> is obvious.
PEP 570 enabled us to make text signature and document consistent.
In document, we use [, b] for optional argument without public default value.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer [, b] if it be what the user see. But the average user will not see this, because the inspect module fails to parse both forms and the user will see just (...) in the help output. The purpose of this change to prevent displaying a wrong result (b=None when None is not acceptable). I do not see a sense of spending additional effort if the result is the same. I will make the representation using brances once I have found how to make it visible to the user.

@ned-deily
Copy link
Member

I'm not going to get into whether this PR is appropriate for 3.8 but, assuming it were, I would be very concerned about making a change of this size and complexity in 3.7 at this stage in its lifecycle.

@@ -4400,7 +4399,7 @@ def bad_node(self, node):
# mild hack: explicitly support NULL as a default value
if isinstance(expr, ast.Name) and expr.id == 'NULL':
value = NULL
py_default = 'None'
py_default = '<unspecified>'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also caution against the use of words like "unspecified" or "undefined" because that can imply to a reader that the behavior is arbitrary and up to the Python implementation when not supplied. We do define these behaviors, they just require reading further documentation.

<see docs> might be better? the brackets make it clear that it isn't an actual Python value no matter what text goes in there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not matter what invalid syntax is used here. The end user will never see it. This is the simplest way to make the insect module not reporting the wrong result. The effect is the same as there is not any signature (as was before using Argument Clinic).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about <unrepresentable> or <nonrepresentable>?

(This will not be seen by an average Python user, it is only for core developers)

@@ -3204,6 +3201,8 @@ def converter_init(self, *, accept={str}, encoding=None, zeroes=False):
# sorry, clinic can't support preallocated buffers
# for es# and et#
self.c_default = "NULL"
if NoneType in accept and self.c_default == "Py_None":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this really okay? we hold the GIL and the code you've modified at a quick first glance isn't using the value when it is == Py_None, but we never Py_INCREF'd the Py_None and there is nothing preventing us from treating it as if we had.

It also potentially adds situations where None is accepted as a parameter where it wasn't before? I'd need to go audit all of the APIs this change is trying to update to see if each of them intends to allow None as a value for a review of that. In that case if someone did pass in None from Python code, it should've been Py_INCREF'd - who's doing the DECREF before clobbering it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the str converter. The target's type is const char *. Py_None is invalid value here. None is converted to NULL. For example see _io.open and various encode/decode methods.

@bedevere-bot
Copy link

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

And if you don't make the requested changes, you will be poked with soft cushions!

Copy link
Member Author

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currenty it is just the simlest way to make the insect module failing to parse the signature instead of returning the false result. The end user will see the same resilt as if there is no any signature.

@@ -92,7 +92,7 @@ test_objects_converter
[clinic start generated code]*/

PyDoc_STRVAR(test_objects_converter__doc__,
"test_objects_converter($module, a, b=None, /)\n"
"test_objects_converter($module, a, b=<unspecified>, /)\n"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer [, b] if it be what the user see. But the average user will not see this, because the inspect module fails to parse both forms and the user will see just (...) in the help output. The purpose of this change to prevent displaying a wrong result (b=None when None is not acceptable). I do not see a sense of spending additional effort if the result is the same. I will make the representation using brances once I have found how to make it visible to the user.

@@ -3204,6 +3201,8 @@ def converter_init(self, *, accept={str}, encoding=None, zeroes=False):
# sorry, clinic can't support preallocated buffers
# for es# and et#
self.c_default = "NULL"
if NoneType in accept and self.c_default == "Py_None":
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the str converter. The target's type is const char *. Py_None is invalid value here. None is converted to NULL. For example see _io.open and various encode/decode methods.

Copy link
Member Author

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being terse. Posted from a phone.

@@ -4400,7 +4399,7 @@ def bad_node(self, node):
# mild hack: explicitly support NULL as a default value
if isinstance(expr, ast.Name) and expr.id == 'NULL':
value = NULL
py_default = 'None'
py_default = '<unspecified>'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not matter what invalid syntax is used here. The end user will never see it. This is the simplest way to make the insect module not reporting the wrong result. The effect is the same as there is not any signature (as was before using Argument Clinic).

@serhiy-storchaka serhiy-storchaka merged commit 279f446 into python:master Sep 14, 2019
@serhiy-storchaka serhiy-storchaka deleted the clinic-unrepresentable-default branch September 14, 2019 09:24
@miss-islington
Copy link
Contributor

Thanks @serhiy-storchaka for the PR 🌮🎉.. I'm working now to backport this PR to: 3.8.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry, @serhiy-storchaka, I could not cleanly backport this to 3.8 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 279f44678c8b84a183f9eeb85e0b086228154497 3.8

serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this pull request Sep 14, 2019
… as None. (pythonGH-13933)

In ArgumentClinic, value "NULL" should now be used only for unrepresentable default values
(like in the optional third parameter of getattr). "None" should be used if None is accepted
as argument and passing None has the same effect as not passing the argument at all..
(cherry picked from commit 279f446)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
@bedevere-bot
Copy link

GH-16141 is a backport of this pull request to the 3.8 branch.

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot x86 Gentoo Non-Debug with X 3.x has failed when building commit 279f446.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/99/builds/3302) and take a look at the build logs.
  4. Check if the failure is related to this commit (279f446) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/99/builds/3302

Failed tests:

  • test_smtpnet

Failed subtests:

  • test_connect_default_port - test.test_smtpnet.SmtpSSLTest

Summary of the results of the build (if available):

== Tests result: FAILURE then FAILURE ==

410 tests OK.

10 slowest tests:

  • test_concurrent_futures: 3 min 3 sec
  • test_multiprocessing_spawn: 2 min 54 sec
  • test_tools: 2 min 30 sec
  • test_tokenize: 2 min 23 sec
  • test_multiprocessing_forkserver: 1 min 43 sec
  • test_lib2to3: 1 min 28 sec
  • test_asyncio: 1 min 25 sec
  • test_multiprocessing_fork: 1 min 16 sec
  • test_capi: 1 min 4 sec
  • test_io: 55 sec 563 ms

1 test failed:
test_smtpnet

8 tests skipped:
test_devpoll test_kqueue test_msilib test_startfile
test_winconsoleio test_winreg test_winsound test_zipfile64

1 re-run test:
test_smtpnet

Total duration: 21 min 36 sec

Click to see traceback logs
Traceback (most recent call last):
  File "/buildbot/buildarea/cpython/3.x.ware-gentoo-x86.nondebug/build/Lib/test/test_smtpnet.py", line 58, in test_connect_default_port
    server = smtplib.SMTP_SSL(self.testServer)
  File "/buildbot/buildarea/cpython/3.x.ware-gentoo-x86.nondebug/build/Lib/smtplib.py", line 1032, in __init__
    SMTP.__init__(self, host, port, local_hostname, timeout,
  File "/buildbot/buildarea/cpython/3.x.ware-gentoo-x86.nondebug/build/Lib/smtplib.py", line 256, in __init__
    raise SMTPConnectError(code, msg)
smtplib.SMTPConnectError: (421, b'4.4.5 Server busy, try again later.')

serhiy-storchaka added a commit that referenced this pull request Sep 14, 2019
… as None. (GH-13933) (GH-16141)

In ArgumentClinic, value "NULL" should now be used only for unrepresentable default values
(like in the optional third parameter of getattr). "None" should be used if None is accepted
as argument and passing None has the same effect as not passing the argument at all.
(cherry picked from commit 279f446)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
@serhiy-storchaka serhiy-storchaka removed their assignment Dec 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants